diff --git a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md index 42318e0d..193a80ef 100644 --- a/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md +++ b/03-DESIGN/01-to-be/47-delivery-from-commit-to-delivered.md @@ -47,6 +47,7 @@ decisions: - "ADR 0549" - "ADR 0548" - "ADR 0547" + - "ADR 0546" - "ADR 0539" - "ADR 0536" - "ADR 0534" @@ -617,7 +618,7 @@ module's progress on each node is its want against its have, shown by the view ( ## Two graphs, one source of truth *ADR 0656, which supersedes ADR 0645 to ADR 0648; ADR 0595, -ADR 0596, ADR 0603 §2, §6, §7, ADR 0567 §5, ADR 0571 §8, ADR 0614 §4, ADR 0618 §2, ADR 0619 §1 to §3, ADR 0636 §1, +ADR 0596, ADR 0603 §2, §6, §7, ADR 0615 §1, §2, ADR 0567 §5, ADR 0571 §8, ADR 0614 §4, ADR 0618 §2, ADR 0619 §1 to §3, ADR 0636 §1, §3, §4, §7, ADR 0639 §7, §8, ADR 0564 §2, ADR 0363 §2.* From research 085's milestone. One graph answered two questions, which modules exist and which version runs where, @@ -707,7 +708,7 @@ Findings 11). How each is kept, read and retained is this design's choice under | Part | Kept data before G (form 0) | After G | Restored at a revert | |---|---|---|---| - | the indexer | the state `modules` (ADR 0603 §2's one key per module) and its durable consumer's position on the forge bridge's stream `forge` | catalog graph revisions as objects, form 1; `modules` no longer declared | yes: `modules` as it stood at G's delivery, and the consumer's position | + | the indexer | the state `modules` (ADR 0603 §2's one key per module) and its durable consumer's position on the forge bridge's stream `forge` | catalog graph revisions as objects, form 1; `modules` no longer declared, nor its tool `indexer_read_modules` or its view, every reader of it reading the catalog half (*Every other reader of which modules exist*, above) | yes: `modules` as it stood at G's delivery, and the consumer's position | | the gate | the states `merges` and `turns` | the delivery record's ledger, form 1; `merges` and `turns` no longer declared | yes: `merges` and `turns` as they stood at G's delivery | | the assigner | the wants, written from the indexer's `modules` | the same wants, form 0, written from the assignment graph; the assignment graph revisions as objects, form 1 | no | @@ -768,6 +769,19 @@ Findings 11). How each is kept, read and retained is this design's choice under candidate's view is read only by the parts that judge a candidate, inside the check its manifest validator and composer, and the indexer's candidate pass (ADR 0656, which changes ADR 0636 §4 in that the candidate pass joins them). +- **Every other reader of which modules exist reads the catalog half, in the same milestone.** From milestone G the + indexer declares no state `modules` and serves neither its tool `indexer_read_modules` nor a view of it (*Reverted*, + below), so every module that learns from it which modules exist moves in milestone G, not after: the watchman (its + manifest findings), the status view (`view_reach`), the forge module (which repositories its account writes), the + holders of the seats `mesh-config`, `mesh-provisioner` and `mesh-self-check`, the claude-code module and the tool + runner. Each takes a first view of the catalog half by the seat `mesh-catalog`'s verb `revision` and follows its + event `catalog-revision`, through `meshcatalogclient` in Go or the seat's generated TypeScript contract in the forge + module, names the seat and never the indexer, and keeps no list of its own (ADR 0656 §6, ADR 0596 §2; ADR 0615 §1, + under which every reader of the indexer's state moves in one milestone). The order is the module graph's: each + declares the verb in its `invokes`, so the served-verb edge delivers none of them to a node before an indexer serving + `revision` runs there (ADR 0615 §2, ADR 0614). The design's choice under ADR 0656 §6: one form of the fact, never + `modules` kept beside the catalog graph for these readers, which would be a second source of the same fact. How it is + checked: test 61. - **The trunk's heads come from the catalog half.** The checker takes the trunk heads a check merges onto from the catalog half, which carries the heads, and never reads the gate's state `source` (ADR 0596 §2); with the hold and the turns removed it reads nothing of the gate at all (*Nothing merges into a repository under check*). @@ -1012,7 +1026,8 @@ code finds none of the reads the revision view replaces, each by name: the index the checker's watch of the indexer's `candidates.`, the forge bridge's read of the gate's `merges` and `owed`, the checker's read of the gate's `source` and `turns`, the forge module's watch of the checker's `owed` (its `mesh/check` status, now the checker's `owed` event performed by the forge bridge) and its read of the gate's `source`, the grants -part's read of the assigner's state `wants`, the +part's read of the assigner's state `wants`, any module's read of the indexer's `modules` (its tool +`indexer_read_modules` in an `invokes`, its view in a `consumes`), the checker's validator request with no seat definitions, a seat list compiled into the node-engine, the checker, the builder or the grants part, a seat list's reader wired by a part itself, and a call of the forge module's own tools by a delivery part or the gate; an old node-engine that wakes takes its new build in a form it reads. @@ -1289,7 +1304,8 @@ and its verdict is carried (*A move of the trunk carries every verdict*); the ch the gate no longer watches the checker's verdicts for a hold. **Its record is to be accepted before the push:** ADR 0548 §2 to §4, §9 and §10, ADR 0551 and ADR 0534 §4's judgement of `mesh/check` by the merge are in force, and ADR 0661, which ends the first two and changes the third (proposed, needs the operator's Approve), is to be accepted before -milestone G's pull requests are pushed; until it is accepted, the rule below holds as those records have it. How it is checked: in the gate's whole-module test an approved merge into a +milestone G's pull requests are pushed; until it is accepted, the rule below holds as those records have it. ADR 0662 +is withdrawn; G builds ADR 0661. How it is checked: in the gate's whole-module test an approved merge into a repository under a running check is handed at once, and the gate's manifest declares no `turns` and no setting `check-gates-merge`; in the checker's, a check claims at once with no gate state granted to read. @@ -1860,7 +1876,7 @@ later change of a kept data's form, not as a case of this milestone. ## Compositions, wants and the apply -*ADR 0360 §8, §9, ADR 0377, ADR 0429 §4, §6, ADR 0539 §9, §14 to §16, ADR 0547 §2 to §9, ADR 0549, ADR 0555.* +*ADR 0360 §8, §9, ADR 0377, ADR 0429 §4, §6, ADR 0539 §9, §14 to §16, ADR 0546 §5, §6, ADR 0547 §2 to §9, ADR 0549, ADR 0555.* - **Each node composes its own.** For each want `want..` the node agent composes that module for its own node with the composition of `mesh-delivery-sdk` from the manifest by digest the indexer wrote, the module's resolved @@ -2036,6 +2052,18 @@ later change of a kept data's form, not as a case of this milestone. fingerprint, the digest, the phase and the health after the module's start window. A failed apply is loud, retried by the next change of the want or the composition, never by a clock, and fixed forward (ADR 0360 §8, ADR 0539 §9). +- **A put without hold ends itself once the node runs it.** A put the assigner's tool `assigner_put` writes with + `hold` false ends when the node's have runs its fingerprint healthy, and the assigner's rules write the want again + from their next pass (ADR 0546 §5); a held put stays until `assigner_release` (ADR 0546 §6). The assigner hears that + the node runs it as the node-engine seat's `running..` naming the put's fingerprint, through a durable + consumer of its own declared in its `consumes`, the one its composing waits hear too (*Composing waits per node*), + so a put asked while the node was away ends once the node says it runs it; it never reads the node's have across + the seam (ADR 0596 §2). On that event it marks the put ended, says the step as its event `put`, and from then on its + rules own the want; a `running` naming another fingerprint ends nothing. The design's choice under ADR 0546 §5: the + event the node already says is the one fact that ends the put, so a put never pins a want by being forgotten, as + lead-47's puts of a node-engine build did for seven hours on 2026-11-09 (issue 1966), and milestone G's one logged + put of its own indexer ends by itself. Built first in the issue 1966 recovery, kept whole in milestone G. How it is + checked: test 62. - **The bus module is wanted like any module; only a warranted want replaces its server** (ADR 0594, changing ADR 0539 §14 and §15, ADR 0546 §8 and ADR 0565 §7 for the bus module). The assigner writes the bus module's want by the same rules as every module's, and the node agent applies what that want brings (its files, its processes' bus @@ -2640,6 +2668,17 @@ What milestone G's prepare found, and its test: does not claim `oci-artifact-registry`; fetched bytes that differ from the done key's digest are not applied; an artifact over the bus's value limit is fetched whole as an object; with the keeping node away, or the build swept, the want waits and the have says why (whole, builder, build module and node-engine). +61. **No module reads the indexer's `modules`.** The watchman's manifest findings, the status view's `view_reach`, the + forge module's writable repositories and the reads of the holders of `mesh-config`, `mesh-provisioner` and + `mesh-self-check`, of the claude-code module and of the tool runner each answer from the catalog half: after a + merge that adds a module, each names it once `catalog-revision` is said, with no call of the indexer by name; the + indexer's manifest declares no `modules` (each module's existing tests, a row each; live, a search of the catalog's + and mesh-tools' code and manifests finds no `indexer_read_modules` and no view `modules`). +62. **A put without hold ends itself.** A put with `hold` false of a fingerprint the node does not run yet ends on that + node's `running` naming its fingerprint, says the step `put`, and the next pass of the rules writes the want, so a + later build is wanted with no `assigner_release`; a `running` of another fingerprint ends nothing; a held put stays + until released; a put whose `running` was said while the assigner was stopped ends after its restart (whole, + assigner; live, `assigner_puts` after milestone G's put of its own indexer). ## What retires @@ -2961,7 +3000,11 @@ another, and the switch carrying what is owed; the seat `git` covers every forge and the gate, its act verbs granted by the holder's trusted `callers`, the forge's acting tools and its watch of the checker retired, and `merge-pull` judging no check, its record to be accepted before the push; the order forge, bridge, gate with its way back, and the indexer's start without the forge; `module-held`, an error for a failed forge read and -the re-ask of a check that could not run; numbered tests 56 to 60; and the store seat's holder's own build. +the re-ask of a check that could not run; numbered tests 56 to 60; and the store seat's holder's own build. Round 3 +takes in three findings of G's second prepare refresh, as lead-47 ruled (2026-11-09): every other module that read the +indexer's `modules` reads the catalog half in milestone G (*The revision view*, *Reverted*; test 61); a put without +hold ends itself on the node's `running`, built first in the issue 1966 recovery (*Compositions, wants and the apply*; +test 62); and ADR 0662, which decided the same switch as ADR 0661 another way, is withdrawn, so G builds ADR 0661. Left as notes on issue 1921, not in this amendment: a conformance check that a changed layout raises its `form`; the size and retention of restore points and set-aside data; who may call `restore` for bus data and which manifest grants