colregs 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +194 -26
- package/PROVENANCE.md +46 -13
- package/README.md +324 -20
- package/data/applicability.json +1247 -236
- package/data/deprecated-identifiers.json +7 -0
- package/data/facts.json +549 -112
- package/data/geometry.json +34 -34
- package/data/images.json +52 -26
- package/data/lights.json +36 -36
- package/data/rules.json +887 -104
- package/docs/adr/0001-name-and-jurisdiction-model.md +194 -0
- package/docs/adr/0002-wig-gate-and-jurisdiction-field.md +77 -0
- package/docs/adr/0003-language-as-a-dimension.md +220 -0
- package/docs/adr/0004-licence-layering.md +78 -0
- package/docs/adr/0005-rule-categories-and-the-situation-record.md +323 -0
- package/docs/adr/0006-json-schema-and-identifier-diff.md +95 -0
- package/docs/conventions.md +27 -0
- package/docs/gates.json +84 -0
- package/docs/identifiers.md +435 -0
- package/docs/requirements.md +1320 -0
- package/docs/verification/2026-08-30-q6-q8.md +278 -0
- package/docs/verification/2026-09-05-rule27f-rule28-anchor-scenarios.md +330 -0
- package/fixtures/applicability-fixtures.json +498 -138
- package/fixtures/situation-fixtures.json +3603 -0
- package/package.json +27 -5
- package/schema/applicability-fixtures.schema.json +47 -0
- package/schema/applicability.schema.json +401 -0
- package/schema/deprecated-identifiers.schema.json +29 -0
- package/schema/facts.schema.json +793 -0
- package/schema/geometry.schema.json +239 -0
- package/schema/images.schema.json +53 -0
- package/schema/lights.schema.json +131 -0
- package/schema/rules.schema.json +50 -0
- package/schema/situation-fixtures.schema.json +325 -0
package/README.md
CHANGED
|
@@ -1,24 +1,69 @@
|
|
|
1
1
|
# colregs
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The COLREGS 72 navigation *light* rules as language-neutral JSON, plus the
|
|
4
|
+
USCG's own diagrams and enough geometry to draw the lights yourself. Built as
|
|
5
|
+
the base other countries' national amalgamations hang off of, not scoped to
|
|
6
|
+
one country's rulebook.
|
|
6
7
|
|
|
7
8
|
Data only. No runtime, no dependencies, no inference.
|
|
8
9
|
|
|
9
|
-
> **Status: pre-release.**
|
|
10
|
-
>
|
|
11
|
-
|
|
10
|
+
> **Status: pre-release.** Not complete, and not fit for navigation. Navigate
|
|
11
|
+
> by the published rules.
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
data/rules.json verbatim rule text, keyed by paragraph path and jurisdiction
|
|
15
|
+
data/lights.json the six Rule 21 lights: colour, arc, Rule 22 range
|
|
16
|
+
data/facts.json the fact record, and how to decode SignalK navigation.state
|
|
17
|
+
data/applicability.json predicate -> lights, each entry also carrying modality, citation, jurisdiction
|
|
18
|
+
data/geometry.json Annex I: heights, spacings, colour, intensity
|
|
19
|
+
data/images.json every image, its source, and what it illustrates
|
|
20
|
+
data/deprecated-identifiers.json retired identifiers: what they denoted, when, and their replacement
|
|
21
|
+
images/ 38 USCG diagrams + 5 arc GIFs
|
|
22
|
+
fixtures/ fact records and the entries that apply to them
|
|
23
|
+
```
|
|
12
24
|
|
|
13
25
|
## Coverage
|
|
14
26
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
Part C lights (Rules 20-31) only, `intl` jurisdiction only, night only. Day
|
|
28
|
+
shapes, Part D signals, and every other jurisdiction (US Inland, Canada,
|
|
29
|
+
CEVNI) are on the roadmap in [`docs/requirements.md`](docs/requirements.md)
|
|
30
|
+
but not present here.
|
|
31
|
+
|
|
32
|
+
## The four layers
|
|
33
|
+
|
|
34
|
+
**Rule text.** Keyed by *paragraph path*, like `27(a)(i)` or `25(d)(ii)`,
|
|
35
|
+
because the paragraph is the unit you actually cite. The text is verbatim
|
|
36
|
+
International text; Inland-only inserts were stripped rather than paraphrased.
|
|
37
|
+
|
|
38
|
+
**Light definitions.** This layer is Rule 21. Each light carries its colour,
|
|
39
|
+
its arc as a bearing range, and its minimum visible range by length band from
|
|
40
|
+
Rule 22. Bearings run in degrees clockwise from right ahead, and an arc whose
|
|
41
|
+
`from_deg` exceeds its `to_deg` wraps through the bow. So the masthead light
|
|
42
|
+
is 247.5° to 112.5°, which is 225° of arc.
|
|
43
|
+
|
|
44
|
+
**Facts.** Three orthogonal axes (`fact:propulsion`, `fact:activity`,
|
|
45
|
+
`fact:position`), a `fact:making_way` modifier that refines
|
|
46
|
+
`position:underway`, and scalars such as `fact:length_m` and
|
|
47
|
+
`fact:tow_length_m`. There is deliberately no vessel-class field. Under COLREGS
|
|
48
|
+
what a vessel *is* follows from what it is *doing*, so classification falls
|
|
49
|
+
out of the axes on its own.
|
|
20
50
|
|
|
21
|
-
|
|
51
|
+
SignalK's `navigation.state` flattens all of that into one enum. `facts.json`
|
|
52
|
+
therefore carries a decode table, the enum values it can't decode, and the
|
|
53
|
+
five places where the flattening loses information. Fishing at anchor and
|
|
54
|
+
making-way are the two of those that matter in practice.
|
|
55
|
+
|
|
56
|
+
**Applicability entries.** Each entry is a predicate over facts, a set of
|
|
57
|
+
lights or references to other entries, a modality, a citation, and a
|
|
58
|
+
jurisdiction. Every entry has an id (`25b`, `27a-mw`) that both consumers can
|
|
59
|
+
point at.
|
|
60
|
+
|
|
61
|
+
**Identifiers.** Two classes, with opposite requirements. Citation-derived ids
|
|
62
|
+
— paragraph paths and the entry ids built from them — carry no prefix, because
|
|
63
|
+
the path *is* the citation. Vocabulary ids do: `light:masthead`,
|
|
64
|
+
`fact:activity`, `activity:nuc`, `rel:in_lieu_of`. See
|
|
65
|
+
[`docs/identifiers.md`](docs/identifiers.md); coming from a 0.1.x release, see
|
|
66
|
+
[Migrating from 0.1.x](#migrating-from-01x).
|
|
22
67
|
|
|
23
68
|
## Design
|
|
24
69
|
|
|
@@ -26,25 +71,284 @@ This repo is requirements-first. Coding sessions work against numbered
|
|
|
26
71
|
requirements and cite them; decisions that shaped the design are recorded as
|
|
27
72
|
ADRs rather than argued again.
|
|
28
73
|
|
|
29
|
-
- [`docs/requirements.md`](docs/requirements.md)
|
|
30
|
-
- [`docs/adr/`](docs/adr/)
|
|
74
|
+
- [`docs/requirements.md`](docs/requirements.md): the source of truth
|
|
75
|
+
- [`docs/adr/`](docs/adr/): decisions, with the reasoning that produced them
|
|
31
76
|
|
|
32
77
|
Three ideas carry most of the design:
|
|
33
78
|
|
|
34
79
|
**The paragraph is the unit.** Rule text, citations and composition all key on
|
|
35
|
-
the paragraph path
|
|
80
|
+
the paragraph path (`27(a)(i)`, not "Rule 27"). Citation unit and composition
|
|
36
81
|
unit turn out to be the same thing.
|
|
37
82
|
|
|
38
|
-
**
|
|
83
|
+
**Jurisdiction is a dimension, not a fork.** Every rule-text record and every
|
|
84
|
+
applicability entry carries a `jurisdiction`: `intl` (the reserved base value)
|
|
85
|
+
or `<country-or-body>/<waters>` (`us/inland`, `eu/cevni`). A jurisdiction is a
|
|
86
|
+
delta on `intl`; entries it doesn't override are inherited, not restated
|
|
87
|
+
(REQ-SCOPE-2/3). Geography that merely gates a rule inside one jurisdiction
|
|
88
|
+
(Great Lakes, Western Rivers) is an ordinary fact a predicate reads, not a
|
|
89
|
+
jurisdiction of its own (REQ-SCOPE-5).
|
|
90
|
+
|
|
91
|
+
**Predicates, not enumerations.** Gates are `fact:length_m < 7`, never a pre-built
|
|
39
92
|
list of configurations. Enumerated tables are where prior art silently loses
|
|
40
93
|
rules; a predicate cannot omit a case it was never asked about.
|
|
41
94
|
|
|
42
|
-
**Alternatives are first-class.** COLREGS routinely permits a choice
|
|
95
|
+
**Alternatives are first-class.** COLREGS routinely permits a choice: a
|
|
43
96
|
tricolor *in lieu of* separate sidelights, a torch *in lieu of* either. The data
|
|
44
97
|
carries every lawful option with its modality and gate, and picks none of them.
|
|
45
98
|
Selection belongs to the consumer.
|
|
46
99
|
|
|
47
|
-
##
|
|
100
|
+
## Predicate semantics
|
|
101
|
+
|
|
102
|
+
An entry applies when **every** constraint in its `when` is satisfied. An
|
|
103
|
+
absent fact never satisfies a constraint. Numeric constraints are
|
|
104
|
+
`{gte, gt, lte, lt}`; a list means membership; anything else is equality.
|
|
105
|
+
`fact:activity: "activity:ram"` also matches `activity:ram_underwater`, which
|
|
106
|
+
is a refinement of it.
|
|
107
|
+
|
|
108
|
+
A `when` is a conjunction, and two constructs open it up. `{"not": C}` is a
|
|
109
|
+
constraint satisfied when the fact does *not* satisfy `C`; `any_of` is
|
|
110
|
+
disjunction, holding sub-predicates as a key of a `when` and constraints as the
|
|
111
|
+
value of a fact. **`not` over an absent fact is unsatisfied**, like every other
|
|
112
|
+
constraint over an absent fact — so `{"not": C}` and `C` are both false on a
|
|
113
|
+
record that never mentions the fact, and the two are not complements there. That
|
|
114
|
+
is deliberate: predicates stay conservative, and a duty is never laid on a vessel
|
|
115
|
+
because a consumer left a field out. It also means `not` is a constraint on one
|
|
116
|
+
fact and never a key of a `when` — a predicate-level negation would be satisfied
|
|
117
|
+
by silence, which is the one thing the absent-fact rule is there to forbid. Where
|
|
118
|
+
a paragraph really does mean "any vessel other than …", the negation goes on the
|
|
119
|
+
fact the paragraph names, and the fact has to be present for the entry to apply.
|
|
120
|
+
|
|
121
|
+
| form | where | means |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| `{"gte": n}` … `{"lt": n}` | a fact's constraint | numeric comparison |
|
|
124
|
+
| `["a", "b"]` | a fact's constraint | membership |
|
|
125
|
+
| `"a"` / `true` / `12` | a fact's constraint | equality |
|
|
126
|
+
| `{"not": C}` | a fact's constraint | the fact is present and does not satisfy `C` |
|
|
127
|
+
| `{"any_of": [C, …]}` | a fact's constraint | the fact satisfies at least one `C` |
|
|
128
|
+
| `"any_of": [W, …]` | a key of a `when` | at least one sub-predicate `W` holds |
|
|
129
|
+
|
|
130
|
+
The `ram`/`ram_underwater` refinement belongs to the *value*, not to one
|
|
131
|
+
constraint form: it applies to equality, to list membership and to each
|
|
132
|
+
`any_of` disjunct alike, and `{"not": C}` negates the refined reading rather
|
|
133
|
+
than sneaking underneath it. It used to fire on a scalar constraint only, so a
|
|
134
|
+
list quietly missed it; that is fixed, and a list and `{"any_of": […]}` are now
|
|
135
|
+
interchangeable wherever both are legal.
|
|
136
|
+
|
|
137
|
+
Some facts are **derived** rather than supplied. `facts.json`'s `derived`
|
|
138
|
+
section holds them, each with a decode table that is its definition — an ordered
|
|
139
|
+
list of predicate/value rows, first match wins — read the same way as the
|
|
140
|
+
SignalK `navigation.state` table. `fact:rule18_class` is the one that exists: a
|
|
141
|
+
vessel's rank under Rule 18, decoded from her propulsion, her activity and the
|
|
142
|
+
27(c) and WIG booleans, because Rule 18 ranks vessels by the Rule 3 terms of art
|
|
143
|
+
and `fact:activity` answers a different question — what she *shows*. A consumer
|
|
144
|
+
never supplies a derived fact.
|
|
145
|
+
|
|
146
|
+
Entries **compose**: several apply to one fact record, and Rule 28 or Rule 26
|
|
147
|
+
add to Rule 23 rather than replacing it. Relations between them:
|
|
148
|
+
|
|
149
|
+
| relation | meaning |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `rel:includes` | import the referenced entry's **lights only**, never its predicate |
|
|
152
|
+
| `rel:conditional_includes` | import lights when the stated `when` holds; `one_of` is a set of legal alternatives |
|
|
153
|
+
| `rel:in_lieu_of` | this entry's lights replace the referenced entries' lights |
|
|
154
|
+
| `rel:excludes` | must not be shown together (25(c) and the tricolor) |
|
|
155
|
+
| `rel:exempts` | the referenced requirement does not apply (30(e)) |
|
|
156
|
+
| `rel:overrides` | the superiority relation: this paragraph's requirement prevails over the referenced one's when both apply (Rule 18's "except where Rules 9, 10 and 13 otherwise require") |
|
|
157
|
+
|
|
158
|
+
A condition on whether a paragraph applies to the vessel at all goes in the
|
|
159
|
+
predicate; a condition on which of two applicable paragraphs prevails is a
|
|
160
|
+
relation. Delete the other paragraph: if this one is still true of the vessel,
|
|
161
|
+
it is a relation. Rule 28 at anchor is a predicate; Rule 18 displacing Rule 15's
|
|
162
|
+
role is `rel:overrides` (REQ-MODEL-13, ADR 0005 §4).
|
|
163
|
+
|
|
164
|
+
Where the rules permit a choice, the data keeps every lawful option instead of
|
|
165
|
+
picking one. A 12 m sloop under sail has three legal displays: 25(a), the
|
|
166
|
+
25(b) tricolor, or 25(a) plus the 25(c) red-over-green. Which one a given boat
|
|
167
|
+
shows depends on what's installed, and that decision belongs to the consumer.
|
|
168
|
+
|
|
169
|
+
Modality is `shall`, `may`, `shall-if-practicable`, `shall-not`,
|
|
170
|
+
`shall-not-impede`, or `conditional` with a `modality_by` table when it turns
|
|
171
|
+
on a fact (23(a)(ii) is `shall` at 50 m and above, `may` below).
|
|
172
|
+
|
|
173
|
+
Most entries read one vessel and produce lights. A few read **two** — a
|
|
174
|
+
situation, not a fact record — and produce an `effect` instead. Rules 4, 11
|
|
175
|
+
and 19(a) say which section of Part B governs; Rules 18, 9, 10, 12 and 15 say
|
|
176
|
+
which vessel gives way — Rule 18 reading `fact:rule18_class` rather than
|
|
177
|
+
re-listing the activity axis, Rules 12 and 15 reading the propulsion their own
|
|
178
|
+
words name and leaving the rank to Rule 18's `rel:overrides`; and Rules 7(d),
|
|
179
|
+
13, 14 and 15 say what kind of encounter it is —
|
|
180
|
+
`head-on`, `crossing` or `overtaking` — or that risk of collision exists.
|
|
181
|
+
Those carry `category` and `subjects: 2`, and address each vessel
|
|
182
|
+
through a subject segment: `own:fact:activity`, `other:fact:propulsion`,
|
|
183
|
+
`pair:geo:in_sight`. A key with no subject means `own:`, so nothing above
|
|
184
|
+
changes. `docs/identifiers.md` has the namespace and the effect vocabulary;
|
|
185
|
+
`fixtures/situation-fixtures.json` is their contract.
|
|
186
|
+
|
|
187
|
+
The three encounter types **partition** relative bearing. 13(b)'s overtaking
|
|
188
|
+
sector is written once, as one constraint; Rule 15's crossing is `not` over
|
|
189
|
+
that same constraint and `not` over Rule 14's head-on cone, so no crossing
|
|
190
|
+
sector is enumerated anywhere and none can drift out of step. The suite sweeps
|
|
191
|
+
both vessels' bearings in half-degree steps and asserts that exactly one
|
|
192
|
+
encounter applies at every point, that 13(b)'s 22.5°-abaft-the-beam edge is
|
|
193
|
+
exclusive on both sides, and that Rule 13(d)'s latch holds the classification
|
|
194
|
+
at `overtaking` however far the bearing afterwards draws out. The numbers the
|
|
195
|
+
Rules do not state — what counts as an appreciable bearing change, how wide
|
|
196
|
+
"nearly reciprocal" is — are declared once in `facts.json` under
|
|
197
|
+
`situation.constants`, marked pencil, and read from there by every entry.
|
|
198
|
+
|
|
199
|
+
A situation can state geometry no two vessels can occupy, so the suite checks
|
|
200
|
+
every fixture that states its kinematics against them (REQ-VERIFY-8): the two
|
|
201
|
+
relative bearings must be two readings of one line of sight, positions must
|
|
202
|
+
reproduce range and bearing, and CPA, TCPA and bearing rate must be the ones
|
|
203
|
+
the headings and speeds give. The equations and tolerances are declared once in
|
|
204
|
+
`facts.json` under `situation.geometry.consistency`. The sweeps construct
|
|
205
|
+
situations that pass the same check, and the property that no two vessels are
|
|
206
|
+
both give-way is asserted over a sweep of steady-bearing geometries — where it
|
|
207
|
+
is a theorem — with the both-starboard geometry that breaks it pinned as one
|
|
208
|
+
the check rejects.
|
|
209
|
+
|
|
210
|
+
## What this package does not do
|
|
211
|
+
|
|
212
|
+
It does not infer anything. It is a pure function of the fact record. Deciding
|
|
213
|
+
*that* a vessel is making way, or fishing, or aground is somebody else's job.
|
|
214
|
+
Nothing here reads a sensor.
|
|
215
|
+
|
|
216
|
+
It does not select a single display. Where the rules offer alternatives, all of
|
|
217
|
+
them come back.
|
|
218
|
+
|
|
219
|
+
## Verifying
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm test
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Every fixture reproduces exactly; every citation, cross-reference, light and
|
|
226
|
+
geometry reference resolves; every image is on disk with its SHA-256 recorded;
|
|
227
|
+
every decoded `navigation.state` value and every fact a predicate reads is
|
|
228
|
+
declared.
|
|
229
|
+
|
|
230
|
+
A **drift test** (REQ-VERIFY-2) cross-checks two directions: forward, fact
|
|
231
|
+
record to lights, and reverse, lights already shown to which other entries
|
|
232
|
+
could explain them. It fails on any collision the data doesn't already
|
|
233
|
+
declare through `rel:includes`/`rel:in_lieu_of`/`rel:excludes`/
|
|
234
|
+
`rel:exempts`/`rel:conditional_includes`.
|
|
235
|
+
|
|
236
|
+
Every numeric gate that affects *which entries apply* has fixtures immediately
|
|
237
|
+
either side of its threshold (REQ-VERIFY-5), and every entry is exercised by
|
|
238
|
+
at least one fixture and absent from at least one other (REQ-VERIFY-3). Three
|
|
239
|
+
gates that affect only *modality*, not which entries apply, are flagged as an
|
|
240
|
+
open question rather than fixtured against a schema that can't express the
|
|
241
|
+
distinction; see [Q-5](docs/requirements.md#9-open-questions).
|
|
242
|
+
|
|
243
|
+
`fixtures/applicability-fixtures.json` is the cross-implementation contract: an
|
|
244
|
+
implementation in any language should reproduce those entry sets exactly.
|
|
245
|
+
|
|
246
|
+
## Migrating from 0.1.x
|
|
247
|
+
|
|
248
|
+
0.2.0 is the first release whose vocabulary identifiers carry a type prefix.
|
|
249
|
+
`colregs@0.1.1`, the last version on npm, has the bare names; every 0.1.x
|
|
250
|
+
consumer holds strings that no longer resolve. Renaming an identifier is a
|
|
251
|
+
breaking change under REQ-PKG-4, and the rename is the one exception
|
|
252
|
+
REQ-MODEL-10 records: 0.1.1 predates the identifier audit, sits outside the
|
|
253
|
+
immutability baseline, and nothing after it may be renamed this way again.
|
|
254
|
+
|
|
255
|
+
**What did not change.** Paragraph paths (`27(a)(i)`) and entry ids (`25b`,
|
|
256
|
+
`27a-mw`) are citation-derived and stay bare. No entry id present in 0.1.1
|
|
257
|
+
is removed — the 40 entries of 0.1.1 are all in 0.2.0, with 30 more.
|
|
258
|
+
|
|
259
|
+
**What did.** Every light id, fact key, fact value and relation verb, in
|
|
260
|
+
every place it appears: `lights.json` keys, `facts.json` keys and `values`,
|
|
261
|
+
the `light` field of an entry's `lights[]`, the keys and values of an entry's
|
|
262
|
+
`when` and `modality_by[].when`, the relation keys on an entry
|
|
263
|
+
(`includes` → `rel:includes`, and so on), the `relations` map in
|
|
264
|
+
`applicability.json`, the `light` field in `geometry.json`, the
|
|
265
|
+
`signalk_navigation_state.decode` table, `actuable_subset.fields`, and the
|
|
266
|
+
`facts` record of every fixture. The rule is in
|
|
267
|
+
[`docs/identifiers.md`](docs/identifiers.md): a light is `light:<id>`, a
|
|
268
|
+
fact key is `fact:<key>`, a value of an enumerated fact is `<fact>:<value>`,
|
|
269
|
+
a relation is `rel:<name>`. The full table, generated from the two data
|
|
270
|
+
sets rather than from memory:
|
|
271
|
+
|
|
272
|
+
| kind | 0.1.1 | 0.2.0 |
|
|
273
|
+
|---|---|---|
|
|
274
|
+
| light id | `masthead` | `light:masthead` |
|
|
275
|
+
| light id | `sidelights` | `light:sidelights` |
|
|
276
|
+
| light id | `sidelight_starboard` | `light:sidelight_starboard` |
|
|
277
|
+
| light id | `sidelight_port` | `light:sidelight_port` |
|
|
278
|
+
| light id | `sternlight` | `light:sternlight` |
|
|
279
|
+
| light id | `towing` | `light:towing` |
|
|
280
|
+
| light id | `all_round` | `light:all_round` |
|
|
281
|
+
| light id | `flashing` | `light:flashing` |
|
|
282
|
+
| light id | `torch` | `light:torch` |
|
|
283
|
+
| light id | `deck_lights` | `light:deck_lights` |
|
|
284
|
+
| fact key | `propulsion` | `fact:propulsion` |
|
|
285
|
+
| value of propulsion | `power` | `propulsion:power` |
|
|
286
|
+
| value of propulsion | `sail` | `propulsion:sail` |
|
|
287
|
+
| value of propulsion | `oars` | `propulsion:oars` |
|
|
288
|
+
| fact key | `activity` | `fact:activity` |
|
|
289
|
+
| value of activity | `none` | `activity:none` |
|
|
290
|
+
| value of activity | `fishing` | `activity:fishing` |
|
|
291
|
+
| value of activity | `trawling` | `activity:trawling` |
|
|
292
|
+
| value of activity | `towing` | `activity:towing` |
|
|
293
|
+
| value of activity | `pushing` | `activity:pushing` |
|
|
294
|
+
| value of activity | `being_towed` | `activity:being_towed` |
|
|
295
|
+
| value of activity | `nuc` | `activity:nuc` |
|
|
296
|
+
| value of activity | `ram` | `activity:ram` |
|
|
297
|
+
| value of activity | `ram_underwater` | `activity:ram_underwater` |
|
|
298
|
+
| value of activity | `cbd` | `activity:cbd` |
|
|
299
|
+
| value of activity | `mine` | `activity:mine` |
|
|
300
|
+
| value of activity | `pilot` | `activity:pilot` |
|
|
301
|
+
| value of activity | `diving` | `activity:diving` |
|
|
302
|
+
| fact key | `position` | `fact:position` |
|
|
303
|
+
| value of position | `underway` | `position:underway` |
|
|
304
|
+
| value of position | `anchored` | `position:anchored` |
|
|
305
|
+
| value of position | `aground` | `position:aground` |
|
|
306
|
+
| value of position | `moored` | `position:moored` |
|
|
307
|
+
| fact key | `making_way` | `fact:making_way` |
|
|
308
|
+
| fact key | `length_m` | `fact:length_m` |
|
|
309
|
+
| fact key | `tow_length_m` | `fact:tow_length_m` |
|
|
310
|
+
| fact key | `max_speed_kn` | `fact:max_speed_kn` |
|
|
311
|
+
| fact key | `gear_extent_m` | `fact:gear_extent_m` |
|
|
312
|
+
| fact key | `beam_m` | `fact:beam_m` |
|
|
313
|
+
| fact key | `composite_unit` | `fact:composite_unit` |
|
|
314
|
+
| fact key | `non_displacement` | `fact:non_displacement` |
|
|
315
|
+
| fact key | `wig` | `fact:wig` |
|
|
316
|
+
| fact key | `wig_near_surface` | `fact:wig_near_surface` |
|
|
317
|
+
| fact key | `near_channel` | `fact:near_channel` |
|
|
318
|
+
| fact key | `inconspicuous_partly_submerged_tow` | `fact:inconspicuous_partly_submerged_tow` |
|
|
319
|
+
| fact key | `towed_alongside` | `fact:towed_alongside` |
|
|
320
|
+
| fact key | `obstruction_exists` | `fact:obstruction_exists` |
|
|
321
|
+
| fact key | `obstruction_side` | `fact:obstruction_side` |
|
|
322
|
+
| value of obstruction_side | `port` | `obstruction_side:port` |
|
|
323
|
+
| value of obstruction_side | `starboard` | `obstruction_side:starboard` |
|
|
324
|
+
| relation | `includes` | `rel:includes` |
|
|
325
|
+
| relation | `conditional_includes` | `rel:conditional_includes` |
|
|
326
|
+
| relation | `in_lieu_of` | `rel:in_lieu_of` |
|
|
327
|
+
| relation | `excludes` | `rel:excludes` |
|
|
328
|
+
| relation | `exempts` | `rel:exempts` |
|
|
329
|
+
|
|
330
|
+
The mapping is mechanical and total: strip nothing, prepend the namespace.
|
|
331
|
+
The one string that needed the prefix to disambiguate is `towing`, which in
|
|
332
|
+
0.1.1 was both a light id and an `activity` value; it is now `light:towing`
|
|
333
|
+
or `activity:towing` depending on which it was.
|
|
334
|
+
|
|
335
|
+
A consumer that builds a fact record from SignalK `navigation.state` gets
|
|
336
|
+
the new keys and values from the decode table for free. One that stored a
|
|
337
|
+
0.1.1 fact record, light id or relation name must rewrite it by the table
|
|
338
|
+
above; `fixtures/applicability-fixtures.json` is the check that the rewrite
|
|
339
|
+
came out right.
|
|
340
|
+
|
|
341
|
+
From 0.2.0 on, every identifier in the package is immutable once published
|
|
342
|
+
(REQ-MODEL-10). [`data/deprecated-identifiers.json`](data/deprecated-identifiers.json)
|
|
343
|
+
is the REQ-MODEL-11 registry a retired identifier goes into, and `npm test`
|
|
344
|
+
refuses a removal that is not recorded there.
|
|
345
|
+
|
|
346
|
+
## Provenance and licence
|
|
347
|
+
|
|
348
|
+
Rule text, the `NRHB_*` diagrams and the five `*arc.gif` files are USCG
|
|
349
|
+
publications, public domain; see [PROVENANCE.md](PROVENANCE.md). The
|
|
350
|
+
compilation is Apache-2.0.
|
|
48
351
|
|
|
49
|
-
|
|
50
|
-
|
|
352
|
+
Not authoritative, not endorsed by the Coast Guard. Navigate by the published
|
|
353
|
+
rules. When the `ca/inland` delta lands, it will carry the same condition
|
|
354
|
+
its licence does: it must not be represented as an official version.
|