From a8103cf0b1506aa0e52a01215a253b80c3b6892b Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 10 Nov 2026 02:49:51 +0100 Subject: [PATCH] Take in round 1 of the review by architectural domain of the 086 amendment The four reviewers asked changes in every domain and fix-1965 ruled on each, with ADR 0666 and ADR 0667's wording staged to match: foundation parts keep old sections, merge-pull judges from its own state so a head merges while the runner is down, a group's wants wait for group-ended, a failed head is said to its author then the operator, the checker goes only after a first end-to-end pipeline and a tested backup, and the stores are sized again for publish rebuilds. Claude-Session: https://claude.ai/code/session_01JG73KK8HD1gufnqyFxMFdW --- 00-META/glossary.md | 6 +- .../47-delivery-from-commit-to-delivered.md | 453 +++++++++++------- 2 files changed, 294 insertions(+), 165 deletions(-) diff --git a/00-META/glossary.md b/00-META/glossary.md index aacc3e0f..74353fcb 100644 --- a/00-META/glossary.md +++ b/00-META/glossary.md @@ -547,7 +547,7 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel and never in a manifest (ADR 0666 §4). Not the **upgrade policy** (Module), how a module's builds reach its nodes (see [Homonyms](#homonyms)). - **registration** — a module's entry in the catalog: its git origin, the path of its manifest, its watched branches and - its policy, kept as a ledger by the seat `mesh-catalog`, every version with who changed it and on whose Approve; + its policy, kept by the seat `mesh-catalog`, every version with who changed it and on whose Approve; registering and changing one are trusted acts (ADR 0666 §2). The mesh knows modules, and a repository only as a module's git origin. - **watched branch** — a branch a module's registration names, whose commits start that module's pipeline and which a @@ -876,8 +876,8 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel delivery part and the gate reach the forge: reads (`pull`, `open-pulls`, `tags`, `trees`, `file`, `contains`, `statuses`) for the parts that declare them, acts (`status`, `comment`, `view`, `note`, `merge-pull`) for the forge bridge alone, as the holder's trusted value `callers` names, and the forge's events (`pull.*`, `forge.*`, - `repo.writable`) as the seat's (design 47, *The verbs*). From milestone G's delivery `merge-pull` is a session's own - merge, refused only for a head whose latest run failed a `required` step, a head that moved or an unprotected branch + `repo.writable`) as the seat's (design 47, *The verbs*). From milestone G's delivery `merge-pull` is a session's + merge, refused only for a head at whose fingerprint a run failed a `required` step, a head that moved or an unprotected branch (ADR 0666 §6), the read `branch` and the event `branch-moved` say a branch's head and protection, and the callers per verb are the seat definition's (ADR 0666 §12). Not the **forge** itself, the server, nor the forge module's own tools. 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 43381f9d..2f7cac29 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 @@ -181,7 +181,7 @@ source of truth* and *The check on the change's own acting parts* hold the whole ADR 0667, from research 086). Each module's registration in the catalog names its watched branches and its policy; a commit on a watched branch runs the module's pipeline steps (lint, tests, composition, code review, approval) by the seat `mesh-pipeline-runner`; only a `required` step that did not pass holds a delivery; the order comes from edges -between artifacts; and no Approve is asked per merge, a session merging its own pull request through the seat `git`. +between artifacts; and no Approve is asked per merge, a session merging a pull request through the seat `git`. The checker and its try go. Milestone G builds this with research 085's two graphs as one milestone, and until its delivery the sections it replaces hold and check and deliver it (ADR 0667 §1, §2). *Pipelines per module*, below, holds the whole of it. @@ -225,8 +225,9 @@ source revision is derived from the keys: every **want** equals its module's **f digests instead of judging it again (ADR 0548 §1, §5; *A move of the trunk carries every verdict*, below). From research 085's milestone its judging rules are a **checking program** built from the change's heads (ADR 0656) and run in a build seat's sandbox (ADR 0448 §2); the running checker only asks, records and publishes (*The check - on the change's own acting parts*, below). It makes milestone G's own check, and G's delivery removes it, its buckets - and its bus account after a backup (ADR 0667 §2, §6): from then the pipeline makes the check (ADR 0666 §11). + on the change's own acting parts*, below). It makes milestone G's own check, and is removed with its buckets and its + bus account once the first pipeline after G's delivery has delivered a change end to end, after a tested backup + (ADR 0667 §2, §6): from then the pipeline makes the check (ADR 0666 §11). - **The pipeline runner** (module `mesh-delivery-pipeline`, holding the seat `mesh-pipeline-runner`), from milestone G's delivery: runs each module's pipeline for each commit or group on its watched branches, asking each pipeline step of the seat that serves it and saying each step's end and the pipeline's end as events, its state on the bus; it @@ -239,7 +240,7 @@ source revision is derived from the keys: every **want** equals its module's **f milestone removes the hold, the turns and the setting (*Nothing merges into a repository under check*, below). From that milestone it keeps one delivery record per milestone's delivery as a ledger instance (ADR 0656), its `merges` carried into the records (*The delivery record*, below). From G's delivery it merges nothing and asks no Approve: a - session merges its own pull request through the seat `git`, and the gate keeps the delivery record, its groups and the + session merges a pull request through the seat `git`, and the gate keeps the delivery record, its groups and the source revision per watched branch (ADR 0666 §6, §7). - **The teller** carries conditions and asks to the operator's phone and is the only writer of an ask's answer. - **The assigner** writes which fingerprint each node should run, by six rules: the build is done, the @@ -414,9 +415,9 @@ The target (ADR 0547): (ADR 0421 §2); it is the review ADR 0382 §6 asks (ADR 0421 §9). No ready mark, label, comment, forge review or recheck stands before it. The operator's Approve is asked for every merge into main, a hotfix's too (ADR 0398 §3; the operator, 2026-10-16 23:40). Milestone G's own merges are the last asked so (ADR 0667 §2). -- **From milestone G's delivery a merge waits for nothing of the mesh.** A session merges its own pull request through - the seat `git`'s `merge-pull`, judged on its head, the branch's protection and the head's latest run, which refuses it - only where a `required` step failed and is never waited for; the pipeline then runs on the landed commit, and only its `required` steps, the `approval` step where a policy names it among them, hold the +- **From milestone G's delivery a merge waits for nothing of the mesh.** A session merges a pull request through + the seat `git`'s `merge-pull`, judged on its head, the branch's protection and the runs at its build-input + fingerprint, which refuse it only where a `required` step failed and are never waited for; the pipeline then runs on the landed commit, and only its `required` steps, the `approval` step where a policy names it among them, hold the delivery (ADR 0666 §5, §6; *Pipelines per module*). The trunk is still what runs, on each module's watched branches, which a placement chooses. @@ -452,15 +453,19 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l ### A module's registration - **What it holds.** The seat `mesh-catalog` keeps each module's **registration**: its git origin, the path of its - manifest, its watched branches and its policy, as a ledger on the bus (ADR 0595's template `ledger`), one instance - per module, every version an operation with who changed it and the warrant of the operator's Approve (ADR 0666 §2). + manifest, its watched branches and its policy, on the bus, every version with who changed it and the warrant of the + operator's Approve (ADR 0666 §2). The indexer is a foundation part, so the registrations are kept in its old sections + (ADR 0619 §1 to §3, ADR 0666 §2): one key per module in its old `state` section `registrations`, and every version on + its old `streams` section's stream `registration-history`, kept with no age limit. The catalog graph is derived from the registrations and the manifests they point to; the mesh knows modules, and a repository only as a module's git origin. - **Changing one is a trusted act.** The seat's verbs `register` (a module whole), `policy` (one module's step statuses, per artifact), `watch` and `unwatch` (add or remove a watched branch) each raise an authorising ask of tier approve through the seat `operator-channel` (design 46 §10), naming every value the change moves, one line each - ("`mesh-grants:program` unit tests: `required` → `bypass`"), and write the operation only on its warrant; a Decline or - an expiry writes nothing (ADR 0666 §2). A manifest moved to another path is the one manifest change that changes the + ("`mesh-grants:program` unit tests: `required` → `bypass`"), and write the version only on its warrant; a Decline or + an expiry writes nothing (ADR 0666 §2). Until a record binds each forge account to its bus identity, `register` and + `policy` refuse code review as a `required` step, naming why, so no review gates while its author cannot be told + (ADR 0666 §12; issue 1966, note 157). A manifest moved to another path is the one manifest change that changes the registration; any other manifest change is a commit, judged at its revision. - **Said and read.** Each written change is said as the seat's event `registration-changed` (the module, the version, what moved); the verb `registrations` answers every registration, or one with its history. The indexer derives the @@ -479,15 +484,17 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l judged until then: lint, unit tests, integration tests and composition `required`, code review `optional`, approval `bypass`; it raises them as one ask naming every registration, as the seat `mesh-module-assigner`'s `adopt` proposes placement whole (ADR 0567). Until that Approve the runner starts no delivering pipeline and says why, so the - operator is told of this one ask before G's delivery starts. -- **Kept for the life of the mesh**, never derived again (research 086, choice 25): the ledger's cap is 64 MiB. About - 120 registrations of about 1 KiB, and an estimated change a week each (a guess, not a measure), grow about 6 MiB a - year, so the cap holds about ten years; past 80 % the indexer says `filling`, as every store of *Two graphs, one + operator is told of this one ask before G's delivery starts. A Decline or an expiry leaves the seed unwritten and + says so; the indexer's tool `indexer_seed_again` raises the ask again, recorded in the hand-act log. +- **Kept for the life of the mesh**, never derived again (research 086, choice 25): the history stream's cap is 64 MiB. + About 120 registrations of about 1 KiB, and an estimated change a week each (a guess, not a measure), grow about 6 MiB + a year, so the cap holds about ten years; past 80 % the indexer says `filling`, as every store of *Two graphs, one source of truth* does. - **How it is checked.** Whole (indexer): an unprotected watched branch is refused, naming it; a policy change without the warrant writes nothing, and a declined one writes nothing; a change from `required` to `bypass` asks, showing that line; `registration-changed` is said and `registrations` answers the history; the first start proposes the seed - as one ask. Unit (the Go build module's lint step): a module name in a string, a constant and a table is refused, an + as one ask, and `indexer_seed_again` asks it again after a Decline and after an expiry; a policy making code review + `required` is refused. Unit (the Go build module's lint step): a module name in a string, a constant and a table is refused, an import path is not. Tests 75, 68 and 83. ### Watched branches and the catalog graph per branch @@ -496,11 +503,14 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l registrations name, through the seat `git`'s event `branch-moved` (a branch's new head, from the forge's push webhook, which a merge and an admitted push alike say), and takes the commit from the forge's own record by the seat's verb `branch`, never from the event's body (ADR 0666 §3). One event for every way a branch moves, because a merge is - not the only one. At its start it reads each watched branch's head the same way. + not the only one. `branch-moved` is kept on the seat's stream `SEAT_git_branch-moved`, which the bridge hears through + a durable consumer, so a move said while the bridge is down is heard when it starts; at its start it also reads each + watched branch's head the same way. - **A head with no pipeline is a finding.** A watched branch's head that starts no pipeline within five minutes is the watchman's finding `pipeline-stands`, naming the branch and its head, raised by the condition keeper (ADR 0564 §2), unless it waits as progress not owed: a member of a gathered group is governed by ADR 0633 §5's 30-minute bound, and - a merge behind a pending revision of the same branch by its 60-minute bound (ADR 0666 §13). + a merge behind a pending revision of the same branch by its 60-minute bound (ADR 0666 §13). The finding clears on the + runner's `pipeline-started` for that head. - **The catalog graph per watched branch.** The indexer keeps the catalog graph once per watched branch, from that branch's manifests at each source revision (ADR 0666 §3): each revision names its branch, and the stores, caps and pins of *Two graphs, one source of truth* hold per branch. @@ -509,7 +519,10 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l assigner computes each node's entries from the catalog graph of the branch its placement names, so a module watched on `main` and `beta` runs `beta` only where a placement chose it. - **A source revision per watched branch.** The gate keeps one source revision per watched branch, `source.`, - in place of `source.main` (ADR 0429 §11 to §13 as ADR 0666 §3 changes them), and serves it by the seat + in place of `source.main` (ADR 0429 §11 to §13 as ADR 0666 §3 changes them), in the old `state` section `source` + already holds, its key's layout being the only change. The gate is no foundation part: the bus module's delivery + waits on no act of the gate's, since the indexer takes a revision in from the forge bridge's stream and the assigner + writes wants from the runner's events, so the gate's other kept data stay in ADR 0595's templates (ADR 0666 §2), and serves it by the seat `mesh-delivery`'s verb `source` with the branch, saying `source-moved` on each new revision; the indexer and the node-engine's catch-up read it there, never the gate's state (ADR 0596). Each want names a build-input fingerprint computed at one such revision. @@ -527,12 +540,15 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l read at its start. Whole (indexer, assigner): a commit on `beta` gives a revision of the `beta` graph only and moves only the want of the node whose placement chose `beta`; a revision whose own validator refuses it stays pending and holds `beta` while `main` moves on. Whole (watchman): a head with no pipeline for five minutes raises - `pipeline-stands`, and a gathered member does not. Tests 64, 68, 78 and 82. + `pipeline-stands`, cleared by `pipeline-started` for that head, and a gathered member does not; a move said while the + bridge was stopped is heard from the seat's stream. Tests 64, 68, 76, 78 and 82. ### Pipeline steps and the policy - **The runner.** The seat `mesh-pipeline-runner`, held once for the mesh by the module `mesh-delivery-pipeline`, - runs each pipeline (ADR 0666 §4). It reads the policy from the registrations, asks each step that is not `bypass` of + runs each pipeline (ADR 0666 §4). It is a foundation part, since the bus module's own delivery waits on its pipeline + (ADR 0666 §2): its kept data are in old sections (ADR 0619 §2), it waits on no bus module process to start, and it + joins the manifest validator's list of foundation parts, which refuses its manifest asking a template. It reads the policy from the registrations, asks each step that is not `bypass` of the seat that serves it, and says each step's start and end and the pipeline's end (*Health and going back*, below). - **The steps and who serves them.** Lint, unit tests and integration tests are the build seats' (`node-build-go`, `node-build-node`, `node-build-image`): each gains the verb `steps`, which answers which pipeline steps an artifact @@ -546,8 +562,12 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l kept in the registration and never in a manifest: the manifest validator refuses a manifest that names a status (ADR 0666 §4; research 086, R3). A `required` step that ends `nothing to run` holds the delivery and names the step. - **Asked on a work queue, ended by an event.** The runner asks each step on the serving seat's work queue and hears - its end as that seat's event `step-ended` (the record's `step ended`), through a durable consumer of its own, so a - step outlives a restart of either side (ADR 0666 §4). A step's outcome is one of `passed`, `failed`, `nothing to run`, + its end as that seat's event `step-ended` (the record's `step ended`), on + `mesh.seat..event.step-ended.`, the node that ran it in the subject and each holder's account granted only + its own node's subject, through a durable consumer of its own, so a step outlives a restart of either side (ADR 0666 + §4, ADR 0363 §2). A build seat's holder restarted mid-step gets the step again from its work queue and finishes it + (ADR 0664 §1). A unit or integration test step says its test counts in `step-ended`, and `pipeline-ended` names any + repository over 50 integration or 500 unit tests, and any catalog module over them (ADR 0666 §4; the test budget). A step's outcome is one of `passed`, `failed`, `nothing to run`, `bypassed`, `carried` (with the pipeline it was carried from), `could not run` (naming the part not heard), `waiting on `, `accepted` (a failed `optional` step a person accepted, with who and why), `superseded` and `cancelled`. @@ -558,14 +578,20 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l - **Approval comes last.** The runner asks the `approval` step only once every other `required` step of the pipeline passed, so the operator approves a commit the mesh already judged, the one place ADR 0661 §3 had the check gate the ask. A failure after an approval is said, as a failed `optional` step is, and the approval stays. -- **Kept on the bus.** The runner keeps each pipeline's state in its state `pipelines` (a state template), its step log - in its log `step-log` (a log template), and each package's passing result per level in its state `kept`, under the - digest of what its tests read (ADR 0666 §4; *The runner's kept data*, below). +- **Kept on the bus, in old sections.** The runner keeps each pipeline's state in its old `state` section `pipelines`, + one key per pipeline keyed by its watched branch, source revision and module, written by compare-and-set so a holder + replaced mid-pipeline and its successor never both write one; its step log on its old `streams` section's stream + `step-log`; each step's output in its old `objects` section `step-outputs`, named in the log; and each package's + passing result per level in its old `state` section `kept`, under the digest of what its tests read (ADR 0666 §2, §4; + *The runner's kept data*, below). At its first start it takes the checker's kept verdicts into `kept`, read by the + checker's tool `checker_kept`, so the first pipelines after G carry what the checker had judged. - **How it is checked.** Whole (runner): a step with unchanged fingerprint and policy is carried and says from where, 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. Whole (Go build module): `steps` answers the steps of a fixture artifact, and a - `step` ask ends with `step-ended`. Unit (manifest validator): a manifest naming a status is refused. Tests 65, 66, 73 + 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` + 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. ### What holds a delivery @@ -575,56 +601,73 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l writes a want only from a source revision whose every `required` step passed for the modules it moves, on the watched branch a placement chose, by compare-and-set on a newer revision, so an older revision ending after a newer one writes nothing (ADR 0666 §5). This is one more rule beside the assigner's others (ADR 0429 §6), checked per module. - From G's delivery it replaces the trunk-only want (ADR 0656 §2 as ADR 0666 §5 changes it). + From G's delivery it replaces the trunk-only want (ADR 0656 §2 as ADR 0666 §5 changes it). For a group's source + 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 §5). - **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. -- **A newer commit supersedes an older pipeline.** On a newer commit of the same watched branch the runner ends the - older running pipeline as `superseded` and drops its waiting asks by each build seat's `drop` (ADR 0664 §4), naming +- **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 §5); a module the commit leaves as it was finishes its + pipeline. A newer publish of a package likewise supersedes the rebuild pipelines an older publish of it started. A + superseded pipeline's waiting asks are dropped by each build seat's `drop` (ADR 0664 §4), naming the newer commit as the cause, so a cancelled pipeline leaves no ask on a stream (a gap G's prepare found: a cancelled build withdrew only the builder's wait). - **A step nothing starts ends its pipeline.** A step whose prerequisite nothing starts (a seat with no holder, a prerequisite step `bypass`) ends the pipeline refused within five minutes, naming the step and what it waits for, never as a silent wait (research 086, R5); a step whose seat has no holder ends its pipeline failed, naming the seat (ADR 0666 §11). +- **A failed head is said to its author, then to the operator.** A `required` step that failed, or ended `could not + run`, on a watched branch's head is the runner's finding `pipeline-failed`, naming the module, the branch, the commit + and the step; the condition keeper raises it as the commit's author's for two hours and then the operator's, as ADR + 0505 §5 and §6 have a delivery whose cure is its author's new head, and clears it when a newer revision of that branch + passes that step (ADR 0666 §13). The author is the forge's record of the commit, read through the seat `git`. - **The delivery record keeps every step.** The gate's delivery record consumes the step and pipeline events and keeps them as long as the record (ADR 0666 §5; *The delivery record*). - **How it is checked.** Whole (assigner): a failed `required` step writes no want; a failed `optional` step holds - nothing; an older revision's `pipeline-ended` after a newer one's writes nothing. Whole (runner): a newer commit - supersedes the older pipeline and its asks are dropped; a step with no holder ends the pipeline naming the seat within - five minutes. Tests 66, 67, 87 and 89. + nothing; an older revision's `pipeline-ended` after a newer one's writes nothing; a group with one member passed and + another still running writes no want until `group-ended`. Whole (runner): a newer commit that changed a module's + fingerprint supersedes its older pipeline and drops its asks, and one that left it unchanged lets it finish; a step + with no holder ends the pipeline naming the seat within five minutes; a failed `required` step on a head raises + `pipeline-failed`, the author's for two hours and then the operator's, cleared by a newer passing revision. Tests 66, + 67, 87, 89 and 98. -### Approval is a step, and a session merges its own pull request +### Approval is a step, and a session merges a pull request - **No Approve per merge.** The operator's approval is the pipeline step `approval`, its status in each module's policy; no Approve is asked per merge, and the delivery gate's merge turns and its Approve per merge go (ADR 0666 §6, which changes ADR 0661 §3 to §5). The operator is asked only where a module's policy says `approval`, and for registrations and policy changes. - **The approval is an ask of the runner's.** The runner raises an authorising ask of tier approve on the seat - `operator-channel` under its own name, its `about` the module, the watched branch and the commit, so a newer commit's - ask replaces the older one's (design 46 §10); the warrant ends the step passed, a Decline ends it `declined`. Only a - declined `approval` step is asked again, by the runner's verb `ask-again` (ADR 0666 §6). While it waits the runner + `operator-channel` under its own name, its `about` the module and the watched branch only, so a newer commit's ask + replaces the older one's (design 46 §10). The warrant ends the step passed; an ask that is declined, expires or is + refused ends it `declined`, and one that is replaced ends it `superseded`. Only a declined `approval` step is asked + again, by the runner's verb `ask-again` (ADR 0666 §6). While it waits the runner says `wait-held` waiting on the operator, never a stall (ADR 0283). -- **A session merges its own pull request.** A session merges by calling the seat `git`'s verb `merge-pull` over the - mesh, which merges with the forge tools' account (ADR 0398 §2) at the head the caller names. It judges that this is - still the pull request's head and that the branch's protection refuses a direct push, and it reads the head's latest - run by its modules' policies: it refuses a head on which a step a policy marks `required` failed, and merges a head - whose `required` steps passed or that has no run yet, a failed `optional` or a `bypass` step refusing nothing; it never - waits for a run and never asks an Approve (ADR 0666 §6). The forge keeps only its branch protection. -- **The latest run, read through the runner's seat.** The holder of the seat `git` reads it by the seat - `mesh-pipeline-runner`'s verb `list` with the head's commit, declared in its `invokes`, so the order of their builds - is an edge of kind 6; the latest run is the newest run on request or pipeline naming that commit, a group's naming - every member's head. A run still running is judged by the steps it has ended: one `required` step already failed - refuses the merge, and anything else merges, since the merge never waits. A refusal names the run, the module and the - step, so the session knows what to fix; an unanswered read of the runner refuses too, naming it, since a head whose - run cannot be read is not known to have passed (research 086, R8). The gate merges nothing, and its forge merge token is +- **A session merges a pull request.** Any session the tool runner proves, and the operator, merges by calling the seat + `git`'s verb `merge-pull` over the mesh, which merges with the forge tools' account (ADR 0398 §2) at the head the + caller names. It judges that this is still the pull request's head and that the branch's protection refuses a direct + push, the protection read again on every `branch-moved` of the branch, and it judges the head's runs by its modules' + policies: it refuses a head when any run at its build-input fingerprint failed a step a policy marks `required`, and + merges a head whose `required` steps passed or that has no run yet, a failed `optional` or a `bypass` step refusing + nothing; it never waits for a run and never asks an Approve (ADR 0666 §6). The forge keeps only its branch protection. +- **Judged from its own state, never by a call.** The holder of the seat `git` consumes the runner's `step-ended` + through a durable consumer of its own and keeps, in its own state `failed-steps`, each failed `required` step by + module and build-input fingerprint, with the commits it was seen at and the run that failed it, for 30 days; so a head + merges while the runner is down, judged on what it already heard (ADR 0666 §6, ADR 0596). A head's fingerprints are + those its runs named for its commit; a step that failed at that fingerprint in any run, a group's or another commit's + of the same content included, refuses it. A run still running is judged by the steps it has ended, since the merge + never waits. A refusal names the run, the module and the step, so the session knows what to fix. The gate merges nothing, and its forge merge token is removed by G's delivery (ADR 0667 §6); the forge bridge hears the landed commit as it hears every commit of a watched branch. - **The operator-channel hides no ask.** It keeps design 46's three open asks per asker, never holds the newest back, and replaces an open ask by the same asker's ask with the same `about` (ADR 0666 §6; design 46 §6). - **How it is checked.** Whole (forge module, forge bridge): a session's `merge-pull` at its head merges with no run yet, - and with a passed one, and asks no Approve; a head whose latest run failed a `required` step, a head that moved and a - branch without protection are refused, each naming why; a failed `optional` step refuses nothing. Whole (runner): an `approval` step is - asked last, a Decline ends it `declined`, `ask-again` asks it once more, and a newer commit's ask replaces the older. + and with a passed one, and asks no Approve; with the runner stopped a head merges; a head at whose fingerprint any + run failed a `required` step, a head that moved and a branch whose protection was removed since its last move are + refused, each naming why; a failed `optional` step refuses nothing. Whole (runner): an `approval` step is asked last, + a Decline and an expiry each end it `declined` and `ask-again` asks it once more, and a newer commit's ask replaces the + older and ends its step `superseded`. Live: a declined approval and a fourth ask each reach the operator. Tests 71 and 91. ### Groups @@ -702,14 +745,22 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l replaced value leaves one object. - **One object store per state, granted to its owner.** Each state asked by the template `state` gets its object store beside it, `-objects`, a template form of ADR 0595 that the bus module provides and the grants part grants to - the state's owner alone (ADR 0666 §10). Its size is the template's (ADR 0595 §3). + the state's owner alone (ADR 0666 §10); a foundation part's large values go in an old `objects` section of its own. + Its size is the template's (ADR 0595 §3). An object store holds no space until a value is written to it, so the many + it adds reserve nothing; the few values over the limit (a delivery record, a catalog graph revision list, a test's + output) are estimated, as a guess, at under 1 GiB across the mesh. +- **An object sent is readable by the module it is for.** A reply's or an event's object is written to the sender's + object store, and the grants part grants the read of that one object's name to the module the reply or the event is + for: a reply's caller, an event's consumers as their `consumes` declare them (ADR 0666 §10). A consumer's reader of + the form is delivered before its producer writes it, an edge of kind 4. - **Its tools are the runtime's.** mesh-sdk's runtime serves every module `_state_objects` (the objects of each - state, with their size and the key that names each) and `_state_objects_drop` (drop the objects whose key is - gone, recorded in the hand-act log). + state, with their size, the key that names each and the fill against its cap) and `_state_objects_drop` (drop + the objects whose key is gone, recorded in the hand-act log). - **Its cost.** A change of mesh-sdk's runtime rebuilds every module once, said to the operator with G's delivery. - **How it is checked.** Whole (mesh-sdk, against the real bus): values of one, ten and a hundred times the per-value - limit stored, sent as a reply and as an event, and read back whole; a replaced large value leaves one object; a key - deleted takes its object. Tests 69 and 90. + limit stored, sent as a reply and as an event, and read back whole by another module that the reply or event is for, + and refused to a module it is not for; a replaced large value leaves one object; a key deleted takes its object. + Tests 69 and 90. ### The pipeline makes the check, and the checker goes @@ -720,10 +771,12 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l change alters runs from the change's build of it, built within 20 minutes or ending `waiting for a build node` or `did not build`, the first tier of *The check on the change's own acting parts* made the runner's. - **The run on request.** The runner's verb `run` takes one or more members, each a module at a named commit, runs them - through their pipelines and delivers nothing, replacing the checker's try (ADR 0666 §11). The runner says - `run-started`, the indexer builds the run's candidate from it, and the candidate's composition step writes no want - (ADR 0656 §9); the candidate is dropped on that run's `pipeline-ended`. A step that could not run ends `could not - run`, never as passed. A composition step for a node that sleeps passes it with a warning (ADR 0593 §9). + through their pipelines and delivers nothing, replacing the checker's try (ADR 0666 §11). Its callers are the + sessions, as the agents' bus identities the tool runner proves, and the operator, and nothing else, since a run of a + group builds and publishes its packages' tagged versions (design 51). The runner says `run-started`, the indexer builds + the run's candidate from it, and the candidate's composition step writes no want (ADR 0656 §9); the candidate is + dropped on that run's `pipeline-ended`. A step that could not run ends `could not run`, never as passed. A + composition step for a node that sleeps passes it with a warning (ADR 0593 §9). - **The runner is an acting part in the checker's place.** The acting rule's step `check` becomes the runner's step `pipeline` (*What ADR 0656 leaves to this design*): its own change runs on its own new version, a failing new runner holds while the old one runs pipelines (ADR 0656 §4), and the pipelines in flight when its holder is replaced are @@ -735,35 +788,42 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l | the merge check, one status `mesh/check` | the pipeline, its result in `pipeline-ended`, the runner's `show` and the delivery record; no status on the forge | | the try | the run on request | | the composition check | the composition step, the assigner's | - | the kept verdicts and the carry | the runner's `kept` and its carry (ADR 0548 §5) | - | the checking program: the manifest validator at the heads, the cycle rule, the composer, the rule names | the indexer's validation before take-in; the indexer's cycle rule; the composition step; the pipeline's end naming a change to the runner, step detection or the lint rule | + | the kept verdicts and the carry | the runner's `kept`, taken from the checker's at the runner's first start, and its carry (ADR 0548 §5) | + | the checking program: the manifest validator at the heads, the cycle rule, the composer, the rule names | the indexer's validation before take-in; the indexer's cycle rule; the composition step; `widens` in the pipeline's end | | the `run` ask, published by the checker's account | published by the runner's account and the indexer's (its validation), each with step keys under its own name | - | its buckets and bus account | removed after a backup by G's delivery (ADR 0667 §6) | + | its buckets and bus account | removed after the first pipeline after G's delivery has delivered a change end to end, after a backup kept 90 days whose restore is tested, the operator told before (ADR 0667 §6) | -- **How it is checked.** Whole (runner, assigner): a run on request of `feature/1966-x` delivers nothing; a composition - step refuses two modules owning one path; a step whose part cannot be heard ends `could not run`; a node asleep passes - with a warning; a runner stopped mid-step takes its pipelines up again. Live: after G's delivery no module claims - the seat `mesh-delivery-checker`. Tests 64, 84 and 88. +- **How it is checked.** Whole (runner, assigner): a run on request of `feature/1966-x` delivers nothing, and a call of + `run` from another account is refused; a composition step refuses two modules owning one path; a step whose part + cannot be heard ends `could not run`; a node asleep passes with a warning; a runner stopped mid-step takes its + pipelines up again. Live: once the checker is removed no module claims the seat `mesh-delivery-checker`. Tests 64, + 84 and 88. ### Who may say what - **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 §12). 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). + source of caller limits; the runner's verbs are the first (ADR 0666 §12). 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 + 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). - **A step's result from its holder only.** The runner takes a step's result only from the bus account of that step's seat holder, naming the commit and the build-input fingerprint; a result from another account, or naming another commit or fingerprint, is refused and said (ADR 0666 §12). -- **A review gates.** A code review's result is taken through the verb `review` from the reviewer's bus account and - refused from the commit's author, so a review gates where the policy says `required` (ADR 0666 §12, which changes ADR - 0659 §2). -- **A widening is said, never refused.** A change that alters the runner, step detection or the lint rule, or widens an - acting rule, a grant or a credential, says so in its `pipeline-ended`, its field `widens` naming each; nothing refuses - it for that (ADR 0666 §12, the operator, 2026-11-10). This is what replaces ADR 0656 §8's naming in the Approve ask. +- **A review gates, once it can.** A code review's result is taken through the verb `review` from the reviewer's bus + account and refused from the commit's author, so a review gates where a policy says `required` (ADR 0666 §12, which + changes ADR 0659 §2). Until a record binds each forge account to its bus identity no policy may say it (*A module's + registration*; issue 1966, note 157). +- **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 + 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 §12, 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. - **How it is checked.** Whole (runner, grants part): a forged step result and an author's own review are refused; a - caller not in a verb's `callers` is refused by the bus; a change widening a grant names it in `widens` and is - delivered. Tests 85 and 86. + caller not in a verb's `callers`, and any caller but the holder roles and the operator of a verb with no `callers`, + are refused by the bus; a change widening a grant, and one altering the Go build module's test runner, each name it in + `widens`, computed by the running runner, and are delivered. Tests 85 and 86. ### Health and going back @@ -773,30 +833,37 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l | Event | Says | |---|---| - | `pipeline-started`, `pipeline-ended` | a pipeline's start, and its end with every step's result, the source revision and `widens` | - | `group-ended` | a group's one pipeline's end, apart from each module's | + | `pipeline-started`, `pipeline-ended` | a pipeline's start, and its end with every step's result, its test counts, the source revision and `widens` | + | `group-ended` | a group's one pipeline's end, on which alone its wants are written | | `run-started` | a run on request's start, with its members at their commits | - | `step-started`, `step-ended` | each step's start and end: the step, its status in the policy, its outcome, its build-input fingerprint, and for a carried result what it was carried from; a bypassed step too | + | `step-started`, `step-ended` | each step's start and end: the step, its status in the policy, its outcome, its build-input fingerprint, its test counts, and for a carried result what it was carried from; a bypassed step too | | `wait-held`, `wait-ended` | a step's wait: on a person (approval, code review), on a build node, on the revision view | +- **What a session hears after its merge.** Between its `merge-pull` and the delivery, a session waits with `mesh_wait` + on the runner's `pipeline-started` and `pipeline-ended` of its module, branch and commit, and then on the status + view's `delivered` of the source revision; a failed head reaches it as `pipeline-failed` (*What holds a delivery*). - **Nothing stands still unseen.** The watchman times each step's owed progress from `wait-held` and `step-started`, never by run length; a step or a watched branch's head standing still five minutes is its finding `pipeline-stands`, - raised by the condition keeper and cleared on the step's end (ADR 0564 §2, §4). A step waiting on a person is said as - waiting on that person (ADR 0283), never as a stall; a group waiting for its members, and a merge behind a pending - revision, are governed by their own bounds (ADR 0666 §13). At its start the watchman seeds its open waits from the - runner's `stands`, as it seeds `take-in-waits` from `indexer_pending`. + raised by the condition keeper and cleared on the step's end, or for a head on its `pipeline-started` (ADR 0564 §2, + §4). A step waiting on a person is said as waiting on that person (ADR 0283), never as a stall; a group waiting for + its members, and a merge behind a pending revision, are governed by their own bounds (ADR 0666 §13). At its start the + watchman seeds its open waits from the runner's `stands`, as it seeds `take-in-waits` from `indexer_pending`. +- **The runner's own health.** Its manifest declares its health check, run outside its process (ADR 0240): the runner + answers `show`, and its durable consumers of `step-ended`, `take-in.taken`, `package-published` and `decided` are + each less than five minutes behind; a failed check names which. - **The runner waits for its view.** With no revision view it says so in `_first_views` and raises `view-waits` after five minutes, as every part does (ADR 0656 §6). - **Going back is one act.** A failing new version holds while the old keeps running (ADR 0656 §4); a return to an earlier build is one value in the placement, the module's `build` in its placement key, set by a placement proposal (ADR 0666 §13). - **How it is checked.** Whole (runner, watchman): a step whose worker dies raises `pipeline-stands` within five minutes; - a step waiting on the operator raises nothing; a runner restarted mid-step takes its pipelines up again. Whole + a head with no pipeline raises it and its `pipeline-started` clears it; a step waiting on the operator raises nothing; + a runner restarted mid-step takes its pipelines up again; its health check fails naming a consumer behind. Whole (assigner): a placement's `build` delivers the earlier build. Tests 76, 77 and 88. ### A recovery fix is an ordinary merge -- **No recovery merge verb.** A fix that recovers the mesh is merged like any change on a watched branch, by its +- **No recovery merge verb.** A fix that recovers the mesh is merged like any change on a watched branch, by a session's `merge-pull`, and runs its pipeline; no trusted recovery merge verb is built (ADR 0666 §15). The shape this design sketched for one (a verb `merge` of the seat `mesh-delivery` with `recovery-callers`) is dropped. - **Named a recovery, said everywhere.** Its author names it a recovery by the seat `mesh-delivery`'s verb `recovery` @@ -809,12 +876,15 @@ check and deliver milestone G itself (ADR 0667 §2); each of them says so in a l ### The tools Every new state has a tool that reads it and every new act a tool that starts it by hand (ADR 0666 §14), against the -four lines a module's tools answer: +four lines a module's tools answer; every read tool of a store also answers its fill against its cap: | Part (seat) | Read everything it holds | Do by hand what it does itself | Recover without help | |---|---|---|---| -| the runner (`mesh-pipeline-runner`) | `show` (one pipeline whole, its steps and step log), `list` (the pipelines of a module or branch), `stands` (what stands still, since when), `why-carried` (where a step's result was carried from), `kept` (the kept results by digest) | `start` (a delivering pipeline for a watched branch's head), `run` (the run on request), `rerun` (one step again) | `accept` (a failed `optional` step, with why), `cancel` (a pipeline, dropping its asks), `ask-again` (a declined `approval`) | -| the indexer (`mesh-catalog`) | `registrations` (with each one's history); `indexer_edges` (an artifact's edges per watched branch), `indexer_order` (the order of a change, its cycles named), `indexer_catalog_difference` (two revisions); `indexer_pending` (a group with its missing members) | `register`, `policy`, `watch`, `unwatch` (each on the operator's Approve) | `indexer_take_in_pending` (a group taken in as gathered), `indexer_drop_pending` (dropped) | +| the runner (`mesh-pipeline-runner`) | `show` (one pipeline whole, its steps, step log and outputs), `list` (the pipelines of a module, a branch or a commit), `stands` (what stands still, since when), `why-carried` (where a step's result was carried from), `kept` (the kept results by digest) | `start` (a delivering pipeline for a watched branch's head), `run` (the run on request), `rerun` (one step again) | `accept` (a failed `optional` step, with why), `cancel` (a pipeline, dropping its asks), `ask-again` (a declined `approval`) | +| the indexer (`mesh-catalog`) | `registrations` (with each one's history); `indexer_edges` (an artifact's edges per watched branch), `indexer_order` (the order of a change, its cycles named), `indexer_catalog_difference` (two revisions); `indexer_pending` (a group with its missing members) | `register`, `policy`, `watch`, `unwatch` (each on the operator's Approve) | `indexer_seed_again` (the first registrations' ask raised again), `indexer_take_in_pending` (a group taken in as gathered), `indexer_drop_pending` (dropped) | +| the gate (`mesh-delivery`) | `source` with a branch (`gate_source`: every branch's source revision) | — | `gate_source_again` (say `source-moved` again for a branch) | +| the forge module (`git`) | `git_failed_steps` (the failed `required` steps it holds, by module and fingerprint, with the run that failed each) | — | `git_failed_steps_drop` (drop one, with why) | +| the grants part (`mesh-grants`) | `grants_callers` (the callers each verb admits, read from the seat definitions) | — | `grants_why_refused` (for an account and a verb, the grant it lacks and the definition's line that leaves it out) | | the build seats | `steps` (the steps detected for an artifact) | `steps` with `again` (detect again) | `drop` (ADR 0664 §4) | | the builder (`mesh-builds`) | `builder_versions` (a package's published versions) | `builder_publish_again` | — | | the assigner (`mesh-wants`) | `assigner_why_not` (why a module is not on a machine yet: the pipeline it waits for, its hold, the placement, the node's last `running`) | — | `assigner_release` | @@ -823,30 +893,39 @@ four lines a module's tools answer: | every module (mesh-sdk's runtime) | `_state_objects` | — | `_state_objects_drop` | Every recover tool writes its act, who and why in the hand-act log of the seat `mesh-hand-acts`. How it is checked: -each tool answers its whole-module test's case, and `mesh_describe` reads each (test 93). +each tool answers its whole-module test's case, every store's read answers its fill, and `mesh_describe` reads each +(test 93). ### The runner's kept data, and the build capacity -Each kept form names its template, its retention and its cap where the template takes one; a state template fixes its -own size (ADR 0595 §3), up to 64 MiB. The numbers are estimates, read from the fill tools once G runs: an estimated 20 -deliveries a day (as *The delivery record*), about 5 modules each, about 6 steps each. +Each kept form names its section or template, its retention and its cap; a state template fixes its own size (ADR 0595 +§3), up to 64 MiB. The numbers are estimates, to be read from the fill tools once G runs: an estimated 20 merges a day +(as *The delivery record*), each starting a pipeline for about 3 modules of its repository whose fingerprint it changes, +and an estimated 2 mesh-sdk publishes a day, each rebuilding about 120 artifacts and starting about 120 pipelines: about +300 pipelines a day, of about 6 steps each. -| Part | Kept data | Template | Retention | Cap and growth | +| Part | Kept data | Section or template | Retention | Cap and growth | |---|---|---|---|---| -| the runner | `pipelines`: one key per pipeline (`..`), its steps, statuses, outcomes and fingerprints | state | while its record is kept (90 days, the gate's `record-retention`) or it is its branch's newest | the template's 64 MiB; about 100 pipelines a day of about 4 KiB is about 36 MiB at 90 days | -| the runner | `step-log`: one entry per step's start and end, a step's output by its object's name | log | 90 days | 256 MiB; about 6,000 entries a day of about 0.2 KiB is about 110 MiB at 90 days | -| the runner | `kept`: a package's passing result per level, by digest | state | 30 days unread | the template's 64 MiB | -| the indexer | `registrations` | ledger | the life of the mesh, never derived again | 64 MiB (*A module's registration*) | +| the runner | `pipelines`: one key per pipeline, keyed by watched branch, source revision and module, its steps, statuses, outcomes, fingerprints and test counts | old `state` section | 30 days, or while it is its branch's newest for its module; the delivery record keeps its own copy of the events for 90 | 128 MiB; about 300 pipelines a day of about 4 KiB is about 36 MiB at 30 days | +| the runner | `step-log`: one entry per step's start and end, its output by name | old `streams` section | 30 days | 64 MiB; about 3,600 entries a day of about 0.2 KiB is about 22 MiB at 30 days | +| the runner | `step-outputs`: a lint or test step's output | old `objects` section | 7 days | 1 GiB; about 1,200 steps run a day (the rest carried) of about 50 KiB is about 420 MiB at 7 days | +| the runner | `kept`: a package's passing result per level, by digest | old `state` section | 30 days unread | 128 MiB; a publish changes the digest of about 1,000 importing packages at two levels, so about 4,000 entries a day of about 0.3 KiB, about 36 MiB at 30 days | +| 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 | state | 64 revisions of each key | the template's 64 MiB | -| every module | `-objects` beside each state | objects | with its key | the template's | +| the gate | `source`: one key per watched branch | its old `state` section, as today | 64 revisions of each key | a few KiB | +| the forge module | `failed-steps`: failed `required` steps by module and fingerprint | state | 30 days | the template's 64 MiB; an estimated 50 failed steps a day of about 0.5 KiB is under 1 MiB at 30 days | +| every module | `-objects` beside each state | objects | with its key | the template's; nothing reserved until written | **The build capacity.** A pipeline runs a module's steps once per commit on a watched branch, carrying what did not change, where the check ran before the merge and carried after each trunk move; a group runs one pipeline per watched -branch; a second watched branch runs the steps of the modules it carries once more. The pipeline steps go on the build -seats' stream `check`, after `delivery` and before `recheck`, within each node's build capacity (ADR 0525 §4, §5), and -a run on request on the same stream; nothing else claims capacity, so the build nodes do no more work than the check -did, and less where a change was checked before its merge and again after. +branch; a second watched branch runs the steps of the modules it carries once more. A mesh-sdk publish asks about 120 +lint steps and the test steps of the importing packages, about 240 more, the rest carried; a newer publish of the same +package supersedes the older one's rebuild pipelines, so two publishes close together run the rebuilds once. The first +pipelines after G's delivery run every module once, but carry every package whose digest the checker's kept verdicts, +taken into `kept`, already hold, so they run only what changed since. The steps go on the build seats' stream `check`, +after `delivery` and before `recheck`, within each node's build capacity (ADR 0525 §4, §5), and a run on request on the +same stream. How it is checked: live, the build nodes' time per day in the week after G, read from the build modules' +step keys and the builder's build log, against the checker's last week (test 99). ### How milestone G itself is checked and delivered @@ -865,42 +944,55 @@ did, and less where a change was checked before its merge and again after. stream; the bus module, with `-objects` and its grant to the owner alone, before the modules requiring it, the grants part writing that grant from the milestone's heads. A restart of the bus its new version needs is said to the operator before it starts. +- **The new assigner before the new merge.** The new assigner, which writes a want only from a passed pipeline, is + delivered before the forge module's new `merge-pull`, which asks no Approve, and before the runner: an edge of kind 4 + from `mesh-delivery-assigner` to each, declared in their manifests' `needs` since nothing else says it. Without it a + merge made with no Approve could reach the old assigner, which writes wants from the trunk with no pipeline. - **A gap is built, not worked around.** An order the delivery plan cannot derive from the edges is built in the delivery system within G; a node-engine of the version before applies every want whose manifests use no field it does not read, and a want that uses one waits for the new node-engine on that node (ADR 0667 §5). -- **What its delivery removes.** After a backup, the checker's buckets and bus account and the gate's forge merge token - (ADR 0667 §6). +- **What is removed, and when.** The checker's buckets and bus account and the gate's forge merge token are removed only + after the first pipeline after G's delivery has delivered a change end to end (test 63), after a backup of the buckets + kept 90 days, as the delivery records are, whose restore is tested, and the operator is told before it (ADR 0667 §6). - **Told to the operator before it starts**: one more Approve per merge under ADR 0661 for G's own group, then none; the - one ask of the seed registrations; a rebuild of every module for mesh-sdk's runtime; the bus's restart. -- **How it is checked.** Tests 94 to 97. + one ask of the seed registrations; a rebuild of every module for mesh-sdk's runtime; the bus's restart; and later the + checker's removal. +- **How it is checked.** Tests 94 to 97, and 100 for the assigner's edge. ### Choices this design makes under ADR 0666 and ADR 0667 | Choice | Why | |---|---| -| The registrations a ledger instance per module, capped at 64 MiB, kept for the life of the mesh | a registration has a history kept with who and on whose Approve (ADR 0666 §2); a ledger keeps every operation, and nothing derives a registration again | +| The registrations in the indexer's old `state` section with their history on an old stream, capped at 64 MiB, kept for the life of the mesh | the indexer is a foundation part (ADR 0619 §1 to §3, ADR 0666 §2); a registration keeps every version with who and on whose Approve, and nothing derives it again | +| The runner a foundation part, its kept data in old sections, on the manifest validator's list | the bus module's own delivery waits on its pipeline (ADR 0666 §2) | +| The gate no foundation part, its `source` in the old section it already has | the bus module's delivery waits on no act of the gate's; only the key's layout changes | | The verbs `register`, `policy`, `watch`, `unwatch`, `registrations` and the event `registration-changed` on `mesh-catalog` | one verb per trusted act, each its own ask naming what moves; readers follow the event (ADR 0596) | -| The seed of the first registrations proposed as one ask, with the statuses the check judged until then and approval `bypass` | registering is a trusted act (ADR 0666 §2), and one ask for the whole seed is how placement was adopted (ADR 0567); the statuses keep what was judged, and no Approve per merge is the operator's word | -| The seat `git`'s read verb `branch` and event `branch-moved` | registering reads a branch's protection through the seat `git` (ADR 0666 §2), and a branch moves by a merge or an admitted push, both of which start a pipeline | -| The watchman's finding `pipeline-stands` for a step or a head still five minutes | the record's five minutes (ADR 0666 §13), one finding for both, timed from the runner's events | +| The seed of the first registrations proposed as one ask, with the statuses the check judged until then and approval `bypass`, raised again by `indexer_seed_again` | registering is a trusted act (ADR 0666 §2), and one ask for the whole seed is how placement was adopted (ADR 0567); a declined or expired seed must not leave the pipelines stopped with no way on | +| Code review refused as `required` until forge accounts are bound to bus identities | a review is refused from its author (ADR 0666 §12), which cannot be told until then | +| The seat `git`'s read verb `branch` and event `branch-moved`, kept on its seat stream | registering reads a branch's protection through the seat `git` (ADR 0666 §2); a branch moves by a merge or an admitted push; a stream keeps a move said while the bridge is down | +| The watchman's finding `pipeline-stands` for a step or a head still five minutes, cleared by the step's end or the head's `pipeline-started` | the record's five minutes (ADR 0666 §13), one finding for both, timed from the runner's events | +| The runner's finding `pipeline-failed`, the author's for two hours, then the operator's | ADR 0666 §13 with ADR 0505 §5, §6 | | A module's watched branch and its `build` in the placement key, set by a proposal | a placement names the branch and a return is one value in it (ADR 0666 §3, §13); every placement change goes by a proposal (ADR 0567) | | The gate's `source.`, its verb `source` and event `source-moved` | one source revision per watched branch (ADR 0666 §3), read through the seat (G's prepare, the indexer's watch of the gate's `source`) | -| The build seats' verb `steps` and accepted kind `step` on `check`; the assigner's kind `step` on `mesh-wants` | steps are asked on the serving seat's work queue (ADR 0666 §4); the `check` stream already orders after `delivery` | -| The outcomes, with `accepted`, `superseded` and `cancelled` | every end a step can have is said as itself, never folded into passed or failed | -| `approval` asked last | the operator approves a commit the mesh already judged, the point ADR 0661 §3 kept in one place | -| A superseded pipeline's asks dropped by `drop` | a cancelled pipeline must leave no ask on a stream (ADR 0664 §4; G's prepare) | +| The build seats' verb `steps` and accepted kind `step` on `check`; the assigner's kind `step` on `mesh-wants`; `step-ended` with the node in its subject | steps are asked on the serving seat's work queue (ADR 0666 §4); the `check` stream already orders after `delivery`; a node's account says only its own node's ends (ADR 0363 §2) | +| The outcomes, with `accepted`, `superseded` and `cancelled`; an approval expired or refused ends `declined`, replaced `superseded` | every end a step can have is said as itself (ADR 0666 §6) | +| `approval` asked last, its `about` the module and the branch | the operator approves a commit the mesh already judged, the point ADR 0661 §3 kept in one place; one ask per module and branch, a newer commit's replacing it | +| A superseded pipeline's asks dropped by `drop`, and a pipeline superseded only when its module's fingerprint changed | a cancelled pipeline must leave no ask on a stream (ADR 0664 §4; G's prepare); a module the commit did not change has nothing newer to run (ADR 0666 §5) | +| A group's wants only on `group-ended` | a group is delivered whole or not at all (ADR 0666 §5; research 086, R5) | | 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 | | The cycle rule in the indexer's graph | the graph is the indexer's, and the checking program goes with the checker | | 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 §9); its waits move only when a later change gives the seat its verbs | -| Each state's object store `-objects`, and the runtime's two tools | one object store per state (ADR 0666 §10); the runtime serves the tools every module needs, as it serves the views' | -| The `run` ask published by the runner's account and the indexer's | 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) | -| The checker's step `check` becomes `pipeline` | the runner is an acting part in the checker's place (ADR 0666 §11) | -| The field `callers` in a seat definition replaces the holders' trusted `callers` | the record makes the definition the grants part's one source (ADR 0666 §12) | -| `widens` in `pipeline-ended` | a widening is said in the pipeline's end and nothing refuses it (ADR 0666 §12, §15) | -| `merge-pull` reads the head's latest run through the runner's `list`, a running run judged by the steps it ended, an unanswered read refused | the record has it read the run and never wait (ADR 0666 §6); the seat's verb is how one module asks another's data (ADR 0596); a run that cannot be read is not known to have passed (research 086, R8) | +| Each state's object store `-objects`, an object sent readable by its recipient, and the runtime's two tools | one object store per state, granted to its owner, the one object to the module it is for (ADR 0666 §10); the runtime serves the tools every module needs | +| 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 | +| The checker's step `check` becomes `pipeline`; the checker's kept verdicts taken into `kept` | the runner is an acting part in the checker's place (ADR 0666 §11); the first pipelines then run only what changed | +| 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 §12); a field left out must open nothing | +| `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 §12, §15); a change must not compute its own | +| `merge-pull` judged from the forge module's own `failed-steps`, heard from `step-ended`, any run at the head's fingerprint counting, 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 §6, ADR 0596) | +| The new assigner before the new `merge-pull` and the runner, by `needs` | a merge with no Approve must never reach an assigner that writes wants without a pipeline | | The verb `recovery` of `mesh-delivery` | a recovery is named by its author as a fact the bus keeps with who said it, never read from text (ADR 0666 §15, research 086 R10) | | No forge status for a pipeline | the step results live on the bus (research 086 R10), shown by the runner and the delivery record; a status would be a second copy outside it | -| The runner's `pipelines`, `step-log` and `kept`, with retention by the record's | a trace reads every step of a record; a pipeline no record keeps is read by nobody | +| The runner's `pipelines` kept 30 days, its outputs 7, keyed by source revision | the delivery record keeps its own copy of the events for 90 days; about 300 pipelines a day must fit its caps | +| The checker's removal after the first end-to-end pipeline and a tested restore, its backup kept 90 days | ADR 0667 §6; 90 days is the delivery records' retention, the longest a trace reads back | | The pipeline steps on the `check` stream after `delivery` | a delivery's build is never held by a pipeline, as a check never held one (ADR 0525 §4) | ## A delivery @@ -1552,7 +1644,7 @@ say another runs a build (ADR 0363 §2); the gate's events are granted to the ga | a milestone's ask asked, withdrawn and answered, until G's delivery | `milestone-asked`, `milestone-withdrawn`, `milestone-answered` | `mesh-delivery`, the gate | `mesh.seat.mesh-delivery.event.`, the milestone in the event, on the seat's family stream, apart from each delivery's `transition` | the same | | a delivery record opened, and a merge named a recovery | `record-opened`, `recovery-merged` | `mesh-delivery`, the gate | `mesh.seat.mesh-delivery.event.` | the same | | a pipeline, its steps, its waits and a run on request, from G's delivery | `pipeline-started`, `pipeline-ended`, `group-ended`, `run-started`, `step-started`, `step-ended`, `wait-held`, `wait-ended` | `mesh-pipeline-runner`, the runner | `mesh.seat.mesh-pipeline-runner.event....` | the seat's definition in `mesh-delivery-contracts` | -| a pipeline step ended, from G's delivery | `step-ended` | each build seat, `mesh-wants` | `mesh.seat..event.step-ended` | each seat's definition | +| a pipeline step ended, from G's delivery | `step-ended` | each build seat, `mesh-wants` | `mesh.seat..event.step-ended.`, the node that ran it | each seat's definition | | a registration changed; a package published, from G's delivery | `registration-changed`; `package-published` | `mesh-catalog`, the indexer; `mesh-builds`, the builder | `mesh.seat.mesh-catalog.event.registration-changed`; `mesh.seat.mesh-builds.event.package-published` | the seats' definitions in `mesh-delivery-contracts` | The events, their fields, their subjects and which are a seat's are this design's choices: a seat's event where @@ -2178,9 +2270,9 @@ takes its place and the checker's try, its events and the indexer's try candidat *ADR 0421, ADR 0398 §3, ADR 0406 §1, ADR 0659; from milestone G's delivery ADR 0666 §6.* **Until milestone G's delivery**, which is merged under it (ADR 0667 §2). From that delivery no Approve is asked per -merge and the gate merges nothing: a session merges its own pull request through the seat `git`'s `merge-pull`, and +merge and the gate merges nothing: a session merges a pull request through the seat `git`'s `merge-pull`, and the operator's approval is the pipeline step `approval` where a module's policy names it (*Approval is a step, and a -session merges its own pull request*). +session merges a pull request*). - **Asked as soon as the checks pass.** When a pull request's delivery reaches `ready` (both `mesh/merge-gate` and `mesh/repo-check` passed at its head against its trunk's head), mesh-delivery asks the operator's Approve of its @@ -2217,7 +2309,7 @@ session merges its own pull request*). merges through the seat `git`'s verb `merge-pull`, which judges those two and no check, and a trunk move holds no merge for its carry (ADR 0661; *The seat `git`*, under *The verbs*). This shape is built for no merge: milestone G's own merges are made by the running gate, and from G's delivery `merge-pull` is the session's own act, judged on the - pull request's head, the branch's protection and the head's latest run, never on an Approve (ADR 0666 §6, which + pull request's head, the branch's protection and the runs at its fingerprint, never on an Approve (ADR 0666 §6, which changes ADR 0661 §3 to §5). - **A push or a Decline ends the Approve.** A new head ends its ask or its Approve, for a group every member's, and is said once on the pull request; the new head is asked again once its checks pass. A Decline merges nothing and @@ -2888,9 +2980,9 @@ of each verb (ADR 0666 §4, §12, §14): | Verb | Answers or does | Callers | |---|---|---| -| `run` | the run on request of one or more members, each a module at a named commit; delivers nothing | any person, an agent session | +| `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; `list` also the holder of the seat `git`, for `merge-pull` | +| `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) | @@ -2930,7 +3022,7 @@ parts' manifests declare in `invokes` and `consumes` and what their code calls, | `contains` | whether one commit contains another | the indexer, the gate (`gitea_contains`) | | `statuses` | the statuses a commit carries | the gate (`gitea_commit_statuses`) | | `status`, `comment`, `view`, `note` | a commit status, a comment, the delivery's one view comment, a line on the commit's note under `refs/notes/mesh-plan`; a comment and a note line carry the act's id and an id already held is skipped | the forge bridge alone, performing the gate's and the checker's `owed` (`gitea_commit_status`, `gitea_add_comment`, `gitea_delivery_view`, `gitea_note_append`) | -| `merge-pull` | until G's delivery: merges a pull request at the head the operator's Approve names; refuses a head that moved, a branch no rule guards, a head the Approve does not name and a merge git refuses; judges no check (below). From G's delivery: merges with the forge tools' account (ADR 0398 §2) at the head the caller names, judging that it is still the pull request's head and that the branch's protection refuses a direct push, and refusing a head whose latest run, read through the seat `mesh-pipeline-runner`, failed a `required` step; a head with no run yet or a passed one merges, it never waits for a run and never asks an Approve (ADR 0666 §6). A pull request already merged at that head is answered performed | until G's delivery the forge bridge alone (`gitea_merge_pull_request`); from it a session over the mesh, merging its own pull request | +| `merge-pull` | until G's delivery: merges a pull request at the head the operator's Approve names; refuses a head that moved, a branch no rule guards, a head the Approve does not name and a merge git refuses; judges no check (below). From G's delivery: merges with the forge tools' account (ADR 0398 §2) at the head the caller names, judging that it is still the pull request's head and that the branch's protection refuses a direct push, the protection read again on every `branch-moved`, and refusing a head when any run at its build-input fingerprint failed a `required` step, judged from its own state `failed-steps` heard from the runner's `step-ended`, never by a call; a head with no run yet or a passed one merges, it never waits for a run and never asks an Approve (ADR 0666 §6). A pull request already merged at that head is answered performed | until G's delivery the forge bridge alone (`gitea_merge_pull_request`); from it any session the tool runner proves, and the operator | | Event of the seat | Says | Heard by (today's event) | |---|---|---| @@ -2956,13 +3048,13 @@ Each is said on `mesh.seat.git.event.`, declared in the seat's definition `gitea_commit_status`, `gitea_delivery_view`, `gitea_note_append`, `gitea_add_comment`) retire with the milestone, and so do its watch of the checker's state `owed` and its read of the gate's `source`, so the bridge stays the one part that acts on the forge. How it is checked: test 51 reads the grants, not the code. -- **`merge-pull` judges no check, and from G's delivery no Approve, only the head's latest run.** The operator's answer that no check gates delivery (Telegram, 2026-11-09 01:11 UTC, +- **`merge-pull` judges no check, and from G's delivery no Approve, only the runs at the head's fingerprint.** The operator's answer that no check gates delivery (Telegram, 2026-11-09 01:11 UTC, "Remove them in G") covers the forge module's own setting `check-gates-merge` as well as the gate's: both are removed, and `merge-pull` merges an approved head whatever its `mesh/check` says. The record that ends ADR 0551 and ADR 0548 §2 to §4, §9 and §10 also changes ADR 0534 §4's judgement of `mesh/check` by the merge; it is to be accepted before the push (*Nothing merges into a repository under check*). From G's delivery it judges no Approve either, its caller - is the session that merges its own pull request, and it refuses a head whose latest run failed a `required` step, - never waiting for one (ADR 0666 §6; *Approval is a step, and a session merges its own pull request*). The reads the + is any session the tool runner proves, and it refuses a head when any run at its fingerprint failed a `required` step, + never waiting for one (ADR 0666 §6; *Approval is a step, and a session merges a pull request*). The reads the gate would have needed to merge (the forge's word for a conflict, the base's required statuses, the merging account's write access) are not added: no part of the mesh but `merge-pull` merges, and it answers git's own refusal of a merge as refused. @@ -3383,13 +3475,15 @@ milestone with more tests than it starts with (research 085, Direction, One mile 67. **R5, a change across repositories whole or not at all.** A change over three repositories, its own packages included, is delivered whole from one source revision; when one member's `required` step fails none is delivered; a step whose prerequisite nothing starts ends its pipeline refused within five minutes, naming the step and the - prerequisite (whole, indexer, gate and runner, mesh-delivery and mesh-catalog; live). + prerequisite; with one member passed and another still running no want is written until `group-ended` (whole, + indexer, gate, runner and assigner, mesh-delivery and mesh-catalog; live). 68. **R6, modules, never repositories.** A module whose watched branch is `beta` on one machine is delivered from it there only; the lint step refuses a module, branch or repository name in a string, a constant or a table, and not an import path (whole, assigner, mesh-delivery; unit, the Go build module's lint, mesh-catalog; live, a search of the delivery parts' code). 69. **R7, any size.** Values of one, ten and a hundred times the bus's per-value limit are stored, sent as a verb's reply - and as an event, and read back whole (whole, mesh-sdk, against the real bus). + and as an event, and read back whole by another module the reply or the event is for, and refused to a module it is + not for (whole, mesh-sdk, against the real bus). 70. **R8, an unread input refuses.** A build whose published packages cannot be read is refused, naming the state (whole, builder, mesh-delivery). 71. **R9, no ask hidden.** A fourth ask and an ask after a Decline reach the channel; an ask with the same `about` from @@ -3401,11 +3495,13 @@ milestone with more tests than it starts with (research 085, Direction, One mile and delivers it alone; a step whose inputs did not change is carried, not run (whole, runner and builder, mesh-delivery). 74. **R12, every requirement tested.** This list maps each of R1 to R11 and R13 to R18 to a named test against the real - bus, and the milestone's review refuses it while one has none (the review). + bus, and the milestone's check runs each of them: its record names every one as run against the real bus, and the + milestone is not delivered while one is missing from it (live, read from the check's record). 75. **R13, a registration change is trusted.** Moving a step from `required` to `bypass` asks, showing that line, and writes nothing without the warrant (whole, indexer, mesh-delivery). -76. **R14, nothing stands still unseen.** A step whose worker dies raises `pipeline-stands` within five minutes (whole, - runner and watchman, mesh-delivery). +76. **R14, nothing stands still unseen.** A step whose worker dies raises `pipeline-stands` within five minutes; a + watched branch's head with no pipeline raises it, and that head's `pipeline-started` clears it (whole, runner and + watchman, mesh-delivery). 77. **R15, going back is one act.** A failing new version leaves the old one running, and a placement's `build` set back delivers the old build (whole, assigner, mesh-delivery; live). 78. **R16, a manifest judged per watched branch.** A `beta` manifest needing a seat nobody holds fails its composition @@ -3430,20 +3526,27 @@ The failure paths: 84. **A composition step for a node that sleeps** passes it with a warning; a step whose part is not heard ends `could not run`, never passed; two modules owning one path are refused (whole, runner and assigner). 85. **A forged step result**, from an account other than the step's seat holder's, or naming another commit or - fingerprint, is refused and said (whole, runner). + fingerprint, is refused and said; a `step-ended` on another node's subject is refused by the bus; a verb whose + definition names no `callers` admits only the holder roles and the operator (whole, runner and grants part). 86. **An author's own review** is refused; a reviewer's passes the step (whole, runner). 87. **A step seat with no holder** ends its pipeline failed, naming the seat, within five minutes (whole, runner). -88. **A runner stopped mid-step** takes its pipelines up again from its kept state when it starts, and a new runner's - failing build leaves the old one running pipelines (whole, runner). -89. **An older revision ending after a newer one** writes no want (whole, assigner). +88. **A runner stopped mid-step** takes its pipelines up again from its kept state when it starts, a replaced holder + and its successor never both write one pipeline key (compare-and-set), and a new runner's failing build leaves the + old one running pipelines; a build module restarted mid-step finishes the step from its work queue (whole, runner + and Go build module). +89. **An older revision ending after a newer one** writes no want; a newer commit supersedes a module's pipeline only + when it changed that module's build-input fingerprint (whole, assigner and runner). 90. **A replaced oversized value** leaves one object, and a deleted key takes its object (whole, mesh-sdk). 91. **A session's merge** through `merge-pull` at its head merges with no run yet and with a passed run, and asks no - Approve; a head whose latest run failed a `required` step, a head that moved, a branch without protection and an - unanswered read of the runner are refused, each naming why; a failed `optional` step refuses nothing (whole, forge - module and forge bridge, mesh-catalog and mesh-delivery). + Approve; with the runner stopped it still merges, judged on the `step-ended` it kept; a head at whose fingerprint any + run failed a `required` step, a head that moved, and a branch whose protection was removed since its last + `branch-moved` are refused, each naming why; a failed `optional` step refuses nothing; a call from an account that is + no proved session nor the operator is refused (whole, forge module and forge bridge, mesh-catalog and mesh-delivery). 92. **A recovery named** by `recovery` is marked in its record and `recovery-merged` reaches every channel (whole, gate and teller). -93. **Every tool of *The tools*** answers its whole-module case and is read by `mesh_describe` (whole, each module). +93. **Every tool of *The tools*** answers its whole-module case, every store's read tool answers its fill against its + cap, `grants_why_refused` names the grant a refused caller lacks, `gate_source_again` says `source-moved` again, and + each is read by `mesh_describe` (whole, each module). ADR 0667's checks, of milestone G itself: @@ -3454,8 +3557,19 @@ ADR 0667's checks, of milestone G itself: (live). 96. **No order by hand.** The delivery plan names every ordering edge it derived, and the hand-act log of the seat `mesh-hand-acts` names none for the milestone (live). -97. **What G removes.** After its delivery the checker's buckets and bus account and the gate's forge merge token are - gone, and a backup of the buckets exists (live). +97. **What G removes, and when.** The checker's buckets and bus account and the gate's forge merge token are removed + only after test 63 has passed on the mesh, after a backup of the buckets whose restore was tested, and after the + operator was told; then they are gone, and the backup is kept 90 days (live). +98. **A failed head is said.** A `required` step that failed, or could not run, on a watched branch's head raises + `pipeline-failed`, the commit's author's for two hours and then the operator's, cleared when a newer revision of + that branch passes it (whole, runner and condition keeper). +99. **The build capacity.** In the week after G, the build nodes' time per day, read from the build modules' step keys + and the builder's build log, is set beside the checker's in its last week; a newer publish supersedes an older one's + rebuild pipelines, and the first pipelines after G carry what the checker's kept verdicts held (live; whole, runner). +100. **The new assigner before the new merge.** In G's delivery the delivery plan delivers the new assigner before the + forge module's new `merge-pull` and before the runner, by their `needs`, and no merge made through the new + `merge-pull` reaches an old assigner (live, read from the delivery plan and the forge module's and the assigner's + `running`). ## What retires @@ -3513,9 +3627,10 @@ ADR 0667's checks, of milestone G itself: own tools, for the seat `git`'s verbs; and the four seat-list readers the delivery parts wire by hand. - At milestone G's delivery, from research 086 (ADR 0666, ADR 0667): the checker (`mesh-delivery-checker`), its seat, its try with `tryevent` and the indexer's try candidates, its kept verdicts and carries (the runner's from then), the - checking program and `mesh/check`, its buckets and bus account after a backup (ADR 0667 §6); the bundle of steps run - before a merge; the Approve per merge, the milestone ask and its three events, and the gate's merges, with its forge - merge token (ADR 0667 §6); the gate's merge states, one key per pull request and its verbs `table`, `recheck` and + checking program and `mesh/check`, and its buckets and bus account, removed with the gate's forge merge token only + after the first pipeline after G's delivery has delivered a change end to end, after a backup kept 90 days whose + restore is tested, the operator told before (ADR 0667 §6); the bundle of steps run before a merge; the Approve per + merge, the milestone ask and its three events, and the gate's merges; the gate's merge states, one key per pull request and its verbs `table`, `recheck` and `close`; the trunk-only want; `source.main`, for one source revision per watched branch; every fixed branch, repository and module name in code logic; the recovery merge verb this design sketched, never built; and the holders' trusted `callers` values, for the seat definitions' `callers`. The words **merge check**, **try**, **trunk commit** @@ -3570,7 +3685,7 @@ release reports the controller's code lines against research 063's baseline (acc | L6 | Provisioning leaves the controller (ADR 0570): every provision is one key of the seat `mesh-provisioner`, held by mesh-provisioner, holding a reference and never a value, and each placed module's provisioning plan a key of its state `plans`, both composed from placement, the wants and the manifests on change events; each provider acts once all a provision depends on is provided; the assigner moves a want only once its build's provisions are provided; a provision no want needs is retiring, and its account or credential is removed only on the operator's Approve, its data never; the vault mints each provision's secret sealed to the consumer's and the provider's node, and the consumer's node-engine writes it; a wait for a person is a provision's state, which the watchman reads; bus permissions stay with the grants part (ADR 0349, ADR 0230, ADR 0547 §11) | — | mesh-sdk, the node-engine (`mesh-host`), mesh-tools (the tool runner's provisioner client), mesh-catalog (mesh-provisioner, the vault, the provisioner client, postgres, keycloak, gitea, route-adapter), mesh-delivery (assigner, watchman) | 1954 | | L7 | History and records leave the controller (ADR 0571): the builder keeps its build log, one entry at a build's start and one at its end, from which build history and durations are read and the module mesh-catalog asks the builds it missed; the artifact sweep is the seat `mesh-artifact-sweep`, held by artifact-store-tools beside the artifact store, its keep set from the store's own listing, the wants and the build log, sweeping at each build's end from the lease write and recording each deletion in the hand-act log; disk readings are disk-load's own state on every node; who holds which seat is the state `seat-holders` of the seat `mesh-placement` (now `mesh-module-assigner`), and tools are found by the tool runners' announcements; what a node runs is its want and its have; the grants part writes `grants..` and keeps memberships in its own state; root-free is a probe of the self-check; no manifest but the controller's reads, invokes or consumes `mesh-controller`, but a named list kept to the lease write, so the lease write's check passes (ADR 0189, ADR 0547 §11, ADR 0549 §6) | — | mesh-sdk, mesh-controller (its pin only), mesh-delivery (builder, indexer, assigner, grants part, view), mesh-catalog (artifact-store-tools, disk-load, the backup seat's holder, mounts, nfs-server, minio, mesh-watcher, the messenger, the self-check, the module mesh-catalog, docker), mesh-tools (the tool runner) | 1955 | | B0 | The bootstrap delivery: every check, a lone pull request's as a group of one and a verdict carried after a trunk move included, is judged by a checking program built from the change's own heads in the build seat's sandbox, which also makes the heads' one seat list that the check hands the manifest validator and the composer; it brings no seat definition and no manifest field, so the running checker checks it (ADR 0644; *The bootstrap delivery, and the one milestone after it*) | 26 needs it | mesh-sdk (`go/delivery`: the seat `node-build-go`'s ask `run` and the checker's record of which checking program judged; `go/composer`: the request's seat list), mesh-catalog (mesh-build-go: the run step, the refused answer, the kept programs' tools and sweep), mesh-delivery (checker: the checking program and its command), hq (this design, the glossary) | 1921 | -| G | Two graphs and one revision view: the catalog graph and the assignment graph kept per revision, a change delivered as its graph difference, the acting parts' rules on their seats as bounded waits that hold their modules when the new version fails, the check on the change's own acting parts, the revision view and each process's own build, the gate's delivery record, and the trace's links (ADR 0656); no part reads a pull request's description (ADR 0659); every delivery part reaches the forge through the seat `git` and names no other module; nothing holds an approved merge for another check; and, one milestone with them, research 086's pipelines: a change of any module goes from a commit on a watched branch to the machines through its module's pipeline, its policy in its registration, ordered by edges between artifacts, with no Approve per merge and no hand act, the checker gone (ADR 0666, ADR 0667) | 26 to 62, 63 to 97 | mesh-sdk (the runtime: the fingerprint, the view, the definition reader, the seat list's one wiring), mesh-contracts and the domains' contracts modules (`acts`, the new verbs and events, the seat `mesh-grants`, the seat `git`'s verbs), mesh-delivery (indexer, assigner, checker until its removal, builder, grants part, gate's view, forge bridge, watchman, the new pipeline runner `mesh-delivery-pipeline`, `contracts` and `sdk` moved under `modules/`), mesh-catalog (the gate, the build modules, the forge module, mesh-issues, mesh-knowledge, the `node-backup` holder, the router, nats: a module's kept data on the bus as a backed-up item and the object store beside each state), mesh-sdk (also the shared state layer of any size), the node-engine (`mesh-host`), hq | 1966, 1961 (retargeted to this row's shape), 1660, 1972, 1721, 1783, 1785, 1794, 1791, 1373, 595; 1962 goes back with 1958, whose assignment entry it needs (ADR 0641 §3) | +| G | Two graphs and one revision view: the catalog graph and the assignment graph kept per revision, a change delivered as its graph difference, the acting parts' rules on their seats as bounded waits that hold their modules when the new version fails, the check on the change's own acting parts, the revision view and each process's own build, the gate's delivery record, and the trace's links (ADR 0656); no part reads a pull request's description (ADR 0659); every delivery part reaches the forge through the seat `git` and names no other module; nothing holds an approved merge for another check; and, one milestone with them, research 086's pipelines: a change of any module goes from a commit on a watched branch to the machines through its module's pipeline, its policy in its registration, ordered by edges between artifacts, with no Approve per merge and no hand act, the checker gone (ADR 0666, ADR 0667). Test counts at its start (G's prepare, 2026-11-09): mesh-delivery 665 unit and 68 integration, the node-engine (`mesh-host`) 1,742 unit; each other repository's and each catalog module's from the last check's verdict, read in the joint prepare | 26 to 62, 63 to 100 | mesh-sdk (the runtime: the fingerprint, the view, the definition reader, the seat list's one wiring), mesh-contracts and the domains' contracts modules (`acts`, the new verbs and events, the seat `mesh-grants`, the seat `git`'s verbs), mesh-delivery (indexer, assigner, checker until its removal, builder, grants part, gate's view, forge bridge, watchman, the new pipeline runner `mesh-delivery-pipeline`, `contracts` and `sdk` moved under `modules/`), mesh-catalog (the gate, the build modules, the forge module, mesh-issues, mesh-knowledge, the `node-backup` holder, the router, nats: a module's kept data on the bus as a backed-up item and the object store beside each state), mesh-sdk (also the shared state layer of any size), the node-engine (`mesh-host`), hq | 1966, 1961 (retargeted to this row's shape), 1660, 1972, 1721, 1783, 1785, 1794, 1791, 1373, 595; 1962 goes back with 1958, whose assignment entry it needs (ADR 0641 §3) | An issue is in one row only (ADR 0493 §2): where a row named an issue another row names too, the last row keeps it and the earlier row says so in words (the operator, 2026-10-26). Milestone M1 makes each row a record of the issue tracker @@ -3720,9 +3835,8 @@ B0's own choices, each checked by the rows of *How it is checked* below: author (ADR 0666 §15; *A recovery fix is an ordinary merge*). The verb this design sketched for it is not built. - **How the runner knows a review's caller is the commit's author.** ADR 0666 §12 refuses a review from the commit's author; the forge names the author by its forge account and the runtime proves the caller's bus account, and no - record or design says which forge account belongs to which bus identity. Until one does, the runner refuses a - review whose caller's identity carries the name the commit's forge account carries, said as such in its refusal; - issue 1966 tracks it (note 157). + record binds the two. Until one does, code review is never a `required` step: `register` and `policy` refuse it + (*A module's registration*); issue 1966 tracks it (note 157). - What a process started by a node-engine that hands no fingerprint does beyond saying `own build unknown`, for a part other than the indexer. - The caps' and the growth's numbers are estimates (*Two graphs, one source of truth*); the fill tools read the real @@ -3792,15 +3906,30 @@ test 62); and ADR 0662, which decided the same switch as ADR 0661 another way, i The amendment for research 086's graduation (2026-11-10) writes ADR 0666 and ADR 0667 into this design: *Pipelines per module* whole (registrations, watched branches and the catalog graph per branch, the pipeline steps and the policy, -what holds a delivery, approval as a step and a session's own merge through `merge-pull` reading the head's latest run, +what holds a delivery, approval as a step and a session's merge through `merge-pull` judged on the runs at the head's fingerprint, groups, the six kinds of edge between artifacts, a publish that rebuilds, values of any size, the pipeline making the check, callers per verb, health, the recovery fix, the tools, the runner's kept data and the build capacity, and how -milestone G itself is delivered), a line in every section the pipelines replace, and tests 63 to 97. It folds in what +milestone G itself is delivered), a line in every section the pipelines replace, and tests 63 to 100. It folds in what milestone G's prepare left for the joint amendment: the events `milestone-asked`, `milestone-withdrawn`, `milestone-answered` and `record-opened` as built, `assignments-changed` for the seat's event, the size of the bridge's `performed` fixed by its template, the seat `git`'s `merging` and `not-found`, `acts` a list with none on `node-backup`, the gate's `source` per watched branch with `source-moved`, a superseded pipeline's asks dropped by `drop`, and -`kept-artifact` an edge of the sixth kind (the operator kept six). Its review by architectural domain is still to come. +`kept-artifact` an edge of the sixth kind (the operator kept six). Its review by architectural domain ran, four domains +side by side, and fix-1965 ruled on round 1 (2026-11-10), the record's wording following: the registrations, the +runner's kept data and the gate's `source` in old sections, the runner a foundation part and the gate not; +`merge-pull` judged from the forge module's own state of failed steps heard from `step-ended`, any run at the head's +fingerprint counting, its protection read on every move, any proved session merging; the first registrations' ask +raised again by a tool; the node in `step-ended`'s subject; `step-outputs`; `branch-moved` kept on the seat's stream; +the grants part's and the gate's new tools and every store's fill; a group's wants on `group-ended` alone; an +approval's end states and its `about`; `pipeline-failed`, the author's then the operator's; `pipeline-stands` cleared by +`pipeline-started`; what a session hears after its merge, `widens` passed on by the teller and computed by the running +runner over every part serving a step, and the runner's health check; an object sent readable by its recipient; the +new assigner before the new `merge-pull` and the runner; the checker removed only after a first end-to-end pipeline and +a tested backup kept 90 days; code review never `required` until forge accounts are bound to bus identities; a missing +`callers` admitting the holder roles and the operator only; `run` called by sessions and the operator; the stores +estimated again with publish rebuilds; the build capacity; test counts in `step-ended`; `pipelines` keyed by source +revision; a pipeline superseded only on a changed fingerprint; a build seat restarted mid-step; tests 98 to 100. Round 2 +is to come. Left as notes on issue 1921, not in this amendment: a conformance check that a changed layout raises its `form`; the size and retention of restore points and set-aside data; who may call `restore` for bus data and which manifest grants