mailwoman 8.6.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (892) hide show
  1. package/README.md +2 -2
  2. package/api-engine.ts +29 -30
  3. package/cli-kit/dropin.ts +195 -0
  4. package/cli-kit/index.ts +27 -0
  5. package/cli.ts +4 -3
  6. package/commands/autocomplete.tsx +4 -1
  7. package/commands/clients/generate.tsx +2 -2
  8. package/commands/corpus/build.tsx +2 -1
  9. package/commands/corpus/fetch.tsx +10 -1
  10. package/commands/corpus/golden-relabel.tsx +53 -0
  11. package/commands/corpus/overlay-manifest.tsx +7 -2
  12. package/commands/corpus/shard/index.tsx +14 -1
  13. package/commands/corpus/shard/kryptonite.tsx +1 -1
  14. package/commands/corpus/shard/translit.tsx +4 -3
  15. package/commands/corpus/sub-venue-extract.tsx +66 -0
  16. package/commands/corpus/sub-venue-lexicon.tsx +94 -0
  17. package/commands/data/pull.tsx +343 -0
  18. package/commands/data/status.tsx +183 -0
  19. package/commands/dev/lint/corpus-shard.tsx +2 -2
  20. package/commands/eval/gauntlet-build.tsx +1 -1
  21. package/commands/eval/gauntlet.tsx +59 -3
  22. package/commands/eval/oa-resolver.tsx +32 -4
  23. package/commands/eval/poi-board.tsx +2 -2
  24. package/commands/eval/score-trends.tsx +41 -0
  25. package/commands/filer/linkage-eval.tsx +1 -1
  26. package/commands/gazetteer/anchor-lexicon.tsx +4 -12
  27. package/commands/gazetteer/build/anchor-lookup.tsx +23 -2
  28. package/commands/gazetteer/build/bdc.tsx +11 -11
  29. package/commands/gazetteer/build/candidate.tsx +9 -4
  30. package/commands/gazetteer/build/poi.tsx +7 -8
  31. package/commands/gazetteer/build/postcode-codepoint.tsx +84 -0
  32. package/commands/gazetteer/build/postcode-geonames.tsx +88 -0
  33. package/commands/gazetteer/build/postcode-locality.tsx +2 -2
  34. package/commands/gazetteer/build/postcode-ni-osm.tsx +105 -0
  35. package/commands/gazetteer/build/postcode-prefix.tsx +272 -0
  36. package/commands/gazetteer/conventions.tsx +2 -1
  37. package/commands/gazetteer/granularity.tsx +1 -1
  38. package/commands/gazetteer/importance.tsx +75 -13
  39. package/commands/gazetteer/inspect/graph.tsx +1 -19
  40. package/commands/gazetteer/inspect/mermaid.tsx +1 -19
  41. package/commands/gazetteer/inspect/sync.tsx +3 -4
  42. package/commands/gazetteer/inspect/tree.tsx +1 -19
  43. package/commands/gazetteer/pair-index.tsx +86 -35
  44. package/commands/gazetteer/polygons.tsx +7 -16
  45. package/commands/gazetteer/postcode-binary.tsx +76 -73
  46. package/commands/gazetteer/release.tsx +3 -2
  47. package/commands/gazetteer/verify-codepoint.tsx +69 -0
  48. package/commands/gazetteer/verify.tsx +38 -0
  49. package/commands/geocode.tsx +28 -1
  50. package/commands/parse.tsx +127 -36
  51. package/commands/poi.tsx +5 -1
  52. package/commands/registry/gold-set-sample.tsx +2 -2
  53. package/commands/registry/run.tsx +18 -11
  54. package/commands/registry/viz.tsx +9 -9
  55. package/commands/release/hf.tsx +1 -1
  56. package/commands/reverse.tsx +7 -3
  57. package/commands/serve.tsx +5 -1
  58. package/commands/situs/address-points.tsx +16 -29
  59. package/commands/situs/build.tsx +5 -5
  60. package/commands/situs/interpolation-shard.tsx +5 -29
  61. package/commands/situs/interpolation.tsx +10 -6
  62. package/commands/skill/install.tsx +121 -0
  63. package/data-bundles.ts +357 -0
  64. package/data-release.ts +6 -3
  65. package/dev-tools/build-gb-anchor-bin.run.ts +122 -0
  66. package/dev-tools/build-hard-slice-board.run.ts +230 -0
  67. package/dev-tools/capture-v1-parse.run.ts +11 -10
  68. package/dev-tools/convert-parity-fixtures.run.ts +13 -4
  69. package/dev-tools/diff-territory-spans.run.ts +101 -0
  70. package/dev-tools/extract-parity-corpus.run.ts +11 -3
  71. package/dev-tools/failure-census.run.ts +0 -0
  72. package/dev-tools/failure-report.run.ts +0 -0
  73. package/dev-tools/gb-fragment-board.run.ts +176 -0
  74. package/dev-tools/hard-slice-rows-toponym.ts +487 -0
  75. package/dev-tools/hard-slice-rows.ts +393 -0
  76. package/dev-tools/hard-slice-sweep-rows.ts +175 -0
  77. package/dev-tools/lint-mdx-angles.ts +4 -4
  78. package/dev-tools/postcode-coherence-coverage.run.ts +152 -0
  79. package/dev-tools/postcode-coherence-scale.run.ts +216 -0
  80. package/dev-tools/probe-comma-free-locality.run.ts +110 -0
  81. package/dev-tools/probe-fst-bias.run.ts +118 -0
  82. package/dev-tools/router-kind-probe.run.ts +4 -7
  83. package/dev-tools/score-anchor-v2-boards.run.ts +292 -0
  84. package/dev-tools/score-hard-slice-board.run.ts +457 -0
  85. package/dev-tools/us-recall-flip-census.run.ts +4 -7
  86. package/doctor/checks.ts +22 -29
  87. package/doctor/runner.ts +30 -20
  88. package/eval-harness/baseline-assert.ts +3 -1
  89. package/eval-harness/capability-manifest.ts +10 -6
  90. package/eval-harness/digit-board.ts +4 -7
  91. package/eval-harness/error-analysis.ts +5 -8
  92. package/eval-harness/fragment-board.ts +4 -7
  93. package/eval-harness/fragment-dev.ts +2 -6
  94. package/eval-harness/gates/v9.0.0-base.json +82 -0
  95. package/eval-harness/gauntlet/ablation-expectation.ts +1094 -0
  96. package/eval-harness/gauntlet/ablation-gazetteer.ts +354 -0
  97. package/eval-harness/gauntlet/ablation-report.ts +216 -0
  98. package/eval-harness/gauntlet/ablation-types.ts +252 -0
  99. package/eval-harness/gauntlet/ablation.ts +876 -0
  100. package/eval-harness/gauntlet/build-fdic-holdout.ts +2 -2
  101. package/eval-harness/gauntlet/build-regression-db.ts +42 -20
  102. package/eval-harness/gauntlet/cases/ad/regression.jsonl +2 -0
  103. package/eval-harness/gauntlet/cases/af/regression.jsonl +2 -0
  104. package/eval-harness/gauntlet/cases/ag/regression.jsonl +1 -0
  105. package/eval-harness/gauntlet/cases/ai/regression.jsonl +1 -0
  106. package/eval-harness/gauntlet/cases/al/regression.jsonl +2 -0
  107. package/eval-harness/gauntlet/cases/ao/regression.jsonl +1 -0
  108. package/eval-harness/gauntlet/cases/as/regression.jsonl +1 -0
  109. package/eval-harness/gauntlet/cases/at/regression.jsonl +1 -0
  110. package/eval-harness/gauntlet/cases/au/regression.jsonl +2 -0
  111. package/eval-harness/gauntlet/cases/aw/regression.jsonl +1 -0
  112. package/eval-harness/gauntlet/cases/ba/regression.jsonl +2 -0
  113. package/eval-harness/gauntlet/cases/bb/regression.jsonl +1 -0
  114. package/eval-harness/gauntlet/cases/bd/regression.jsonl +2 -0
  115. package/eval-harness/gauntlet/cases/be/regression.jsonl +1 -0
  116. package/eval-harness/gauntlet/cases/bf/regression.jsonl +1 -0
  117. package/eval-harness/gauntlet/cases/bi/regression.jsonl +1 -0
  118. package/eval-harness/gauntlet/cases/bj/regression.jsonl +2 -0
  119. package/eval-harness/gauntlet/cases/bm/regression.jsonl +3 -0
  120. package/eval-harness/gauntlet/cases/bn/regression.jsonl +2 -0
  121. package/eval-harness/gauntlet/cases/bq/regression.jsonl +1 -0
  122. package/eval-harness/gauntlet/cases/br/regression.jsonl +1 -0
  123. package/eval-harness/gauntlet/cases/bs/regression.jsonl +2 -0
  124. package/eval-harness/gauntlet/cases/bt/regression.jsonl +2 -0
  125. package/eval-harness/gauntlet/cases/bw/regression.jsonl +2 -0
  126. package/eval-harness/gauntlet/cases/by/regression.jsonl +1 -0
  127. package/eval-harness/gauntlet/cases/bz/regression.jsonl +2 -0
  128. package/eval-harness/gauntlet/cases/ca/regression.jsonl +4 -0
  129. package/eval-harness/gauntlet/cases/cd/regression.jsonl +2 -0
  130. package/eval-harness/gauntlet/cases/cf/regression.jsonl +1 -0
  131. package/eval-harness/gauntlet/cases/cg/regression.jsonl +2 -0
  132. package/eval-harness/gauntlet/cases/ch/regression.jsonl +1 -0
  133. package/eval-harness/gauntlet/cases/ck/regression.jsonl +2 -0
  134. package/eval-harness/gauntlet/cases/cn/regression.jsonl +1 -0
  135. package/eval-harness/gauntlet/cases/co/regression.jsonl +2 -0
  136. package/eval-harness/gauntlet/cases/cr/regression.jsonl +3 -0
  137. package/eval-harness/gauntlet/cases/cv/regression.jsonl +2 -0
  138. package/eval-harness/gauntlet/cases/cw/regression.jsonl +1 -0
  139. package/eval-harness/gauntlet/cases/cy/regression.jsonl +2 -0
  140. package/eval-harness/gauntlet/cases/de/regression.jsonl +3 -0
  141. package/eval-harness/gauntlet/cases/dj/regression.jsonl +1 -0
  142. package/eval-harness/gauntlet/cases/dm/regression.jsonl +1 -0
  143. package/eval-harness/gauntlet/cases/do/regression.jsonl +1 -0
  144. package/eval-harness/gauntlet/cases/eg/regression.jsonl +1 -0
  145. package/eval-harness/gauntlet/cases/er/regression.jsonl +1 -0
  146. package/eval-harness/gauntlet/cases/es/regression.jsonl +8 -0
  147. package/eval-harness/gauntlet/cases/fi/regression.jsonl +1 -0
  148. package/eval-harness/gauntlet/cases/fk/regression.jsonl +1 -0
  149. package/eval-harness/gauntlet/cases/fm/regression.jsonl +1 -0
  150. package/eval-harness/gauntlet/cases/fo/regression.jsonl +1 -0
  151. package/eval-harness/gauntlet/cases/fr/regression.jsonl +36 -0
  152. package/eval-harness/gauntlet/cases/gb/regression.jsonl +55 -0
  153. package/eval-harness/gauntlet/cases/gd/regression.jsonl +1 -0
  154. package/eval-harness/gauntlet/cases/ge/regression.jsonl +2 -0
  155. package/eval-harness/gauntlet/cases/generalization/country-sweep-2026-08-05-passes.jsonl +279 -0
  156. package/eval-harness/gauntlet/cases/gm/regression.jsonl +1 -0
  157. package/eval-harness/gauntlet/cases/gt/regression.jsonl +1 -0
  158. package/eval-harness/gauntlet/cases/gw/regression.jsonl +1 -0
  159. package/eval-harness/gauntlet/cases/hk/regression.jsonl +1 -0
  160. package/eval-harness/gauntlet/cases/id/regression.jsonl +1 -0
  161. package/eval-harness/gauntlet/cases/ie/regression.jsonl +11 -0
  162. package/eval-harness/gauntlet/cases/il/regression.jsonl +2 -0
  163. package/eval-harness/gauntlet/cases/im/regression.jsonl +3 -0
  164. package/eval-harness/gauntlet/cases/in/regression.jsonl +3 -0
  165. package/eval-harness/gauntlet/cases/io/regression.jsonl +1 -0
  166. package/eval-harness/gauntlet/cases/is/regression.jsonl +1 -0
  167. package/eval-harness/gauntlet/cases/it/regression.jsonl +2 -0
  168. package/eval-harness/gauntlet/cases/jo/regression.jsonl +1 -0
  169. package/eval-harness/gauntlet/cases/jp/regression.jsonl +1 -0
  170. package/eval-harness/gauntlet/cases/kh/regression.jsonl +1 -0
  171. package/eval-harness/gauntlet/cases/kw/regression.jsonl +1 -0
  172. package/eval-harness/gauntlet/cases/ky/regression.jsonl +1 -0
  173. package/eval-harness/gauntlet/cases/lb/regression.jsonl +1 -0
  174. package/eval-harness/gauntlet/cases/load.ts +185 -0
  175. package/eval-harness/gauntlet/cases/ma/regression.jsonl +1 -0
  176. package/eval-harness/gauntlet/cases/ml/regression.jsonl +1 -0
  177. package/eval-harness/gauntlet/cases/mp/regression.jsonl +1 -0
  178. package/eval-harness/gauntlet/cases/ms/regression.jsonl +1 -0
  179. package/eval-harness/gauntlet/cases/mu/regression.jsonl +1 -0
  180. package/eval-harness/gauntlet/cases/mw/regression.jsonl +1 -0
  181. package/eval-harness/gauntlet/cases/mx/regression.jsonl +5 -0
  182. package/eval-harness/gauntlet/cases/my/regression.jsonl +2 -0
  183. package/eval-harness/gauntlet/cases/na/regression.jsonl +1 -0
  184. package/eval-harness/gauntlet/cases/ni/regression.jsonl +2 -0
  185. package/eval-harness/gauntlet/cases/ph/regression.jsonl +1 -0
  186. package/eval-harness/gauntlet/cases/pk/regression.jsonl +1 -0
  187. package/eval-harness/gauntlet/cases/pl/regression.jsonl +2 -0
  188. package/eval-harness/gauntlet/cases/pm/regression.jsonl +1 -0
  189. package/eval-harness/gauntlet/cases/pr/regression.jsonl +4 -0
  190. package/eval-harness/gauntlet/cases/ru/regression.jsonl +1 -0
  191. package/eval-harness/gauntlet/cases/rw/regression.jsonl +1 -0
  192. package/eval-harness/gauntlet/cases/sa/regression.jsonl +1 -0
  193. package/eval-harness/gauntlet/cases/sb/regression.jsonl +1 -0
  194. package/eval-harness/gauntlet/cases/sc/regression.jsonl +1 -0
  195. package/eval-harness/gauntlet/cases/se/regression.jsonl +1 -0
  196. package/eval-harness/gauntlet/cases/seed-case.ts +175 -0
  197. package/eval-harness/gauntlet/cases/sg/regression.jsonl +1 -0
  198. package/eval-harness/gauntlet/cases/sh/regression.jsonl +1 -0
  199. package/eval-harness/gauntlet/cases/si/regression.jsonl +5 -0
  200. package/eval-harness/gauntlet/cases/sk/regression.jsonl +1 -0
  201. package/eval-harness/gauntlet/cases/sm/regression.jsonl +1 -0
  202. package/eval-harness/gauntlet/cases/so/regression.jsonl +2 -0
  203. package/eval-harness/gauntlet/cases/sr/regression.jsonl +1 -0
  204. package/eval-harness/gauntlet/cases/st/regression.jsonl +1 -0
  205. package/eval-harness/gauntlet/cases/sv/regression.jsonl +1 -0
  206. package/eval-harness/gauntlet/cases/sx/regression.jsonl +2 -0
  207. package/eval-harness/gauntlet/cases/th/regression.jsonl +1 -0
  208. package/eval-harness/gauntlet/cases/tk/regression.jsonl +1 -0
  209. package/eval-harness/gauntlet/cases/tm/regression.jsonl +1 -0
  210. package/eval-harness/gauntlet/cases/to/regression.jsonl +1 -0
  211. package/eval-harness/gauntlet/cases/tt/regression.jsonl +2 -0
  212. package/eval-harness/gauntlet/cases/ua/regression.jsonl +1 -0
  213. package/eval-harness/gauntlet/cases/us/regression.jsonl +33 -0
  214. package/eval-harness/gauntlet/cases/ve/regression.jsonl +1 -0
  215. package/eval-harness/gauntlet/cases/vg/regression.jsonl +1 -0
  216. package/eval-harness/gauntlet/cases/vi/regression.jsonl +3 -0
  217. package/eval-harness/gauntlet/cases/vn/regression.jsonl +1 -0
  218. package/eval-harness/gauntlet/cases/vu/regression.jsonl +1 -0
  219. package/eval-harness/gauntlet/cases/za/regression.jsonl +1 -0
  220. package/eval-harness/gauntlet/check-case.ts +149 -0
  221. package/eval-harness/gauntlet/corpus-stamp.ts +131 -0
  222. package/eval-harness/gauntlet/harness.ts +188 -8
  223. package/eval-harness/gauntlet/holdout.ts +21 -9
  224. package/eval-harness/gauntlet/metamorphic.ts +2 -12
  225. package/eval-harness/gauntlet/regression.ts +59 -86
  226. package/eval-harness/gauntlet/run.ts +89 -5
  227. package/eval-harness/gauntlet/schema.ts +75 -1
  228. package/eval-harness/hard-slice-board.ts +321 -0
  229. package/eval-harness/invariance/compare.ts +3 -3
  230. package/eval-harness/invariance/runner.ts +34 -30
  231. package/eval-harness/invariance/transforms.ts +2 -2
  232. package/eval-harness/ledger-append.ts +6 -4
  233. package/eval-harness/mask-regression.ts +6 -6
  234. package/eval-harness/oa-resolver-eval.ts +56 -14
  235. package/eval-harness/oracle-k.ts +11 -15
  236. package/eval-harness/parity-corpus.ts +4 -8
  237. package/eval-harness/poi-board.ts +31 -25
  238. package/eval-harness/promotion-gate-verdict.ts +7 -4
  239. package/eval-harness/promotion-gate.ts +21 -3
  240. package/eval-harness/score-trends.ts +257 -0
  241. package/eval-harness/v0-tree-adapter.ts +0 -5
  242. package/gazetteer-pipeline/admin/enrich.ts +22 -13
  243. package/gazetteer-pipeline/admin/fold-geonames.ts +16 -25
  244. package/gazetteer-pipeline/admin/fold-overture.ts +157 -19
  245. package/gazetteer-pipeline/admin/freeze.ts +2 -2
  246. package/gazetteer-pipeline/admin/index.ts +2 -1
  247. package/gazetteer-pipeline/admin/ingest-wof.ts +19 -3
  248. package/gazetteer-pipeline/anchor-lookup.ts +293 -123
  249. package/gazetteer-pipeline/borough-pairs.ts +40 -5
  250. package/gazetteer-pipeline/evidence-lexicons.ts +38 -9
  251. package/gazetteer-pipeline/fst.ts +150 -2
  252. package/gazetteer-pipeline/granularity-report.ts +1 -1
  253. package/gazetteer-pipeline/importance-fanout.ts +167 -0
  254. package/gazetteer-pipeline/index.ts +118 -36
  255. package/gazetteer-pipeline/lieudit-pairs.ts +0 -0
  256. package/gazetteer-pipeline/pair-index-hierarchy-probe.ts +13 -8
  257. package/gazetteer-pipeline/pair-index-hierarchy-verify.ts +27 -12
  258. package/gazetteer-pipeline/pair-index.ts +28 -14
  259. package/gazetteer-pipeline/poi/build-poi.ts +10 -12
  260. package/gazetteer-pipeline/postcode/binary.ts +243 -0
  261. package/gazetteer-pipeline/postcode/centroid-fills.ts +208 -45
  262. package/gazetteer-pipeline/postcode/codepoint/extract.ts +216 -0
  263. package/gazetteer-pipeline/postcode/codepoint/fetch.ts +385 -0
  264. package/gazetteer-pipeline/postcode/codepoint/index.ts +13 -0
  265. package/gazetteer-pipeline/postcode/codepoint/parse.ts +285 -0
  266. package/gazetteer-pipeline/postcode/codepoint-gate.ts +434 -0
  267. package/gazetteer-pipeline/postcode/codepoint-shard.ts +474 -0
  268. package/gazetteer-pipeline/postcode/geonames-tail.ts +359 -0
  269. package/gazetteer-pipeline/postcode/index.ts +2 -0
  270. package/gazetteer-pipeline/postcode/ni-osm/fetch.ts +391 -0
  271. package/gazetteer-pipeline/postcode/ni-osm/index.ts +11 -0
  272. package/gazetteer-pipeline/postcode/ni-osm/parse.ts +219 -0
  273. package/gazetteer-pipeline/postcode/ni-osm-shard.ts +558 -0
  274. package/gazetteer-pipeline/postcode/nl-pc6.ts +18 -14
  275. package/gazetteer-pipeline/postcode/zcta-centroids.ts +6 -6
  276. package/gazetteer-pipeline/postcode-locality/base.ts +8 -93
  277. package/gazetteer-pipeline/postcode-locality/jp.ts +12 -108
  278. package/gazetteer-pipeline/postcode-locality/kr.ts +6 -109
  279. package/gazetteer-pipeline/postcode-locality/tw.ts +18 -20
  280. package/gazetteer-pipeline/postcode-prefix.ts +329 -0
  281. package/gazetteer-pipeline/verify.ts +20 -15
  282. package/geocode-core.ts +125 -36
  283. package/geocode-stream.ts +10 -3
  284. package/out/api-engine.d.ts +1 -1
  285. package/out/api-engine.d.ts.map +1 -1
  286. package/out/api-engine.js +23 -30
  287. package/out/api-engine.js.map +1 -1
  288. package/out/cli-kit/dropin.d.ts +104 -0
  289. package/out/cli-kit/dropin.d.ts.map +1 -0
  290. package/out/cli-kit/dropin.js +139 -0
  291. package/out/cli-kit/dropin.js.map +1 -0
  292. package/out/cli-kit/index.d.ts +9 -0
  293. package/out/cli-kit/index.d.ts.map +1 -1
  294. package/out/cli-kit/index.js +23 -0
  295. package/out/cli-kit/index.js.map +1 -1
  296. package/out/cli.js +2 -1
  297. package/out/cli.js.map +1 -1
  298. package/out/commands/autocomplete.d.ts.map +1 -1
  299. package/out/commands/autocomplete.js +4 -1
  300. package/out/commands/autocomplete.js.map +1 -1
  301. package/out/commands/clients/generate.d.ts +2 -2
  302. package/out/commands/clients/generate.js +2 -2
  303. package/out/commands/corpus/build.d.ts.map +1 -1
  304. package/out/commands/corpus/build.js +2 -1
  305. package/out/commands/corpus/build.js.map +1 -1
  306. package/out/commands/corpus/fetch.d.ts +2 -0
  307. package/out/commands/corpus/fetch.d.ts.map +1 -1
  308. package/out/commands/corpus/fetch.js +8 -2
  309. package/out/commands/corpus/fetch.js.map +1 -1
  310. package/out/commands/corpus/golden-relabel.d.ts +24 -0
  311. package/out/commands/corpus/golden-relabel.d.ts.map +1 -0
  312. package/out/commands/corpus/golden-relabel.js +46 -0
  313. package/out/commands/corpus/golden-relabel.js.map +1 -0
  314. package/out/commands/corpus/overlay-manifest.d.ts +1 -1
  315. package/out/commands/corpus/overlay-manifest.d.ts.map +1 -1
  316. package/out/commands/corpus/overlay-manifest.js +7 -2
  317. package/out/commands/corpus/overlay-manifest.js.map +1 -1
  318. package/out/commands/corpus/shard/index.d.ts +5 -0
  319. package/out/commands/corpus/shard/index.d.ts.map +1 -1
  320. package/out/commands/corpus/shard/index.js +14 -1
  321. package/out/commands/corpus/shard/index.js.map +1 -1
  322. package/out/commands/corpus/shard/kryptonite.d.ts +1 -1
  323. package/out/commands/corpus/shard/kryptonite.js +1 -1
  324. package/out/commands/corpus/shard/translit.d.ts +2 -2
  325. package/out/commands/corpus/shard/translit.d.ts.map +1 -1
  326. package/out/commands/corpus/shard/translit.js +3 -3
  327. package/out/commands/corpus/shard/translit.js.map +1 -1
  328. package/out/commands/corpus/sub-venue-extract.d.ts +34 -0
  329. package/out/commands/corpus/sub-venue-extract.d.ts.map +1 -0
  330. package/out/commands/corpus/sub-venue-extract.js +53 -0
  331. package/out/commands/corpus/sub-venue-extract.js.map +1 -0
  332. package/out/commands/corpus/sub-venue-lexicon.d.ts +35 -0
  333. package/out/commands/corpus/sub-venue-lexicon.d.ts.map +1 -0
  334. package/out/commands/corpus/sub-venue-lexicon.js +78 -0
  335. package/out/commands/corpus/sub-venue-lexicon.js.map +1 -0
  336. package/out/commands/data/pull.d.ts +49 -0
  337. package/out/commands/data/pull.d.ts.map +1 -0
  338. package/out/commands/data/pull.js +267 -0
  339. package/out/commands/data/pull.js.map +1 -0
  340. package/out/commands/data/status.d.ts +28 -0
  341. package/out/commands/data/status.d.ts.map +1 -0
  342. package/out/commands/data/status.js +140 -0
  343. package/out/commands/data/status.js.map +1 -0
  344. package/out/commands/dev/lint/corpus-shard.d.ts +1 -1
  345. package/out/commands/dev/lint/corpus-shard.js +2 -2
  346. package/out/commands/eval/gauntlet-build.d.ts +1 -1
  347. package/out/commands/eval/gauntlet-build.js +1 -1
  348. package/out/commands/eval/gauntlet.d.ts +15 -0
  349. package/out/commands/eval/gauntlet.d.ts.map +1 -1
  350. package/out/commands/eval/gauntlet.js +55 -3
  351. package/out/commands/eval/gauntlet.js.map +1 -1
  352. package/out/commands/eval/oa-resolver.d.ts +5 -2
  353. package/out/commands/eval/oa-resolver.d.ts.map +1 -1
  354. package/out/commands/eval/oa-resolver.js +29 -4
  355. package/out/commands/eval/oa-resolver.js.map +1 -1
  356. package/out/commands/eval/poi-board.js +2 -2
  357. package/out/commands/eval/score-trends.d.ts +20 -0
  358. package/out/commands/eval/score-trends.d.ts.map +1 -0
  359. package/out/commands/eval/score-trends.js +30 -0
  360. package/out/commands/eval/score-trends.js.map +1 -0
  361. package/out/commands/filer/linkage-eval.d.ts +1 -1
  362. package/out/commands/filer/linkage-eval.js +1 -1
  363. package/out/commands/gazetteer/anchor-lexicon.d.ts +1 -1
  364. package/out/commands/gazetteer/anchor-lexicon.d.ts.map +1 -1
  365. package/out/commands/gazetteer/anchor-lexicon.js +4 -9
  366. package/out/commands/gazetteer/anchor-lexicon.js.map +1 -1
  367. package/out/commands/gazetteer/build/anchor-lookup.d.ts +9 -0
  368. package/out/commands/gazetteer/build/anchor-lookup.d.ts.map +1 -1
  369. package/out/commands/gazetteer/build/anchor-lookup.js +22 -2
  370. package/out/commands/gazetteer/build/anchor-lookup.js.map +1 -1
  371. package/out/commands/gazetteer/build/bdc.d.ts +6 -6
  372. package/out/commands/gazetteer/build/bdc.js +11 -11
  373. package/out/commands/gazetteer/build/bdc.js.map +1 -1
  374. package/out/commands/gazetteer/build/candidate.d.ts.map +1 -1
  375. package/out/commands/gazetteer/build/candidate.js +9 -4
  376. package/out/commands/gazetteer/build/candidate.js.map +1 -1
  377. package/out/commands/gazetteer/build/poi.d.ts +3 -3
  378. package/out/commands/gazetteer/build/poi.d.ts.map +1 -1
  379. package/out/commands/gazetteer/build/poi.js +7 -8
  380. package/out/commands/gazetteer/build/poi.js.map +1 -1
  381. package/out/commands/gazetteer/build/postcode-codepoint.d.ts +27 -0
  382. package/out/commands/gazetteer/build/postcode-codepoint.d.ts.map +1 -0
  383. package/out/commands/gazetteer/build/postcode-codepoint.js +64 -0
  384. package/out/commands/gazetteer/build/postcode-codepoint.js.map +1 -0
  385. package/out/commands/gazetteer/build/postcode-geonames.d.ts +26 -0
  386. package/out/commands/gazetteer/build/postcode-geonames.d.ts.map +1 -0
  387. package/out/commands/gazetteer/build/postcode-geonames.js +66 -0
  388. package/out/commands/gazetteer/build/postcode-geonames.js.map +1 -0
  389. package/out/commands/gazetteer/build/postcode-locality.d.ts +1 -1
  390. package/out/commands/gazetteer/build/postcode-locality.js +2 -2
  391. package/out/commands/gazetteer/build/postcode-ni-osm.d.ts +31 -0
  392. package/out/commands/gazetteer/build/postcode-ni-osm.d.ts.map +1 -0
  393. package/out/commands/gazetteer/build/postcode-ni-osm.js +79 -0
  394. package/out/commands/gazetteer/build/postcode-ni-osm.js.map +1 -0
  395. package/out/commands/gazetteer/build/postcode-prefix.d.ts +46 -0
  396. package/out/commands/gazetteer/build/postcode-prefix.d.ts.map +1 -0
  397. package/out/commands/gazetteer/build/postcode-prefix.js +196 -0
  398. package/out/commands/gazetteer/build/postcode-prefix.js.map +1 -0
  399. package/out/commands/gazetteer/conventions.d.ts.map +1 -1
  400. package/out/commands/gazetteer/conventions.js +2 -1
  401. package/out/commands/gazetteer/conventions.js.map +1 -1
  402. package/out/commands/gazetteer/granularity.js +1 -1
  403. package/out/commands/gazetteer/granularity.js.map +1 -1
  404. package/out/commands/gazetteer/importance.d.ts +9 -0
  405. package/out/commands/gazetteer/importance.d.ts.map +1 -1
  406. package/out/commands/gazetteer/importance.js +58 -11
  407. package/out/commands/gazetteer/importance.js.map +1 -1
  408. package/out/commands/gazetteer/inspect/graph.d.ts.map +1 -1
  409. package/out/commands/gazetteer/inspect/graph.js +1 -15
  410. package/out/commands/gazetteer/inspect/graph.js.map +1 -1
  411. package/out/commands/gazetteer/inspect/mermaid.d.ts.map +1 -1
  412. package/out/commands/gazetteer/inspect/mermaid.js +1 -15
  413. package/out/commands/gazetteer/inspect/mermaid.js.map +1 -1
  414. package/out/commands/gazetteer/inspect/sync.d.ts.map +1 -1
  415. package/out/commands/gazetteer/inspect/sync.js +4 -3
  416. package/out/commands/gazetteer/inspect/sync.js.map +1 -1
  417. package/out/commands/gazetteer/inspect/tree.d.ts.map +1 -1
  418. package/out/commands/gazetteer/inspect/tree.js +1 -15
  419. package/out/commands/gazetteer/inspect/tree.js.map +1 -1
  420. package/out/commands/gazetteer/pair-index.d.ts +11 -3
  421. package/out/commands/gazetteer/pair-index.d.ts.map +1 -1
  422. package/out/commands/gazetteer/pair-index.js +75 -32
  423. package/out/commands/gazetteer/pair-index.js.map +1 -1
  424. package/out/commands/gazetteer/polygons.d.ts.map +1 -1
  425. package/out/commands/gazetteer/polygons.js +7 -13
  426. package/out/commands/gazetteer/polygons.js.map +1 -1
  427. package/out/commands/gazetteer/postcode-binary.d.ts +23 -8
  428. package/out/commands/gazetteer/postcode-binary.d.ts.map +1 -1
  429. package/out/commands/gazetteer/postcode-binary.js +59 -59
  430. package/out/commands/gazetteer/postcode-binary.js.map +1 -1
  431. package/out/commands/gazetteer/release.d.ts.map +1 -1
  432. package/out/commands/gazetteer/release.js +3 -2
  433. package/out/commands/gazetteer/release.js.map +1 -1
  434. package/out/commands/gazetteer/verify-codepoint.d.ts +22 -0
  435. package/out/commands/gazetteer/verify-codepoint.d.ts.map +1 -0
  436. package/out/commands/gazetteer/verify-codepoint.js +48 -0
  437. package/out/commands/gazetteer/verify-codepoint.js.map +1 -0
  438. package/out/commands/gazetteer/verify.d.ts +9 -0
  439. package/out/commands/gazetteer/verify.d.ts.map +1 -1
  440. package/out/commands/gazetteer/verify.js +34 -0
  441. package/out/commands/gazetteer/verify.js.map +1 -1
  442. package/out/commands/geocode.d.ts +6 -0
  443. package/out/commands/geocode.d.ts.map +1 -1
  444. package/out/commands/geocode.js +23 -1
  445. package/out/commands/geocode.js.map +1 -1
  446. package/out/commands/parse.d.ts +24 -9
  447. package/out/commands/parse.d.ts.map +1 -1
  448. package/out/commands/parse.js +92 -32
  449. package/out/commands/parse.js.map +1 -1
  450. package/out/commands/poi.d.ts.map +1 -1
  451. package/out/commands/poi.js +4 -1
  452. package/out/commands/poi.js.map +1 -1
  453. package/out/commands/registry/gold-set-sample.d.ts +1 -1
  454. package/out/commands/registry/gold-set-sample.js +2 -2
  455. package/out/commands/registry/run.d.ts.map +1 -1
  456. package/out/commands/registry/run.js +14 -13
  457. package/out/commands/registry/run.js.map +1 -1
  458. package/out/commands/registry/viz.d.ts +2 -2
  459. package/out/commands/registry/viz.js +8 -8
  460. package/out/commands/registry/viz.js.map +1 -1
  461. package/out/commands/release/hf.js +1 -1
  462. package/out/commands/release/hf.js.map +1 -1
  463. package/out/commands/reverse.d.ts.map +1 -1
  464. package/out/commands/reverse.js +5 -3
  465. package/out/commands/reverse.js.map +1 -1
  466. package/out/commands/serve.d.ts.map +1 -1
  467. package/out/commands/serve.js +5 -1
  468. package/out/commands/serve.js.map +1 -1
  469. package/out/commands/situs/address-points.d.ts +1 -1
  470. package/out/commands/situs/address-points.d.ts.map +1 -1
  471. package/out/commands/situs/address-points.js +11 -23
  472. package/out/commands/situs/address-points.js.map +1 -1
  473. package/out/commands/situs/build.d.ts +1 -1
  474. package/out/commands/situs/build.js +5 -5
  475. package/out/commands/situs/build.js.map +1 -1
  476. package/out/commands/situs/interpolation-shard.d.ts.map +1 -1
  477. package/out/commands/situs/interpolation-shard.js +5 -23
  478. package/out/commands/situs/interpolation-shard.js.map +1 -1
  479. package/out/commands/situs/interpolation.d.ts.map +1 -1
  480. package/out/commands/situs/interpolation.js +10 -6
  481. package/out/commands/situs/interpolation.js.map +1 -1
  482. package/out/commands/skill/install.d.ts +46 -0
  483. package/out/commands/skill/install.d.ts.map +1 -0
  484. package/out/commands/skill/install.js +96 -0
  485. package/out/commands/skill/install.js.map +1 -0
  486. package/out/data-bundles.d.ts +171 -0
  487. package/out/data-bundles.d.ts.map +1 -0
  488. package/out/data-bundles.js +270 -0
  489. package/out/data-bundles.js.map +1 -0
  490. package/out/data-release.d.ts.map +1 -1
  491. package/out/data-release.js +5 -3
  492. package/out/data-release.js.map +1 -1
  493. package/out/dev-tools/build-gb-anchor-bin.run.d.ts +38 -0
  494. package/out/dev-tools/build-gb-anchor-bin.run.d.ts.map +1 -0
  495. package/out/dev-tools/build-gb-anchor-bin.run.js +103 -0
  496. package/out/dev-tools/build-gb-anchor-bin.run.js.map +1 -0
  497. package/out/dev-tools/build-hard-slice-board.run.d.ts +25 -0
  498. package/out/dev-tools/build-hard-slice-board.run.d.ts.map +1 -0
  499. package/out/dev-tools/build-hard-slice-board.run.js +183 -0
  500. package/out/dev-tools/build-hard-slice-board.run.js.map +1 -0
  501. package/out/dev-tools/capture-v1-parse.run.js +10 -9
  502. package/out/dev-tools/capture-v1-parse.run.js.map +1 -1
  503. package/out/dev-tools/convert-parity-fixtures.run.js +10 -4
  504. package/out/dev-tools/convert-parity-fixtures.run.js.map +1 -1
  505. package/out/dev-tools/diff-territory-spans.run.d.ts +20 -0
  506. package/out/dev-tools/diff-territory-spans.run.d.ts.map +1 -0
  507. package/out/dev-tools/diff-territory-spans.run.js +86 -0
  508. package/out/dev-tools/diff-territory-spans.run.js.map +1 -0
  509. package/out/dev-tools/extract-parity-corpus.run.js +9 -3
  510. package/out/dev-tools/extract-parity-corpus.run.js.map +1 -1
  511. package/out/dev-tools/failure-census.run.js +0 -0
  512. package/out/dev-tools/failure-census.run.js.map +1 -1
  513. package/out/dev-tools/failure-report.run.js +0 -0
  514. package/out/dev-tools/failure-report.run.js.map +1 -1
  515. package/out/dev-tools/gb-fragment-board.run.d.ts +31 -0
  516. package/out/dev-tools/gb-fragment-board.run.d.ts.map +1 -0
  517. package/out/dev-tools/gb-fragment-board.run.js +134 -0
  518. package/out/dev-tools/gb-fragment-board.run.js.map +1 -0
  519. package/out/dev-tools/hard-slice-rows-toponym.d.ts +24 -0
  520. package/out/dev-tools/hard-slice-rows-toponym.d.ts.map +1 -0
  521. package/out/dev-tools/hard-slice-rows-toponym.js +483 -0
  522. package/out/dev-tools/hard-slice-rows-toponym.js.map +1 -0
  523. package/out/dev-tools/hard-slice-rows.d.ts +53 -0
  524. package/out/dev-tools/hard-slice-rows.d.ts.map +1 -0
  525. package/out/dev-tools/hard-slice-rows.js +371 -0
  526. package/out/dev-tools/hard-slice-rows.js.map +1 -0
  527. package/out/dev-tools/hard-slice-sweep-rows.d.ts +34 -0
  528. package/out/dev-tools/hard-slice-sweep-rows.d.ts.map +1 -0
  529. package/out/dev-tools/hard-slice-sweep-rows.js +166 -0
  530. package/out/dev-tools/hard-slice-sweep-rows.js.map +1 -0
  531. package/out/dev-tools/lint-mdx-angles.d.ts.map +1 -1
  532. package/out/dev-tools/lint-mdx-angles.js +3 -4
  533. package/out/dev-tools/lint-mdx-angles.js.map +1 -1
  534. package/out/dev-tools/postcode-coherence-coverage.run.d.ts +25 -0
  535. package/out/dev-tools/postcode-coherence-coverage.run.d.ts.map +1 -0
  536. package/out/dev-tools/postcode-coherence-coverage.run.js +115 -0
  537. package/out/dev-tools/postcode-coherence-coverage.run.js.map +1 -0
  538. package/out/dev-tools/postcode-coherence-scale.run.d.ts +42 -0
  539. package/out/dev-tools/postcode-coherence-scale.run.d.ts.map +1 -0
  540. package/out/dev-tools/postcode-coherence-scale.run.js +164 -0
  541. package/out/dev-tools/postcode-coherence-scale.run.js.map +1 -0
  542. package/out/dev-tools/probe-comma-free-locality.run.d.ts +24 -0
  543. package/out/dev-tools/probe-comma-free-locality.run.d.ts.map +1 -0
  544. package/out/dev-tools/probe-comma-free-locality.run.js +84 -0
  545. package/out/dev-tools/probe-comma-free-locality.run.js.map +1 -0
  546. package/out/dev-tools/probe-fst-bias.run.d.ts +26 -0
  547. package/out/dev-tools/probe-fst-bias.run.d.ts.map +1 -0
  548. package/out/dev-tools/probe-fst-bias.run.js +92 -0
  549. package/out/dev-tools/probe-fst-bias.run.js.map +1 -0
  550. package/out/dev-tools/router-kind-probe.run.js +2 -6
  551. package/out/dev-tools/router-kind-probe.run.js.map +1 -1
  552. package/out/dev-tools/score-anchor-v2-boards.run.d.ts +35 -0
  553. package/out/dev-tools/score-anchor-v2-boards.run.d.ts.map +1 -0
  554. package/out/dev-tools/score-anchor-v2-boards.run.js +217 -0
  555. package/out/dev-tools/score-anchor-v2-boards.run.js.map +1 -0
  556. package/out/dev-tools/score-hard-slice-board.run.d.ts +44 -0
  557. package/out/dev-tools/score-hard-slice-board.run.d.ts.map +1 -0
  558. package/out/dev-tools/score-hard-slice-board.run.js +306 -0
  559. package/out/dev-tools/score-hard-slice-board.run.js.map +1 -0
  560. package/out/dev-tools/us-recall-flip-census.run.js +2 -6
  561. package/out/dev-tools/us-recall-flip-census.run.js.map +1 -1
  562. package/out/doctor/checks.d.ts +14 -13
  563. package/out/doctor/checks.d.ts.map +1 -1
  564. package/out/doctor/checks.js +8 -14
  565. package/out/doctor/checks.js.map +1 -1
  566. package/out/doctor/runner.d.ts +1 -1
  567. package/out/doctor/runner.d.ts.map +1 -1
  568. package/out/doctor/runner.js +25 -16
  569. package/out/doctor/runner.js.map +1 -1
  570. package/out/eval-harness/baseline-assert.d.ts.map +1 -1
  571. package/out/eval-harness/baseline-assert.js +2 -1
  572. package/out/eval-harness/baseline-assert.js.map +1 -1
  573. package/out/eval-harness/capability-manifest.d.ts.map +1 -1
  574. package/out/eval-harness/capability-manifest.js +10 -7
  575. package/out/eval-harness/capability-manifest.js.map +1 -1
  576. package/out/eval-harness/digit-board.d.ts.map +1 -1
  577. package/out/eval-harness/digit-board.js +2 -6
  578. package/out/eval-harness/digit-board.js.map +1 -1
  579. package/out/eval-harness/error-analysis.d.ts.map +1 -1
  580. package/out/eval-harness/error-analysis.js +5 -8
  581. package/out/eval-harness/error-analysis.js.map +1 -1
  582. package/out/eval-harness/fragment-board.d.ts.map +1 -1
  583. package/out/eval-harness/fragment-board.js +2 -6
  584. package/out/eval-harness/fragment-board.js.map +1 -1
  585. package/out/eval-harness/fragment-dev.d.ts.map +1 -1
  586. package/out/eval-harness/fragment-dev.js +2 -5
  587. package/out/eval-harness/fragment-dev.js.map +1 -1
  588. package/out/eval-harness/gauntlet/ablation-expectation.d.ts +551 -0
  589. package/out/eval-harness/gauntlet/ablation-expectation.d.ts.map +1 -0
  590. package/out/eval-harness/gauntlet/ablation-expectation.js +776 -0
  591. package/out/eval-harness/gauntlet/ablation-expectation.js.map +1 -0
  592. package/out/eval-harness/gauntlet/ablation-gazetteer.d.ts +73 -0
  593. package/out/eval-harness/gauntlet/ablation-gazetteer.d.ts.map +1 -0
  594. package/out/eval-harness/gauntlet/ablation-gazetteer.js +254 -0
  595. package/out/eval-harness/gauntlet/ablation-gazetteer.js.map +1 -0
  596. package/out/eval-harness/gauntlet/ablation-report.d.ts +51 -0
  597. package/out/eval-harness/gauntlet/ablation-report.d.ts.map +1 -0
  598. package/out/eval-harness/gauntlet/ablation-report.js +155 -0
  599. package/out/eval-harness/gauntlet/ablation-report.js.map +1 -0
  600. package/out/eval-harness/gauntlet/ablation-types.d.ts +232 -0
  601. package/out/eval-harness/gauntlet/ablation-types.d.ts.map +1 -0
  602. package/out/eval-harness/gauntlet/ablation-types.js +38 -0
  603. package/out/eval-harness/gauntlet/ablation-types.js.map +1 -0
  604. package/out/eval-harness/gauntlet/ablation.d.ts +176 -0
  605. package/out/eval-harness/gauntlet/ablation.d.ts.map +1 -0
  606. package/out/eval-harness/gauntlet/ablation.js +622 -0
  607. package/out/eval-harness/gauntlet/ablation.js.map +1 -0
  608. package/out/eval-harness/gauntlet/build-fdic-holdout.js +2 -2
  609. package/out/eval-harness/gauntlet/build-fdic-holdout.js.map +1 -1
  610. package/out/eval-harness/gauntlet/build-regression-db.d.ts +19 -2
  611. package/out/eval-harness/gauntlet/build-regression-db.d.ts.map +1 -1
  612. package/out/eval-harness/gauntlet/build-regression-db.js +29 -18
  613. package/out/eval-harness/gauntlet/build-regression-db.js.map +1 -1
  614. package/out/eval-harness/gauntlet/cases/load.d.ts +57 -0
  615. package/out/eval-harness/gauntlet/cases/load.d.ts.map +1 -0
  616. package/out/eval-harness/gauntlet/cases/load.js +150 -0
  617. package/out/eval-harness/gauntlet/cases/load.js.map +1 -0
  618. package/out/eval-harness/gauntlet/cases/seed-case.d.ts +123 -0
  619. package/out/eval-harness/gauntlet/cases/seed-case.d.ts.map +1 -0
  620. package/out/eval-harness/gauntlet/cases/seed-case.js +99 -0
  621. package/out/eval-harness/gauntlet/cases/seed-case.js.map +1 -0
  622. package/out/eval-harness/gauntlet/check-case.d.ts +44 -0
  623. package/out/eval-harness/gauntlet/check-case.d.ts.map +1 -0
  624. package/out/eval-harness/gauntlet/check-case.js +127 -0
  625. package/out/eval-harness/gauntlet/check-case.js.map +1 -0
  626. package/out/eval-harness/gauntlet/corpus-stamp.d.ts +60 -0
  627. package/out/eval-harness/gauntlet/corpus-stamp.d.ts.map +1 -0
  628. package/out/eval-harness/gauntlet/corpus-stamp.js +100 -0
  629. package/out/eval-harness/gauntlet/corpus-stamp.js.map +1 -0
  630. package/out/eval-harness/gauntlet/harness.d.ts +103 -6
  631. package/out/eval-harness/gauntlet/harness.d.ts.map +1 -1
  632. package/out/eval-harness/gauntlet/harness.js +105 -7
  633. package/out/eval-harness/gauntlet/harness.js.map +1 -1
  634. package/out/eval-harness/gauntlet/holdout.d.ts +7 -0
  635. package/out/eval-harness/gauntlet/holdout.d.ts.map +1 -1
  636. package/out/eval-harness/gauntlet/holdout.js +14 -8
  637. package/out/eval-harness/gauntlet/holdout.js.map +1 -1
  638. package/out/eval-harness/gauntlet/metamorphic.d.ts +1 -1
  639. package/out/eval-harness/gauntlet/metamorphic.d.ts.map +1 -1
  640. package/out/eval-harness/gauntlet/metamorphic.js +2 -9
  641. package/out/eval-harness/gauntlet/metamorphic.js.map +1 -1
  642. package/out/eval-harness/gauntlet/regression.d.ts +18 -1
  643. package/out/eval-harness/gauntlet/regression.d.ts.map +1 -1
  644. package/out/eval-harness/gauntlet/regression.js +43 -71
  645. package/out/eval-harness/gauntlet/regression.js.map +1 -1
  646. package/out/eval-harness/gauntlet/run.d.ts +60 -2
  647. package/out/eval-harness/gauntlet/run.d.ts.map +1 -1
  648. package/out/eval-harness/gauntlet/run.js +62 -3
  649. package/out/eval-harness/gauntlet/run.js.map +1 -1
  650. package/out/eval-harness/gauntlet/schema.d.ts +60 -2
  651. package/out/eval-harness/gauntlet/schema.d.ts.map +1 -1
  652. package/out/eval-harness/gauntlet/schema.js +24 -0
  653. package/out/eval-harness/gauntlet/schema.js.map +1 -1
  654. package/out/eval-harness/hard-slice-board.d.ts +185 -0
  655. package/out/eval-harness/hard-slice-board.d.ts.map +1 -0
  656. package/out/eval-harness/hard-slice-board.js +223 -0
  657. package/out/eval-harness/hard-slice-board.js.map +1 -0
  658. package/out/eval-harness/invariance/compare.d.ts +3 -3
  659. package/out/eval-harness/invariance/compare.js +3 -3
  660. package/out/eval-harness/invariance/runner.d.ts +4 -4
  661. package/out/eval-harness/invariance/runner.d.ts.map +1 -1
  662. package/out/eval-harness/invariance/runner.js +29 -26
  663. package/out/eval-harness/invariance/runner.js.map +1 -1
  664. package/out/eval-harness/invariance/transforms.js +2 -2
  665. package/out/eval-harness/invariance/transforms.js.map +1 -1
  666. package/out/eval-harness/ledger-append.d.ts.map +1 -1
  667. package/out/eval-harness/ledger-append.js +5 -4
  668. package/out/eval-harness/ledger-append.js.map +1 -1
  669. package/out/eval-harness/mask-regression.d.ts.map +1 -1
  670. package/out/eval-harness/mask-regression.js +6 -7
  671. package/out/eval-harness/mask-regression.js.map +1 -1
  672. package/out/eval-harness/oa-resolver-eval.d.ts +23 -2
  673. package/out/eval-harness/oa-resolver-eval.d.ts.map +1 -1
  674. package/out/eval-harness/oa-resolver-eval.js +27 -12
  675. package/out/eval-harness/oa-resolver-eval.js.map +1 -1
  676. package/out/eval-harness/oracle-k.d.ts +1 -1
  677. package/out/eval-harness/oracle-k.d.ts.map +1 -1
  678. package/out/eval-harness/oracle-k.js +7 -14
  679. package/out/eval-harness/oracle-k.js.map +1 -1
  680. package/out/eval-harness/parity-corpus.d.ts.map +1 -1
  681. package/out/eval-harness/parity-corpus.js +3 -6
  682. package/out/eval-harness/parity-corpus.js.map +1 -1
  683. package/out/eval-harness/poi-board.d.ts +15 -15
  684. package/out/eval-harness/poi-board.d.ts.map +1 -1
  685. package/out/eval-harness/poi-board.js +13 -7
  686. package/out/eval-harness/poi-board.js.map +1 -1
  687. package/out/eval-harness/promotion-gate-verdict.d.ts.map +1 -1
  688. package/out/eval-harness/promotion-gate-verdict.js +5 -3
  689. package/out/eval-harness/promotion-gate-verdict.js.map +1 -1
  690. package/out/eval-harness/promotion-gate.d.ts.map +1 -1
  691. package/out/eval-harness/promotion-gate.js +10 -3
  692. package/out/eval-harness/promotion-gate.js.map +1 -1
  693. package/out/eval-harness/score-trends.d.ts +45 -0
  694. package/out/eval-harness/score-trends.d.ts.map +1 -0
  695. package/out/eval-harness/score-trends.js +187 -0
  696. package/out/eval-harness/score-trends.js.map +1 -0
  697. package/out/eval-harness/v0-tree-adapter.d.ts +0 -5
  698. package/out/eval-harness/v0-tree-adapter.d.ts.map +1 -1
  699. package/out/eval-harness/v0-tree-adapter.js +0 -5
  700. package/out/eval-harness/v0-tree-adapter.js.map +1 -1
  701. package/out/gazetteer-pipeline/admin/enrich.d.ts.map +1 -1
  702. package/out/gazetteer-pipeline/admin/enrich.js +16 -7
  703. package/out/gazetteer-pipeline/admin/enrich.js.map +1 -1
  704. package/out/gazetteer-pipeline/admin/fold-geonames.d.ts +14 -15
  705. package/out/gazetteer-pipeline/admin/fold-geonames.d.ts.map +1 -1
  706. package/out/gazetteer-pipeline/admin/fold-geonames.js +16 -14
  707. package/out/gazetteer-pipeline/admin/fold-geonames.js.map +1 -1
  708. package/out/gazetteer-pipeline/admin/fold-overture.d.ts +28 -1
  709. package/out/gazetteer-pipeline/admin/fold-overture.d.ts.map +1 -1
  710. package/out/gazetteer-pipeline/admin/fold-overture.js +127 -14
  711. package/out/gazetteer-pipeline/admin/fold-overture.js.map +1 -1
  712. package/out/gazetteer-pipeline/admin/freeze.js +2 -2
  713. package/out/gazetteer-pipeline/admin/freeze.js.map +1 -1
  714. package/out/gazetteer-pipeline/admin/index.d.ts.map +1 -1
  715. package/out/gazetteer-pipeline/admin/index.js +2 -1
  716. package/out/gazetteer-pipeline/admin/index.js.map +1 -1
  717. package/out/gazetteer-pipeline/admin/ingest-wof.d.ts +13 -0
  718. package/out/gazetteer-pipeline/admin/ingest-wof.d.ts.map +1 -1
  719. package/out/gazetteer-pipeline/admin/ingest-wof.js +19 -3
  720. package/out/gazetteer-pipeline/admin/ingest-wof.js.map +1 -1
  721. package/out/gazetteer-pipeline/anchor-lookup.d.ts +85 -3
  722. package/out/gazetteer-pipeline/anchor-lookup.d.ts.map +1 -1
  723. package/out/gazetteer-pipeline/anchor-lookup.js +214 -109
  724. package/out/gazetteer-pipeline/anchor-lookup.js.map +1 -1
  725. package/out/gazetteer-pipeline/borough-pairs.d.ts +10 -0
  726. package/out/gazetteer-pipeline/borough-pairs.d.ts.map +1 -1
  727. package/out/gazetteer-pipeline/borough-pairs.js +22 -4
  728. package/out/gazetteer-pipeline/borough-pairs.js.map +1 -1
  729. package/out/gazetteer-pipeline/evidence-lexicons.d.ts.map +1 -1
  730. package/out/gazetteer-pipeline/evidence-lexicons.js +31 -7
  731. package/out/gazetteer-pipeline/evidence-lexicons.js.map +1 -1
  732. package/out/gazetteer-pipeline/fst.d.ts +37 -0
  733. package/out/gazetteer-pipeline/fst.d.ts.map +1 -1
  734. package/out/gazetteer-pipeline/fst.js +110 -2
  735. package/out/gazetteer-pipeline/fst.js.map +1 -1
  736. package/out/gazetteer-pipeline/granularity-report.d.ts +1 -1
  737. package/out/gazetteer-pipeline/granularity-report.js +1 -1
  738. package/out/gazetteer-pipeline/importance-fanout.d.ts +100 -0
  739. package/out/gazetteer-pipeline/importance-fanout.d.ts.map +1 -0
  740. package/out/gazetteer-pipeline/importance-fanout.js +120 -0
  741. package/out/gazetteer-pipeline/importance-fanout.js.map +1 -0
  742. package/out/gazetteer-pipeline/index.d.ts +38 -7
  743. package/out/gazetteer-pipeline/index.d.ts.map +1 -1
  744. package/out/gazetteer-pipeline/index.js +91 -29
  745. package/out/gazetteer-pipeline/index.js.map +1 -1
  746. package/out/gazetteer-pipeline/lieudit-pairs.d.ts +6 -0
  747. package/out/gazetteer-pipeline/lieudit-pairs.d.ts.map +1 -1
  748. package/out/gazetteer-pipeline/lieudit-pairs.js +0 -0
  749. package/out/gazetteer-pipeline/lieudit-pairs.js.map +1 -1
  750. package/out/gazetteer-pipeline/pair-index-hierarchy-probe.d.ts +3 -3
  751. package/out/gazetteer-pipeline/pair-index-hierarchy-probe.d.ts.map +1 -1
  752. package/out/gazetteer-pipeline/pair-index-hierarchy-probe.js +11 -6
  753. package/out/gazetteer-pipeline/pair-index-hierarchy-probe.js.map +1 -1
  754. package/out/gazetteer-pipeline/pair-index-hierarchy-verify.js +22 -12
  755. package/out/gazetteer-pipeline/pair-index-hierarchy-verify.js.map +1 -1
  756. package/out/gazetteer-pipeline/pair-index.d.ts +21 -12
  757. package/out/gazetteer-pipeline/pair-index.d.ts.map +1 -1
  758. package/out/gazetteer-pipeline/pair-index.js +26 -13
  759. package/out/gazetteer-pipeline/pair-index.js.map +1 -1
  760. package/out/gazetteer-pipeline/poi/build-poi.d.ts +8 -10
  761. package/out/gazetteer-pipeline/poi/build-poi.d.ts.map +1 -1
  762. package/out/gazetteer-pipeline/poi/build-poi.js +6 -7
  763. package/out/gazetteer-pipeline/poi/build-poi.js.map +1 -1
  764. package/out/gazetteer-pipeline/postcode/binary.d.ts +114 -0
  765. package/out/gazetteer-pipeline/postcode/binary.d.ts.map +1 -0
  766. package/out/gazetteer-pipeline/postcode/binary.js +176 -0
  767. package/out/gazetteer-pipeline/postcode/binary.js.map +1 -0
  768. package/out/gazetteer-pipeline/postcode/centroid-fills.d.ts +10 -0
  769. package/out/gazetteer-pipeline/postcode/centroid-fills.d.ts.map +1 -1
  770. package/out/gazetteer-pipeline/postcode/centroid-fills.js +147 -40
  771. package/out/gazetteer-pipeline/postcode/centroid-fills.js.map +1 -1
  772. package/out/gazetteer-pipeline/postcode/codepoint/extract.d.ts +116 -0
  773. package/out/gazetteer-pipeline/postcode/codepoint/extract.d.ts.map +1 -0
  774. package/out/gazetteer-pipeline/postcode/codepoint/extract.js +122 -0
  775. package/out/gazetteer-pipeline/postcode/codepoint/extract.js.map +1 -0
  776. package/out/gazetteer-pipeline/postcode/codepoint/fetch.d.ts +248 -0
  777. package/out/gazetteer-pipeline/postcode/codepoint/fetch.d.ts.map +1 -0
  778. package/out/gazetteer-pipeline/postcode/codepoint/fetch.js +249 -0
  779. package/out/gazetteer-pipeline/postcode/codepoint/fetch.js.map +1 -0
  780. package/out/gazetteer-pipeline/postcode/codepoint/index.d.ts +13 -0
  781. package/out/gazetteer-pipeline/postcode/codepoint/index.d.ts.map +1 -0
  782. package/out/gazetteer-pipeline/postcode/codepoint/index.js +13 -0
  783. package/out/gazetteer-pipeline/postcode/codepoint/index.js.map +1 -0
  784. package/out/gazetteer-pipeline/postcode/codepoint/parse.d.ts +167 -0
  785. package/out/gazetteer-pipeline/postcode/codepoint/parse.d.ts.map +1 -0
  786. package/out/gazetteer-pipeline/postcode/codepoint/parse.js +195 -0
  787. package/out/gazetteer-pipeline/postcode/codepoint/parse.js.map +1 -0
  788. package/out/gazetteer-pipeline/postcode/codepoint-gate.d.ts +223 -0
  789. package/out/gazetteer-pipeline/postcode/codepoint-gate.d.ts.map +1 -0
  790. package/out/gazetteer-pipeline/postcode/codepoint-gate.js +266 -0
  791. package/out/gazetteer-pipeline/postcode/codepoint-gate.js.map +1 -0
  792. package/out/gazetteer-pipeline/postcode/codepoint-shard.d.ts +101 -0
  793. package/out/gazetteer-pipeline/postcode/codepoint-shard.d.ts.map +1 -0
  794. package/out/gazetteer-pipeline/postcode/codepoint-shard.js +312 -0
  795. package/out/gazetteer-pipeline/postcode/codepoint-shard.js.map +1 -0
  796. package/out/gazetteer-pipeline/postcode/geonames-tail.d.ts +120 -0
  797. package/out/gazetteer-pipeline/postcode/geonames-tail.d.ts.map +1 -0
  798. package/out/gazetteer-pipeline/postcode/geonames-tail.js +233 -0
  799. package/out/gazetteer-pipeline/postcode/geonames-tail.js.map +1 -0
  800. package/out/gazetteer-pipeline/postcode/index.d.ts +2 -0
  801. package/out/gazetteer-pipeline/postcode/index.d.ts.map +1 -1
  802. package/out/gazetteer-pipeline/postcode/index.js +2 -0
  803. package/out/gazetteer-pipeline/postcode/index.js.map +1 -1
  804. package/out/gazetteer-pipeline/postcode/ni-osm/fetch.d.ts +243 -0
  805. package/out/gazetteer-pipeline/postcode/ni-osm/fetch.d.ts.map +1 -0
  806. package/out/gazetteer-pipeline/postcode/ni-osm/fetch.js +245 -0
  807. package/out/gazetteer-pipeline/postcode/ni-osm/fetch.js.map +1 -0
  808. package/out/gazetteer-pipeline/postcode/ni-osm/index.d.ts +11 -0
  809. package/out/gazetteer-pipeline/postcode/ni-osm/index.d.ts.map +1 -0
  810. package/out/gazetteer-pipeline/postcode/ni-osm/index.js +11 -0
  811. package/out/gazetteer-pipeline/postcode/ni-osm/index.js.map +1 -0
  812. package/out/gazetteer-pipeline/postcode/ni-osm/parse.d.ts +119 -0
  813. package/out/gazetteer-pipeline/postcode/ni-osm/parse.d.ts.map +1 -0
  814. package/out/gazetteer-pipeline/postcode/ni-osm/parse.js +128 -0
  815. package/out/gazetteer-pipeline/postcode/ni-osm/parse.js.map +1 -0
  816. package/out/gazetteer-pipeline/postcode/ni-osm-shard.d.ts +143 -0
  817. package/out/gazetteer-pipeline/postcode/ni-osm-shard.d.ts.map +1 -0
  818. package/out/gazetteer-pipeline/postcode/ni-osm-shard.js +376 -0
  819. package/out/gazetteer-pipeline/postcode/ni-osm-shard.js.map +1 -0
  820. package/out/gazetteer-pipeline/postcode/nl-pc6.d.ts.map +1 -1
  821. package/out/gazetteer-pipeline/postcode/nl-pc6.js +15 -12
  822. package/out/gazetteer-pipeline/postcode/nl-pc6.js.map +1 -1
  823. package/out/gazetteer-pipeline/postcode/zcta-centroids.d.ts +1 -1
  824. package/out/gazetteer-pipeline/postcode/zcta-centroids.d.ts.map +1 -1
  825. package/out/gazetteer-pipeline/postcode/zcta-centroids.js +5 -7
  826. package/out/gazetteer-pipeline/postcode/zcta-centroids.js.map +1 -1
  827. package/out/gazetteer-pipeline/postcode-locality/base.d.ts.map +1 -1
  828. package/out/gazetteer-pipeline/postcode-locality/base.js +5 -80
  829. package/out/gazetteer-pipeline/postcode-locality/base.js.map +1 -1
  830. package/out/gazetteer-pipeline/postcode-locality/jp.d.ts +2 -2
  831. package/out/gazetteer-pipeline/postcode-locality/jp.d.ts.map +1 -1
  832. package/out/gazetteer-pipeline/postcode-locality/jp.js +12 -94
  833. package/out/gazetteer-pipeline/postcode-locality/jp.js.map +1 -1
  834. package/out/gazetteer-pipeline/postcode-locality/kr.d.ts +1 -1
  835. package/out/gazetteer-pipeline/postcode-locality/kr.d.ts.map +1 -1
  836. package/out/gazetteer-pipeline/postcode-locality/kr.js +6 -95
  837. package/out/gazetteer-pipeline/postcode-locality/kr.js.map +1 -1
  838. package/out/gazetteer-pipeline/postcode-locality/tw.d.ts +2 -2
  839. package/out/gazetteer-pipeline/postcode-locality/tw.d.ts.map +1 -1
  840. package/out/gazetteer-pipeline/postcode-locality/tw.js +8 -12
  841. package/out/gazetteer-pipeline/postcode-locality/tw.js.map +1 -1
  842. package/out/gazetteer-pipeline/postcode-prefix.d.ts +113 -0
  843. package/out/gazetteer-pipeline/postcode-prefix.d.ts.map +1 -0
  844. package/out/gazetteer-pipeline/postcode-prefix.js +211 -0
  845. package/out/gazetteer-pipeline/postcode-prefix.js.map +1 -0
  846. package/out/gazetteer-pipeline/verify.d.ts.map +1 -1
  847. package/out/gazetteer-pipeline/verify.js +15 -11
  848. package/out/gazetteer-pipeline/verify.js.map +1 -1
  849. package/out/geocode-core.d.ts +37 -0
  850. package/out/geocode-core.d.ts.map +1 -1
  851. package/out/geocode-core.js +77 -34
  852. package/out/geocode-core.js.map +1 -1
  853. package/out/geocode-stream.d.ts +8 -1
  854. package/out/geocode-stream.d.ts.map +1 -1
  855. package/out/geocode-stream.js +10 -3
  856. package/out/geocode-stream.js.map +1 -1
  857. package/out/poi-intent.d.ts +3 -3
  858. package/out/poi-overpass.d.ts +1 -1
  859. package/out/poi-overpass.js +1 -1
  860. package/out/release-tools/publish-hf.d.ts +1 -1
  861. package/out/release-tools/publish-hf.d.ts.map +1 -1
  862. package/out/release-tools/publish-hf.js +7 -4
  863. package/out/release-tools/publish-hf.js.map +1 -1
  864. package/out/resolver-backend.d.ts +34 -9
  865. package/out/resolver-backend.d.ts.map +1 -1
  866. package/out/resolver-backend.js +59 -11
  867. package/out/resolver-backend.js.map +1 -1
  868. package/out/runtime-pipeline.d.ts +2 -2
  869. package/out/runtime-pipeline.d.ts.map +1 -1
  870. package/out/runtime-pipeline.js +1 -1
  871. package/out/test-kit/cli-spawn-lock.d.ts +29 -0
  872. package/out/test-kit/cli-spawn-lock.d.ts.map +1 -0
  873. package/out/test-kit/cli-spawn-lock.js +143 -0
  874. package/out/test-kit/cli-spawn-lock.js.map +1 -0
  875. package/out/tools/generate-clients.d.ts.map +1 -1
  876. package/out/tools/generate-clients.js +2 -5
  877. package/out/tools/generate-clients.js.map +1 -1
  878. package/package.json +41 -30
  879. package/poi-intent.ts +3 -3
  880. package/poi-overpass.ts +1 -1
  881. package/release-tools/publish-hf.ts +7 -4
  882. package/resolver-backend.ts +64 -11
  883. package/runtime-pipeline.ts +2 -1
  884. package/skills/mailwoman/SKILL.md +112 -0
  885. package/test-kit/cli-spawn-lock.ts +155 -0
  886. package/tools/generate-clients.ts +2 -5
  887. package/types/node.d.ts +1 -0
  888. package/eval-harness/gauntlet/cases/regression.ts +0 -2222
  889. package/out/eval-harness/gauntlet/cases/regression.d.ts +0 -44
  890. package/out/eval-harness/gauntlet/cases/regression.d.ts.map +0 -1
  891. package/out/eval-harness/gauntlet/cases/regression.js +0 -2177
  892. package/out/eval-harness/gauntlet/cases/regression.js.map +0 -1
package/README.md CHANGED
@@ -170,7 +170,7 @@ Programmatically, build a `WofSqlitePlaceLookup` backend (from
170
170
  `@mailwoman/resolver-wof-sqlite`), pass it to `createWOFResolver` (from `@mailwoman/resolver`),
171
171
  and hand the resolver to `createRuntimePipeline({ classifier, resolver })`. The resolved
172
172
  `result.tree` roots then carry a `wof:id` and coordinate. See
173
- [Getting started → Adding resolution](https://mailwoman.sister.software/articles/getting-started/)
173
+ [Getting started → Adding resolution](https://mailwoman.sister.software/docs/developers/get-started/install-and-first-parse)
174
174
  for the worked example.
175
175
 
176
176
  ## Architecture
@@ -210,7 +210,7 @@ package is the umbrella that wires them together as a single `npm install`.
210
210
  ## Related
211
211
 
212
212
  - [Documentation & blog](https://mailwoman.sister.software)
213
- - [What Mailwoman Is](https://mailwoman.sister.software/articles/concepts/what-mailwoman-is/)
213
+ - [What Mailwoman Is](https://mailwoman.sister.software/docs/developers/get-started/what-mailwoman-is)
214
214
  - [GitHub](https://github.com/sister-software/mailwoman)
215
215
 
216
216
  ## License
package/api-engine.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * `/api/batch`, `/api/resolve-tree`, `/api/reload` handlers, `AddressRouter`'s retired `/parse`
9
9
  * handler, and `HealthRouter`'s `/health` data block — onto the engine-agnostic `@mailwoman/api`
10
10
  * contract's live routes (`/v1/parse`, `/v1/geocode`, `/v1/batch`, `/v1/resolve`, `/v1/reload`).
11
- * `mailwoman/server/` is deleted (Task 2) — this file is its sole successor, a fresh port rather
11
+ * `mailwoman/server/` is deleted — this file is its sole successor, a fresh port rather
12
12
  * than a thin wrapper.
13
13
  *
14
14
  * `createServeEngine` builds the shared stack ONCE, at boot, instead of express's lazy
@@ -26,14 +26,14 @@
26
26
  */
27
27
 
28
28
  import { existsSync, readdirSync, readFileSync } from "node:fs"
29
- import { createRequire } from "node:module"
30
- import { join } from "node:path"
29
+ import { fileURLToPath } from "node:url"
31
30
 
32
31
  import type { BatchRow, GeocodeOutcome, HealthData, MailwomanAPIEngine, ResolveTreeOutcome } from "@mailwoman/api"
33
32
  import { recordTimed } from "@mailwoman/api-kit"
34
33
  import { decodeAsTuples, decodeAsXML } from "@mailwoman/core"
35
34
  import type { AddressTree } from "@mailwoman/core/decoder"
36
35
  import { $public } from "@mailwoman/core/env"
36
+ import { tryParsingJSON } from "@mailwoman/core/objects"
37
37
  import { deriveInputMode } from "@mailwoman/core/pipeline"
38
38
  import { classifyKindSync } from "@mailwoman/kind-classifier"
39
39
  import { computeQueryShape } from "@mailwoman/query-shape"
@@ -48,7 +48,13 @@ import {
48
48
  ShardProvider,
49
49
  } from "./geocode-core.ts"
50
50
  import { INTERP_RADIUS_CALIBRATION, interpCalibrationForRegion } from "./interp-calibration.ts"
51
- import { createResolverBackend, mailwomanDataRoot, resolveCandidateDBPath, wofShardPaths } from "./resolver-backend.ts"
51
+ import {
52
+ buildNoGazetteerMessage,
53
+ createResolverBackend,
54
+ mailwomanDataRoot,
55
+ resolveCandidateDBPath,
56
+ wofShardPaths,
57
+ } from "./resolver-backend.ts"
52
58
 
53
59
  /**
54
60
  * Default per-state shard root + interp calibration — mirrors the express server's defaults (`GeocodeRouter.ts`).
@@ -82,30 +88,13 @@ function wofPaths(): string[] {
82
88
 
83
89
  /**
84
90
  * #1009-style boot preflight message. Same shape as the drop-ins' (`photon/cli.ts`, `nominatim/cli.ts`) — a stranger's
85
- * first `mailwoman serve` must say exactly what data is missing and the one command that fixes it — adapted to this
86
- * package's own override (`MAILWOMAN_WOF_DB`, a comma-separated FTS shard list) alongside the shared
87
- * candidate-gazetteer fast path (`MAILWOMAN_CANDIDATE_DB`).
91
+ * first `mailwoman serve` must say exactly what data is missing and the one command that fixes it.
88
92
  */
89
93
  function buildPreflightMessage(): string {
90
- const conventionCandidate = join(DATA_ROOT, "wof", "candidate.db")
91
-
92
- return [
93
- "✗ no gazetteer data found — `mailwoman serve` needs a WOF SQLite distribution to geocode/resolve.",
94
- "",
95
- " Fastest path (worldwide resolution, ~1.4 GB, byte-range friendly):",
96
- ` mkdir -p ${join(DATA_ROOT, "wof")}`,
97
- ` curl -fSL https://public.sister.software/mailwoman/gazetteer/2026-07-07a/candidate.db \\`,
98
- ` -o ${conventionCandidate}`,
99
- "",
100
- " Then point `$MAILWOMAN_CANDIDATE_DB` at that file and re-run `serve`:",
101
- ` export MAILWOMAN_CANDIDATE_DB=${conventionCandidate}`,
102
- "",
103
- " Or point at your own gazetteer:",
104
- " $MAILWOMAN_WOF_DB=<path1,path2,...> (admin WOF SQLite shard(s) — the FTS backend)",
105
- " $MAILWOMAN_CANDIDATE_DB=<path> (candidate-table gazetteer — population-first, demo-parity)",
106
- "",
107
- " Docs: https://mailwoman.sister.software/docs",
108
- ].join("\n")
94
+ return buildNoGazetteerMessage({
95
+ dataRoot: DATA_ROOT,
96
+ docsPath: "/docs/developers/get-started/ten-minute-trial",
97
+ })
109
98
  }
110
99
 
111
100
  /**
@@ -120,7 +109,13 @@ function readModelCard(): Record<string, unknown> | null {
120
109
  }
121
110
 
122
111
  try {
123
- candidates.push(createRequire(import.meta.url).resolve("@mailwoman/neural-weights-en-us/model-card.json"))
112
+ // Native ESM resolution of the weights package's card. `@mailwoman/neural-weights-*` packages carry no `exports`
113
+ // map, so the subpath resolves as a plain file inside the package, and (unlike `node:module`'s
114
+ // `findPackageJSON`) `import.meta.resolve` realpaths through the workspace symlink — the same string the CJS
115
+ // `require.resolve` this replaced returned. It does NOT throw for a missing FILE inside a resolvable package,
116
+ // only for an unresolvable package; the `existsSync` below already gates every candidate, so that is a no-op
117
+ // here.
118
+ candidates.push(fileURLToPath(import.meta.resolve("@mailwoman/neural-weights-en-us/model-card.json")))
124
119
  } catch {
125
120
  /* package not resolvable from here — fall through */
126
121
  }
@@ -129,9 +124,13 @@ function readModelCard(): Record<string, unknown> | null {
129
124
 
130
125
  for (const p of candidates) {
131
126
  try {
132
- if (existsSync(p)) return JSON.parse(readFileSync(p, "utf8")) as Record<string, unknown>
127
+ if (existsSync(p)) {
128
+ const card = tryParsingJSON<Record<string, unknown>>(readFileSync(p, "utf8"))
129
+
130
+ if (card) return card
131
+ }
133
132
  } catch {
134
- /* unreadable / malformed — try the next candidate */
133
+ /* unreadable — try the next candidate */
135
134
  }
136
135
  }
137
136
 
@@ -325,7 +324,7 @@ export async function createServeEngine(): Promise<ServeEngine> {
325
324
  // `onnxruntime-node`'s `session.run()` blocks the JS thread rather than releasing to the libuv pool,
326
325
  // and `node:sqlite` reads are synchronous. The pool bought nothing but the appearance of tuning, so
327
326
  // it's a plain loop now. To actually parallelize, cross a thread boundary — see
328
- // `mailwoman/geocode-stream.ts`. Receipts: `docs/articles/plan/reference/performance.mdx`.
327
+ // `mailwoman/geocode-stream.ts`. Receipts: `docs/engineering/reference/performance.mdx`.
329
328
  const batch: MailwomanAPIEngine["batch"] = async (addresses, opts) => {
330
329
  // Decision A endpoint default: batch rows are the record register.
331
330
  const inputMode = opts?.inputMode ?? "formatted"
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The shared skeleton behind the drop-in CLIs — `mailwoman-libpostal`, `mailwoman-nominatim`,
7
+ * `mailwoman-photon`. All three are the same program with a different engine bolted in: dispatch
8
+ * `serve` / `openapi` off the first positional, boot the neural classifier with a friendly
9
+ * failure, (for the two geocoding drop-ins) locate a gazetteer with a friendly failure, then print
10
+ * a banner. Those pieces were copied between the three files, and the copies were being kept in
11
+ * sync BY HAND — nominatim/cli.ts said so in a comment ("same message shape as
12
+ * @mailwoman/photon's pre-flight (kept in lockstep)"). This module is the lockstep.
13
+ *
14
+ * WHY IT LIVES HERE and not in `@mailwoman/api-kit`, which already owns `printOpenAPIDocument` and
15
+ * `serveNode` and would otherwise be the obvious home: the preflights need `@mailwoman/neural` and
16
+ * this package's `resolver-backend`, and api-kit is engine-agnostic by charter. Splitting the
17
+ * skeleton across two packages to preserve that charter costs more than the duplication did. All
18
+ * three drop-ins already declare `mailwoman` as a dependency, so landing the whole thing here adds
19
+ * no dependency to anyone.
20
+ *
21
+ * WHY IT IS NOT IN `cli-kit/index.ts`: that barrel is the Pastel/Ink toolkit for
22
+ * `mailwoman/commands/*` and imports `ink` + `react`. The drop-ins are plain `parseArgs` scripts
23
+ * that render no UI, and `npx @mailwoman/libpostal serve` should not pay for a TUI runtime to
24
+ * start an HTTP server. Hence a standalone module with its own `mailwoman/cli-kit/dropin`
25
+ * subpath, deliberately NOT re-exported through the barrel.
26
+ */
27
+
28
+ import { existsSync } from "node:fs"
29
+ import { parseArgs } from "node:util"
30
+
31
+ import { NeuralAddressClassifier } from "@mailwoman/neural"
32
+
33
+ import {
34
+ buildNoGazetteerMessage,
35
+ mailwomanDataRoot,
36
+ resolveCandidateDBPath,
37
+ wofShardPaths,
38
+ } from "../resolver-backend.ts"
39
+
40
+ /**
41
+ * The docs page every drop-in's missing-gazetteer message points a stranger at (#1009). One constant so the three
42
+ * messages cannot drift onto different pages when the docs move.
43
+ */
44
+ const GAZETTEER_DOCS_PATH = "/docs/developers/get-started/ten-minute-trial"
45
+
46
+ /**
47
+ * Print an error and exit non-zero. Typed `never` so callers get definite-assignment narrowing after the call.
48
+ */
49
+ function fail(message: string): never {
50
+ console.error(message)
51
+
52
+ process.exit(1)
53
+ }
54
+
55
+ /**
56
+ * Parse the `openapi` subcommand's flags, validating `--flavor`. Exits 1 with the binary's usage line on a bad flavor.
57
+ *
58
+ * Returns the shape `printOpenAPIDocument` takes, so a drop-in's `openapi` command is this call plus building its app
59
+ * around a stub engine — which is what keeps the command pure route-table introspection that never boots a classifier
60
+ * or opens a gazetteer.
61
+ */
62
+ export function parseOpenAPIFlags(binaryName: string): { flavor?: string; out?: string } {
63
+ const { values } = parseArgs({
64
+ options: {
65
+ flavor: { type: "string", default: "3.1" },
66
+ out: { type: "string" },
67
+ },
68
+ allowPositionals: true,
69
+ })
70
+
71
+ if (values.flavor !== "3.1" && values.flavor !== "3.0") {
72
+ console.error(`✗ --flavor must be "3.1" or "3.0" (got "${values.flavor}")`)
73
+
74
+ fail(`Usage: ${binaryName} openapi [--flavor 3.1|3.0] [--out <path>]`)
75
+ }
76
+
77
+ return values
78
+ }
79
+
80
+ /**
81
+ * Load the en-US neural classifier, failing FRIENDLY (#1009).
82
+ *
83
+ * `resolveWeights` (`neural/weights.ts`) already names the exact fix command; this guard only keeps that message from
84
+ * being buried under an unhandled-rejection stack trace. Eager, so a missing-weights boot fails at startup rather than
85
+ * on the first request.
86
+ */
87
+ export async function loadClassifierOrExit(): Promise<NeuralAddressClassifier> {
88
+ try {
89
+ return await NeuralAddressClassifier.loadFromWeights({ locale: "en-US" })
90
+ } catch (error) {
91
+ return fail(`✗ ${error instanceof Error ? error.message : String(error)}`)
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Where a geocoding drop-in reads its places from.
97
+ */
98
+ export interface GazetteerPaths {
99
+ /**
100
+ * The candidate gazetteer (worldwide resolution), when one was found.
101
+ */
102
+ candidateDb: string | undefined
103
+ /**
104
+ * The WOF admin FTS shards that exist on disk.
105
+ */
106
+ wofPaths: string[]
107
+ /**
108
+ * The first shard — the admin DB the reverse geocoder opens. `undefined` when there are no shards.
109
+ */
110
+ adminDBPath: string | undefined
111
+ }
112
+
113
+ /**
114
+ * Locate the gazetteer for a geocoding drop-in, with both of the #1009 friendly failures:
115
+ *
116
+ * - An EXPLICIT `--candidate-db` that does not exist errors loudly. It must never silently fall back to whatever ambient
117
+ * data-root file happens to be present — a typo'd path would otherwise serve the wrong gazetteer without a word.
118
+ * - No candidate DB AND no shards prints the named-artifact message with the one command that fixes it, instead of
119
+ * letting the resolver throw its internal "resolveShards: at least one shard is required".
120
+ */
121
+ export function resolveGazetteerOrExit(candidateDBFlag: string | undefined): GazetteerPaths {
122
+ if (candidateDBFlag && !existsSync(candidateDBFlag)) {
123
+ fail(`✗ --candidate-db not found: ${candidateDBFlag}`)
124
+ }
125
+
126
+ const wofPaths = wofShardPaths().filter(existsSync)
127
+ // Candidate gazetteer = worldwide resolution (population-first ranking + global coverage + the FTS5-trigram typo
128
+ // fallback). --candidate-db, else $MAILWOMAN_CANDIDATE_DB, else the `<data-root>/wof/candidate.db` convention
129
+ // path. Absent → the admin FTS shards.
130
+ const candidateDb = resolveCandidateDBPath(candidateDBFlag)
131
+
132
+ if (!candidateDb && !wofPaths.length) {
133
+ fail(buildNoGazetteerMessage({ dataRoot: mailwomanDataRoot(), docsPath: GAZETTEER_DOCS_PATH }))
134
+ }
135
+
136
+ return { adminDBPath: wofPaths[0], candidateDb, wofPaths }
137
+ }
138
+
139
+ /**
140
+ * The `cors:` line of a drop-in's startup banner.
141
+ */
142
+ export function corsBannerLine(cors: boolean): string {
143
+ return ` cors: ${cors ? "enabled (Access-Control-Allow-Origin: *)" : "disabled (--no-cors)"}`
144
+ }
145
+
146
+ /**
147
+ * The `wof:` + `resolver:` lines of a geocoding drop-in's startup banner — which gazetteer the process actually opened,
148
+ * and (when it fell back to admin-only) the flag that widens it.
149
+ */
150
+ export function gazetteerBannerLines({ adminDBPath, candidateDb }: GazetteerPaths): string[] {
151
+ return [
152
+ ` wof: ${adminDBPath ?? "(none found — set MAILWOMAN_WOF_DB)"}`,
153
+ candidateDb
154
+ ? ` resolver: candidate gazetteer (worldwide) — ${candidateDb}`
155
+ : ` resolver: admin-only (US-optimized) — point --candidate-db / $MAILWOMAN_CANDIDATE_DB at a candidate gazetteer for worldwide`,
156
+ ]
157
+ }
158
+
159
+ /**
160
+ * A drop-in CLI's two subcommands.
161
+ */
162
+ export interface DropInCLI {
163
+ /**
164
+ * The binary name, for the usage message (e.g. `mailwoman-photon`).
165
+ */
166
+ binaryName: string
167
+ /**
168
+ * Usage lines for the subcommands, without the leading `Usage:` header.
169
+ */
170
+ usage: string[]
171
+ serve: () => Promise<void>
172
+ openapi: () => void
173
+ }
174
+
175
+ /**
176
+ * Dispatch a drop-in CLI's subcommand off the first positional.
177
+ *
178
+ * `strict: false` because the per-command parsers own their own flags — this pass only reads the positional. An unknown
179
+ * command exits 1; a bare invocation prints usage and exits 0.
180
+ */
181
+ export async function runDropInCLI({ binaryName, openapi, serve, usage }: DropInCLI): Promise<void> {
182
+ const command = parseArgs({ strict: false, allowPositionals: true }).positionals[0]
183
+
184
+ switch (command) {
185
+ case "serve":
186
+ await serve()
187
+ break
188
+ case "openapi":
189
+ openapi()
190
+ break
191
+ default:
192
+ console.error([`Usage: ${binaryName} <command>`, ...usage].join("\n"))
193
+ process.exit(command ? 1 : 0)
194
+ }
195
+ }
package/cli-kit/index.ts CHANGED
@@ -10,6 +10,7 @@
10
10
  * importable under node's type stripping (the dev `node →` exports condition).
11
11
  */
12
12
 
13
+ import { type PlacetypeRole, PlacetypeRoles } from "@mailwoman/core"
13
14
  import { Box, Text } from "ink"
14
15
  import { createElement as h, useEffect, useState } from "react"
15
16
  import type * as React from "react"
@@ -129,3 +130,29 @@ export function CheckList({ checks, verdict }: { checks: readonly Check[]; verdi
129
130
 
130
131
  return h(Box, { flexDirection: "column" }, ...lines, summary)
131
132
  }
133
+
134
+ /**
135
+ * Parse a `--roles a,b,c` flag into validated {@link PlacetypeRole}s, or `undefined` when the flag is absent (which
136
+ * every caller reads as "all roles").
137
+ *
138
+ * Rejects an unknown role with {@link commandError} rather than silently filtering it — a typo in a role name would
139
+ * otherwise produce an empty, entirely plausible-looking result.
140
+ */
141
+ export function parseRoles(raw: string | undefined): PlacetypeRole[] | undefined {
142
+ if (!raw) return undefined
143
+
144
+ const valid = new Set<string>(PlacetypeRoles)
145
+
146
+ const parsed = raw
147
+ .split(",")
148
+ .map((s) => s.trim())
149
+ .filter(Boolean)
150
+
151
+ for (const role of parsed) {
152
+ if (!valid.has(role)) {
153
+ throw commandError(`Unknown placetype role '${role}'. Valid roles: ${PlacetypeRoles.join(", ")}.`)
154
+ }
155
+ }
156
+
157
+ return parsed as PlacetypeRole[]
158
+ }
package/cli.ts CHANGED
@@ -8,14 +8,15 @@
8
8
 
9
9
  import { readFileSync } from "node:fs"
10
10
 
11
+ import { parseJSONStrict } from "@mailwoman/core/objects"
11
12
  import Pastel from "pastel"
12
13
 
13
14
  // Read the real version from this package's package.json rather than hardcoding it (it drifted to
14
15
  // 0.1.0 while the package shipped 4.x). `import.meta.url` points at the compiled out/cli.js, so
15
16
  // `../package.json` resolves to the installed package root in every layout (dev, tarball, global).
16
- const { version } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as {
17
- version: string
18
- }
17
+ const { version } = parseJSONStrict<{ version: string }>(
18
+ readFileSync(new URL("../package.json", import.meta.url), "utf8")
19
+ )
19
20
 
20
21
  const app = new Pastel({
21
22
  importMeta: import.meta,
@@ -19,13 +19,16 @@ import { readFileSync } from "node:fs"
19
19
 
20
20
  import { $public } from "@mailwoman/core/env"
21
21
  import { Text } from "ink"
22
+ import { argument } from "pastel"
22
23
  import zod from "zod"
23
24
 
24
25
  import { type CommandComponent, commandError, useCommandTask } from "../cli-kit/index.ts"
25
26
 
26
27
  export { ArgumentsSchema as args, AutocompleteConfigSchema as options }
27
28
 
28
- const ArgumentsSchema = zod.array(zod.string().describe("Prefix string to complete"))
29
+ const ArgumentsSchema = zod
30
+ .array(zod.string())
31
+ .describe(argument({ name: "prefix", description: "Prefix string to complete" }))
29
32
 
30
33
  /**
31
34
  * Config accepted by `mailwoman autocomplete`, validated before the server starts so a bad flag fails fast.
@@ -9,8 +9,8 @@
9
9
  * `feat/api-clients` branch) and a Rust crate (progenitor `generate_api!`, the salvaged Cargo.toml
10
10
  * / lib.rs pattern), then VERIFY both actually build (`uv build` + a wheel import-check, `cargo
11
11
  * check --examples`). Output lands under the gitignored `clients-build/` — nothing generated here
12
- * is committed. This is the local, receipt-verified proof the gated CI job (Phase 5 Task 4)
13
- * replays on dispatch. See `docs/articles/api.mdx` "Client libraries" for install/usage snippets
12
+ * is committed. This is the local, receipt-verified proof the gated CI job replays on dispatch.
13
+ * See `docs/articles/api.mdx` "Client libraries" for install/usage snippets
14
14
  * and the not-yet-published status.
15
15
  */
16
16
 
@@ -14,6 +14,7 @@
14
14
  * the CLI handles partial builds during development.
15
15
  */
16
16
 
17
+ import { parseJSONStrict } from "@mailwoman/core/objects"
17
18
  import { buildCorpus, defaultAdapterRegistry, type BuildStage } from "@mailwoman/corpus"
18
19
  import type { AdapterOptions } from "@mailwoman/corpus/types"
19
20
  import { Box, Text } from "ink"
@@ -72,7 +73,7 @@ const CorpusBuild: CommandComponent<typeof BuildConfigSchema> = ({ options }) =>
72
73
  let inputsParsed: Record<string, zod.infer<typeof AdapterInputSchema>>
73
74
 
74
75
  try {
75
- inputsParsed = InputsSchema.parse(JSON.parse(options.inputs))
76
+ inputsParsed = InputsSchema.parse(parseJSONStrict(options.inputs))
76
77
  } catch (error) {
77
78
  throw commandError(`invalid --inputs JSON: ${(error as Error).message}`)
78
79
  }
@@ -17,9 +17,11 @@ import {
17
17
  fetchNAD,
18
18
  fetchNPPES,
19
19
  fetchOpenAddresses,
20
+ fetchOurAirports,
20
21
  fetchStateHISchools,
21
22
  fetchStateSources,
22
23
  fetchTigerFull,
24
+ fetchWikidataSubVenue,
23
25
  } from "@mailwoman/corpus/tools"
24
26
  import { Text } from "ink"
25
27
  import { argument } from "pastel"
@@ -36,14 +38,17 @@ const ArgsSchema = zod.tuple([
36
38
  "imls-pls",
37
39
  "nppes",
38
40
  "openaddresses",
41
+ "ourairports",
39
42
  "state-sources",
40
43
  "state-hi-schools",
41
44
  "tiger-full",
45
+ "wikidata-subvenue",
42
46
  ])
43
47
  .describe(
44
48
  argument({
45
49
  name: "source",
46
- description: "Fetch source id (ban, nad, hrsa, imls-pls, nppes, openaddresses, state-sources, …)",
50
+ description:
51
+ "Fetch source id (ban, nad, hrsa, imls-pls, nppes, openaddresses, ourairports, state-sources, wikidata-subvenue, …)",
47
52
  })
48
53
  ),
49
54
  ])
@@ -107,6 +112,10 @@ function runSource(source: FetchSourceID, options: Options): Promise<FetchSummar
107
112
  return fetchNPPES(base, report)
108
113
  case "openaddresses":
109
114
  return fetchOpenAddresses({ ...base, country: options.country }, report)
115
+ case "ourairports":
116
+ return fetchOurAirports(base, report)
117
+ case "wikidata-subvenue":
118
+ return fetchWikidataSubVenue(base, report)
110
119
  case "state-sources":
111
120
  return fetchStateSources(base, report)
112
121
  case "state-hi-schools":
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `mailwoman corpus golden-relabel` — move a golden answer-key version onto the corpus's US
7
+ * street-suffix convention (folded `street` → `street` + `street_suffix`). Writes a NEW version
8
+ * dir plus a review deck; the parent version is read-only. See
9
+ * `corpus/src/tools/golden-relabel-street.ts` for what it changes and, more importantly, what it
10
+ * refuses to.
11
+ */
12
+
13
+ import { Text } from "ink"
14
+ import zod from "zod"
15
+
16
+ import { type CommandComponent, useCommandTask } from "../../cli-kit/index.ts"
17
+
18
+ const OptionsSchema = zod.object({
19
+ input: zod.string().describe("Parent golden version dir (read-only), e.g. data/eval/golden/v0.1.2"),
20
+ output: zod.string().describe("Output golden version dir, e.g. data/eval/golden/v0.1.3"),
21
+ deck: zod.string().optional().describe("Review-deck JSONL path. Default <output>/REVIEW-DECK.jsonl"),
22
+ commit: zod.string().optional().describe("Commit SHA recorded as tool provenance in the manifest"),
23
+ splitPrefix: zod
24
+ .boolean()
25
+ .default(true)
26
+ .describe("Also lift a folded leading directional into street_prefix. --no-split-prefix measures the fold's cost"),
27
+ })
28
+
29
+ export { OptionsSchema as options }
30
+
31
+ const Cmd: CommandComponent<typeof OptionsSchema> = ({ options }) => {
32
+ const state = useCommandTask(async () => {
33
+ const { relabelGoldenDirectory } = await import("@mailwoman/corpus/tools")
34
+
35
+ const report = await relabelGoldenDirectory({
36
+ input: options.input,
37
+ output: options.output,
38
+ ...(options.deck ? { deck: options.deck } : {}),
39
+ ...(options.commit ? { commit: options.commit } : {}),
40
+ splitPrefix: options.splitPrefix,
41
+ })
42
+
43
+ return `${report.totalChanged} rows split, ${report.totalFlagged} flagged → ${report.outputDir}`
44
+ })
45
+
46
+ if (state.status === "error") return <Text color="red">✗ {state.message}</Text>
47
+
48
+ if (state.status === "done") return <Text color="green">✓ {state.result}</Text>
49
+
50
+ return null
51
+ }
52
+
53
+ export default Cmd
@@ -16,7 +16,12 @@ const OptionsSchema = zod.object({
16
16
  base: zod.string().describe("Base corpus manifest path"),
17
17
  newDir: zod.string().describe("New overlay corpus dir"),
18
18
  modalRoot: zod.string().describe("Modal volume root the manifest paths are relative to"),
19
- version: zod.string().describe("New corpus version"),
19
+ // NOT `version`: Pastel registers `-v, --version` on the ROOT program, and commander resolves it
20
+ // before the subcommand's own options, so `--version 9.9.9` printed the CLI version (8.7.0) and
21
+ // exited 0 without ever running the tool (#1491). Pastel decamelizes the key, so this derives
22
+ // `--corpus-version`. `mailwoman/test/command-option-collisions.test.ts` keeps the whole command
23
+ // tree off the reserved names.
24
+ corpusVersion: zod.string().describe("New corpus version"),
20
25
  shardParquet: zod.string().describe("The ONE shard parquet to add"),
21
26
  source: zod.string().describe("Shard source label"),
22
27
  note: zod.string().describe("Manifest note"),
@@ -32,7 +37,7 @@ const Cmd: CommandComponent<typeof OptionsSchema> = ({ options }) => {
32
37
  base: options.base,
33
38
  newDir: options.newDir,
34
39
  modalRoot: options.modalRoot,
35
- version: options.version,
40
+ version: options.corpusVersion,
36
41
  shardParquet: options.shardParquet,
37
42
  source: options.source,
38
43
  note: options.note,
@@ -64,6 +64,14 @@ const OptionsSchema = zod.object({
64
64
  .optional()
65
65
  .describe("fr-fragment: REQUIRED — reserved street-surface list to exclude (the fragment board's eval set)"),
66
66
  multilocaleCount: zod.string().optional().describe("street-affix: multilocale row count"),
67
+ lexicon: zod.string().optional().describe("sub-venue: lexicon JSON (default: the committed corpus/data one)"),
68
+ extractsDir: zod.string().optional().describe("sub-venue: OSM sub-venue extract JSONL directory"),
69
+ poiDb: zod.string().optional().describe("sub-venue: poi.db path (en-US / fr-FR venue + confound pools)"),
70
+ subVenueTuples: zod.string().optional().describe("sub-venue: GB/US/FR address-context tuples JSONL"),
71
+ negativeFraction: zod
72
+ .string()
73
+ .optional()
74
+ .describe("sub-venue: share of rows that are confound negatives (default 0.3)"),
67
75
  })
68
76
 
69
77
  export { ArgumentsSchema as args, OptionsSchema as options }
@@ -119,6 +127,11 @@ const CorpusShard: CommandComponent<typeof OptionsSchema, typeof ArgumentsSchema
119
127
  banDir: options.banDir,
120
128
  excludeSurfaces: options.excludeSurfaces,
121
129
  multilocaleCount: num(options.multilocaleCount),
130
+ lexicon: options.lexicon,
131
+ extractsDir: options.extractsDir,
132
+ poiDb: options.poiDb,
133
+ subVenueTuples: options.subVenueTuples,
134
+ negativeFraction: num(options.negativeFraction),
122
135
  }
123
136
 
124
137
  console.error(`▸ shard recipe "${name}" [${recipe.mode}] seed=${seed} → ${options.output}`)
@@ -138,7 +151,7 @@ const CorpusShard: CommandComponent<typeof OptionsSchema, typeof ArgumentsSchema
138
151
 
139
152
  return [
140
153
  `recipe: ${name}`,
141
- `${stats.emitted.toLocaleString()} rows emitted, ${stats.skipped.toLocaleString()} skipped${stats.read != null ? `, ${stats.read.toLocaleString()} read` : ""} → ${options.output}`,
154
+ `${stats.emitted.toLocaleString()} rows emitted, ${stats.skipped.toLocaleString()} skipped${stats.read != null ? `, ${stats.read.toLocaleString()} read` : ""}${stats.contaminated ? `, ${stats.contaminated.toLocaleString()} board-reserved` : ""} → ${options.output}`,
142
155
  ]
143
156
  })
144
157
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * `mailwoman corpus shard kryptonite` — build a parquet shard from the DeepSeek-generated
7
7
  * kryptonite JSONL and emit the combined corpus MANIFEST (base shards + the new shard). See
8
- * docs/articles/plan/reference/CORPUS_V0_4_0_GENERATION.md for the reproducibility contract.
8
+ * docs/engineering/reference/CORPUS_V0_4_0_GENERATION.md for the reproducibility contract.
9
9
  */
10
10
 
11
11
  import { buildKryptoniteShard } from "@mailwoman/corpus/tools"
@@ -6,7 +6,7 @@
6
6
  * `mailwoman corpus shard translit` — build per-script parquet shards from the DeepSeek-generated
7
7
  * transliteration JSONL (one shard per `deepseek-translit-<slug>` source) and emit the combined
8
8
  * corpus MANIFEST. Sibling of `corpus shard kryptonite`; also canonicalizes legacy base-shard
9
- * paths (`/mnt/playpen/mailwoman-data/…` → `/data/…`).
9
+ * paths (`$MAILWOMAN_DATA_ROOT/…` → `/data/…`).
10
10
  */
11
11
 
12
12
  import { buildTranslitShard } from "@mailwoman/corpus/tools"
@@ -23,8 +23,9 @@ const OptionsSchema = zod.object({
23
23
  canonicalPathPrefix: zod.string().default("/data/").describe("Prefix replacing legacy base-shard paths"),
24
24
  legacyPathPrefix: zod
25
25
  .string()
26
- .default("/mnt/playpen/mailwoman-data/")
27
- .describe("Legacy base-shard path prefix to rewrite"),
26
+
27
+ .optional()
28
+ .describe("Legacy base-shard path prefix to rewrite (default: $MAILWOMAN_DATA_ROOT)"),
28
29
  })
29
30
 
30
31
  export { OptionsSchema as options }