colregs 0.3.0 → 0.3.2

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 (44) hide show
  1. package/README.md +13 -11
  2. package/data/applicability.json +478 -503
  3. package/data/facts.json +22 -22
  4. package/data/geometry.json +8 -8
  5. package/data/i18n/en.json +27 -0
  6. package/data/i18n/fi.json +25 -0
  7. package/data/images.json +32 -32
  8. package/data/operations.json +79 -0
  9. package/data/rules.json +5 -0
  10. package/data/version.json +1 -1
  11. package/docs/adr/0006-json-schema-and-identifier-diff.md +2 -0
  12. package/docs/adr/0011-api-shape.md +7 -7
  13. package/docs/adr/0012-trace-and-rule2-departure-api.md +2 -2
  14. package/docs/adr/0014-engine-interface-owned-by-colregs.md +103 -0
  15. package/docs/adr/0015-rule-ids-are-paragraph-keys.md +191 -0
  16. package/docs/adr/0016-encounter-roles-are-pooled-across-frames.md +82 -0
  17. package/docs/adr/0017-closed-vocabularies-are-prefixed-identifiers.md +105 -0
  18. package/docs/budgets.json +8 -15
  19. package/docs/decisions.md +6 -0
  20. package/docs/identifiers.md +121 -109
  21. package/docs/maritime-sources.md +58 -0
  22. package/docs/normative-language.md +103 -0
  23. package/docs/part-b-invariants.md +48 -45
  24. package/docs/requirements.md +147 -138
  25. package/fixtures/applicability-fixtures.json +190 -190
  26. package/fixtures/situation-fixtures.json +870 -599
  27. package/package.json +1 -1
  28. package/schema/applicability-fixtures.schema.json +4 -13
  29. package/schema/applicability.schema.json +77 -77
  30. package/schema/conduct-evaluation.schema.json +135 -0
  31. package/schema/display-evaluation.schema.json +146 -0
  32. package/schema/encounter-evaluation.schema.json +109 -0
  33. package/schema/evaluation.schema.json +149 -0
  34. package/schema/fact-record.schema.json +30 -0
  35. package/schema/facts.schema.json +4 -4
  36. package/schema/i18n-catalog.schema.json +47 -0
  37. package/schema/operations.schema.json +124 -0
  38. package/schema/rule2-departure-finding.schema.json +72 -0
  39. package/schema/rule2-departure-model.schema.json +159 -0
  40. package/schema/situation-fixtures.schema.json +30 -127
  41. package/schema/situation.schema.json +72 -0
  42. package/schema/trace.schema.json +33 -0
  43. package/data/deprecated-identifiers.json +0 -7
  44. package/schema/deprecated-identifiers.schema.json +0 -29
@@ -0,0 +1,159 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mark-brannan/colregs/schema/rule2-departure-model.schema.json",
4
+ "title": "Rule2DepartureModel",
5
+ "description": "One solved region grid, named immutably by `version`, the positional second input of evaluateRule2Departure (ADR 0012 §4, ADR 0014). Only `version`, `colregs_version`, the solver parameters and the `regions` encoding are API; any other field is the artefact's own, so additional properties are allowed. Structure only.",
6
+ "type": "object",
7
+ "required": [
8
+ "version",
9
+ "colregs_version",
10
+ "dynamics",
11
+ "horizon_s",
12
+ "cadence_s",
13
+ "separation_m",
14
+ "information",
15
+ "adversary"
16
+ ],
17
+ "allOf": [
18
+ {
19
+ "$ref": "#/$defs/solverParameters"
20
+ }
21
+ ],
22
+ "properties": {
23
+ "version": {
24
+ "type": "string",
25
+ "minLength": 1
26
+ },
27
+ "colregs_version": {
28
+ "type": "string",
29
+ "minLength": 1
30
+ },
31
+ "regions": {
32
+ "type": "array",
33
+ "items": {
34
+ "$ref": "#/$defs/region"
35
+ }
36
+ }
37
+ },
38
+ "$defs": {
39
+ "solverParameters": {
40
+ "$comment": "The axes the Rule 2 sensitivity matrix varies (colregs Q-17 to Q-22); the field set is a claim about what that matrix is.",
41
+ "type": "object",
42
+ "properties": {
43
+ "dynamics": {
44
+ "type": "array",
45
+ "items": {
46
+ "type": "string"
47
+ }
48
+ },
49
+ "horizon_s": {
50
+ "type": "number"
51
+ },
52
+ "cadence_s": {
53
+ "type": "number"
54
+ },
55
+ "separation_m": {
56
+ "type": "number"
57
+ },
58
+ "information": {
59
+ "type": "string",
60
+ "enum": [
61
+ "full",
62
+ "partial"
63
+ ]
64
+ },
65
+ "adversary": {
66
+ "type": "string",
67
+ "enum": [
68
+ "compliant",
69
+ "physics"
70
+ ]
71
+ }
72
+ }
73
+ },
74
+ "status": {
75
+ "$comment": "The status alphabet is colregs' (ADR 0005 §5), not an engine's to rename: not-flagged, model-rule-conflict and no-robust-policy-in-model name R0, R1 and R2; inconclusive-in-model names none.",
76
+ "type": "string",
77
+ "enum": [
78
+ "not-flagged",
79
+ "model-rule-conflict",
80
+ "no-robust-policy-in-model",
81
+ "inconclusive-in-model"
82
+ ]
83
+ },
84
+ "advisory": {
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "required": [
88
+ "action",
89
+ "margin_m",
90
+ "breaches",
91
+ "envelope"
92
+ ],
93
+ "properties": {
94
+ "action": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "properties": {
98
+ "alter_deg": {
99
+ "type": "number"
100
+ },
101
+ "sog_kn": {
102
+ "type": "number"
103
+ }
104
+ }
105
+ },
106
+ "margin_m": {
107
+ "type": "number"
108
+ },
109
+ "breaches": {
110
+ "type": "array",
111
+ "items": {
112
+ "$ref": "evaluation.schema.json#/$defs/paragraphCite"
113
+ }
114
+ },
115
+ "envelope": {
116
+ "type": "object",
117
+ "additionalProperties": false,
118
+ "required": [
119
+ "holds_until_s"
120
+ ],
121
+ "properties": {
122
+ "holds_until_s": {
123
+ "type": "number"
124
+ }
125
+ }
126
+ }
127
+ }
128
+ },
129
+ "region": {
130
+ "$comment": "Regions of situation space as predicates over the flat `<subject>:<class>:<key>` namespace, first match wins, no match is inconclusive-in-model.",
131
+ "type": "object",
132
+ "additionalProperties": false,
133
+ "required": [
134
+ "when",
135
+ "status"
136
+ ],
137
+ "properties": {
138
+ "when": {
139
+ "$ref": "applicability.schema.json#/$defs/situationWhen"
140
+ },
141
+ "status": {
142
+ "$ref": "#/$defs/status"
143
+ },
144
+ "advisories": {
145
+ "type": "array",
146
+ "items": {
147
+ "$ref": "#/$defs/advisory"
148
+ }
149
+ },
150
+ "assumptions_violated": {
151
+ "type": "array",
152
+ "items": {
153
+ "type": "string"
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+ }
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/mark-brannan/colregs/schema/situation-fixtures.schema.json",
4
4
  "title": "fixtures/situation-fixtures.json",
5
- "description": "Two-subject situation fixtures (ADR 0005, REQ-CAT-5). Structure only -- see docs/adr/0006-json-schema-and-identifier-diff.md. Namespace resolution (every kin:/geo:/hist: key declared in facts.json) stays in the tests.",
5
+ "description": "Two-subject situation fixtures (ADR 0005, REQ-CAT-5). Structure only -- see docs/adr/0006-json-schema-and-identifier-diff.md. A case's situation is schema/situation.schema.json; namespace resolution (every kin:/geo:/hist: key declared in facts.json) stays in the tests.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": [
@@ -12,26 +12,16 @@
12
12
  "cases"
13
13
  ],
14
14
  "$defs": {
15
- "entryId": {
16
- "type": "string",
17
- "pattern": "^[0-9]+[a-z0-9]*(-[a-z0-9]+)*$"
15
+ "ruleId": {
16
+ "$ref": "applicability.schema.json#/$defs/ruleId"
18
17
  },
19
18
  "modality": {
20
- "type": "string",
21
- "enum": [
22
- "shall",
23
- "may",
24
- "shall-if-practicable",
25
- "conditional",
26
- "exempt",
27
- "shall-not",
28
- "shall-not-impede"
29
- ]
19
+ "$ref": "applicability.schema.json#/$defs/modality"
30
20
  },
31
21
  "expectItem": {
32
22
  "oneOf": [
33
23
  {
34
- "$ref": "#/$defs/entryId"
24
+ "$ref": "#/$defs/ruleId"
35
25
  },
36
26
  {
37
27
  "type": "object",
@@ -42,7 +32,7 @@
42
32
  ],
43
33
  "properties": {
44
34
  "entry": {
45
- "$ref": "#/$defs/entryId"
35
+ "$ref": "#/$defs/ruleId"
46
36
  },
47
37
  "modality": {
48
38
  "$ref": "#/$defs/modality"
@@ -51,106 +41,19 @@
51
41
  }
52
42
  ]
53
43
  },
54
- "scalar": {
55
- "oneOf": [
56
- {
57
- "type": "string",
58
- "pattern": "^[a-z][a-z0-9_]*:[a-z0-9_]+$"
59
- },
60
- {
61
- "type": "number"
62
- },
63
- {
64
- "type": "boolean"
65
- },
66
- {
67
- "type": "null"
68
- },
69
- {
70
- "type": "object",
71
- "additionalProperties": false,
72
- "required": [
73
- "latitude",
74
- "longitude"
75
- ],
76
- "properties": {
77
- "latitude": {
78
- "type": "number",
79
- "minimum": -90,
80
- "maximum": 90
81
- },
82
- "longitude": {
83
- "type": "number",
84
- "minimum": -180,
85
- "maximum": 180
86
- }
87
- }
88
- }
89
- ]
90
- },
91
- "factRecord": {
92
- "type": "object",
93
- "additionalProperties": false,
94
- "patternProperties": {
95
- "^fact:[a-z0-9_]+$": {
96
- "$ref": "#/$defs/scalar"
97
- }
98
- }
99
- },
100
- "kinRecord": {
101
- "type": "object",
102
- "additionalProperties": false,
103
- "patternProperties": {
104
- "^kin:[a-z0-9_]+$": {
105
- "$ref": "#/$defs/scalar"
106
- }
107
- }
108
- },
109
- "geoRecord": {
110
- "type": "object",
111
- "additionalProperties": false,
112
- "patternProperties": {
113
- "^geo:[a-z0-9_]+$": {
114
- "$ref": "#/$defs/scalar"
115
- }
116
- }
117
- },
118
- "histRecord": {
119
- "type": "object",
120
- "additionalProperties": false,
121
- "patternProperties": {
122
- "^hist:[a-z0-9_]+$": {
123
- "$ref": "#/$defs/scalar"
124
- }
125
- }
126
- },
127
- "envRecord": {
128
- "type": "object",
129
- "additionalProperties": false,
130
- "patternProperties": {
131
- "^env:[a-z0-9_]+$": {
132
- "$ref": "#/$defs/scalar"
133
- }
134
- }
135
- },
136
- "vessel": {
44
+ "subjectRole": {
137
45
  "type": "object",
138
46
  "additionalProperties": false,
139
47
  "required": [
140
- "fact"
48
+ "role",
49
+ "by"
141
50
  ],
142
51
  "properties": {
143
- "fact": {
144
- "$ref": "#/$defs/factRecord"
145
- },
146
- "kin": {
147
- "$ref": "#/$defs/kinRecord"
148
- },
149
- "geo": {
150
- "$ref": "#/$defs/geoRecord"
52
+ "role": {
53
+ "$ref": "applicability.schema.json#/$defs/effectRole"
151
54
  },
152
- "hist": {
153
- "$ref": "#/$defs/histRecord"
55
+ "by": {
56
+ "$ref": "#/$defs/ruleId"
154
57
  }
155
58
  }
156
59
  }
@@ -200,7 +103,7 @@
200
103
  "type": "string"
201
104
  },
202
105
  "bare": {
203
- "$ref": "#/$defs/entryId"
106
+ "$ref": "#/$defs/ruleId"
204
107
  },
205
108
  "with_modality": {
206
109
  "type": "object",
@@ -211,7 +114,7 @@
211
114
  ],
212
115
  "properties": {
213
116
  "entry": {
214
- "$ref": "#/$defs/entryId"
117
+ "$ref": "#/$defs/ruleId"
215
118
  },
216
119
  "modality": {
217
120
  "$ref": "#/$defs/modality"
@@ -286,28 +189,28 @@
286
189
  }
287
190
  },
288
191
  "situation": {
192
+ "$comment": "A Situation (schema/situation.schema.json, ADR 0014).",
193
+ "$ref": "situation.schema.json"
194
+ },
195
+ "roles": {
196
+ "$comment": "The pooled, resolved roles of both subjects (ADR 0016). `expect` stays the self-frame entry ids.",
289
197
  "type": "object",
290
198
  "additionalProperties": false,
291
199
  "required": [
292
- "own"
200
+ "self",
201
+ "other"
293
202
  ],
294
203
  "properties": {
295
- "own": {
296
- "$ref": "#/$defs/vessel"
204
+ "self": {
205
+ "type": "array",
206
+ "items": {
207
+ "$ref": "#/$defs/subjectRole"
208
+ }
297
209
  },
298
210
  "other": {
299
- "$ref": "#/$defs/vessel"
300
- },
301
- "pair": {
302
- "type": "object",
303
- "additionalProperties": false,
304
- "properties": {
305
- "geo": {
306
- "$ref": "#/$defs/geoRecord"
307
- },
308
- "env": {
309
- "$ref": "#/$defs/envRecord"
310
- }
211
+ "type": "array",
212
+ "items": {
213
+ "$ref": "#/$defs/subjectRole"
311
214
  }
312
215
  }
313
216
  }
@@ -0,0 +1,72 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mark-brannan/colregs/schema/situation.schema.json",
4
+ "title": "Situation",
5
+ "description": "Two vessels and the encounter at one instant: the input evaluateEncounter reads, nested by subject and class (ADR 0005 §2, ADR 0011 §3, ADR 0014). Structure only -- every kin:/geo:/hist:/env: key must be declared in data/facts.json §situation, checked in the tests.",
6
+ "$comment": "The same shape as a case's `situation` in schema/situation-fixtures.schema.json, stated once here so an operation can name it; `self` required, `other` optional (Rule 19's single-vessel scope), every class and key optional -- absent is absent.",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": ["self"],
10
+ "properties": {
11
+ "self": { "$ref": "#/$defs/subject" },
12
+ "other": { "$ref": "#/$defs/subject" },
13
+ "pair": {
14
+ "type": "object",
15
+ "additionalProperties": false,
16
+ "properties": {
17
+ "geo": { "$ref": "#/$defs/geoRecord" },
18
+ "env": { "$ref": "#/$defs/envRecord" }
19
+ }
20
+ }
21
+ },
22
+ "$defs": {
23
+ "scalar": {
24
+ "oneOf": [
25
+ { "type": "string", "pattern": "^[a-z][a-z0-9_]*:[a-z0-9_]+$" },
26
+ { "type": "number" },
27
+ { "type": "boolean" },
28
+ { "type": "null" },
29
+ {
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": ["latitude", "longitude"],
33
+ "properties": {
34
+ "latitude": { "type": "number", "minimum": -90, "maximum": 90 },
35
+ "longitude": { "type": "number", "minimum": -180, "maximum": 180 }
36
+ }
37
+ }
38
+ ]
39
+ },
40
+ "kinRecord": {
41
+ "type": "object",
42
+ "additionalProperties": false,
43
+ "patternProperties": { "^kin:[a-z0-9_]+$": { "$ref": "#/$defs/scalar" } }
44
+ },
45
+ "geoRecord": {
46
+ "type": "object",
47
+ "additionalProperties": false,
48
+ "patternProperties": { "^geo:[a-z0-9_]+$": { "$ref": "#/$defs/scalar" } }
49
+ },
50
+ "histRecord": {
51
+ "type": "object",
52
+ "additionalProperties": false,
53
+ "patternProperties": { "^hist:[a-z0-9_]+$": { "$ref": "#/$defs/scalar" } }
54
+ },
55
+ "envRecord": {
56
+ "type": "object",
57
+ "additionalProperties": false,
58
+ "patternProperties": { "^env:[a-z0-9_]+$": { "$ref": "#/$defs/scalar" } }
59
+ },
60
+ "subject": {
61
+ "type": "object",
62
+ "additionalProperties": false,
63
+ "required": ["fact"],
64
+ "properties": {
65
+ "fact": { "$ref": "fact-record.schema.json" },
66
+ "kin": { "$ref": "#/$defs/kinRecord" },
67
+ "geo": { "$ref": "#/$defs/geoRecord" },
68
+ "hist": { "$ref": "#/$defs/histRecord" }
69
+ }
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/mark-brannan/colregs/schema/trace.schema.json",
4
+ "title": "Trace",
5
+ "description": "The situation over time: the window evaluateConduct reads (ADR 0012 §2, ADR 0014). A conforming implementation rejects an empty samples list, a `t_s` that does not strictly increase, and `other` present in some samples and absent in others; `t_s` is seconds on the caller's clock, read as differences only, and the pair's identity is the caller's, since a Situation names no vessel. Structure only.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "samples"
10
+ ],
11
+ "properties": {
12
+ "samples": {
13
+ "type": "array",
14
+ "minItems": 1,
15
+ "items": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": [
19
+ "t_s",
20
+ "situation"
21
+ ],
22
+ "properties": {
23
+ "t_s": {
24
+ "type": "number"
25
+ },
26
+ "situation": {
27
+ "$ref": "situation.schema.json"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
@@ -1,7 +0,0 @@
1
- {
2
- "entry:14a": {
3
- "denoted": "The head-on classification: encounter head-on when each vessel has the other ahead or nearly ahead, cited to 14(a). Renamed when the cite moved to 14(b), the deeming paragraph the entry actually reads (Q-45); the predicate and effect are unchanged.",
4
- "deprecated_in": "0.2.0",
5
- "replacement": "entry:14b"
6
- }
7
- }
@@ -1,29 +0,0 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/mark-brannan/colregs/schema/deprecated-identifiers.schema.json",
4
- "title": "data/deprecated-identifiers.json",
5
- "description": "REQ-MODEL-11's deprecation registry: every retired identifier, what it denoted, the version that deprecated it, and its replacement where one exists. Keys are the same prefixed forms the identifier diff compares (test/data.test.mjs's extractIdentifiers) -- e.g. 'entry:25d2', 'paragraph:27(a)(i)', 'light:masthead', 'fact-key:activity', 'fact-value:activity:nuc', 'rel:includes'. Structure only -- see docs/adr/0006-json-schema-and-identifier-diff.md.",
6
- "type": "object",
7
- "additionalProperties": {
8
- "type": "object",
9
- "additionalProperties": false,
10
- "required": ["denoted", "deprecated_in"],
11
- "properties": {
12
- "denoted": {
13
- "type": "string",
14
- "minLength": 1,
15
- "description": "What the identifier meant, so a consumer pinned to an old version can resolve a stale reference without the identifier itself."
16
- },
17
- "deprecated_in": {
18
- "type": "string",
19
- "pattern": "^\\d+\\.\\d+\\.\\d+$",
20
- "description": "The released version that deprecated this identifier (REQ-MODEL-10)."
21
- },
22
- "replacement": {
23
- "type": ["string", "null"],
24
- "minLength": 1,
25
- "description": "The identifier that replaces this one, in the same prefixed form, or null where nothing replaces it."
26
- }
27
- }
28
- }
29
- }