@mailwoman/corpus 4.13.0 → 4.15.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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * G-NAF (Australia) corpus adapter — the parser-teaching half of #208.
7
+ *
8
+ * The model mis-parses Australian addresses in their native postcode-first / house-number-last
9
+ * order: it tags a leading 4-digit postcode as a house number (its US/EU prior) and swaps street
10
+ * ↔ locality with it. `scripts/eval/au-order-probe.ts` proved this is a word-ORDER coverage gap,
11
+ * not capability — the same addresses parse perfectly in canonical order (65% → 87% @25km if the
12
+ * parse were order-robust). EU survives the same eval because its postcodes are
13
+ * format-distinctive (a hyphenated `26-300` reads as a postcode anywhere); a bare AU `3053` only
14
+ * disambiguates by position.
15
+ *
16
+ * So this adapter renders each assembled G-NAF tuple (from {@link ./assemble}) in one of three real
17
+ * AU layouts — real-AU canonical (number-first, postcode-trailing), postcode-first,
18
+ * locality-first — ROTATED by row index (`i % 3`), so the locality + postcode each land in every
19
+ * position across the shard. This is the exact mechanism that fixed #148's v1.9.0 order-overfit
20
+ * for the 16 EU locales (`scripts/rerender-overture-multiorder.mjs`, v1.9.1 → shipped v4.13.0);
21
+ * AU was simply never in that train (`country_weights` had no AU, and `data_loader.py` excludes
22
+ * unlisted countries). Rotating one order per row (rather than emitting all three) keeps this a
23
+ * clean single-variable extension of the proven recipe + matches its source-mass structure. The
24
+ * corpus aligner BIO-labels each (every component surface form occurs verbatim in `raw`, so
25
+ * alignment lands).
26
+ *
27
+ * Input: the assembled component JSONL (one `{house_number,street,locality,region,postcode}` per
28
+ * line). Open G-NAF licence — attribute "Geoscape Australia".
29
+ */
30
+ import type { CorpusAdapter } from "../../types.js";
31
+ export declare const GNAF_ADAPTER_ID = "gnaf";
32
+ /** Open G-NAF is freely redistributable with attribution to Geoscape Australia (CC-BY-style). */
33
+ export declare const GNAF_DEFAULT_LICENSE = "CC-BY-4.0";
34
+ /**
35
+ * Build the G-NAF adapter. `inputPath` is the assembled component JSONL (see {@link ./assemble}); it
36
+ * is country-pinned to AU regardless of `opts.country` (G-NAF is Australia-only).
37
+ */
38
+ export declare function createGnafAdapter(): CorpusAdapter;
39
+ export declare const gnafAdapter: CorpusAdapter;
40
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../src/adapters/gnaf/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAMH,OAAO,KAAK,EAAgC,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEjF,eAAO,MAAM,eAAe,SAAS,CAAA;AACrC,iGAAiG;AACjG,eAAO,MAAM,oBAAoB,cAAc,CAAA;AA2B/C;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,aAAa,CA4DjD;AAED,eAAO,MAAM,WAAW,eAAsB,CAAA"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * G-NAF (Australia) corpus adapter — the parser-teaching half of #208.
7
+ *
8
+ * The model mis-parses Australian addresses in their native postcode-first / house-number-last
9
+ * order: it tags a leading 4-digit postcode as a house number (its US/EU prior) and swaps street
10
+ * ↔ locality with it. `scripts/eval/au-order-probe.ts` proved this is a word-ORDER coverage gap,
11
+ * not capability — the same addresses parse perfectly in canonical order (65% → 87% @25km if the
12
+ * parse were order-robust). EU survives the same eval because its postcodes are
13
+ * format-distinctive (a hyphenated `26-300` reads as a postcode anywhere); a bare AU `3053` only
14
+ * disambiguates by position.
15
+ *
16
+ * So this adapter renders each assembled G-NAF tuple (from {@link ./assemble}) in one of three real
17
+ * AU layouts — real-AU canonical (number-first, postcode-trailing), postcode-first,
18
+ * locality-first — ROTATED by row index (`i % 3`), so the locality + postcode each land in every
19
+ * position across the shard. This is the exact mechanism that fixed #148's v1.9.0 order-overfit
20
+ * for the 16 EU locales (`scripts/rerender-overture-multiorder.mjs`, v1.9.1 → shipped v4.13.0);
21
+ * AU was simply never in that train (`country_weights` had no AU, and `data_loader.py` excludes
22
+ * unlisted countries). Rotating one order per row (rather than emitting all three) keeps this a
23
+ * clean single-variable extension of the proven recipe + matches its source-mass structure. The
24
+ * corpus aligner BIO-labels each (every component surface form occurs verbatim in `raw`, so
25
+ * alignment lands).
26
+ *
27
+ * Input: the assembled component JSONL (one `{house_number,street,locality,region,postcode}` per
28
+ * line). Open G-NAF licence — attribute "Geoscape Australia".
29
+ */
30
+ import { createReadStream } from "node:fs";
31
+ import { createInterface } from "node:readline";
32
+ import { stableSourceId } from "../../adapter.js";
33
+ import { reconcileComponents } from "../../format.js";
34
+ export const GNAF_ADAPTER_ID = "gnaf";
35
+ /** Open G-NAF is freely redistributable with attribution to Geoscape Australia (CC-BY-style). */
36
+ export const GNAF_DEFAULT_LICENSE = "CC-BY-4.0";
37
+ /**
38
+ * The address layouts an AU address actually arrives in. The model already handles
39
+ * postcode-TRAILING (canonical); the two postcode-LEADING forms are the ones it fails, so they
40
+ * carry the lever. We keep the canonical form too so the retrain doesn't forget it.
41
+ */
42
+ function renderOrders(c) {
43
+ const region = c.region ? ` ${c.region}` : "";
44
+ return [
45
+ // real-AU canonical: number-first, street, suburb [state] postcode — "50 Barry Street, Carlton NSW 2000"
46
+ `${c.house_number} ${c.street}, ${c.locality}${region} ${c.postcode}`,
47
+ // postcode-first (the dominant failure): "2000 Carlton, Barry Street 50"
48
+ `${c.postcode} ${c.locality}, ${c.street} ${c.house_number}`,
49
+ // locality-first: "Carlton, 2000, Barry Street 50"
50
+ `${c.locality}, ${c.postcode}, ${c.street} ${c.house_number}`,
51
+ ];
52
+ }
53
+ /**
54
+ * Build the G-NAF adapter. `inputPath` is the assembled component JSONL (see {@link ./assemble}); it
55
+ * is country-pinned to AU regardless of `opts.country` (G-NAF is Australia-only).
56
+ */
57
+ export function createGnafAdapter() {
58
+ return {
59
+ id: GNAF_ADAPTER_ID,
60
+ defaultLicense: GNAF_DEFAULT_LICENSE,
61
+ description: "G-NAF (Australia): assembled address tuples rendered in multiple word orders (canonical / postcode-first / locality-first) — teaches the model AU's postcode-first layout.",
62
+ async *rows(opts) {
63
+ const stream = createReadStream(opts.inputPath, { encoding: "utf8" });
64
+ const lines = createInterface({ input: stream, crlfDelay: Infinity });
65
+ let emitted = 0;
66
+ let idx = 0; // rotates the render order (i % 3), matching v1.9.1's rerender
67
+ try {
68
+ for await (const line of lines) {
69
+ if (opts.signal?.aborted)
70
+ break;
71
+ if (opts.limit !== undefined && emitted >= opts.limit)
72
+ break;
73
+ if (!line.trim())
74
+ continue;
75
+ let t;
76
+ try {
77
+ t = JSON.parse(line);
78
+ }
79
+ catch {
80
+ continue;
81
+ }
82
+ if (!t.house_number || !t.street || !t.locality || !t.postcode)
83
+ continue;
84
+ const orders = renderOrders(t);
85
+ const order = idx % orders.length;
86
+ idx++;
87
+ const raw = orders[order];
88
+ const components = {
89
+ house_number: t.house_number,
90
+ street: t.street,
91
+ locality: t.locality,
92
+ postcode: t.postcode,
93
+ };
94
+ // region (state) rides only the canonical render (order 0); the postcode-leading layouts
95
+ // omit it (matching the eval's serialization) so it never breaks verbatim alignment.
96
+ if (order === 0 && t.region)
97
+ components.region = t.region;
98
+ const aligned = reconcileComponents(components, raw);
99
+ if (Object.keys(aligned).length === 0)
100
+ continue;
101
+ yield {
102
+ raw,
103
+ components: aligned,
104
+ country: "AU",
105
+ locale: "en-AU",
106
+ source: GNAF_ADAPTER_ID,
107
+ source_id: `${stableSourceId(GNAF_ADAPTER_ID, aligned)}-o${order}`,
108
+ corpus_version: "",
109
+ license: GNAF_DEFAULT_LICENSE,
110
+ };
111
+ emitted++;
112
+ }
113
+ }
114
+ finally {
115
+ lines.close();
116
+ stream.destroy();
117
+ }
118
+ },
119
+ };
120
+ }
121
+ export const gnafAdapter = createGnafAdapter();
122
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../src/adapters/gnaf/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Assemble a sampled, component-labeled Australian address set from G-NAF (the Geocoded National
7
+ * Address File — Geoscape Australia, Open G-NAF licence; any derived artifact must attribute
8
+ * "Geoscape Australia"). G-NAF is a relational PSV distribution (~16.9M addresses);
9
+ * reconstructing a street address joins three tables — ADDRESS_DETAIL (number, postcode, the
10
+ * PIDs) → STREET_LOCALITY (street name + type) → LOCALITY (suburb). State is the per-file prefix
11
+ * (ACT/NSW/…).
12
+ *
13
+ * Streaming + in-memory join via the house {@link PSVSpliterator} (pipe-separated; `mode: "object"`
14
+ * keys each row by its header) — NOT raw `read_csv` SQL, which a flat-file join doesn't need and
15
+ * which the #183–190 cleanup retired. The two lookup tables (STREET_LOCALITY ~765k rows, LOCALITY
16
+ * ~16k) fit as Maps; ADDRESS_DETAIL is streamed once and reservoir-sampled, so memory stays
17
+ * bounded (the OOM lesson from the Overture ingest).
18
+ *
19
+ * No coordinates: the output feeds the PARSER ({@link ../gnaf/adapter}, #208) — teaching the model
20
+ * AU's postcode-first / house-number-last word order, the gap `scripts/eval/au-order-probe.ts`
21
+ * pinned (65%→87% if the parse were order-robust). The parser needs the address string +
22
+ * component labels, not lat/lon.
23
+ *
24
+ * Output: component tuples as JSONL, consumed by the `gnaf` corpus adapter (which renders them in
25
+ * multiple orders + the corpus aligner BIO-labels them). An optional held-out eval set is
26
+ * excluded by (street, locality, postcode) so the training shard never overlaps the benchmark.
27
+ */
28
+ export interface GnafAssembleOptions {
29
+ /** G-NAF `Standard` directory (holds the per-state `*_psv.psv` tables). */
30
+ standardDir: string;
31
+ /** Target sample size (uniform reservoir → population-proportional across states). */
32
+ sampleSize: number;
33
+ /** Output JSONL path. */
34
+ out: string;
35
+ /** Optional held-out eval JSONL (rows with a `components` field) — its (street,locality,postcode)
36
+ are excluded. */
37
+ holdoutPath?: string;
38
+ /** Progress sink (the CLI passes a setter). */
39
+ onProgress?: (message: string) => void;
40
+ }
41
+ export interface GnafAssembleResult {
42
+ written: number;
43
+ seen: number;
44
+ heldOut: number;
45
+ byState: Record<string, number>;
46
+ }
47
+ /** UPPERCASE → Title Case, preserving intra-word apostrophes/hyphens (O'Brien, Coff's Harbour). */
48
+ export declare function titlecase(s: string): string;
49
+ /** Holdout/dedup key: a street within a locality+postcode (house-number-agnostic — conservative). */
50
+ export declare function gnafHoldoutKey(street: string, locality: string, postcode: string): string;
51
+ export declare function assembleGnaf(opts: GnafAssembleOptions): Promise<GnafAssembleResult>;
52
+ //# sourceMappingURL=assemble.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../../../src/adapters/gnaf/assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,MAAM,WAAW,mBAAmB;IACnC,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAA;IAClB,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAA;IACX;gBACe;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAED,mGAAmG;AACnG,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED,qGAAqG;AACrG,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzF;AAmCD,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiEzF"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Assemble a sampled, component-labeled Australian address set from G-NAF (the Geocoded National
7
+ * Address File — Geoscape Australia, Open G-NAF licence; any derived artifact must attribute
8
+ * "Geoscape Australia"). G-NAF is a relational PSV distribution (~16.9M addresses);
9
+ * reconstructing a street address joins three tables — ADDRESS_DETAIL (number, postcode, the
10
+ * PIDs) → STREET_LOCALITY (street name + type) → LOCALITY (suburb). State is the per-file prefix
11
+ * (ACT/NSW/…).
12
+ *
13
+ * Streaming + in-memory join via the house {@link PSVSpliterator} (pipe-separated; `mode: "object"`
14
+ * keys each row by its header) — NOT raw `read_csv` SQL, which a flat-file join doesn't need and
15
+ * which the #183–190 cleanup retired. The two lookup tables (STREET_LOCALITY ~765k rows, LOCALITY
16
+ * ~16k) fit as Maps; ADDRESS_DETAIL is streamed once and reservoir-sampled, so memory stays
17
+ * bounded (the OOM lesson from the Overture ingest).
18
+ *
19
+ * No coordinates: the output feeds the PARSER ({@link ../gnaf/adapter}, #208) — teaching the model
20
+ * AU's postcode-first / house-number-last word order, the gap `scripts/eval/au-order-probe.ts`
21
+ * pinned (65%→87% if the parse were order-robust). The parser needs the address string +
22
+ * component labels, not lat/lon.
23
+ *
24
+ * Output: component tuples as JSONL, consumed by the `gnaf` corpus adapter (which renders them in
25
+ * multiple orders + the corpus aligner BIO-labels them). An optional held-out eval set is
26
+ * excluded by (street, locality, postcode) so the training shard never overlaps the benchmark.
27
+ */
28
+ import { createWriteStream } from "node:fs";
29
+ import { readdir, readFile } from "node:fs/promises";
30
+ import { join } from "node:path";
31
+ import { PSVSpliterator } from "spliterator";
32
+ /** UPPERCASE → Title Case, preserving intra-word apostrophes/hyphens (O'Brien, Coff's Harbour). */
33
+ export function titlecase(s) {
34
+ return s
35
+ .toLowerCase()
36
+ .replace(/(^|[\s'\-/])([a-z])/g, (_m, p, c) => p + c.toUpperCase())
37
+ .trim();
38
+ }
39
+ /** Holdout/dedup key: a street within a locality+postcode (house-number-agnostic — conservative). */
40
+ export function gnafHoldoutKey(street, locality, postcode) {
41
+ return `${street}|${locality}|${postcode}`.toLowerCase();
42
+ }
43
+ async function* psvObjects(path) {
44
+ yield* PSVSpliterator.fromAsync(path, { mode: "object", header: true });
45
+ }
46
+ /** Load a small lookup table fully into a Map keyed by `keyCol`. */
47
+ async function loadMap(paths, keyCol, pick) {
48
+ const m = new Map();
49
+ for (const p of paths) {
50
+ for await (const r of psvObjects(p)) {
51
+ const k = r[keyCol];
52
+ if (k != null && k !== "")
53
+ m.set(String(k), pick(r));
54
+ }
55
+ }
56
+ return m;
57
+ }
58
+ /** Build the held-out key set from an eval JSONL whose rows carry a `components` object. */
59
+ async function loadHoldout(path) {
60
+ const keys = new Set();
61
+ const text = await readFile(path, "utf8");
62
+ for (const line of text.split("\n")) {
63
+ if (!line.trim())
64
+ continue;
65
+ try {
66
+ const c = JSON.parse(line).components;
67
+ if (c?.street && c?.locality && c?.postcode)
68
+ keys.add(gnafHoldoutKey(c.street, c.locality, c.postcode));
69
+ }
70
+ catch {
71
+ /* skip malformed */
72
+ }
73
+ }
74
+ return keys;
75
+ }
76
+ export async function assembleGnaf(opts) {
77
+ const progress = opts.onProgress ?? (() => { });
78
+ const files = await readdir(opts.standardDir);
79
+ const pick = (re, exclude) => files.filter((f) => re.test(f) && !(exclude && exclude.test(f))).map((f) => join(opts.standardDir, f));
80
+ // `*_LOCALITY_psv.psv` also globs `*_STREET_LOCALITY_psv.psv` — exclude the latter explicitly.
81
+ const streetPaths = pick(/_STREET_LOCALITY_psv\.psv$/);
82
+ const localityPaths = pick(/_LOCALITY_psv\.psv$/, /_STREET_LOCALITY_psv\.psv$/);
83
+ const addressPaths = pick(/_ADDRESS_DETAIL_psv\.psv$/);
84
+ const holdout = opts.holdoutPath ? await loadHoldout(opts.holdoutPath) : new Set();
85
+ if (opts.holdoutPath)
86
+ progress(`held-out eval keys: ${holdout.size}`);
87
+ progress(`loading STREET_LOCALITY (${streetPaths.length} files) + LOCALITY (${localityPaths.length})…`);
88
+ const streetMap = await loadMap(streetPaths, "STREET_LOCALITY_PID", (r) => ({
89
+ name: String(r.STREET_NAME ?? ""),
90
+ type: String(r.STREET_TYPE_CODE ?? ""),
91
+ suffix: String(r.STREET_SUFFIX_CODE ?? ""),
92
+ }));
93
+ const localityMap = await loadMap(localityPaths, "LOCALITY_PID", (r) => String(r.LOCALITY_NAME ?? ""));
94
+ progress(`streets=${streetMap.size.toLocaleString()} localities=${localityMap.size.toLocaleString()}`);
95
+ const reservoir = [];
96
+ let seen = 0;
97
+ let heldOut = 0;
98
+ for (const p of addressPaths) {
99
+ const state = (p.match(/\/([A-Z]+)_ADDRESS_DETAIL/) ?? [])[1] ?? "";
100
+ for await (const r of psvObjects(p)) {
101
+ const numberFirst = String(r.NUMBER_FIRST ?? "");
102
+ if (!numberFirst || r.DATE_RETIRED || !r.POSTCODE)
103
+ continue;
104
+ const st = streetMap.get(String(r.STREET_LOCALITY_PID ?? ""));
105
+ const suburbRaw = localityMap.get(String(r.LOCALITY_PID ?? ""));
106
+ if (!st?.name || !suburbRaw)
107
+ continue;
108
+ const street = `${titlecase(st.name)} ${titlecase(st.type)}${st.suffix ? " " + titlecase(st.suffix) : ""}`.trim();
109
+ const locality = titlecase(suburbRaw);
110
+ const postcode = String(r.POSTCODE);
111
+ if (holdout.has(gnafHoldoutKey(street, locality, postcode))) {
112
+ heldOut++;
113
+ continue;
114
+ }
115
+ let house = numberFirst + (r.NUMBER_FIRST_SUFFIX ? String(r.NUMBER_FIRST_SUFFIX) : "");
116
+ if (r.NUMBER_LAST)
117
+ house = `${house}-${String(r.NUMBER_LAST)}`;
118
+ if (r.FLAT_NUMBER)
119
+ house = `${String(r.FLAT_NUMBER)}/${house}`;
120
+ const tuple = { house_number: house, street, locality, region: state, postcode };
121
+ seen++;
122
+ if (reservoir.length < opts.sampleSize)
123
+ reservoir.push(tuple);
124
+ else {
125
+ const j = Math.floor(Math.random() * seen);
126
+ if (j < opts.sampleSize)
127
+ reservoir[j] = tuple;
128
+ }
129
+ }
130
+ progress(`${state}: ${seen.toLocaleString()} valid joinable seen`);
131
+ }
132
+ const out = createWriteStream(opts.out);
133
+ const byState = {};
134
+ for (const t of reservoir) {
135
+ out.write(JSON.stringify(t) + "\n");
136
+ byState[t.region] = (byState[t.region] ?? 0) + 1;
137
+ }
138
+ await new Promise((res) => out.end(res));
139
+ progress(`wrote ${reservoir.length.toLocaleString()} tuples → ${opts.out}`);
140
+ return { written: reservoir.length, seen, heldOut, byState };
141
+ }
142
+ //# sourceMappingURL=assemble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../../../src/adapters/gnaf/assemble.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAoBhD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EAmBpD,CAAA;AAQD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACjG,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,GACrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACtG,OAAO,EACN,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,GACpB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACN,2BAA2B,EAC3B,gCAAgC,EAChC,qBAAqB,GACrB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACN,+BAA+B,EAC/B,oCAAoC,EACpC,yBAAyB,GACzB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACN,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,GACtB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACN,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,GACtB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC1F,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,oBAAoB,GACpB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACN,yBAAyB,EACzB,8BAA8B,EAC9B,mBAAmB,GACnB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACxH,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACzG,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjH,OAAO,EACN,uBAAuB,EACvB,4BAA4B,EAC5B,kCAAkC,GAClC,MAAM,6CAA6C,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AACnF,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAqBhD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EAoBpD,CAAA;AAQD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACjG,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,GACrB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACtG,OAAO,EACN,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,GACpB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACN,2BAA2B,EAC3B,gCAAgC,EAChC,qBAAqB,GACrB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACN,+BAA+B,EAC/B,oCAAoC,EACpC,yBAAyB,GACzB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACN,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,GACtB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACN,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,GACtB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC1F,OAAO,EACN,0BAA0B,EAC1B,+BAA+B,EAC/B,oBAAoB,GACpB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACN,yBAAyB,EACzB,8BAA8B,EAC9B,mBAAmB,GACnB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACxH,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACzG,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AACjH,OAAO,EACN,uBAAuB,EACvB,4BAA4B,EAC5B,kCAAkC,GAClC,MAAM,6CAA6C,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AACnF,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA"}
@@ -23,6 +23,7 @@ import { banAdapter } from "./ban/adapter.js";
23
23
  import { fccBdcAdapter } from "./fcc-bdc/adapter.js";
24
24
  import { geonamesPostalAdapter } from "./geonames-postal/adapter.js";
25
25
  import { geonamesAdapter } from "./geonames/adapter.js";
26
+ import { gnafAdapter } from "./gnaf/adapter.js";
26
27
  import { openaddressesAdapter } from "./openaddresses/adapter.js";
27
28
  import { overtureAdapter } from "./overture/adapter.js";
28
29
  import { stateHiSchoolsAdapter } from "./state-hi-schools/adapter.js";
@@ -57,6 +58,7 @@ export const BUILTIN_ADAPTERS = [
57
58
  tigerAdapter,
58
59
  openaddressesAdapter,
59
60
  overtureAdapter,
61
+ gnafAdapter,
60
62
  fccBdcAdapter,
61
63
  usgovHrsaFqhcAdapter,
62
64
  usgovNppesAdapter,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
  export * from "./adapter.js";
7
+ export * from "./adapters/gnaf/assemble.js";
7
8
  export * from "./adapters/index.js";
8
9
  export * from "./align.js";
9
10
  export * from "./build.js";
@@ -12,6 +13,7 @@ export * from "./golden.js";
12
13
  export * from "./parquet.js";
13
14
  export * from "./runner.js";
14
15
  export * from "./split.js";
16
+ export * from "./synthesize-anchor-absorption.js";
15
17
  export * from "./synthesize-german.js";
16
18
  export * from "./synthesize-house-venue.js";
17
19
  export * from "./synthesize-intersection.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,cAAc,CAAA;AAC5B,cAAc,6BAA6B,CAAA;AAC3C,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
package/out/src/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
  export * from "./adapter.js";
7
+ export * from "./adapters/gnaf/assemble.js";
7
8
  export * from "./adapters/index.js";
8
9
  export * from "./align.js";
9
10
  export * from "./build.js";
@@ -12,6 +13,7 @@ export * from "./golden.js";
12
13
  export * from "./parquet.js";
13
14
  export * from "./runner.js";
14
15
  export * from "./split.js";
16
+ export * from "./synthesize-anchor-absorption.js";
15
17
  export * from "./synthesize-german.js";
16
18
  export * from "./synthesize-house-venue.js";
17
19
  export * from "./synthesize-intersection.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,cAAc,CAAA;AAC5B,cAAc,6BAA6B,CAAA;AAC3C,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Anchor-absorption counter-augmentation (#220/#723, Probe A1). Teaches the model the CONTEXT-
7
+ * DEPENDENT leading-5-digit disambiguation that the killed #723 override was faking, AND that the
8
+ * `anchor_paint_mode=shaped` WHERE fix alone over-corrected on (Probe A0: it flipped the default to
9
+ * house_number, recovering CASE-H but ERODING CASE-P — postcode F1 99.3→86.5 on leading-postcode
10
+ * rows like "05764 Finel Hollow Road, VT").
11
+ *
12
+ * THE DISCRIMINATOR the model must learn (from the CASE-H vs CASE-P contrast, NOT a flipped default):
13
+ * - a leading 5-digit WITH a trailing postcode + street context → it is the HOUSE NUMBER (CASE-H)
14
+ * - a leading 5-digit with NO trailing postcode (US-rural / DE) → it IS the POSTCODE (CASE-P)
15
+ * Both leading tokens are real ZIPs (so the painted anchor fires on both); only the surrounding
16
+ * context separates them. The model attends to the trailing token to decide the leading one.
17
+ *
18
+ * Slice mix (the A0 learning sets a HEAVY CASE-P floor so the default doesn't flip — DeepSeek's
19
+ * ≥35% CASE-P; here CASE-P total = 35%):
20
+ * H-adversarial 30% US street, leading real-ZIP house# + TRAILING postcode → house_number
21
+ * P-us-rural 20% US rural, leading postcode, NO trailing → postcode (the A0-erosion fix)
22
+ * P-de 15% German leading postcode "{pc} {city}, {street} {hn}" → postcode
23
+ * anchor-fp 10% leading 5-digit that is NOT a real ZIP + trailing postcode → house_number
24
+ * locale-ambig 15% minimal context; the local token (street-type vs none) decides
25
+ * standard 10% normal small house# + trailing postcode → house_number (baseline)
26
+ *
27
+ * Real ZIPs for the leading-5-digit are sampled from the postcode anchor lookup at build time
28
+ * (passed via opts.realZips) so the shaped anchor fires on them exactly as at inference; fake ZIPs
29
+ * (anchor-fp) are 5-digit strings deliberately absent from the lookup.
30
+ */
31
+ import type { ComponentTag } from "@mailwoman/core/types";
32
+ export interface AnchorAbsorptionBaseTuple {
33
+ locality: string;
34
+ region: string;
35
+ postcode: string;
36
+ }
37
+ export type AnchorAbsorptionTemplate = "h-adversarial" | "h-no-trailing-locality" | "p-us-rural" | "p-de" | "anchor-fp" | "locale-ambig" | "standard";
38
+ export interface AnchorAbsorptionSynthesisOpts {
39
+ random?: () => number;
40
+ forceTemplate?: AnchorAbsorptionTemplate;
41
+ /** Real US ZIPs (in the anchor lookup) to use as the LEADING 5-digit house number — so the painted
42
+ * anchor fires on it, the CASE-H/anchor-fp trigger. Builder loads these from pilot-anchor-lookup.json. */
43
+ realZips?: ReadonlyArray<string>;
44
+ }
45
+ export interface SynthesizedAnchorAbsorptionRow {
46
+ raw: string;
47
+ components: Partial<Record<ComponentTag, string>>;
48
+ locale: string;
49
+ template: AnchorAbsorptionTemplate;
50
+ }
51
+ /** Build one anchor-absorption counter-augmentation row. */
52
+ export declare function synthesizeAnchorAbsorptionRow(opts?: AnchorAbsorptionSynthesisOpts): SynthesizedAnchorAbsorptionRow;
53
+ export declare const ALL_TEMPLATES: ReadonlyArray<AnchorAbsorptionTemplate>;
54
+ //# sourceMappingURL=synthesize-anchor-absorption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesize-anchor-absorption.d.ts","sourceRoot":"","sources":["../../src/synthesize-anchor-absorption.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,MAAM,WAAW,yBAAyB;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,wBAAwB,GACjC,eAAe,GACf,wBAAwB,GACxB,YAAY,GACZ,MAAM,GACN,WAAW,GACX,cAAc,GACd,UAAU,CAAA;AAEb,MAAM,WAAW,6BAA6B;IAC7C,MAAM,CAAC,EAAE,MAAM,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,wBAAwB,CAAA;IACxC;8GAC0G;IAC1G,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,8BAA8B;IAC9C,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAA;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,wBAAwB,CAAA;CAClC;AA6CD,4DAA4D;AAC5D,wBAAgB,6BAA6B,CAC5C,IAAI,GAAE,6BAAkC,GACtC,8BAA8B,CA4FhC;AAaD,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,wBAAwB,CAQjE,CAAA"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Anchor-absorption counter-augmentation (#220/#723, Probe A1). Teaches the model the CONTEXT-
7
+ * DEPENDENT leading-5-digit disambiguation that the killed #723 override was faking, AND that the
8
+ * `anchor_paint_mode=shaped` WHERE fix alone over-corrected on (Probe A0: it flipped the default to
9
+ * house_number, recovering CASE-H but ERODING CASE-P — postcode F1 99.3→86.5 on leading-postcode
10
+ * rows like "05764 Finel Hollow Road, VT").
11
+ *
12
+ * THE DISCRIMINATOR the model must learn (from the CASE-H vs CASE-P contrast, NOT a flipped default):
13
+ * - a leading 5-digit WITH a trailing postcode + street context → it is the HOUSE NUMBER (CASE-H)
14
+ * - a leading 5-digit with NO trailing postcode (US-rural / DE) → it IS the POSTCODE (CASE-P)
15
+ * Both leading tokens are real ZIPs (so the painted anchor fires on both); only the surrounding
16
+ * context separates them. The model attends to the trailing token to decide the leading one.
17
+ *
18
+ * Slice mix (the A0 learning sets a HEAVY CASE-P floor so the default doesn't flip — DeepSeek's
19
+ * ≥35% CASE-P; here CASE-P total = 35%):
20
+ * H-adversarial 30% US street, leading real-ZIP house# + TRAILING postcode → house_number
21
+ * P-us-rural 20% US rural, leading postcode, NO trailing → postcode (the A0-erosion fix)
22
+ * P-de 15% German leading postcode "{pc} {city}, {street} {hn}" → postcode
23
+ * anchor-fp 10% leading 5-digit that is NOT a real ZIP + trailing postcode → house_number
24
+ * locale-ambig 15% minimal context; the local token (street-type vs none) decides
25
+ * standard 10% normal small house# + trailing postcode → house_number (baseline)
26
+ *
27
+ * Real ZIPs for the leading-5-digit are sampled from the postcode anchor lookup at build time
28
+ * (passed via opts.realZips) so the shaped anchor fires on them exactly as at inference; fake ZIPs
29
+ * (anchor-fp) are 5-digit strings deliberately absent from the lookup.
30
+ */
31
+ function pick(arr, random) {
32
+ return arr[Math.floor(random() * arr.length)];
33
+ }
34
+ /** A realistic US house number: mostly 1–4 digits (the common range), 25% a real 5-digit ZIP (the HARD
35
+ * case — a 5-digit leading number that is still a house number when a locality is present). */
36
+ function houseNum(random, realZips) {
37
+ if (random() < 0.25)
38
+ return pick(realZips, random);
39
+ return String(1 + Math.floor(random() * 9999));
40
+ }
41
+ // Curated, provenance-light reference vocab (real US street/city/state + DE). Surface forms must appear
42
+ // in `raw` for alignRow; these are plain ASCII tokens that align cleanly.
43
+ const STREET_NAMES = [
44
+ "Main", "Oak", "Elm", "Maple", "Cedar", "Pine", "Washington", "Lincoln", "Park", "Hill",
45
+ "Finel Hollow", "Mt Tabor", "Swasey", "Camperdown", "Mellville", "Rhone", "Westpark", "Crescent Meadow",
46
+ ];
47
+ const STREET_TYPES = ["St", "Ave", "Rd", "Dr", "Ln", "Blvd", "Ct", "Way", "Road", "Drive"];
48
+ const US_TUPLES = [
49
+ { locality: "Springfield", region: "IL", postcode: "62701" },
50
+ { locality: "Portland", region: "OR", postcode: "97215" },
51
+ { locality: "Houston", region: "TX", postcode: "77598" },
52
+ { locality: "Dallas", region: "TX", postcode: "75229" },
53
+ { locality: "Austin", region: "TX", postcode: "78748" },
54
+ { locality: "Albuquerque", region: "NM", postcode: "87102" },
55
+ { locality: "Rochester", region: "NY", postcode: "14606" },
56
+ { locality: "Sacramento", region: "CA", postcode: "95823" },
57
+ ];
58
+ // US rural states where the leading-postcode "{ZIP} {Street}, {STATE}" form (no trailing ZIP) is real —
59
+ // the VT/rural format the #723 override broke and Probe A0 eroded.
60
+ const RURAL_REGIONS = ["VT", "ND", "SD", "NH", "ME", "MT", "WY"];
61
+ // DE leading-postcode tuples: "{postcode} {locality}, {street} {house}".
62
+ const DE_TUPLES = [
63
+ { postcode: "10115", locality: "Berlin", street: "Hauptstraße" },
64
+ { postcode: "80331", locality: "München", street: "Sendlinger Straße" },
65
+ { postcode: "20095", locality: "Hamburg", street: "Mönckebergstraße" },
66
+ { postcode: "50667", locality: "Köln", street: "Hohe Straße" },
67
+ { postcode: "01067", locality: "Dresden", street: "Prager Straße" },
68
+ ];
69
+ const HOUSE_NUMS = ["5", "12", "27", "100", "212", "1450", "8"];
70
+ // Fake 5-digit strings that are NOT real US ZIPs (so the anchor lookup MISSES them) — for anchor-fp.
71
+ const FAKE_ZIPS = ["00000", "99998", "99997", "00001", "99996"];
72
+ /** Build one anchor-absorption counter-augmentation row. */
73
+ export function synthesizeAnchorAbsorptionRow(opts = {}) {
74
+ const random = opts.random ?? Math.random;
75
+ const realZips = opts.realZips && opts.realZips.length ? opts.realZips : US_TUPLES.map((t) => t.postcode);
76
+ const template = opts.forceTemplate ?? pick(ALL_TEMPLATES, random);
77
+ const street = `${pick(STREET_NAMES, random)} ${pick(STREET_TYPES, random)}`;
78
+ if (template === "h-adversarial") {
79
+ // US street, leading real-ZIP house number, WITH a trailing postcode → the leading is house_number.
80
+ const zip = pick(realZips, random);
81
+ const t = pick(US_TUPLES, random);
82
+ const raw = `${zip} ${street}, ${t.locality}, ${t.region} ${t.postcode}`;
83
+ return {
84
+ raw,
85
+ components: { house_number: zip, street, locality: t.locality, region: t.region, postcode: t.postcode },
86
+ locale: "en-US",
87
+ template,
88
+ };
89
+ }
90
+ if (template === "p-us-rural") {
91
+ // US rural, leading postcode, NO trailing postcode → the leading IS the postcode (the A0-erosion fix).
92
+ const zip = pick(realZips, random);
93
+ const region = pick(RURAL_REGIONS, random);
94
+ const raw = `${zip} ${street}, ${region}`;
95
+ return {
96
+ raw,
97
+ components: { postcode: zip, street, region },
98
+ locale: "en-US",
99
+ template,
100
+ };
101
+ }
102
+ if (template === "p-de") {
103
+ // German leading postcode "{pc} {city}, {street} {hn}" → the leading is the postcode.
104
+ const d = pick(DE_TUPLES, random);
105
+ const hn = pick(HOUSE_NUMS, random);
106
+ const raw = `${d.postcode} ${d.locality}, ${d.street} ${hn}`;
107
+ return {
108
+ raw,
109
+ components: { postcode: d.postcode, locality: d.locality, street: d.street, house_number: hn },
110
+ locale: "de-DE",
111
+ template,
112
+ };
113
+ }
114
+ if (template === "anchor-fp") {
115
+ // Leading 5-digit that is NOT a real ZIP (anchor MISSES) + trailing postcode → still house_number.
116
+ const fake = pick(FAKE_ZIPS, random);
117
+ const t = pick(US_TUPLES, random);
118
+ const raw = `${fake} ${street}, ${t.locality}, ${t.region} ${t.postcode}`;
119
+ return {
120
+ raw,
121
+ components: { house_number: fake, street, locality: t.locality, region: t.region, postcode: t.postcode },
122
+ locale: "en-US",
123
+ template,
124
+ };
125
+ }
126
+ if (template === "locale-ambig") {
127
+ // Minimal context — the LOCAL token decides. Half: "{realZip} {street}" (street-type → house#);
128
+ // half: "{realZip} {locality}" (no street, leading postcode → postcode). No trailing, no region.
129
+ const zip = pick(realZips, random);
130
+ if (random() < 0.5) {
131
+ return { raw: `${zip} ${street}`, components: { house_number: zip, street }, locale: "en-US", template };
132
+ }
133
+ const t = pick(US_TUPLES, random);
134
+ return { raw: `${zip} ${t.locality}`, components: { postcode: zip, locality: t.locality }, locale: "en-US", template };
135
+ }
136
+ if (template === "h-no-trailing-locality") {
137
+ // The A3 fix (#220): the common US format "{house#} {street}, {locality}, {STATE}" with NO trailing
138
+ // postcode → the leading number is the HOUSE NUMBER. The CONTRAST to p-us-rural (same no-trailing,
139
+ // state-bearing shape) is the LOCALITY: present here, absent there. The A2 shard lacked this slice,
140
+ // so p-us-rural's "leading-number + STATE → postcode" rule over-generalized to 98 golden house#
141
+ // rows ("36 Oxbow Dr, Bradford, VT" → postcode). The house# spans 1-4 digits AND real 5-digit ZIPs
142
+ // (the hard case: 5-digit + locality is STILL a house number, distinct from p-us-rural's no-locality).
143
+ const hn = houseNum(random, realZips);
144
+ const t = pick(US_TUPLES, random);
145
+ const region = random() < 0.5 ? pick(RURAL_REGIONS, random) : t.region;
146
+ const raw = `${hn} ${street}, ${t.locality}, ${region}`;
147
+ return {
148
+ raw,
149
+ components: { house_number: hn, street, locality: t.locality, region },
150
+ locale: "en-US",
151
+ template,
152
+ };
153
+ }
154
+ // standard: normal house number + trailing postcode → house_number (baseline, keeps the common case).
155
+ const hn = houseNum(random, realZips);
156
+ const t = pick(US_TUPLES, random);
157
+ const raw = `${hn} ${street}, ${t.locality}, ${t.region} ${t.postcode}`;
158
+ return {
159
+ raw,
160
+ components: { house_number: hn, street, locality: t.locality, region: t.region, postcode: t.postcode },
161
+ locale: "en-US",
162
+ template,
163
+ };
164
+ }
165
+ // Weighted template bag — the slice mix. Expanded to a flat array so `pick` draws at the target
166
+ // frequencies (matches the boundary-stress ALL_TEMPLATES idiom).
167
+ //
168
+ // A3 (#220, after the per-row diagnostic on the A2 probe): A1/A2 both held SLICE-H (100) + postcode
169
+ // (~98) but cost house_number (95.8->92.8), and the A2 mix-rebalance did NOT move it — so it was never a
170
+ // CASE-P-quantity problem. The row-by-row v192-vs-A2 diff (hn-regression-diff.ts) pinned it: 132/132 house#
171
+ // regressions were house#->POSTCODE on "{house#} {street}, {locality}, {STATE}" no-trailing rows — the
172
+ // p-us-rural rule ("leading-number + STATE + no-trailing -> postcode") OVER-GENERALIZED because the shard
173
+ // had NO counter-slice for the common locality-bearing house# case. A3 ADDS h-no-trailing-locality (15%)
174
+ // to teach the LOCALITY discriminator (present -> house#, absent + 5-digit -> postcode = p-us-rural) and
175
+ // trims p-us-rural 16->13. Goal: house_number recovers WITHOUT re-eroding postcode/SLICE-H. CASE-P = 26%.
176
+ export const ALL_TEMPLATES = [
177
+ ...Array(25).fill("h-adversarial"),
178
+ ...Array(15).fill("h-no-trailing-locality"),
179
+ ...Array(13).fill("p-us-rural"),
180
+ ...Array(13).fill("p-de"),
181
+ ...Array(8).fill("anchor-fp"),
182
+ ...Array(14).fill("locale-ambig"),
183
+ ...Array(12).fill("standard"),
184
+ ];
185
+ //# sourceMappingURL=synthesize-anchor-absorption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesize-anchor-absorption.js","sourceRoot":"","sources":["../../src/synthesize-anchor-absorption.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mailwoman/corpus",
3
- "version": "4.13.0",
3
+ "version": "4.15.0",
4
4
  "description": "Mailwoman corpus pipeline: BIO-labeled dataset builder for the neural classifier.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -17,14 +17,14 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@dsnp/parquetjs": "1.8.7",
20
- "@mailwoman/codex": "4.13.0",
21
- "@mailwoman/core": "4.13.0",
22
- "@mailwoman/formatter": "4.13.0",
20
+ "@mailwoman/codex": "4.15.0",
21
+ "@mailwoman/core": "4.15.0",
22
+ "@mailwoman/formatter": "4.15.0",
23
23
  "csv-parse": "^5.6.0",
24
24
  "fast-glob": "^3.3.3",
25
25
  "fastest-levenshtein": "^1.0.16",
26
26
  "lru-cache": "^10.4.3",
27
- "spliterator": "^2.0.0"
27
+ "spliterator": "^2.2.1"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/node": "^25.9.2"