Source arbitration now covers everything a source can claim, and the provenance trail says where each value actually came from.
Arbitration
- Nomenclature is arbitrated. Taxon status, rank, authorship, year, publication and phylum were left on last-write-wins: POWO could say a taxon was accepted, a later GBIF pass could say doubtful, and the column took whichever ran last — with nothing recorded. GBIF builds its taxonomy by automated consensus and Kew is the authority, so the outcome was backwards. It no longer happens, and the disagreement is queryable.
- The raw strings a source publishes alongside a parsed field (
sexuality_rawand its siblings) were overwriting each other silently. They are arbitrated too. scientific_nameis deliberately excluded: renaming drives the slug, the plant linkage and the search tokens, so it needs its own path rather than a silent arbitration between two imports.
Provenance
- Facts now record the identifier the value carries at its source. A fact said
powowithout saying which POWO record, so the trail stopped at the database name.GET /api/v1/species/{id}/factsnow returnssource_record_id, including on rejected claims — the ones you most want to trace back. - Two fields a source could send and see silently dropped now land:
phylum, and the common name column. A test asserts every field the contract claims to arbitrate is actually reachable, so this class of gap fails loudly rather than vanishing.
Data quality tracking
- The quality snapshot runs daily instead of weekly, and the management dashboard gains a day-by-day evolution view with a window selector, plus a list of which fields gained or lost species over the period. Regressions are shown alongside progress.
- Progress is measured as the share of measurable cells that are filled, rather than the average completion ratio — the latter shifts when field applicability changes, so it cannot be compared across days.
Fixes
- An ingestion targeted at a species that did not repeat its scientific name silently cleared authorship, publication and rank. The guard was meant to distrust a source naming a different taxon; it fired on a merely absent name.
- Cultivation guidance (sowing, row spacing, days to harvest) is now expected only of cultivated species, not of anything with an edible part. Recording that a foraged thistle has edible roots used to make it look less complete.
- Unknown boolean filter values return a 400 listing the accepted tokens instead of silently coercing (
filter[edible]=noused to mean yes). - Images with no identified part are grouped under an explicit
unknownkey rather than an empty one.
Notes for API clients: facts entries gain a populated source_record_id. Boolean filters now reject values outside the documented set instead of guessing.