From b08147e5318db423c625249842a48d17adefddd5 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 03:00:44 +0100 Subject: [PATCH 1/3] Answer the questions of milestone G's final prepare in its part, so develop starts from the design alone The prepare found about a hundred places where G's lines left the builder a choice. Each answer is now a line of G-9 with its question and its check: one default of callers per verb class, so no verb is closed for lack of a list; the seat-definition forms; kept data and restore points; versions; steps and test counting; the readers and the gate's remaining parts. Earlier lines the answers change are amended in place. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- .../47-delivery-from-commit-to-delivered.md | 2 +- .../G-1-pipelines-registration-and-steps.md | 2 +- .../G-2-pipelines-sizes-checks-and-tools.md | 2 +- .../G-4-revision-view-and-steps.md | 13 +- .../47-milestones/G-6-verbs-and-retires.md | 8 +- .../01-to-be/47-milestones/G-7-answers.md | 20 +- .../G-8-findings-heard-as-events.md | 6 +- .../47-milestones/G-9-prepare-answers.md | 250 ++++++++++++++++++ 03-DESIGN/01-to-be/47-milestones/G.md | 6 +- .../51-the-registries-keep-what-is-named.md | 2 +- 10 files changed, 283 insertions(+), 28 deletions(-) create mode 100644 03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md 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 267d5a29..2723d9da 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 @@ -1,7 +1,7 @@ --- layer: to-be status: in-progress -code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-catalog modules/gitea, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, mesh-contracts, hq 00-META/checks] +code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-catalog modules/gitea, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, mesh-contracts, mesh-tools, mesh-networking, hq 00-META/checks] updated: 2026-11-11 decisions: - "ADR 0667" diff --git a/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md index e6dcba40..068a18f7 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md @@ -255,7 +255,7 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l revision the runner says one `group-ended` once every member's modules have ended, and the assigner writes the group's wants only on it: a member's own `pipeline-ended` writes nothing (ADR 0666 §9). - §30 **A failed `optional` step holds nothing.** It is shown in `pipeline-ended`, in the delivery record and in the runner's - `show`; a person may accept it by the runner's verb `accept`, recorded in the hand-act log with who and why. + `show`; the operator may accept it by the runner's verb `accept` (§394), recorded in the hand-act log with who and why. - §31 **A newer commit supersedes an older pipeline of a module whose fingerprint it changed.** On a newer commit of the same watched branch the runner ends a module's older running pipeline as `superseded` only when the newer commit changed that module's build-input fingerprint (ADR 0666 §9); a module the commit leaves as it was finishes its diff --git a/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md b/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md index ecd38119..b1b6cc7d 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md +++ b/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md @@ -117,7 +117,7 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli - §68 **Callers per verb, in the seat's definition.** Each seat definition names, per verb, the callers allowed to call it, in its field `callers` (holder roles, modules, the operator, the healers), which the grants part reads as its one source of caller limits; the runner's verbs are the first (ADR 0666 §20). A verb whose definition names no `callers` - admits only the seat's holder roles and the operator, so a field left out opens nothing. It replaces the holder's + takes the default of its class (§391), so no verb is closed for lack of a list. It replaces the holder's trusted config value `callers` of the seat `git` and the package seats (design 51), which no holder set for most verbs. A format its running reader cannot read, so its reader is delivered first (ADR 0667 §4). - §69 **A step's result from its holder only.** The runner takes a step's result only from the bus account of that step's diff --git a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md index b4cfe0a4..ace14f36 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md @@ -3,7 +3,7 @@ layer: to-be status: in-progress design: 47 milestone: G -updated: 2026-11-10 +updated: 2026-11-11 decisions: - "ADR 0667" - "ADR 0666" @@ -62,8 +62,8 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli indexer declares no state `modules` and serves neither its tool `indexer_read_modules` nor a view of it (*Reverted*, above), 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 + holders of the seats `mesh-config`, `mesh-provisioner` and `mesh-self-check`, the claude-code module, the tool + runner and the node-engine (§421). 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). A reader that misses a `catalog-revision` @@ -266,9 +266,10 @@ and the assignment graph revisions; an entry taken in, built, checked, composed, entry's fingerprint and its node. The gate's delivery record is built from them. The seat's event comes first where the parts follow it through a seat (ADR 0656); a holder's own event stays under its own subject, declared in its own manifest's `streams` and published on `mesh.stream..event.` (ADR 0363 §1, §2). A seat's event is -declared in its definition and its holder's manifest claims the seat; a seat event's name has no dot, since it is read -as a subject's token, and it is kept on the stream `SEAT__`, which the grants part makes with its durable -consumers, keeping it by the age and cap the definition's `keep` names, 90 days unless it names less. **An event a node publishes carries the node in +declared in its definition and its holder's manifest claims the seat; an event whose definition names `keep` has no +dot in its name and is kept on the stream `SEAT__`, which the grants part makes with its durable +consumers, keeping it by the age and cap `keep` names (§396), and an event naming no `keep` stays on its seat's family +stream. **An event a node publishes carries the node in its subject**, and the grants part grants each node-engine's account only its own node's subjects, so one node cannot say another runs a build (ADR 0363 §2); the gate's events are granted to the gate's account alone. diff --git a/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md b/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md index 8e88fddd..e740f369 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md +++ b/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md @@ -3,7 +3,7 @@ layer: to-be status: in-progress design: 47 milestone: G -updated: 2026-11-10 +updated: 2026-11-11 decisions: - "ADR 0667" - "ADR 0666" @@ -106,9 +106,9 @@ parts' manifests declare in `invokes` and `consumes` and what their code calls, | Event of the seat | Says | Heard by (today's event) | |---|---|---| -| `pull.updated`, `pull.merged`, `pull.closed` | a pull request's new head, its merge with the merge commit, its close | the forge bridge, the gate (`gitea.pull.*`) | -| `forge.pull`, `forge.status`, `forge.delete` | the forge's own webhook of a pull request, of a commit status, of a deleted branch | the gate (`forge.pull`, `forge.status`), the forge bridge (`forge.delete`) (`gitea.forge.*`) | -| `repo.writable` | a repository the forge can write again | the gate (`gitea.repo.writable`) | +| `pull-updated`, `pull-merged`, `pull-closed` (§396) | a pull request's new head, its merge with the merge commit, its close | the forge bridge, the gate (`gitea.pull.*`) | +| `forge-pull`, `forge-status`, `forge-delete` | the forge's own webhook of a pull request, of a commit status, of a deleted branch | the gate (`forge.pull`, `forge.status`), the forge bridge (`forge.delete`) (`gitea.forge.*`) | +| `repo-writable` | a repository the forge can write again | the gate (`gitea.repo.writable`) | | `branch-moved` | from milestone G's delivery: a branch's new head, by a merge or an admitted push, from the forge's push webhook | the forge bridge | §311 Each is said on `mesh.seat.git.event.`, declared in the seat's definition, and heard through the hearer's diff --git a/03-DESIGN/01-to-be/47-milestones/G-7-answers.md b/03-DESIGN/01-to-be/47-milestones/G-7-answers.md index 0714bc9f..581395ab 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-7-answers.md +++ b/03-DESIGN/01-to-be/47-milestones/G-7-answers.md @@ -62,7 +62,7 @@ record it follows from, and replaces the builder's own choice where one was made unit step leaves the approval `not asked`; its passing rerun asks it, and once approved the second `pipeline-ended` writes the want. - §326 **A build seat keeps its `steps` answer.** The build module keeps each artifact's detected steps in its state - `steps`, from the template `state`, one key per artifact holding the answer for that artifact's newest build-input + `detected-steps` (§414), from the template `state`, one key per artifact holding the answer for that artifact's newest build-input fingerprint, replaced when a newer fingerprint is detected and by `steps` with `again`; a key whose artifact no longer exists is dropped by `steps` with `drop`, on a person's word, written in the hand-act log. With one key per artifact (about 120) the state needs no aging and no read time. Why: ADR 0666 §25 asks a tool for "the steps @@ -90,7 +90,8 @@ record it follows from, and replaces the builder's own choice where one was made 30 days each `kept` digest the entry names whose `last-read` is past 30 days; at 90 days the passed pipeline the entry names, unless it is its branch's newest. It then moves the sequence; nothing is scanned whole. Each delete writes a line in the runner's journal naming the key or object and its retention. A foundation part's sent store - (`sent-objects`) is aged the same way by its owner at each send, from the sequence of its own sends. Nothing waits on + (`sent-objects`) is aged the same way by its owner at each send, from the sequence of its own sends, which mesh-sdk's + sender keeps in the owner's old `state` section (§410). Nothing waits on a timer, and nothing but the owner deletes. Why: an old section cannot declare an age, and deleting one's own entries is the owner's act, not the removal of a store ADR 0595 §4 holds to a person's word; §57's rule that only the drop tool removes an object holds for a template's `-objects`, while the runner's `step-outputs` are its own old @@ -99,10 +100,10 @@ record it follows from, and replaces the builder's own choice where one was made - §331 **The kept event streams' caps, and when one is full.** On the seat `mesh-pipeline-runner`, each kept 90 days: `pipeline-started` 32 MiB, `pipeline-ended` 192 MiB, `group-ended` 64 MiB, `run-started` 16 MiB, `step-started` and `step-ended` 128 MiB each, `wait-held` and `wait-ended` 32 MiB each; the seat `git`'s `branch-moved` 64 MiB; each - build seat's `step-ended` 128 MiB; `mesh-wants`'s `step-ended` 32 MiB; `mesh-builds`' `package-published` and - `mesh-catalog`'s `registration-changed` 16 MiB each; `package-published` 128 MiB; `version-released` 128 MiB, - `version-delivered` 64 MiB, `toolchain-agreed` 16 MiB, and `versions-filled` 1 MiB with no age limit; all others - 90 days. At about 300 releases a day (a mesh-sdk publish rebuilding about 120 modules), `package-published` of about + build seat's `step-ended` 128 MiB; `mesh-wants`'s `step-ended` 32 MiB; `mesh-catalog`'s `registration-changed` 16 MiB; + `mesh-builds`' `package-published` 128 MiB; `mesh-delivery`'s `owed` 7 days and 64 MiB (§396); `version-released` 128 MiB, + `version-delivered` 64 MiB, `toolchain-agreed` 16 MiB, and `versions-filled` 1 MiB with no age limit; every other kept + event 90 days and 16 MiB (§396). At about 300 releases a day (a mesh-sdk publish rebuilding about 120 modules), `package-published` of about two artifacts each and `version-released` each say about 0.6 MiB a day, about 54 MiB in 90 days, and `version-delivered` about 27 MiB. Why: about 300 pipelines a day of about 6 steps (*The runner's kept data*) say about 1,800 step events a day of about 0.5 KiB, about 80 MiB in 90 days, and about 300 @@ -151,7 +152,8 @@ record it follows from, and replaces the builder's own choice where one was made `persons`, and every other text the names the design gives that verb. Why: ADR 0666 §20 makes the definition the grants part's one source of caller limits, in a form it reads; `invokers`, which ADR 0666 §20's list does not name, is the operator's choice for the verbs whose text said "any caller whose role grants it" (Telegram, 2026-11-11 02:13 - CET: "Any declaring module"), and by the same answer, that a verb open today stays open to any module declaring it, + CET: "Any declaring module"; every verb's default by its class is §391, a holder role and a module written + `seat:` and `module:`, §392), and by the same answer, that a verb open today stays open to any module declaring it, for the fifteen verbs of the Connectivity domain's seats that name no `callers` on main, which §68 would otherwise close to their holders and the operator: `node-hostname`'s `entries`, `add` and `remove`; `node-intrusion-prevention`'s `status`, `banned`, `ban` and `unban`; `node-packet-filter`'s `rules`, `reload` and @@ -175,7 +177,7 @@ record it follows from, and replaces the builder's own choice where one was made above. Why: one source of caller limits (ADR 0666 §20). How it is checked: the generator's test refuses an unknown entry. - §340 **The reader release first.** mesh-sdk's seat-definition reader released before G's check reads `callers` as text - or as a list; G's own reader refuses text. The same release carries mesh-sdk's manifest reader of the new words of + or as a list; G's own reader refuses text; it reads every new form G writes (§409). The same release carries mesh-sdk's manifest reader of the new words of §89 (`version`, a `*` emitter in `consumes`, an observer's finding stream), which the running checker's validator reads before G's manifests use them. Why: readers first (ADR 0667 §4), and every definition is a list from G; it is merged ahead of G's check because the running checker, which makes G's own check (ADR 0667 §2), must read G's definitions, the operator's choice of a @@ -384,7 +386,7 @@ record it follows from, and replaces the builder's own choice where one was made `builder_versions` also answers each reserved version with its artifacts' digests (§369), so a registry holder still on its version before G, which asks `builder_versions`, stores a publish of a reserved version made between the builder's delivery and its own (§381). The builder's state - `versions`, the floor and its tool `builder_floor_again`, the event `numbered`, `builder_versions`, and `tag-asks` are + `versions`, the floor and its tool `builder_floor_again` and `builder_versions` are removed in the first change after the first pipeline after G's delivery has delivered a change end to end, the state through `drop` on a person's word (ADR 0595 §4). Why: numbering reads only the catalog's released versions (§348), and without this every first version under G would start below today's and Go's `@latest` would never move (the design's choice, round 2 of the review by architectural domain, 2026-11-10). diff --git a/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md b/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md index 3daebf3a..d7d90e65 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md +++ b/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md @@ -39,8 +39,8 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1 next statement of §384 covers a lost one), published on `mesh.stream..event..`, the node it runs on in the subject (ADR 0363 §2; §260). `finding-written` is said when a finding is raised or what it says changes, and only then (ADR 0289 §1, §4); `finding-cleared` when the observer no longer observes it. `finding-written` - carries `scope`, `id` and `kind` (the key `..` of ADR 0564 §2), `severity`, `subject`, `evidence`, - ADR 0253's words (`headline`, `explanation`), `since` and `at`; `finding-cleared` carries `scope`, `id`, `kind`, `at` + carries the finding's layout whole, plus `scope`, `id` and `kind` (the key `..` of ADR 0564 §2) and + `since` (§437); `finding-cleared` carries `scope`, `id`, `kind`, `at` and `why`. The observer and the node are the subject's alone: the grants part grants each module's account publish on its own stream's subjects of its own node's segment only, the keeper takes both from the subject, and it refuses an event whose body names another observer or node, said in its journal. mesh-sdk's finding writer (`go/views`' @@ -141,7 +141,7 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1 the catalog's holder stopped it raises and clears from its kept sources' events, raises `view-waits` after five minutes itself, and clears nothing with `module left the node` until the assignment half answers. - §389 **The watchman says a machine's presence as events.** The seat `mesh-watchdogs` gains the events `machine-away` - and `machine-back` (`mesh.seat.mesh-watchdogs.event.machine-away.`, `.machine-back.`, carrying the node, + and `machine-back` (`mesh.seat.mesh-watchdogs.event.machine-away.`, `.machine-back.`, §436, carrying the machine, `at` and since when it was last heard), said by the watchman when its presence key of a machine expires and when the machine is heard again (ADR 0564 §4), declared in the seat's definition and kept 90 days, 16 MiB. The keeper consumes them for `findings-unstated` (no machine away is named, and an ask is said again to a module of a machine diff --git a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md new file mode 100644 index 00000000..1cbb06d6 --- /dev/null +++ b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md @@ -0,0 +1,250 @@ +--- +layer: to-be +status: in-progress +design: 47 +milestone: G +updated: 2026-11-11 +decisions: + - "ADR 0670" + - "ADR 0668" + - "ADR 0667" + - "ADR 0666" + - "ADR 0656" + - "ADR 0636" + - "ADR 0625" + - "ADR 0615" + - "ADR 0596" + - "ADR 0595" + - "ADR 0564" + - "ADR 0363" +--- + +# 47, milestone G: the answers to the questions of G's final prepare + +One file of milestone G's part of [design 47](../47-delivery-from-commit-to-delivered.md); the part opens at +[G.md](G.md). Its design lines are numbered across every file of the part and cited as "design 47 G §n". + +## What G's final prepare found open, answered by this design (2026-11-11) + +*G's final prepare (lead-47, 2026-11-11) collected about a hundred questions from its preparers, each cited here by +its id in that prepare: Q1 to Q19 (mesh-contracts), S1 to S18 (mesh-sdk), Q-H1 to Q-H11 (`mesh-host`), Q-T1 to Q-T8 +(mesh-tools), C1 to C22 (mesh-catalog) and D1 to D19 (mesh-delivery). Each line is the design's own choice within the +records it cites, or the operator's intent already given, or the operator's answer, said as such. Where several +preparers asked one thing, one line answers all. A line that changes an earlier line amends it there; the earlier +line says so.* + +### Who may call a verb + +- §391 **Every verb takes a default of callers by its class.** From the operator's answers of 2026-11-11 (02:13 CET, + "Any declaring module"; 02:47 and 02:56 CET, "As proposed"), a verb's definition names its class in the field + `class`, and a verb whose definition names no `callers` takes its class's default, which the seat-definition reader + applies and the manifest validator says per verb ("`.` takes the default of ``"): a `read`, the + class a verb names none of, takes `invokers`, `persons` and `sessions`, so every verb open today stays open; an + `act` (a new act that changes what the mesh does: registers, sets a policy, watches or unwatches a branch, + recovers) takes `operator` and `sessions`; a `warrant` (a verb that runs on the operator's warrant) takes `operator` + and carries the approval mark; `accept` is the operator's alone (§394). A verb that names `callers` keeps them, so + no verb is closed by §68 for lack of a list. Why: ADR 0666 §20 makes the definition the one source of caller + limits; the operator asked on 2026-11-11 why caller questions kept coming, and answered them as one rule (Q1, S3, + C3, D2's reads, Q18). How it is checked: unit (seat-definition reader), a table test with one row per class, and a + row for a verb with `callers` of its own; unit (manifest validator), the default each verb took is said. +- §392 **A caller entry names its kind of name.** In `callers`, a holder role is written `seat:` and a module + `module:`, beside `operator`, `healers`, `persons`, `sessions`, `invokers` and `holder:@same-node` + (§336), since a name such as `mesh-grants` is both a seat and a module. Why: the design's choice (Q2). How it is + checked: unit (definition reader), a bare name refused, both prefixed forms accepted. +- §393 **The node-engine's eleven verbs name today's callers.** The eleven verbs of the seat `node-engine` that name + no `callers` on main get, in their definition, the callers the node-engine's compiled callers table names for each + on main, written in §392's forms, and that table goes from the node-engine's code: the definition is the one + source (§68). Why: the design's choice (Q-H8). How it is checked: unit (definition reader), each of the eleven names + its callers; the code review finds no callers table in the node-engine. +- §394 **The callers of G's new trusted acts.** `mesh-catalog`'s `register`, `policy`, `watch` and `unwatch`, and + `mesh-delivery`'s `recovery`, are of class `act`: the operator and sessions; `registrations` is a `read`. + `mesh-pipeline-runner`'s `review` is called by sessions, and refused from the change's author (§70); its `accept` by + the operator alone, which amends §30's "a person". `operator-channel`'s `ask-again` is a seat verb, its callers the + operator and the healers (§83, §40). Why: the operator, 2026-11-11 02:56 CET on Telegram, "As proposed" (S4, S10, + C18, D2, D3, D4). How it is checked: whole (indexer, runner, operator-channel), a call from any other caller is + refused by the bus; unit (definition reader), each verb's class and callers. +- §395 **An accepted kind naming no callers keeps today's grant.** `operator-channel`'s kinds `ask`, `cancel` and + `condition` keep the grant they have today, open to every asker, so the runner's approval (§37), the seed ask (§8) + and every other asker are not refused (§338). Why: the operator's intent, a verb open today stays open (Q18). How it + is checked: whole (operator-channel), an asker's `ask` is taken. + +### The forms of a seat's definition + +- §396 **A dot only where no stream is named from the event; `keep`'s form.** An event whose definition names `keep` + has no dot in its name, since its stream `SEAT__` is named from it; an event naming no `keep` stays on + its seat's family stream and may have a dot. `keep` is an object `{max-age-days, max-mib, last-per-subject}`, its age + 90 days and its cap 16 MiB unless it names others (§331). The seat `git`'s events take hyphens: `pull-updated`, + `pull-merged`, `pull-closed`, `forge-pull`, `forge-status`, `forge-delete` and `repo-writable` (§310), and `owed` is + kept on its seat stream 7 days and 64 MiB (§162). This amends §260. Why: the design's choice (Q3, Q4, S5, C1, C2). + How it is checked: unit (definition reader), a dotted event with `keep` refused, one without accepted, `keep`'s + defaults. +- §397 **The forms of `subject`, `acts.on` and `bound`.** `subject` is the words after `mesh.seat..event.` with + `` tokens, `` written out; `acts.on` is one string, `every`, a language, or `kind:image`; `bound` is a + duration such as `30m`. Why: the design's choice (Q5). How it is checked: unit (definition reader), each form + accepted and another refused. +- §398 **The step `place` is `mesh-wants`'.** The step `place` is declared in the definition of the seat `mesh-wants`, + where §260's table has the assigner's placing waits. Why: the design's choice (Q6). How it is checked: the seat's + fixtures. +- §399 **A binding names its objects and its sent store.** The binding of a state, as the seat `mesh-broker` answers + it, gains `objects`, the bus name of its `-objects` (§58), and a module's sent store is a binding entry + `sent-objects` (§59), so a module learns both names from its bindings. Why: the design's choice (Q7). How it is + checked: unit (mesh-broker's contract), a binding with both read. +- §400 **No new verb is optional.** A verb G adds is not `optional`: the order of its holder's delivery is §298's + edges, and a claim refused meanwhile is a gap of the delivery system built within G (§93). Why: the design's choice + (Q9). How it is checked: unit (definition reader), no verb G adds is marked `optional`. +- §401 **The seat `mesh-grants` has no verbs in G.** Its definition carries its rule and its four events only; its + module's tools `grants_waits`, `grants_release`, `grants_callers` and `grants_why_refused` stay its own. Why: the + design's choice (Q12). How it is checked: the seat's fixtures. +- §402 **A placement's `build` is a fingerprint, and `unwatch` waits for the placements.** A placement's `build` names a + fingerprint; `unwatch` refuses while a placement names the branch, naming the placement. Why: the design's choice + (Q13). How it is checked: whole (indexer), `unwatch` of a placed branch refused. +- §403 **A held-back ask.** A held-back ask (§83, design 46 §6) is answered in `asks` with the state `held-back` and the + field `held-since`, and no field `behind`. Why: the design's choice (Q14). How it is checked: the seat's fixtures. +- §404 **The node-engine's events' bodies.** `capabilities-changed` carries the node record's stated capabilities whole + and `at`; `composed` the module, the fingerprint and the composition's digest; `running` with `stopped` carries + `stopped: true` and no fingerprint (§365). Why: the design's choice (Q17). How it is checked: the seat's fixtures. + +### Kept data on the bus, restore points and the reader release + +- §405 **The bus module's restore points and node-backup's verbs.** The seat `mesh-broker` gains `snapshot-kept` and + `restore-kept`, their callers `holder:node-backup@same-node` (§337); the seat `node-backup`'s `now` and `restore` + gain `kept`, `form` and `fingerprint`, and say `ended.` and `restored.`, each keyed by the module, the + kept data, its form and the fingerprint; listing and discarding stay node-backup's `backed-up` and `discard-aside` + (§302). Test 36's whole case lives in `mesh-host`. Why: the design's choice, one answer to three preparers (Q8, S9, + Q-H6, C19's verb names). How it is checked: test 36; a call of `snapshot-kept` from another node's `node-backup` + holder is refused by the bus. +- §406 **A catch-up names its tool and arguments.** A restore point records the catch-up tool and its arguments whole + (§299), and the restored manifest grants that tool to `holder:node-engine@same-node`. Why: the design's choice (Q-H7). + How it is checked: whole (node-engine), a restore runs its recorded catch-up. +- §407 **The object store package.** mesh-sdk's object store package is `go/stateobjects`; it also takes a foundation + part's old `objects` section (§58, §346). A reply or event over the limit is made an object by that package through + §345's put session, and read back through the same session form for a get; the call that reads a sent object is + `mesh/objects.sent-get`, under the existing capability (§347). A foundation part's bundle is bound to its old + `objects` section as its states are (§176, §194). Why: the design's choice (S14, D17, Q-T3, S13, Q-T4, Q-T5). How it + is checked: unit (`go/stateobjects`), an old section and a template store each take a large value; whole (tool + runner), a large reply read back. +- §408 **The ledger's calls.** The ledger's fill and removal calls are in mesh-sdk's `buscalls`, under the existing + `ledger` calls (§155, §159, §181); no capability word `ledger-fill` is added. Why: the design's choice (S15, Q-T6). + How it is checked: the code review. +- §409 **The reader release reads every new form G writes.** The reader release of §340 reads every new definition + form and manifest word G writes: `callers`, `class`, `keep`, `subject`, `acts`, the step `pipeline`, `on` + `kind:image`, `version`, the `*` emitter, an observer's finding stream, and an artifact's `needs`; `check` stays + beside `pipeline` until the checker is removed (§97, §203). Why: readers first (ADR 0667 §4; S2, S18). How it is + checked: unit (the release's reader), each form read. +- §410 **A foundation part's sent store keeps its send sequence.** mesh-sdk's sender keeps the sequence of a foundation + part's sends in the owner's old `state` section and ages `sent-objects` from it at each send (§330). Why: an + `objects` section has no sequence (S7). How it is checked: unit (sender), a send past 7 days ages the oldest. + +### Versions + +- §411 **`version` replaces the old field, and `series` goes.** Every manifest's top-level `version` takes the + `MAJOR.MINOR` of §368 in the same change, replacing today's `"1"`, and each artifact's `series` goes, refused by the + manifest validator; a contracts module's version is `0.1` unless §372's fill gives higher. Why: one version per + module (§52, §374; Q15, S1, Q-H3, D14). How it is checked: unit (manifest validator), `series` refused. +- §412 **The first fill's sources.** §372's fill reads, per module, the packages its catalog entry names in their + ecosystems (the Go module path, the npm name); where the builder holds no version of a package, the forge's tags of + its repository (`go/vMAJOR.MINOR.PATCH`) are the floor. Why: the live builder answers none for mesh-sdk while the + forge holds `go/v0.1.14` (S17, C9). How it is checked: whole (indexer), a module with tags and no builder versions + fills from the tags. +- §413 **`tag-asks` and `version.numbered` go at G's delivery.** The builder's `tag-asks` and its event + `version.numbered` are removed at G's delivery, as §373 has for the tagged versions; the build modules consume + `version.numbered` no more from G. This amends §372. Why: the design's choice (D19). How it is checked: the + catalog's validation at G's heads finds no `consumes` of `version.numbered`. + +### Steps, tests and pipelines + +- §414 **The build seats' state is `detected-steps`.** The state §326 names `steps` is `detected-steps`, apart from + today's step keys `steps`. This amends §326. Why: the design's choice (C5, D13). How it is checked: whole (Go build + module), as §326. +- §415 **Kinds on the stream `check`, and a recovery's steps.** A step ask is the kind `check.step`, a run on request's + `check.run`; a recovery's steps are `delivery.step`, which the runner may publish (§86). Why: the design's choice + (D5, C6). How it is checked: whole (runner, Go build module), a recovery's step is taken from `delivery` first. +- §416 **A step ask carries the kept results.** The runner's step ask carries the kept results by package digest + (§25), so a build seat runs only the packages without one. Why: the design's choice (C7). How it is checked: whole + (Go build module), a carried package is not run. +- §417 **Go's lint is gofmt and vet.** Go's lint step runs gofmt and go vet, in the lint step only (§328). Why: the + design's choice (C8). How it is checked: whole (Go build module), a vet failure fails lint and no unit step. +- §418 **The repository checks run as a step.** Each repository's own checks, which the checker runs today, run as a + pipeline step of its build seat from G's delivery. Why: the checker goes (C20). How it is checked: whole (runner), + a failing repository check fails its step. +- §419 **How tests are counted.** A test is a top-level Go test function or a TypeScript `test(` call; an existing + module ends G with no more tests than it starts with, and the new runner within 50 integration and 500 unit tests; a + module over the budget at its start is named in the pipeline's end. Why: the test budget per module (S16, D6). How + it is checked: `pipeline-ended`'s counts. +- §420 **A run on request's key, and the step-run package.** A run on request is keyed by the run's id under its named + branch (§54, §64, §85); the step-run code is the delivery SDK's package `sdk/steprun`, and the runner's + client sits beside the other seats' clients; the runner's kept data layouts are the seat's `states` (§27, §306). Why: + the design's choice (D16, D8, D10). How it is checked: whole (runner), two runs of one commit are two pipelines. + +### Readers, branches and the node-engine + +- §421 **The node-engine reads the catalog half for its branch.** The node-engine joins §196's readers: it reads the + manifests and verdicts of the modules it composes from the catalog half, of the branch each module's placement + names, and the parts by digest from its want (§379); its reads of the indexer's and builder's states go. The tool + runner follows every watched branch's newest `catalog-revision`, as §365. Why: ADR 0596 §2 (Q-H1, Q-H2, Q-T8). How it + is checked: the node-engine's manifest reads no other module's state; test 61. +- §422 **The node-engine's first-view tools are seat verbs.** The node-engine serves its view's two tools as seat verbs + of `node-engine`, beside its seat-list verbs, since it serves no module tools. Why: the design's choice (Q-H4). How + it is checked: the seat's fixtures. +- §423 **A kept-build wait says the existing words.** A have waiting for a kept build (§271) says the existing phase and + words, with no new field. Why: the design's choice (Q-H10). How it is checked: whole (node-engine). +- §424 **Each process's own build, and each bundle's.** A process says `own build unknown` in its + `_first_views` (§205); each tools bundle's composed environment carries its module's fingerprint. Why: the + design's choice (S12, Q-T7). How it is checked: whole (tool runner), a bundle reads its fingerprint. +- §425 **A kept call asks again what its asker names.** An asker passes the kept-call form the ask's key and the event + that replaces it, and the form asks again only while that key is open and no replacing event was heard (§351). Why: + the design's choice (S11). How it is checked: unit (kept-call form). +- §426 **The tool runner keeps no waits list.** §74's session waits use `mesh_wait` on any event (ADR 0670), and + `gitea.forge.status` goes (§133). Why: ADR 0670 (Q-T2). How it is checked: the tool runner's manifest has no waits. + +### The gate, the forge and the move + +- §427 **The contracts and SDK folders move, importers in the group.** The delivery repository's contracts and SDK + move to `modules/mesh-delivery-contracts` and `modules/mesh-delivery-sdk`, their Go module paths and TypeScript names + renamed to match, and every importer moves in the same group. Why: design it as it should be (C4, D1). How it is + checked: the group's check builds every importer. +- §428 **The fixed names G removes.** Each name is read from the registrations, the catalog half or the seat list + (§7): in mesh-delivery, module names of the delivery parts, the forge module, the build modules, `mesh-grants`, + `mesh-config`, `mesh-vault`, `mesh-wireguard`, the tool runner and the bus module, and the branch `main`; in + mesh-catalog, the gate's merge branch, the SDK's repository and the teller's, view's and forge bridge's module + names, the forge module's base branch and the indexer's name and tool, and the build modules' indexer tool; in + `mesh-host`, the node-engine's own module name in its guard, compose and bootstrap; in mesh-sdk, the node-engine's + names (§364); in mesh-tools, the assigner's first views by name; in mesh-networking, `mesh-wireguard` and + `mesh-provisioner`. Why: the design's choice (Q-H9, C10, D7). How it is checked: the code review (§7). +- §429 **Lines "until G's delivery".** The new gate builds the forms from G's delivery and the switch (§156, §169) + alone; what holds only until G's delivery is not rebuilt. Why: the design's choice (C11). How it is checked: whole + (gate), test 36's gate half. +- §430 **The gate's sources before the first registrations.** The gate keeps `source.` per repository and + watched branch, the branch escaped as §73, following the registrations, and writes `source.` for + every repository from its start, before the first registrations (§15, §95). Why: the design's choice (C12, D18). + How it is checked: whole (gate), `source` answers before any registration. +- §431 **The fate of the gate's other parts.** From G's delivery the gate's `asks` go with the Approve per merge; + `deliveries`, `show`, `groups` and `stalled` are answered from the delivery records; `checks` and `settle` go with the + merge states, and the five verbs of release 6 leave the definition; the events `group` and `merged` go, their readers + moving to the seat `git`'s events, while `transition` stays; the reads of the teller's answers and the view's reach + are by their events, and of the checker's verdicts go with it. Readers of the gate's `source` move to the verb + `source` and `source-moved`, and the assigner reads no `merges`. Why: the design's choice (C13, C14, D9, D11). How it + is checked: whole (gate), each verb served or not as named. +- §432 **The edges a `needs` names.** An artifact's `needs` names artifact references `:` of the + catalog graph's edges (§95, §121). Why: the design's choice (C21). How it is checked: unit (manifest validator). +- §433 **The bus module reads the catalog half.** The bus module's `consumes` and its call of `indexer_bus_state` are + replaced by its view of the catalog half (§344). Why: ADR 0596 §2 (C22). How it is checked: its manifest. +- §434 **Findings name their owner and whom they wait on, and the keeper reads by events.** A finding of §33, §8 and + §75 carries `owner` and `waiting-on`; the keeper's other reads are by events or verbs, and no homes rows are added. + Hand-written finding code in Go moves to mesh-sdk's `FindingWriter`. Why: the design's choice (C16, C17, C15's Go + half). How it is checked: the code review; the keeper's manifest reads nothing. +- §435 **`compose-candidate` goes with the checker.** The node-engine's verb `compose-candidate`, whose caller is the + checker, is kept in G and removed in the change that removes the checker (§97), with the check's candidates. Why: + the design's choice (Q16, Q-H1's candidates). How it is checked: the seat's fixtures at G's heads keep it. +- §436 **A presence event names the machine, not its publisher.** `machine-away` and `machine-back` carry the machine + as a subject part named ``, which the grants part does not bind to the publisher's node, since the + watchman says them for another machine. This amends §389. Why: `` in a subject is the publishing node (§260; + S8). How it is checked: whole (watchman), the event for an away machine is published by the watchman's account. +- §437 **`finding-written` carries the finding's layout whole.** `finding-written` and each entry of `findings-stated` + carry the finding's layout as the state `findings` holds it whole (its `summary`, `source`, `observer`, `actions`, + `needs`, `resolver`, `ref` and `run` among it), plus `scope`, `id` and `since`, so a condition built from the event + alone loses nothing. This amends §383. Why: the design's choice (Q19). How it is checked: unit (writer), the event's + body holds every field of the key. +- §438 **The record names every repository G builds.** Design 47's milestones row and frontmatter `code:` name + mesh-tools and mesh-networking, and design 51's line on what a node-engine hears says it consumes the node-engine + seat's `running` (§199). Why: the design's choice (Q-T1, Q-H11). How it is checked: the index test. diff --git a/03-DESIGN/01-to-be/47-milestones/G.md b/03-DESIGN/01-to-be/47-milestones/G.md index de83d5c5..f1adc023 100644 --- a/03-DESIGN/01-to-be/47-milestones/G.md +++ b/03-DESIGN/01-to-be/47-milestones/G.md @@ -5,6 +5,7 @@ design: 47 milestone: G updated: 2026-11-11 decisions: + - "ADR 0670" - "ADR 0668" - "ADR 0667" - "ADR 0666" @@ -75,7 +76,7 @@ file on 2026-11-10, and is cited as "design 47 G §n". A sentence that holds a d stayed in the main file, and G builds what it says from G's delivery. A section named in italics is in this part, or, when it is not here, in the main file. -The part is eight files, each read whole, its design lines numbered across them: +The part is nine files, each read whole, its design lines numbered across them: - [G-1-pipelines-registration-and-steps](G-1-pipelines-registration-and-steps.md): pipelines per module: registration, watched branches, steps and policy, what holds a delivery, approval, groups, dependencies, a publish. - [G-2-pipelines-sizes-checks-and-tools](G-2-pipelines-sizes-checks-and-tools.md): pipelines per module: any size, the pipeline makes the check, who may say what, health, recovery, tools, kept data, how G itself is delivered, the choices under ADR 0666 and ADR 0667. @@ -84,4 +85,5 @@ The part is eight files, each read whole, its design lines numbered across them: - [G-5-acting-parts-check-and-kept-data](G-5-acting-parts-check-and-kept-data.md): the acting parts, the removed hold, the check on the change's own acting parts, after the merge, taken in, and kept data on the bus. - [G-6-verbs-and-retires](G-6-verbs-and-retires.md): the verbs G adds and what retires. - [G-7-answers](G-7-answers.md): the answers to the builders', the reviewers' and the operator's questions (§322 to §382). -- [G-8-findings-heard-as-events](G-8-findings-heard-as-events.md): the operator's answers of 2026-11-11, findings heard as events (§383 on). +- [G-8-findings-heard-as-events](G-8-findings-heard-as-events.md): the operator's answers of 2026-11-11, findings heard as events (§383 to §390). +- [G-9-prepare-answers](G-9-prepare-answers.md): the answers to the questions of G's final prepare (§391 on). diff --git a/03-DESIGN/01-to-be/51-the-registries-keep-what-is-named.md b/03-DESIGN/01-to-be/51-the-registries-keep-what-is-named.md index 0daf1a1c..9c15ff5c 100644 --- a/03-DESIGN/01-to-be/51-the-registries-keep-what-is-named.md +++ b/03-DESIGN/01-to-be/51-the-registries-keep-what-is-named.md @@ -239,7 +239,7 @@ the verb. matches `settled` by the holder its declaration names. A change of the seat's holder composes the declaration again, so the name it carries is the holder of now. The seat and the holder are not part of what a container is (they are not in its digest), so a declaration composed again for them replaces no container. **The seam that changes is the grants part's list of what a node-engine - hears** (`NodeAgentHears`; the node-engine declares no `consumes` of its own): it gains one entry, the status + hears** (`NodeAgentHears`; from design 47's milestone G the node-engine also declares its `consumes` of the node-engine seat's `running`, design 47 G §199, §438): it gains one entry, the status view's `settled` family, which the node-engine filters for the holder of the seat its failed image names. **At its own start** the node-engine also applies once more every have that failed naming an image of a store, so a restart or an absence across the swap misses nothing. A module already being applied is not applied a second time; a retry -- 2.54.0 From 30b29a58a4325416bdf9a460ef973127b35b38fa Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 03:04:05 +0100 Subject: [PATCH 2/3] Have only the indexer read manifests, and settle the four prepare items that contradicted each other The operator's rule is that the indexer alone uses manifests to build the catalog graph, so every other part's read of a manifest becomes a read of the catalog half. Lead-47's rulings settle the finding layout as a seat contract with generated writers, process-builds as a node-engine seat verb, a grants-for read on mesh-grants for widens, and aside on node-backup. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- 00-META/glossary.md | 3 +- .../47-delivery-from-commit-to-delivered.md | 13 +++--- .../G-1-pipelines-registration-and-steps.md | 2 +- .../G-2-pipelines-sizes-checks-and-tools.md | 10 ++-- .../G-4-revision-view-and-steps.md | 14 +++--- .../47-milestones/G-6-verbs-and-retires.md | 2 +- .../G-8-findings-heard-as-events.md | 8 ++-- .../47-milestones/G-9-prepare-answers.md | 46 +++++++++++++++---- 8 files changed, 64 insertions(+), 34 deletions(-) diff --git a/00-META/glossary.md b/00-META/glossary.md index c14e2624..dcd083b3 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -596,7 +596,8 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel change, are triggers that rebuild, never waits; a verb edge on a cycle is left out (ADR 0603 §1, §2, ADR 0614); from research 085's milestone an acting part's edge is a wait within its step (ADR 0656). From milestone G's delivery it is kept once per **watched branch**, and its edges run between **artifact references**, of six kinds, the reverse order holding when something goes away (ADR 0666 §6, §14). - Nothing stores the order. Not the **assignment graph**, computed from it. + Nothing stores the order. Only the indexer reads the manifests; every other part reads the catalog graph (the operator, + 2026-11-11; design 47 G §442). Not the **assignment graph**, computed from it. *Not:* ~~build graph~~ - **assignment graph** — the module versions placed on nodes at one revision, with the edges between versions that its inputs give: provisioning, contribution, and the acting parts' versions that are to act on each entry. The 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 2723d9da..6f44c187 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 @@ -273,7 +273,7 @@ source revision is derived from the keys: every **want** equals its module's **f delivery it runs the composition step, and writes a want only from a revision whose every `required` pipeline step passed, on the watched branch a placement chose (ADR 0666 §9, §17). - **The node agent**, the node-engine's own process, follows its node's wants, **composes each wanted module for - its own node** with the composition of `mesh-delivery-sdk` from the manifest by digest, the module's resolved values from + its own node** with the composition of `mesh-delivery-sdk` from the catalog graph's entry of the build (from milestone G; before it, the manifest by digest), the module's resolved values from mesh-config, its secrets and bus credential asked of the vault sealed to the node's key, its licences and what its providers contribute, applies one module at a time and only what differs from what runs, backs up a data module first, and writes its haves with the fingerprint and the digest of the composition it runs (ADR 0547 §2, @@ -724,7 +724,7 @@ From its delivery, a check is this: issue 482). A trunk move asks no check but a carry, which runs only what the move changed (ADR 0548 §5). - **The composition check is the assigner's.** Whether the machines still compose with a change is checked by the part that owns what each machine should run. The assigner reads the modules, fingerprints and manifests - the indexer holds and the builds the builder holds; the machines, their roles, assignments and settings, and + the indexer holds (from milestone G, the catalog half alone: design 47 G §442) and the builds the builder holds; the machines, their roles, assignments and settings, and the grants and credentials it reads from the grants part's state and the vault's accounts, and the rest from the buckets it names in its manifest's `reads` (ADR 0237 §1, ADR 0408 §3, ADR 0547 §4). It clones no repository but at most the change's own, and @@ -1060,7 +1060,7 @@ backup holder backs up nothing, and the have says so. *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 + its own node with the composition of `mesh-delivery-sdk` from the catalog graph's entry of the build, from milestone G (before it, the manifest by digest the indexer wrote), the module's resolved values read from mesh-config's resolved state filtered to its node, its secrets and bus credential asked of the vault sealed to the node's key (ADR 0349 §11), its licences, and what its providers contribute; and the node's own composition (adoption, firewall openings, accounts, the resolver, identities and groups) from the same @@ -1074,8 +1074,9 @@ backup holder backs up nothing, and the have says so. assigner's credential alone on an approved proposal and said by `assignments-changed` (ADR 0567, ADR 0641); - **the node records**, each in its node's own have key `.node`, written by that node alone and heard as the key's change (ADR 0555 §3); - - **the manifests**, the indexer's `modules.` and its manifests by digest, or the digest the composing - node's want names where it runs another build; the private network's manifest is its holder `mesh-wireguard`'s + - **the manifests**, until milestone G the indexer's `modules.` and its manifests by digest, or the digest the composing + node's want names where it runs another build; from milestone G the catalog graph's entries of the catalog half, + the indexer being the only part that reads a manifest (design 47 G §442); the private network's manifest is its holder `mesh-wireguard`'s own (ADR 0636 §4); - **the config values**, mesh-config's resolved state, the composing node's slice alone for a node agent; a module in the settings form (its manifest declares no config, so mesh-config holds none for it) has its values in the @@ -1699,7 +1700,7 @@ Each change ADR 0656 makes in an earlier record, and its test: and act once the view is back, clearing it; the node-engine waits only for the catalog half; a candidate's heads are read by the indexer's candidate pass and by no running part (whole). 48. **A process reports its handed build** (ADR 0639 §7). A part started while its node's want differs from what runs - reports the build it was started with, and `node_process_builds` reads it (whole, node-engine). + reports the build it was started with, and the node-engine seat's verb `process-builds` reads it (whole, node-engine). 49. **The forge bridge reads a group from the gate's verb** (ADR 0633 §4, §5). The forge bridge sets the group on each merged message and publishes a group's end again from the seat `mesh-delivery`'s verb `groups`, and its account holds no read of the gate's `merges` state, so a read of it is refused (whole, forge bridge). diff --git a/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md index 068a18f7..ee12ec53 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md @@ -372,7 +372,7 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l program's cycle rule goes with the checker. - §50 **A format's reader first.** A format a running reader cannot read is preceded by its reader, an edge of kind 4 on every watched branch (ADR 0666 §14): the indexer's manifest validator for a new field of a seat definition or a - manifest, and on each node the node-engine that reads a manifest's new fields before any manifest that writes them + manifest, and on each node the node-engine that reads a catalog graph entry's new fields before any manifest that writes them (ADR 0667 §4). - §51 **How it is checked.** Unit (indexer's graph): a chain per artifact where modules would cycle; two programs needing each other's new verb are one step; two artifacts each needing the other's new package to build are refused, naming diff --git a/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md b/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md index b1b6cc7d..da1581bb 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md +++ b/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md @@ -55,9 +55,9 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli event, read within its call's bound or its consumer's lag, so its expiry is not a removal of kept data that ADR 0595 §4 holds to a person's word (the design's choice; 7 days is a guess at the longest a consumer lags, read from the fill tools once G runs). A full sent store is the bus module's `full` and its condition (ADR 0595 §6), and the sender - then refuses the large reply or event loudly, naming the store. The grants part derives from the manifests a standing grant to read them: the + then refuses the large reply or event loudly, naming the store. The grants part derives from the catalog graph (§442), never from a manifest, a standing grant to read them: the callers its seat definition names for the verbs it serves, and the consumers whose `consumes` declare its events; - no other module may read them (ADR 0666 §16). The grant follows the manifests, so it is written when they change, + no other module may read them (ADR 0666 §16). The grant follows the catalog graph, so it is written at each `catalog-revision` that changes it, never per object. A consumer's reader of the form is delivered before its producer writes it, an edge of kind 4. - §60 **Its tools come with the package.** The package serves each module that imports it `_state_objects` (the @@ -129,7 +129,7 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli registration*; issue 1966, note 157). - §71 **A widening is said, never refused.** A change that alters any part serving a step (the runner, step detection, the lint rule, a build seat's test runner, the composer), or widens an acting rule, a grant or a credential, says so in - its `pipeline-ended`, its field `widens` naming each. The running runner computes it, from the sources of the change + its `pipeline-ended`, its field `widens` naming each. The running runner computes it, the serving parts from the seat list by fingerprint and the grants through the seat `mesh-grants`' verb `grants-for` (§441), from the sources of the change against those of the watched branch, never the runner built from the change, so a change cannot hide its own widening; nothing refuses it for that (ADR 0666 §23, the operator, 2026-11-10). The teller passes `widens` on to every channel, as it does `recovery-merged`. This is what replaces ADR 0656 §8's naming in the Approve ask. @@ -275,7 +275,7 @@ step keys and the builder's build log, against the checker's last week (test 99) them; the manifest validator for the manifests' new words (`version`, §368; a `*` emitter in `consumes`, §386; the finding stream an observer declares, §383, §387) and the grants part that makes a `*` entry's durable consumers (§386), before the keeper's or any observer's manifest using them; on each node the node-engine that reads `form` - and `catch-up` before any manifest writing them. The running checker's validator makes G's own check, so the reading + and `catch-up` from the catalog graph before any manifest writing them. The manifest validator the running checker asks for G's own check is the indexer's, so the reading of these words goes in the reader release of §340, whether or not that validator already takes one of them. - §90 **The stream maker first** (ADR 0667 §5): the grants part, which makes each kept seat stream and its durable consumers, before the parts that hear a kept stream. @@ -341,7 +341,7 @@ step keys and the builder's build log, against the checker's last week (test 99) | §121 The six kinds derived from existing words, `needs` per artifact only where nothing says it | one form of each fact (ADR 0656 §6); the catalog entry's `needs` already exists from G | | §122 The cycle rule in the indexer's graph | the graph is the indexer's, and the checking program goes with the checker | | §123 The builder's seat `mesh-builds` and its event `package-published` | the record has the builder say the publication as an event of its seat (ADR 0666 §15); its waits move only when a later change gives the seat its verbs | -| §124 Each state's object store `-objects` through mesh-sdk's small package, sent objects readable by a standing grant derived from the manifests, and the package's two tools | one object store per state, granted to its owner; the sender's declared callers and consumers read what it sends (ADR 0666 §16); only its users import it, so nothing else is rebuilt | +| §124 Each state's object store `-objects` through mesh-sdk's small package, sent objects readable by a standing grant derived from the catalog graph, and the package's two tools | one object store per state, granted to its owner; the sender's declared callers and consumers read what it sends (ADR 0666 §16); only its users import it, so nothing else is rebuilt | | §125 The `run` ask published by the runner's account and the indexer's; the verb `run` called by the sessions and the operator only | the steps and the validation run code from the change, in the sandbox only, and each asker reads only its own step keys (ADR 0363 §2); a run publishes tagged packages, so nothing else may ask one | | §126 The checker's step `check` becomes `pipeline`; `kept` starts empty | the runner is an acting part in the checker's place (ADR 0666 §19); a step's result is taken only from its seat holder (ADR 0666 §21), so no verdict of the checker's is taken in, at the cost of one round of every module's tests | | §127 The field `callers` in a seat definition replaces the holders' trusted `callers`, a missing field admitting the holder roles and the operator only | the record makes the definition the grants part's one source (ADR 0666 §20); a field left out must open nothing | diff --git a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md index ace14f36..08069af1 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md @@ -105,8 +105,8 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli indexer's whole-module test, started with a definition on a contracts trunk that no event announced, the first manifest claiming that seat is judged with it. - §199 **Who holds a seat is applied by one rule, from what each node runs.** The node-engine and the grants part decide a - seat's pass by mesh-sdk's `SeatsToPassOn` (ADR 0660 §3), reading the manifest of the build each assignment runs - (ADR 0660 §2). What each node runs is heard, never asked: each part keeps it from the node-engine seat's events + seat's pass by mesh-sdk's `SeatsToPassOn` (ADR 0660 §3), reading the catalog graph's entry of the build each assignment + runs, never a manifest (ADR 0660 §2; §442). What each node runs is heard, never asked: each part keeps it from the node-engine seat's events `running..` (*What each step says*), through a durable consumer of its own declared in its `consumes`, so a pass is decided with no call to a node that may be away. The seat's stream keeps the last message per subject with no age limit, so the last `running` of every module on every node stays on it however long ago it was said, @@ -115,7 +115,7 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli digest of the build's manifest, which is the indexer's manifest of that build (ADR 0660 §2's "the indexer's manifest of it"), read by digest from the catalog half; the builder's done key is not needed, since the event names the digest it would give. A node that has said no `running` for a module since the part's consumer began counts by - the trunk's manifest, as ADR 0660 §2 has it where the running build cannot be read, and both parts apply that same + the catalog graph's entry of the module on its placement's branch, as ADR 0660 §2 has it where the running build cannot be read, and both parts apply that same fallback in the one function (ADR 0660 §3). Never another node's have key, its want or the assignment half (ADR 0596 §2; *Each part acts on its own entries*). The design's choice under ADR 0660 §2: the node that runs a build says what it runs, and an event kept by a durable consumer answers when that node is away. How it is checked: test 56. @@ -241,11 +241,11 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli | §242 An Approve given held while its heads stand (issue 1972) | the operator approved those heads; a check of them asked again changes nothing they approved (ADR 0441 §1, ADR 0548 §8) | | §243 The milestone events on a subject of their own | a waiter on one member's pull request otherwise wakes on every member's | | §244 The issue tracker's link kinds to a decision and a research effort, and the knowledge base's link from a decision to its milestone | the trace from research to the running build is then links all the way, with no text match (research 085, Findings 7; ADR 0493 §4) | -| §245 The view's state read and asked again by mesh-sdk's `go/views` tools `_first_views` and `_first_view_again`, which gain the revision a part holds and what it waits for; the typed first view and the following of each half in the seats' client packages `meshcatalogclient` and `meshwantsclient`, built on `go/views`; the finding `view-waits` after five minutes; and `node_process_builds` | every part's view and every process's own build is read and steered by a tool; `go/views` already follows an owner's events durably and serves those two tools, so a second follower or a second pair of tools would be two forms of one thing; a view tool typed by the two seats would make mesh-sdk import contracts (ADR 0635 §4), so the typed half sits in the seats' client packages (ADR 0625 §4); a part waiting for the view is raised on the bound the seat list's readers keep | +| §245 The view's state read and asked again by mesh-sdk's `go/views` tools `_first_views` and `_first_view_again`, which gain the revision a part holds and what it waits for; the typed first view and the following of each half in the seats' client packages `meshcatalogclient` and `meshwantsclient`, built on `go/views`; the finding `view-waits` after five minutes; and the node-engine seat's verb `process-builds` (§440) | every part's view and every process's own build is read and steered by a tool; `go/views` already follows an owner's events durably and serves those two tools, so a second follower or a second pair of tools would be two forms of one thing; a view tool typed by the two seats would make mesh-sdk import contracts (ADR 0635 §4), so the typed half sits in the seats' client packages (ADR 0625 §4); a part waiting for the view is raised on the bound the seat list's readers keep | | §246 The seat list's reader and its two tools wired once by mesh-sdk's runtime | ADR 0636 §7 puts them in the runtime bundle; four hand-wired copies would each learn `acts` apart | | §247 The trunk's heads from the catalog half, and nothing read of the gate by the checker | ADR 0596 §2; with the hold and turns removed nothing of the gate is left for the checker to read | | §248 The indexer reads every contracts trunk's definitions at its start, before it judges | a definition merged while it was down is never judged against a list that lacks it (ADR 0636 §1) | -| §249 Another node's running build kept from the node-engine seat's `running` events by a durable consumer, the event carrying the fingerprint and the manifest's digest, the trunk's manifest for a node that said nothing | ADR 0660 §2 reads the manifest of the build each node runs; an event kept by a durable consumer answers while a node is away, where a call would wait on it; one fallback in the one function keeps the two parts agreed (ADR 0660 §3) | +| §249 Another node's running build kept from the node-engine seat's `running` events by a durable consumer, the event carrying the fingerprint and the manifest's digest, the catalog graph's entry for a node that said nothing | ADR 0660 §2 reads the manifest of the build each node runs; an event kept by a durable consumer answers while a node is away, where a call would wait on it; one fallback in the one function keeps the two parts agreed (ADR 0660 §3) | | §250 What the gate and the checker owe the forge said as the event `owed` per repository and pull request, each act safe to repeat at the forge, each outcome said as `owed.ended` and recorded, an unanswered act said again at the gate's start and stalled after 15 minutes | ADR 0596 §1, §2 end the watches of the gate's and the checker's keys; an act safe to repeat cannot be lost between the act and its record, where an id recorded first could; an outcome said and recorded leaves no act unseen | | §251 A merge made at the forge opens a `forge-made` delivery record | its trace and outcomes are kept like every delivery's, and no later merge waits behind a merge the gate never heard | | §252 Every delivery part and the gate reach the forge only through the seat `git`'s verbs and events, the act verbs granted by the holder's trusted `callers` to the forge bridge alone, a failed read answered as an error | the delivery parts name no other module (ADR 0656 §1, acceptance test 27); the forge's answers are typed in the seat's contract instead of guessed in each caller; the bridge stays the one part that acts on the forge; an error read as an empty answer would hide a forge down | @@ -319,8 +319,8 @@ what it heard and how far it is behind, and `_first_view_again`, granted read the view again now. `go/views` stays seat-neutral, naming no seat and no seat's type (ADR 0635 §4); the typed first view of each half and the following of its events are the seats' client packages, `meshcatalogclient` for `mesh-catalog` and `meshwantsclient` for `mesh-wants`, each built on `go/views` (ADR 0625 §4), so no part follows the -view by a follower of its own. A tool -of the node-engine, `node_process_builds`, reads the build each process was started with. The tools answer the four +view by a follower of its own. The node-engine's seat +verb `process-builds` (§440) reads the build each process was started with. The tools answer the four lines every module's tools answer (design 26), so that every state these parts keep is read and every act they do is steered by a tool. diff --git a/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md b/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md index e740f369..8c9d0f91 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md +++ b/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md @@ -77,7 +77,7 @@ each step says*. §309 **The seat `node-engine`**'s event `running..` carries, from research 085's milestone, the module, its fingerprint and the digest of its build's manifest, so the node-engine of another node and the grants part decide a -seat's pass from it (ADR 0660 §2; *Who holds a seat is applied by one rule*). No verb is added. +seat's pass from the catalog graph's entry of that build (ADR 0660 §2; *Who holds a seat is applied by one rule*). No verb is added. §310 **The seat `git`.** The seat `git` (design 26, *The git seat*), of the Delivery domain, defined in `mesh-delivery-contracts`, holds no verb today, and the delivery parts and the gate reach the forge by naming the forge diff --git a/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md b/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md index d7d90e65..e76ea41b 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md +++ b/03-DESIGN/01-to-be/47-milestones/G-8-findings-heard-as-events.md @@ -43,8 +43,7 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1 `since` (§437); `finding-cleared` carries `scope`, `id`, `kind`, `at` and `why`. The observer and the node are the subject's alone: the grants part grants each module's account publish on its own stream's subjects of its own node's segment only, the keeper takes both from the subject, and it refuses - an event whose body names another observer or node, said in its journal. mesh-sdk's finding writer (`go/views`' - `FindingWriter`) says them for every part, after the key it writes in the part's own state `findings`, which stays + an event whose body names another observer or node, said in its journal. The writer generated from the seat `mesh-conditions`' definition (§439) says them for every part, after the key it writes in the part's own state `findings`, which stays the owner's and is read only by the owner's read tool; a publish the bus does not acknowledge is sent again for one minute, then written in the part's journal as an error naming the finding, and the next statement covers it. The keeper takes a finding only from a source of its own list (§388) and raises or changes a condition on @@ -102,9 +101,8 @@ record says so in its Why. Round 3 of the review by architectural domain (2026-1 `*.` takes the event `` from every module whose manifest declares it, and is the one generic form for hearing an event that many modules say; the keeper's `*.finding-written`, `*.finding-cleared` and `*.findings-stated` are the first. The manifest validator takes `*` only as the whole emitter, and only before an - event that a seat's definition or a contract in mesh-sdk defines, with its fields (for the finding events, mesh-sdk's - finding writer); it refuses `*` before any other event, `*.>`, and `*` in part of an emitter's name. The grants part, - from the manifests as it derives every grant (§59), makes on each declaring module's stream one durable consumer + event that a seat's definition or a contract in mesh-sdk defines, with its fields (for the finding events, the seat `mesh-conditions`' definition, §439); it refuses `*` before any other event, `*.>`, and `*` in part of an emitter's name. The grants part, + from the catalog graph as it derives every grant (§59, §442), makes on each declaring module's stream one durable consumer for the consumer, named `_` as ADR 0363 §5 names one, with its grants to read and acknowledge it and its membership's word to bind it; it drops that consumer when the module no longer declares the event, and makes one for a module that declares it later, with no change to the consumer's manifest. A `*` entry never reaches a diff --git a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md index 1cbb06d6..d58280da 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md +++ b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md @@ -92,9 +92,9 @@ line says so.* - §400 **No new verb is optional.** A verb G adds is not `optional`: the order of its holder's delivery is §298's edges, and a claim refused meanwhile is a gap of the delivery system built within G (§93). Why: the design's choice (Q9). How it is checked: unit (definition reader), no verb G adds is marked `optional`. -- §401 **The seat `mesh-grants` has no verbs in G.** Its definition carries its rule and its four events only; its - module's tools `grants_waits`, `grants_release`, `grants_callers` and `grants_why_refused` stay its own. Why: the - design's choice (Q12). How it is checked: the seat's fixtures. +- §401 **The seat `mesh-grants` has one verb in G.** Its definition carries its rule, its four events and the read + `grants-for` (§441); its module's tools `grants_waits`, `grants_release`, `grants_callers` and `grants_why_refused` stay its own. Why: the + design's choice (Q12, amended by D15, §441). How it is checked: the seat's fixtures. - §402 **A placement's `build` is a fingerprint, and `unwatch` waits for the placements.** A placement's `build` names a fingerprint; `unwatch` refuses while a placement names the branch, naming the placement. Why: the design's choice (Q13). How it is checked: whole (indexer), `unwatch` of a placed branch refused. @@ -110,11 +110,12 @@ line says so.* `restore-kept`, their callers `holder:node-backup@same-node` (§337); the seat `node-backup`'s `now` and `restore` gain `kept`, `form` and `fingerprint`, and say `ended.` and `restored.`, each keyed by the module, the kept data, its form and the fingerprint; listing and discarding stay node-backup's `backed-up` and `discard-aside` - (§302). Test 36's whole case lives in `mesh-host`. Why: the design's choice, one answer to three preparers (Q8, S9, - Q-H6, C19's verb names). How it is checked: test 36; a call of `snapshot-kept` from another node's `node-backup` + (§302), and so does `aside`, which sets a module's live kept data aside before a restore; `mesh-broker` serves + only `snapshot-kept` and `restore-kept`. Test 36's whole case lives in `mesh-host`. Why: the design's choice, one answer to three preparers (Q8, S9, + Q-H6, C19; lead-47's ruling, 2026-11-11). How it is checked: test 36; a call of `snapshot-kept` from another node's `node-backup` holder is refused by the bus. - §406 **A catch-up names its tool and arguments.** A restore point records the catch-up tool and its arguments whole - (§299), and the restored manifest grants that tool to `holder:node-engine@same-node`. Why: the design's choice (Q-H7). + (§299), and the restored module's catalog graph entry grants that tool to `holder:node-engine@same-node`. Why: the design's choice (Q-H7). How it is checked: whole (node-engine), a restore runs its recorded catch-up. - §407 **The object store package.** mesh-sdk's object store package is `go/stateobjects`; it also takes a foundation part's old `objects` section (§58, §346). A reply or event over the limit is made an object by that package through @@ -179,7 +180,7 @@ line says so.* ### Readers, branches and the node-engine - §421 **The node-engine reads the catalog half for its branch.** The node-engine joins §196's readers: it reads the - manifests and verdicts of the modules it composes from the catalog half, of the branch each module's placement + catalog graph entries and verdicts of the modules it composes from the catalog half, never a manifest, of the branch each module's placement names, and the parts by digest from its want (§379); its reads of the indexer's and builder's states go. The tool runner follows every watched branch's newest `catalog-revision`, as §365. Why: ADR 0596 §2 (Q-H1, Q-H2, Q-T8). How it is checked: the node-engine's manifest reads no other module's state; test 61. @@ -231,7 +232,7 @@ line says so.* replaced by its view of the catalog half (§344). Why: ADR 0596 §2 (C22). How it is checked: its manifest. - §434 **Findings name their owner and whom they wait on, and the keeper reads by events.** A finding of §33, §8 and §75 carries `owner` and `waiting-on`; the keeper's other reads are by events or verbs, and no homes rows are added. - Hand-written finding code in Go moves to mesh-sdk's `FindingWriter`. Why: the design's choice (C16, C17, C15's Go + Hand-written finding code in Go moves to the generated writer (§439). Why: the design's choice (C16, C17, C15's Go half). How it is checked: the code review; the keeper's manifest reads nothing. - §435 **`compose-candidate` goes with the checker.** The node-engine's verb `compose-candidate`, whose caller is the checker, is kept in G and removed in the change that removes the checker (§97), with the check's candidates. Why: @@ -248,3 +249,32 @@ line says so.* - §438 **The record names every repository G builds.** Design 47's milestones row and frontmatter `code:` name mesh-tools and mesh-networking, and design 51's line on what a node-engine hears says it consumes the node-engine seat's `running` (§199). Why: the design's choice (Q-T1, Q-H11). How it is checked: the index test. + +### Lead-47's rulings on the four stopped items, and the operator's rule on manifests (2026-11-11) + +- §439 **The finding events' layout is a seat contract, and its writers are generated.** The bodies of + `finding-written`, `finding-cleared`, `findings-stated` and the finding's layout are defined in the seat + `mesh-conditions`' definition, beside `findings` and `findings-asked`; the seat generator (seatgen) generates the Go and + the TypeScript writers from it, so the forge module's TypeScript writer comes with it. mesh-sdk's `go/views` writer + takes the subject handed in by the seat's client and names no seat (§262). This amends §383 and §386. Why: lead-47's + ruling, 2026-11-11, on Q10, S6 and C15, one answer for the three. How it is checked: unit (seat generator), both + writers generated from the definition say the same bodies; whole (forge module), its writer says `finding-written`. +- §440 **`process-builds` is a node-engine seat verb.** The read of the build each process was started with is the + seat `node-engine`'s verb `process-builds`, of class `read`, its callers by §391's default, since the node-engine + serves seat verbs and no module tools (§422). This amends §262 and test 48. Why: lead-47's ruling, 2026-11-11, on + Q11 and Q-H5. How it is checked: test 48; unit (definition reader), the verb's default callers. +- §441 **The seat `mesh-grants` answers the grants a candidate composes.** The seat `mesh-grants` gains the read + `grants-for`: given a candidate change, the grants that the change's catalog graph composes, against the watched + branch's; its callers by §391's default. The running runner reads a change's grants for `widens` through it, and its + serving parts from the seat list by fingerprint (§71). This amends §401. Why: lead-47's ruling, 2026-11-11, on D15 + and Q12. How it is checked: whole (grants part, runner), a change widening a grant names it in `widens` from + `grants-for`. +- §442 **Only the indexer reads a manifest.** The indexer alone reads the manifests, to build the catalog graph; every + other part (the grants part, the condition keeper, the assigner, the runner, the tool runner, the node-engine, the + checks and the reviews) reads the catalog graph, the catalog half of the revision of the branch concerned (§196, + §421). This amends §50, §59, §89, §199, §249, §309, §386, §406 and §421, and the main file's node agent, its inputs + and the composition check. Why: the operator, 2026-11-11 about 03:05 CET at the terminal: "only the indexer uses the + manifest to build the module catalog". How it is checked: the catalog's validation finds no manifest read in any + module's code but the indexer's (code review), and the grants part's table test derives each grant from a catalog + graph fixture with no manifest. + -- 2.54.0 From b4a07c1de6f69ec398ef38bfada442978b32ddef Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 03:15:06 +0100 Subject: [PATCH 3/3] Answer the step-0b review of G-9: the catalog entry carries its manifest, grants follow the placed build The review found that reading the catalog graph instead of manifests needed the entry to carry the manifest and stay while a build names it, the grants to follow the wanted build, the pre-G node-engines their manifests by digest, and the restore, caller, stream, finding and test-budget lines a name for every field they left open. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- .../47-delivery-from-commit-to-delivered.md | 4 +- .../G-1-pipelines-registration-and-steps.md | 2 +- .../G-2-pipelines-sizes-checks-and-tools.md | 4 +- .../G-3-delivery-record-and-graphs.md | 11 +- .../G-4-revision-view-and-steps.md | 3 +- .../G-5-acting-parts-check-and-kept-data.md | 4 +- .../47-milestones/G-6-verbs-and-retires.md | 4 +- .../47-milestones/G-9-prepare-answers.md | 242 ++++++++++++------ 8 files changed, 174 insertions(+), 100 deletions(-) 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 6f44c187..6109f620 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 @@ -1655,8 +1655,8 @@ list: assigner and gate wanted; a module delivered during milestone G keeps its fingerprint while they wait; no want goes to a fingerprint older than the trunk's; the operator is asked again only for an ask raised after the restore point. A revert whose restore point is missing is held, naming it. Proved with the real builds of the indexer, the - assigner and the gate from before milestone G, not fixtures (whole, checker, gate, assigner, indexer, node-engine, - backup holder, bus module). + assigner and the gate from before milestone G, not fixtures, started by their fingerprints in the artifact store + (whole, in `mesh-host`: checker, gate, assigner, indexer, node-engine, backup holder, bus module; design 47 G §405). 37. **Nothing is delivered ahead.** Research 085's milestone is delivered with no part delivered ahead of it, read from its delivery record (ADR 0656, How it is checked). 38. **A newer indexer is reached.** A merged revision naming a newer indexer gives, from the running indexer, a catalog diff --git a/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md index ee12ec53..d9fe3b09 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-1-pipelines-registration-and-steps.md @@ -235,7 +235,7 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l and an `approval` step is not; a module with no integration tests shows `nothing to run`, and a `required` unit-test step on a module with no tests holds its delivery; a bypassed step is said; a runner restarted mid-step hears the step's end and finishes the pipeline; two runners writing one pipeline key, one loses by compare-and-set; a test step's - counts are in `step-ended` and a repository over budget is named in `pipeline-ended`. Whole (Go build module): `steps` + counts are in `step-ended` and a catalog module over budget is named in `pipeline-ended` (§419). Whole (Go build module): `steps` answers the steps of a fixture artifact, a `step` ask ends with `step-ended` on its own node's subject, one on another node's subject is refused by the bus, and a build module restarted mid-step finishes it. Unit (manifest validator): a manifest naming a status is refused. Tests 65, 66, 73 and 88. diff --git a/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md b/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md index da1581bb..a0587c2c 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md +++ b/03-DESIGN/01-to-be/47-milestones/G-2-pipelines-sizes-checks-and-tools.md @@ -235,7 +235,7 @@ and an estimated 2 mesh-sdk publishes a day, each rebuilding about 120 artifacts | the watchman, the keeper | `machine-away`, `machine-back` (§389); `findings-asked` (§390) | the seats' definitions | 90 days; 7 days | 16 MiB each | | the runner | `aged`: three step-log sequences (§330) | old `state` section | never deleted | bytes | | the teller | `widens-said` (§335) | the template `state` | until the branch is unwatched | a few KiB; the template's | -| each build module | `steps` (§326) | the template `state` | one key per artifact, dropped by `steps` with `drop` | under 1 MiB; the template's | +| each build module | `detected-steps` (§326, §414) | the template `state` | one key per artifact, dropped by `steps` with `drop` | under 1 MiB; the template's | | the indexer | `registrations` and its stream `registration-history` | old `state` and `streams` sections | the life of the mesh, never derived again | 64 MiB (*A module's registration*) | | the indexer | catalog graph revisions, per watched branch | objects in the old form (ADR 0619 §2) | while a record pins it or it is its branch's current | 512 MiB, as *Two graphs, one source of truth*; a second watched branch on a few modules adds a few MiB | | the gate | `source`: one key per watched branch | its old `state` section, as today | 64 revisions of each key; a branch's key deleted when `registration-changed` says the last registration watching it unwatched it (`unwatch`) | a few KiB | @@ -344,7 +344,7 @@ step keys and the builder's build log, against the checker's last week (test 99) | §124 Each state's object store `-objects` through mesh-sdk's small package, sent objects readable by a standing grant derived from the catalog graph, and the package's two tools | one object store per state, granted to its owner; the sender's declared callers and consumers read what it sends (ADR 0666 §16); only its users import it, so nothing else is rebuilt | | §125 The `run` ask published by the runner's account and the indexer's; the verb `run` called by the sessions and the operator only | the steps and the validation run code from the change, in the sandbox only, and each asker reads only its own step keys (ADR 0363 §2); a run publishes tagged packages, so nothing else may ask one | | §126 The checker's step `check` becomes `pipeline`; `kept` starts empty | the runner is an acting part in the checker's place (ADR 0666 §19); a step's result is taken only from its seat holder (ADR 0666 §21), so no verdict of the checker's is taken in, at the cost of one round of every module's tests | -| §127 The field `callers` in a seat definition replaces the holders' trusted `callers`, a missing field admitting the holder roles and the operator only | the record makes the definition the grants part's one source (ADR 0666 §20); a field left out must open nothing | +| §127 The field `callers` in a seat definition replaces the holders' trusted `callers`, a missing field taking the default of the verb's `class` (§391) | the record makes the definition the grants part's one source (ADR 0666 §20); a field left out must open nothing | | §128 `widens` in `pipeline-ended`, computed by the running runner over every part serving a step, passed on by the teller | a widening is said and nothing refuses it (ADR 0666 §23, §26); a change must not compute its own | | §129 `merge-pull` judged from the forge module's own `failed-steps`, heard from `step-ended`, any run at the head's fingerprint counting unless a later rerun of that step passed, the protection read again on every `branch-moved` | the record has it judge from the events it consumes, never by a call, so a head merges while the runner is down (ADR 0666 §11, ADR 0596) | | §130 The new assigner before the new `merge-pull` and the runner, by `needs`, both switching on the first `registration-changed` | a merge with no Approve must never reach an assigner that writes wants without a pipeline (ADR 0667 §10) | diff --git a/03-DESIGN/01-to-be/47-milestones/G-3-delivery-record-and-graphs.md b/03-DESIGN/01-to-be/47-milestones/G-3-delivery-record-and-graphs.md index 67f0b389..b4ecce4d 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-3-delivery-record-and-graphs.md +++ b/03-DESIGN/01-to-be/47-milestones/G-3-delivery-record-and-graphs.md @@ -3,7 +3,7 @@ layer: to-be status: in-progress design: 47 milestone: G -updated: 2026-11-10 +updated: 2026-11-11 decisions: - "ADR 0666" - "ADR 0656" @@ -284,16 +284,17 @@ Findings 11). How each is kept, read and retained is this design's choice under must read every revision it moved between, and a revision neither pinned nor current is read by nobody. - §179 **An unchanged entry is stored once.** A revision is kept as its list of entries' digests, and each entry as an object of its own named by its digest, so an entry that two revisions share is stored once; an entry object is - removed when no kept revision lists it. Consecutive revisions differ by the few entries a delivery moves, so this + removed when no kept revision lists it and no want or running build names its fingerprint (§443). Consecutive revisions differ by the few entries a delivery moves, so this keeps the growth to what changes. It is chosen over a larger cap because whole revisions would grow with every revision whatever changed, and a cap would only delay the same fill. - §180 **The caps and the growth** (estimates, to be read from the fill tools once the milestone runs). A whole assignment graph revision of about 120 modules on four nodes is under the bus's 256 KiB value limit (its unit test), and a - catalog graph revision of about 120 entries about 120 KiB. A record pins the revisions before and after its + catalog graph revision's list of about 120 entries about 4 KiB, its entries, each carrying its manifest whole + (§443), about 15 KiB each. A record pins the revisions before and after its delivery, and consecutive records share one, so at an estimated 20 deliveries a day about 20 revisions of each graph a day stay pinned. A delivery moving 5 modules on four nodes adds about 20 assignment entries of about 1 KiB and a - list of about 15 KiB, and 5 catalog entries and a list of about 4 KiB: about 0.7 MiB a day of assignment graph and - 0.2 MiB of catalog graph, about 63 MiB and 18 MiB at the records' default retention of 90 days. The caps are 512 MiB + list of about 15 KiB, and 5 catalog entries of about 15 KiB and a list of about 4 KiB: about 0.7 MiB a day of assignment graph and + 1.6 MiB of catalog graph, about 63 MiB and 144 MiB at the records' default retention of 90 days. The caps are 512 MiB for each, many times the steady state. Placement-only and capability-only revisions are pinned by no record and go when they stop being current. - §181 **A store filling is said before it is full.** The indexer, the assigner and the gate each say their fill against diff --git a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md index 08069af1..2a18de0b 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md +++ b/03-DESIGN/01-to-be/47-milestones/G-4-revision-view-and-steps.md @@ -57,7 +57,8 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli 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). From G's delivery a running part acts on a revision of a watched branch as on a trunk revision, and a - candidate's view is read only by a run on request's steps and the indexer's candidate pass (ADR 0666 §6, §18). + candidate's view is read only by a run on request's steps, the grants part's `grants-for` (§441) and the indexer's + candidate pass (ADR 0666 §6, §18). - §196 **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*, above), so every module that learns from it which modules exist moves in milestone G, not after: the watchman (its diff --git a/03-DESIGN/01-to-be/47-milestones/G-5-acting-parts-check-and-kept-data.md b/03-DESIGN/01-to-be/47-milestones/G-5-acting-parts-check-and-kept-data.md index 64ca5ec3..7a924046 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-5-acting-parts-check-and-kept-data.md +++ b/03-DESIGN/01-to-be/47-milestones/G-5-acting-parts-check-and-kept-data.md @@ -3,7 +3,7 @@ layer: to-be status: in-progress design: 47 milestone: G -updated: 2026-11-10 +updated: 2026-11-11 decisions: - "ADR 0667" - "ADR 0666" @@ -338,7 +338,7 @@ later change of a kept data's form, not as a case of this milestone. catch-up tool the newer manifest declares beside that kept data. A failed backup holds that module as any failed backup does. - §297 **A revert restores it before the reverted build starts.** When a want takes a module back across a change of a - kept data's `form`, the node agent applying it asks that seat's verb `restore` for the restore point of that module, + kept data's `form`, the node agent applying it stops the newer build, then asks that seat's verb `restore` (§405) for the restore point of that module, kept data and form, waits for the seat's event `restored`, and only then starts the reverted build. The node agent that restores is the one running when the revert starts. As every restore is, it is brought back beside the live data and never over it: the live kept data of the newer form is set aside under a name of its own, and only the operator diff --git a/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md b/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md index 8c9d0f91..45ceb2c4 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md +++ b/03-DESIGN/01-to-be/47-milestones/G-6-verbs-and-retires.md @@ -59,8 +59,8 @@ of each verb (ADR 0666 §7, §20, §25): | `run` | the run on request of one or more members, each a module at a named commit; delivers nothing | the sessions (the agents' bus identities the tool runner proves) and the operator, nothing else | | `start` | a delivering pipeline for a watched branch's head, by hand | the operator, the healers | | `show`, `list`, `stands`, `why-carried`, `kept` | one pipeline whole with its step log; the pipelines and runs of a module, a branch or a commit; what stands still; where a result was carried from; the kept results | any person, an agent session, the healers | -| `review` | a code review's result for a commit and fingerprint | the reviewers the definition names; refused from the commit's author | -| `rerun`, `accept`, `cancel`, `ask-again` | one step again; a failed `optional` step accepted with why; a pipeline ended, its asks dropped; a declined `approval` asked again | the operator, the healers (`accept` and `ask-again` the operator) | +| `review` | a code review's result for a commit and fingerprint | sessions; refused from the commit's author (§394) | +| `rerun`, `accept`, `cancel`, `ask-again` | one step again; a failed `optional` step accepted with why; a pipeline ended, its asks dropped; a declined `approval` asked again | the operator, the healers (`accept` and `ask-again` the operator; §391, §394) | §307 **The seat `mesh-catalog`** gains, from milestone G's delivery, `register`, `policy`, `watch`, `unwatch` and `registrations`, and the event `registration-changed` (*A module's registration*), and `catalog-revision` names its diff --git a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md index d58280da..f7ff6c2f 100644 --- a/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md +++ b/03-DESIGN/01-to-be/47-milestones/G-9-prepare-answers.md @@ -38,15 +38,17 @@ line says so.* - §391 **Every verb takes a default of callers by its class.** From the operator's answers of 2026-11-11 (02:13 CET, "Any declaring module"; 02:47 and 02:56 CET, "As proposed"), a verb's definition names its class in the field `class`, and a verb whose definition names no `callers` takes its class's default, which the seat-definition reader - applies and the manifest validator says per verb ("`.` takes the default of ``"): a `read`, the - class a verb names none of, takes `invokers`, `persons` and `sessions`, so every verb open today stays open; an - `act` (a new act that changes what the mesh does: registers, sets a policy, watches or unwatches a branch, - recovers) takes `operator` and `sessions`; a `warrant` (a verb that runs on the operator's warrant) takes `operator` - and carries the approval mark; `accept` is the operator's alone (§394). A verb that names `callers` keeps them, so - no verb is closed by §68 for lack of a list. Why: ADR 0666 §20 makes the definition the one source of caller - limits; the operator asked on 2026-11-11 why caller questions kept coming, and answered them as one rule (Q1, S3, - C3, D2's reads, Q18). How it is checked: unit (seat-definition reader), a table test with one row per class, and a - row for a verb with `callers` of its own; unit (manifest validator), the default each verb took is said. + applies and the manifest validator says per verb ("`.` takes the default of ``"): a `read` takes + `invokers`, `persons` and `sessions`; an `act` (a new act that changes what the mesh does: registers, sets a policy, + watches or unwatches a branch, recovers, restores) takes `operator` and `sessions`; a `warrant` (a verb that runs on + the operator's warrant) takes `operator` and carries the approval mark; `accept` is the operator's alone (§394). A + verb on main that names no class is a `read`, so every verb open today stays open; a verb G adds must name its + `class`, and the definition reader refuses one that does not. A verb that names `callers` keeps them, so no verb is + closed by §68 for lack of a list; §68, §127 and §306 point here. Why: ADR 0666 §20 makes the definition the one source + of caller limits; the operator asked on 2026-11-11 why caller questions kept coming, and answered them as one rule + (Q1, S3, C3, D2's reads, Q18). How it is checked: unit (seat-definition reader), a table test with one row per class, + a row for a verb with `callers` of its own, and a row refusing a verb G adds without `class`; unit (manifest + validator), the default each verb took is said. - §392 **A caller entry names its kind of name.** In `callers`, a holder role is written `seat:` and a module `module:`, beside `operator`, `healers`, `persons`, `sessions`, `invokers` and `holder:@same-node` (§336), since a name such as `mesh-grants` is both a seat and a module. Why: the design's choice (Q2). How it is @@ -63,21 +65,24 @@ line says so.* operator and the healers (§83, §40). Why: the operator, 2026-11-11 02:56 CET on Telegram, "As proposed" (S4, S10, C18, D2, D3, D4). How it is checked: whole (indexer, runner, operator-channel), a call from any other caller is refused by the bus; unit (definition reader), each verb's class and callers. -- §395 **An accepted kind naming no callers keeps today's grant.** `operator-channel`'s kinds `ask`, `cancel` and - `condition` keep the grant they have today, open to every asker, so the runner's approval (§37), the seed ask (§8) - and every other asker are not refused (§338). Why: the operator's intent, a verb open today stays open (Q18). How it - is checked: whole (operator-channel), an asker's `ask` is taken. +- §395 **An accepted kind naming no callers keeps today's grant.** `operator-channel`'s kinds `ask` and `condition` + keep the grant they have today, open to every asker, so the runner's approval (§37), the seed ask (§8) and every + other asker are not refused (§338); `cancel` stays limited to each asker's own subject (ADR 0259 §3). Why: the + operator's intent, a verb open today stays open (Q18). How it is checked: whole (operator-channel), an asker's `ask` + is taken and its `cancel` of another asker's ask is refused by the bus. ### The forms of a seat's definition - §396 **A dot only where no stream is named from the event; `keep`'s form.** An event whose definition names `keep` has no dot in its name, since its stream `SEAT__` is named from it; an event naming no `keep` stays on - its seat's family stream and may have a dot. `keep` is an object `{max-age-days, max-mib, last-per-subject}`, its age - 90 days and its cap 16 MiB unless it names others (§331). The seat `git`'s events take hyphens: `pull-updated`, - `pull-merged`, `pull-closed`, `forge-pull`, `forge-status`, `forge-delete` and `repo-writable` (§310), and `owed` is - kept on its seat stream 7 days and 64 MiB (§162). This amends §260. Why: the design's choice (Q3, Q4, S5, C1, C2). - How it is checked: unit (definition reader), a dotted event with `keep` refused, one without accepted, `keep`'s - defaults. + the shared stream EVENTS, its seat's family, kept 7 days, and may have a dot. `keep` is an object of three fields: + `max-age-days` (days; `0` is the one value for no age limit), `max-mib`, and `last-per-subject` (yes or no); unless + it names others its age is 90 days, its cap 16 MiB and `last-per-subject` no (§331). The seat `git`'s events take + hyphens: `pull-updated`, `pull-merged`, `pull-closed`, `forge-pull`, `forge-status`, `forge-delete` and + `repo-writable` (§310). The gate's `owed` is kept on its seat stream `SEAT_mesh-delivery_owed`, 7 days and 64 MiB + (§162), its one name. This amends §260. Why: the design's choice (Q3, Q4, S5, C1, C2). How it is checked: unit + (definition reader), a dotted event with `keep` refused, one without accepted, `keep`'s defaults and `0` read as no + age limit. - §397 **The forms of `subject`, `acts.on` and `bound`.** `subject` is the words after `mesh.seat..event.` with `` tokens, `` written out; `acts.on` is one string, `every`, a language, or `kind:image`; `bound` is a duration such as `30m`. Why: the design's choice (Q5). How it is checked: unit (definition reader), each form @@ -102,21 +107,33 @@ line says so.* field `held-since`, and no field `behind`. Why: the design's choice (Q14). How it is checked: the seat's fixtures. - §404 **The node-engine's events' bodies.** `capabilities-changed` carries the node record's stated capabilities whole and `at`; `composed` the module, the fingerprint and the composition's digest; `running` with `stopped` carries - `stopped: true` and no fingerprint (§365). Why: the design's choice (Q17). How it is checked: the seat's fixtures. + `stopped: true` and no fingerprint (§365), and mesh-sdk's `SeatsToPassOn` counts such a module as not running on that + node. Why: the design's choice (Q17). How it is checked: the seat's fixtures; unit (`SeatsToPassOn`), a row where a + `stopped` holder passes no seat. ### Kept data on the bus, restore points and the reader release - §405 **The bus module's restore points and node-backup's verbs.** The seat `mesh-broker` gains `snapshot-kept` and - `restore-kept`, their callers `holder:node-backup@same-node` (§337); the seat `node-backup`'s `now` and `restore` - gain `kept`, `form` and `fingerprint`, and say `ended.` and `restored.`, each keyed by the module, the - kept data, its form and the fingerprint; listing and discarding stay node-backup's `backed-up` and `discard-aside` - (§302), and so does `aside`, which sets a module's live kept data aside before a restore; `mesh-broker` serves - only `snapshot-kept` and `restore-kept`. Test 36's whole case lives in `mesh-host`. Why: the design's choice, one answer to three preparers (Q8, S9, - Q-H6, C19; lead-47's ruling, 2026-11-11). How it is checked: test 36; a call of `snapshot-kept` from another node's `node-backup` - holder is refused by the bus. + `restore-kept`, of class `act`, their callers `holder:node-backup@same-node` alone (§337): the bus module's account is + the one that moves bus data, so `restore-kept` sets the live kept data aside under a name of its own and then + restores the restore point beside it, with the argument `aside-only` it sets the live data aside and restores + nothing, and with the argument `discard-aside`, naming data set aside, it removes that data and restores nothing. + The seat `node-backup`'s `now`, `restore` and `aside` (class `act`, callers by §391's default) and `discard-aside` + (callers `operator` alone) gain `kept`, `form` and `fingerprint` and call those verbs; listing stays `backed-up` + (§302). Before any live data is set aside, the node agent stops the newer build of the module (§297). `now` and + `restore` say `ended` and `restored` on `mesh.seat.node-backup.event.ended...` and + `.restored...`, carrying the module, the kept data, its form, the fingerprint and `outcome` + (`done` or `failed`, with its `error`); the node agent's wait for either is bounded at 30 minutes, past which its + have says the wait, naming the seat, and the watchman's `delivery-waits` raises it. Test 36's whole case lives in + `mesh-host`, and starts the builds from before G by their fingerprints in the artifact store. Why: the design's + choice, one answer to three preparers (Q8, S9, Q-H6, C19; lead-47's ruling, 2026-11-11). How it is checked: test 36; + a call of `snapshot-kept` from another node's `node-backup` holder, and a `discard-aside` from any caller but the + operator, are refused by the bus; a failed restore says `restored` with `failed` and its error. - §406 **A catch-up names its tool and arguments.** A restore point records the catch-up tool and its arguments whole - (§299), and the restored module's catalog graph entry grants that tool to `holder:node-engine@same-node`. Why: the design's choice (Q-H7). - How it is checked: whole (node-engine), a restore runs its recorded catch-up. + (§299), and the fingerprint of the newer build it was taken before; the grants part derives the grant of that tool to + `holder:node-engine@same-node` from the catalog graph's entry of that recorded fingerprint (§443). Why: the design's + choice (Q-H7). How it is checked: whole (node-engine), a restore runs its recorded catch-up, granted from the + recorded build's entry. - §407 **The object store package.** mesh-sdk's object store package is `go/stateobjects`; it also takes a foundation part's old `objects` section (§58, §346). A reply or event over the limit is made an object by that package through §345's put session, and read back through the same session form for a get; the call that reads a sent object is @@ -132,9 +149,11 @@ line says so.* `kind:image`, `version`, the `*` emitter, an observer's finding stream, and an artifact's `needs`; `check` stays beside `pipeline` until the checker is removed (§97, §203). Why: readers first (ADR 0667 §4; S2, S18). How it is checked: unit (the release's reader), each form read. -- §410 **A foundation part's sent store keeps its send sequence.** mesh-sdk's sender keeps the sequence of a foundation - part's sends in the owner's old `state` section and ages `sent-objects` from it at each send (§330). Why: an - `objects` section has no sequence (S7). How it is checked: unit (sender), a send past 7 days ages the oldest. +- §410 **A foundation part's sent store keeps its send sequence.** mesh-sdk's sender keeps, per node, the sequence of + a foundation part's sends in the owner's old `state` section `sent-log`, one key `` written by compare-and-set + at each send, and ages `sent-objects` from it at each send (§330); `_state_objects` reads it. Why: an + `objects` section has no sequence (S7). How it is checked: unit (sender), a send past 7 days ages the oldest, and two + sends at once lose none by compare-and-set. ### Versions @@ -144,9 +163,11 @@ line says so.* module (§52, §374; Q15, S1, Q-H3, D14). How it is checked: unit (manifest validator), `series` refused. - §412 **The first fill's sources.** §372's fill reads, per module, the packages its catalog entry names in their ecosystems (the Go module path, the npm name); where the builder holds no version of a package, the forge's tags of - its repository (`go/vMAJOR.MINOR.PATCH`) are the floor. Why: the live builder answers none for mesh-sdk while the - forge holds `go/v0.1.14` (S17, C9). How it is checked: whole (indexer), a module with tags and no builder versions - fills from the tags. + its repository (`go/vMAJOR.MINOR.PATCH`) are the floor, only tags the forge protects. The fill is a kept call that + waits until both sources have answered for every module, and fills nothing until then, never part of the modules. + Why: the live builder answers none for mesh-sdk while the forge holds `go/v0.1.14` (S17, C9). How it is checked: + whole (indexer), a module with tags and no builder versions fills from the tags; with the forge down, nothing is + filled and `call-unanswered` is raised after five minutes; an unprotected tag is not read. - §413 **`tag-asks` and `version.numbered` go at G's delivery.** The builder's `tag-asks` and its event `version.numbered` are removed at G's delivery, as §373 has for the tagged versions; the build modules consume `version.numbered` no more from G. This amends §372. Why: the design's choice (D19). How it is checked: the @@ -166,12 +187,16 @@ line says so.* - §417 **Go's lint is gofmt and vet.** Go's lint step runs gofmt and go vet, in the lint step only (§328). Why: the design's choice (C8). How it is checked: whole (Go build module), a vet failure fails lint and no unit step. - §418 **The repository checks run as a step.** Each repository's own checks, which the checker runs today, run as a - pipeline step of its build seat from G's delivery. Why: the checker goes (C20). How it is checked: whole (runner), - a failing repository check fails its step. -- §419 **How tests are counted.** A test is a top-level Go test function or a TypeScript `test(` call; an existing - module ends G with no more tests than it starts with, and the new runner within 50 integration and 500 unit tests; a - module over the budget at its start is named in the pipeline's end. Why: the test budget per module (S16, D6). How - it is checked: `pipeline-ended`'s counts. + pipeline step of its build seat from G's delivery, keyed per repository and source revision, so a repository's + checks run once for a source revision however many of its modules it moves (ADR 0548); hq's check (its `go test + ./...` at its root) runs on the seat `node-build-go`. Why: the checker goes (C20). How it is checked: whole (runner), + a failing repository check fails its step, and a revision moving two modules of one repository runs it once. +- §419 **How tests are counted.** A test is a top-level Go test function or a TypeScript `test(` call, counted per + catalog module. A module ends G with no more tests than it starts with, and a module over its budget at its start + whose tests G's change touches ends with fewer (the test budget); the new runner stays within 50 integration and 500 + unit tests. `pipeline-ended` carries per module `tests` (`unit`, `integration`) and `over-budget` (yes or no); G's own + check, made by the running checker (§340), counts by the same rule. Why: the test budget per module (S16, D6). How it + is checked: `pipeline-ended`'s counts; unit (runner), a module over budget is named `over-budget`. - §420 **A run on request's key, and the step-run package.** A run on request is keyed by the run's id under its named branch (§54, §64, §85); the step-run code is the delivery SDK's package `sdk/steprun`, and the runner's client sits beside the other seats' clients; the runner's kept data layouts are the seat's `states` (§27, §306). Why: @@ -179,14 +204,19 @@ line says so.* ### Readers, branches and the node-engine -- §421 **The node-engine reads the catalog half for its branch.** The node-engine joins §196's readers: it reads the - catalog graph entries and verdicts of the modules it composes from the catalog half, never a manifest, of the branch each module's placement - names, and the parts by digest from its want (§379); its reads of the indexer's and builder's states go. The tool - runner follows every watched branch's newest `catalog-revision`, as §365. Why: ADR 0596 §2 (Q-H1, Q-H2, Q-T8). How it - is checked: the node-engine's manifest reads no other module's state; test 61. -- §422 **The node-engine's first-view tools are seat verbs.** The node-engine serves its view's two tools as seat verbs - of `node-engine`, beside its seat-list verbs, since it serves no module tools. Why: the design's choice (Q-H4). How - it is checked: the seat's fixtures. +- §421 **The node-engine reads the entry its want names.** The node-engine joins §196's readers: it reads, from the + catalog half, the catalog graph's entry of the fingerprint its want names (§443), never a manifest and never by + branch, so a want needs no field `branch`, and the parts by digest from its want (§379); its reads of the indexer's + and builder's states go. When the catalog half no longer holds that entry, the node-engine holds the want and its + have says the phase `entry-missing`, naming the fingerprint. The tool runner follows every watched branch's newest + `catalog-revision`, as §365. Why: ADR 0596 §2 (Q-H1, Q-H2, Q-T8; review of step 0b). How it is checked: the + node-engine's account holds no read of another module's state; test 61, extended to the node-engine; whole + (node-engine), a want naming an entry the half does not hold says `entry-missing`. +- §422 **The node-engine's first-view tools are seat verbs.** The node-engine serves its view's two tools as the seat + `node-engine`'s verbs `first-views` and `first-view-again`, beside its seat-list verbs, since it serves no module + tools: `first-views` a `read`, its callers any person and the healers, and `first-view-again` an `act`, its callers + the operator and the healers, as §204 names them. Why: the design's choice (Q-H4). How it is checked: the seat's + fixtures; whole (node-engine), a call from another caller is refused by the bus. - §423 **A kept-build wait says the existing words.** A have waiting for a kept build (§271) says the existing phase and words, with no new field. Why: the design's choice (Q-H10). How it is checked: whole (node-engine). - §424 **Each process's own build, and each bundle's.** A process says `own build unknown` in its @@ -217,15 +247,20 @@ line says so.* (gate), test 36's gate half. - §430 **The gate's sources before the first registrations.** The gate keeps `source.` per repository and watched branch, the branch escaped as §73, following the registrations, and writes `source.` for - every repository from its start, before the first registrations (§15, §95). Why: the design's choice (C12, D18). - How it is checked: whole (gate), `source` answers before any registration. + every repository from its start, before the first registrations (§15, §95). It starts from its own kept `source` + keys; the forge's heads it asks as a kept call (ADR 0668), so a gate started while the forge is down serves what it + kept, writes nothing for a repository it has no key of, and raises `call-unanswered` after five minutes. Why: the + design's choice (C12, D18). How it is checked: whole (gate), `source` answers before any registration, and with the + forge stopped it serves its kept keys and says `call-unanswered`. - §431 **The fate of the gate's other parts.** From G's delivery the gate's `asks` go with the Approve per merge; `deliveries`, `show`, `groups` and `stalled` are answered from the delivery records; `checks` and `settle` go with the - merge states, and the five verbs of release 6 leave the definition; the events `group` and `merged` go, their readers - moving to the seat `git`'s events, while `transition` stays; the reads of the teller's answers and the view's reach - are by their events, and of the checker's verdicts go with it. Readers of the gate's `source` move to the verb - `source` and `source-moved`, and the assigner reads no `merges`. Why: the design's choice (C13, C14, D9, D11). How it - is checked: whole (gate), each verb served or not as named. + merge states, and the five verbs of release 6 leave the definition; the events `group` and `merged` go, while + `transition` stays; their readers move: the knowledge base's delivery overview (what `knowledge-base.progress` + draws) reads the seat `git`'s `pull-merged` and the runner's `group-ended`, and the issue tracker and the tool runner + the same. The reads of the teller's answers and the view's reach are by their events, and of the checker's verdicts + go with it. Readers of the gate's `source` move to the verb `source` and `source-moved`, and the assigner reads no + `merges`. Why: the design's choice (C13, C14, D9, D11). How it is checked: whole (gate), each verb served or not as + named; whole (knowledge base), the overview shows a group's end from `group-ended`. - §432 **The edges a `needs` names.** An artifact's `needs` names artifact references `:` of the catalog graph's edges (§95, §121). Why: the design's choice (C21). How it is checked: unit (manifest validator). - §433 **The bus module reads the catalog half.** The bus module's `consumes` and its call of `indexer_bus_state` are @@ -239,42 +274,79 @@ line says so.* the design's choice (Q16, Q-H1's candidates). How it is checked: the seat's fixtures at G's heads keep it. - §436 **A presence event names the machine, not its publisher.** `machine-away` and `machine-back` carry the machine as a subject part named ``, which the grants part does not bind to the publisher's node, since the - watchman says them for another machine. This amends §389. Why: `` in a subject is the publishing node (§260; - S8). How it is checked: whole (watchman), the event for an away machine is published by the watchman's account. + watchman says them for another machine; publish on them is granted to the holder of `mesh-watchdogs` alone. This + amends §389. Why: `` in a subject is the publishing node (§260; S8). How it is checked: whole (watchman), the + event for an away machine is published by the watchman's account; the grants part's table test, a row refusing the + same event from any other account. - §437 **`finding-written` carries the finding's layout whole.** `finding-written` and each entry of `findings-stated` - carry the finding's layout as the state `findings` holds it whole (its `summary`, `source`, `observer`, `actions`, - `needs`, `resolver`, `ref` and `run` among it), plus `scope`, `id` and `since`, so a condition built from the event - alone loses nothing. This amends §383. Why: the design's choice (Q19). How it is checked: unit (writer), the event's - body holds every field of the key. + carry the fields §439 lists, so a condition built from the event alone loses nothing. This amends §383. Why: the + design's choice (Q19). How it is checked: unit (writer), the event's body holds every field of the key. - §438 **The record names every repository G builds.** Design 47's milestones row and frontmatter `code:` name mesh-tools and mesh-networking, and design 51's line on what a node-engine hears says it consumes the node-engine seat's `running` (§199). Why: the design's choice (Q-T1, Q-H11). How it is checked: the index test. ### Lead-47's rulings on the four stopped items, and the operator's rule on manifests (2026-11-11) -- §439 **The finding events' layout is a seat contract, and its writers are generated.** The bodies of - `finding-written`, `finding-cleared`, `findings-stated` and the finding's layout are defined in the seat - `mesh-conditions`' definition, beside `findings` and `findings-asked`; the seat generator (seatgen) generates the Go and - the TypeScript writers from it, so the forge module's TypeScript writer comes with it. mesh-sdk's `go/views` writer - takes the subject handed in by the seat's client and names no seat (§262). This amends §383 and §386. Why: lead-47's - ruling, 2026-11-11, on Q10, S6 and C15, one answer for the three. How it is checked: unit (seat generator), both - writers generated from the definition say the same bodies; whole (forge module), its writer says `finding-written`. +- §439 **The finding events' layout is a seat contract, and its writers are generated.** The seat `mesh-conditions`' + definition defines, in its section `bodies` (the bodies other modules say on their own streams, from which the grants + part makes no seat event or stream), the finding and the bodies of `finding-written`, `finding-cleared` and + `findings-stated`, beside `findings` and `findings-asked`. A finding's fields, the one list: `kind`, `scope`, `id`, + `at`, `since`, `severity`, `summary`, `headline`, `explanation`, `subject`, `evidence`, `source`, `observer`, + `owner`, `waiting-on`, `actions`, `needs`, `resolver`, `ref` and `run`; `finding-cleared` carries `kind`, `scope`, + `id`, `at` and `why`; `findings-stated` carries `at`, `asked`, `findings` and `pending`. The seat generator (seatgen) + generates the Go and the TypeScript writers from it, so the forge module's TypeScript writer comes with it. mesh-sdk's + `go/views` writer takes the subject handed in by the seat's client and names no seat (§262). This amends §383, §386 + and §434. Why: lead-47's ruling, 2026-11-11, on Q10, S6 and C15, one answer for the three; the list is the design's + choice. How it is checked: unit (seat generator), both writers generated from the definition say the same bodies; + unit (grants part), a body of `bodies` makes no stream; whole (forge module), its writer says `finding-written`. - §440 **`process-builds` is a node-engine seat verb.** The read of the build each process was started with is the - seat `node-engine`'s verb `process-builds`, of class `read`, its callers by §391's default, since the node-engine - serves seat verbs and no module tools (§422). This amends §262 and test 48. Why: lead-47's ruling, 2026-11-11, on - Q11 and Q-H5. How it is checked: test 48; unit (definition reader), the verb's default callers. + seat `node-engine`'s verb `process-builds`, a `read`, its callers any person, agent sessions and the healers, since + the node-engine serves seat verbs and no module tools (§422). This amends §262 and test 48. Why: lead-47's ruling, + 2026-11-11, on Q11 and Q-H5. How it is checked: test 48; the grants part's table test, its three callers. - §441 **The seat `mesh-grants` answers the grants a candidate composes.** The seat `mesh-grants` gains the read - `grants-for`: given a candidate change, the grants that the change's catalog graph composes, against the watched - branch's; its callers by §391's default. The running runner reads a change's grants for `widens` through it, and its - serving parts from the seat list by fingerprint (§71). This amends §401. Why: lead-47's ruling, 2026-11-11, on D15 - and Q12. How it is checked: whole (grants part, runner), a change widening a grant names it in `widens` from - `grants-for`. -- §442 **Only the indexer reads a manifest.** The indexer alone reads the manifests, to build the catalog graph; every - other part (the grants part, the condition keeper, the assigner, the runner, the tool runner, the node-engine, the - checks and the reviews) reads the catalog graph, the catalog half of the revision of the branch concerned (§196, - §421). This amends §50, §59, §89, §199, §249, §309, §386, §406 and §421, and the main file's node agent, its inputs - and the composition check. Why: the operator, 2026-11-11 about 03:05 CET at the terminal: "only the indexer uses the - manifest to build the module catalog". How it is checked: the catalog's validation finds no manifest read in any - module's code but the indexer's (code review), and the grants part's table test derives each grant from a catalog - graph fixture with no manifest. + `grants-for`. Its argument is the candidate: a source revision or a run's id, and its watched branch. The grants part + takes that candidate's catalog half by `mesh-catalog`'s `revision` (one of §195's readers of a candidate's view) and + answers, per module, the grants it would compose added and removed against the branch's newest, each named by its + subject and verb. Its callers are §391's default. The running runner reads a change's grants for `widens` through it, + as a kept call, and its serving parts from the seat list by fingerprint (§71); while the grants part does not answer, + `pipeline-ended`'s `widens` says `could not run`, naming `mesh-grants`, and holds nothing (§71: a widening is said, + never refused). This amends §401. Why: lead-47's ruling, 2026-11-11, on D15 and Q12. How it is checked: whole (grants + part, runner), a change widening a grant names it in `widens` from `grants-for`, and with the grants part stopped + `widens` says `could not run`. +- §442 **Only the indexer reads a manifest.** The indexer alone reads the manifests, to build the catalog graph, whose + entry carries the validated manifest whole (§443); every other part (the grants part, the condition keeper, the + assigner, the runner, the tool runner, the node-engine, the checks and the reviews) reads the catalog graph's entry + of the build concerned from the catalog half (§196, §421). Today's readers move: in mesh-catalog, `brother`, + `distribution`, the forge module's package registry and `mesh-build-go` read the entry they need by `mesh-catalog`'s + `entry` or `revision`; in `mesh-host`, the node-engine reads the entry its want names (§421). The one exception is + the bootstrap: `mesh-host`'s `mesh-bootstrap` and `mesh-compose` read the manifests from a checkout of the catalog repository, before + any indexer runs. This amends §50, §59, §89, §199, §249, §309, §386, §406 and §421, and the main file's node agent, + its inputs and the composition check. Why: the operator, 2026-11-11 about 03:05 CET at the terminal: "only the + indexer uses the manifest to build the module catalog". How it is checked: test 61, extended to the node-engine and + the grants part: whole cases whose accounts hold no read of a manifest; the grants part's table test derives each + grant from a catalog graph fixture with no manifest. +### From the review of step 0b (2026-11-11) + +- §443 **The catalog graph's entry carries the manifest, and is kept while a build names it.** Each catalog graph + entry carries the validated manifest whole beside the fields §174 names, kept as an object of the indexer's old + `objects` section by its digest (§179), so no size limit applies to it. The indexer keeps an entry while a kept + revision lists it, or a want (heard by `mesh-wants`' `wanted`) or a running build (heard by the node-engine seat's + `running..`) names its fingerprint, and removes it at the first revision after none does; the seat + `mesh-catalog` gains the read `entry`, which answers one entry by its fingerprint, so a build older than the newest + is read by the want's fingerprint. This amends §179 and §180. Why: §442; the design's choice. How it is checked: + whole (indexer), an entry no revision lists stays readable by `entry` while a want names its fingerprint, and goes + after the want moves on. +- §444 **The grants part derives each module's grants from the build placed.** The grants part derives each module's + grants from the catalog graph's entry of the build its want names (heard by `wanted`), never from a branch's newest + revision, so a change on a branch no placement names grants nothing. This amends §59 and §386. Why: §442; a grant + follows what runs. How it is checked: the grants part's table test, a widening on a branch no placement names + grants nothing, and the same widening once wanted is granted. +- §445 **The indexer keeps the manifests by digest for node-engines before G.** Until no node runs a node-engine from + before G, the indexer keeps writing each manifest by digest in its state `manifests`, which those node-engines + read; that state and its writing go in the first change after the node-engine seat's `running` events say every + node runs G's node-engine, the state through `drop` on a person's word (ADR 0595 §4). The node-engine's own manifest + in G uses no word the node-engine of the version before refuses, since that reader refuses unknown fields; the + manifest validator holds it to that reader's words at G's heads. Why: readers first (ADR 0667 §4). How it is + checked: unit (manifest validator), a row refusing a node-engine manifest with a word the older reader refuses; + whole (node-engine of the version before), it composes from a manifest by digest written by G's indexer. -- 2.54.0