colregs 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROVENANCE.md +3 -3
- package/README.md +19 -10
- package/data/applicability.json +219 -244
- package/data/corpora.json +41 -0
- package/data/editions.json +27 -0
- package/data/facts.json +4 -4
- package/data/geometry.json +8 -8
- package/data/i18n/en.json +27 -0
- package/data/i18n/fi.json +25 -0
- package/data/images.json +32 -32
- package/data/operations.json +79 -0
- package/data/rules.json +176 -599
- package/data/text/intl/2016/en-US.uscg.json +877 -0
- package/data/text/intl/2016/es.boe.json +23 -0
- package/data/text/intl/2016/fi.finlex.json +22 -0
- package/data/text/us/inland/2014/en-US.ecfr.json +22 -0
- package/data/version.json +1 -1
- package/docs/adr/0001-name-and-jurisdiction-model.md +42 -2
- package/docs/adr/0003-language-as-a-dimension.md +8 -7
- package/docs/adr/0006-json-schema-and-identifier-diff.md +2 -0
- package/docs/adr/0011-api-shape.md +1 -1
- package/docs/adr/0012-trace-and-rule2-departure-api.md +3 -4
- package/docs/adr/0013-corpus-files-with-editions.md +70 -0
- package/docs/adr/0014-engine-interface-owned-by-colregs.md +103 -0
- package/docs/adr/0015-rule-ids-are-paragraph-keys.md +191 -0
- package/docs/budgets.json +17 -17
- package/docs/gates.json +3 -3
- package/docs/identifiers.md +49 -51
- package/docs/maritime-sources.md +58 -0
- package/docs/normative-language.md +103 -0
- package/docs/part-b-invariants.md +31 -29
- package/docs/requirements.md +118 -97
- package/docs/timeline.md +102 -0
- package/docs/verification/2026-09-09-text-slug-straw-man.md +3 -2
- package/fixtures/applicability-fixtures.json +190 -190
- package/fixtures/situation-fixtures.json +287 -287
- package/package.json +1 -1
- package/schema/applicability-fixtures.schema.json +4 -13
- package/schema/applicability.schema.json +27 -27
- package/schema/conduct-evaluation.schema.json +135 -0
- package/schema/corpora.schema.json +68 -0
- package/schema/corpus.schema.json +329 -0
- package/schema/display-evaluation.schema.json +146 -0
- package/schema/editions.schema.json +47 -0
- package/schema/encounter-evaluation.schema.json +109 -0
- package/schema/evaluation.schema.json +149 -0
- package/schema/fact-record.schema.json +30 -0
- package/schema/i18n-catalog.schema.json +47 -0
- package/schema/operations.schema.json +124 -0
- package/schema/rule2-departure-finding.schema.json +72 -0
- package/schema/rule2-departure-model.schema.json +159 -0
- package/schema/rules.schema.json +20 -90
- package/schema/situation-fixtures.schema.json +10 -146
- package/schema/situation.schema.json +72 -0
- package/schema/trace.schema.json +33 -0
- package/data/deprecated-identifiers.json +0 -7
- package/schema/deprecated-identifiers.schema.json +0 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "colregs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "COLREGS 72 and its national amalgamations as language-neutral JSON — rule text, light definitions, and applicability predicates — with cross-implementation fixtures",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,14 +8,7 @@
|
|
|
8
8
|
"additionalProperties": false,
|
|
9
9
|
"required": ["jurisdiction", "cases"],
|
|
10
10
|
"$defs": {
|
|
11
|
-
"
|
|
12
|
-
"oneOf": [
|
|
13
|
-
{ "type": "string", "pattern": "^[a-z][a-z0-9_]*:[a-z0-9_]+$" },
|
|
14
|
-
{ "type": "number" },
|
|
15
|
-
{ "type": "boolean" }
|
|
16
|
-
]
|
|
17
|
-
},
|
|
18
|
-
"entryId": { "type": "string", "pattern": "^[0-9]+[a-z0-9]*(-[a-z0-9]+)?$" }
|
|
11
|
+
"ruleId": { "$ref": "applicability.schema.json#/$defs/ruleId" }
|
|
19
12
|
},
|
|
20
13
|
"properties": {
|
|
21
14
|
"note": { "type": "string" },
|
|
@@ -31,16 +24,14 @@
|
|
|
31
24
|
"name": { "type": "string", "minLength": 1 },
|
|
32
25
|
"jurisdiction": { "type": "string", "pattern": "^[a-z]+(/[a-z]+)*$" },
|
|
33
26
|
"facts": {
|
|
27
|
+
"$comment": "A FactRecord (schema/fact-record.schema.json, ADR 0014); a case asserts at least one fact.",
|
|
34
28
|
"type": "object",
|
|
35
29
|
"minProperties": 1,
|
|
36
|
-
"
|
|
37
|
-
"patternProperties": {
|
|
38
|
-
"^fact:[a-z0-9_]+$": { "$ref": "#/$defs/factValue" }
|
|
39
|
-
}
|
|
30
|
+
"$ref": "fact-record.schema.json"
|
|
40
31
|
},
|
|
41
32
|
"expect": {
|
|
42
33
|
"type": "array",
|
|
43
|
-
"items": { "$ref": "#/$defs/
|
|
34
|
+
"items": { "$ref": "#/$defs/ruleId" }
|
|
44
35
|
}
|
|
45
36
|
}
|
|
46
37
|
}
|
|
@@ -7,7 +7,21 @@
|
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["entries"],
|
|
9
9
|
"$defs": {
|
|
10
|
-
"
|
|
10
|
+
"ruleCategory": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": [
|
|
13
|
+
"definition",
|
|
14
|
+
"standard",
|
|
15
|
+
"scope",
|
|
16
|
+
"display",
|
|
17
|
+
"classification",
|
|
18
|
+
"precedence",
|
|
19
|
+
"conduct",
|
|
20
|
+
"care",
|
|
21
|
+
"meta"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"ruleId": { "type": "string", "pattern": "^rule:[0-9]+[a-z]?(_[ivx]+)*(:[a-z][a-z0-9_]*)?$" },
|
|
11
25
|
"modality": {
|
|
12
26
|
"type": "string",
|
|
13
27
|
"enum": ["shall", "may", "shall-if-practicable", "conditional", "exempt", "shall-not", "shall-not-impede"]
|
|
@@ -174,20 +188,20 @@
|
|
|
174
188
|
"one_of": {
|
|
175
189
|
"type": "array",
|
|
176
190
|
"minItems": 2,
|
|
177
|
-
"items": { "$ref": "#/$defs/
|
|
191
|
+
"items": { "$ref": "#/$defs/ruleId" }
|
|
178
192
|
},
|
|
179
193
|
"rel:includes": {
|
|
180
194
|
"type": "array",
|
|
181
195
|
"minItems": 1,
|
|
182
|
-
"items": { "$ref": "#/$defs/
|
|
196
|
+
"items": { "$ref": "#/$defs/ruleId" }
|
|
183
197
|
},
|
|
184
198
|
"cite": { "type": "string", "minLength": 1 }
|
|
185
199
|
}
|
|
186
200
|
},
|
|
187
|
-
"
|
|
201
|
+
"ruleIdList": {
|
|
188
202
|
"type": "array",
|
|
189
203
|
"minItems": 1,
|
|
190
|
-
"items": { "$ref": "#/$defs/
|
|
204
|
+
"items": { "$ref": "#/$defs/ruleId" }
|
|
191
205
|
}
|
|
192
206
|
},
|
|
193
207
|
"properties": {
|
|
@@ -312,7 +326,7 @@
|
|
|
312
326
|
"additionalProperties": false,
|
|
313
327
|
"required": ["id", "jurisdiction", "cite", "category", "note"],
|
|
314
328
|
"properties": {
|
|
315
|
-
"id": { "$ref": "#/$defs/
|
|
329
|
+
"id": { "$ref": "#/$defs/ruleId" },
|
|
316
330
|
"jurisdiction": { "type": "string", "pattern": "^[a-z]+(/[a-z]+)*$" },
|
|
317
331
|
"cite": { "type": "string", "minLength": 1 },
|
|
318
332
|
"category": { "type": "string", "enum": ["care", "meta"] },
|
|
@@ -320,19 +334,6 @@
|
|
|
320
334
|
}
|
|
321
335
|
}
|
|
322
336
|
},
|
|
323
|
-
"retired_entry_ids": {
|
|
324
|
-
"type": "object",
|
|
325
|
-
"additionalProperties": false,
|
|
326
|
-
"required": ["ids"],
|
|
327
|
-
"properties": {
|
|
328
|
-
"note": { "type": "string" },
|
|
329
|
-
"ids": {
|
|
330
|
-
"type": "object",
|
|
331
|
-
"propertyNames": { "$ref": "#/$defs/entryId" },
|
|
332
|
-
"additionalProperties": { "type": "string", "minLength": 1 }
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
},
|
|
336
337
|
"entries": {
|
|
337
338
|
"type": "array",
|
|
338
339
|
"minItems": 1,
|
|
@@ -341,12 +342,11 @@
|
|
|
341
342
|
"additionalProperties": false,
|
|
342
343
|
"required": ["id", "jurisdiction", "cite", "when", "modality"],
|
|
343
344
|
"properties": {
|
|
344
|
-
"id": { "$ref": "#/$defs/
|
|
345
|
+
"id": { "$ref": "#/$defs/ruleId" },
|
|
345
346
|
"jurisdiction": { "type": "string", "pattern": "^[a-z]+(/[a-z]+)*$" },
|
|
346
347
|
"cite": { "type": "string", "minLength": 1 },
|
|
347
348
|
"category": {
|
|
348
|
-
"
|
|
349
|
-
"enum": ["definition", "standard", "scope", "display", "classification", "precedence", "conduct", "care", "meta"]
|
|
349
|
+
"$ref": "#/$defs/ruleCategory"
|
|
350
350
|
},
|
|
351
351
|
"subjects": { "type": "integer", "const": 2 },
|
|
352
352
|
"when": { "$ref": "#/$defs/situationWhen" },
|
|
@@ -366,16 +366,16 @@
|
|
|
366
366
|
"note": { "type": "string" },
|
|
367
367
|
"gap": { "type": "string", "minLength": 1 },
|
|
368
368
|
"no_gate_note": { "type": "string", "minLength": 1 },
|
|
369
|
-
"rel:includes": { "$ref": "#/$defs/
|
|
369
|
+
"rel:includes": { "$ref": "#/$defs/ruleIdList" },
|
|
370
370
|
"rel:conditional_includes": {
|
|
371
371
|
"type": "array",
|
|
372
372
|
"minItems": 1,
|
|
373
373
|
"items": { "$ref": "#/$defs/conditionalInclude" }
|
|
374
374
|
},
|
|
375
|
-
"rel:in_lieu_of": { "$ref": "#/$defs/
|
|
376
|
-
"rel:excludes": { "$ref": "#/$defs/
|
|
377
|
-
"rel:exempts": { "$ref": "#/$defs/
|
|
378
|
-
"rel:overrides": { "$ref": "#/$defs/
|
|
375
|
+
"rel:in_lieu_of": { "$ref": "#/$defs/ruleIdList" },
|
|
376
|
+
"rel:excludes": { "$ref": "#/$defs/ruleIdList" },
|
|
377
|
+
"rel:exempts": { "$ref": "#/$defs/ruleIdList" },
|
|
378
|
+
"rel:overrides": { "$ref": "#/$defs/ruleIdList" }
|
|
379
379
|
},
|
|
380
380
|
"allOf": [
|
|
381
381
|
{
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/mark-brannan/colregs/schema/conduct-evaluation.schema.json",
|
|
4
|
+
"title": "ConductEvaluation",
|
|
5
|
+
"description": "The result of evaluateConduct: one verdict per applied conduct entry per subject over the window the caller handed over, and the Rule 13(d)/17 phase changes seen (ADR 0012 §3, ADR 0014). Structure only.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"colregs",
|
|
10
|
+
"window",
|
|
11
|
+
"applied",
|
|
12
|
+
"verdicts",
|
|
13
|
+
"phases"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"colregs": {
|
|
17
|
+
"$ref": "evaluation.schema.json#/$defs/colregs"
|
|
18
|
+
},
|
|
19
|
+
"window": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"required": [
|
|
23
|
+
"from_s",
|
|
24
|
+
"to_s",
|
|
25
|
+
"samples"
|
|
26
|
+
],
|
|
27
|
+
"properties": {
|
|
28
|
+
"from_s": {
|
|
29
|
+
"type": "number"
|
|
30
|
+
},
|
|
31
|
+
"to_s": {
|
|
32
|
+
"type": "number"
|
|
33
|
+
},
|
|
34
|
+
"samples": {
|
|
35
|
+
"type": "integer",
|
|
36
|
+
"minimum": 1
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"applied": {
|
|
41
|
+
"$ref": "evaluation.schema.json#/$defs/ruleIds"
|
|
42
|
+
},
|
|
43
|
+
"verdicts": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"items": {
|
|
46
|
+
"$ref": "#/$defs/verdict"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"phases": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"items": {
|
|
52
|
+
"$ref": "#/$defs/phaseChange"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"$defs": {
|
|
57
|
+
"subject": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": [
|
|
60
|
+
"own",
|
|
61
|
+
"other"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"verdict": {
|
|
65
|
+
"$comment": "`pending`: the window ended before the duty could be judged. An entry that never attached is absent, not pending.",
|
|
66
|
+
"type": "object",
|
|
67
|
+
"additionalProperties": false,
|
|
68
|
+
"required": [
|
|
69
|
+
"id",
|
|
70
|
+
"subject",
|
|
71
|
+
"verdict"
|
|
72
|
+
],
|
|
73
|
+
"properties": {
|
|
74
|
+
"id": {
|
|
75
|
+
"$ref": "evaluation.schema.json#/$defs/ruleId"
|
|
76
|
+
},
|
|
77
|
+
"subject": {
|
|
78
|
+
"$ref": "#/$defs/subject"
|
|
79
|
+
},
|
|
80
|
+
"verdict": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"enum": [
|
|
83
|
+
"kept",
|
|
84
|
+
"breached",
|
|
85
|
+
"pending"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
"attached_at_s": {
|
|
89
|
+
"type": "number"
|
|
90
|
+
},
|
|
91
|
+
"decided_at_s": {
|
|
92
|
+
"type": "number"
|
|
93
|
+
},
|
|
94
|
+
"robustness": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"required": [
|
|
98
|
+
"value",
|
|
99
|
+
"unit"
|
|
100
|
+
],
|
|
101
|
+
"properties": {
|
|
102
|
+
"value": {
|
|
103
|
+
"type": "number"
|
|
104
|
+
},
|
|
105
|
+
"unit": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"minLength": 1
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"phaseChange": {
|
|
114
|
+
"$comment": "`phase` is a paragraph cite, never an entry id: several phases have no entry.",
|
|
115
|
+
"type": "object",
|
|
116
|
+
"additionalProperties": false,
|
|
117
|
+
"required": [
|
|
118
|
+
"subject",
|
|
119
|
+
"phase",
|
|
120
|
+
"at_s"
|
|
121
|
+
],
|
|
122
|
+
"properties": {
|
|
123
|
+
"subject": {
|
|
124
|
+
"$ref": "#/$defs/subject"
|
|
125
|
+
},
|
|
126
|
+
"phase": {
|
|
127
|
+
"$ref": "evaluation.schema.json#/$defs/paragraphCite"
|
|
128
|
+
},
|
|
129
|
+
"at_s": {
|
|
130
|
+
"type": "number"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/mark-brannan/colregs/schema/corpora.schema.json",
|
|
4
|
+
"title": "data/corpora.json",
|
|
5
|
+
"description": "Index of the text corpora under data/text/: which exist, where each lives, and how many paragraphs it covers. Derived from the corpus files and checked against them by test/data.test.mjs; a consumer that cannot list a directory reads this instead. See docs/adr/0013-corpus-files-with-editions.md.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"corpora"
|
|
10
|
+
],
|
|
11
|
+
"properties": {
|
|
12
|
+
"note": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"corpora": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"patternProperties": {
|
|
19
|
+
"^[a-z]+(/[a-z]+)*@[a-z0-9-]+\\.[A-Za-z0-9-]+\\.[a-z0-9]+$": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"required": [
|
|
23
|
+
"file",
|
|
24
|
+
"edition",
|
|
25
|
+
"edition_status",
|
|
26
|
+
"language",
|
|
27
|
+
"source_id",
|
|
28
|
+
"tier",
|
|
29
|
+
"paragraphs"
|
|
30
|
+
],
|
|
31
|
+
"properties": {
|
|
32
|
+
"file": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"pattern": "^text/.+\\.json$"
|
|
35
|
+
},
|
|
36
|
+
"edition": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"pattern": "^[a-z]+(/[a-z]+)*@[a-z0-9-]+$"
|
|
39
|
+
},
|
|
40
|
+
"edition_status": {
|
|
41
|
+
"enum": ["verified", "claimed", "unknown"]
|
|
42
|
+
},
|
|
43
|
+
"language": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"minLength": 2
|
|
46
|
+
},
|
|
47
|
+
"source_id": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"pattern": "^[a-z0-9]+$"
|
|
50
|
+
},
|
|
51
|
+
"tier": {
|
|
52
|
+
"enum": [
|
|
53
|
+
"authentic",
|
|
54
|
+
"official",
|
|
55
|
+
"national",
|
|
56
|
+
"community"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
"paragraphs": {
|
|
60
|
+
"type": "integer",
|
|
61
|
+
"minimum": 0
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/mark-brannan/colregs/schema/corpus.schema.json",
|
|
4
|
+
"title": "data/text/<jurisdiction>/<edition>/<language>.<source_id>.json",
|
|
5
|
+
"description": "One rule-text corpus: the words of one edition of one jurisdiction's rules, in one language, from one source, keyed by paragraph path into data/rules.json. Verbatim unless withheld under a licence bar. See docs/adr/0003-language-as-a-dimension.md, docs/adr/0010-text-withheld-jurisdictions.md and docs/adr/0013-corpus-files-with-editions.md.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"id",
|
|
10
|
+
"edition",
|
|
11
|
+
"edition_status",
|
|
12
|
+
"language",
|
|
13
|
+
"source_id",
|
|
14
|
+
"tier",
|
|
15
|
+
"normalization",
|
|
16
|
+
"source",
|
|
17
|
+
"rights",
|
|
18
|
+
"paragraphs"
|
|
19
|
+
],
|
|
20
|
+
"allOf": [
|
|
21
|
+
{
|
|
22
|
+
"$comment": "colregs#85 / ADR 0010: a withheld paragraph is a citation, not a reproduction -- 'retrieved' is when that citation was last checked against the primary source.",
|
|
23
|
+
"if": {
|
|
24
|
+
"properties": {
|
|
25
|
+
"paragraphs": {
|
|
26
|
+
"not": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"patternProperties": {
|
|
29
|
+
"^.*$": {
|
|
30
|
+
"not": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"properties": {
|
|
33
|
+
"text_status": {
|
|
34
|
+
"const": "withheld"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"required": [
|
|
38
|
+
"text_status"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"then": {
|
|
48
|
+
"properties": {
|
|
49
|
+
"source": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"properties": {
|
|
52
|
+
"retrieved": {
|
|
53
|
+
"type": "string"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"required": [
|
|
57
|
+
"retrieved"
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"$defs": {
|
|
65
|
+
"path": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"pattern": "^[0-9]+(\\([a-z]\\))?(\\([ivx]+\\))?$"
|
|
68
|
+
},
|
|
69
|
+
"date": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"properties": {
|
|
75
|
+
"id": {
|
|
76
|
+
"$comment": "<edition>.<language>.<source_id>; CI checks it agrees with the file's path, with data/corpora.json, and that the edition is registered in data/editions.json.",
|
|
77
|
+
"type": "string",
|
|
78
|
+
"pattern": "^[a-z]+(/[a-z]+)*@[a-z0-9-]+\\.[A-Za-z0-9-]+\\.[a-z0-9]+$"
|
|
79
|
+
},
|
|
80
|
+
"edition": {
|
|
81
|
+
"$comment": "Edition id from data/editions.json (<jurisdiction>@<tag>): the consolidated state this text reflects -- REQ-LANG-10. The jurisdiction is the edition's, never restated here.",
|
|
82
|
+
"type": "string",
|
|
83
|
+
"pattern": "^[a-z]+(/[a-z]+)*@[a-z0-9-]+$"
|
|
84
|
+
},
|
|
85
|
+
"edition_status": {
|
|
86
|
+
"$comment": "Confidence in the `edition` claim above, not in the text itself: 'verified' means this corpus's edition was checked against the primary source; 'claimed' means asserted but not yet checked (every stub starts here); 'unknown' means even the claim is inherited/guessed. See ADR 0013.",
|
|
87
|
+
"enum": ["verified", "claimed", "unknown"]
|
|
88
|
+
},
|
|
89
|
+
"language": {
|
|
90
|
+
"$comment": "BCP 47. Carries the language of the text and nothing else -- REQ-LANG-1.",
|
|
91
|
+
"type": "string",
|
|
92
|
+
"pattern": "^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2}|-[0-9]{3})?$"
|
|
93
|
+
},
|
|
94
|
+
"source_id": {
|
|
95
|
+
"$comment": "Short handle for the publishing route (uscg, finlex, boe, ecfr); the identity of the source is the structured `source` object.",
|
|
96
|
+
"type": "string",
|
|
97
|
+
"pattern": "^[a-z0-9]+$"
|
|
98
|
+
},
|
|
99
|
+
"tier": {
|
|
100
|
+
"$comment": "Legal authority of the source, never of the language -- REQ-LANG-3.",
|
|
101
|
+
"enum": [
|
|
102
|
+
"authentic",
|
|
103
|
+
"official",
|
|
104
|
+
"national",
|
|
105
|
+
"community"
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
"normalization": {
|
|
109
|
+
"$comment": "Unicode normalization form the text is stored in -- REQ-LANG-9.",
|
|
110
|
+
"enum": [
|
|
111
|
+
"NFC",
|
|
112
|
+
"NFD",
|
|
113
|
+
"NFKC",
|
|
114
|
+
"NFKD"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
"translation_of": {
|
|
118
|
+
"$comment": "Corpus id this text is a translation of, where it is one and that is known. Absent for independently promulgated national texts.",
|
|
119
|
+
"type": "string"
|
|
120
|
+
},
|
|
121
|
+
"source": {
|
|
122
|
+
"$comment": "REQ-PROV-6: structured source identity, not a prose string.",
|
|
123
|
+
"type": "object",
|
|
124
|
+
"additionalProperties": false,
|
|
125
|
+
"required": [
|
|
126
|
+
"publisher",
|
|
127
|
+
"title",
|
|
128
|
+
"url",
|
|
129
|
+
"retrieved"
|
|
130
|
+
],
|
|
131
|
+
"properties": {
|
|
132
|
+
"publisher": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"minLength": 1
|
|
135
|
+
},
|
|
136
|
+
"title": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"minLength": 1
|
|
139
|
+
},
|
|
140
|
+
"edition": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"minLength": 1
|
|
143
|
+
},
|
|
144
|
+
"published": {
|
|
145
|
+
"$ref": "#/$defs/date"
|
|
146
|
+
},
|
|
147
|
+
"effective": {
|
|
148
|
+
"$ref": "#/$defs/date"
|
|
149
|
+
},
|
|
150
|
+
"url": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"minLength": 1
|
|
153
|
+
},
|
|
154
|
+
"retrieved": {
|
|
155
|
+
"oneOf": [
|
|
156
|
+
{
|
|
157
|
+
"type": "null"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"$ref": "#/$defs/date"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"rights": {
|
|
167
|
+
"$comment": "REQ-PROV-6: three separate statements, never one flat licence field.",
|
|
168
|
+
"type": "object",
|
|
169
|
+
"additionalProperties": false,
|
|
170
|
+
"required": [
|
|
171
|
+
"source_text",
|
|
172
|
+
"redistribution_basis",
|
|
173
|
+
"package_licence"
|
|
174
|
+
],
|
|
175
|
+
"properties": {
|
|
176
|
+
"source_text": {
|
|
177
|
+
"type": "string",
|
|
178
|
+
"minLength": 1
|
|
179
|
+
},
|
|
180
|
+
"redistribution_basis": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"minLength": 1
|
|
183
|
+
},
|
|
184
|
+
"attribution": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"minLength": 1
|
|
187
|
+
},
|
|
188
|
+
"package_licence": {
|
|
189
|
+
"type": "string",
|
|
190
|
+
"minLength": 1
|
|
191
|
+
},
|
|
192
|
+
"contributors": {
|
|
193
|
+
"type": "array",
|
|
194
|
+
"items": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"minLength": 1
|
|
197
|
+
},
|
|
198
|
+
"minItems": 1
|
|
199
|
+
},
|
|
200
|
+
"reviewers": {
|
|
201
|
+
"type": "array",
|
|
202
|
+
"items": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"minLength": 1
|
|
205
|
+
},
|
|
206
|
+
"minItems": 1
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"note": {
|
|
211
|
+
"type": "string"
|
|
212
|
+
},
|
|
213
|
+
"gaps": {
|
|
214
|
+
"$comment": "Skeleton paths this source could not supply. Distinct from withheld: a gap is text we could not obtain, withheld is text we may not publish.",
|
|
215
|
+
"type": "array",
|
|
216
|
+
"items": {
|
|
217
|
+
"type": "object",
|
|
218
|
+
"additionalProperties": false,
|
|
219
|
+
"required": [
|
|
220
|
+
"path",
|
|
221
|
+
"reason"
|
|
222
|
+
],
|
|
223
|
+
"properties": {
|
|
224
|
+
"path": {
|
|
225
|
+
"$ref": "#/$defs/path"
|
|
226
|
+
},
|
|
227
|
+
"reason": {
|
|
228
|
+
"type": "string",
|
|
229
|
+
"minLength": 1
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"paragraphs": {
|
|
235
|
+
"type": "object",
|
|
236
|
+
"additionalProperties": false,
|
|
237
|
+
"patternProperties": {
|
|
238
|
+
"^[0-9]+(\\([a-z]\\))?(\\([ivx]+\\))?$": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"additionalProperties": false,
|
|
241
|
+
"required": [
|
|
242
|
+
"rule_title"
|
|
243
|
+
],
|
|
244
|
+
"allOf": [
|
|
245
|
+
{
|
|
246
|
+
"$comment": "ADR 0010: a withheld paragraph is modelled but ships no text.",
|
|
247
|
+
"if": {
|
|
248
|
+
"properties": {
|
|
249
|
+
"text_status": {
|
|
250
|
+
"const": "withheld"
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"required": [
|
|
254
|
+
"text_status"
|
|
255
|
+
]
|
|
256
|
+
},
|
|
257
|
+
"then": {
|
|
258
|
+
"properties": {
|
|
259
|
+
"text": false,
|
|
260
|
+
"withheld_reason": {
|
|
261
|
+
"type": "string",
|
|
262
|
+
"minLength": 1
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"required": [
|
|
266
|
+
"withheld_reason"
|
|
267
|
+
]
|
|
268
|
+
},
|
|
269
|
+
"else": {
|
|
270
|
+
"$comment": "mirrors, text_digest and text_slug are open to verbatim paragraphs too; only withheld_reason is incoherent without a bar.",
|
|
271
|
+
"properties": {
|
|
272
|
+
"text": {
|
|
273
|
+
"type": "string",
|
|
274
|
+
"minLength": 1
|
|
275
|
+
},
|
|
276
|
+
"withheld_reason": false
|
|
277
|
+
},
|
|
278
|
+
"required": [
|
|
279
|
+
"text"
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
],
|
|
284
|
+
"properties": {
|
|
285
|
+
"rule_title": {
|
|
286
|
+
"$comment": "Verbatim source material like `text`; on a withheld paragraph, a neutral label written for this package -- ADR 0010.",
|
|
287
|
+
"type": "string",
|
|
288
|
+
"minLength": 1
|
|
289
|
+
},
|
|
290
|
+
"text": {
|
|
291
|
+
"type": "string",
|
|
292
|
+
"minLength": 1
|
|
293
|
+
},
|
|
294
|
+
"text_status": {
|
|
295
|
+
"$comment": "Absent means verbatim. 'withheld' means the text is not ours to publish -- ADR 0010.",
|
|
296
|
+
"enum": [
|
|
297
|
+
"verbatim",
|
|
298
|
+
"withheld"
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
"withheld_reason": {
|
|
302
|
+
"type": "string",
|
|
303
|
+
"minLength": 1
|
|
304
|
+
},
|
|
305
|
+
"text_slug": {
|
|
306
|
+
"$comment": "Pencil, ADR 0010: sorted set of lemmatised key nouns and verbs, English counterparts where the source is not English.",
|
|
307
|
+
"type": "array",
|
|
308
|
+
"items": {
|
|
309
|
+
"type": "string",
|
|
310
|
+
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
|
|
311
|
+
},
|
|
312
|
+
"minItems": 1,
|
|
313
|
+
"uniqueItems": true
|
|
314
|
+
},
|
|
315
|
+
"text_digest": {
|
|
316
|
+
"$comment": "Pencil, ADR 0010: algorithm-qualified digest of the normalised text, e.g. 'sha256:<hex>'.",
|
|
317
|
+
"type": "string",
|
|
318
|
+
"pattern": "^[a-z0-9-]+:[A-Za-z0-9+/=]+$"
|
|
319
|
+
},
|
|
320
|
+
"mirrors": {
|
|
321
|
+
"$comment": "Paragraph path in intl this provision restates; display labelled as the international equivalent, never as this jurisdiction's text.",
|
|
322
|
+
"$ref": "#/$defs/path"
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|