The catalogues are PDFs: prose entries and positional tables. Extraction is
Python; analysis is R. The full pipeline and a defect log are in the
repository.
Every defect found is published
Including — especially — the ones in our own code. The log
(docs/findings.md) records thirteen. A sample:
Seven fabricated coins. Rows of consecutive plate-page numbers
(103 104 105 106 107) were parsed as coins, producing
entries with a mint named “105”. Caught by a check that a coin dated
AH 106 / AD 104 cannot exist.
Seventeen corrupted die axes. Catalogue reference numbers
(Tbg IX 394) were swallowed as die axes, wrecking two
fields at once — the axis was wrong and the reference truncated.
A ruler column 30.8% wrong. Its most frequent value was
Obv: Qaratakin, a legend transcription.
Restoration brackets destroyed at parse time, so every partly-read
legend arrived looking as certain as a fully legible one.
A correct date read as an error. A Tabaristan hemidrachm dated
“AH 105 / AD 756” tripped the date checker — but Tabaristan
coins use the post-Yazdegerd era, and 651 + 105 = 756. The row was right and the
check was wrong.
That last one is the operating assumption: when a check fires on real
data, the check is wrong until shown otherwise.
Why internal consistency is not enough
Datasets like this are usually validated by checking that they agree with
themselves — counts summing to totals, dates parsing, weights in range.
Two of the defects above passed exactly that kind of validation, because nothing
about them was inconsistent. A fabricated row and a real one are both
well-formed. The arithmetic still balances.