@mailwoman/corpus 10.6.0 → 10.7.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 (223) hide show
  1. package/data/PROVENANCE.md +24 -0
  2. package/data/address-source-register.json +18948 -8757
  3. package/data/corpus-source-inputs.json +4756 -0
  4. package/data/license-decisions.json +7260 -0
  5. package/data/licenses/whosonfirst-licenses.md +3 -2
  6. package/data/reviewed-ve-postcode-tuples.json +5 -72
  7. package/data/source-additions.json +2450 -0
  8. package/data/source-resolutions.json +87 -0
  9. package/data/training-manifests/v0.7.10-gb-county.effective.json +2335 -0
  10. package/data/training-manifests/v0.7.10-gb-county.json +1132 -0
  11. package/data/training-manifests/v0.7.2-address-systems.effective.json +3 -2
  12. package/data/training-manifests/v0.7.7-no-ppd.json +550 -0
  13. package/data/training-manifests/v0.7.8-rights-clean.json +538 -0
  14. package/data/training-manifests/v0.7.9-country-gap.json +1132 -0
  15. package/data/us-situs-sources.json +128 -0
  16. package/lib/adapters/cordis/adapter.ts +1 -1
  17. package/lib/adapters/libpostal-dictionary.ts +23 -3
  18. package/lib/adapters/osm/adapter.ts +42 -11
  19. package/lib/adapters.ts +14 -0
  20. package/lib/az/adapters/opendata/adapter.ts +389 -0
  21. package/lib/bs/adapters/gbpa/adapter.ts +248 -0
  22. package/lib/build/types.ts +16 -0
  23. package/lib/build.ts +21 -0
  24. package/lib/ee/adapters/ads/adapter.ts +18 -0
  25. package/lib/fo/adapters/adressur/adapter.ts +242 -0
  26. package/lib/gb/adapters/os-open/adapter.ts +12 -0
  27. package/lib/gb/county.ts +59 -0
  28. package/lib/gb/os-open/open/names.ts +41 -0
  29. package/lib/gu/adapters/bsp/adapter.ts +434 -0
  30. package/lib/im/adapters/land-registry/adapter.ts +340 -0
  31. package/lib/international/recipes/locale.ts +164 -19
  32. package/lib/li/adapters/llv/adapter.ts +246 -0
  33. package/lib/recipes/bare/postcode.ts +10 -34
  34. package/lib/recipes/country-balanced.ts +95 -78
  35. package/lib/recipes/intersection.ts +22 -30
  36. package/lib/recipes/po/box/cedex/recipe.ts +8 -5
  37. package/lib/recipes/po/box/cedex/sources.ts +2 -23
  38. package/lib/recipes/scaffold.ts +28 -3
  39. package/lib/recipes/sources.ts +112 -1
  40. package/lib/recipes/street/affix.ts +17 -29
  41. package/lib/recipes/sub/venue/context.ts +33 -9
  42. package/lib/recipes/sub/venue/sources.ts +54 -13
  43. package/lib/recipes/sub/venue.ts +68 -23
  44. package/lib/recipes/unit.ts +20 -7
  45. package/lib/registers.ts +33 -0
  46. package/lib/source-register/corpus-inputs.ts +528 -0
  47. package/lib/source-register/effective-manifest.ts +37 -5
  48. package/lib/source-register/types.ts +20 -0
  49. package/lib/south-asia/recipes/register.ts +1 -1
  50. package/lib/tools/overlay/manifest.ts +109 -1
  51. package/lib/tools/source-register/build.ts +47 -1
  52. package/lib/tools/variety-sample.ts +633 -0
  53. package/lib/us/adapters/usgov/nad/adapter.ts +39 -10
  54. package/lib/us/recipes/skeleton-sources.ts +156 -0
  55. package/lib/us/tools/nad-skeletons.ts +395 -0
  56. package/lib/uy/adapters/ide/adapter.ts +275 -0
  57. package/lib/ve/recipes/reviewed-postcode-tail.ts +29 -6
  58. package/out/adapters/cordis/adapter.d.ts +1 -1
  59. package/out/adapters/cordis/adapter.js +1 -1
  60. package/out/adapters/libpostal-dictionary.d.ts +9 -0
  61. package/out/adapters/libpostal-dictionary.d.ts.map +1 -1
  62. package/out/adapters/libpostal-dictionary.js +19 -3
  63. package/out/adapters/libpostal-dictionary.js.map +1 -1
  64. package/out/adapters/osm/adapter.d.ts +12 -1
  65. package/out/adapters/osm/adapter.d.ts.map +1 -1
  66. package/out/adapters/osm/adapter.js +30 -13
  67. package/out/adapters/osm/adapter.js.map +1 -1
  68. package/out/adapters.d.ts.map +1 -1
  69. package/out/adapters.js +14 -0
  70. package/out/adapters.js.map +1 -1
  71. package/out/az/adapters/opendata/adapter.d.ts +88 -0
  72. package/out/az/adapters/opendata/adapter.d.ts.map +1 -0
  73. package/out/az/adapters/opendata/adapter.js +282 -0
  74. package/out/az/adapters/opendata/adapter.js.map +1 -0
  75. package/out/bs/adapters/gbpa/adapter.d.ts +64 -0
  76. package/out/bs/adapters/gbpa/adapter.d.ts.map +1 -0
  77. package/out/bs/adapters/gbpa/adapter.js +187 -0
  78. package/out/bs/adapters/gbpa/adapter.js.map +1 -0
  79. package/out/build/types.d.ts +15 -0
  80. package/out/build/types.d.ts.map +1 -1
  81. package/out/build/types.js.map +1 -1
  82. package/out/build.d.ts.map +1 -1
  83. package/out/build.js +17 -0
  84. package/out/build.js.map +1 -1
  85. package/out/ee/adapters/ads/adapter.d.ts +6 -0
  86. package/out/ee/adapters/ads/adapter.d.ts.map +1 -1
  87. package/out/ee/adapters/ads/adapter.js +16 -0
  88. package/out/ee/adapters/ads/adapter.js.map +1 -1
  89. package/out/fo/adapters/adressur/adapter.d.ts +63 -0
  90. package/out/fo/adapters/adressur/adapter.d.ts.map +1 -0
  91. package/out/fo/adapters/adressur/adapter.js +177 -0
  92. package/out/fo/adapters/adressur/adapter.js.map +1 -0
  93. package/out/gb/adapters/os-open/adapter.d.ts +8 -0
  94. package/out/gb/adapters/os-open/adapter.d.ts.map +1 -1
  95. package/out/gb/adapters/os-open/adapter.js +11 -0
  96. package/out/gb/adapters/os-open/adapter.js.map +1 -1
  97. package/out/gb/county.d.ts +30 -0
  98. package/out/gb/county.d.ts.map +1 -0
  99. package/out/gb/county.js +51 -0
  100. package/out/gb/county.js.map +1 -0
  101. package/out/gb/os-open/open/names.d.ts +17 -0
  102. package/out/gb/os-open/open/names.d.ts.map +1 -1
  103. package/out/gb/os-open/open/names.js +19 -0
  104. package/out/gb/os-open/open/names.js.map +1 -1
  105. package/out/gu/adapters/bsp/adapter.d.ts +83 -0
  106. package/out/gu/adapters/bsp/adapter.d.ts.map +1 -0
  107. package/out/gu/adapters/bsp/adapter.js +346 -0
  108. package/out/gu/adapters/bsp/adapter.js.map +1 -0
  109. package/out/im/adapters/land-registry/adapter.d.ts +68 -0
  110. package/out/im/adapters/land-registry/adapter.d.ts.map +1 -0
  111. package/out/im/adapters/land-registry/adapter.js +261 -0
  112. package/out/im/adapters/land-registry/adapter.js.map +1 -0
  113. package/out/international/recipes/locale.d.ts +24 -4
  114. package/out/international/recipes/locale.d.ts.map +1 -1
  115. package/out/international/recipes/locale.js +107 -15
  116. package/out/international/recipes/locale.js.map +1 -1
  117. package/out/li/adapters/llv/adapter.d.ts +69 -0
  118. package/out/li/adapters/llv/adapter.d.ts.map +1 -0
  119. package/out/li/adapters/llv/adapter.js +181 -0
  120. package/out/li/adapters/llv/adapter.js.map +1 -0
  121. package/out/recipes/bare/postcode.d.ts.map +1 -1
  122. package/out/recipes/bare/postcode.js +9 -30
  123. package/out/recipes/bare/postcode.js.map +1 -1
  124. package/out/recipes/country-balanced.d.ts.map +1 -1
  125. package/out/recipes/country-balanced.js +82 -73
  126. package/out/recipes/country-balanced.js.map +1 -1
  127. package/out/recipes/intersection.d.ts +3 -2
  128. package/out/recipes/intersection.d.ts.map +1 -1
  129. package/out/recipes/intersection.js +20 -26
  130. package/out/recipes/intersection.js.map +1 -1
  131. package/out/recipes/po/box/cedex/recipe.d.ts.map +1 -1
  132. package/out/recipes/po/box/cedex/recipe.js +5 -4
  133. package/out/recipes/po/box/cedex/recipe.js.map +1 -1
  134. package/out/recipes/po/box/cedex/sources.d.ts +2 -45
  135. package/out/recipes/po/box/cedex/sources.d.ts.map +1 -1
  136. package/out/recipes/po/box/cedex/sources.js +0 -20
  137. package/out/recipes/po/box/cedex/sources.js.map +1 -1
  138. package/out/recipes/scaffold.d.ts +15 -2
  139. package/out/recipes/scaffold.d.ts.map +1 -1
  140. package/out/recipes/scaffold.js +21 -1
  141. package/out/recipes/scaffold.js.map +1 -1
  142. package/out/recipes/sources.d.ts.map +1 -1
  143. package/out/recipes/sources.js +112 -1
  144. package/out/recipes/sources.js.map +1 -1
  145. package/out/recipes/street/affix.d.ts.map +1 -1
  146. package/out/recipes/street/affix.js +8 -20
  147. package/out/recipes/street/affix.js.map +1 -1
  148. package/out/recipes/sub/venue/context.d.ts +14 -3
  149. package/out/recipes/sub/venue/context.d.ts.map +1 -1
  150. package/out/recipes/sub/venue/context.js +29 -9
  151. package/out/recipes/sub/venue/context.js.map +1 -1
  152. package/out/recipes/sub/venue/sources.d.ts +41 -8
  153. package/out/recipes/sub/venue/sources.d.ts.map +1 -1
  154. package/out/recipes/sub/venue/sources.js +26 -7
  155. package/out/recipes/sub/venue/sources.js.map +1 -1
  156. package/out/recipes/sub/venue.d.ts.map +1 -1
  157. package/out/recipes/sub/venue.js +35 -14
  158. package/out/recipes/sub/venue.js.map +1 -1
  159. package/out/recipes/unit.d.ts +4 -0
  160. package/out/recipes/unit.d.ts.map +1 -1
  161. package/out/recipes/unit.js +7 -6
  162. package/out/recipes/unit.js.map +1 -1
  163. package/out/registers.d.ts +33 -0
  164. package/out/registers.d.ts.map +1 -1
  165. package/out/registers.js +33 -0
  166. package/out/registers.js.map +1 -1
  167. package/out/source-register/corpus-inputs.d.ts +240 -0
  168. package/out/source-register/corpus-inputs.d.ts.map +1 -0
  169. package/out/source-register/corpus-inputs.js +275 -0
  170. package/out/source-register/corpus-inputs.js.map +1 -0
  171. package/out/source-register/effective-manifest.d.ts +2 -0
  172. package/out/source-register/effective-manifest.d.ts.map +1 -1
  173. package/out/source-register/effective-manifest.js +33 -4
  174. package/out/source-register/effective-manifest.js.map +1 -1
  175. package/out/source-register/types.d.ts +21 -1
  176. package/out/source-register/types.d.ts.map +1 -1
  177. package/out/source-register/types.js +20 -0
  178. package/out/source-register/types.js.map +1 -1
  179. package/out/south-asia/recipes/register.js +1 -1
  180. package/out/south-asia/recipes/register.js.map +1 -1
  181. package/out/tools/overlay/manifest.d.ts +7 -0
  182. package/out/tools/overlay/manifest.d.ts.map +1 -1
  183. package/out/tools/overlay/manifest.js +72 -1
  184. package/out/tools/overlay/manifest.js.map +1 -1
  185. package/out/tools/source-register/build.d.ts +9 -0
  186. package/out/tools/source-register/build.d.ts.map +1 -1
  187. package/out/tools/source-register/build.js +25 -3
  188. package/out/tools/source-register/build.js.map +1 -1
  189. package/out/tools/variety-sample.d.ts +196 -0
  190. package/out/tools/variety-sample.d.ts.map +1 -0
  191. package/out/tools/variety-sample.js +417 -0
  192. package/out/tools/variety-sample.js.map +1 -0
  193. package/out/us/adapters/usgov/nad/adapter.d.ts +80 -0
  194. package/out/us/adapters/usgov/nad/adapter.d.ts.map +1 -1
  195. package/out/us/adapters/usgov/nad/adapter.js +27 -8
  196. package/out/us/adapters/usgov/nad/adapter.js.map +1 -1
  197. package/out/us/recipes/skeleton-sources.d.ts +92 -0
  198. package/out/us/recipes/skeleton-sources.d.ts.map +1 -0
  199. package/out/us/recipes/skeleton-sources.js +121 -0
  200. package/out/us/recipes/skeleton-sources.js.map +1 -0
  201. package/out/us/tools/nad-skeletons.d.ts +120 -0
  202. package/out/us/tools/nad-skeletons.d.ts.map +1 -0
  203. package/out/us/tools/nad-skeletons.js +262 -0
  204. package/out/us/tools/nad-skeletons.js.map +1 -0
  205. package/out/uy/adapters/ide/adapter.d.ts +64 -0
  206. package/out/uy/adapters/ide/adapter.d.ts.map +1 -0
  207. package/out/uy/adapters/ide/adapter.js +206 -0
  208. package/out/uy/adapters/ide/adapter.js.map +1 -0
  209. package/out/ve/recipes/reviewed-postcode-tail.d.ts +6 -2
  210. package/out/ve/recipes/reviewed-postcode-tail.d.ts.map +1 -1
  211. package/out/ve/recipes/reviewed-postcode-tail.js +16 -5
  212. package/out/ve/recipes/reviewed-postcode-tail.js.map +1 -1
  213. package/package.json +14 -14
  214. package/lib/recipes/unit/sources.ts +0 -44
  215. package/lib/tools/fetch/ppd.ts +0 -121
  216. package/out/recipes/unit/sources.d.ts +0 -28
  217. package/out/recipes/unit/sources.d.ts.map +0 -1
  218. package/out/recipes/unit/sources.js +0 -30
  219. package/out/recipes/unit/sources.js.map +0 -1
  220. package/out/tools/fetch/ppd.d.ts +0 -15
  221. package/out/tools/fetch/ppd.d.ts.map +0 -1
  222. package/out/tools/fetch/ppd.js +0 -86
  223. package/out/tools/fetch/ppd.js.map +0 -1
@@ -0,0 +1,240 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Joins a corpus source id to the register sources whose data its rows are built from.
7
+ *
8
+ * A corpus source id is the `source` value stored on every corpus row, keyed by a training config's
9
+ * `source_weights` and listed in a training manifest. The register scopes a source to one publisher in one
10
+ * jurisdiction and records its license decision. This table is the one record joining the two. Before it, a source whose
11
+ * register row was refused or never read could feed a corpus build and a training run: HM Land Registry Price Paid
12
+ * Data reached `rendered-gb` and `spliced-sub-venue` while its row read `unchecked` (#2635).
13
+ *
14
+ * The table is `packages/corpus/data/corpus-source-inputs.json`. A derived or synthetic source lists every input
15
+ * whose data reaches one of its rows. An input with no register row gets one in `source-additions.json`, under an
16
+ * `unchecked` decision, so the gap reads as a gap rather than as an absence.
17
+ */
18
+ import type { PathBuilderLike } from "path-ts";
19
+ import { SourceOperation, type AddressSourceRegister, type LicenseDecision } from "#source-register/types";
20
+ /**
21
+ * The operations a register decision must permit before a source's rows may
22
+ * be built into a corpus or trained on.
23
+ *
24
+ * Both need adaptation: normalizing an address into labeled components is a derived work,
25
+ * and fitting a model on it is another.
26
+ */
27
+ export declare const TRAINING_OPERATIONS: readonly SourceOperation[];
28
+ /**
29
+ * One register source whose data reaches a corpus source's rows.
30
+ */
31
+ export interface CorpusSourceInput {
32
+ /**
33
+ * The register's `sourceID`.
34
+ */
35
+ registerSource: string;
36
+ /**
37
+ * The `licenseID` that register source points at, repeated so a reviewer reads the decision key here.
38
+ *
39
+ * {@linkcode auditCorpusSourceInputs} refuses a value that disagrees with the register.
40
+ */
41
+ license: string;
42
+ /**
43
+ * What the corpus source reads from it: the file, the fields and the component they fill.
44
+ */
45
+ reads: string;
46
+ }
47
+ /**
48
+ * Everything one corpus source's rows are built from.
49
+ */
50
+ export interface CorpusSourceMapping {
51
+ /**
52
+ * Other spellings rows of this source are stored under, such as the retired `synth-*` spelling.
53
+ */
54
+ aliases?: readonly string[];
55
+ /**
56
+ * Every register source whose data reaches a row.
57
+ */
58
+ inputs: readonly CorpusSourceInput[];
59
+ /**
60
+ * Inputs written in this repository, which need no register row: a hand-written word list, a template.
61
+ */
62
+ authored?: readonly string[];
63
+ note?: string;
64
+ /**
65
+ * What the source read in corpora built before its producer changed inputs under the same id.
66
+ *
67
+ * `inputs` describes what a build reads today.
68
+ * The build and training checks read it.
69
+ *
70
+ * A corpus already built keeps the rows it was built from, so the release audit reads the
71
+ * entry naming that corpus: `spliced-sub-venue` kept its name when its GB skeletons moved from
72
+ * Price Paid Data to OS OpenData, and the published model trained on the Price Paid Data rows.
73
+ */
74
+ history?: readonly CorpusSourceHistory[];
75
+ }
76
+ /**
77
+ * The inputs one source read in the corpora named.
78
+ */
79
+ export interface CorpusSourceHistory {
80
+ corpora: readonly string[];
81
+ inputs: readonly CorpusSourceInput[];
82
+ because: string;
83
+ }
84
+ /**
85
+ * The committed table.
86
+ */
87
+ export interface CorpusSourceInputsFile {
88
+ sources: Readonly<Record<string, CorpusSourceMapping>>;
89
+ }
90
+ /**
91
+ * The table indexed for lookup under every spelling it records.
92
+ */
93
+ export interface CorpusSourceInputs {
94
+ readonly file: CorpusSourceInputsFile;
95
+ /**
96
+ * The mapping a spelling resolves to, with the id it is filed under.
97
+ */
98
+ resolve(source: string): {
99
+ id: string;
100
+ mapping: CorpusSourceMapping;
101
+ } | null;
102
+ }
103
+ /**
104
+ * Resolves the committed table through the package's `./data/*` export.
105
+ */
106
+ export declare function corpusSourceInputsPath(): string;
107
+ /**
108
+ * Indexes a table by id and alias.
109
+ *
110
+ * @throws When two entries claim one spelling, because a lookup would then answer for whichever came last.
111
+ */
112
+ export declare function indexCorpusSourceInputs(file: CorpusSourceInputsFile): CorpusSourceInputs;
113
+ /**
114
+ * One message per structural problem in the table, read against the register.
115
+ */
116
+ export declare function auditCorpusSourceInputs(file: CorpusSourceInputsFile, register: AddressSourceRegister): string[];
117
+ /**
118
+ * Reads the committed table and checks it against the register.
119
+ *
120
+ * @throws When the file does not parse or the audit reports a problem.
121
+ */
122
+ export declare function readCorpusSourceInputs(register: AddressSourceRegister, path?: PathBuilderLike): Promise<CorpusSourceInputs>;
123
+ /**
124
+ * Why one corpus source lacks the permission {@linkcode TRAINING_OPERATIONS} need.
125
+ */
126
+ export interface SourceRightsGap {
127
+ /**
128
+ * The corpus source id as the caller named it.
129
+ */
130
+ source: string;
131
+ /**
132
+ * The register source lacking the permission, or `null` when the table has no entry for the corpus source.
133
+ */
134
+ registerSource: string | null;
135
+ licenseID: string | null;
136
+ /**
137
+ * The decision's review state, or `null` when there is no decision to read.
138
+ */
139
+ state: LicenseDecision["state"] | null;
140
+ /**
141
+ * The operations the decision does not permit.
142
+ */
143
+ missing: SourceOperation[];
144
+ because: string;
145
+ }
146
+ /**
147
+ * Every reason a corpus source's rows may not be built into a corpus or trained on.
148
+ *
149
+ * An empty array is the only answer a caller may read as permission.
150
+ * A source the table does not map answers one gap whose `registerSource` is `null`,
151
+ * because an unmapped source is one nobody has traced to its publishers.
152
+ *
153
+ * `corpusVersion` names a corpus already built, so a source whose inputs changed under
154
+ * the same id is read against what that corpus's rows were built from.
155
+ * A build or training check omits it and reads today's inputs.
156
+ */
157
+ export declare function sourceRightsGaps(source: string, inputs: CorpusSourceInputs, register: AddressSourceRegister, corpusVersion?: string): SourceRightsGap[];
158
+ /**
159
+ * One line naming the corpus source, the register row and the missing permission.
160
+ */
161
+ export declare function describeSourceRightsGap(gap: SourceRightsGap): string;
162
+ /**
163
+ * Raised when a build or training run would admit a source lacking the permission.
164
+ */
165
+ export declare class SourceRightsError extends Error {
166
+ readonly gaps: readonly SourceRightsGap[];
167
+ constructor(context: string, gaps: readonly SourceRightsGap[]);
168
+ }
169
+ /**
170
+ * What a checked output records about the sources it admitted.
171
+ *
172
+ * Its field names are snake_case because it is written into corpus manifests,
173
+ * which a Python reader also reads.
174
+ */
175
+ export interface SourceRightsRecord {
176
+ /**
177
+ * False when an override admitted a source lacking the permission.
178
+ */
179
+ shippable: boolean;
180
+ unshippable_reason: string | null;
181
+ /**
182
+ * Every corpus source the check read, sorted.
183
+ */
184
+ sources_checked: string[];
185
+ gaps: SourceRightsGap[];
186
+ /**
187
+ * Inputs whose corpus sources could not be read, so the check could not judge them,
188
+ * such as a base corpus whose files name no source and whose manifest carries no record.
189
+ */
190
+ unverified: string[];
191
+ }
192
+ /**
193
+ * Checks corpus sources one at a time as an output admits them.
194
+ */
195
+ export interface SourceRightsAdmission {
196
+ /**
197
+ * Admits a source or throws {@linkcode SourceRightsError}.
198
+ *
199
+ * Under an override it logs each gap once and returns them instead.
200
+ */
201
+ admit(source: string): readonly SourceRightsGap[];
202
+ /**
203
+ * Admits several sources at once, so a refusal names every one of them.
204
+ */
205
+ admitAll(sources: Iterable<string>): readonly SourceRightsGap[];
206
+ /**
207
+ * Refuses an input whose sources cannot be read, or records it under an override.
208
+ *
209
+ * An input the check cannot read stays unverified rather than clear.
210
+ */
211
+ admitUnverified(description: string): void;
212
+ record(): SourceRightsRecord;
213
+ }
214
+ /**
215
+ * Options for {@linkcode createSourceRightsAdmission}.
216
+ */
217
+ export interface SourceRightsAdmissionOptions {
218
+ /**
219
+ * Names the output in a refusal, as `corpus build v0.7.7` or `recipe sub-venue`.
220
+ */
221
+ context: string;
222
+ /**
223
+ * Why a local experiment admits sources lacking the permission.
224
+ *
225
+ * Setting it marks the output unshippable rather than relaxing the rule.
226
+ */
227
+ unshippableReason?: string | null;
228
+ log?: (line: string) => void;
229
+ }
230
+ /**
231
+ * Builds the admission check over an already-read register and table.
232
+ *
233
+ * @throws When `unshippableReason` is set and blank, because an override must say why.
234
+ */
235
+ export declare function createSourceRightsAdmission(register: AddressSourceRegister, inputs: CorpusSourceInputs, options: SourceRightsAdmissionOptions): SourceRightsAdmission;
236
+ /**
237
+ * Reads the committed register and table and builds the admission check over them.
238
+ */
239
+ export declare function openSourceRightsAdmission(options: SourceRightsAdmissionOptions): Promise<SourceRightsAdmission>;
240
+ //# sourceMappingURL=corpus-inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus-inputs.d.ts","sourceRoot":"","sources":["../../lib/source-register/corpus-inputs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,275 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Joins a corpus source id to the register sources whose data its rows are built from.
7
+ *
8
+ * A corpus source id is the `source` value stored on every corpus row, keyed by a training config's
9
+ * `source_weights` and listed in a training manifest. The register scopes a source to one publisher in one
10
+ * jurisdiction and records its license decision. This table is the one record joining the two. Before it, a source whose
11
+ * register row was refused or never read could feed a corpus build and a training run: HM Land Registry Price Paid
12
+ * Data reached `rendered-gb` and `spliced-sub-venue` while its row read `unchecked` (#2635).
13
+ *
14
+ * The table is `packages/corpus/data/corpus-source-inputs.json`. A derived or synthetic source lists every input
15
+ * whose data reaches one of its rows. An input with no register row gets one in `source-additions.json`, under an
16
+ * `unchecked` decision, so the gap reads as a gap rather than as an absence.
17
+ */
18
+ import { readLocalJSONFile } from "@mailwoman/core/fs/readers";
19
+ import { stringifyJSON } from "@mailwoman/core/json";
20
+ import { resolveModulePath } from "@mailwoman/core/module/resolvers";
21
+ import { permissionFor, readAddressSourceRegister } from "#source-register/register";
22
+ import { LicenseReviewState, OperationPermission, SourceOperation, } from "#source-register/types";
23
+ /**
24
+ * The operations a register decision must permit before a source's rows may
25
+ * be built into a corpus or trained on.
26
+ *
27
+ * Both need adaptation: normalizing an address into labeled components is a derived work,
28
+ * and fitting a model on it is another.
29
+ */
30
+ export const TRAINING_OPERATIONS = [SourceOperation.Transform, SourceOperation.Train];
31
+ /**
32
+ * Resolves the committed table through the package's `./data/*` export.
33
+ */
34
+ export function corpusSourceInputsPath() {
35
+ return resolveModulePath("@mailwoman/corpus/data/corpus-source-inputs.json");
36
+ }
37
+ /**
38
+ * Indexes a table by id and alias.
39
+ *
40
+ * @throws When two entries claim one spelling, because a lookup would then answer for whichever came last.
41
+ */
42
+ export function indexCorpusSourceInputs(file) {
43
+ const bySpelling = new Map();
44
+ for (const [id, mapping] of Object.entries(file.sources)) {
45
+ for (const spelling of [id, ...(mapping.aliases ?? [])]) {
46
+ const claimed = bySpelling.get(spelling);
47
+ if (claimed && claimed !== id) {
48
+ throw new Error(`corpus source spelling ${stringifyJSON(spelling)} is claimed by both ${claimed} and ${id}`);
49
+ }
50
+ bySpelling.set(spelling, id);
51
+ }
52
+ }
53
+ return {
54
+ file,
55
+ resolve(source) {
56
+ const id = bySpelling.get(source);
57
+ return id ? { id, mapping: file.sources[id] } : null;
58
+ },
59
+ };
60
+ }
61
+ /**
62
+ * One message per structural problem in the table, read against the register.
63
+ */
64
+ export function auditCorpusSourceInputs(file, register) {
65
+ const problems = [];
66
+ const sources = new Map(register.sources.map((source) => [source.sourceID, source]));
67
+ for (const [id, mapping] of Object.entries(file.sources)) {
68
+ const named = stringifyJSON(id);
69
+ if (!mapping.inputs.length && !mapping.authored?.length) {
70
+ problems.push(`corpus source ${named} lists no input, so nothing records what its rows are built from`);
71
+ }
72
+ for (const entry of mapping.history ?? []) {
73
+ if (!entry.corpora.length || !entry.because) {
74
+ problems.push(`corpus source ${named} has a history entry naming no corpus or giving no reason`);
75
+ }
76
+ }
77
+ for (const input of [...mapping.inputs, ...(mapping.history ?? []).flatMap((entry) => entry.inputs)]) {
78
+ const row = sources.get(input.registerSource);
79
+ if (!row) {
80
+ problems.push(`corpus source ${named} reads register source ${stringifyJSON(input.registerSource)}, which the register ` +
81
+ "does not carry. Add the row to `source-additions.json` and regenerate the register.");
82
+ continue;
83
+ }
84
+ if (row.license !== input.license) {
85
+ problems.push(`corpus source ${named} records license ${stringifyJSON(input.license)} for ${input.registerSource}, ` +
86
+ `and the register points that source at ${stringifyJSON(row.license)}`);
87
+ }
88
+ if (!input.reads) {
89
+ problems.push(`corpus source ${named} reads ${input.registerSource} and does not say what it reads`);
90
+ }
91
+ }
92
+ }
93
+ return problems;
94
+ }
95
+ /**
96
+ * Reads the committed table and checks it against the register.
97
+ *
98
+ * @throws When the file does not parse or the audit reports a problem.
99
+ */
100
+ export async function readCorpusSourceInputs(register, path) {
101
+ const resolved = path ?? corpusSourceInputsPath();
102
+ const file = await readLocalJSONFile(resolved);
103
+ const problems = auditCorpusSourceInputs(file, register);
104
+ if (problems.length) {
105
+ throw new Error(`${resolved} failed its audit against the register:\n ${problems.join("\n ")}`);
106
+ }
107
+ return indexCorpusSourceInputs(file);
108
+ }
109
+ /**
110
+ * Every reason a corpus source's rows may not be built into a corpus or trained on.
111
+ *
112
+ * An empty array is the only answer a caller may read as permission.
113
+ * A source the table does not map answers one gap whose `registerSource` is `null`,
114
+ * because an unmapped source is one nobody has traced to its publishers.
115
+ *
116
+ * `corpusVersion` names a corpus already built, so a source whose inputs changed under
117
+ * the same id is read against what that corpus's rows were built from.
118
+ * A build or training check omits it and reads today's inputs.
119
+ */
120
+ export function sourceRightsGaps(source, inputs, register, corpusVersion) {
121
+ const resolved = inputs.resolve(source);
122
+ if (!resolved) {
123
+ return [
124
+ {
125
+ source,
126
+ registerSource: null,
127
+ licenseID: null,
128
+ state: null,
129
+ missing: [...TRAINING_OPERATIONS],
130
+ because: "no entry in packages/corpus/data/corpus-source-inputs.json says which register sources its rows are " +
131
+ "built from",
132
+ },
133
+ ];
134
+ }
135
+ const decisions = new Map(register.licenses.map((decision) => [decision.licenseID, decision]));
136
+ const rows = new Map(register.sources.map((row) => [row.sourceID, row]));
137
+ const gaps = [];
138
+ const former = corpusVersion
139
+ ? resolved.mapping.history?.find((entry) => entry.corpora.includes(corpusVersion))
140
+ : undefined;
141
+ for (const input of former?.inputs ?? resolved.mapping.inputs) {
142
+ const row = rows.get(input.registerSource);
143
+ const decision = row ? decisions.get(row.license) : undefined;
144
+ if (!row || !decision) {
145
+ gaps.push({
146
+ source,
147
+ registerSource: input.registerSource,
148
+ licenseID: row?.license ?? null,
149
+ state: null,
150
+ missing: [...TRAINING_OPERATIONS],
151
+ because: row
152
+ ? `the register declares no decision ${stringifyJSON(row.license)}`
153
+ : "the register has no such row",
154
+ });
155
+ continue;
156
+ }
157
+ const readings = TRAINING_OPERATIONS.map((operation) => ({
158
+ operation,
159
+ reading: permissionFor(decision, operation),
160
+ }));
161
+ const missing = readings.filter(({ reading }) => reading.permission !== OperationPermission.Permitted);
162
+ if (!missing.length)
163
+ continue;
164
+ gaps.push({
165
+ source,
166
+ registerSource: row.sourceID,
167
+ licenseID: decision.licenseID,
168
+ state: decision.state,
169
+ missing: missing.map(({ operation }) => operation),
170
+ because: decision.state === LicenseReviewState.Refused
171
+ ? `the decision is refused: ${decision.refusedBecause}`
172
+ : missing[0].reading.because,
173
+ });
174
+ }
175
+ return gaps;
176
+ }
177
+ /**
178
+ * One line naming the corpus source, the register row and the missing permission.
179
+ */
180
+ export function describeSourceRightsGap(gap) {
181
+ const missing = gap.missing.join(" and ");
182
+ if (!gap.registerSource) {
183
+ return `corpus source ${gap.source} is unmapped and so lacks a permission for ${missing}: ${gap.because}`;
184
+ }
185
+ return (`corpus source ${gap.source} reads register source ${gap.registerSource} ` +
186
+ `(license ${gap.licenseID ?? "none"}, ${gap.state ?? "no decision"}), which does not permit ${missing}: ${gap.because}`);
187
+ }
188
+ /**
189
+ * Raised when a build or training run would admit a source lacking the permission.
190
+ */
191
+ export class SourceRightsError extends Error {
192
+ gaps;
193
+ constructor(context, gaps) {
194
+ super(`${context} refuses ${new Set(gaps.map((gap) => gap.source)).size} corpus source(s) whose register rows ` +
195
+ `lack an elected decision permitting ${TRAINING_OPERATIONS.join(" and ")}:\n ` +
196
+ gaps.map(describeSourceRightsGap).join("\n ") +
197
+ "\nRecord the decision in packages/corpus/data/license-decisions.json, map the source in " +
198
+ "packages/corpus/data/corpus-source-inputs.json, or pass --unshippable-reason <why> for a local " +
199
+ "experiment, which marks the output as not shippable.");
200
+ this.name = "SourceRightsError";
201
+ this.gaps = gaps;
202
+ }
203
+ }
204
+ /**
205
+ * Builds the admission check over an already-read register and table.
206
+ *
207
+ * @throws When `unshippableReason` is set and blank, because an override must say why.
208
+ */
209
+ export function createSourceRightsAdmission(register, inputs, options) {
210
+ const reason = options.unshippableReason ?? null;
211
+ if (reason !== null && !reason.trim()) {
212
+ throw new Error(`${options.context}: --unshippable-reason must say why the output is not shippable`);
213
+ }
214
+ const log = options.log ?? ((line) => console.error(line));
215
+ const checked = new Map();
216
+ const admitAll = (sources) => {
217
+ const fresh = [];
218
+ const all = [];
219
+ for (const source of sources) {
220
+ const known = checked.get(source);
221
+ if (known) {
222
+ all.push(...known);
223
+ continue;
224
+ }
225
+ const gaps = sourceRightsGaps(source, inputs, register);
226
+ fresh.push(...gaps);
227
+ all.push(...gaps);
228
+ if (!gaps.length || reason !== null) {
229
+ checked.set(source, gaps);
230
+ }
231
+ }
232
+ if (!fresh.length)
233
+ return all;
234
+ if (reason === null)
235
+ throw new SourceRightsError(options.context, fresh);
236
+ for (const gap of fresh) {
237
+ log(`UNSHIPPABLE ${options.context}: ${describeSourceRightsGap(gap)} (override: ${reason})`);
238
+ }
239
+ return all;
240
+ };
241
+ const unverified = [];
242
+ return {
243
+ admit: (source) => admitAll([source]),
244
+ admitAll,
245
+ admitUnverified: (description) => {
246
+ if (reason === null) {
247
+ throw new Error(`${options.context} cannot check the corpus sources of ${description}, and an input it cannot read is ` +
248
+ "not one it found clear. Pass --unshippable-reason <why> for a local experiment, which marks the " +
249
+ "output as not shippable.");
250
+ }
251
+ log(`UNSHIPPABLE ${options.context}: the corpus sources of ${description} were not checked (override: ${reason})`);
252
+ unverified.push(description);
253
+ },
254
+ record: () => {
255
+ const gaps = [...checked.values()].flat();
256
+ const shippable = gaps.length === 0 && unverified.length === 0;
257
+ return {
258
+ shippable,
259
+ unshippable_reason: shippable ? null : reason,
260
+ sources_checked: [...checked.keys()].toSorted(),
261
+ gaps,
262
+ unverified: [...unverified],
263
+ };
264
+ },
265
+ };
266
+ }
267
+ /**
268
+ * Reads the committed register and table and builds the admission check over them.
269
+ */
270
+ export async function openSourceRightsAdmission(options) {
271
+ const register = await readAddressSourceRegister();
272
+ const inputs = await readCorpusSourceInputs(register);
273
+ return createSourceRightsAdmission(register, inputs, options);
274
+ }
275
+ //# sourceMappingURL=corpus-inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus-inputs.js","sourceRoot":"","sources":["../../lib/source-register/corpus-inputs.ts"],"names":[],"mappings":"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"}
@@ -139,6 +139,8 @@ export interface RequiredAttribution {
139
139
  * Only `trainingSources` are read, so a source the corpus holds and the run never drew owes no attribution.
140
140
  * A license is included when `summarizeLicense` records an attribution obligation for it, or
141
141
  * when it is unrecognized, since an unrecognized license's obligations are unknown rather than absent.
142
+ *
143
+ * A source joins the group of every license in {@linkcode CONTENT_LICENSES} beside its own.
142
144
  */
143
145
  export declare function requiredAttributions(sources: readonly EffectiveSourceRecord[]): RequiredAttribution[];
144
146
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"effective-manifest.d.ts","sourceRoot":"","sources":["../../lib/source-register/effective-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"effective-manifest.d.ts","sourceRoot":"","sources":["../../lib/source-register/effective-manifest.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ import { sha256Hex } from "@mailwoman/core/hash";
25
25
  import { stringifyJSON } from "@mailwoman/core/json";
26
26
  import { LicenseObligation, summarizeLicense } from "@mailwoman/core/license/obligations";
27
27
  import { OSM_ATTRIBUTION, OSM_LICENSE } from "#adapters/osm/adapter";
28
+ import { currentSourceName } from "#recipes/sources";
28
29
  /**
29
30
  * Where an `audit_epoch_mixture --json` output for one config is looked for.
30
31
  *
@@ -92,22 +93,50 @@ export const DrawEvidence = {
92
93
  const ATTRIBUTION_STATEMENTS = {
93
94
  [OSM_LICENSE]: OSM_ATTRIBUTION,
94
95
  };
96
+ /**
97
+ * Recognized licenses carried by contents of a source whose rows state one free-text
98
+ * license, keyed by the source's current spelling.
99
+ *
100
+ * The derivation groups sources by the license their rows state.
101
+ * The `sub-venue` recipe states one license over three publications.
102
+ *
103
+ * That license is free text, and the OpenStreetMap venue names it carries are under ODbL 1.0.
104
+ * Grouping by that text alone leaves the source out of the ODbL group,
105
+ * the group that carries the recorded OpenStreetMap statement.
106
+ *
107
+ * The source keeps its own group as well, because that text also credits the
108
+ * publishers of the address skeletons.
109
+ */
110
+ const CONTENT_LICENSES = {
111
+ "spliced-sub-venue": [OSM_LICENSE],
112
+ };
113
+ /**
114
+ * The licenses a source owes attribution under: the one its rows state and those its contents carry.
115
+ */
116
+ function attributedLicenses(record) {
117
+ const current = currentSourceName(record.source) ?? record.source;
118
+ return [record.license, ...(CONTENT_LICENSES[current] ?? [])].filter((license) => {
119
+ const summary = summarizeLicense(license);
120
+ return !summary.recognized || summary.obligations.includes(LicenseObligation.Attribution);
121
+ });
122
+ }
95
123
  /**
96
124
  * The attributions owed by the sources that reached the trainer, grouped by license.
97
125
  *
98
126
  * Only `trainingSources` are read, so a source the corpus holds and the run never drew owes no attribution.
99
127
  * A license is included when `summarizeLicense` records an attribution obligation for it, or
100
128
  * when it is unrecognized, since an unrecognized license's obligations are unknown rather than absent.
129
+ *
130
+ * A source joins the group of every license in {@linkcode CONTENT_LICENSES} beside its own.
101
131
  */
102
132
  export function requiredAttributions(sources) {
103
133
  const byLicense = new Map();
104
134
  for (const record of sources) {
105
135
  if (record.emittedRows <= 0)
106
136
  continue;
107
- const summary = summarizeLicense(record.license);
108
- if (summary.recognized && !summary.obligations.includes(LicenseObligation.Attribution))
109
- continue;
110
- byLicense.set(record.license, [...(byLicense.get(record.license) ?? []), record.source]);
137
+ for (const license of attributedLicenses(record)) {
138
+ byLicense.set(license, [...(byLicense.get(license) ?? []), record.source]);
139
+ }
111
140
  }
112
141
  return [...byLicense]
113
142
  .toSorted(([a], [b]) => a.localeCompare(b))