colregs 0.3.1 → 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.
- package/README.md +5 -5
- package/data/applicability.json +270 -270
- package/data/facts.json +19 -19
- package/data/i18n/en.json +3 -3
- package/data/i18n/fi.json +3 -3
- package/data/version.json +1 -1
- package/docs/adr/0011-api-shape.md +7 -7
- package/docs/adr/0012-trace-and-rule2-departure-api.md +2 -2
- package/docs/adr/0016-encounter-roles-are-pooled-across-frames.md +82 -0
- package/docs/adr/0017-closed-vocabularies-are-prefixed-identifiers.md +105 -0
- package/docs/budgets.json +4 -1
- package/docs/decisions.md +6 -0
- package/docs/identifiers.md +73 -59
- package/docs/part-b-invariants.md +19 -18
- package/docs/requirements.md +72 -72
- package/fixtures/situation-fixtures.json +600 -329
- package/package.json +1 -1
- package/schema/applicability.schema.json +59 -59
- package/schema/conduct-evaluation.schema.json +1 -1
- package/schema/encounter-evaluation.schema.json +6 -6
- package/schema/evaluation.schema.json +2 -2
- package/schema/facts.schema.json +4 -4
- package/schema/i18n-catalog.schema.json +2 -2
- package/schema/situation-fixtures.schema.json +39 -0
- package/schema/situation.schema.json +3 -3
package/docs/requirements.md
CHANGED
|
@@ -53,10 +53,10 @@ Neither consumer lives in this repo.
|
|
|
53
53
|
| **paragraph path** | The citation unit: `27(a)(i)`, `25(d)(ii)`. Not the rule number. |
|
|
54
54
|
| **fact record** | A set of facts about one vessel at one moment; the input. |
|
|
55
55
|
| **entry** | One applicability record: predicate → lights/refs → modality → citation. |
|
|
56
|
-
| **modality** | `shall` / `may` / `shall-if-practicable`. |
|
|
56
|
+
| **modality** | `modality:shall` / `modality:may` / `modality:shall-if-practicable`. |
|
|
57
57
|
| **jurisdiction** | A body of rules: `intl`, `us/inland`, `ca/inland`, … |
|
|
58
58
|
| **delta** | A jurisdiction's departures from the international text. |
|
|
59
|
-
| **identifier** | Any name the data is addressed by: entry id, paragraph path, light id, fact key, fact value, relation name. |
|
|
59
|
+
| **identifier** | Any name the data is addressed by: entry id, paragraph path, light id, fact key, fact value, relation name, modality/role/encounter/category value, jurisdiction value. |
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
@@ -68,7 +68,7 @@ Neither consumer lives in this repo.
|
|
|
68
68
|
applicability entry and every rule-text record, expressed as
|
|
69
69
|
`<country-or-body>/<waters>` with `intl` as the reserved base value.
|
|
70
70
|
Examples: `intl`, `us/inland`, `us/great-lakes`, `us/western-rivers`,
|
|
71
|
-
`ca/inland`, `de/binnen`, `eu/cevni`.
|
|
71
|
+
`ca/inland`, `de/binnen`, `eu/cevni`. The jurisdiction value is itself an identifier, unprefixed and immutable under REQ-MODEL-10 (ADR 0017).
|
|
72
72
|
- **REQ-SCOPE-3** — A jurisdiction MUST be expressible as a *delta*: entries
|
|
73
73
|
absent from a jurisdiction's data inherit from `intl`. A jurisdiction MUST
|
|
74
74
|
NOT require restating the whole body of rules. Inheritance is "unless
|
|
@@ -168,7 +168,7 @@ Four layers, each independently addressable.
|
|
|
168
168
|
- `rel:in_lieu_of` — legal alternatives for the same fact record;
|
|
169
169
|
- `rel:excludes` — mutual exclusion, including across rules; symmetric
|
|
170
170
|
(A excludes B implies B excludes A), and no participating entry MAY be
|
|
171
|
-
forceful (`shall`/`shall-if-practicable`) — a directed "this one
|
|
171
|
+
forceful (`modality:shall`/`modality:shall-if-practicable`) — a directed "this one
|
|
172
172
|
prevails" is `rel:overrides` (ADR 0007), not `rel:excludes`;
|
|
173
173
|
- `rel:exempts` — one entry lifting another's obligation;
|
|
174
174
|
- `rel:conditional_includes` — import or alternatives, gated on a predicate.
|
|
@@ -297,27 +297,27 @@ towards, not because the shape is settled.
|
|
|
297
297
|
two-subject entries and defaulted for the rest; no record in `rules.json`
|
|
298
298
|
carries one, so a paragraph with no entry is uncategorised)** —
|
|
299
299
|
Every rule paragraph record MUST carry exactly one `category` from the
|
|
300
|
-
closed set `scope`, `definition`, `standard`, `display`,
|
|
301
|
-
`classification`, `precedence`, `conduct`, `care`, `meta`. The field
|
|
302
|
-
defaults to `display`, so existing entries are correct unedited. CI MUST
|
|
300
|
+
closed set `category:scope`, `category:definition`, `category:standard`, `category:display`,
|
|
301
|
+
`category:classification`, `category:precedence`, `category:conduct`, `category:care`, `category:meta`. The field
|
|
302
|
+
defaults to `category:display`, so existing entries are correct unedited. CI MUST
|
|
303
303
|
fail on a value outside the set. Where a paragraph plays a second role,
|
|
304
304
|
that role MUST be expressed as a relation (REQ-CAT-3), never as a second
|
|
305
305
|
category.
|
|
306
|
-
- **REQ-CAT-2** — `care` and `meta` paragraphs (Rules 2(a) and 2(b)) MUST NOT
|
|
306
|
+
- **REQ-CAT-2** — `category:care` and `category:meta` paragraphs (Rules 2(a) and 2(b)) MUST NOT
|
|
307
307
|
be applicability entries. They MUST be recorded in a registry sibling to
|
|
308
308
|
`known_omissions`, stating that the package represents them and evaluates
|
|
309
|
-
neither. CI MUST fail on a `care` or `meta` paragraph that appears as an
|
|
309
|
+
neither. CI MUST fail on a `category:care` or `category:meta` paragraph that appears as an
|
|
310
310
|
entry.
|
|
311
|
-
- **REQ-CAT-3** **(unimplemented in part — `shall-not` has no entry yet)** —
|
|
312
|
-
The modality vocabulary MUST admit `shall-not` and `shall-not-impede`
|
|
313
|
-
alongside `shall`, `may`, `shall-if-practicable`, `conditional` and
|
|
314
|
-
`exempt`, and the relation vocabulary MUST admit `rel:overrides` as a
|
|
311
|
+
- **REQ-CAT-3** **(unimplemented in part — `modality:shall-not` has no entry yet)** —
|
|
312
|
+
The modality vocabulary MUST admit `modality:shall-not` and `modality:shall-not-impede`
|
|
313
|
+
alongside `modality:shall`, `modality:may`, `modality:shall-if-practicable`, `modality:conditional` and
|
|
314
|
+
`modality:exempt`, and the relation vocabulary MUST admit `rel:overrides` as a
|
|
315
315
|
sixth verb beside REQ-MODEL-7's five. Both remain closed sets; CI MUST
|
|
316
316
|
fail on a value outside them, and on a cycle in `rel:overrides`.
|
|
317
317
|
- **REQ-CAT-4** — A two-subject rule MUST read a **situation record**:
|
|
318
318
|
two per-vessel fact records, a kinematic state per vessel, relative
|
|
319
319
|
geometry, and history. The per-vessel fact record MUST NOT change to accommodate it, and kinematic
|
|
320
|
-
state MUST be a distinct fact class — a consumer that reads only `display`
|
|
320
|
+
state MUST be a distinct fact class — a consumer that reads only `category:display`
|
|
321
321
|
entries MUST NOT be required to supply one. Adding the situation record
|
|
322
322
|
MUST leave every existing fixture valid unedited.
|
|
323
323
|
- **REQ-CAT-5** — A situation MUST NOT be expressible in the current
|
|
@@ -328,10 +328,10 @@ towards, not because the shape is settled.
|
|
|
328
328
|
- **REQ-CAT-6** — The situation record MUST be declared in
|
|
329
329
|
`data/facts.json` under `situation`, and MUST address each vessel's facts
|
|
330
330
|
through the subject namespace of `docs/identifiers.md`:
|
|
331
|
-
`<subject>:<class>:<key>`, subject from `
|
|
332
|
-
`fact`/`kin`/`geo`/`hist`/`env`. A key with no subject segment MUST mean `
|
|
331
|
+
`<subject>:<class>:<key>`, subject from `self`/`other`/`pair`, class from
|
|
332
|
+
`fact`/`kin`/`geo`/`hist`/`env`. A key with no subject segment MUST mean `self:`,
|
|
333
333
|
so that every predicate and fixture published today is a valid situation
|
|
334
|
-
predicate unedited. `
|
|
334
|
+
predicate unedited. `self:fact:*` and `other:fact:*` MUST resolve to the
|
|
335
335
|
per-vessel fact record key for key, with no key renamed or copied.
|
|
336
336
|
`pair` MUST carry only classes whose facts are symmetric between the two
|
|
337
337
|
vessels; `env` — where the encounter is happening — is `pair`-only for that
|
|
@@ -350,27 +350,27 @@ towards, not because the shape is settled.
|
|
|
350
350
|
`expect` MUST be either a bare entry id — the published one-subject form,
|
|
351
351
|
asserting nothing about modality — or `{entry, modality}` naming the
|
|
352
352
|
modality that entry is expected to carry, which is what Q-5 needs. A case
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
names an entry.
|
|
353
|
+
MAY state `roles`, the pooled two-frame answer for both subjects (ADR
|
|
354
|
+
0016). An `illustrative` case MUST assert no entries and MUST NOT join the
|
|
355
|
+
replay. CI MUST fail on an undeclared fact, an unresolvable key, an unknown
|
|
356
|
+
entry id or modality, a stated role the pooled read does not yield, and on
|
|
357
|
+
an `illustrative` case that names an entry.
|
|
358
358
|
|
|
359
359
|
- **REQ-CAT-8** — A two-subject entry MUST state an `effect` and MUST NOT
|
|
360
|
-
state `lights`. For a `precedence` entry the effect MUST be a role per
|
|
361
|
-
subject, `{
|
|
362
|
-
`shall-not-impede`, `keep-clear`, `none`; for a `scope` entry it MUST name
|
|
360
|
+
state `lights`. For a `category:precedence` entry the effect MUST be a role per
|
|
361
|
+
subject, `{self, other}`, from the closed set `role:give-way`, `role:stand-on`,
|
|
362
|
+
`role:shall-not-impede`, `role:keep-clear`, `role:none`; for a `category:scope` entry it MUST name
|
|
363
363
|
the part, the section and the rules that section governs; for a
|
|
364
|
-
`classification` entry it MUST carry exactly one key, either `encounter`
|
|
365
|
-
from the closed set `head-on`, `crossing`, `overtaking`, `none`, or
|
|
366
|
-
`risk_of_collision`, whose only value is `true`. `stand-on` MUST
|
|
367
|
-
appear only as the counterpart of `give-way`, and the counterpart of
|
|
368
|
-
`shall-not-impede` MUST be `none` — Rule 8(f)(iii) is why. CI MUST fail on a
|
|
364
|
+
`category:classification` entry it MUST carry exactly one key, either `encounter`
|
|
365
|
+
from the closed set `encounter:head-on`, `encounter:crossing`, `encounter:overtaking`, `encounter:none`, or
|
|
366
|
+
`risk_of_collision`, whose only value is `true`. `role:stand-on` MUST
|
|
367
|
+
appear only as the counterpart of `role:give-way`, and the counterpart of
|
|
368
|
+
`role:shall-not-impede` MUST be `role:none` — Rule 8(f)(iii) is why. CI MUST fail on a
|
|
369
369
|
role or an encounter outside its set, on an effect whose shape does not match
|
|
370
370
|
its category, and on a `rel:overrides` that resolves to no entry, points at an
|
|
371
371
|
entry of a different category, or closes a cycle. `✎` pencil, with the rest of
|
|
372
372
|
§4.1.
|
|
373
|
-
- **REQ-CAT-9** — The `classification` entries for Rules 13, 14 and 15 MUST
|
|
373
|
+
- **REQ-CAT-9** — The `category:classification` entries for Rules 13, 14 and 15 MUST
|
|
374
374
|
**partition** the pair's relative geometry: for any situation those entries
|
|
375
375
|
all reach, exactly one encounter type MUST apply — never two, never none.
|
|
376
376
|
The crossing sector MUST NOT be enumerated; it MUST be derived, as the
|
|
@@ -447,7 +447,7 @@ See ADR 0003.
|
|
|
447
447
|
from the other, and no property beyond the language of the text — not
|
|
448
448
|
source, audience, nor legal applicability — MUST be inferred from a tag.
|
|
449
449
|
- **REQ-LANG-2** — Identifiers — entry ids, fact values, light ids,
|
|
450
|
-
paragraph paths, relation names — MUST be language-neutral and MUST NOT
|
|
450
|
+
paragraph paths, relation names, modality/role/encounter/category values — MUST be language-neutral and MUST NOT
|
|
451
451
|
be localized. Translations attach to identifiers; they never replace them.
|
|
452
452
|
Identifiers are schema keywords, not display strings: each vocabulary
|
|
453
453
|
distinguishes machine identifier, display label (catalog), and definition,
|
|
@@ -805,7 +805,7 @@ Tracked here until resolved; each becomes an ADR.
|
|
|
805
805
|
this package: a making-way indicator, and `design.maxSpeed`.
|
|
806
806
|
- **Q-5** — REQ-VERIFY-5 asks for boundary fixtures on every numeric gate.
|
|
807
807
|
Three gates (`rule:23a_ii`, `rule:26b_ii`, `rule:30c`'s `fact:length_m` thresholds) live only in
|
|
808
|
-
`modality_by`, not in the entry's `when` — they flip `shall` to `may`, not
|
|
808
|
+
`modality_by`, not in the entry's `when` — they flip `modality:shall` to `modality:may`, not
|
|
809
809
|
which entries apply. The fixture format only asserts applying entry ids, not
|
|
810
810
|
expected modality, so there is no way to fixture these three without
|
|
811
811
|
extending the schema to carry expected modality per entry. Not done
|
|
@@ -956,7 +956,7 @@ listed here, one line each, because the ADR is what makes them live. Most are
|
|
|
956
956
|
- **Q-14** — Which category does each paragraph take? The proposal's table is
|
|
957
957
|
a first cut; settled paragraph by paragraph as Rules 1–19 are transcribed.
|
|
958
958
|
PR #24 settles the first sixteen and departs from the table once: 13(a) is
|
|
959
|
-
`precedence`, not `classification` (`Q-37`).
|
|
959
|
+
`category:precedence`, not `category:classification` (`Q-37`).
|
|
960
960
|
- **Q-15** — Which verification tool discharges each category (Alloy, Z3, TLA+,
|
|
961
961
|
STL, Rocq)? Settled by building one proof per category, not by argument.
|
|
962
962
|
*(engine)*
|
|
@@ -1004,38 +1004,38 @@ listed here, one line each, because the ADR is what makes them live. Most are
|
|
|
1004
1004
|
- **Q-26** — How large is the relative-frame state space? The 10⁴–10⁶ figure
|
|
1005
1005
|
is a back-of-envelope guess; settled by a worksheet. *(engine)*
|
|
1006
1006
|
- **Q-27** — What are the field names for `category`, `subjects`, `when`,
|
|
1007
|
-
`effect` and the widened `modality`? Settled when the first non-`display`
|
|
1007
|
+
`effect` and the widened `modality`? Settled when the first non-`category:display`
|
|
1008
1008
|
entry lands, and cheap to change until then.
|
|
1009
1009
|
Unchanged by PR #22, which names none of those five. The names it
|
|
1010
1010
|
does fix — `situation`, the four classes, the three subjects — are
|
|
1011
1011
|
REQ-CAT-6's and are equally pencil.
|
|
1012
1012
|
- **Q-28** — What namespace distinguishes the two subjects of a two-subject
|
|
1013
|
-
entry (`
|
|
1013
|
+
entry (`self:` / `other:` is the working proposal)? No such segment exists in
|
|
1014
1014
|
`docs/identifiers.md`; settled before Rule 18 lands, and it is an
|
|
1015
1015
|
identifier decision under REQ-MODEL-10.
|
|
1016
1016
|
**Decided in pencil 2026-09-04** (PR #22): `<subject>:<class>:<key>`
|
|
1017
|
-
with subject `
|
|
1018
|
-
bare key meaning `
|
|
1017
|
+
with subject `self`/`other`/`pair` and class `fact`/`kin`/`geo`/`hist`, and a
|
|
1018
|
+
bare key meaning `self:`. Written up in `docs/identifiers.md` §"Two
|
|
1019
1019
|
subjects", required by REQ-CAT-6, and exercised by
|
|
1020
1020
|
`fixtures/situation-fixtures.json`. Three things the working proposal did
|
|
1021
1021
|
not have: a third subject, because range and in-sight belong to the
|
|
1022
1022
|
encounter and not to either vessel; a class segment, so kinematics and
|
|
1023
1023
|
history are new classes rather than new fact keys; and the bare-key default,
|
|
1024
1024
|
which is what makes the whole thing additive under REQ-MODEL-10 — no
|
|
1025
|
-
existing identifier is renamed or repointed, and `
|
|
1025
|
+
existing identifier is renamed or repointed, and `self`/`other`/`pair` become
|
|
1026
1026
|
reserved at the head of the identifier space, which is the only cost.
|
|
1027
1027
|
Settled for good by Rule 18 being written against it.
|
|
1028
1028
|
- **Q-29** — What are the file names and schemas for the invariants file and
|
|
1029
1029
|
the region grid, and how does a level-3 invariant carry `jurisdiction`?
|
|
1030
1030
|
Settled when the first invariant is written down.
|
|
1031
|
-
- **Q-30** — What does the `care`/`meta` registry look like as a file — its
|
|
1031
|
+
- **Q-30** — What does the `category:care`/`category:meta` registry look like as a file — its
|
|
1032
1032
|
name, its schema, and its relationship to `known_omissions`? Settled by
|
|
1033
1033
|
REQ-CAT-2's implementation, which is the next data change after this ADR.
|
|
1034
1034
|
|
|
1035
1035
|
**Decided in pencil, PR #23.** The registry is `represented_paragraphs`,
|
|
1036
1036
|
a sibling array to `known_omissions` in `data/applicability.json`. Each
|
|
1037
1037
|
record: `id` (paragraph-derived, e.g. `2a`), `jurisdiction`, `cite`,
|
|
1038
|
-
`category` (`care` or `meta`), and a one-sentence `note`; no `when`, no
|
|
1038
|
+
`category` (`category:care` or `category:meta`), and a one-sentence `note`; no `when`, no
|
|
1039
1039
|
`lights` — a registry record states that the paragraph is represented
|
|
1040
1040
|
and evaluated by nothing here, never a predicate. Holds the `2(a)` and
|
|
1041
1041
|
`2(b)` records this PR adds. `✎` under `docs/conventions.md`: the file
|
|
@@ -1049,8 +1049,8 @@ here rather than in a commit message. All pencil.
|
|
|
1049
1049
|
|
|
1050
1050
|
**Decided in pencil 2026-09-04 (PR #24)**, answering the data half of `Q-27`:
|
|
1051
1051
|
the field names are `category`, `subjects` and `effect`, and `effect` is
|
|
1052
|
-
`{
|
|
1053
|
-
applies_rules}` for a `scope` one. Written up in `docs/identifiers.md`
|
|
1052
|
+
`{self, other}` roles for a `category:precedence` entry and `{part, section,
|
|
1053
|
+
applies_rules}` for a `category:scope` one. Written up in `docs/identifiers.md`
|
|
1054
1054
|
§"Effects", required by `REQ-CAT-8`, and exercised by
|
|
1055
1055
|
`fixtures/situation-fixtures.json`. `Q-28`'s namespace is settled for good by
|
|
1056
1056
|
the same PR — Rule 18 is written against it and it held, with one addition:
|
|
@@ -1062,13 +1062,13 @@ named that gap before the class existed.
|
|
|
1062
1062
|
- **Q-31** — `modality` is a single closed value, and 18(c), 18(d)(i) and 9(a)
|
|
1063
1063
|
each carry two deontic qualifications at once: a practicability caveat
|
|
1064
1064
|
("so far as possible", "if the circumstances of the case admit") *and* the
|
|
1065
|
-
duty itself. 18(c) is expressible because `shall-if-practicable` already
|
|
1065
|
+
duty itself. 18(c) is expressible because `modality:shall-if-practicable` already
|
|
1066
1066
|
exists; 18(d)(i) is not, and its caveat is dropped with a `gap` note on the
|
|
1067
1067
|
entry. Settled by deciding whether practicability is a second field beside
|
|
1068
1068
|
`modality` rather than a value inside it — which is the same question
|
|
1069
1069
|
`modality_by` answers for the light rules, and should probably be answered
|
|
1070
1070
|
the same way. **Narrowed, not settled, 2026-09-04 (PR #25):** 18(d)(i) is now
|
|
1071
|
-
`shall-if-practicable` with `effect.
|
|
1071
|
+
`modality:shall-if-practicable` with `effect.self: role:shall-not-impede`, so the two
|
|
1072
1072
|
qualifications sit in two fields and neither is dropped. That works only
|
|
1073
1073
|
because this duty happens to be a *role*, which `effect` already carries;
|
|
1074
1074
|
9(a)'s "if the circumstances of the case admit" has no second field to move
|
|
@@ -1086,7 +1086,7 @@ named that gap before the class existed.
|
|
|
1086
1086
|
`rule18_class:fishing` by 3(d), and the 27(c) tow that severely restricts the
|
|
1087
1087
|
pair — the one the old predicates could not catch at all — to
|
|
1088
1088
|
`rule18_class:ram`, via a new boolean `fact:tow_restricts_deviation`. Every
|
|
1089
|
-
Rule 18, 9 and 10 entry reads the class; no `precedence` entry reads
|
|
1089
|
+
Rule 18, 9 and 10 entry reads the class; no `category:precedence` entry reads
|
|
1090
1090
|
`fact:activity` any more, and a test enforces that. `fact:activity` itself is
|
|
1091
1091
|
unchanged and no entry that reads it was touched. What is *not* settled: the
|
|
1092
1092
|
eighth rank Rule 18 distinguishes is the seaplane of 3(e), and it has no
|
|
@@ -1116,7 +1116,7 @@ named that gap before the class existed.
|
|
|
1116
1116
|
alternative was declined: it would have produced a predicate no reader could
|
|
1117
1117
|
check against the rule text, to avoid a language feature the rules themselves
|
|
1118
1118
|
use in plain words.
|
|
1119
|
-
- **Q-34** — A `shall-not-impede` entry names a duty toward `other`, but the
|
|
1119
|
+
- **Q-34** — A `modality:shall-not-impede` entry names a duty toward `other`, but the
|
|
1120
1120
|
paragraphs identify the protected vessel by a property this package does not
|
|
1121
1121
|
carry: "a vessel which can safely navigate only within a narrow channel"
|
|
1122
1122
|
(9(b), 9(d)), "any vessel following a traffic lane" (10(i), 10(j)), and a
|
|
@@ -1142,37 +1142,37 @@ named that gap before the class existed.
|
|
|
1142
1142
|
predicate reads only facts, so entry `rule:8f_iii` reads the risk-of-collision half
|
|
1143
1143
|
alone and applies to every pair with risk of collision. Settled by deciding
|
|
1144
1144
|
whether a norm may read another norm's effect, which is the same question a
|
|
1145
|
-
`conduct` monitor will ask about role and phase.
|
|
1145
|
+
`category:conduct` monitor will ask about role and phase.
|
|
1146
1146
|
- **Q-36** — Rule 18(a)(iv) and 18(d)(i) are both in force between a sailing
|
|
1147
1147
|
vessel and a vessel constrained by her draught: the CBD vessel gives way, and
|
|
1148
1148
|
the sailing vessel must not impede her. Neither overrides the other and the
|
|
1149
|
-
model records both, so one subject holds `stand-on` and `shall-not-impede`
|
|
1149
|
+
model records both, so one subject holds `role:stand-on` and `role:shall-not-impede`
|
|
1150
1150
|
at once. The test suite pins it as a finding rather than asserting it away.
|
|
1151
1151
|
Settled by reading 8(f)(ii) against the cases, not by picking a role.
|
|
1152
|
-
- **Q-37** — 13(a) is `classification` in ADR 0005 §1 and in the proposal's
|
|
1152
|
+
- **Q-37** — 13(a) is `category:classification` in ADR 0005 §1 and in the proposal's
|
|
1153
1153
|
first-cut table, but it is the one paragraph of Rule 13 that assigns a role
|
|
1154
|
-
and a `classification` entry has nowhere to put one. Entry `rule:13a` is
|
|
1155
|
-
`precedence` here, with 13(b)'s sector test left for the `classification`
|
|
1154
|
+
and a `category:classification` entry has nowhere to put one. Entry `rule:13a` is
|
|
1155
|
+
`category:precedence` here, with 13(b)'s sector test left for the `category:classification`
|
|
1156
1156
|
entry that would set the `hist:was_overtaking` latch. Settled with the rest
|
|
1157
1157
|
of `Q-14`, paragraph by paragraph.
|
|
1158
1158
|
|
|
1159
1159
|
**Closed in pencil 2026-09-04 (PR #26).** 13(b) is now written, as *two*
|
|
1160
|
-
`classification` entries rather than one — one per subject — because the
|
|
1160
|
+
`category:classification` entries rather than one — one per subject — because the
|
|
1161
1161
|
encounter type belongs to the pair and reading aspect alone classified the
|
|
1162
|
-
overtaken vessel's side of the same encounter as a crossing. 13(a) stays `precedence`, and its predicate now carries both
|
|
1162
|
+
overtaken vessel's side of the same encounter as a crossing. 13(a) stays `category:precedence`, and its predicate now carries both
|
|
1163
1163
|
halves of "any vessel overtaking any other": the 13(b) sector and the 13(d)
|
|
1164
1164
|
latch, as an `any_of`, which closes the gap the entry recorded. 13(d) is a
|
|
1165
|
-
third `classification` entry, reading history and no geometry at all. The
|
|
1165
|
+
third `category:classification` entry, reading history and no geometry at all. The
|
|
1166
1166
|
split confirms the thing ADR 0005 §1 was really defending — one category per
|
|
1167
1167
|
paragraph. **Reversed in part, 2026-09-16:** ADR 0015 as rewritten makes
|
|
1168
1168
|
13(b) one symmetric entry, `rule:13b`, reading the same sector object on
|
|
1169
|
-
either subject under `any_of`. 13(a) staying `precedence` is untouched.
|
|
1169
|
+
either subject under `any_of`. 13(a) staying `category:precedence` is untouched.
|
|
1170
1170
|
- **Q-38** — 9(d), 18(d)(ii), 18(e), 18(f)(ii), 1(a)–(e) and 20(b)–(c) are
|
|
1171
1171
|
recorded in `known_omissions` rather than modelled: 9(d) needs the channel's
|
|
1172
1172
|
axis, 18(e) needs a fact for being a seaplane, 20(b)–(c) need time of day,
|
|
1173
1173
|
and 1(a)–(e) are addressed to an authority rather than to a vessel. Settled
|
|
1174
1174
|
one at a time as the facts they need land; none blocks the rest of Part B.
|
|
1175
|
-
- **Q-39** — Rule 4's `scope` entry has an empty `when`, because "any condition
|
|
1175
|
+
- **Q-39** — Rule 4's `category:scope` entry has an empty `when`, because "any condition
|
|
1176
1176
|
of visibility" is the absence of a condition. That makes it unfalsifiable —
|
|
1177
1177
|
`REQ-VERIFY-3`'s "excluded by at least one fixture" half cannot be satisfied
|
|
1178
1178
|
and the test exempts it explicitly. Settled by deciding whether an ungated
|
|
@@ -1181,17 +1181,17 @@ named that gap before the class existed.
|
|
|
1181
1181
|
|
|
1182
1182
|
### From the classification norms (PR #26)
|
|
1183
1183
|
|
|
1184
|
-
Rules 7(d), 12, 13(b)–(d), 14 and 15 are the first `classification` entries and
|
|
1185
|
-
the second family of `precedence` ones. All pencil. What the model expressed is
|
|
1184
|
+
Rules 7(d), 12, 13(b)–(d), 14 and 15 are the first `category:classification` entries and
|
|
1185
|
+
the second family of `category:precedence` ones. All pencil. What the model expressed is
|
|
1186
1186
|
written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
1187
1187
|
|
|
1188
|
-
- **Q-40** — **Rule 12 is `precedence`, not `classification`.** ADR 0005 §1 and
|
|
1189
|
-
the proposal's table both file it under `classification`; it produces a role
|
|
1188
|
+
- **Q-40** — **Rule 12 is `category:precedence`, not `category:classification`.** ADR 0005 §1 and
|
|
1189
|
+
the proposal's table both file it under `category:classification`; it produces a role
|
|
1190
1190
|
— "one of them shall keep out of the way of the other" — and a
|
|
1191
1191
|
classification effect has nowhere to put one, which is `Q-37`'s argument
|
|
1192
1192
|
applied a second time. Two sailing vessels are still in a head-on, a crossing
|
|
1193
1193
|
or an overtaking; Rule 12 says which of them gives way, not what kind of
|
|
1194
|
-
meeting it is. 12(b) is a `definition` and is the cite on `kin:wind_side`
|
|
1194
|
+
meeting it is. 12(b) is a `category:definition` and is the cite on `kin:wind_side`
|
|
1195
1195
|
rather than an entry. The second half of the question is narrower and worse:
|
|
1196
1196
|
12(a) says "two sailing vessels", which is 3(c), but entries the three Rule 12 entries
|
|
1197
1197
|
read `rule18_class:sail` instead, so a vessel engaged in fishing under sail
|
|
@@ -1255,7 +1255,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1255
1255
|
which is still how the fixtures are written and is what makes these six
|
|
1256
1256
|
overrides observable rather than invisible.
|
|
1257
1257
|
|
|
1258
|
-
The category half — Rule 12 as `precedence` — is unchanged and stays with
|
|
1258
|
+
The category half — Rule 12 as `category:precedence` — is unchanged and stays with
|
|
1259
1259
|
`Q-14`.
|
|
1260
1260
|
- **Q-41** — **13(c) and 14(c) invert the absent-fact rule.** "When a vessel is
|
|
1261
1261
|
in any doubt as to whether she is overtaking, she shall assume that this is
|
|
@@ -1316,14 +1316,14 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1316
1316
|
the same question `Q-39` asks about an ungated norm, from the other end.
|
|
1317
1317
|
|
|
1318
1318
|
**Decided in pencil 2026-09-05 (PR #36): the head-on classification cites
|
|
1319
|
-
14(b), and 14(a) is `conduct`.** The question assumed 14(b) produced no
|
|
1319
|
+
14(b), and 14(a) is `category:conduct`.** The question assumed 14(b) produced no
|
|
1320
1320
|
effect of its own. It produces the only effect the entry has: "such a
|
|
1321
1321
|
situation shall be deemed to exist when…" is the deeming test, and
|
|
1322
|
-
`{"encounter": "head-on"}` is what a deeming test yields — exactly as
|
|
1322
|
+
`{"encounter": "encounter:head-on"}` is what a deeming test yields — exactly as
|
|
1323
1323
|
`rule:13b` cites 13(b), the deeming paragraph,
|
|
1324
1324
|
and not 13(a). 14(a) states the situation in words ("reciprocal or nearly
|
|
1325
1325
|
reciprocal courses") and imposes the duty ("each shall alter her course to
|
|
1326
|
-
starboard"); the duty is `conduct`, and the words are what 14(b) makes
|
|
1326
|
+
starboard"); the duty is `category:conduct`, and the words are what 14(b) makes
|
|
1327
1327
|
checkable. So the entry is `rule:14b`, cites 14(b), and reads nothing 14(b) does
|
|
1328
1328
|
not fix; 14(a) joins `known_omissions` as conduct beside 18(d)(ii), and
|
|
1329
1329
|
the `14a` id it displaced is gone with the rest of the citation-derived ids
|
|
@@ -1333,7 +1333,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1333
1333
|
instance of it.
|
|
1334
1334
|
- **Q-46** — **"Coming up with" is a comparison of two facts.** 13(b) deems a
|
|
1335
1335
|
vessel to be overtaking when *coming up with* another from more than 22.5°
|
|
1336
|
-
abaft her beam. That is `
|
|
1336
|
+
abaft her beam. That is `self:kin:sog_kn` against `other:kin:sog_kn`, and the
|
|
1337
1337
|
predicate language compares a fact to a constant and never one fact to
|
|
1338
1338
|
another — the same wall `rule:12a_ii` hits on "both have the wind on the same side",
|
|
1339
1339
|
which it gets over only because that comparison has two values to enumerate
|
|
@@ -1351,7 +1351,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1351
1351
|
Not approximated with a range or a bearing: past and clear is a seamanship
|
|
1352
1352
|
judgement of the same kind as risk of collision, and a threshold for it would
|
|
1353
1353
|
be a number invented rather than declared. Settled by whatever settles the
|
|
1354
|
-
`conduct` monitors, which are the things that watch a duty end rather than
|
|
1354
|
+
`category:conduct` monitors, which are the things that watch a duty end rather than
|
|
1355
1355
|
begin.
|
|
1356
1356
|
|
|
1357
1357
|
**Ruled 2026-09-08:** while one vessel holds the latch, 13(a)'s sector
|
|
@@ -1364,7 +1364,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1364
1364
|
drops back onto the latch-holder's own stern, and only the latch-holder
|
|
1365
1365
|
gives way.
|
|
1366
1366
|
- **Q-48** — **Nothing checks that a situation is geometrically possible.**
|
|
1367
|
-
`
|
|
1367
|
+
`self:geo:rel_bearing_deg`, `other:geo:rel_bearing_deg`, the two
|
|
1368
1368
|
`kin:heading_deg` and the two `kin:sog_kn` are six facts related by two
|
|
1369
1369
|
equations, and the situation record enforces neither. A consumer — or a
|
|
1370
1370
|
fixture — can state a pair of bearings that no two headings produce, and the
|
|
@@ -1381,7 +1381,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1381
1381
|
**Decided in pencil 2026-09-05: the record gains a consistency check,
|
|
1382
1382
|
declared in data and enforced in the suite.** `data/facts.json` declares the
|
|
1383
1383
|
equations under `situation.geometry.consistency` — the two relative bearings
|
|
1384
|
-
are two readings of one line of sight (`
|
|
1384
|
+
are two readings of one line of sight (`self + self heading + 180 ≡ aspect +
|
|
1385
1385
|
other heading`), positions reproduce range and both bearings, and the two
|
|
1386
1386
|
headings and speeds reproduce CPA, TCPA and bearing rate — with tolerances,
|
|
1387
1387
|
and `REQ-VERIFY-8` requires the suite to apply them. A quantity a record does
|
|
@@ -1398,7 +1398,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1398
1398
|
"never both give-way" property is asserted over a sweep of steady-bearing
|
|
1399
1399
|
geometries — every relative bearing, several speed pairs, both intercept
|
|
1400
1400
|
solutions — where it is a theorem rather than an observation:
|
|
1401
|
-
`u·sin(
|
|
1401
|
+
`u·sin(self bearing) = −v·sin(aspect)`, so the two bearings lie on opposite
|
|
1402
1402
|
sides and 15(a) can name only one vessel. The both-starboard counterexample
|
|
1403
1403
|
is pinned as a record the check rejects. What is *not* settled, and is
|
|
1404
1404
|
pinned too: the theorem is exact only at a bearing rate of zero, and
|
|
@@ -1412,7 +1412,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
1412
1412
|
|
|
1413
1413
|
- **Q-49** — **Must `rule:13d`'s effect cross the Section II/III boundary for Rule 19(d)(i) to be expressible?**
|
|
1414
1414
|
- *broad* — drop `rule:13d`'s `pair:geo:in_sight` gate so `encounter: overtaking` is visible in Section III; breaks the scope invariant.
|
|
1415
|
-
- *narrow* — `rule:13d` stays gated; a 19(d)(i) entry reads `
|
|
1415
|
+
- *narrow* — `rule:13d` stays gated; a 19(d)(i) entry reads `self:hist:was_overtaking`/`other:hist:was_overtaking` directly, as `rule:14b` and `rule:15a:crossing` already do.
|
|
1416
1416
|
- Default: narrow (nothing changes).
|
|
1417
1417
|
- Recommendation: narrow — the test named below shows the fact resolves out of sight
|
|
1418
1418
|
(`Q-49: hist:was_overtaking resolves out of sight; rule:13d does not fire`, `test/data.test.mjs`).
|