diff --git a/00-META/checks/README.md b/00-META/checks/README.md index e2f8d23d..fbfc2666 100644 --- a/00-META/checks/README.md +++ b/00-META/checks/README.md @@ -26,6 +26,7 @@ indistinguishable from one that cannot. | `rests-on` | `decisions:` and `extends:` name records that exist and are **accepted** | the class behind both incidents | | `live-citation` | a governing document citing a **superseded** record names its replacement in the same paragraph | `01-to-be/README.md` citing ADR 0022 as live guidance | | `supersession` | if A says it was superseded by B, B says it supersedes A | ADR 0012 never declared that it superseded 0011 | +| `partial-supersession` | a record's `supersedes-in-part:` names records that exist, each carrying a dated *Superseded in part* note naming it under its heading; and every such note is named back by its superseder's field | 11 of 21 partial supersessions had no note on the record they change, and 6 more were said only in prose ([research 045](../../01-RESEARCH/045-a-knowledge-base-the-mesh-writes/00-overview.md)) | | `numbering` | the number in the filename is the number in the heading | — | | `topics` | every record names a topic of the reading order in `02-DECISIONS/README.md` | — | | *(index.py)* | the reading order is written, every record's topic is one of it, and the README stores no list of records ([ADR 0248](../../02-DECISIONS/0248-the-decision-index-is-generated-when-it-is-read-and-never-stored.md)) | a stored list made every two open decisions conflict ([issue 297](../../04-ISSUES/297-two-open-decisions-always-conflict/00-report.md)); it failed on the README of `main` before the list was removed | diff --git a/00-META/checks/records.py b/00-META/checks/records.py index 0c1ea1d2..6bd0c086 100644 --- a/00-META/checks/records.py +++ b/00-META/checks/records.py @@ -264,6 +264,74 @@ def check_supersession_symmetry(failures, records): ) +PARTIAL_MARK = re.compile( + r"^> \*\*Superseded in part — (\d{4}-\d{2}-\d{2}), by \[ADR (\d{4})\]\(", re.M +) + + +# The form these notes had before the check: it named the later record but nothing read it. +NARROWED_MARK = re.compile(r"^> \*\*Narrowed, not replaced — [^\n]*\[ADR \d{4}\]\(", re.M) + + +def check_partial_supersession(failures, records): + """A record superseded in part says so under its heading, and its superseder names it. + + A partial supersession was written only in the newer record's prose six times, and 11 of the + 21 `supersedes-in-part:` links had no note on the record they change, so a reader who arrived + at the older record by a citation read a rule that no longer held. Both directions are + checked: the field on the newer record and the dated note on the older one, naming each other. + The note is dated by the newer record's `date:`, and the older form of the note, which named a + later record and was read by nothing, is refused so it cannot be a way round this check. + """ + for number, record in records.items(): + claimed = record["front"].get("supersedes-in-part", []) + if isinstance(claimed, str): + claimed = [claimed] if claimed else [] + for entry in claimed: + match = ADR_FILE.match(os.path.basename(entry)) + if not match or match.group(1) not in records: + failures.add("partial-supersession", rel(record["path"]), f"no such record: {entry}") + continue + older = records[match.group(1)] + marks = [by for _, by in PARTIAL_MARK.findall(older["text"])] + if number not in marks: + failures.add( + "partial-supersession", + rel(older["path"]), + f"ADR {number} supersedes this in part; this record carries no " + f"'> **Superseded in part — YYYY-MM-DD, by [ADR {number}](…).**' note", + ) + for line in NARROWED_MARK.findall(record["text"]): + failures.add( + "partial-supersession", + rel(record["path"]), + f"a note names a later record in the old form ({line.strip()[:60]}…); write it as " + f"'> **Superseded in part — YYYY-MM-DD, by [ADR NNNN](…).**' and declare it in that " + f"record's `supersedes-in-part:`", + ) + for date, by in PARTIAL_MARK.findall(record["text"]): + if by in records and date != str(records[by]["front"].get("date", "")): + failures.add( + "partial-supersession", + rel(record["path"]), + f"the note for ADR {by} is dated {date}; ADR {by} is dated " + f"{records[by]['front'].get('date', 'nowhere')}", + ) + if by not in records: + failures.add("partial-supersession", rel(record["path"]), f"note names no such record: ADR {by}") + continue + names = records[by]["front"].get("supersedes-in-part", []) + if isinstance(names, str): + names = [names] if names else [] + if record["name"] not in [os.path.basename(str(n)) for n in names]: + failures.add( + "partial-supersession", + rel(records[by]["path"]), + f"ADR {number} says this supersedes it in part; this record's " + f"`supersedes-in-part:` does not name it", + ) + + def check_topics(failures, records): """Every record names a topic of the reading order. @@ -406,6 +474,7 @@ def main(): check_rests_on(failures, records) check_live_citations(failures, records) check_supersession_symmetry(failures, records) + check_partial_supersession(failures, records) check_numbering(failures, records) check_topics(failures, records) check_status_against_code(failures) diff --git a/02-DECISIONS/0006-the-substrate-and-the-control-plane.md b/02-DECISIONS/0006-the-substrate-and-the-control-plane.md index 37f408cf..eacc6791 100644 --- a/02-DECISIONS/0006-the-substrate-and-the-control-plane.md +++ b/02-DECISIONS/0006-the-substrate-and-the-control-plane.md @@ -8,6 +8,11 @@ reconstructed: false # 6. The substrate and the control plane +> **Superseded in part — 2026-10-07, by [ADR 0244](0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md).** +> The seven contexts below no longer describe the mesh: it is described in ten domains, and "domain" replaces +> "context" in this sense; *observability* becomes Health and repair. This record keeps its word, and the +> glossary says how to read it. Everything else decided here stands. + *Consolidated 2026-08-28 from six records. Extended 2026-08-29, by building it: the language, and what must be running before the control plane starts — which this record had left not established and could not have settled the way it was asking.* diff --git a/02-DECISIONS/0008-a-context-owns-its-store.md b/02-DECISIONS/0008-a-context-owns-its-store.md index 8175dd4c..ab3c9968 100644 --- a/02-DECISIONS/0008-a-context-owns-its-store.md +++ b/02-DECISIONS/0008-a-context-owns-its-store.md @@ -4,7 +4,7 @@ status: accepted date: 2026-08-26 deciders: jochen reconstructed: false -extends: 0009-modules-and-the-graph.md +extends: 02-DECISIONS/0009-modules-and-the-graph.md --- # 8. A context owns its store, exclusively diff --git a/02-DECISIONS/0009-modules-and-the-graph.md b/02-DECISIONS/0009-modules-and-the-graph.md index 390c36a2..44b6f96f 100644 --- a/02-DECISIONS/0009-modules-and-the-graph.md +++ b/02-DECISIONS/0009-modules-and-the-graph.md @@ -8,6 +8,11 @@ reconstructed: false # 9. Modules and the graph +> **Superseded in part — 2026-10-06, by [ADR 0226](0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md).** +> The section *what a domain module turns out to be* no longer describes what runs: `networking` is retired, +> every machine is assigned the private network's own module, and the catalogue holds no domain module. The +> mechanism, a module with requirements and no files, and the rest of this record stand as decided here. + *Consolidated 2026-08-28 from six records.* ## Everything is a module @@ -38,7 +43,7 @@ hand. ### What a domain module turns out to be, and why it is not the one refused above -> **Narrowed, not replaced — 2026-10-06, by [ADR 0226](0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md).** The catalogue no longer +> **Superseded in part — 2026-10-06, by [ADR 0226](0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md).** The catalogue no longer > holds a domain module: `networking` was retired, and every machine is assigned the private network's > own module. A module with requirements and no files stays a thing a module may be; "why it is worth > having" below describes what this record decided for `networking`, not what runs. diff --git a/02-DECISIONS/0018-a-picture-is-read-from-what-runs.md b/02-DECISIONS/0018-a-picture-is-read-from-what-runs.md index 04d9d32d..2316672d 100644 --- a/02-DECISIONS/0018-a-picture-is-read-from-what-runs.md +++ b/02-DECISIONS/0018-a-picture-is-read-from-what-runs.md @@ -4,7 +4,7 @@ status: accepted date: 2026-08-24 deciders: jochen reconstructed: false -extends: 0017-a-test-defends-a-decision.md +extends: 02-DECISIONS/0017-a-test-defends-a-decision.md --- # 18. A picture of a system is read from the system, never from what asked for it diff --git a/02-DECISIONS/0040-what-a-module-is.md b/02-DECISIONS/0040-what-a-module-is.md index 84cc967a..8b025787 100644 --- a/02-DECISIONS/0040-what-a-module-is.md +++ b/02-DECISIONS/0040-what-a-module-is.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-03 deciders: jochen reconstructed: false -extends: 0009-modules-and-the-graph.md +extends: 02-DECISIONS/0009-modules-and-the-graph.md --- # 40. What a module is diff --git a/02-DECISIONS/0041-events-are-a-relationship.md b/02-DECISIONS/0041-events-are-a-relationship.md index 030037c2..83bf0b10 100644 --- a/02-DECISIONS/0041-events-are-a-relationship.md +++ b/02-DECISIONS/0041-events-are-a-relationship.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-03 deciders: jochen reconstructed: false -extends: 0040-what-a-module-is.md +extends: 02-DECISIONS/0040-what-a-module-is.md --- # 41. Events are a relationship, the lighter sibling of provisioning diff --git a/02-DECISIONS/0042-the-shape-of-an-event-on-the-wire.md b/02-DECISIONS/0042-the-shape-of-an-event-on-the-wire.md index 0479407c..d5633851 100644 --- a/02-DECISIONS/0042-the-shape-of-an-event-on-the-wire.md +++ b/02-DECISIONS/0042-the-shape-of-an-event-on-the-wire.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-03 deciders: jochen reconstructed: false -extends: 0041-events-are-a-relationship.md +extends: 02-DECISIONS/0041-events-are-a-relationship.md --- # 42. The shape of an event on the wire diff --git a/02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md b/02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md index cefd1111..1acfab82 100644 --- a/02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md +++ b/02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-04 deciders: jochen reconstructed: false -extends: 0041-events-are-a-relationship.md +extends: 02-DECISIONS/0041-events-are-a-relationship.md --- # 43. A module's broker account is scoped by what it emits and consumes diff --git a/02-DECISIONS/0044-a-public-name-is-provisioned-like-any-capability.md b/02-DECISIONS/0044-a-public-name-is-provisioned-like-any-capability.md index 0aa0f9de..8be68a42 100644 --- a/02-DECISIONS/0044-a-public-name-is-provisioned-like-any-capability.md +++ b/02-DECISIONS/0044-a-public-name-is-provisioned-like-any-capability.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-04 deciders: jochen reconstructed: false -extends: 0027-a-provision-names-what-the-consumer-is-coupled-to.md +extends: 02-DECISIONS/0027-a-provision-names-what-the-consumer-is-coupled-to.md --- # 44. A public name is provisioned, not registered by hand diff --git a/02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md b/02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md index a5c61ac4..cd85065f 100644 --- a/02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md +++ b/02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md @@ -4,11 +4,16 @@ status: accepted date: 2026-09-04 deciders: jochen reconstructed: false -extends: 0005-the-node-host.md +extends: 02-DECISIONS/0005-the-node-host.md --- # 45. A machine's firewall is the sum of what its modules listen on +> **Superseded in part — 2026-09-28, by [ADR 0138](0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md).** +> That a listen's `from` "is the whole of public-versus-internal" no longer holds: an assignment states each +> endpoint's reach, a statement that also governs names and certificates, and `from` is the packet filter's +> share of it. The firewall derived and applied on the node, not a provider, stands as decided here. + ## Context The reverse proxy is a *provider*: a module `requires` the `route` capability and a running proxy diff --git a/02-DECISIONS/0046-a-module-configuration-is-its-assignments-not-its-manifest.md b/02-DECISIONS/0046-a-module-configuration-is-its-assignments-not-its-manifest.md index 402c5baa..ffb4380c 100644 --- a/02-DECISIONS/0046-a-module-configuration-is-its-assignments-not-its-manifest.md +++ b/02-DECISIONS/0046-a-module-configuration-is-its-assignments-not-its-manifest.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-04 deciders: jochen reconstructed: false -extends: 0027-a-provision-names-what-the-consumer-is-coupled-to.md +extends: 02-DECISIONS/0027-a-provision-names-what-the-consumer-is-coupled-to.md --- # 46. A module's configuration is its assignment's, not its manifest's diff --git a/02-DECISIONS/0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md b/02-DECISIONS/0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md index 7201c0af..28a5bb76 100644 --- a/02-DECISIONS/0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md +++ b/02-DECISIONS/0047-a-module-runs-its-code-as-its-own-process-with-its-own-account.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-04 deciders: jochen reconstructed: false -extends: 0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md +extends: 02-DECISIONS/0043-a-module-broker-account-is-scoped-by-emits-and-consumes.md --- # 47. A module runs its code as its own process, with its own account diff --git a/02-DECISIONS/0051-shared-data-is-the-operators.md b/02-DECISIONS/0051-shared-data-is-the-operators.md index ee7b9ced..f48954ba 100644 --- a/02-DECISIONS/0051-shared-data-is-the-operators.md +++ b/02-DECISIONS/0051-shared-data-is-the-operators.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-05 deciders: jochen reconstructed: false -extends: 0030-data-outlives-the-mesh-that-declared-it.md +extends: 02-DECISIONS/0030-data-outlives-the-mesh-that-declared-it.md --- # 51. Shared data is the operator's, and a module is granted access to it diff --git a/02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md b/02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md index 1f2e3860..96783bdb 100644 --- a/02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md +++ b/02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-05 deciders: jochen reconstructed: false -extends: 0005-the-node-host.md +extends: 02-DECISIONS/0005-the-node-host.md --- # 52. An init step is a container run once to completion, gating what follows diff --git a/02-DECISIONS/0053-a-step-that-runs-on-a-schedule.md b/02-DECISIONS/0053-a-step-that-runs-on-a-schedule.md index b13d6e6c..865ce7a2 100644 --- a/02-DECISIONS/0053-a-step-that-runs-on-a-schedule.md +++ b/02-DECISIONS/0053-a-step-that-runs-on-a-schedule.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-06 deciders: jochen reconstructed: false -extends: 0052-a-step-that-runs-once-before-a-container.md +extends: 02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md --- # 53. A scheduled step is a container run on a recurring schedule diff --git a/02-DECISIONS/0054-model-usage-is-recorded-at-two-grains.md b/02-DECISIONS/0054-model-usage-is-recorded-at-two-grains.md index 86b61e53..47336f84 100644 --- a/02-DECISIONS/0054-model-usage-is-recorded-at-two-grains.md +++ b/02-DECISIONS/0054-model-usage-is-recorded-at-two-grains.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-06 deciders: jochen reconstructed: false -extends: 0050-model-access-is-vendor-agnostic.md +extends: 02-DECISIONS/0050-model-access-is-vendor-agnostic.md --- # 54. Model usage is a vendor-neutral record, produced by the adapter, at two grains diff --git a/02-DECISIONS/0055-model-access-is-answered-by-a-licence-or-a-node.md b/02-DECISIONS/0055-model-access-is-answered-by-a-licence-or-a-node.md index 17aaa41a..d148d68a 100644 --- a/02-DECISIONS/0055-model-access-is-answered-by-a-licence-or-a-node.md +++ b/02-DECISIONS/0055-model-access-is-answered-by-a-licence-or-a-node.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-07 deciders: jochen reconstructed: false -extends: 0050-model-access-is-vendor-agnostic.md +extends: 02-DECISIONS/0050-model-access-is-vendor-agnostic.md --- # 55. Model access is answered by a licence, or by a node that hosts the model diff --git a/02-DECISIONS/0066-public-routing-is-name-agnostic.md b/02-DECISIONS/0066-public-routing-is-name-agnostic.md index 37fb663f..8c4f88e3 100644 --- a/02-DECISIONS/0066-public-routing-is-name-agnostic.md +++ b/02-DECISIONS/0066-public-routing-is-name-agnostic.md @@ -4,14 +4,14 @@ status: accepted date: 2026-09-09 deciders: jochen reconstructed: false -extends: 0007-connectivity.md +extends: 02-DECISIONS/0007-connectivity.md --- # 66. Public routing is name-agnostic, its names are resolved inside the mesh, and an internal authority can certify them -> **Narrowed, not replaced — 2026-10-03.** One clause of the decision below no longer holds: *publishing -> a granted name into internal resolution, mesh-wide*. A public name now resolves publicly, and only -> names under the mesh's own suffix get a private answer — [ADR 0191](0191-the-meshs-resolver-holds-only-the-meshs-own-names.md). +> **Superseded in part — 2026-10-03, by [ADR 0191](0191-the-meshs-resolver-holds-only-the-meshs-own-names.md).** +> One clause of the decision below no longer holds: *publishing a granted name into internal resolution, +> mesh-wide*. A public name now resolves publicly, and only names under the mesh's own suffix get a private answer. > Inside the mesh a route is reached and certified by its internal name > ([ADR 0151](0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md)). The label, the > node's public domain and their composition stand as decided here. diff --git a/02-DECISIONS/0067-genesis-is-a-pivot.md b/02-DECISIONS/0067-genesis-is-a-pivot.md index 681b0539..060a7056 100644 --- a/02-DECISIONS/0067-genesis-is-a-pivot.md +++ b/02-DECISIONS/0067-genesis-is-a-pivot.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-10 deciders: jochen reconstructed: false -extends: 0006-the-substrate-and-the-control-plane.md +extends: 02-DECISIONS/0006-the-substrate-and-the-control-plane.md --- # 67. Genesis is a pivot: a temporary control plane installs the registry that makes it permanent diff --git a/02-DECISIONS/0068-the-lab-takes-requests.md b/02-DECISIONS/0068-the-lab-takes-requests.md index 12225d5c..f5ef5e43 100644 --- a/02-DECISIONS/0068-the-lab-takes-requests.md +++ b/02-DECISIONS/0068-the-lab-takes-requests.md @@ -4,7 +4,7 @@ status: superseded date: 2026-09-12 deciders: jochen reconstructed: false -extends: 0016-the-lab.md +extends: 02-DECISIONS/0016-the-lab.md superseded-by: 02-DECISIONS/0149-the-live-mesh-is-the-test-bed.md --- diff --git a/02-DECISIONS/0069-a-module-is-a-repository-and-a-path.md b/02-DECISIONS/0069-a-module-is-a-repository-and-a-path.md index 7c439176..82fa411a 100644 --- a/02-DECISIONS/0069-a-module-is-a-repository-and-a-path.md +++ b/02-DECISIONS/0069-a-module-is-a-repository-and-a-path.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-12 deciders: jochen reconstructed: false -extends: 0009-modules-and-the-graph.md +extends: 02-DECISIONS/0009-modules-and-the-graph.md --- # 69. A module is a repository and a path within it diff --git a/02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md b/02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md index 5c217537..ce5bba0e 100644 --- a/02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md +++ b/02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-12 deciders: jochen reconstructed: false -extends: 0067-genesis-is-a-pivot.md +extends: 02-DECISIONS/0067-genesis-is-a-pivot.md --- # 70. The catalogue owns the module graph, and genesis builds rather than carries diff --git a/02-DECISIONS/0071-where-genesis-gets-its-source.md b/02-DECISIONS/0071-where-genesis-gets-its-source.md index 6ebb2016..3fdcc03f 100644 --- a/02-DECISIONS/0071-where-genesis-gets-its-source.md +++ b/02-DECISIONS/0071-where-genesis-gets-its-source.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-12 deciders: jochen reconstructed: false -extends: 0070-the-catalogue-owns-the-module-graph.md +extends: 02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md --- # 71. Genesis clones from a mesh, and checks what it got diff --git a/02-DECISIONS/0072-two-graphs-and-the-build-chain.md b/02-DECISIONS/0072-two-graphs-and-the-build-chain.md index 354cf94c..45a69152 100644 --- a/02-DECISIONS/0072-two-graphs-and-the-build-chain.md +++ b/02-DECISIONS/0072-two-graphs-and-the-build-chain.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-12 deciders: jochen reconstructed: false -extends: 0070-the-catalogue-owns-the-module-graph.md +extends: 02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md --- # 72. Two graphs, and a build chain that orders itself diff --git a/02-DECISIONS/0073-the-installer-carries-a-builder.md b/02-DECISIONS/0073-the-installer-carries-a-builder.md index 47fbc8ab..c83ac552 100644 --- a/02-DECISIONS/0073-the-installer-carries-a-builder.md +++ b/02-DECISIONS/0073-the-installer-carries-a-builder.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-13 deciders: jochen reconstructed: false -extends: 0070-the-catalogue-owns-the-module-graph.md +extends: 02-DECISIONS/0070-the-catalogue-owns-the-module-graph.md --- # 73. The installer carries a builder, and the registry stays where it is diff --git a/02-DECISIONS/0074-the-wire-is-specified-not-the-types.md b/02-DECISIONS/0074-the-wire-is-specified-not-the-types.md index e1ffe2f9..f0287a1f 100644 --- a/02-DECISIONS/0074-the-wire-is-specified-not-the-types.md +++ b/02-DECISIONS/0074-the-wire-is-specified-not-the-types.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-15 deciders: jochen reconstructed: false -extends: 0039-what-the-sdk-holds-and-refuses.md +extends: 02-DECISIONS/0039-what-the-sdk-holds-and-refuses.md --- # 74. The mesh defines a module protocol; an SDK is an implementation of it diff --git a/02-DECISIONS/0075-two-stores-and-which-provides-what.md b/02-DECISIONS/0075-two-stores-and-which-provides-what.md index 07be4d16..5205d385 100644 --- a/02-DECISIONS/0075-two-stores-and-which-provides-what.md +++ b/02-DECISIONS/0075-two-stores-and-which-provides-what.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-15 deciders: jochen reconstructed: false -extends: 0014-no-npm-workspace.md +extends: 02-DECISIONS/0014-no-npm-workspace.md --- # 75. An artifact store is a provision; a package registry is a different one diff --git a/02-DECISIONS/0076-the-sdk-is-a-published-package.md b/02-DECISIONS/0076-the-sdk-is-a-published-package.md index a1648a85..ffd1ae81 100644 --- a/02-DECISIONS/0076-the-sdk-is-a-published-package.md +++ b/02-DECISIONS/0076-the-sdk-is-a-published-package.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-16 deciders: jochen reconstructed: false -extends: 0075-two-stores-and-which-provides-what.md +extends: 02-DECISIONS/0075-two-stores-and-which-provides-what.md --- # 76. The SDK is a published package, and the toolchain resolves it by version diff --git a/02-DECISIONS/0077-the-controller-and-the-foundation.md b/02-DECISIONS/0077-the-controller-and-the-foundation.md index 1bdc5fde..d9cc7ebd 100644 --- a/02-DECISIONS/0077-the-controller-and-the-foundation.md +++ b/02-DECISIONS/0077-the-controller-and-the-foundation.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-16 deciders: jochen reconstructed: false -extends: 0006-the-substrate-and-the-control-plane.md +extends: 02-DECISIONS/0006-the-substrate-and-the-control-plane.md --- # 77. The parts are named controller, foundation, node — not control plane, substrate, master diff --git a/02-DECISIONS/0078-the-store-and-broker-are-modules.md b/02-DECISIONS/0078-the-store-and-broker-are-modules.md index 31e97edb..00c114b0 100644 --- a/02-DECISIONS/0078-the-store-and-broker-are-modules.md +++ b/02-DECISIONS/0078-the-store-and-broker-are-modules.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-16 deciders: jochen reconstructed: false -extends: 0033-the-substrate-is-a-store-and-a-broker.md +extends: 02-DECISIONS/0033-the-substrate-is-a-store-and-a-broker.md --- # 78. The store and the broker are ordinary modules diff --git a/02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md b/02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md index 578c99d1..6ccae0e1 100644 --- a/02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md +++ b/02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-17 deciders: jochen reconstructed: false -extends: 0078-the-store-and-broker-are-modules.md +extends: 02-DECISIONS/0078-the-store-and-broker-are-modules.md --- # 79. The foundation seats are named after their servers diff --git a/02-DECISIONS/0080-the-development-cycle-is-checked.md b/02-DECISIONS/0080-the-development-cycle-is-checked.md index ee2f4bb2..50460553 100644 --- a/02-DECISIONS/0080-the-development-cycle-is-checked.md +++ b/02-DECISIONS/0080-the-development-cycle-is-checked.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-17 deciders: jochen reconstructed: false -extends: 0019-how-this-repository-works.md +extends: 02-DECISIONS/0019-how-this-repository-works.md --- # 80. The development cycle is checked, not trusted diff --git a/02-DECISIONS/0081-a-decision-nothing-cites-is-not-yet-in-the-chain.md b/02-DECISIONS/0081-a-decision-nothing-cites-is-not-yet-in-the-chain.md index 6087d83c..1f519992 100644 --- a/02-DECISIONS/0081-a-decision-nothing-cites-is-not-yet-in-the-chain.md +++ b/02-DECISIONS/0081-a-decision-nothing-cites-is-not-yet-in-the-chain.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-17 deciders: jochen reconstructed: false -extends: 0080-the-development-cycle-is-checked.md +extends: 02-DECISIONS/0080-the-development-cycle-is-checked.md --- # 81. A decision nothing cites is not yet in the chain diff --git a/02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md b/02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md index 4cac697a..ed6964a8 100644 --- a/02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md +++ b/02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-17 deciders: jochen reconstructed: false -extends: 0072-two-graphs-and-the-build-chain.md +extends: 02-DECISIONS/0072-two-graphs-and-the-build-chain.md --- # 82. The registry is reached by name, and the overlay is its security diff --git a/02-DECISIONS/0083-one-push-leaves-the-mesh-consistent.md b/02-DECISIONS/0083-one-push-leaves-the-mesh-consistent.md index 88c5d77b..b181df99 100644 --- a/02-DECISIONS/0083-one-push-leaves-the-mesh-consistent.md +++ b/02-DECISIONS/0083-one-push-leaves-the-mesh-consistent.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-18 deciders: jochen reconstructed: false -extends: 0010-delivery.md +extends: 02-DECISIONS/0010-delivery.md --- # 83. One push leaves the mesh consistent diff --git a/02-DECISIONS/0088-the-foundation-filters-before-anything-listens.md b/02-DECISIONS/0088-the-foundation-filters-before-anything-listens.md index d46e5c71..311663cd 100644 --- a/02-DECISIONS/0088-the-foundation-filters-before-anything-listens.md +++ b/02-DECISIONS/0088-the-foundation-filters-before-anything-listens.md @@ -9,6 +9,11 @@ extends: 02-DECISIONS/0078-the-store-and-broker-are-modules.md # 88. The foundation filters before anything listens +> **Superseded in part — 2026-09-22, by [ADR 0100](0100-a-node-in-use-is-adopted-before-it-is-converged.md).** +> On a node raised adopted, the base ruleset is not loaded: its duty, the store never reachable from outside, +> passes to a table of the mesh's that only refuses. On every other node the base ruleset, loaded before the +> store and broker are raised, stands as decided here. + ## Context Adopting the store and broker as ordinary modules diff --git a/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md b/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md index 066a53fc..f77de354 100644 --- a/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md +++ b/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md @@ -9,6 +9,10 @@ extends: 02-DECISIONS/0096-an-upstream-image-is-copied-between-registries.md # 97. A vendor image is a declared build input, and a recipe fetches nothing undeclared +> **Superseded in part — 2026-10-08, by [ADR 0257](0257-a-copied-base-is-recorded-where-it-is-copied-kept-by-the-builds-that-stood-on-it-and-held-once-per-image.md).** +> A declared image is no longer copied "under the module's repository": it is copied into one repository per +> upstream image, whichever modules stand on it. Everything else decided here stands. + ## Context Three modules could not be built by the mesh's builder because their recipes reached for what diff --git a/02-DECISIONS/0099-a-step-that-runs-once-names-what-it-reads.md b/02-DECISIONS/0099-a-step-that-runs-once-names-what-it-reads.md index b18c94ae..e076bcda 100644 --- a/02-DECISIONS/0099-a-step-that-runs-once-names-what-it-reads.md +++ b/02-DECISIONS/0099-a-step-that-runs-once-names-what-it-reads.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-21 deciders: jochen reconstructed: false -extends: 0052-a-step-that-runs-once-before-a-container.md +extends: 02-DECISIONS/0052-a-step-that-runs-once-before-a-container.md --- # 99. A step that runs once names what it reads, and runs again when it changed diff --git a/02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md b/02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md index 7dad5130..e0cbd990 100644 --- a/02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md +++ b/02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md @@ -5,10 +5,17 @@ date: 2026-09-22 deciders: jochen reconstructed: false extends: 02-DECISIONS/0078-the-store-and-broker-are-modules.md +supersedes-in-part: + - 02-DECISIONS/0088-the-foundation-filters-before-anything-listens.md --- # 100. A node in use is adopted before it is converged +> **Superseded in part — 2026-09-23, by [ADR 0105](0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md).** +> The rule that the private network's range must not overlap a tunnel the predecessor still runs now applies +> only where the found tunnel is left running beside the mesh's. On the hub, where the mesh adopts the found +> tunnel in place, there is one tunnel and one range. Everything else decided here stands. + ## Context The mesh replaces a predecessor mesh that is running, on the same machines, with the services diff --git a/02-DECISIONS/0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md b/02-DECISIONS/0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md index 5767c367..0fb7080c 100644 --- a/02-DECISIONS/0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md +++ b/02-DECISIONS/0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md @@ -5,6 +5,8 @@ date: 2026-09-23 deciders: jochen reconstructed: false extends: 02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md +supersedes-in-part: + - 02-DECISIONS/0100-a-node-in-use-is-adopted-before-it-is-converged.md --- # 105. The mesh adopts the predecessor's tunnel in place diff --git a/02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md b/02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md index e89a7433..414abbaa 100644 --- a/02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md +++ b/02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-25 deciders: jochen reconstructed: false -extends: 0075-two-stores-and-which-provides-what.md +extends: 02-DECISIONS/0075-two-stores-and-which-provides-what.md --- # 109. A package registry seat is one per ecosystem, not one for all of them diff --git a/02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md b/02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md index 82113244..42036ea2 100644 --- a/02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md +++ b/02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md @@ -4,11 +4,16 @@ status: accepted date: 2026-09-25 deciders: jochen reconstructed: false -extends: 0009-modules-and-the-graph.md +extends: 02-DECISIONS/0009-modules-and-the-graph.md --- # 110. A seat is held by one assignment, from a closed set, and it may deliver a provision +> **Superseded in part — 2026-09-27, by [ADR 0122](0122-a-seat-is-data-a-rename-is-a-database-update.md).** +> "The controller carries the set in code" no longer holds: the seats are rows of a table in the controller's +> store, seeded by a migration, and a seat is referenced by a stable id, its name only a label. The closed set, +> one holder per scope and a delivering seat as the single answer for its provision stand as decided here. + > **Narrowed, not replaced — 2026-09-27, on merging two lines of work.** This was marked superseded by > [ADR 0126](0126-a-module-declares-its-own-seats.md), and that overstated it: 0126 says in as many > words that *"everything 0110 decided about what a seat is stands untouched"*. What moved is where the diff --git a/02-DECISIONS/0111-a-build-source-is-on-the-git-seat-or-external.md b/02-DECISIONS/0111-a-build-source-is-on-the-git-seat-or-external.md index 02fb4327..7e577fa3 100644 --- a/02-DECISIONS/0111-a-build-source-is-on-the-git-seat-or-external.md +++ b/02-DECISIONS/0111-a-build-source-is-on-the-git-seat-or-external.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-25 deciders: jochen reconstructed: false -extends: 0069-a-module-is-a-repository-and-a-path.md +extends: 02-DECISIONS/0069-a-module-is-a-repository-and-a-path.md --- # 111. A build source is on the mesh's git seat, or it is an external repository diff --git a/02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md b/02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md index 54af58f6..f5890a26 100644 --- a/02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md +++ b/02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-25 deciders: jochen reconstructed: false -extends: 0046-a-module-configuration-is-its-assignments-not-its-manifest.md +extends: 02-DECISIONS/0046-a-module-configuration-is-its-assignments-not-its-manifest.md --- # 112. A module definition names no node, no mesh and no path: everything it needs is a requirement the mesh resolves diff --git a/02-DECISIONS/0114-a-shared-credential-rotates-over-two-credentials.md b/02-DECISIONS/0114-a-shared-credential-rotates-over-two-credentials.md index a03831ab..19dee25c 100644 --- a/02-DECISIONS/0114-a-shared-credential-rotates-over-two-credentials.md +++ b/02-DECISIONS/0114-a-shared-credential-rotates-over-two-credentials.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-26 deciders: jochen reconstructed: false -extends: 0113-the-vault-makes-every-secret.md +extends: 02-DECISIONS/0113-the-vault-makes-every-secret.md --- # 114. A credential two parties hold rotates over two credentials; one a single party holds rotates in place, staged; and retiring a credential never removes what it reached diff --git a/02-DECISIONS/0115-one-assignment-of-a-module-per-node.md b/02-DECISIONS/0115-one-assignment-of-a-module-per-node.md index 59365291..5bfc9f85 100644 --- a/02-DECISIONS/0115-one-assignment-of-a-module-per-node.md +++ b/02-DECISIONS/0115-one-assignment-of-a-module-per-node.md @@ -3,7 +3,7 @@ topic: what runs on it status: accepted date: 2026-09-26 deciders: jochen -extends: 0112-a-module-definition-names-no-node-mesh-or-path.md +extends: 02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md --- # 115. One assignment of a module per node: the module's name is the assignment's identity diff --git a/02-DECISIONS/0117-a-machines-uplink-is-a-seat.md b/02-DECISIONS/0117-a-machines-uplink-is-a-seat.md index d5e6f8f6..b9756bea 100644 --- a/02-DECISIONS/0117-a-machines-uplink-is-a-seat.md +++ b/02-DECISIONS/0117-a-machines-uplink-is-a-seat.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-26 deciders: jochen reconstructed: false -extends: 0110-a-seat-is-a-module-assignment-from-a-closed-set.md +extends: 02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md --- # 117. A machine's uplink is a seat: the mesh configures the manager, never the link diff --git a/02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md b/02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md index 7e11f52b..7947cbdb 100644 --- a/02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md +++ b/02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-27 deciders: jochen reconstructed: false -extends: 0102-the-mesh-writes-into-a-shared-file-never-over-it.md +extends: 02-DECISIONS/0102-the-mesh-writes-into-a-shared-file-never-over-it.md --- # 118. Undeclaring removes what the mesh made, and gives a unit back the state it was found in @@ -80,7 +80,7 @@ records the state it first found the unit in, and undeclaring returns the unit t manager: running before the mesh arrived, running after it leaves. - **A unit the mesh started is stopped again**, and one it enabled is disabled again — the packet filter a converge loaded, which returning to adopted unloads. -> **Narrowed, not replaced — 2026-10-09, by [ADR 0269](0269-what-the-meshs-own-declaration-stopped-is-started-again-when-it-goes.md).** +> **Superseded in part — 2026-10-09, by [ADR 0269](0269-what-the-meshs-own-declaration-stopped-is-started-again-when-it-goes.md).** > "Never started on the way out" has one exception. The host now records what the mesh declared beside > what it found. A unit found running or enabled that the mesh's own declaration held stopped or disabled > is started or enabled again when that declaration goes, but only while it is still exactly as the mesh diff --git a/02-DECISIONS/0119-a-taken-tunnels-predecessor-is-retired.md b/02-DECISIONS/0119-a-taken-tunnels-predecessor-is-retired.md index 219c55cf..4b57cb72 100644 --- a/02-DECISIONS/0119-a-taken-tunnels-predecessor-is-retired.md +++ b/02-DECISIONS/0119-a-taken-tunnels-predecessor-is-retired.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-27 deciders: jochen reconstructed: false -extends: 0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md +extends: 02-DECISIONS/0105-the-mesh-adopts-the-predecessors-tunnel-in-place.md --- # 119. A taken tunnel's predecessor is retired once the take is proven diff --git a/02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md b/02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md index c142cda5..7bcc58c0 100644 --- a/02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md +++ b/02-DECISIONS/0120-a-roster-fact-carries-its-format-as-a-template.md @@ -4,7 +4,7 @@ status: accepted date: 2026-09-27 deciders: jochen reconstructed: false -extends: 0112-a-module-definition-names-no-node-mesh-or-path.md +extends: 02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md --- # 120. A roster fact carries its format as a template: the mesh owns the data, the module owns the format diff --git a/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md b/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md index 9f32bfa5..2c684b24 100644 --- a/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md +++ b/02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md @@ -4,19 +4,23 @@ status: accepted date: 2026-09-27 deciders: jochen reconstructed: false -extends: 0110-a-seat-is-a-module-assignment-from-a-closed-set.md +extends: 02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md --- # 121. A system seat is named for its scope, and a module may define its own -> **Narrowed, not replaced — 2026-10-03.** *"`the-dns-port` → `node-dns-resolver`"* no longer holds: -> the serving role moves to mesh scope as `mesh-resolver`, one per mesh, and `node-dns-resolver` is -> retired ([ADR 0194](0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md)). The -> distinction this record kept — serving and asking are two roles, two seats — stands, and -> `node-resolver-config` is unchanged. +> **Superseded in part — 2026-10-03, by [ADR 0194](0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md).** +> *"`the-dns-port` → `node-dns-resolver`"* no longer holds: the serving role moves to mesh scope as +> `mesh-resolver`, one per mesh, and `node-dns-resolver` is retired. The distinction this record kept — +> serving and asking are two roles, two seats — stands, and `node-resolver-config` is unchanged. > **The mechanism changed — 2026-10-02, by [ADR 0190](0190-a-seats-work-is-shared-by-its-holders-and-building-is-the-first-such-role.md).** The naming rule stands. The build role this record made mesh-scoped — *the mesh's single build machine* — is node-scoped now: `node-build-agent`, one holder per machine, every holder taking from one work queue. +> **Superseded in part — 2026-09-27, by [ADR 0122](0122-a-seat-is-data-a-rename-is-a-database-update.md).** +> "The renames are a coordinated migration, not a rename" no longer holds: a seat is a row in the controller's +> store, referenced by a stable id, so a rename is one update of its name, and only the claiming manifests are +> edited in the catalogue. The naming rule, the module-defined seats and the seats settled here stand. + ## Context [ADR 0110](0110-a-seat-is-a-module-assignment-from-a-closed-set.md) made seats a closed set the diff --git a/02-DECISIONS/0122-a-seat-is-data-a-rename-is-a-database-update.md b/02-DECISIONS/0122-a-seat-is-data-a-rename-is-a-database-update.md index 4d3eeb79..3676bdf0 100644 --- a/02-DECISIONS/0122-a-seat-is-data-a-rename-is-a-database-update.md +++ b/02-DECISIONS/0122-a-seat-is-data-a-rename-is-a-database-update.md @@ -5,8 +5,8 @@ date: 2026-09-27 deciders: jochen reconstructed: false supersedes-in-part: - - 0110-a-seat-is-a-module-assignment-from-a-closed-set.md - - 0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md + - 02-DECISIONS/0110-a-seat-is-a-module-assignment-from-a-closed-set.md + - 02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md --- # 122. A seat is data the controller owns, and a rename is a database update diff --git a/02-DECISIONS/0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md b/02-DECISIONS/0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md index 0f795815..4996cc6f 100644 --- a/02-DECISIONS/0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md +++ b/02-DECISIONS/0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md @@ -5,6 +5,8 @@ date: 2026-09-28 deciders: jochen reconstructed: false extends: 02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md +supersedes-in-part: + - 02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md --- # 138. An assignment binds an endpoint and says how far it reaches diff --git a/02-DECISIONS/0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md b/02-DECISIONS/0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md index c4d7cd3a..7339440a 100644 --- a/02-DECISIONS/0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md +++ b/02-DECISIONS/0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md @@ -9,9 +9,9 @@ extends: 02-DECISIONS/0066-public-routing-is-name-agnostic.md # 151. A route's internal name is composed under the node that serves it -> **Narrowed, not replaced — 2026-10-03.** *"The roster publishes it as itself, once, at the serving -> node's address"* no longer holds: a public name is never given a private answer, and resolves publicly -> ([ADR 0191](0191-the-meshs-resolver-holds-only-the-meshs-own-names.md)). The internal name this record +> **Superseded in part — 2026-10-03, by [ADR 0191](0191-the-meshs-resolver-holds-only-the-meshs-own-names.md).** +> *"The roster publishes it as itself, once, at the serving node's address"* no longer holds: a public name +> is never given a private answer, and resolves publicly. The internal name this record > composes is what that rests on, and stands. ## Context diff --git a/02-DECISIONS/0191-the-meshs-resolver-holds-only-the-meshs-own-names.md b/02-DECISIONS/0191-the-meshs-resolver-holds-only-the-meshs-own-names.md index be16cb4f..735a1198 100644 --- a/02-DECISIONS/0191-the-meshs-resolver-holds-only-the-meshs-own-names.md +++ b/02-DECISIONS/0191-the-meshs-resolver-holds-only-the-meshs-own-names.md @@ -5,8 +5,8 @@ date: 2026-10-03 deciders: jochen reconstructed: false supersedes-in-part: - - 0066-public-routing-is-name-agnostic.md - - 0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md + - 02-DECISIONS/0066-public-routing-is-name-agnostic.md + - 02-DECISIONS/0151-a-routes-internal-name-is-composed-under-the-node-that-serves-it.md --- # 191. The mesh's resolver holds only the mesh's own names; a public name resolves publicly diff --git a/02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md b/02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md index 77614de9..8c2135e6 100644 --- a/02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md +++ b/02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md @@ -5,8 +5,8 @@ date: 2026-10-03 deciders: jochen reconstructed: false supersedes-in-part: - - 0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md -extends: 0191-the-meshs-resolver-holds-only-the-meshs-own-names.md + - 02-DECISIONS/0121-a-system-seat-is-named-for-its-scope-and-modules-define-their-own.md +extends: 02-DECISIONS/0191-the-meshs-resolver-holds-only-the-meshs-own-names.md --- # 194. The mesh has one resolver, and every node asks it for the mesh's names @@ -16,10 +16,9 @@ extends: 0191-the-meshs-resolver-holds-only-the-meshs-own-names.md > server, each holding every node's internal domain from the same roster. One resolving module, the > mesh's names held only by its holders, and the retirement of every per-node copy stand. -> **Narrowed, not replaced — 2026-10-03.** How a node asks is decided again by -> [ADR 0196](0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md): every -> node and container asks `mesh-resolver` first and a public resolver only when it is silent. There is -> no `systemd-resolved` module and no runtime `dns` naming `mesh-resolver`, and step 2 of the migration +> **Superseded in part — 2026-10-03, by [ADR 0196](0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md).** +> How a node asks is decided again there: every node and container asks `mesh-resolver` first and a public +> resolver only when it is silent. There is no `systemd-resolved` module and no runtime `dns` naming `mesh-resolver`, and step 2 of the migration > reads as 0196 states it. Option 2 below was rejected for a laptop with its tunnel down resolving > nothing; a public resolver listed second answers exactly then. The one resolver, its placement and > the retirement of every per-node copy stand. diff --git a/02-DECISIONS/0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md b/02-DECISIONS/0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md index 0d192619..e77b8c8b 100644 --- a/02-DECISIONS/0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md +++ b/02-DECISIONS/0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md @@ -5,12 +5,12 @@ date: 2026-10-03 deciders: jochen reconstructed: false supersedes-in-part: - - 0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md + - 02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md --- # 196. A node asks the mesh's resolver first, and a public one only when it is silent -> **Narrowed, not replaced — 2026-10-05, by [ADR 0223](0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md).** The public resolver listed second goes: musl asks +> **Superseded in part — 2026-10-05, by [ADR 0223](0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md).** The public resolver listed second goes: musl asks > every listed server at once and takes the first reply, so a public "no such name" for a mesh name > won it, and every Alpine build on the home server failed. Every machine now lists the mesh's > resolvers — two holders of `mesh-dns-resolver`, its own first on a holder — and nothing else. Every diff --git a/02-DECISIONS/0199-a-module-that-answers-names-declares-its-zone-and-a-nodes-hosts-file-is-one-modules.md b/02-DECISIONS/0199-a-module-that-answers-names-declares-its-zone-and-a-nodes-hosts-file-is-one-modules.md index 2d1912b6..3c257d9d 100644 --- a/02-DECISIONS/0199-a-module-that-answers-names-declares-its-zone-and-a-nodes-hosts-file-is-one-modules.md +++ b/02-DECISIONS/0199-a-module-that-answers-names-declares-its-zone-and-a-nodes-hosts-file-is-one-modules.md @@ -4,7 +4,7 @@ status: accepted date: 2026-10-03 deciders: jochen reconstructed: false -extends: 0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md +extends: 02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md --- # 199. A module that answers names declares its zone, and a node's hosts file is one module's diff --git a/02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md b/02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md index a227d9ea..064127f6 100644 --- a/02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md +++ b/02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md @@ -5,7 +5,7 @@ date: 2026-10-05 deciders: jochen reconstructed: false supersedes-in-part: - - 0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md + - 02-DECISIONS/0196-a-node-asks-the-meshs-resolver-first-and-a-public-one-only-when-it-is-silent.md extends: 02-DECISIONS/0194-the-mesh-has-one-resolver-and-every-node-asks-it-for-the-meshs-names.md --- diff --git a/02-DECISIONS/0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md b/02-DECISIONS/0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md index aa342c14..dbc5714c 100644 --- a/02-DECISIONS/0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md +++ b/02-DECISIONS/0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md @@ -5,7 +5,7 @@ date: 2026-10-06 deciders: jochen reconstructed: false supersedes-in-part: - - 0009-modules-and-the-graph.md + - 02-DECISIONS/0009-modules-and-the-graph.md extends: 02-DECISIONS/0007-connectivity.md --- diff --git a/02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md b/02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md index 8321d058..12fd639a 100644 --- a/02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md +++ b/02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md @@ -9,6 +9,13 @@ extends: 02-DECISIONS/0227-the-core-holds-nine-rules-each-checked-and-is-built-t # 234. The mesh holds a conversation with its operator, over channels that are seats, and an answer that performs an action is authorised by the controller +> **Superseded in part — 2026-10-09, by [ADR 0259](0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md).** +> §8's controller holding an ask whose answer performs an action, its verbs `authorise request`, +> `authorise answer` and `authorisations`, and the controller performing no longer hold: the router holds the +> ask and issues a warrant, and the asker performs. The operator's identities (§3) and the factors' secrets +> (§8) are the router's own state, not the controller's. The tiers and proofs, the kinded benches, the content +> rule, the desk never authorising, long polling and every tier completable on the away channel stand. + ## Context **The output channel was built in its smallest form** ([ADR 0227](0227-the-core-holds-nine-rules-each-checked-and-is-built-to-them-in-six-phases.md), diff --git a/02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md b/02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md index 47b2a3fe..51d5076c 100644 --- a/02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md +++ b/02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md @@ -9,7 +9,7 @@ extends: 02-DECISIONS/0227-the-core-holds-nine-rules-each-checked-and-is-built-t # 237. A change is judged against the mesh that runs, before it merges, on the build seat -> **Narrowed, not replaced — 2026-10-06, by [ADR 0238](0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md).** +> **Superseded in part — 2026-10-06, by [ADR 0238](0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md).** > Decision 4's *which* and *what* moved: a pull request is checked when the mesh's module graph says it > reaches a module — the planner's own answer, not *a repository it builds a module from into that > branch* — and every repository of the mesh runs its own `merge-check.sh` as a second status, diff --git a/02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md b/02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md index 40fe4c7e..1040b7ca 100644 --- a/02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md +++ b/02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md @@ -5,7 +5,7 @@ date: 2026-10-06 deciders: jochen reconstructed: false supersedes-in-part: - - 0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md + - 02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md extends: 02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md --- diff --git a/02-DECISIONS/0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md b/02-DECISIONS/0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md index a8d9084e..8f4d6f45 100644 --- a/02-DECISIONS/0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md +++ b/02-DECISIONS/0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md @@ -5,7 +5,7 @@ date: 2026-10-06 deciders: jochen reconstructed: false supersedes-in-part: - - 0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md + - 02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md extends: 02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md --- diff --git a/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md b/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md index 8ec4d1f8..17322f64 100644 --- a/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md +++ b/02-DECISIONS/0244-the-mesh-is-described-in-domains-and-one-word-names-one-thing.md @@ -5,6 +5,8 @@ date: 2026-10-07 deciders: jochen reconstructed: false extends: 02-DECISIONS/0006-the-substrate-and-the-control-plane.md +supersedes-in-part: + - 02-DECISIONS/0006-the-substrate-and-the-control-plane.md --- # 244. The mesh is described in domains, and one word names one thing diff --git a/02-DECISIONS/0248-the-decision-index-is-generated-when-it-is-read-and-never-stored.md b/02-DECISIONS/0248-the-decision-index-is-generated-when-it-is-read-and-never-stored.md index 47d70b56..82988c42 100644 --- a/02-DECISIONS/0248-the-decision-index-is-generated-when-it-is-read-and-never-stored.md +++ b/02-DECISIONS/0248-the-decision-index-is-generated-when-it-is-read-and-never-stored.md @@ -5,7 +5,7 @@ date: 2026-10-07 deciders: jochen reconstructed: false supersedes-in-part: - - 0019-how-this-repository-works.md + - 02-DECISIONS/0019-how-this-repository-works.md --- # 248. The decision index is generated when it is read, and never stored diff --git a/02-DECISIONS/0249-a-delivery-groups-order-rules-have-a-precedence-and-a-declared-order-outranks-them-all.md b/02-DECISIONS/0249-a-delivery-groups-order-rules-have-a-precedence-and-a-declared-order-outranks-them-all.md index ea3bde6b..acd7c2b9 100644 --- a/02-DECISIONS/0249-a-delivery-groups-order-rules-have-a-precedence-and-a-declared-order-outranks-them-all.md +++ b/02-DECISIONS/0249-a-delivery-groups-order-rules-have-a-precedence-and-a-declared-order-outranks-them-all.md @@ -5,7 +5,7 @@ date: 2026-10-08 deciders: jochen reconstructed: false supersedes-in-part: - - 0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md + - 02-DECISIONS/0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md extends: 02-DECISIONS/0239-a-delivery-is-owned-by-the-mesh-delivery-module-and-runs-from-commit-to-delivered.md --- diff --git a/02-DECISIONS/0253-a-condition-says-itself-to-the-operator-in-plain-words-beside-its-summary.md b/02-DECISIONS/0253-a-condition-says-itself-to-the-operator-in-plain-words-beside-its-summary.md index 4e88c3bb..f0621acb 100644 --- a/02-DECISIONS/0253-a-condition-says-itself-to-the-operator-in-plain-words-beside-its-summary.md +++ b/02-DECISIONS/0253-a-condition-says-itself-to-the-operator-in-plain-words-beside-its-summary.md @@ -9,6 +9,12 @@ extends: 02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md # 253. A condition says itself to the operator in plain words beside its summary, says whether the operator is needed, and is answered from the notification +> **Superseded in part — 2026-10-08, by [ADR 0258](0258-a-desk-click-performs-only-an-acknowledgement-and-an-answer-is-a-one-time-ticket.md).** +> §6's reading of *acknowledge*, its promise to honour a tier "when one exists", and the consequence that the +> verb's own record says who chose it no longer hold: a desk click performs only an acknowledgement (Details, +> Silence for a week) until answers are authorised, and release, stop, start and restart are said in words. +> The plain words, the verdict, the quiet rule, the time zone and the one-line clearance stand as decided here. + ## Context The operator could not read the mesh's notifications diff --git a/02-DECISIONS/0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md b/02-DECISIONS/0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md index bd6e2502..d77598d7 100644 --- a/02-DECISIONS/0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md +++ b/02-DECISIONS/0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md @@ -5,7 +5,7 @@ date: 2026-10-08 deciders: jochen reconstructed: false supersedes-in-part: - - 0252-a-module-puts-an-account-in-a-group-and-the-mesh-says-when-a-new-login-is-needed.md + - 02-DECISIONS/0252-a-module-puts-an-account-in-a-group-and-the-mesh-says-when-a-new-login-is-needed.md extends: 02-DECISIONS/0236-a-build-is-judged-on-its-first-machine-and-put-back-by-something-other-than-itself-and-so-it-rolls-out-unattended.md --- diff --git a/02-DECISIONS/0257-a-copied-base-is-recorded-where-it-is-copied-kept-by-the-builds-that-stood-on-it-and-held-once-per-image.md b/02-DECISIONS/0257-a-copied-base-is-recorded-where-it-is-copied-kept-by-the-builds-that-stood-on-it-and-held-once-per-image.md index 7a082ab2..c938a9dc 100644 --- a/02-DECISIONS/0257-a-copied-base-is-recorded-where-it-is-copied-kept-by-the-builds-that-stood-on-it-and-held-once-per-image.md +++ b/02-DECISIONS/0257-a-copied-base-is-recorded-where-it-is-copied-kept-by-the-builds-that-stood-on-it-and-held-once-per-image.md @@ -5,7 +5,7 @@ date: 2026-10-08 deciders: jochen reconstructed: false supersedes-in-part: - - 0097-a-vendor-image-is-a-declared-build-input.md + - 02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md extends: 02-DECISIONS/0251-the-registries-say-what-they-hold-and-keep-what-is-named-and-a-machine-keeps-the-image-it-runs-and-the-one-before.md --- diff --git a/02-DECISIONS/0258-a-desk-click-performs-only-an-acknowledgement-and-an-answer-is-a-one-time-ticket.md b/02-DECISIONS/0258-a-desk-click-performs-only-an-acknowledgement-and-an-answer-is-a-one-time-ticket.md index 1bb6bda8..25600c57 100644 --- a/02-DECISIONS/0258-a-desk-click-performs-only-an-acknowledgement-and-an-answer-is-a-one-time-ticket.md +++ b/02-DECISIONS/0258-a-desk-click-performs-only-an-acknowledgement-and-an-answer-is-a-one-time-ticket.md @@ -5,6 +5,8 @@ date: 2026-10-08 deciders: jochen reconstructed: false extends: 02-DECISIONS/0253-a-condition-says-itself-to-the-operator-in-plain-words-beside-its-summary.md +supersedes-in-part: + - 02-DECISIONS/0253-a-condition-says-itself-to-the-operator-in-plain-words-beside-its-summary.md --- # 258. A desk click performs only an acknowledgement, an answer is a one-time ticket, and a verdict is never weakened diff --git a/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md b/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md index 63a6bcbf..1ae9b0fa 100644 --- a/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md +++ b/02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md @@ -5,7 +5,7 @@ date: 2026-10-09 deciders: jochen reconstructed: false supersedes-in-part: - - 0234-the-mesh-holds-a-conversation-with-its-operator.md + - 02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md extends: 02-DECISIONS/0234-the-mesh-holds-a-conversation-with-its-operator.md --- diff --git a/02-DECISIONS/0267-an-artifact-is-rebuilt-only-when-its-build-source-changes-and-a-module-moves-only-along-build-dependencies-on-artifacts.md b/02-DECISIONS/0267-an-artifact-is-rebuilt-only-when-its-build-source-changes-and-a-module-moves-only-along-build-dependencies-on-artifacts.md index 0cc89164..b4799976 100644 --- a/02-DECISIONS/0267-an-artifact-is-rebuilt-only-when-its-build-source-changes-and-a-module-moves-only-along-build-dependencies-on-artifacts.md +++ b/02-DECISIONS/0267-an-artifact-is-rebuilt-only-when-its-build-source-changes-and-a-module-moves-only-along-build-dependencies-on-artifacts.md @@ -5,8 +5,8 @@ date: 2026-10-08 deciders: jochen reconstructed: false supersedes-in-part: - - 0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md - - 0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md + - 02-DECISIONS/0162-a-merge-produces-a-tiered-plan-the-mesh-keeps.md + - 02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md extends: 02-DECISIONS/0238-a-commit-is-the-build-at-hand-one-commit-one-change-plan-checked-off-the-trunk-and-published-only-on-it.md --- diff --git a/02-DECISIONS/0269-what-the-meshs-own-declaration-stopped-is-started-again-when-it-goes.md b/02-DECISIONS/0269-what-the-meshs-own-declaration-stopped-is-started-again-when-it-goes.md index a2b4ae7a..e790b8a7 100644 --- a/02-DECISIONS/0269-what-the-meshs-own-declaration-stopped-is-started-again-when-it-goes.md +++ b/02-DECISIONS/0269-what-the-meshs-own-declaration-stopped-is-started-again-when-it-goes.md @@ -5,6 +5,8 @@ date: 2026-10-09 deciders: jochen reconstructed: false extends: 02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md +supersedes-in-part: + - 02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md --- # 269. What the mesh's own declaration stopped is started again when it goes diff --git a/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md b/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md index 24053636..38248b47 100644 --- a/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md +++ b/02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md @@ -14,6 +14,13 @@ extends: 02-DECISIONS/0249-a-delivery-groups-order-rules-have-a-precedence-and-a # 276. Merges are assembled in a rolling window, and each batch is delivered by one walk with one commit per repository +> **Superseded in part — 2026-10-10, by [ADR 0282](0282-a-fix-to-a-leaf-module-runs-healthy-on-every-node-within-five-minutes-of-its-merge-and-a-core-module-within-ten.md).** +> Decision 4's "one walk at a time", and decision 1's window for every merge, no longer hold: a lone merge is +> cut at once, and walks that share no repository, module or edge of the module graph run at once, one +> first-node judgement per node at a time. Two walks of one repository never at once, no walk superseded once +> it started, and the window for a merge that waits for its delivery group or arrives while a batch assembles +> stand as decided here. + ## Context Shortly after midnight on 2026-10-10 two pull requests of the catalogue were merged 18 seconds apart, the diff --git a/02-DECISIONS/0282-a-fix-to-a-leaf-module-runs-healthy-on-every-node-within-five-minutes-of-its-merge-and-a-core-module-within-ten.md b/02-DECISIONS/0282-a-fix-to-a-leaf-module-runs-healthy-on-every-node-within-five-minutes-of-its-merge-and-a-core-module-within-ten.md index 74a8fe31..29ad016f 100644 --- a/02-DECISIONS/0282-a-fix-to-a-leaf-module-runs-healthy-on-every-node-within-five-minutes-of-its-merge-and-a-core-module-within-ten.md +++ b/02-DECISIONS/0282-a-fix-to-a-leaf-module-runs-healthy-on-every-node-within-five-minutes-of-its-merge-and-a-core-module-within-ten.md @@ -5,6 +5,8 @@ date: 2026-10-10 deciders: jochen reconstructed: false extends: 02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md +supersedes-in-part: + - 02-DECISIONS/0276-merges-are-assembled-in-a-rolling-window-and-each-batch-is-delivered-by-one-walk-with-one-commit-per-repository.md --- # 282. A fix to a leaf module runs healthy on every node within five minutes of its merge, and a core module within ten diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index 9535486c..a9080ed5 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -73,6 +73,19 @@ rule for the author and the reviewer, and the diff is where it is caught. Making mean a record declaring the relationship in its frontmatter, which is a change to the record schema and has not been decided. +**A supersession in part is the declared case, and it is machine-checked.** A record that replaces part of +an older one names it under `supersedes-in-part:`, and the older record carries, directly under its +heading and newest first, a note in the form + +> **Superseded in part — YYYY-MM-DD, by ADR NNNN** (a link to it). What no longer holds, and what stands +> as decided here. + +dated by the newer record's `date:`. `00-META/checks/records.py` (`partial-supersession`) fails when +either half is missing, when the note's date is not the newer record's, and on a note in the older form +*Narrowed, not replaced*. Where the note sits is the reviewer's to see in the diff. Saying "this narrows" or "this replaces" an older record in prose alone is not +enough: on 2026-10-11, 6 records did only that, and 11 of 21 declared links had no note on the record +they changed. + The records run in the order the decisions were taken, oldest first. **Every decision is a record.** There is no ledger and no index file — if a decision is worth @@ -92,6 +105,8 @@ deciders: name reconstructed: true|false # true when the record was written after the fact from evidence superseded-by: # 02-DECISIONS/NNNN-....md, when status is superseded extends: # 02-DECISIONS/NNNN-....md, when this record widens an earlier one +supersedes: # a list of 02-DECISIONS/NNNN-....md this record replaces whole +supersedes-in-part: # a list of 02-DECISIONS/NNNN-....md of which this record replaces a part --- ```