colregs 0.3.3 → 0.3.4
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 +10 -3
- package/data/applicability.json +118 -12
- package/data/corpora.json +5 -5
- package/data/editions.json +7 -2
- package/data/images.json +12 -4
- package/data/rules.json +216 -1
- package/data/text/intl/1977/fi.finlex.json +881 -0
- package/data/version.json +1 -1
- package/docs/adr/0013-corpus-files-with-editions.md +19 -0
- package/docs/adr/0020-skeleton-is-a-delta.md +80 -0
- package/docs/budgets.json +2 -1
- package/docs/decisions.md +2 -0
- package/docs/gates.json +41 -0
- package/docs/maritime-sources.md +17 -0
- package/docs/part-b-invariants.md +3 -1
- package/docs/requirements.md +24 -25
- package/fixtures/applicability-fixtures.json +50 -2
- package/package.json +1 -1
- package/schema/display-evaluation.schema.json +0 -4
- package/schema/rules.schema.json +48 -0
- package/data/text/intl/2016/fi.finlex.json +0 -22
package/data/version.json
CHANGED
|
@@ -53,6 +53,25 @@ anyone has checked, and the `us/inland@2014` edition is recalled, not
|
|
|
53
53
|
verified, and says so. That is the honest cost of this option and the reason
|
|
54
54
|
to look at both.
|
|
55
55
|
|
|
56
|
+
## Considered and declined (amendment, 2026-09-16)
|
|
57
|
+
|
|
58
|
+
Four designs additive on option B, declined for now rather than on
|
|
59
|
+
principle — each recorded in requirements.md §10 as a timed gate, closing
|
|
60
|
+
event the first national text whose edition cannot be determined:
|
|
61
|
+
|
|
62
|
+
- **Validity intervals on editions (`in_force_until`).** (GATE-7)
|
|
63
|
+
`superseded_by` plus `in_force` already infers validity for every
|
|
64
|
+
edition on file; a dedicated field would duplicate that inference.
|
|
65
|
+
- **A per-source publication record separate from the edition, FRBR
|
|
66
|
+
manifestation.** (GATE-8) `source` lives on the corpus and one edition
|
|
67
|
+
has one source per jurisdiction today; nothing distinguishes yet.
|
|
68
|
+
- **A content digest per corpus for verification.** (GATE-9)
|
|
69
|
+
`edition_status` already flags an unchecked corpus; a digest adds
|
|
70
|
+
tamper/drift detection nothing on file has needed.
|
|
71
|
+
- **A skeleton per edition, instead of one shared skeleton.** (GATE-10)
|
|
72
|
+
Low risk today: no amendment has ever renumbered a rule (GATE-1's
|
|
73
|
+
verified history). The trigger is the first one that does.
|
|
74
|
+
|
|
56
75
|
## Consequences
|
|
57
76
|
|
|
58
77
|
- Breaking file layout (REQ-PKG-4): `data/rules.json` no longer carries
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# ADR 0020 — The skeleton is a delta too: a jurisdiction's paragraphs are a merge patch over `intl`
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-17
|
|
4
|
+
Status: proposed — merging this PR is the ruling; a revert undoes it
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
ADR 0018 made the entries table a delta over `intl`. The skeleton was not
|
|
9
|
+
one. `data/rules.json` keyed every paragraph by bare path, one record per
|
|
10
|
+
key, and every one of them was `intl`; the corpus test asserted that a
|
|
11
|
+
corpus paragraph's path belongs to the corpus's own jurisdiction. So a
|
|
12
|
+
`us/inland` corpus could not carry `21(a)`: the key existed and was
|
|
13
|
+
`intl`'s. The 2026-08-30 diff of 33 CFR 83 against Part C found 18 paths
|
|
14
|
+
where Inland spells the same path with different text, three it does not
|
|
15
|
+
spell at all, and a dozen it adds. None of the 18 could be stated. That,
|
|
16
|
+
not a licence, is why the Inland corpus stub had no paragraphs (issue
|
|
17
|
+
#161), and why every planning session stalled on "the second jurisdiction".
|
|
18
|
+
|
|
19
|
+
Solace ruled on issue #137 on 2026-09-17: `us/inland`, Part C, before v1.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
1. **`rules.json` gains `deltas`, keyed by jurisdiction.** A delta has
|
|
24
|
+
`paragraphs` (own rows, keyed by path, each carrying its jurisdiction)
|
|
25
|
+
and `suppressions` (paths the source does not spell, each with a `why`).
|
|
26
|
+
`paragraphs` at the top level stays the `intl` base, untouched, so every
|
|
27
|
+
existing consumer reads what it read.
|
|
28
|
+
|
|
29
|
+
2. **A jurisdiction's resolved skeleton is the RFC 7396 merge patch of its
|
|
30
|
+
delta over the base**, the same statement ADR 0018 makes for entries: own
|
|
31
|
+
rows present, suppressed paths `null`, an unmentioned path inherited
|
|
32
|
+
whole. A restated path merges field by field, so an own row that says
|
|
33
|
+
nothing about `images` inherits the base figure. The test builds the
|
|
34
|
+
patch, applies a literal RFC 7396 implementation, and asserts the
|
|
35
|
+
resolved skeleton is what corpora, entries and fixtures key into.
|
|
36
|
+
|
|
37
|
+
3. **A path is stated in a delta when its text differs from `intl` or has no
|
|
38
|
+
`intl` counterpart; suppressed when the source does not spell it; silent
|
|
39
|
+
otherwise.** A `[Reserved]` section is a spelled path with reserved text,
|
|
40
|
+
so it is stated, not suppressed: Inland `28` and `26(d)` are rows whose
|
|
41
|
+
corpus text will be `[Reserved]`.
|
|
42
|
+
|
|
43
|
+
4. **An entry in force under a jurisdiction cites a path in that
|
|
44
|
+
jurisdiction's resolved skeleton.** An inherited `intl` entry whose path
|
|
45
|
+
the delta suppresses cannot stand by silence: it is tombstoned, and where
|
|
46
|
+
the norm survives under another path, replaced (ADR 0018 point 3).
|
|
47
|
+
|
|
48
|
+
5. **`us/inland` lands with its Part C skeleton delta**, every row from
|
|
49
|
+
`docs/verification/2026-08-30-q6-q8.md`: 19 restated paths (the 18
|
|
50
|
+
differing plus `28`), 18 Inland-only paths, and `23(d)(i)`, `23(d)(ii)`,
|
|
51
|
+
`23(d)(iii)` suppressed. A new sub-paragraph is stated when `intl`
|
|
52
|
+
already carries sibling sub-rows of that parent; where `intl`'s parent is
|
|
53
|
+
one row, the parent is restated and the sub-paragraph waits for the
|
|
54
|
+
corpus. So `24(f)`'s Inland `(iii)` and `22(d)`'s Inland `(ii)` wait
|
|
55
|
+
(`24(f)`, `22(d)` are one row each in `intl`), while `24(g)(v)` is stated
|
|
56
|
+
(`intl`'s `24(g)(i)` is a sibling row). `NRHB_23_e.png` and
|
|
57
|
+
`NRHB_24_j.png` are mapped to `23(e)` and `24(j)` and stop being
|
|
58
|
+
unmapped.
|
|
59
|
+
|
|
60
|
+
6. **The first replace lands with it.** Inland 83.23(d) is the under-12 m
|
|
61
|
+
provision as one paragraph; `23(d)(i)` is not a path there. Point 4
|
|
62
|
+
forces the branch ADR 0018 left unexercised: `rule:23d_i` is tombstoned
|
|
63
|
+
under `us/inland` and `rule:23d`, same predicate and lights, cites
|
|
64
|
+
`23(d)`. Fixtures show both sides.
|
|
65
|
+
|
|
66
|
+
## Consequences
|
|
67
|
+
|
|
68
|
+
- The Inland corpus can now be filled: every path it will carry resolves.
|
|
69
|
+
Text is 17 U.S.C. 105, so REQ-PROV-2 does not gate it. That is the next PR.
|
|
70
|
+
- `us/inland` is now six applicability records and a skeleton delta of 40
|
|
71
|
+
rows. README's coverage statement says so; it is still not a model of the
|
|
72
|
+
Inland Rules until the entries for the restated paths land.
|
|
73
|
+
- The skeleton edition `us/inland@2014` is declared and still recalled, not
|
|
74
|
+
verified against the Federal Register (REQ-LANG-10). The corpus fetch
|
|
75
|
+
verifies it or corrects it.
|
|
76
|
+
- GATE-1 is untouched: a path that differs across jurisdictions at one time
|
|
77
|
+
is REQ-MODEL-1 working as designed, and this ADR gives it a home.
|
|
78
|
+
- **Cost to reverse.** Delete `deltas` from data and schema, the resolver and
|
|
79
|
+
three tests, `rule:23d` and its tombstone, two fixtures; unmap two images.
|
|
80
|
+
No consumer reads `deltas` yet. Pre-1.0, a revert.
|
package/docs/budgets.json
CHANGED
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"docs/adr/0019-relation-reach-and-import-reads.md": 110,
|
|
28
28
|
"docs/timeline.md": 130,
|
|
29
29
|
"docs/maritime-sources.md": 130,
|
|
30
|
-
"docs/decisions.md": 40
|
|
30
|
+
"docs/decisions.md": 40,
|
|
31
|
+
"docs/adr/0020-skeleton-is-a-delta.md": 110
|
|
31
32
|
},
|
|
32
33
|
"json_prose": {
|
|
33
34
|
"targets": [
|
package/docs/decisions.md
CHANGED
|
@@ -6,3 +6,5 @@ each: date, short name, the answer, a link to the argument.
|
|
|
6
6
|
- 2026-09-16 — docs ownership: colregs-engine's docs are sited wrong; colregs owns docs going forward, no new doc lands in colregs-engine. `normative-language.md` was already migrated the same day (commit fe0f8c2, #125); migration of the remaining three (`formal-methods-glossary.md`, `formal-methods-reading-list.md`, `engine-notes.md`) is not yet scheduled. Argued on kanban; no public writeup to link.
|
|
7
7
|
- 2026-09-16 — own vs self: rename the subject segment `own` to `self` across the situation record (fact keys, precedence effect keys, facts.json, fixtures, docs/identifiers.md). Work spawned as [colregs#138](https://github.com/mark-brannan/colregs/issues/138).
|
|
8
8
|
- 2026-09-16 — Q-54, Rule 17's phases are monotone: once 17(a)(ii) permission or the 17(b) duty has arisen for the stand-on vessel, it does not fall back on belated give-way compliance. Argued in [colregs#72](https://github.com/mark-brannan/colregs/issues/72); recorded in `docs/requirements.md`.
|
|
9
|
+
- 2026-09-16 — Q-53, 17(a)(ii) is an exception, not a suspension: the stand-on vessel's duty stands and a departure is lawful only as action to avoid collision; a monitor flags any other alteration. Argued in [colregs#72](https://github.com/mark-brannan/colregs/issues/72); recorded in `docs/requirements.md`.
|
|
10
|
+
- 2026-09-17 — second jurisdiction: `us/inland`, Part C, before v1. Ruled on [colregs#137](https://github.com/mark-brannan/colregs/issues/137); skeleton delta lands under ADR 0020, text and entries follow.
|
package/docs/gates.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"first-non-english-corpus": "the second corpus of any one jurisdiction, which in practice is the first non-English text",
|
|
12
12
|
"first-community-translation-of-national-corpus": "the first `community`-tier translation of a `national`-tier corpus",
|
|
13
13
|
"first-external-contribution": "the first merged contribution from someone other than the copyright holder",
|
|
14
|
+
"first-undated-national-edition": "the first national text whose edition cannot be determined",
|
|
14
15
|
"none": "the decline does not get cheaper or dearer with time; recorded so it is not re-read as merely deferred"
|
|
15
16
|
},
|
|
16
17
|
"statuses": {
|
|
@@ -79,6 +80,46 @@
|
|
|
79
80
|
"status": "open",
|
|
80
81
|
"settled_by": null,
|
|
81
82
|
"note": "ADR 0004 settles the code licence (MIT \u2192 Apache-2.0) and leaves the data licence open. Already-published npm versions stay under the licence they shipped with; the gate governs future releases only, and is held open deliberately by REQ-PROV-7's CONTRIBUTING.md terms (DCO-style certification plus a relicensing grant); a CLA-assistant bot is the upgrade path if contributors arrive."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "GATE-7",
|
|
86
|
+
"title": "validity intervals on editions (`in_force_until`)",
|
|
87
|
+
"declined_in": "docs/adr/0013-corpus-files-with-editions.md",
|
|
88
|
+
"closing_event": "first-undated-national-edition",
|
|
89
|
+
"trigger": "an edition superseded with no successor edition registered to bound it \u2014 repeal without replacement, or two editions of one jurisdiction whose validity ranges cannot be ordered from `superseded_by` alone",
|
|
90
|
+
"status": "open",
|
|
91
|
+
"settled_by": null,
|
|
92
|
+
"note": "Declined alongside ADR 0013 (option B, GATE-2 adopted): `superseded_by` plus `in_force` infers validity for every edition on file today. An explicit `in_force_until` is additive, not a rewrite, so paying for it before a case needs it buys nothing."
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "GATE-8",
|
|
96
|
+
"title": "a per-source publication record separate from the edition (FRBR manifestation)",
|
|
97
|
+
"declined_in": "docs/adr/0013-corpus-files-with-editions.md",
|
|
98
|
+
"closing_event": "first-undated-national-edition",
|
|
99
|
+
"trigger": "two distinct published sources for the same edition that disagree \u2014 e.g. an official gazette printing and a codifier's republication of the same edition differing in errata \u2014 so \"the source\" stops being a property of the edition",
|
|
100
|
+
"status": "open",
|
|
101
|
+
"settled_by": null,
|
|
102
|
+
"note": "Declined alongside ADR 0013: today `source` lives on the corpus and one edition has one source per jurisdiction. A manifestation layer is additive when a second publication record is actually needed."
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "GATE-9",
|
|
106
|
+
"title": "a content digest per corpus for verification",
|
|
107
|
+
"declined_in": "docs/adr/0013-corpus-files-with-editions.md",
|
|
108
|
+
"closing_event": "first-undated-national-edition",
|
|
109
|
+
"trigger": "a corpus found to differ from its cited source with no accompanying edition or source change \u2014 silent drift a hash would have caught and prose review did not",
|
|
110
|
+
"status": "open",
|
|
111
|
+
"settled_by": null,
|
|
112
|
+
"note": "Declined alongside ADR 0013: `edition_status` (verified/claimed/unknown, this ADR's before-merge item 1) already flags an unchecked corpus. A digest adds tamper/drift detection on top, which nothing on file today has needed."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "GATE-10",
|
|
116
|
+
"title": "a skeleton per edition",
|
|
117
|
+
"declined_in": "docs/adr/0013-corpus-files-with-editions.md",
|
|
118
|
+
"closing_event": "first-undated-national-edition",
|
|
119
|
+
"trigger": "the first amendment that deletes or renumbers a path",
|
|
120
|
+
"status": "open",
|
|
121
|
+
"settled_by": null,
|
|
122
|
+
"note": "Declined alongside ADR 0013: one shared `data/rules.json` skeleton is low risk because no amendment has ever renumbered a rule (seven IMO amendments since 1972, none doing so). A per-edition skeleton is the fallback the day one does."
|
|
82
123
|
}
|
|
83
124
|
]
|
|
84
125
|
}
|
package/docs/maritime-sources.md
CHANGED
|
@@ -26,6 +26,12 @@ question the rule text leaves open.
|
|
|
26
26
|
- **Nautical Institute — *Action by the Stand-On Vessel*** (Seaways case study). The stand-on vessel's stages as taught; does not reach whether they are reversible.
|
|
27
27
|
<https://www.nautinst.org/resources-page/200115-action-by-the-stand-on-vessel.html>
|
|
28
28
|
- **USCG Navigation Rules (Amalgamated)**. <https://www.navcen.uscg.gov/navigation-rules-amalgamated>
|
|
29
|
+
- **Steamship Mutual — *Navigation in Restricted Visibility***. Confirms Section II reapplies once vessels are in sight of one another again; silent on whether status accumulated before the loss of sight (a `Q-51`/`Q-52` classification, a `Q-54` Rule 17 stage) carries forward.
|
|
30
|
+
<https://www.steamshipmutual.com/publications/articles/restrictedvisibility0109>
|
|
31
|
+
- **Britannia P&I — *Navigation in restricted visibility***. No stand-on vessel exists under Rule 19; also silent on status continuity across the transition.
|
|
32
|
+
<https://britanniapandi.com/en_gb/guidance/navigation-in-restricted-visibility/>
|
|
33
|
+
- **Professional Mariner — *Overtaking or crossing? Don't assume what other ship will do***. The Rule 13(d) bearing-shift overtaking history, discussed only within continuous visual contact.
|
|
34
|
+
<https://professionalmariner.com/overtaking-or-crossing-dont-assume-what-other-ship-will-do/>
|
|
29
35
|
|
|
30
36
|
## Marine incident analysis
|
|
31
37
|
|
|
@@ -47,6 +53,16 @@ ambiguous give-way/stand-on roles are what the Rules are written against.
|
|
|
47
53
|
<https://www.bahamasmaritime.com/wp-content/uploads/2026/02/2026-5-Polesie-Verity-ReportAndAnnexes.pdf>
|
|
48
54
|
- IMO GISIS Marine Casualties and Incidents module. Not a paper but a source class: the mandatory-reporting database of marine safety investigation reports. Ground truth for real COLREGS-relevant incidents.
|
|
49
55
|
<https://www.imo.org/en/OurWork/IIIS/Pages/Marine-Safety-Investigation-reports.aspx>
|
|
56
|
+
- NTSB/MAR-16/01 — *Conti Peridot*/*Carla Maersk* collision, Houston Ship Channel. Occurred entirely within restricted visibility; no in-sight phase, no Rule 13/17 discussion. Checked for `Q-55` and found not on point.
|
|
57
|
+
<https://www.ntsb.gov/investigations/AccidentReports/Reports/MAR1601.pdf>
|
|
58
|
+
- Dutch Safety Board — *Collision in Restricted Visibility* (*VB Seal*/*Gulholmen*, Maasmond, 2026). Rules appendix cites only Rules 6 and 19; the encounter never had an in-sight phase. Checked for `Q-55` and found not on point.
|
|
59
|
+
<https://onderzoeksraad.nl/wp-content/uploads/2026/07/collision-in-restricted-visibility.pdf>
|
|
60
|
+
- TSB Canada M23C0143 — ferry *Svanoy*. Fog/lookout casualty; no Section II status question arises.
|
|
61
|
+
<https://www.tsb.gc.ca/eng/rapports-reports/marine/2023/m23c0143/m23c0143.html>
|
|
62
|
+
- SWZ Maritime on Nautical Institute MARS 202601 (near-miss in fog). Operational-failure summary only; no rule-regime discussion.
|
|
63
|
+
<https://swzmaritime.nl/news/2026/02/13/near-vessel-collision-in-fog/> · MARS index: <https://www.nautinst.org/technical-resources/mars.html>
|
|
64
|
+
- Marine Insight — fog/TSS-turn collision write-up. Overtaking occurred entirely within fog; no visibility transition at issue.
|
|
65
|
+
<https://www.marineinsight.com/real-life-incident-vessels-collide-in-dense-fog-during-sudden-tss-turn/>
|
|
50
66
|
|
|
51
67
|
## Known gaps
|
|
52
68
|
|
|
@@ -55,4 +71,5 @@ ambiguous give-way/stand-on roles are what the Rules are written against.
|
|
|
55
71
|
manoeuvrability, shoal water, a lee shore, set, visibility or sea state.
|
|
56
72
|
- Two standard texts — Cockcroft & Lameijer, *A Guide to the Collision Avoidance Rules*, and Farwell's *Rules of the Nautical Road* — are not online. Either may settle how the stages of a close-quarters encounter are divided, and whether they are treated as irreversible.
|
|
57
73
|
- Several of the questions in `docs/requirements.md` §11 appear unlitigated: overtaking geometry with no risk of collision, an overtaking situation becoming a head-on, resumption of course by a stand-on vessel that has acted, and the fate of accumulated Section II state across a visibility transition.
|
|
74
|
+
- `Q-55` (visibility transition): checked casualty reports, P&I guidance and trade-press commentary beyond the sources above — no authority found in either direction on whether a `Q-51`/`Q-52` classification or a `Q-54` Rule 17 stage survives a restricted-visibility interruption or resets on regaining sight. Deferred indefinitely, 2026-09-16; Cockcroft & Lameijer and Farwell (both already listed above as unreachable) remain the most plausible sources to settle it.
|
|
58
75
|
- BAILII refuses automated access. Use the National Archives Find Case Law service: <https://caselaw.nationalarchives.gov.uk/>
|
|
@@ -396,7 +396,9 @@ without further action by the give-way vessel.
|
|
|
396
396
|
- **Formally.** Reachability over the stand-on vessel's manoeuvring envelope:
|
|
397
397
|
`Safe(s, σ_own, σ_other)` of ADR 0005 §5 with the give-way strategy set
|
|
398
398
|
unconstrained — the first Part B invariant needing `kin:dynamics`.
|
|
399
|
-
- **Reading
|
|
399
|
+
- **Reading ruled.** Exception, not suspension (`Q-53`, 2026-09-16): the
|
|
400
|
+
17(a)(i) duty stands and the only lawful departure is action to avoid
|
|
401
|
+
collision; a checker flags any other alteration.
|
|
400
402
|
|
|
401
403
|
### INV-17b — phase 3: the stand-on vessel shall act
|
|
402
404
|
|
package/docs/requirements.md
CHANGED
|
@@ -639,8 +639,7 @@ specification until 1.0.
|
|
|
639
639
|
|
|
640
640
|
### Open gates
|
|
641
641
|
|
|
642
|
-
Each
|
|
643
|
-
|
|
642
|
+
Each names the declined design, closing event, and trigger.
|
|
644
643
|
- **GATE-1 — `paragraph_id` split from `citation_path`**
|
|
645
644
|
(ADR 0003, declined; REQ-LANG-3, REQ-PKG-4).
|
|
646
645
|
*Closing event*: the 1.0 tag. Before it, splitting the two is a
|
|
@@ -764,8 +763,9 @@ Each gate names the declined design, the closing event, and the trigger.
|
|
|
764
763
|
unlikely short of major success. Recorded regardless: "unlikely" is not
|
|
765
764
|
a closing event (REQ-GATE-1).
|
|
766
765
|
|
|
767
|
-
|
|
768
|
-
|
|
766
|
+
Four gates from ADR 0013 (option B), *closing event* for all four the first national text whose edition cannot be determined: **GATE-7 — validity intervals on editions (`in_force_until`)**, trigger an edition superseded with no successor to bound it; **GATE-8 — a per-source publication record separate from the edition (FRBR manifestation)**, trigger two published sources for one edition that disagree; **GATE-9 — a content digest per corpus for verification**, trigger a corpus differing from its cited source with no edition or source change; **GATE-10 — a skeleton per edition**, trigger the first amendment that deletes or renumbers a path.
|
|
767
|
+
|
|
768
|
+
Gates whose closing event is "none" are recorded because a future reader will otherwise re-ask whether they were merely deferred. They were not.
|
|
769
769
|
|
|
770
770
|
### Gate status is data
|
|
771
771
|
|
|
@@ -1416,6 +1416,7 @@ written up in `docs/identifiers.md` §"Effects"; what it could not is here.
|
|
|
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`).
|
|
1419
|
+
- **Q-58** — **Do the Rule 18/12 role entries need `other:hist:was_overtaking: false`, like `rule:13a` and `rule:15a:keep_out_of_the_way` (Q-47)?** The nine `18a*`/`18b*`/`18c*` and three `12a*` entries carry no such gate, and `rule:13a` overrides them only when *self* holds the history; when the *other* holds it, self is named give-way under Rule 18 or 12 while 13(a) puts the duty on the other alone. Default **ungated** (nothing changes), recorded as a `gap` on the twelve. Recommend **gated**, in Q-47's shape: 13(a)'s 'notwithstanding' and Rule 18's own exception for Rule 13 both displace these entries, and Q-47 already ruled the history decides who holds the role. colregs-engine#75 (closed) read the table as self-centric and recommended a consumer swap subjects for the other's duty; that answers the other's role, not self's wrong one. `colregs#117`.
|
|
1419
1420
|
|
|
1420
1421
|
### From the Part B invariants (P4.1)
|
|
1421
1422
|
|
|
@@ -1426,21 +1427,19 @@ nothing is blocked while open.
|
|
|
1426
1427
|
- **Q-50** — **Does risk of collision gate Rules 13 and 18?** 14(a) and 15(a)
|
|
1427
1428
|
say "so as to involve risk of collision"; Rule 13 and Rule 18 do not.
|
|
1428
1429
|
*Wide:* they attach whenever in sight and the geometry holds — Rule 11 is the
|
|
1429
|
-
only gate Section II states
|
|
1430
|
-
give-way and Rule 16 binds her. *Narrow:* Section II's duties attach only with
|
|
1430
|
+
only gate Section II states. *Narrow:* Section II's duties attach only with
|
|
1431
1431
|
risk of collision; 14 and 15 are emphasis. Default **wide**: `rule:13a`, `rule:13b`,
|
|
1432
|
-
`rule:13d` and every Rule 18 entry read `in_sight` only.
|
|
1432
|
+
`rule:13d` and every Rule 18 entry read `in_sight` only. **Ruled
|
|
1433
|
+
2026-09-17:** wide — the window is the encounter itself. A pair the engine is
|
|
1434
|
+
evaluating is an encounter, at whatever range suits the vessels; inside it 13
|
|
1435
|
+
and 18 attach on sight and geometry alone, and how close is clear stays a
|
|
1436
|
+
monitor parameter. *The Nowy Sacz* [1977] 2 Lloyd's Rep 91 (CA) holds risk
|
|
1437
|
+
of collision unnecessary for the overtaking rule; *Meghna Princess* [2017]
|
|
1438
|
+
SGHC 220 [56] restates it; nothing found on Rule 18 either way (colregs#72).
|
|
1433
1439
|
- **Q-51** — **What arms 13(d)'s overtaking history?** *A:* 13(b)'s deeming, at the first
|
|
1434
1440
|
state the geometry holds. *B:* 13(a)'s duty actually attaching. They differ
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
duty attaches. KIVELI [2025] EWHC 1185 (Admlty) holds the analogous Rule 14
|
|
1438
|
-
history arms on risk of collision and then persists; no authority was found on
|
|
1439
|
-
overtaking geometry with no risk of collision. Free to reverse: four entries
|
|
1440
|
-
(`rule:13a`, `rule:13b`, `rule:13d`) and their fixtures, and nothing consumes the one
|
|
1441
|
-
state this changes the answer for. Settled by: a decision on Rule 13 itself,
|
|
1442
|
-
or Cockcroft & Lameijer on whether overtaking status needs risk of
|
|
1443
|
-
collision.
|
|
1441
|
+
only on `Q-50`'s surface. **Ruled 2026-09-17:** B, closed by `Q-50` wide —
|
|
1442
|
+
with no gate between geometry and duty the two readings coincide (colregs#72).
|
|
1444
1443
|
- **Q-52** — **What does 13(d)'s overtaking history forbid?** *Narrow:* reclassification to
|
|
1445
1444
|
*crossing* only, as the paragraph says, leaving head-on to Rule 14 on the
|
|
1446
1445
|
geometry of the moment. *Broad:* the encounter stays an overtaking and no
|
|
@@ -1456,9 +1455,10 @@ nothing is blocked while open.
|
|
|
1456
1455
|
*Suspension:* "may, however" lifts the duty once non-compliance is apparent;
|
|
1457
1456
|
a monitor then flags nothing. *Exception:* the duty stands and a departure is
|
|
1458
1457
|
lawful only as action to avoid collision by her manoeuvre alone; a monitor
|
|
1459
|
-
flags any other alteration. No default (Rule 17 has no entry).
|
|
1460
|
-
|
|
1461
|
-
|
|
1458
|
+
flags any other alteration. No default (Rule 17 has no entry). **Ruled
|
|
1459
|
+
2026-09-16:** exception — the 17(a)(i) duty stands and a departure is lawful
|
|
1460
|
+
only as action to avoid collision; a monitor flags any other alteration.
|
|
1461
|
+
Purpose, not source (colregs#72); read with `Q-54`.
|
|
1462
1462
|
- **Q-54** — **Are Rule 17's phases monotone?** *Monotone:* one three-valued
|
|
1463
1463
|
marker per stand-on vessel per encounter; late compliance does not take the
|
|
1464
1464
|
permission away. *Re-evaluating:* each phase is a predicate on the current
|
|
@@ -1471,8 +1471,9 @@ nothing is blocked while open.
|
|
|
1471
1471
|
becomes of a 13(d) overtaking history or a Rule 17 phase. *Persisting:* they belong to the
|
|
1472
1472
|
encounter and survive the fog. *Resetting:* Section II starts afresh on the
|
|
1473
1473
|
geometry when sight is regained — the reclassification 13(d) forbids, via
|
|
1474
|
-
visibility. No default (nothing is temporal).
|
|
1475
|
-
|
|
1474
|
+
visibility. No default (nothing is temporal). **Deferred indefinitely** (Solace,
|
|
1475
|
+
2026-09-16): no authority either way (colregs#72); scenario contrived. Lean, not
|
|
1476
|
+
ruling: **resetting** — a new encounter after the fog; persisting withdrawn.
|
|
1476
1477
|
- **Q-56** — **The third visibility state: a hole, or closed by the model?**
|
|
1477
1478
|
Not in sight *and* not in or near restricted visibility (clear weather, beyond
|
|
1478
1479
|
visual range, radar contact) is outside Rule 11 and 19(a): Section I only.
|
|
@@ -1494,7 +1495,5 @@ module, expensive after.
|
|
|
1494
1495
|
|
|
1495
1496
|
A third, ruled rather than pencil: **`docs/part-b-invariants.md` stays
|
|
1496
1497
|
hand-written Markdown; no derived JSON registry.** Ruled 2026-09-08. Revisit
|
|
1497
|
-
only if P4.2's TLA+ needs to cite `INV-` ids mechanically
|
|
1498
|
-
|
|
1499
|
-
revisit costs one file's worth of tooling, not a re-derivation of the ids
|
|
1500
|
-
themselves.
|
|
1498
|
+
only if P4.2's TLA+ needs to cite `INV-` ids mechanically; the cost then is one
|
|
1499
|
+
file's worth of tooling, not a re-derivation of the ids.
|
|
@@ -936,7 +936,7 @@
|
|
|
936
936
|
"expect": []
|
|
937
937
|
},
|
|
938
938
|
{
|
|
939
|
-
"name": "6 m outboard, max speed 6 kn, US Inland: 23(d)(ii) has no Inland counterpart, 23(d)(i)
|
|
939
|
+
"name": "6 m outboard, max speed 6 kn, US Inland: 23(d)(ii) has no Inland counterpart, 23(d)(i) is replaced by 23(d), 23(a) is inherited",
|
|
940
940
|
"jurisdiction": "us/inland",
|
|
941
941
|
"facts": {
|
|
942
942
|
"fact:propulsion": "propulsion:power",
|
|
@@ -949,7 +949,7 @@
|
|
|
949
949
|
"rule:23a_i",
|
|
950
950
|
"rule:23a_ii",
|
|
951
951
|
"rule:23a_iii_iv",
|
|
952
|
-
"rule:
|
|
952
|
+
"rule:23d"
|
|
953
953
|
]
|
|
954
954
|
},
|
|
955
955
|
{
|
|
@@ -965,6 +965,54 @@
|
|
|
965
965
|
"rule:30a",
|
|
966
966
|
"rule:30c"
|
|
967
967
|
]
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"name": "same yacht motoring, US Inland: 23(d)(i) is replaced by Inland 23(d)",
|
|
971
|
+
"jurisdiction": "us/inland",
|
|
972
|
+
"facts": {
|
|
973
|
+
"fact:propulsion": "propulsion:power",
|
|
974
|
+
"fact:activity": "activity:none",
|
|
975
|
+
"fact:position": "position:underway",
|
|
976
|
+
"fact:length_m": 11.6
|
|
977
|
+
},
|
|
978
|
+
"expect": [
|
|
979
|
+
"rule:23a_i",
|
|
980
|
+
"rule:23a_ii",
|
|
981
|
+
"rule:23a_iii_iv",
|
|
982
|
+
"rule:23d"
|
|
983
|
+
]
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
"name": "pushing ahead, not a composite unit, US Inland: 24(c)(iii) replaces the sternlight with two towing lights",
|
|
987
|
+
"jurisdiction": "us/inland",
|
|
988
|
+
"facts": {
|
|
989
|
+
"fact:propulsion": "propulsion:power",
|
|
990
|
+
"fact:activity": "activity:pushing",
|
|
991
|
+
"fact:position": "position:underway",
|
|
992
|
+
"fact:length_m": 30,
|
|
993
|
+
"fact:composite_unit": false
|
|
994
|
+
},
|
|
995
|
+
"expect": [
|
|
996
|
+
"rule:24c:towing_lights",
|
|
997
|
+
"rule:24c:underway_lights"
|
|
998
|
+
]
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
"name": "pushing ahead, not a composite unit, at anchor, US Inland (issue #137 review: sidelights/towing lights are underway-gated, masthead only at anchor)",
|
|
1002
|
+
"jurisdiction": "us/inland",
|
|
1003
|
+
"facts": {
|
|
1004
|
+
"fact:propulsion": "propulsion:power",
|
|
1005
|
+
"fact:activity": "activity:pushing",
|
|
1006
|
+
"fact:position": "position:anchored",
|
|
1007
|
+
"fact:length_m": 30,
|
|
1008
|
+
"fact:composite_unit": false
|
|
1009
|
+
},
|
|
1010
|
+
"expect": [
|
|
1011
|
+
"rule:24c:towing_lights",
|
|
1012
|
+
"rule:30a",
|
|
1013
|
+
"rule:30b",
|
|
1014
|
+
"rule:30c"
|
|
1015
|
+
]
|
|
968
1016
|
}
|
|
969
1017
|
]
|
|
970
1018
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "colregs",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
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
|
"colregs": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"colregs",
|
|
10
10
|
"applied",
|
|
11
11
|
"exempted",
|
|
12
|
-
"excluded",
|
|
13
12
|
"overridden",
|
|
14
13
|
"displays",
|
|
15
14
|
"optional_additions",
|
|
@@ -27,9 +26,6 @@
|
|
|
27
26
|
"exempted": {
|
|
28
27
|
"$ref": "evaluation.schema.json#/$defs/byEntryList"
|
|
29
28
|
},
|
|
30
|
-
"excluded": {
|
|
31
|
-
"$ref": "evaluation.schema.json#/$defs/byEntryList"
|
|
32
|
-
},
|
|
33
29
|
"overridden": {
|
|
34
30
|
"$ref": "evaluation.schema.json#/$defs/byEntryList"
|
|
35
31
|
},
|
package/schema/rules.schema.json
CHANGED
|
@@ -12,6 +12,54 @@
|
|
|
12
12
|
"note": {
|
|
13
13
|
"type": "string"
|
|
14
14
|
},
|
|
15
|
+
"paragraphs": {
|
|
16
|
+
"$ref": "#/$defs/paragraphs"
|
|
17
|
+
},
|
|
18
|
+
"deltas": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"additionalProperties": false,
|
|
21
|
+
"description": "Per-jurisdiction skeleton deltas over `paragraphs` (ADR 0020): own paragraphs by path, suppressed paths, everything else inherited.",
|
|
22
|
+
"patternProperties": {
|
|
23
|
+
"^[a-z]+(/[a-z]+)+$": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"required": [
|
|
27
|
+
"paragraphs",
|
|
28
|
+
"suppressions"
|
|
29
|
+
],
|
|
30
|
+
"properties": {
|
|
31
|
+
"note": {
|
|
32
|
+
"type": "string"
|
|
33
|
+
},
|
|
34
|
+
"paragraphs": {
|
|
35
|
+
"$ref": "#/$defs/paragraphs"
|
|
36
|
+
},
|
|
37
|
+
"suppressions": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"required": [
|
|
43
|
+
"path",
|
|
44
|
+
"why"
|
|
45
|
+
],
|
|
46
|
+
"properties": {
|
|
47
|
+
"path": {
|
|
48
|
+
"$ref": "evaluation.schema.json#/$defs/paragraphCite"
|
|
49
|
+
},
|
|
50
|
+
"why": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"minLength": 1
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"$defs": {
|
|
15
63
|
"paragraphs": {
|
|
16
64
|
"type": "object",
|
|
17
65
|
"additionalProperties": false,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "intl@2016.fi.finlex",
|
|
3
|
-
"edition": "intl@2016",
|
|
4
|
-
"edition_status": "claimed",
|
|
5
|
-
"language": "fi",
|
|
6
|
-
"source_id": "finlex",
|
|
7
|
-
"tier": "national",
|
|
8
|
-
"normalization": "NFC",
|
|
9
|
-
"source": {
|
|
10
|
-
"publisher": "Finlex (Oikeusministeriö), Suomen säädöskokoelman sopimussarja",
|
|
11
|
-
"title": "Asetus kansainvälisistä säännöistä yhteentörmäämisen ehkäisemiseksi merellä vuonna 1972 tehdyn yleissopimuksen voimaansaattamisesta, SopS 30/1977",
|
|
12
|
-
"url": "https://www.finlex.fi/fi/sopimukset/sopsteksti/1977/19770030",
|
|
13
|
-
"retrieved": "2026-09-12"
|
|
14
|
-
},
|
|
15
|
-
"rights": {
|
|
16
|
-
"source_text": "Tekijänoikeuslaki 404/1961 §9: no copyright in treaties and their official translations",
|
|
17
|
-
"redistribution_basis": "Finlex FAQ: published materials carry no usage restriction; open data CC BY 4.0",
|
|
18
|
-
"package_licence": "Apache-2.0"
|
|
19
|
-
},
|
|
20
|
-
"note": "Stub: identity and provenance only; the Finnish text is not transcribed yet. GATE-2 is adopted in docs/gates.json, settled by ADR 0013, so nothing structural blocks it.",
|
|
21
|
-
"paragraphs": {}
|
|
22
|
-
}
|