#822 explicit-country coherence — frontier-gap before/after
The #822 fix (applyExplicitCountryCoherence, PR #852) re-picks a namesake localitylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. to the countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. the
address explicitly names — Vienna, Austria → Vienna AT, not Vienna WV. This measures it against the
frontier-gap diagnostic (scripts/eval/frontier-gap.ts): forward-geocode the top-3 cities by population
for every countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. as a bare "City, Country" query (no countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. constraint — what the drop-in /search
sends), scored by coordinate error (within 50 km of the citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy.'s true GeoNamesGeoNamesA free global gazetteer combining administrative, postal, and POI data across 200+ countries. Supplements Who's On First for postcode centroids and places where WOF has gaps. coordinate).
Config: the default drop-in path (admin-global-priority.db, no MAILWOMAN_CANDIDATE_DB) — the path the
fix touches and the path the nominatim/photon drop-ins use. 506 cities across 187 countries, pop ≥ 50 000.
Result
| Metric | Before (pre-#822) | After (#822) | Δ |
|---|---|---|---|
| Bare resolve-rate | 54.2% | 77.9% | +23.7 pp |
| +hint ceiling | 82.8% | 83.0% | +0.2 pp (flat) |
| Bare US-namesake misroutes | 10.5% (53/506) | 4.3% (22/506) | −6.2 pp |
| Bare-supported countries (≥50%) | 112 | 157 | +45 |
| Placer-recoverable (#822) countries | 57 | 12 | −45 |
| Residual (exonym + coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present.) countries | 18 | 18 | unchanged |
The fix recovered 45 of the 57 placer-recoverable countries — the ones that resolved only once the
countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. was known. It did so on CPU, with no placer retrain: the countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. code comes from the parser's own
country emission (normalized via codex's ISO-3166 table), so the explicit tokentokenOne word or subword in the tokenized input. For the neural classifier, tokens come from SentencePiece (subword units); for the rule classifiers, tokens are whitespace- and punctuation-separated words. in the query does what a
grown coarse-placercoarse-placerA lightweight int8 country classifier (~0.79 MB) that predicts which of a set of target countries an address belongs to, feeding a soft prior into resolver disambiguation. would have. The +hint ceiling barely moved (82.8 → 83.0), which is the tell that the
fix closed the bare↔hint gap structurally rather than lifting raw capability — exactly the shape a
joint-consistency reconcile should have.
This is notable against the prior expectation: the drop-in memo and #822's own framing read the namesake miss as a placer-emission gap needing a GPU retrain. It was a resolverresolverThe component that converts parsed address components (locality, region, postcode) into coordinates by looking them up in the gazetteer. The resolver ranks candidates by name match, population, and proximity, and returns the best-matching place with its centroid or polygon.-logic gap; the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' was already tagging the countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. correctly (the A0 parser probe confirmed it), the greedy walk was just ignoring it.
What the fix does NOT touch — the residual (→ #826)
18 countries fail even with a countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. hint, so neither the placer nor #822 can reach them. This is the parallel exonym + coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. lever already tracked on #826 (the #823 residual split). The post-#822 breakdown:
- Residual A — name-not-found / exonym (5): Kuwait, Réunion, Greece, Hungary, Iraq. The English query
name matches no in-countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. record because the record carries the local name (the
Warsaw/Warszawaclass). Where the place exists under a local name, alt-name surface indexing fixes it; otherwise it is a coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. absence. Note these are mostly the 2nd/3rd-population cities — the capitals (Warsaw, Athens, Budapest, Baghdad) already resolve; the long tail does not. - Residual B — gazetteergazetteerA geographical index that maps place names and postcodes to real-world coordinates. Mailwoman uses a custom-built Who's On First (WOF) SQLite database as its gazetteer — the 'atlas' half of the grammar/atlas architecture. coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. / disambiguation (13): Brazil, Belize, Honduras, Madagascar, São Tomé, Afghanistan, Albania, Burkina Faso, Liberia, Mali, Mozambique, Paraguay, Sweden. Wrong place even with the hint — within-countrycountryThe top-level address component (an ISO country). Closed-vocabulary, so it is best handled by a deterministic matcher feeding a proposal rather than a retrained model head. coveragecoverageThe fraction of a population or region for which a data source has real, non-placeholder entries — e.g. 47% rooftop coverage on Texas addresses. Distinct from accuracy on the rows that are present. or disambiguation, not a name-match problem.
The 12 remaining placer-recoverable countries (Bahrain, Poland, Serbia, Slovakia, Iceland, Singapore, Puerto Rico, …) are the cases where a 2nd/3rd citylocalityThe city / town / settlement component of an address: a populated place sitting between region and neighbourhood in the hierarchy. resolves with a hint but not bare — the smaller residual that growing the #244 coarse placer would still capture.
Reproduce
node --expose-gc scripts/eval/frontier-gap.ts --per-country 3 --min-pop 50000 --out <report.md>
The before/after A/B was run by checking out the pre-#822 resolver/resolve.ts (commit 84dcbe44),
recompiling, running, then restoring HEAD.