@mailwoman/corpus 8.0.0 → 8.2.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.
- package/out/src/adapter.d.ts +15 -5
- package/out/src/adapter.d.ts.map +1 -1
- package/out/src/adapter.js +11 -9
- package/out/src/adapter.js.map +1 -1
- package/out/src/adapters/ban/adapter.d.ts +7 -0
- package/out/src/adapters/ban/adapter.d.ts.map +1 -1
- package/out/src/adapters/ban/adapter.js +9 -2
- package/out/src/adapters/ban/adapter.js.map +1 -1
- package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
- package/out/src/adapters/ban/street-decompose.js +5 -1
- package/out/src/adapters/ban/street-decompose.js.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts +14 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.js +15 -2
- package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
- package/out/src/adapters/geonames/adapter.d.ts +11 -0
- package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames/adapter.js +24 -5
- package/out/src/adapters/geonames/adapter.js.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.d.ts +11 -0
- package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.js +14 -1
- package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/adapter.d.ts +10 -1
- package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
- package/out/src/adapters/gnaf/adapter.js +11 -2
- package/out/src/adapters/gnaf/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/assemble.d.ts +18 -6
- package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
- package/out/src/adapters/gnaf/assemble.js +16 -6
- package/out/src/adapters/gnaf/assemble.js.map +1 -1
- package/out/src/adapters/index.d.ts.map +1 -1
- package/out/src/adapters/index.js.map +1 -1
- package/out/src/adapters/openaddresses/adapter.d.ts +11 -0
- package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
- package/out/src/adapters/openaddresses/adapter.js +18 -3
- package/out/src/adapters/openaddresses/adapter.js.map +1 -1
- package/out/src/adapters/overture/adapter.d.ts +11 -0
- package/out/src/adapters/overture/adapter.d.ts.map +1 -1
- package/out/src/adapters/overture/adapter.js +12 -1
- package/out/src/adapters/overture/adapter.js.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.d.ts +11 -0
- package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.js +11 -0
- package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.d.ts +11 -0
- package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.js +11 -0
- package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.d.ts +11 -0
- package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.js +11 -0
- package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.d.ts +11 -0
- package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.js +15 -2
- package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.d.ts +11 -0
- package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.js +13 -2
- package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
- package/out/src/adapters/tiger/adapter.d.ts +14 -1
- package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
- package/out/src/adapters/tiger/adapter.js +19 -4
- package/out/src/adapters/tiger/adapter.js.map +1 -1
- package/out/src/adapters/tiger/street-decompose.d.ts.map +1 -1
- package/out/src/adapters/tiger/street-decompose.js.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +12 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.js +11 -0
- package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.js +17 -2
- package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.js +12 -1
- package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.js +11 -0
- package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +15 -2
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.d.ts +7 -0
- package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.js +18 -3
- package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.d.ts +13 -3
- package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.js +15 -5
- package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts +7 -0
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.js +9 -2
- package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
- package/out/src/align.d.ts +12 -4
- package/out/src/align.d.ts.map +1 -1
- package/out/src/align.js +9 -5
- package/out/src/align.js.map +1 -1
- package/out/src/build.d.ts +24 -8
- package/out/src/build.d.ts.map +1 -1
- package/out/src/build.js +3 -3
- package/out/src/build.js.map +1 -1
- package/out/src/codex/us-fips-state.d.ts +6 -2
- package/out/src/codex/us-fips-state.d.ts.map +1 -1
- package/out/src/codex/us-fips-state.js +3 -1
- package/out/src/codex/us-fips-state.js.map +1 -1
- package/out/src/golden.d.ts +21 -7
- package/out/src/golden.d.ts.map +1 -1
- package/out/src/golden.js +18 -10
- package/out/src/golden.js.map +1 -1
- package/out/src/license.d.ts +3 -1
- package/out/src/license.d.ts.map +1 -1
- package/out/src/license.js +4 -2
- package/out/src/license.js.map +1 -1
- package/out/src/parquet-wrapper/reader.d.ts +4 -2
- package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
- package/out/src/parquet-wrapper/reader.js +5 -4
- package/out/src/parquet-wrapper/reader.js.map +1 -1
- package/out/src/parquet-wrapper/schema.d.ts +14 -10
- package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
- package/out/src/parquet-wrapper/schema.js +6 -2
- package/out/src/parquet-wrapper/schema.js.map +1 -1
- package/out/src/parquet-wrapper/writer.d.ts +12 -4
- package/out/src/parquet-wrapper/writer.d.ts.map +1 -1
- package/out/src/parquet-wrapper/writer.js +12 -4
- package/out/src/parquet-wrapper/writer.js.map +1 -1
- package/out/src/parquet.d.ts +21 -7
- package/out/src/parquet.d.ts.map +1 -1
- package/out/src/parquet.js +15 -4
- package/out/src/parquet.js.map +1 -1
- package/out/src/runner.d.ts +39 -13
- package/out/src/runner.d.ts.map +1 -1
- package/out/src/runner.js +7 -3
- package/out/src/runner.js.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.d.ts +4 -0
- package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.js +14 -5
- package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
- package/out/src/shard-recipes/boundary-stress.d.ts +4 -0
- package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
- package/out/src/shard-recipes/boundary-stress.js +13 -7
- package/out/src/shard-recipes/boundary-stress.js.map +1 -1
- package/out/src/shard-recipes/country-balanced.d.ts +4 -0
- package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
- package/out/src/shard-recipes/country-balanced.js +39 -11
- package/out/src/shard-recipes/country-balanced.js.map +1 -1
- package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts +4 -0
- package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts.map +1 -1
- package/out/src/shard-recipes/cz-pcfirst-preposition.js +4 -0
- package/out/src/shard-recipes/cz-pcfirst-preposition.js.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.d.ts +4 -0
- package/out/src/shard-recipes/fr-admin-split.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.js +14 -3
- package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
- package/out/src/shard-recipes/fr-bare-street.d.ts +4 -0
- package/out/src/shard-recipes/fr-bare-street.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-bare-street.js +4 -0
- package/out/src/shard-recipes/fr-bare-street.js.map +1 -1
- package/out/src/shard-recipes/fr-fragment.d.ts +4 -0
- package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-fragment.js +25 -8
- package/out/src/shard-recipes/fr-fragment.js.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.d.ts +4 -0
- package/out/src/shard-recipes/fr-lieudit.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.js +21 -8
- package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
- package/out/src/shard-recipes/fr-order.d.ts +4 -0
- package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-order.js +27 -8
- package/out/src/shard-recipes/fr-order.js.map +1 -1
- package/out/src/shard-recipes/german.d.ts +4 -0
- package/out/src/shard-recipes/german.d.ts.map +1 -1
- package/out/src/shard-recipes/german.js +16 -6
- package/out/src/shard-recipes/german.js.map +1 -1
- package/out/src/shard-recipes/house-venue.d.ts +4 -0
- package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
- package/out/src/shard-recipes/house-venue.js +4 -0
- package/out/src/shard-recipes/house-venue.js.map +1 -1
- package/out/src/shard-recipes/index.d.ts +9 -3
- package/out/src/shard-recipes/index.d.ts.map +1 -1
- package/out/src/shard-recipes/index.js +12 -4
- package/out/src/shard-recipes/index.js.map +1 -1
- package/out/src/shard-recipes/intersection.d.ts +4 -0
- package/out/src/shard-recipes/intersection.d.ts.map +1 -1
- package/out/src/shard-recipes/intersection.js +27 -13
- package/out/src/shard-recipes/intersection.js.map +1 -1
- package/out/src/shard-recipes/locale.d.ts +4 -0
- package/out/src/shard-recipes/locale.d.ts.map +1 -1
- package/out/src/shard-recipes/locale.js +9 -4
- package/out/src/shard-recipes/locale.js.map +1 -1
- package/out/src/shard-recipes/nl-postcode.d.ts +4 -0
- package/out/src/shard-recipes/nl-postcode.d.ts.map +1 -1
- package/out/src/shard-recipes/nl-postcode.js +8 -2
- package/out/src/shard-recipes/nl-postcode.js.map +1 -1
- package/out/src/shard-recipes/no-fragment.d.ts +4 -0
- package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
- package/out/src/shard-recipes/no-fragment.js +8 -2
- package/out/src/shard-recipes/no-fragment.js.map +1 -1
- package/out/src/shard-recipes/no-street-led.d.ts +4 -0
- package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street-led.js +5 -1
- package/out/src/shard-recipes/no-street-led.js.map +1 -1
- package/out/src/shard-recipes/no-street.d.ts +4 -0
- package/out/src/shard-recipes/no-street.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street.js +4 -0
- package/out/src/shard-recipes/no-street.js.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.d.ts +4 -0
- package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.js +99 -43
- package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
- package/out/src/shard-recipes/po-box.d.ts +4 -0
- package/out/src/shard-recipes/po-box.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box.js +4 -0
- package/out/src/shard-recipes/po-box.js.map +1 -1
- package/out/src/shard-recipes/scaffold.d.ts +48 -16
- package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
- package/out/src/shard-recipes/scaffold.js +10 -6
- package/out/src/shard-recipes/scaffold.js.map +1 -1
- package/out/src/shard-recipes/si-bare-village.d.ts +4 -0
- package/out/src/shard-recipes/si-bare-village.d.ts.map +1 -1
- package/out/src/shard-recipes/si-bare-village.js +4 -0
- package/out/src/shard-recipes/si-bare-village.js.map +1 -1
- package/out/src/shard-recipes/street-affix.d.ts +4 -0
- package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
- package/out/src/shard-recipes/street-affix.js +29 -10
- package/out/src/shard-recipes/street-affix.js.map +1 -1
- package/out/src/shard-recipes/street-bare.d.ts +4 -0
- package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
- package/out/src/shard-recipes/street-bare.js +4 -0
- package/out/src/shard-recipes/street-bare.js.map +1 -1
- package/out/src/shard-recipes/street.d.ts +4 -0
- package/out/src/shard-recipes/street.d.ts.map +1 -1
- package/out/src/shard-recipes/street.js +4 -0
- package/out/src/shard-recipes/street.js.map +1 -1
- package/out/src/shard-recipes/unit.d.ts +4 -0
- package/out/src/shard-recipes/unit.d.ts.map +1 -1
- package/out/src/shard-recipes/unit.js +45 -14
- package/out/src/shard-recipes/unit.js.map +1 -1
- package/out/src/split.d.ts +18 -6
- package/out/src/split.d.ts.map +1 -1
- package/out/src/split.js +4 -2
- package/out/src/split.js.map +1 -1
- package/out/src/synthesize-anchor-absorption.d.ts +7 -1
- package/out/src/synthesize-anchor-absorption.d.ts.map +1 -1
- package/out/src/synthesize-anchor-absorption.js +28 -14
- package/out/src/synthesize-anchor-absorption.js.map +1 -1
- package/out/src/synthesize-boundary-stress.d.ts +3 -1
- package/out/src/synthesize-boundary-stress.d.ts.map +1 -1
- package/out/src/synthesize-boundary-stress.js +35 -28
- package/out/src/synthesize-boundary-stress.js.map +1 -1
- package/out/src/synthesize-german.d.ts +15 -5
- package/out/src/synthesize-german.d.ts.map +1 -1
- package/out/src/synthesize-german.js +9 -3
- package/out/src/synthesize-german.js.map +1 -1
- package/out/src/synthesize-house-venue.d.ts.map +1 -1
- package/out/src/synthesize-house-venue.js +15 -15
- package/out/src/synthesize-house-venue.js.map +1 -1
- package/out/src/synthesize-intersection.d.ts +9 -3
- package/out/src/synthesize-intersection.d.ts.map +1 -1
- package/out/src/synthesize-intersection.js +25 -6
- package/out/src/synthesize-intersection.js.map +1 -1
- package/out/src/synthesize-no-street.d.ts +3 -1
- package/out/src/synthesize-no-street.d.ts.map +1 -1
- package/out/src/synthesize-no-street.js +5 -6
- package/out/src/synthesize-no-street.js.map +1 -1
- package/out/src/synthesize-po-box.d.ts +15 -5
- package/out/src/synthesize-po-box.d.ts.map +1 -1
- package/out/src/synthesize-po-box.js +21 -7
- package/out/src/synthesize-po-box.js.map +1 -1
- package/out/src/synthesize-street.d.ts +3 -1
- package/out/src/synthesize-street.d.ts.map +1 -1
- package/out/src/synthesize-street.js +6 -1
- package/out/src/synthesize-street.js.map +1 -1
- package/out/src/synthesize.d.ts +39 -13
- package/out/src/synthesize.d.ts.map +1 -1
- package/out/src/synthesize.js +66 -36
- package/out/src/synthesize.js.map +1 -1
- package/out/src/tokenize.d.ts +15 -5
- package/out/src/tokenize.d.ts.map +1 -1
- package/out/src/tokenize.js.map +1 -1
- package/out/src/tools/align-shard.d.ts.map +1 -1
- package/out/src/tools/align-shard.js +3 -1
- package/out/src/tools/align-shard.js.map +1 -1
- package/out/src/tools/audit.d.ts.map +1 -1
- package/out/src/tools/audit.js +20 -8
- package/out/src/tools/audit.js.map +1 -1
- package/out/src/tools/corpus-stats.d.ts.map +1 -1
- package/out/src/tools/corpus-stats.js.map +1 -1
- package/out/src/tools/fetch/ban.d.ts.map +1 -1
- package/out/src/tools/fetch/ban.js +17 -10
- package/out/src/tools/fetch/ban.js.map +1 -1
- package/out/src/tools/fetch/download.d.ts +30 -10
- package/out/src/tools/fetch/download.d.ts.map +1 -1
- package/out/src/tools/fetch/download.js +26 -6
- package/out/src/tools/fetch/download.js.map +1 -1
- package/out/src/tools/fetch/hrsa.d.ts.map +1 -1
- package/out/src/tools/fetch/hrsa.js.map +1 -1
- package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
- package/out/src/tools/fetch/imls-pls.js +18 -18
- package/out/src/tools/fetch/imls-pls.js.map +1 -1
- package/out/src/tools/fetch/index.d.ts +3 -1
- package/out/src/tools/fetch/index.d.ts.map +1 -1
- package/out/src/tools/fetch/index.js +3 -1
- package/out/src/tools/fetch/index.js.map +1 -1
- package/out/src/tools/fetch/nad.d.ts +21 -7
- package/out/src/tools/fetch/nad.d.ts.map +1 -1
- package/out/src/tools/fetch/nad.js +5 -5
- package/out/src/tools/fetch/nad.js.map +1 -1
- package/out/src/tools/fetch/nppes.d.ts.map +1 -1
- package/out/src/tools/fetch/nppes.js +9 -15
- package/out/src/tools/fetch/nppes.js.map +1 -1
- package/out/src/tools/fetch/openaddresses.d.ts +3 -1
- package/out/src/tools/fetch/openaddresses.d.ts.map +1 -1
- package/out/src/tools/fetch/openaddresses.js +32 -23
- package/out/src/tools/fetch/openaddresses.js.map +1 -1
- package/out/src/tools/fetch/ppd.d.ts +3 -1
- package/out/src/tools/fetch/ppd.d.ts.map +1 -1
- package/out/src/tools/fetch/ppd.js +14 -3
- package/out/src/tools/fetch/ppd.js.map +1 -1
- package/out/src/tools/fetch/state-hi-schools.d.ts.map +1 -1
- package/out/src/tools/fetch/state-hi-schools.js +13 -6
- package/out/src/tools/fetch/state-hi-schools.js.map +1 -1
- package/out/src/tools/fetch/state-sources.d.ts.map +1 -1
- package/out/src/tools/fetch/state-sources.js +8 -3
- package/out/src/tools/fetch/state-sources.js.map +1 -1
- package/out/src/tools/fetch/tiger-full.d.ts +9 -3
- package/out/src/tools/fetch/tiger-full.d.ts.map +1 -1
- package/out/src/tools/fetch/tiger-full.js +35 -20
- package/out/src/tools/fetch/tiger-full.js.map +1 -1
- package/out/src/tools/gb-title-case.d.ts.map +1 -1
- package/out/src/tools/gb-title-case.js.map +1 -1
- package/out/src/tools/golden-expand.d.ts +24 -8
- package/out/src/tools/golden-expand.d.ts.map +1 -1
- package/out/src/tools/golden-expand.js +20 -12
- package/out/src/tools/golden-expand.js.map +1 -1
- package/out/src/tools/golden-promote.d.ts +18 -6
- package/out/src/tools/golden-promote.d.ts.map +1 -1
- package/out/src/tools/golden-promote.js +22 -7
- package/out/src/tools/golden-promote.js.map +1 -1
- package/out/src/tools/ingest-csv.d.ts +3 -1
- package/out/src/tools/ingest-csv.d.ts.map +1 -1
- package/out/src/tools/ingest-csv.js +17 -19
- package/out/src/tools/ingest-csv.js.map +1 -1
- package/out/src/tools/jsonl-to-parquet.d.ts +18 -6
- package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
- package/out/src/tools/jsonl-to-parquet.js +11 -5
- package/out/src/tools/jsonl-to-parquet.js.map +1 -1
- package/out/src/tools/lint-shard-vocab.d.ts +36 -12
- package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
- package/out/src/tools/lint-shard-vocab.js +25 -11
- package/out/src/tools/lint-shard-vocab.js.map +1 -1
- package/out/src/tools/lint-shard.d.ts +30 -10
- package/out/src/tools/lint-shard.d.ts.map +1 -1
- package/out/src/tools/lint-shard.js +33 -20
- package/out/src/tools/lint-shard.js.map +1 -1
- package/out/src/tools/overlay-manifest.d.ts.map +1 -1
- package/out/src/tools/overlay-manifest.js +6 -4
- package/out/src/tools/overlay-manifest.js.map +1 -1
- package/out/src/tools/shard-kryptonite.d.ts +6 -2
- package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
- package/out/src/tools/shard-kryptonite.js +1 -1
- package/out/src/tools/shard-kryptonite.js.map +1 -1
- package/out/src/tools/shard-translit.d.ts +9 -3
- package/out/src/tools/shard-translit.d.ts.map +1 -1
- package/out/src/tools/shard-translit.js +2 -2
- package/out/src/tools/shard-translit.js.map +1 -1
- package/out/src/types.d.ts +51 -17
- package/out/src/types.d.ts.map +1 -1
- package/out/src/wof-json.d.ts +9 -3
- package/out/src/wof-json.d.ts.map +1 -1
- package/out/src/wof-json.js +6 -4
- package/out/src/wof-json.js.map +1 -1
- package/package.json +7 -6
- package/src/adapter.ts +24 -13
- package/src/adapters/ban/adapter.ts +12 -2
- package/src/adapters/ban/street-decompose.ts +7 -1
- package/src/adapters/fcc-bdc/adapter.ts +19 -3
- package/src/adapters/geonames/adapter.ts +28 -5
- package/src/adapters/geonames-postal/adapter.ts +17 -1
- package/src/adapters/gnaf/adapter.ts +15 -2
- package/src/adapters/gnaf/assemble.ts +40 -10
- package/src/adapters/index.ts +13 -0
- package/src/adapters/openaddresses/adapter.ts +22 -3
- package/src/adapters/overture/adapter.ts +18 -2
- package/src/adapters/state-hi-schools/adapter.ts +15 -0
- package/src/adapters/state-ia-contractors/adapter.ts +15 -0
- package/src/adapters/state-ny-notaries/adapter.ts +15 -0
- package/src/adapters/state-tx-notaries/adapter.ts +18 -2
- package/src/adapters/synth-po-box/adapter.ts +19 -2
- package/src/adapters/tiger/adapter.ts +23 -4
- package/src/adapters/tiger/street-decompose.ts +1 -0
- package/src/adapters/usgov-hrsa-fqhc/adapter.ts +18 -2
- package/src/adapters/usgov-imls-pls/adapter.ts +15 -0
- package/src/adapters/usgov-irs-bmf/adapter.ts +19 -2
- package/src/adapters/usgov-nad/adapter.ts +14 -1
- package/src/adapters/usgov-nppes/adapter.ts +13 -0
- package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +21 -3
- package/src/adapters/wof-admin-jp/adapter.ts +20 -3
- package/src/adapters/wof-admin-json/adapter.ts +22 -7
- package/src/adapters/wof-postalcode-json/adapter.ts +10 -2
- package/src/align.ts +21 -8
- package/src/build.ts +48 -11
- package/src/codex/us-fips-state.ts +6 -2
- package/src/golden.ts +28 -13
- package/src/license.ts +4 -2
- package/src/parquet-wrapper/reader.ts +6 -4
- package/src/parquet-wrapper/schema.ts +14 -10
- package/src/parquet-wrapper/writer.ts +12 -4
- package/src/parquet.ts +39 -8
- package/src/runner.ts +49 -15
- package/src/shard-recipes/anchor-absorption.ts +21 -5
- package/src/shard-recipes/boundary-stress.ts +20 -7
- package/src/shard-recipes/country-balanced.ts +78 -13
- package/src/shard-recipes/cz-pcfirst-preposition.ts +9 -0
- package/src/shard-recipes/fr-admin-split.ts +30 -5
- package/src/shard-recipes/fr-bare-street.ts +10 -0
- package/src/shard-recipes/fr-fragment.ts +33 -8
- package/src/shard-recipes/fr-lieudit.ts +35 -9
- package/src/shard-recipes/fr-order.ts +47 -9
- package/src/shard-recipes/german.ts +32 -6
- package/src/shard-recipes/house-venue.ts +7 -0
- package/src/shard-recipes/index.ts +12 -4
- package/src/shard-recipes/intersection.ts +63 -14
- package/src/shard-recipes/locale.ts +37 -4
- package/src/shard-recipes/nl-postcode.ts +12 -2
- package/src/shard-recipes/no-fragment.ts +12 -2
- package/src/shard-recipes/no-street-led.ts +11 -1
- package/src/shard-recipes/no-street.ts +7 -0
- package/src/shard-recipes/po-box-cedex.ts +145 -45
- package/src/shard-recipes/po-box.ts +7 -0
- package/src/shard-recipes/scaffold.ts +52 -20
- package/src/shard-recipes/si-bare-village.ts +9 -0
- package/src/shard-recipes/street-affix.ts +88 -13
- package/src/shard-recipes/street-bare.ts +10 -0
- package/src/shard-recipes/street.ts +7 -0
- package/src/shard-recipes/unit.ts +79 -16
- package/src/split.ts +28 -7
- package/src/synthesize-anchor-absorption.ts +41 -14
- package/src/synthesize-boundary-stress.ts +57 -30
- package/src/synthesize-german.ts +30 -7
- package/src/synthesize-house-venue.ts +22 -16
- package/src/synthesize-intersection.ts +34 -7
- package/src/synthesize-no-street.ts +18 -10
- package/src/synthesize-po-box.ts +42 -10
- package/src/synthesize-street.ts +10 -2
- package/src/synthesize.ts +81 -38
- package/src/tokenize.ts +15 -5
- package/src/tools/align-shard.ts +6 -1
- package/src/tools/audit.ts +57 -11
- package/src/tools/corpus-stats.ts +9 -0
- package/src/tools/fetch/ban.ts +32 -10
- package/src/tools/fetch/download.ts +49 -12
- package/src/tools/fetch/hrsa.ts +3 -0
- package/src/tools/fetch/imls-pls.ts +28 -18
- package/src/tools/fetch/index.ts +3 -1
- package/src/tools/fetch/nad.ts +39 -12
- package/src/tools/fetch/nppes.ts +17 -15
- package/src/tools/fetch/openaddresses.ts +52 -24
- package/src/tools/fetch/ppd.ts +22 -3
- package/src/tools/fetch/state-hi-schools.ts +17 -6
- package/src/tools/fetch/state-sources.ts +16 -3
- package/src/tools/fetch/tiger-full.ts +66 -23
- package/src/tools/gb-title-case.ts +1 -0
- package/src/tools/golden-expand.ts +64 -20
- package/src/tools/golden-promote.ts +53 -13
- package/src/tools/ingest-csv.ts +41 -26
- package/src/tools/jsonl-to-parquet.ts +30 -10
- package/src/tools/lint-shard-vocab.ts +75 -24
- package/src/tools/lint-shard.ts +75 -31
- package/src/tools/overlay-manifest.ts +7 -4
- package/src/tools/shard-kryptonite.ts +11 -3
- package/src/tools/shard-translit.ts +20 -5
- package/src/types.ts +51 -17
- package/src/wof-json.ts +18 -7
|
@@ -39,14 +39,18 @@ import { join } from "node:path"
|
|
|
39
39
|
|
|
40
40
|
import { dataRootPath } from "@mailwoman/core/utils"
|
|
41
41
|
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* A column-projected base/shard row: parallel token + label lists plus the row's country.
|
|
44
|
+
*/
|
|
43
45
|
interface CorpusRow {
|
|
44
46
|
tokens: string[]
|
|
45
47
|
labels: string[]
|
|
46
48
|
country: string | null
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Strip a BIO prefix ("B-"/"I-") off a label, matching the Python `strip_bio`.
|
|
53
|
+
*/
|
|
50
54
|
function stripBIO(label: string): string {
|
|
51
55
|
const head = label.slice(0, 2)
|
|
52
56
|
|
|
@@ -77,7 +81,9 @@ function pyRound(x: number): number {
|
|
|
77
81
|
return floor % 2 === 0 ? floor : floor + 1
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Format a fraction as a whole-percent string the way Python's `:.0%` does, e.g. 0.73 -> "73%".
|
|
86
|
+
*/
|
|
81
87
|
function pct(frac: number): string {
|
|
82
88
|
return `${pyRound(frac * 100)}%`
|
|
83
89
|
}
|
|
@@ -91,7 +97,9 @@ function pyFloat(n: number): string {
|
|
|
91
97
|
return Number.isInteger(n) ? n.toFixed(1) : String(n)
|
|
92
98
|
}
|
|
93
99
|
|
|
94
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Left-justify to a minimum width with spaces, matching Python's `{value:N}` string field.
|
|
102
|
+
*/
|
|
95
103
|
function pad(value: string, width: number): string {
|
|
96
104
|
return value.padEnd(width)
|
|
97
105
|
}
|
|
@@ -114,12 +122,14 @@ function dominant(counter: Map<string, number>): [string, number, number] {
|
|
|
114
122
|
}
|
|
115
123
|
}
|
|
116
124
|
|
|
117
|
-
if (total === 0) return ["", 0, 0
|
|
125
|
+
if (total === 0) return ["", 0, 0]
|
|
118
126
|
|
|
119
127
|
return [bestTag, total, bestCount / total]
|
|
120
128
|
}
|
|
121
129
|
|
|
122
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* Bump a (key -> count) tally, creating the inner counter on first sight.
|
|
132
|
+
*/
|
|
123
133
|
function bump(table: Map<string, Map<string, number>>, key: string, sub: string): void {
|
|
124
134
|
let counter = table.get(key)
|
|
125
135
|
|
|
@@ -127,10 +137,13 @@ function bump(table: Map<string, Map<string, number>>, key: string, sub: string)
|
|
|
127
137
|
counter = new Map()
|
|
128
138
|
table.set(key, counter)
|
|
129
139
|
}
|
|
140
|
+
|
|
130
141
|
counter.set(sub, (counter.get(sub) ?? 0) + 1)
|
|
131
142
|
}
|
|
132
143
|
|
|
133
|
-
/**
|
|
144
|
+
/**
|
|
145
|
+
* The DuckDB connection type, without a static dependency on the optional-peer package.
|
|
146
|
+
*/
|
|
134
147
|
type DuckDBConnection = Awaited<
|
|
135
148
|
ReturnType<Awaited<ReturnType<(typeof import("@duckdb/node-api"))["DuckDBInstance"]["create"]>>["connect"]>
|
|
136
149
|
>
|
|
@@ -144,6 +157,7 @@ async function readRows(con: DuckDBConnection, path: string): Promise<CorpusRow[
|
|
|
144
157
|
const result = await con.runAndReadAll(
|
|
145
158
|
`SELECT to_json(tokens) AS tokens, to_json(labels) AS labels, country FROM read_parquet('${path}')`
|
|
146
159
|
)
|
|
160
|
+
|
|
147
161
|
const raw = result.getRowObjects() as Array<{ tokens: unknown; labels: unknown; country: unknown }>
|
|
148
162
|
const rows: CorpusRow[] = []
|
|
149
163
|
|
|
@@ -152,6 +166,7 @@ async function readRows(con: DuckDBConnection, path: string): Promise<CorpusRow[
|
|
|
152
166
|
const labels = JSON.parse(String(r.labels)) as unknown
|
|
153
167
|
|
|
154
168
|
if (!Array.isArray(tokens) || !Array.isArray(labels)) continue
|
|
169
|
+
|
|
155
170
|
rows.push({
|
|
156
171
|
tokens: tokens as string[],
|
|
157
172
|
labels: labels as string[],
|
|
@@ -162,7 +177,9 @@ async function readRows(con: DuckDBConnection, path: string): Promise<CorpusRow[
|
|
|
162
177
|
return rows
|
|
163
178
|
}
|
|
164
179
|
|
|
165
|
-
/**
|
|
180
|
+
/**
|
|
181
|
+
* Read just the first row's `source` value — used to group base parts for a proportional slice.
|
|
182
|
+
*/
|
|
166
183
|
async function readSource(con: DuckDBConnection, path: string): Promise<string> {
|
|
167
184
|
const result = await con.runAndReadAll(`SELECT source FROM read_parquet('${path}') LIMIT 1`)
|
|
168
185
|
const rows = result.getRowObjects() as Array<{ source: unknown }>
|
|
@@ -170,7 +187,9 @@ async function readSource(con: DuckDBConnection, path: string): Promise<string>
|
|
|
170
187
|
return rows.length ? String(rows[0]!.source) : ""
|
|
171
188
|
}
|
|
172
189
|
|
|
173
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* Non-recursive `*.parquet` glob, sorted lexicographically — the Python `sorted(glob.glob(...))`.
|
|
192
|
+
*/
|
|
174
193
|
function globParquet(dir: string): string[] {
|
|
175
194
|
let names: string[]
|
|
176
195
|
|
|
@@ -183,44 +202,68 @@ function globParquet(dir: string): string[] {
|
|
|
183
202
|
return names
|
|
184
203
|
.filter((f) => f.endsWith(".parquet"))
|
|
185
204
|
.map((f) => join(dir, f))
|
|
186
|
-
.
|
|
205
|
+
.toSorted()
|
|
187
206
|
}
|
|
188
207
|
|
|
189
|
-
/**
|
|
208
|
+
/**
|
|
209
|
+
* Options for {@linkcode lintShardVocab}.
|
|
210
|
+
*/
|
|
190
211
|
export interface LintShardVocabOptions {
|
|
191
|
-
/**
|
|
212
|
+
/**
|
|
213
|
+
* The shard parquet to lint.
|
|
214
|
+
*/
|
|
192
215
|
shard: string
|
|
193
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* Base corpus version. Default `v0.5.0`.
|
|
218
|
+
*/
|
|
194
219
|
baseVersion?: string
|
|
195
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* Base corpus root. Default `$MAILWOMAN_DATA_ROOT/corpus/versioned`.
|
|
222
|
+
*/
|
|
196
223
|
baseRoot?: string
|
|
197
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* Base-majority confidence floor for a contradiction. Default 0.7.
|
|
226
|
+
*/
|
|
198
227
|
threshold?: number
|
|
199
|
-
/**
|
|
228
|
+
/**
|
|
229
|
+
* Minimum base support to judge a token. Default 50.
|
|
230
|
+
*/
|
|
200
231
|
minCount?: number
|
|
201
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* Fraction of base parts to scan (proportional per-source slice below 1.0). Default 1.0.
|
|
234
|
+
*/
|
|
202
235
|
fraction?: number
|
|
203
236
|
}
|
|
204
237
|
|
|
205
|
-
/**
|
|
238
|
+
/**
|
|
239
|
+
* One contradiction row: token, shard tag, base tag, base fraction, base total.
|
|
240
|
+
*/
|
|
206
241
|
export type ShardVocabRow = [token: string, shardTag: string, baseTag: string, baseFrac: number, baseTotal: number]
|
|
207
242
|
|
|
208
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* Findings summary returned by {@linkcode lintShardVocab}.
|
|
245
|
+
*/
|
|
209
246
|
export interface LintShardVocabSummary {
|
|
210
|
-
/**
|
|
247
|
+
/**
|
|
248
|
+
* Real contradictions — the command exits 1 when nonzero.
|
|
249
|
+
*/
|
|
211
250
|
errors: number
|
|
212
|
-
/**
|
|
251
|
+
/**
|
|
252
|
+
* Affix-split rows (EXPECTED — the loader's affix-relabel handles them).
|
|
253
|
+
*/
|
|
213
254
|
warnings: number
|
|
214
255
|
findings: { contradictions: ShardVocabRow[]; affixSplits: ShardVocabRow[] }
|
|
215
256
|
}
|
|
216
257
|
|
|
217
|
-
/**
|
|
258
|
+
/**
|
|
259
|
+
* Lint a synthetic shard's (token → tag) vocabulary against the base corpus, country-scoped.
|
|
260
|
+
*/
|
|
218
261
|
export async function lintShardVocab(options: LintShardVocabOptions): Promise<LintShardVocabSummary> {
|
|
219
262
|
const baseVersion = options.baseVersion ?? "v0.5.0"
|
|
220
263
|
const baseRoot = options.baseRoot ?? dataRootPath("corpus", "versioned")
|
|
221
264
|
const threshold = options.threshold ?? 0.7
|
|
222
265
|
const minCount = options.minCount ?? 50
|
|
223
|
-
const fraction = options.fraction ?? 1
|
|
266
|
+
const fraction = options.fraction ?? 1
|
|
224
267
|
|
|
225
268
|
// @duckdb/node-api is an optional peer — lazy import (the pipeline convention).
|
|
226
269
|
const { DuckDBInstance } = await import("@duckdb/node-api")
|
|
@@ -247,10 +290,13 @@ export async function lintShardVocab(options: LintShardVocabOptions): Promise<Li
|
|
|
247
290
|
set = new Set()
|
|
248
291
|
shardCountries.set(w, set)
|
|
249
292
|
}
|
|
293
|
+
|
|
250
294
|
set.add(country)
|
|
251
295
|
}
|
|
252
296
|
}
|
|
297
|
+
|
|
253
298
|
const shardVocab = new Set(shardTags.keys())
|
|
299
|
+
|
|
254
300
|
console.log(`shard: ${shardRows.length} rows, ${shardVocab.size} unique tokens`)
|
|
255
301
|
|
|
256
302
|
// 2. base parts — FULL by default; fraction<1 takes a proportional per-source slice (still big)
|
|
@@ -261,7 +307,7 @@ export async function lintShardVocab(options: LintShardVocabOptions): Promise<Li
|
|
|
261
307
|
throw new Error("no base parts found")
|
|
262
308
|
}
|
|
263
309
|
|
|
264
|
-
if (fraction < 1
|
|
310
|
+
if (fraction < 1) {
|
|
265
311
|
const bysrc = new Map<string, string[]>()
|
|
266
312
|
|
|
267
313
|
for (const p of parts) {
|
|
@@ -272,8 +318,10 @@ export async function lintShardVocab(options: LintShardVocabOptions): Promise<Li
|
|
|
272
318
|
list = []
|
|
273
319
|
bysrc.set(src, list)
|
|
274
320
|
}
|
|
321
|
+
|
|
275
322
|
list.push(p)
|
|
276
323
|
}
|
|
324
|
+
|
|
277
325
|
const sliced: string[] = []
|
|
278
326
|
|
|
279
327
|
for (const ps of bysrc.values()) {
|
|
@@ -283,8 +331,10 @@ export async function lintShardVocab(options: LintShardVocabOptions): Promise<Li
|
|
|
283
331
|
sliced.push(p)
|
|
284
332
|
}
|
|
285
333
|
}
|
|
334
|
+
|
|
286
335
|
parts = sliced
|
|
287
336
|
}
|
|
337
|
+
|
|
288
338
|
console.log(`base ${baseVersion}: scanning ${parts.length} parts (fraction=${pyFloat(fraction)}), COUNTRY-scoped`)
|
|
289
339
|
|
|
290
340
|
// 3. tally each shard token's base tag, SCOPED to the country the shard uses it in
|
|
@@ -336,6 +386,7 @@ export async function lintShardVocab(options: LintShardVocabOptions): Promise<Li
|
|
|
336
386
|
for (const [label, rows] of sections) {
|
|
337
387
|
if (!rows.length) continue
|
|
338
388
|
rows.sort((a, b) => b[4] - a[4] || b[3] - a[3])
|
|
389
|
+
|
|
339
390
|
console.log(`\n${label.startsWith("CONTRA") ? "⚠️ " : "· "}${rows.length} ${label}:`)
|
|
340
391
|
|
|
341
392
|
for (const [w, sTag, bTag, bFrac, bTotal] of rows) {
|
package/src/tools/lint-shard.ts
CHANGED
|
@@ -39,10 +39,22 @@ import { execSync } from "node:child_process"
|
|
|
39
39
|
import { existsSync, readFileSync, writeFileSync } from "node:fs"
|
|
40
40
|
import { fileURLToPath } from "node:url"
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Occurrences of a forbidden label before it is reported — one or two are noise, five is a pattern.
|
|
44
|
+
*/
|
|
45
|
+
const FORBIDDEN_LABEL_REPORT_THRESHOLD = 5
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Examples printed per finding before the list is truncated.
|
|
49
|
+
*/
|
|
50
|
+
const MAX_LISTED_EXAMPLES = 20
|
|
51
|
+
|
|
42
52
|
const SEP = ""
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Calibrated thresholds (DeepSeek turn 9). These can be tuned over time if new failure modes surface that the current
|
|
56
|
+
* numbers miss.
|
|
57
|
+
*/
|
|
46
58
|
const CORPUS_CONFIDENCE_FLOOR = 0.66
|
|
47
59
|
const SHARD_MIN_COUNT = 50
|
|
48
60
|
const CORPUS_MIN_COUNT = 200
|
|
@@ -65,17 +77,29 @@ function defaultRulesPath(): string {
|
|
|
65
77
|
return fileURLToPath(new URL("../../../src/tools/lint-rules.json", import.meta.url))
|
|
66
78
|
}
|
|
67
79
|
|
|
68
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* Options for {@linkcode lintCorpusShard}.
|
|
82
|
+
*/
|
|
69
83
|
export interface LintCorpusShardOptions {
|
|
70
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* The new shard parquet to lint.
|
|
86
|
+
*/
|
|
71
87
|
shardPath: string
|
|
72
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Pre-computed corpus stats JSON (see `corpus-stats.ts`).
|
|
90
|
+
*/
|
|
73
91
|
statsPath: string
|
|
74
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Anti-pattern rules JSON. Default: the `lint-rules.json` beside this module.
|
|
94
|
+
*/
|
|
75
95
|
rulesPath?: string
|
|
76
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Write the markdown report here as well as stdout.
|
|
98
|
+
*/
|
|
77
99
|
outMd?: string
|
|
78
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Write a JSON sidecar of the flags + summary here.
|
|
102
|
+
*/
|
|
79
103
|
outJson?: string
|
|
80
104
|
}
|
|
81
105
|
|
|
@@ -114,6 +138,7 @@ labels_col = t['labels'].to_pylist()
|
|
|
114
138
|
for i in range(len(tokens_col)):
|
|
115
139
|
sys.stdout.write(json.dumps({"tokens": tokens_col[i], "labels": labels_col[i]}) + "\\n")
|
|
116
140
|
`
|
|
141
|
+
|
|
117
142
|
const buf = execSync(`python3`, { input: py, maxBuffer: 1024 * 1024 * 1024 })
|
|
118
143
|
const rows: ShardRow[] = []
|
|
119
144
|
|
|
@@ -145,6 +170,7 @@ function statsFromShard(rows: ShardRow[]): ShardStats {
|
|
|
145
170
|
for (const row of rows) {
|
|
146
171
|
if (row.tokens.length !== row.labels.length) {
|
|
147
172
|
out.truncatedRows++
|
|
173
|
+
|
|
148
174
|
continue
|
|
149
175
|
}
|
|
150
176
|
|
|
@@ -161,6 +187,7 @@ function statsFromShard(rows: ShardRow[]): ShardStats {
|
|
|
161
187
|
labelMap = new Map()
|
|
162
188
|
out.tokens.set(tk, labelMap)
|
|
163
189
|
}
|
|
190
|
+
|
|
164
191
|
labelMap.set(lb, (labelMap.get(lb) ?? 0) + 1)
|
|
165
192
|
|
|
166
193
|
if (i + 1 < row.tokens.length) {
|
|
@@ -172,6 +199,7 @@ function statsFromShard(rows: ShardRow[]): ShardStats {
|
|
|
172
199
|
bMap = new Map()
|
|
173
200
|
out.bigrams.set(bigramKey, bMap)
|
|
174
201
|
}
|
|
202
|
+
|
|
175
203
|
bMap.set(bigramLabel, (bMap.get(bigramLabel) ?? 0) + 1)
|
|
176
204
|
}
|
|
177
205
|
}
|
|
@@ -203,7 +231,9 @@ function majorityLabel(distribution: Map<string, number> | Record<string, number
|
|
|
203
231
|
return { label: bestLabel, count: bestCount, total, confidence: total === 0 ? 0 : bestCount / total }
|
|
204
232
|
}
|
|
205
233
|
|
|
206
|
-
/**
|
|
234
|
+
/**
|
|
235
|
+
* One lint flag emitted by a check.
|
|
236
|
+
*/
|
|
207
237
|
export interface LintShardFlag {
|
|
208
238
|
check: string
|
|
209
239
|
severity: "error" | "warn"
|
|
@@ -217,12 +247,16 @@ export interface LintShardFlag {
|
|
|
217
247
|
ruleID?: string
|
|
218
248
|
}
|
|
219
249
|
|
|
220
|
-
/**
|
|
250
|
+
/**
|
|
251
|
+
* Findings summary returned by {@linkcode lintCorpusShard}.
|
|
252
|
+
*/
|
|
221
253
|
export interface LintCorpusShardSummary {
|
|
222
254
|
errors: number
|
|
223
255
|
warnings: number
|
|
224
256
|
findings: LintShardFlag[]
|
|
225
|
-
/**
|
|
257
|
+
/**
|
|
258
|
+
* The rendered markdown report (also printed to stdout).
|
|
259
|
+
*/
|
|
226
260
|
report: string
|
|
227
261
|
}
|
|
228
262
|
|
|
@@ -307,6 +341,7 @@ function checkBigramCollisions(shard: ShardStats, corpus: CorpusStats): LintShar
|
|
|
307
341
|
const renderBigram = bigram.split(SEP).join(" ")
|
|
308
342
|
const renderShardLabel = shardMaj.label.split(SEP).join(" → ")
|
|
309
343
|
const renderCorpusLabel = corpusMaj.label.split(SEP).join(" → ")
|
|
344
|
+
|
|
310
345
|
flags.push({
|
|
311
346
|
check: "bigram-collision",
|
|
312
347
|
severity: "error",
|
|
@@ -325,6 +360,7 @@ function checkBigramCollisions(shard: ShardStats, corpus: CorpusStats): LintShar
|
|
|
325
360
|
|
|
326
361
|
function checkRules(shard: ShardStats, rulesFile: LintRulesFile): LintShardFlag[] {
|
|
327
362
|
const flags: LintShardFlag[] = []
|
|
363
|
+
|
|
328
364
|
const compiled = rulesFile.rules.map((r) => ({
|
|
329
365
|
rule: r,
|
|
330
366
|
regex: new RegExp(r.pattern, r.pattern_case_sensitive ? "" : "i"),
|
|
@@ -335,7 +371,7 @@ function checkRules(shard: ShardStats, rulesFile: LintRulesFile): LintShardFlag[
|
|
|
335
371
|
if (!regex.test(token)) continue
|
|
336
372
|
|
|
337
373
|
for (const [label, count] of labelMap) {
|
|
338
|
-
if (rule.forbidden_labels.includes(label) && count >=
|
|
374
|
+
if (rule.forbidden_labels.includes(label) && count >= FORBIDDEN_LABEL_REPORT_THRESHOLD) {
|
|
339
375
|
flags.push({
|
|
340
376
|
check: "anti-pattern-rule",
|
|
341
377
|
severity: rule.severity,
|
|
@@ -363,6 +399,7 @@ function checkSanity(shard: ShardStats): LintShardFlag[] {
|
|
|
363
399
|
detail: `${shard.truncatedRows} row(s) have tokens.length !== labels.length. Pipeline alignment bug.`,
|
|
364
400
|
})
|
|
365
401
|
}
|
|
402
|
+
|
|
366
403
|
const allORatio = shard.allORows / Math.max(1, shard.rowCount)
|
|
367
404
|
|
|
368
405
|
if (allORatio >= ALL_O_RATIO_CEILING) {
|
|
@@ -383,28 +420,29 @@ function renderReport(
|
|
|
383
420
|
): string {
|
|
384
421
|
const errors = flags.filter((f) => f.severity === "error")
|
|
385
422
|
const warns = flags.filter((f) => f.severity === "warn")
|
|
386
|
-
const verdict = errors.length
|
|
387
|
-
|
|
388
|
-
lines
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
`**Errors:** ${errors.length} (gates the shard's inclusion unless MANIFEST sets \`lint_acknowledged: true\`)
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
423
|
+
const verdict = !errors.length ? "**PASS** ✓" : "**FLAGGED** ⚠"
|
|
424
|
+
|
|
425
|
+
const lines: string[] = [
|
|
426
|
+
`# Corpus Lint: ${verdict}`,
|
|
427
|
+
"",
|
|
428
|
+
`- **Shard:** \`${opts.shardPath}\``,
|
|
429
|
+
`- **Corpus stats:** \`${opts.statsPath}\``,
|
|
430
|
+
`- **Rules:** \`${opts.rulesPath}\``,
|
|
431
|
+
`- **Shard rows:** ${shard.rowCount}`,
|
|
432
|
+
`- **Unique tokens:** ${shard.tokens.size}`,
|
|
433
|
+
`- **Unique bigrams:** ${shard.bigrams.size}`,
|
|
434
|
+
"",
|
|
435
|
+
`**Errors:** ${errors.length} (gates the shard's inclusion unless MANIFEST sets \`lint_acknowledged: true\`)`,
|
|
436
|
+
`**Warnings:** ${warns.length} (advisory)`,
|
|
437
|
+
"",
|
|
438
|
+
]
|
|
402
439
|
|
|
403
|
-
if (flags.length
|
|
440
|
+
if (!flags.length) {
|
|
404
441
|
lines.push("No anomalies detected.")
|
|
405
442
|
|
|
406
443
|
return lines.join("\n")
|
|
407
444
|
}
|
|
445
|
+
|
|
408
446
|
const byCheck = new Map<string, LintShardFlag[]>()
|
|
409
447
|
|
|
410
448
|
for (const f of flags) {
|
|
@@ -423,16 +461,19 @@ function renderReport(
|
|
|
423
461
|
lines.push(`- **[${f.severity.toUpperCase()}]** ${f.detail}`)
|
|
424
462
|
}
|
|
425
463
|
|
|
426
|
-
if (list.length >
|
|
464
|
+
if (list.length > MAX_LISTED_EXAMPLES) {
|
|
427
465
|
lines.push(`- ... and ${list.length - 20} more`)
|
|
428
466
|
}
|
|
467
|
+
|
|
429
468
|
lines.push("")
|
|
430
469
|
}
|
|
431
470
|
|
|
432
471
|
return lines.join("\n")
|
|
433
472
|
}
|
|
434
473
|
|
|
435
|
-
/**
|
|
474
|
+
/**
|
|
475
|
+
* Lint a shard against corpus stats + the anti-pattern rules; print the markdown report to stdout.
|
|
476
|
+
*/
|
|
436
477
|
export function lintCorpusShard(
|
|
437
478
|
options: LintCorpusShardOptions,
|
|
438
479
|
report?: (line: string) => void
|
|
@@ -440,6 +481,7 @@ export function lintCorpusShard(
|
|
|
440
481
|
const rulesPath = options.rulesPath ?? defaultRulesPath()
|
|
441
482
|
report?.(`Reading corpus stats from ${options.statsPath}...`)
|
|
442
483
|
const corpus: CorpusStats = JSON.parse(readFileSync(options.statsPath, "utf8"))
|
|
484
|
+
|
|
443
485
|
report?.(
|
|
444
486
|
` ${corpus.row_count} rows from ${corpus.shard_paths.length} shard(s); ${Object.keys(corpus.tokens).length} tokens, ${Object.keys(corpus.bigrams).length} bigrams`
|
|
445
487
|
)
|
|
@@ -455,6 +497,7 @@ export function lintCorpusShard(
|
|
|
455
497
|
const rulesFile: LintRulesFile = JSON.parse(readFileSync(rulesPath, "utf8"))
|
|
456
498
|
|
|
457
499
|
report?.(`Running checks...`)
|
|
500
|
+
|
|
458
501
|
const flags: LintShardFlag[] = [
|
|
459
502
|
...checkDistributionOutliers(shard, corpus),
|
|
460
503
|
...checkLabelVacuum(shard, corpus),
|
|
@@ -464,6 +507,7 @@ export function lintCorpusShard(
|
|
|
464
507
|
]
|
|
465
508
|
|
|
466
509
|
const rendered = renderReport({ shardPath: options.shardPath, statsPath: options.statsPath, rulesPath }, shard, flags)
|
|
510
|
+
|
|
467
511
|
console.log(rendered)
|
|
468
512
|
|
|
469
513
|
if (options.outMd) {
|
|
@@ -51,9 +51,11 @@ interface BaseManifest {
|
|
|
51
51
|
total_rows: number
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Escape a path for single-quoted SQL string literals.
|
|
56
|
+
*/
|
|
55
57
|
function sqlString(value: string): string {
|
|
56
|
-
return value.
|
|
58
|
+
return value.replaceAll("'", "''")
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
async function descriptor(
|
|
@@ -78,7 +80,7 @@ async function descriptor(
|
|
|
78
80
|
bytes: statSync(localPath).size,
|
|
79
81
|
sha256: sha256Hex(readFileSync(localPath)),
|
|
80
82
|
first_source_id: sids[0]!,
|
|
81
|
-
last_source_id: sids
|
|
83
|
+
last_source_id: sids.at(-1)!,
|
|
82
84
|
source,
|
|
83
85
|
}
|
|
84
86
|
}
|
|
@@ -103,7 +105,7 @@ export async function assembleOverlayManifest(args: OverlayManifestOptions): Pro
|
|
|
103
105
|
const reroot = (p: string): string => {
|
|
104
106
|
const i = p.indexOf("/corpus/versioned/")
|
|
105
107
|
|
|
106
|
-
return i
|
|
108
|
+
return i !== -1 ? "/data" + p.slice(i) : p
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
const kept = base.shards.map((s) => ({ ...s, path: reroot(s.path) }))
|
|
@@ -134,6 +136,7 @@ export async function assembleOverlayManifest(args: OverlayManifestOptions): Pro
|
|
|
134
136
|
|
|
135
137
|
const out = join(args.newDir, "MANIFEST.json")
|
|
136
138
|
writeFileSync(out, JSON.stringify(manifest, null, 1) + "\n")
|
|
139
|
+
|
|
137
140
|
console.log(`wrote ${out}`)
|
|
138
141
|
console.log(` shards: ${manifest.shards.length} (${kept.length} base kept, +1 ${args.source})`)
|
|
139
142
|
console.log(` counts: ${JSON.stringify(manifest.counts)} total: ${manifest.total_rows}`)
|
|
@@ -31,9 +31,13 @@ export interface ShardKryptoniteOptions {
|
|
|
31
31
|
jsonl: string
|
|
32
32
|
baseManifest: string
|
|
33
33
|
outDir: string
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Default `"0.4.0"`.
|
|
36
|
+
*/
|
|
35
37
|
corpusVersion?: string
|
|
36
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Default `"deepseek-kryptonite"`.
|
|
40
|
+
*/
|
|
37
41
|
source?: string
|
|
38
42
|
}
|
|
39
43
|
|
|
@@ -41,6 +45,7 @@ async function* canonicalRows(jsonl: string, corpusVersion: string): AsyncIterab
|
|
|
41
45
|
for await (const raw of iterateJSONL<Record<string, unknown>>(jsonl)) {
|
|
42
46
|
// Strip sidecar underscore-prefixed fields the generator left behind for debugging.
|
|
43
47
|
const components = raw["components"] as Record<string, string>
|
|
48
|
+
|
|
44
49
|
yield {
|
|
45
50
|
raw: raw["raw"] as string,
|
|
46
51
|
components,
|
|
@@ -81,6 +86,7 @@ export async function buildKryptoniteShard(
|
|
|
81
86
|
await mkdir(options.outDir, { recursive: true })
|
|
82
87
|
|
|
83
88
|
const quarantine: string[] = []
|
|
89
|
+
|
|
84
90
|
const newManifest = await writeShards(
|
|
85
91
|
{ train: labeledRows(options.jsonl, corpusVersion, quarantine) },
|
|
86
92
|
{ outputDir: options.outDir, corpusVersion }
|
|
@@ -91,7 +97,7 @@ export async function buildKryptoniteShard(
|
|
|
91
97
|
`quarantined ${quarantine.length}`
|
|
92
98
|
)
|
|
93
99
|
|
|
94
|
-
if (quarantine.length
|
|
100
|
+
if (quarantine.length) {
|
|
95
101
|
const qPath = join(options.outDir, `corpus-v${corpusVersion}`, "quarantine-kryptonite.tsv")
|
|
96
102
|
writeFileSync(qPath, quarantine.join("\n") + "\n", "utf8")
|
|
97
103
|
report?.(`quarantine log → ${qPath}`)
|
|
@@ -106,6 +112,7 @@ export async function buildKryptoniteShard(
|
|
|
106
112
|
|
|
107
113
|
// Compose the final corpus-v0.4.0 manifest: every shard from base + the new shard(s).
|
|
108
114
|
const base = JSON.parse(readFileSync(options.baseManifest, "utf8")) as ShardManifest
|
|
115
|
+
|
|
109
116
|
const combined: ShardManifest = {
|
|
110
117
|
corpus_version: corpusVersion,
|
|
111
118
|
schema: PARQUET_COLUMNS,
|
|
@@ -119,6 +126,7 @@ export async function buildKryptoniteShard(
|
|
|
119
126
|
},
|
|
120
127
|
total_rows: base.total_rows + newManifest.total_rows,
|
|
121
128
|
}
|
|
129
|
+
|
|
122
130
|
// Stamp source on the legacy v0.3.0 shards too, so audit's shard.source path is the
|
|
123
131
|
// authoritative one. v0.3.0 shards mix sources; we use the first_source_id-prefix
|
|
124
132
|
// inference for them (audit.ts will re-derive on its own when shard.source is absent).
|
|
@@ -44,11 +44,17 @@ export interface ShardTranslitOptions {
|
|
|
44
44
|
jsonl: string
|
|
45
45
|
baseManifest: string
|
|
46
46
|
outDir: string
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Default `"0.4.0"`.
|
|
49
|
+
*/
|
|
48
50
|
corpusVersion?: string
|
|
49
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Default `"/data/"`.
|
|
53
|
+
*/
|
|
50
54
|
canonicalPathPrefix?: string
|
|
51
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Default `"/mnt/playpen/mailwoman-data/"`.
|
|
57
|
+
*/
|
|
52
58
|
legacyPathPrefix?: string
|
|
53
59
|
}
|
|
54
60
|
|
|
@@ -106,6 +112,7 @@ async function writeOneShard(
|
|
|
106
112
|
const writer = await ParquetWriter.openFile<ParquetRow>(LABELED_ROW_SCHEMA, outPath, {
|
|
107
113
|
rowGroupSize: ROW_GROUP_SIZE,
|
|
108
114
|
})
|
|
115
|
+
|
|
109
116
|
writer.setMetadata("mailwoman.corpus_version", corpusVersion)
|
|
110
117
|
writer.setMetadata("mailwoman.split", "train")
|
|
111
118
|
writer.setMetadata("mailwoman.shard_source", source)
|
|
@@ -120,8 +127,10 @@ async function writeOneShard(
|
|
|
120
127
|
if (firstSourceID === "") {
|
|
121
128
|
firstSourceID = row.source_id
|
|
122
129
|
}
|
|
130
|
+
|
|
123
131
|
lastSourceID = row.source_id
|
|
124
132
|
}
|
|
133
|
+
|
|
125
134
|
await writer.close()
|
|
126
135
|
|
|
127
136
|
const fileStat = await stat(outPath)
|
|
@@ -177,8 +186,10 @@ export async function buildTranslitShard(
|
|
|
177
186
|
|
|
178
187
|
if (result.kind !== "labeled") {
|
|
179
188
|
quarantine.push(`${canon.source_id}\t${result.row.reason}`)
|
|
189
|
+
|
|
180
190
|
continue
|
|
181
191
|
}
|
|
192
|
+
|
|
182
193
|
const bucket = buckets.get(canon.source)
|
|
183
194
|
|
|
184
195
|
if (bucket) {
|
|
@@ -187,10 +198,11 @@ export async function buildTranslitShard(
|
|
|
187
198
|
buckets.set(canon.source, [result.row])
|
|
188
199
|
}
|
|
189
200
|
}
|
|
201
|
+
|
|
190
202
|
report?.(`read ${totalIn} rows; ${quarantine.length} quarantined; ${buckets.size} script buckets`)
|
|
191
203
|
|
|
192
204
|
const newShards: ShardDescriptor[] = []
|
|
193
|
-
const sortedKeys = [...buckets.keys()].
|
|
205
|
+
const sortedKeys = [...buckets.keys()].toSorted()
|
|
194
206
|
|
|
195
207
|
for (const source of sortedKeys) {
|
|
196
208
|
const rows = buckets.get(source)!
|
|
@@ -201,7 +213,7 @@ export async function buildTranslitShard(
|
|
|
201
213
|
report?.(` ${source}: ${descriptor.rows} rows → ${outPath} (${descriptor.bytes} bytes)`)
|
|
202
214
|
}
|
|
203
215
|
|
|
204
|
-
if (quarantine.length
|
|
216
|
+
if (quarantine.length) {
|
|
205
217
|
const qPath = join(corpusDir, "quarantine-transliteration.tsv")
|
|
206
218
|
writeFileSync(qPath, quarantine.join("\n") + "\n", "utf8")
|
|
207
219
|
report?.(`quarantine log → ${qPath} (${quarantine.length} rows)`)
|
|
@@ -211,11 +223,14 @@ export async function buildTranslitShard(
|
|
|
211
223
|
// the new translit shards. Kryptonite shard already lives in the base manifest (it was written
|
|
212
224
|
// there by Thread B).
|
|
213
225
|
const base = JSON.parse(readFileSync(options.baseManifest, "utf8")) as ShardManifest
|
|
226
|
+
|
|
214
227
|
const rewrittenBase = base.shards.map((sh) => ({
|
|
215
228
|
...sh,
|
|
216
229
|
path: canonicalizeShardPath(sh.path, legacyPathPrefix, canonicalPathPrefix),
|
|
217
230
|
}))
|
|
231
|
+
|
|
218
232
|
const newTrainRows = newShards.reduce((sum, sh) => sum + sh.rows, 0)
|
|
233
|
+
|
|
219
234
|
const combined: ShardManifest = {
|
|
220
235
|
corpus_version: corpusVersion,
|
|
221
236
|
schema: PARQUET_COLUMNS,
|