FEAT-8b: bake Julian's authoritative Wurfchronik semantics into the extractor
- survivedToGoHome: unlabeled Tabelle1 col E detected positionally; value-
adaptive row parsing recovers it from schema-shifted Tabelle2 rows too
(118 recovered, 79 confirmed by the E=F-TG-s identity)
- breakdown G -> males/females/stillborn/diedLater ('s' = died before Abgabe)
- validation: E = F - TG - s; 113 mismatches as German review-report warnings
- (name, Zucht) canonicalisation: [brackets] == of/von suffix ([ZdkC] ==
von den Kleinen Chaoten); Zucht = dedup discriminator (0 splits in data)
- animal->litter matching via DOB+(Vater,Mutter): 95 high-confidence,
40 date-only, 9 ambiguous; litterRef in animals.json
- regenerated report: 889 raw -> 574 unique (279 dated), 32 conflicts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,12 +19,29 @@ See the format analysis in `FEAT-8a-format-spec.md` (Pam's hive workspace).
|
||||
- Embedded photos (`xl/media`) → `output/photos/<animal-slug>/`, mapped to the
|
||||
animal by drawing anchor position.
|
||||
2. **Dedup + review (stage 2)**
|
||||
- Merge animals on `normalise(name) + DOB` (corroborated by DOB+genotype).
|
||||
- Merge animals on `normalise(call-name) + DOB`, with the **Zucht as
|
||||
discriminator** (Julian's ruling: Wurfchronik `[brackets]` ≡ Stammbaum
|
||||
`of/von <line>` suffix — both are the breeding line; same name+DOB but
|
||||
different Zucht stays two animals).
|
||||
- Match animals onto Wurfchronik litters (`litterRef`) via DOB + (Vater,
|
||||
Mutter) — the Pam-validated build order (chronicle litters are canonical).
|
||||
- Emit a German-language `output/review-report.md` for the breeder to verify
|
||||
(merges, **conflicts**, ambiguous/incomplete entries, unmapped genotype tokens).
|
||||
(merges, **conflicts**, ambiguous/incomplete entries, unmapped genotype
|
||||
tokens, litter data-quality warnings).
|
||||
- **Nothing is loaded into the database** — stage 3 (API load) is separate and
|
||||
waits on DATA-2 + FEAT-1b phase 2.
|
||||
|
||||
### Wurfchronik column semantics (Julian, authoritative)
|
||||
|
||||
`A` Wurfbezeichnung · `B` Geburtsdatum · `C` Mutter · `D` Vater (`[…]` = Zucht,
|
||||
`&` = multiple sires) · `E` **survivedToGoHome** (Tabelle1 only, unlabeled —
|
||||
detected positionally) · `F` Wurfstärke → `totalBorn` · `G` breakdown
|
||||
`Männchen,Weibchen,TG,s` → `males/females/stillborn/diedLater` (`s` = died
|
||||
after birth, before Abgabe) · last column → `note`. Validation: `E` should
|
||||
equal `F − TG − s`; mismatches become German warnings in the review report
|
||||
(data-quality signal, not an import blocker). A few Tabelle2 rows shift these
|
||||
columns — they are read value-adaptively and flagged with a warning.
|
||||
|
||||
Genotypes are mapped to the frozen 8-locus contract (A C D E G P Sp Re) while
|
||||
preserving everything: `genotype.mapped8locus`, `genotype.rawGenotype` (verbatim),
|
||||
`genotype.unmappedTokens` (e.g. the `Uw` locus, markers `WFNZ/WP/DP`). A `-`
|
||||
|
||||
Reference in New Issue
Block a user