@mailwoman/corpus 5.9.0 → 5.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/out/src/adapter.d.ts +1 -1
  2. package/out/src/adapters/ban/adapter.d.ts +1 -1
  3. package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -1
  4. package/out/src/adapters/geonames/adapter.d.ts +1 -1
  5. package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
  6. package/out/src/adapters/gnaf/adapter.d.ts +1 -1
  7. package/out/src/adapters/index.d.ts +19 -19
  8. package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
  9. package/out/src/adapters/overture/adapter.d.ts +1 -1
  10. package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
  11. package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
  12. package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
  13. package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
  14. package/out/src/adapters/synth-po-box/adapter.d.ts +2 -2
  15. package/out/src/adapters/tiger/adapter.d.ts +1 -1
  16. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +1 -1
  17. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
  18. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
  19. package/out/src/adapters/usgov-nad/adapter.d.ts +2 -2
  20. package/out/src/adapters/usgov-nad/adapter.js +1 -1
  21. package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
  22. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
  23. package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
  24. package/out/src/adapters/wof-admin-json/adapter.d.ts +2 -2
  25. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +2 -2
  26. package/out/src/align.d.ts +2 -2
  27. package/out/src/build.d.ts +4 -4
  28. package/out/src/index.d.ts +22 -21
  29. package/out/src/index.d.ts.map +1 -1
  30. package/out/src/index.js +1 -0
  31. package/out/src/index.js.map +1 -1
  32. package/out/src/parquet-wrapper/index.d.ts +3 -3
  33. package/out/src/parquet-wrapper/reader.d.ts +1 -1
  34. package/out/src/parquet-wrapper/writer.d.ts +4 -2
  35. package/out/src/parquet-wrapper/writer.d.ts.map +1 -1
  36. package/out/src/parquet-wrapper/writer.js +3 -1
  37. package/out/src/parquet-wrapper/writer.js.map +1 -1
  38. package/out/src/parquet.d.ts +3 -3
  39. package/out/src/runner.d.ts +2 -2
  40. package/out/src/shard-recipes/anchor-absorption.d.ts +1 -1
  41. package/out/src/shard-recipes/boundary-stress.d.ts +1 -1
  42. package/out/src/shard-recipes/country-balanced.d.ts +1 -1
  43. package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts +1 -1
  44. package/out/src/shard-recipes/fr-admin-split.d.ts +1 -1
  45. package/out/src/shard-recipes/fr-bare-street.d.ts +1 -1
  46. package/out/src/shard-recipes/fr-order.d.ts +1 -1
  47. package/out/src/shard-recipes/german.d.ts +1 -1
  48. package/out/src/shard-recipes/house-venue.d.ts +1 -1
  49. package/out/src/shard-recipes/index.d.ts +2 -2
  50. package/out/src/shard-recipes/intersection.d.ts +1 -1
  51. package/out/src/shard-recipes/locale.d.ts +2 -2
  52. package/out/src/shard-recipes/nl-postcode.d.ts +1 -1
  53. package/out/src/shard-recipes/no-street-led.d.ts +1 -1
  54. package/out/src/shard-recipes/no-street.d.ts +1 -1
  55. package/out/src/shard-recipes/po-box-cedex.d.ts +1 -1
  56. package/out/src/shard-recipes/po-box.d.ts +1 -1
  57. package/out/src/shard-recipes/si-bare-village.d.ts +1 -1
  58. package/out/src/shard-recipes/street-affix.d.ts +1 -1
  59. package/out/src/shard-recipes/street-bare.d.ts +1 -1
  60. package/out/src/shard-recipes/street.d.ts +1 -1
  61. package/out/src/shard-recipes/unit.d.ts +1 -1
  62. package/out/src/split.d.ts +1 -1
  63. package/out/src/split.js +1 -1
  64. package/out/src/split.js.map +1 -1
  65. package/out/src/synthesize-boundary-stress.d.ts +1 -1
  66. package/out/src/synthesize-german.d.ts +1 -1
  67. package/out/src/synthesize-house-venue.d.ts +1 -1
  68. package/out/src/synthesize-intersection.d.ts +1 -1
  69. package/out/src/synthesize-no-street.d.ts +1 -1
  70. package/out/src/synthesize-po-box.d.ts +1 -1
  71. package/out/src/synthesize-street.d.ts +1 -1
  72. package/out/src/synthesize.d.ts +2 -2
  73. package/out/src/tools/align-shard.d.ts +8 -0
  74. package/out/src/tools/align-shard.d.ts.map +1 -0
  75. package/out/src/tools/align-shard.js +58 -0
  76. package/out/src/tools/align-shard.js.map +1 -0
  77. package/out/src/tools/audit.d.ts +28 -0
  78. package/out/src/tools/audit.d.ts.map +1 -0
  79. package/out/src/tools/audit.js +273 -0
  80. package/out/src/tools/audit.js.map +1 -0
  81. package/out/src/tools/corpus-stats.d.ts +44 -0
  82. package/out/src/tools/corpus-stats.d.ts.map +1 -0
  83. package/out/src/tools/corpus-stats.js +151 -0
  84. package/out/src/tools/corpus-stats.js.map +1 -0
  85. package/out/src/tools/fetch/ban.d.ts +31 -0
  86. package/out/src/tools/fetch/ban.d.ts.map +1 -0
  87. package/out/src/tools/fetch/ban.js +248 -0
  88. package/out/src/tools/fetch/ban.js.map +1 -0
  89. package/out/src/tools/fetch/download.d.ts +49 -0
  90. package/out/src/tools/fetch/download.d.ts.map +1 -0
  91. package/out/src/tools/fetch/download.js +81 -0
  92. package/out/src/tools/fetch/download.js.map +1 -0
  93. package/out/src/tools/fetch/hrsa.d.ts +18 -0
  94. package/out/src/tools/fetch/hrsa.d.ts.map +1 -0
  95. package/out/src/tools/fetch/hrsa.js +46 -0
  96. package/out/src/tools/fetch/hrsa.js.map +1 -0
  97. package/out/src/tools/fetch/imls-pls.d.ts +25 -0
  98. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -0
  99. package/out/src/tools/fetch/imls-pls.js +120 -0
  100. package/out/src/tools/fetch/imls-pls.js.map +1 -0
  101. package/out/src/tools/fetch/index.d.ts +118 -0
  102. package/out/src/tools/fetch/index.d.ts.map +1 -0
  103. package/out/src/tools/fetch/index.js +117 -0
  104. package/out/src/tools/fetch/index.js.map +1 -0
  105. package/out/src/tools/fetch/nad.d.ts +56 -0
  106. package/out/src/tools/fetch/nad.d.ts.map +1 -0
  107. package/out/src/tools/fetch/nad.js +225 -0
  108. package/out/src/tools/fetch/nad.js.map +1 -0
  109. package/out/src/tools/fetch/nppes.d.ts +26 -0
  110. package/out/src/tools/fetch/nppes.d.ts.map +1 -0
  111. package/out/src/tools/fetch/nppes.js +136 -0
  112. package/out/src/tools/fetch/nppes.js.map +1 -0
  113. package/out/src/tools/fetch/openaddresses.d.ts +59 -0
  114. package/out/src/tools/fetch/openaddresses.d.ts.map +1 -0
  115. package/out/src/tools/fetch/openaddresses.js +307 -0
  116. package/out/src/tools/fetch/openaddresses.js.map +1 -0
  117. package/out/src/tools/fetch/state-hi-schools.d.ts +25 -0
  118. package/out/src/tools/fetch/state-hi-schools.d.ts.map +1 -0
  119. package/out/src/tools/fetch/state-hi-schools.js +171 -0
  120. package/out/src/tools/fetch/state-hi-schools.js.map +1 -0
  121. package/out/src/tools/fetch/state-sources.d.ts +22 -0
  122. package/out/src/tools/fetch/state-sources.d.ts.map +1 -0
  123. package/out/src/tools/fetch/state-sources.js +110 -0
  124. package/out/src/tools/fetch/state-sources.js.map +1 -0
  125. package/out/src/tools/fetch/tiger-full.d.ts +36 -0
  126. package/out/src/tools/fetch/tiger-full.d.ts.map +1 -0
  127. package/out/src/tools/fetch/tiger-full.js +239 -0
  128. package/out/src/tools/fetch/tiger-full.js.map +1 -0
  129. package/out/src/tools/golden-expand.d.ts +74 -0
  130. package/out/src/tools/golden-expand.d.ts.map +1 -0
  131. package/out/src/tools/golden-expand.js +394 -0
  132. package/out/src/tools/golden-expand.js.map +1 -0
  133. package/out/src/tools/golden-promote.d.ts +60 -0
  134. package/out/src/tools/golden-promote.d.ts.map +1 -0
  135. package/out/src/tools/golden-promote.js +223 -0
  136. package/out/src/tools/golden-promote.js.map +1 -0
  137. package/out/src/tools/index.d.ts +24 -0
  138. package/out/src/tools/index.d.ts.map +1 -0
  139. package/out/src/tools/index.js +24 -0
  140. package/out/src/tools/index.js.map +1 -0
  141. package/out/src/tools/ingest-csv.d.ts +45 -0
  142. package/out/src/tools/ingest-csv.d.ts.map +1 -0
  143. package/out/src/tools/ingest-csv.js +309 -0
  144. package/out/src/tools/ingest-csv.js.map +1 -0
  145. package/out/src/tools/jsonl-to-parquet.d.ts +49 -0
  146. package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -0
  147. package/out/src/tools/jsonl-to-parquet.js +157 -0
  148. package/out/src/tools/jsonl-to-parquet.js.map +1 -0
  149. package/out/src/tools/lint-shard-vocab.d.ts +66 -0
  150. package/out/src/tools/lint-shard-vocab.d.ts.map +1 -0
  151. package/out/src/tools/lint-shard-vocab.js +266 -0
  152. package/out/src/tools/lint-shard-vocab.js.map +1 -0
  153. package/out/src/tools/lint-shard.d.ts +73 -0
  154. package/out/src/tools/lint-shard.d.ts.map +1 -0
  155. package/out/src/tools/lint-shard.js +350 -0
  156. package/out/src/tools/lint-shard.js.map +1 -0
  157. package/out/src/tools/overlay-manifest.d.ts +35 -0
  158. package/out/src/tools/overlay-manifest.d.ts.map +1 -0
  159. package/out/src/tools/overlay-manifest.js +85 -0
  160. package/out/src/tools/overlay-manifest.js.map +1 -0
  161. package/out/src/tools/shard-kryptonite.d.ts +28 -0
  162. package/out/src/tools/shard-kryptonite.d.ts.map +1 -0
  163. package/out/src/tools/shard-kryptonite.js +101 -0
  164. package/out/src/tools/shard-kryptonite.js.map +1 -0
  165. package/out/src/tools/shard-translit.d.ts +42 -0
  166. package/out/src/tools/shard-translit.d.ts.map +1 -0
  167. package/out/src/tools/shard-translit.js +196 -0
  168. package/out/src/tools/shard-translit.js.map +1 -0
  169. package/package.json +63 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest-csv.js","sourceRoot":"","sources":["../../../src/tools/ingest-csv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Convert a JSONL of LabeledRow objects to a Parquet shard matching the v0.5.0 schema.
7
+ *
8
+ * Ported faithfully from scripts/jsonl-to-parquet.py. The Python original wrote Parquet through
9
+ * PyArrow; this writes it through DuckDB (`@duckdb/node-api`) — `read_json` with an EXPLICIT
10
+ * `columns` type map projects the validated rows to the v0.5.0 schema, then `COPY … TO … (FORMAT
11
+ * PARQUET, COMPRESSION SNAPPY, ROW_GROUP_SIZE …)` emits the shard. DuckDB reproduces the exact
12
+ * logical schema PyArrow did — `VARCHAR` (UTF8) scalars, `VARCHAR[]` (LIST<UTF8>) for the string
13
+ * arrays, and `INTEGER[]` (LIST<INT32>) for the span offsets — in the exact column order below.
14
+ * Verified field-for-field against the PyArrow original (same column order, same logical types,
15
+ * same `list<element: …>` child naming, same values), so a PyArrow reader sees an identical
16
+ * table. The trainer in any case reads shards by column name (`pq.read_table(...).to_pylist()`),
17
+ * which is blind to physical layout. INT32 matches the corpus's native TS writer
18
+ * (`@mailwoman/corpus` `LABELED_ROW_SCHEMA`), which already writes the base shards this overlay
19
+ * rides alongside.
20
+ *
21
+ * Schema: raw, tokens, labels, span_starts, span_ends, span_tags, country, locale, source,
22
+ * source_id, corpus_version, license, synth_method, synth_base_id.
23
+ *
24
+ * The span triple (#519, v0.5.0 char-offset labels) is REQUIRED on every row: `alignRow` emits it
25
+ * on every labeled row, so a row arriving without it came from a producer that hasn't migrated —
26
+ * writing it would silently drop the v0.5.0 labels from the shard. Loud failure, naming the row
27
+ * number, instead.
28
+ *
29
+ * Usage: mailwoman dev jsonl-to-parquet --input /tmp/po-box-labeled.jsonl --output
30
+ * /tmp/part-po-box.parquet
31
+ */
32
+ /** Options for {@linkcode jsonlToParquet}. */
33
+ export interface JsonlToParquetOptions {
34
+ /** The labeled-row JSONL to convert. */
35
+ input: string;
36
+ /** The parquet shard to write. */
37
+ output: string;
38
+ /** Parquet row-group size. Default 50000. */
39
+ rowGroupSize?: number;
40
+ }
41
+ /** Summary returned by {@linkcode jsonlToParquet}. */
42
+ export interface JsonlToParquetSummary {
43
+ read: number;
44
+ written: number;
45
+ outPath: string;
46
+ }
47
+ /** Convert a labeled-row JSONL to a v0.5.0-schema Parquet shard. */
48
+ export declare function jsonlToParquet(options: JsonlToParquetOptions, report?: (line: string) => void): Promise<JsonlToParquetSummary>;
49
+ //# sourceMappingURL=jsonl-to-parquet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-to-parquet.d.ts","sourceRoot":"","sources":["../../../src/tools/jsonl-to-parquet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAsDH,8CAA8C;AAC9C,MAAM,WAAW,qBAAqB;IACrC,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CACf;AAkCD,oEAAoE;AACpE,wBAAsB,cAAc,CACnC,OAAO,EAAE,qBAAqB,EAC9B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,qBAAqB,CAAC,CA8DhC"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Convert a JSONL of LabeledRow objects to a Parquet shard matching the v0.5.0 schema.
7
+ *
8
+ * Ported faithfully from scripts/jsonl-to-parquet.py. The Python original wrote Parquet through
9
+ * PyArrow; this writes it through DuckDB (`@duckdb/node-api`) — `read_json` with an EXPLICIT
10
+ * `columns` type map projects the validated rows to the v0.5.0 schema, then `COPY … TO … (FORMAT
11
+ * PARQUET, COMPRESSION SNAPPY, ROW_GROUP_SIZE …)` emits the shard. DuckDB reproduces the exact
12
+ * logical schema PyArrow did — `VARCHAR` (UTF8) scalars, `VARCHAR[]` (LIST<UTF8>) for the string
13
+ * arrays, and `INTEGER[]` (LIST<INT32>) for the span offsets — in the exact column order below.
14
+ * Verified field-for-field against the PyArrow original (same column order, same logical types,
15
+ * same `list<element: …>` child naming, same values), so a PyArrow reader sees an identical
16
+ * table. The trainer in any case reads shards by column name (`pq.read_table(...).to_pylist()`),
17
+ * which is blind to physical layout. INT32 matches the corpus's native TS writer
18
+ * (`@mailwoman/corpus` `LABELED_ROW_SCHEMA`), which already writes the base shards this overlay
19
+ * rides alongside.
20
+ *
21
+ * Schema: raw, tokens, labels, span_starts, span_ends, span_tags, country, locale, source,
22
+ * source_id, corpus_version, license, synth_method, synth_base_id.
23
+ *
24
+ * The span triple (#519, v0.5.0 char-offset labels) is REQUIRED on every row: `alignRow` emits it
25
+ * on every labeled row, so a row arriving without it came from a producer that hasn't migrated —
26
+ * writing it would silently drop the v0.5.0 labels from the shard. Loud failure, naming the row
27
+ * number, instead.
28
+ *
29
+ * Usage: mailwoman dev jsonl-to-parquet --input /tmp/po-box-labeled.jsonl --output
30
+ * /tmp/part-po-box.parquet
31
+ */
32
+ import { randomUUID } from "node:crypto";
33
+ import { createWriteStream } from "node:fs";
34
+ import { unlink } from "node:fs/promises";
35
+ import { tmpdir } from "node:os";
36
+ import { join } from "node:path";
37
+ import { TextSpliterator } from "spliterator";
38
+ const REQUIRED_COLUMNS = [
39
+ "raw",
40
+ "tokens",
41
+ "labels",
42
+ "span_starts",
43
+ "span_ends",
44
+ "span_tags",
45
+ "country",
46
+ "locale",
47
+ "source",
48
+ "source_id",
49
+ "corpus_version",
50
+ "license",
51
+ "synth_method",
52
+ "synth_base_id",
53
+ ];
54
+ const SPAN_COLUMNS = ["span_starts", "span_ends", "span_tags"];
55
+ /**
56
+ * The v0.5.0 DuckDB type for each column, in {@link REQUIRED_COLUMNS} order.
57
+ *
58
+ * Mirrors the PyArrow schema the Python original declared: `pa.string()` → `VARCHAR`, `pa.list_(pa.string())` →
59
+ * `VARCHAR[]`, `pa.list_(pa.int32())` → `INTEGER[]`. The span offsets are INT32 (#519): parallel arrays over `raw`
60
+ * (UTF-16 code units, `[start, end)` exclusive-end, sorted, non-overlapping); `raw` is a short address string, so INT32
61
+ * round-trips as a plain integer where INT64 would surface as bigint.
62
+ */
63
+ const COLUMN_TYPES = {
64
+ raw: "VARCHAR",
65
+ tokens: "VARCHAR[]",
66
+ labels: "VARCHAR[]",
67
+ span_starts: "INTEGER[]",
68
+ span_ends: "INTEGER[]",
69
+ span_tags: "VARCHAR[]",
70
+ country: "VARCHAR",
71
+ locale: "VARCHAR",
72
+ source: "VARCHAR",
73
+ source_id: "VARCHAR",
74
+ corpus_version: "VARCHAR",
75
+ license: "VARCHAR",
76
+ synth_method: "VARCHAR",
77
+ synth_base_id: "VARCHAR",
78
+ };
79
+ /**
80
+ * Enforce the #519 span contract per row: all three present, parallel lengths.
81
+ *
82
+ * A row with span_starts but no span_tags is a corrupt row — never a silent fallback.
83
+ */
84
+ function assertSpanTriple(row, lineNo) {
85
+ const present = SPAN_COLUMNS.filter((c) => row[c] != null);
86
+ if (present.length !== SPAN_COLUMNS.length) {
87
+ const missing = SPAN_COLUMNS.filter((c) => row[c] == null);
88
+ throw new Error(`line ${lineNo}: row is missing the char-offset span triple (#519): ` +
89
+ `missing ${JSON.stringify(missing)} (source_id=${JSON.stringify(row.source_id ?? null)}). Every parquet-bound row ` +
90
+ "must carry span_starts/span_ends/span_tags; re-emit this shard through alignRow.");
91
+ }
92
+ const n = row.span_starts.length;
93
+ if (row.span_ends.length !== n || row.span_tags.length !== n) {
94
+ throw new Error(`line ${lineNo}: span triple arrays are not parallel — ` +
95
+ `starts=${row.span_starts.length} ends=${row.span_ends.length} ` +
96
+ `tags=${row.span_tags.length} (source_id=${JSON.stringify(row.source_id ?? null)})`);
97
+ }
98
+ }
99
+ /** Escape a path for single-quoted SQL string literals. */
100
+ function sqlString(value) {
101
+ return value.replace(/'/g, "''");
102
+ }
103
+ /** Convert a labeled-row JSONL to a v0.5.0-schema Parquet shard. */
104
+ export async function jsonlToParquet(options, report) {
105
+ const rowGroupSize = options.rowGroupSize ?? 50000;
106
+ if (!Number.isInteger(rowGroupSize) || rowGroupSize <= 0) {
107
+ throw new Error(`rowGroupSize must be a positive integer (got ${JSON.stringify(rowGroupSize)})`);
108
+ }
109
+ // Stage the validated rows to a temp NDJSON, then let DuckDB type + write them. Streaming keeps
110
+ // memory O(1) on the Node side (the Python original buffered every column into memory first). The
111
+ // `finally` covers the validation pass too, so a mid-stream span-triple failure leaves no orphan.
112
+ const stagePath = join(tmpdir(), `mw-jsonl-to-parquet-${randomUUID()}.ndjson`);
113
+ const stage = createWriteStream(stagePath, { encoding: "utf8" });
114
+ try {
115
+ let rows = 0;
116
+ let lineNo = 0;
117
+ // TextSpliterator, not JSONSpliterator: the staging write below streams the RAW line bytes to
118
+ // DuckDB verbatim (JSON.parse here only validates), so a re-serialized JSONSpliterator row would
119
+ // defeat the point. CRLF is handled by the existing `rawLine.trim()` (strips a trailing \r),
120
+ // same as readline's crlfDelay:Infinity did.
121
+ for await (const rawLine of TextSpliterator.fromAsync(options.input)) {
122
+ lineNo++;
123
+ const line = rawLine.trim();
124
+ if (!line)
125
+ continue;
126
+ const row = JSON.parse(line);
127
+ assertSpanTriple(row, lineNo);
128
+ // Write the validated line verbatim; DuckDB's `read_json` projects to the explicit `columns`
129
+ // map below (extra keys dropped, absent keys → NULL — matching the Python `row.get(c)`).
130
+ stage.write(line + "\n");
131
+ rows++;
132
+ }
133
+ await new Promise((resolve, reject) => stage.end((err) => (err ? reject(err) : resolve())));
134
+ report?.(`Read ${rows} rows from ${options.input}`);
135
+ const columnsLiteral = "{" + REQUIRED_COLUMNS.map((c) => `'${c}': '${COLUMN_TYPES[c]}'`).join(", ") + "}";
136
+ const selectList = REQUIRED_COLUMNS.join(", ");
137
+ // @duckdb/node-api is an optional peer — lazy import (the pipeline convention).
138
+ const { DuckDBInstance } = await import("@duckdb/node-api");
139
+ const instance = await DuckDBInstance.create();
140
+ const db = await instance.connect();
141
+ // Row order is load-bearing: the overlay-manifest assembler records first/last source_id from
142
+ // shard order. `preserve_insertion_order` (DuckDB default) keeps output order = input order.
143
+ await db.run("SET preserve_insertion_order=true");
144
+ await db.run(`COPY (SELECT ${selectList} FROM read_json('${sqlString(stagePath)}', ` +
145
+ `columns = ${columnsLiteral}, format = 'newline_delimited')) ` +
146
+ `TO '${sqlString(options.output)}' (FORMAT PARQUET, COMPRESSION SNAPPY, ROW_GROUP_SIZE ${rowGroupSize})`);
147
+ const counted = await db.runAndReadAll(`SELECT count(*) AS n FROM read_parquet('${sqlString(options.output)}')`);
148
+ const written = Number(counted.getRowObjects()[0].n);
149
+ report?.(`Wrote ${written} rows to ${options.output}`);
150
+ return { read: rows, written, outPath: options.output };
151
+ }
152
+ finally {
153
+ stage.destroy();
154
+ await unlink(stagePath).catch(() => { });
155
+ }
156
+ }
157
+ //# sourceMappingURL=jsonl-to-parquet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-to-parquet.js","sourceRoot":"","sources":["../../../src/tools/jsonl-to-parquet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * #511 base-consistency lint, GENERALIZED + COUNTRY-SCOPED (v2) — any synthetic shard vs the base.
7
+ *
8
+ * Ported from scripts/lint-shard-vocab.py (pyarrow → @duckdb/node-api); behavior preserved
9
+ * byte-for-byte (same flags, same stdout, same verdicts). The base-root default routes through
10
+ * `dataRootPath` so the lab `/mnt/playpen` literal stays in its one home
11
+ * (core/utils/data-root.ts) and `$MAILWOMAN_DATA_ROOT` is honored; with the env unset it equals
12
+ * the Python default.
13
+ *
14
+ * The #511 lesson: a synthetic shard must not label a token a tag the BASE dominantly labels
15
+ * something else, or training gets conflicting gradients on the same token and the minority (the
16
+ * shard) loses. This reads a shard's own (token -> tag) and checks each token against the base.
17
+ *
18
+ * WHY v2 IS COUNTRY-SCOPED + FULL-COUNT (the night-2026-06-18 lesson, learned the hard way over
19
+ * three tries): a token's correct tag is COUNTRY-specific — "Paris" is locality in FR data and
20
+ * street in US "Paris Ave"; "Marion" is a US town AND many US "Marion" streets. So:
21
+ *
22
+ * 1. A cross-COUNTRY aggregate mis-judges any country-specific token (v1 uniform AND a proportional
23
+ * retry both false-flagged FR cities as "street" from US street-contexts).
24
+ * 2. A SMALL sample is street-BIASED regardless, because the street sources (tiger 39 + nad 378 parts)
25
+ * dwarf the locality sources (a small US-scoped spot-check read Indianapolis 54% street vs
26
+ * its true 219700:29 LOCALITY). The fix: tally each shard token's base tag SCOPED to the
27
+ * country the shard uses it in (the base has a `country` column), over a LARGE/FULL scan
28
+ * (`fraction`, default 1.0). Pure-numeric tokens excluded (house_number/postcode are
29
+ * context-determined). An affix-split flag (shard street_suffix/_prefix vs base "street") is
30
+ * EXPECTED — the loader's affix-relabel handles it; weigh those separately.
31
+ *
32
+ * Usage: mailwoman dev lint shard-vocab --shard <shard.parquet>
33
+ * [--base-version v0.5.0] [--base-root <dir>] [--fraction 1.0] [--threshold 0.7] [--min-count
34
+ * 50]
35
+ */
36
+ /** Options for {@linkcode lintShardVocab}. */
37
+ export interface LintShardVocabOptions {
38
+ /** The shard parquet to lint. */
39
+ shard: string;
40
+ /** Base corpus version. Default `v0.5.0`. */
41
+ baseVersion?: string;
42
+ /** Base corpus root. Default `$MAILWOMAN_DATA_ROOT/corpus/versioned`. */
43
+ baseRoot?: string;
44
+ /** Base-majority confidence floor for a contradiction. Default 0.7. */
45
+ threshold?: number;
46
+ /** Minimum base support to judge a token. Default 50. */
47
+ minCount?: number;
48
+ /** Fraction of base parts to scan (proportional per-source slice below 1.0). Default 1.0. */
49
+ fraction?: number;
50
+ }
51
+ /** One contradiction row: token, shard tag, base tag, base fraction, base total. */
52
+ export type ShardVocabRow = [token: string, shardTag: string, baseTag: string, baseFrac: number, baseTotal: number];
53
+ /** Findings summary returned by {@linkcode lintShardVocab}. */
54
+ export interface LintShardVocabSummary {
55
+ /** Real contradictions — the command exits 1 when nonzero. */
56
+ errors: number;
57
+ /** Affix-split rows (EXPECTED — the loader's affix-relabel handles them). */
58
+ warnings: number;
59
+ findings: {
60
+ contradictions: ShardVocabRow[];
61
+ affixSplits: ShardVocabRow[];
62
+ };
63
+ }
64
+ /** Lint a synthetic shard's (token → tag) vocabulary against the base corpus, country-scoped. */
65
+ export declare function lintShardVocab(options: LintShardVocabOptions): Promise<LintShardVocabSummary>;
66
+ //# sourceMappingURL=lint-shard-vocab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-shard-vocab.d.ts","sourceRoot":"","sources":["../../../src/tools/lint-shard-vocab.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA0JH,8CAA8C;AAC9C,MAAM,WAAW,qBAAqB;IACrC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;AAEnH,+DAA+D;AAC/D,MAAM,WAAW,qBAAqB;IACrC,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE;QAAE,cAAc,EAAE,aAAa,EAAE,CAAC;QAAC,WAAW,EAAE,aAAa,EAAE,CAAA;KAAE,CAAA;CAC3E;AAED,iGAAiG;AACjG,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA2InG"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * #511 base-consistency lint, GENERALIZED + COUNTRY-SCOPED (v2) — any synthetic shard vs the base.
7
+ *
8
+ * Ported from scripts/lint-shard-vocab.py (pyarrow → @duckdb/node-api); behavior preserved
9
+ * byte-for-byte (same flags, same stdout, same verdicts). The base-root default routes through
10
+ * `dataRootPath` so the lab `/mnt/playpen` literal stays in its one home
11
+ * (core/utils/data-root.ts) and `$MAILWOMAN_DATA_ROOT` is honored; with the env unset it equals
12
+ * the Python default.
13
+ *
14
+ * The #511 lesson: a synthetic shard must not label a token a tag the BASE dominantly labels
15
+ * something else, or training gets conflicting gradients on the same token and the minority (the
16
+ * shard) loses. This reads a shard's own (token -> tag) and checks each token against the base.
17
+ *
18
+ * WHY v2 IS COUNTRY-SCOPED + FULL-COUNT (the night-2026-06-18 lesson, learned the hard way over
19
+ * three tries): a token's correct tag is COUNTRY-specific — "Paris" is locality in FR data and
20
+ * street in US "Paris Ave"; "Marion" is a US town AND many US "Marion" streets. So:
21
+ *
22
+ * 1. A cross-COUNTRY aggregate mis-judges any country-specific token (v1 uniform AND a proportional
23
+ * retry both false-flagged FR cities as "street" from US street-contexts).
24
+ * 2. A SMALL sample is street-BIASED regardless, because the street sources (tiger 39 + nad 378 parts)
25
+ * dwarf the locality sources (a small US-scoped spot-check read Indianapolis 54% street vs
26
+ * its true 219700:29 LOCALITY). The fix: tally each shard token's base tag SCOPED to the
27
+ * country the shard uses it in (the base has a `country` column), over a LARGE/FULL scan
28
+ * (`fraction`, default 1.0). Pure-numeric tokens excluded (house_number/postcode are
29
+ * context-determined). An affix-split flag (shard street_suffix/_prefix vs base "street") is
30
+ * EXPECTED — the loader's affix-relabel handles it; weigh those separately.
31
+ *
32
+ * Usage: mailwoman dev lint shard-vocab --shard <shard.parquet>
33
+ * [--base-version v0.5.0] [--base-root <dir>] [--fraction 1.0] [--threshold 0.7] [--min-count
34
+ * 50]
35
+ */
36
+ import { readdirSync } from "node:fs";
37
+ import { join } from "node:path";
38
+ import { dataRootPath } from "@mailwoman/core/utils";
39
+ /** Strip a BIO prefix ("B-"/"I-") off a label, matching the Python `strip_bio`. */
40
+ function stripBIO(label) {
41
+ const head = label.slice(0, 2);
42
+ return head === "B-" || head === "I-" ? label.slice(2) : label;
43
+ }
44
+ /**
45
+ * Python `str.isdigit()`: non-empty and every character a Unicode digit. Pure-numeric tokens (house_number / postcode)
46
+ * are context-determined, not lexical vocab, so they're excluded. `\p{Nd}` covers the decimal digits these address
47
+ * corpora actually contain.
48
+ */
49
+ function isDigit(token) {
50
+ return token.length > 0 && /^\p{Nd}+$/u.test(token);
51
+ }
52
+ /**
53
+ * Round half to even (banker's rounding) — Python's built-in `round()` and `format(..., ".0%")` both use it, so percent
54
+ * strings and the proportional `fraction` slice match the Python output exactly.
55
+ */
56
+ function pyRound(x) {
57
+ const floor = Math.floor(x);
58
+ const diff = x - floor;
59
+ if (diff < 0.5)
60
+ return floor;
61
+ if (diff > 0.5)
62
+ return floor + 1;
63
+ return floor % 2 === 0 ? floor : floor + 1;
64
+ }
65
+ /** Format a fraction as a whole-percent string the way Python's `:.0%` does, e.g. 0.73 -> "73%". */
66
+ function pct(frac) {
67
+ return `${pyRound(frac * 100)}%`;
68
+ }
69
+ /**
70
+ * Format a float the way a Python f-string renders it: integer-valued floats keep one decimal (1.0 -> "1.0"),
71
+ * everything else is its shortest decimal (0.5 -> "0.5"). Used for the `fraction` echo so the banner matches the Python
72
+ * print.
73
+ */
74
+ function pyFloat(n) {
75
+ return Number.isInteger(n) ? n.toFixed(1) : String(n);
76
+ }
77
+ /** Left-justify to a minimum width with spaces, matching Python's `{value:N}` string field. */
78
+ function pad(value, width) {
79
+ return value.padEnd(width);
80
+ }
81
+ /**
82
+ * The dominant tag of a counter: (tag, total, fraction). Empty counter -> ("", 0, 0.0). Ties go to the first-inserted
83
+ * tag, mirroring `Counter.most_common(1)` (stable on equal counts).
84
+ */
85
+ function dominant(counter) {
86
+ let total = 0;
87
+ let bestTag = "";
88
+ let bestCount = -1;
89
+ for (const [tag, count] of counter) {
90
+ total += count;
91
+ if (count > bestCount) {
92
+ bestCount = count;
93
+ bestTag = tag;
94
+ }
95
+ }
96
+ if (total === 0)
97
+ return ["", 0, 0.0];
98
+ return [bestTag, total, bestCount / total];
99
+ }
100
+ /** Bump a (key -> count) tally, creating the inner counter on first sight. */
101
+ function bump(table, key, sub) {
102
+ let counter = table.get(key);
103
+ if (!counter) {
104
+ counter = new Map();
105
+ table.set(key, counter);
106
+ }
107
+ counter.set(sub, (counter.get(sub) ?? 0) + 1);
108
+ }
109
+ /**
110
+ * Read a corpus parquet into rows, projecting only tokens/labels/country. The list columns ride out as JSON text
111
+ * (DuckDB `to_json`) — the same trick the gazetteer builders use for nested columns — and parse back to string arrays
112
+ * here.
113
+ */
114
+ async function readRows(con, path) {
115
+ const result = await con.runAndReadAll(`SELECT to_json(tokens) AS tokens, to_json(labels) AS labels, country FROM read_parquet('${path}')`);
116
+ const raw = result.getRowObjects();
117
+ const rows = [];
118
+ for (const r of raw) {
119
+ const tokens = JSON.parse(String(r.tokens));
120
+ const labels = JSON.parse(String(r.labels));
121
+ if (!Array.isArray(tokens) || !Array.isArray(labels))
122
+ continue;
123
+ rows.push({
124
+ tokens: tokens,
125
+ labels: labels,
126
+ country: r.country == null ? null : String(r.country),
127
+ });
128
+ }
129
+ return rows;
130
+ }
131
+ /** Read just the first row's `source` value — used to group base parts for a proportional slice. */
132
+ async function readSource(con, path) {
133
+ const result = await con.runAndReadAll(`SELECT source FROM read_parquet('${path}') LIMIT 1`);
134
+ const rows = result.getRowObjects();
135
+ return rows.length ? String(rows[0].source) : "";
136
+ }
137
+ /** Non-recursive `*.parquet` glob, sorted lexicographically — the Python `sorted(glob.glob(...))`. */
138
+ function globParquet(dir) {
139
+ let names;
140
+ try {
141
+ names = readdirSync(dir);
142
+ }
143
+ catch {
144
+ return [];
145
+ }
146
+ return names
147
+ .filter((f) => f.endsWith(".parquet"))
148
+ .map((f) => join(dir, f))
149
+ .sort();
150
+ }
151
+ /** Lint a synthetic shard's (token → tag) vocabulary against the base corpus, country-scoped. */
152
+ export async function lintShardVocab(options) {
153
+ const baseVersion = options.baseVersion ?? "v0.5.0";
154
+ const baseRoot = options.baseRoot ?? dataRootPath("corpus", "versioned");
155
+ const threshold = options.threshold ?? 0.7;
156
+ const minCount = options.minCount ?? 50;
157
+ const fraction = options.fraction ?? 1.0;
158
+ // @duckdb/node-api is an optional peer — lazy import (the pipeline convention).
159
+ const { DuckDBInstance } = await import("@duckdb/node-api");
160
+ const instance = await DuckDBInstance.create();
161
+ const con = await instance.connect();
162
+ // 1. the shard's own (token -> dominant tag) + the COUNTRIES it uses each token in
163
+ const shardRows = await readRows(con, options.shard);
164
+ const shardTags = new Map();
165
+ const shardCountries = new Map();
166
+ for (const { tokens, labels, country } of shardRows) {
167
+ const n = Math.min(tokens.length, labels.length);
168
+ for (let i = 0; i < n; i++) {
169
+ const w = tokens[i];
170
+ const l = labels[i];
171
+ if (isDigit(w))
172
+ continue; // numbers are context-determined (house_number/postcode), not lexical vocab
173
+ bump(shardTags, w, stripBIO(l));
174
+ let set = shardCountries.get(w);
175
+ if (!set) {
176
+ set = new Set();
177
+ shardCountries.set(w, set);
178
+ }
179
+ set.add(country);
180
+ }
181
+ }
182
+ const shardVocab = new Set(shardTags.keys());
183
+ console.log(`shard: ${shardRows.length} rows, ${shardVocab.size} unique tokens`);
184
+ // 2. base parts — FULL by default; fraction<1 takes a proportional per-source slice (still big)
185
+ const trainDir = join(baseRoot, baseVersion, `corpus-${baseVersion}`, "train");
186
+ let parts = globParquet(trainDir);
187
+ if (!parts.length) {
188
+ throw new Error("no base parts found");
189
+ }
190
+ if (fraction < 1.0) {
191
+ const bysrc = new Map();
192
+ for (const p of parts) {
193
+ const src = await readSource(con, p);
194
+ let list = bysrc.get(src);
195
+ if (!list) {
196
+ list = [];
197
+ bysrc.set(src, list);
198
+ }
199
+ list.push(p);
200
+ }
201
+ const sliced = [];
202
+ for (const ps of bysrc.values()) {
203
+ const take = Math.max(2, pyRound(ps.length * fraction));
204
+ for (const p of ps.slice(0, take)) {
205
+ sliced.push(p);
206
+ }
207
+ }
208
+ parts = sliced;
209
+ }
210
+ console.log(`base ${baseVersion}: scanning ${parts.length} parts (fraction=${pyFloat(fraction)}), COUNTRY-scoped`);
211
+ // 3. tally each shard token's base tag, SCOPED to the country the shard uses it in
212
+ const baseTags = new Map();
213
+ for (let i = 0; i < parts.length; i++) {
214
+ const rows = await readRows(con, parts[i]);
215
+ for (const { tokens, labels, country } of rows) {
216
+ const n = Math.min(tokens.length, labels.length);
217
+ for (let j = 0; j < n; j++) {
218
+ const w = tokens[j];
219
+ if (shardVocab.has(w) && shardCountries.get(w).has(country)) {
220
+ bump(baseTags, w, stripBIO(labels[j]));
221
+ }
222
+ }
223
+ }
224
+ if ((i + 1) % 100 === 0) {
225
+ console.log(` ...${i + 1}/${parts.length} parts`);
226
+ }
227
+ }
228
+ // 4. compare; flag contradictions (affix-split is expected — surfaced but tagged)
229
+ const flagged = [];
230
+ const affix = [];
231
+ for (const w of shardVocab) {
232
+ const [sTag] = dominant(shardTags.get(w));
233
+ const [bTag, bTotal, bFrac] = dominant(baseTags.get(w) ?? new Map());
234
+ if (bTotal < minCount || !bTag || bTag === sTag || bFrac < threshold)
235
+ continue;
236
+ const row = [w, sTag, bTag, bFrac, bTotal];
237
+ if ((sTag === "street_suffix" || sTag === "street_prefix") && bTag === "street") {
238
+ affix.push(row);
239
+ }
240
+ else {
241
+ flagged.push(row);
242
+ }
243
+ }
244
+ const sections = [
245
+ ["CONTRADICTION", flagged],
246
+ ["affix-split (EXPECTED — affix-relabel handles)", affix],
247
+ ];
248
+ for (const [label, rows] of sections) {
249
+ if (!rows.length)
250
+ continue;
251
+ rows.sort((a, b) => b[4] - a[4] || b[3] - a[3]);
252
+ console.log(`\n${label.startsWith("CONTRA") ? "⚠️ " : "· "}${rows.length} ${label}:`);
253
+ for (const [w, sTag, bTag, bFrac, bTotal] of rows) {
254
+ console.log(` ${pad(w, 18)} shard=${pad(sTag, 14)} base=${bTag} (${pct(bFrac)}, n=${bTotal})`);
255
+ }
256
+ }
257
+ if (!flagged.length) {
258
+ console.log(`\n✅ NO real contradictions (country-scoped, threshold ${pct(threshold)}, support ${minCount}) — shard base-consistent`);
259
+ }
260
+ return {
261
+ errors: flagged.length,
262
+ warnings: affix.length,
263
+ findings: { contradictions: flagged, affixSplits: affix },
264
+ };
265
+ }
266
+ //# sourceMappingURL=lint-shard-vocab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-shard-vocab.js","sourceRoot":"","sources":["../../../src/tools/lint-shard-vocab.ts"],"names":[],"mappings":"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"}