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.
Files changed (34) hide show
  1. package/LICENSE +194 -26
  2. package/PROVENANCE.md +46 -13
  3. package/README.md +324 -20
  4. package/data/applicability.json +1247 -236
  5. package/data/deprecated-identifiers.json +7 -0
  6. package/data/facts.json +549 -112
  7. package/data/geometry.json +34 -34
  8. package/data/images.json +52 -26
  9. package/data/lights.json +36 -36
  10. package/data/rules.json +887 -104
  11. package/docs/adr/0001-name-and-jurisdiction-model.md +194 -0
  12. package/docs/adr/0002-wig-gate-and-jurisdiction-field.md +77 -0
  13. package/docs/adr/0003-language-as-a-dimension.md +220 -0
  14. package/docs/adr/0004-licence-layering.md +78 -0
  15. package/docs/adr/0005-rule-categories-and-the-situation-record.md +323 -0
  16. package/docs/adr/0006-json-schema-and-identifier-diff.md +95 -0
  17. package/docs/conventions.md +27 -0
  18. package/docs/gates.json +84 -0
  19. package/docs/identifiers.md +435 -0
  20. package/docs/requirements.md +1320 -0
  21. package/docs/verification/2026-08-30-q6-q8.md +278 -0
  22. package/docs/verification/2026-09-05-rule27f-rule28-anchor-scenarios.md +330 -0
  23. package/fixtures/applicability-fixtures.json +498 -138
  24. package/fixtures/situation-fixtures.json +3603 -0
  25. package/package.json +27 -5
  26. package/schema/applicability-fixtures.schema.json +47 -0
  27. package/schema/applicability.schema.json +401 -0
  28. package/schema/deprecated-identifiers.schema.json +29 -0
  29. package/schema/facts.schema.json +793 -0
  30. package/schema/geometry.schema.json +239 -0
  31. package/schema/images.schema.json +53 -0
  32. package/schema/lights.schema.json +131 -0
  33. package/schema/rules.schema.json +50 -0
  34. package/schema/situation-fixtures.schema.json +325 -0
package/README.md CHANGED
@@ -1,24 +1,69 @@
1
1
  # colregs
2
2
 
3
- The international collision regulations, and the national amalgamations derived
4
- from them, as language-neutral JSON with the provenance to check every line
5
- against its source and fixtures a second implementation can verify against.
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.** Nothing here is complete, and nothing here is fit for
10
- > navigation. See [`docs/requirements.md`](docs/requirements.md) for what it is
11
- > meant to become.
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
- | **Rules** | Part C, lights (Rules 20–31). Day shapes and Part D signals are not here. |
18
- | **Jurisdictions** | `intl` only. US Inland, Canada and the rest are modelled for but not present. |
19
- | **Conditions** | Night. |
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
- Coverage is stated because silence must not imply it (REQ-SCOPE-6).
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) the source of truth
30
- - [`docs/adr/`](docs/adr/) decisions, with the reasoning that produced them
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 `27(a)(i)`, not "Rule 27". Citation unit and composition
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
- **Predicates, not enumerations.** Gates are `length_m < 7`, never a pre-built
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 a
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
- ## Licence
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
- Code and fixtures: see `LICENSE`. Rule text and diagrams carry their own terms,
50
- recorded per asset — see `PROVENANCE.md` once data lands.
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.