Amend design 47 for milestone G's prepare, so G is built from what the records hold

The prepare found the design behind its records and the code: Placement retired by ADR 0641 while the
design still put two seats in a contracts module never made, ADR 0659 and ADR 0660 not followed, the
checker and the forge bridge reading the gate's state, the delivery parts naming the forge module's
tools, and four hand-wired seat-list readers. Design 47 now writes each as the design's choice under the
record it follows; the hold and the merge turns are removed by the operator's word with their record
still to come, and a session's recovery merge waits for one. The glossary moves Placement's words into
Core and Delivery and adds the seat mesh-grants; the words test refuses Placement as a domain heading
(ADR 0641 §5); design 26 takes the new contracts homes and the seat git's verbs.

Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
This commit is contained in:
2026-11-09 19:21:49 +01:00
parent 2de011e070
commit 7f2f37d9e6
4 changed files with 369 additions and 108 deletions
+30
View File
@@ -38,6 +38,7 @@ import (
// holders the glossary says no seat's holder: no seat "held by" or "claimed by" a named module, no named module
// "holder of" a seat, no module that "holds the seat" (the operator, 2026-11-09). Who holds a seat is read
// from the mesh's assignments, and the glossary's head says where.
// domains no retired domain heads a section of the glossary (ADR 0641 §5: Placement).
// copy with MESH_CATALOG_DIR set to a checkout of the catalog, its copies of the retired words and the
// daemons' lines equal this glossary's and this list (skipped, with its reason, when unset).
//
@@ -830,3 +831,32 @@ func TestHoldersRefusesANamedHolderAndPassesARole(t *testing.T) {
}
}
}
// domains: a retired domain is no heading of the glossary. ADR 0641 §1 retired Placement into Core (module
// assignment) and Delivery (the wants), and §5 has this test refuse it as a domain heading.
var retiredDomains = []string{"Placement"}
func checkRetiredDomains(text string) []string {
var out []string
for _, d := range retiredDomains {
rx := regexp.MustCompile(`(?m)^##\s+` + regexp.QuoteMeta(d) + `\b`)
for _, loc := range rx.FindAllStringIndex(text, -1) {
out = append(out, fmt.Sprintf("%s:%d: %q is a retired domain (ADR 0641 §1) and heads no section", glossaryFile, lineOf(text, loc[0]), d))
}
}
return out
}
func TestWordsGlossaryHasNoRetiredDomainHeading(t *testing.T) {
expectNone(t, checkRetiredDomains(readFile(rootFS(), glossaryFile)))
}
func TestRetiredDomainsRefusesTheHeadingAndPassesProse(t *testing.T) {
if len(checkRetiredDomains("## Placement — what runs on which node\n")) == 0 {
t.Error("a Placement heading was not refused")
}
if got := checkRetiredDomains("## Core\n\nwhich was the Placement domain until ADR 0641\n"); len(got) != 0 {
t.Errorf("prose refused: %v", got)
}
}
+46 -40
View File
@@ -165,8 +165,8 @@ and repair).
**Purpose.** To hold, check and resolve every value a module reads that someone may change, and to say
where each resolved value came from. **Recorded by** the `mesh-config` module, in its buckets on the bus,
with its store as the history behind them. **Upstream of** Provisioning, which places the values;
downstream of Module and Placement. **Decided by** ADR 0262, 0277, 0348.
**Uses:** module, node, manifest (Module), assignment (Placement), provision (Provisioning), proposal
downstream of Module and Core. **Decided by** ADR 0262, 0277, 0348.
**Uses:** module, node, manifest (Module), assignment (Core), provision (Provisioning), proposal
(Operator and conversation).
- **template file** — a file a module ships with placeholders, such as `${config:<key>}`, which the provisioner
@@ -225,10 +225,13 @@ downstream of Module and Placement. **Decided by** ADR 0262, 0277, 0348.
## Core — the mesh's own machinery
**Purpose.** To keep the controller, the bus, the store and every node's engine running and agreed, so
every other domain has something to run on. **Recorded by** the controller and the store.
**Upstream of** every domain but Module; the others use the bus and the store as they are.
**Decided by** ADR 0005, 0006, 0067, 0106, 0141, 0175, 0227, 0229, 0289.
**Uses:** node, module, seat.
every other domain has something to run on; and to decide and apply what each node runs, and say why: module
assignment, which was the Placement domain until ADR 0641 §1 retired it into this one. **Recorded by** the
controller and the store; for module assignment, by the seat `mesh-module-assigner`, in its states on the bus
(ADR 0567). **Upstream of** every domain but Module; the others use the bus and the store as they are.
**Decided by** ADR 0005, 0006, 0067, 0100, 0106, 0126, 0141, 0175, 0176, 0181, 0207, 0221, 0227, 0229, 0252, 0261,
0289, 0411, 0539, 0549, 0559, 0565, 0567, 0571, 0634, 0641.
**Uses:** node, machine, module, seat, manifest (Module), config value (Config), proposal (Operator and conversation).
- **controller** — the component that decides what each node should be, holds the mesh's records, and
tells nodes over the bus. The relationship is *controller and nodes*, and no node is subordinate: a
@@ -299,22 +302,8 @@ every other domain has something to run on. **Recorded by** the controller and t
text is about the controller's records; the builder's *mirrored* `upstream` image (Delivery) is
a different thing, a copy of an outside image in the artifact store.
## Placement — what runs on which node
**Purpose.** To decide, send and apply what each node runs, and to say why.
**Recorded by** the controller's `inventory` database; from ADR 0567, by the seat `mesh-module-assigner`, in its states on
the bus. **Upstream of** Provisioning, Connectivity, Data
and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 0252, 0261, 0411, 0539, 0549, 0559, 0565, 0567, 0571, 0634, 0656.
**Uses:** node, machine, module, seat, manifest (Module), config value (Config), proposal (Operator and conversation).
- **assignment** — a module put on a node. Its config values on that node (module-assignment config,
Config) are `mesh-config`'s, never part of what the controller records (ADR 0348 §9).
- **assignment graph** — the module versions placed on nodes at one revision, with the edges between versions that
its inputs give: provisioning, contribution, and the acting parts' versions that are to act on each entry. The
assigner computes it from the catalog graph, the placements and the nodes' capabilities, and nothing else writes it;
it keeps each revision naming the revisions of its inputs, served by the seat `mesh-wants`, and writes the wants
from a trunk revision's alone (ADR 0656). Not the **catalog graph** (Delivery), whose entries are modules, not
versions on nodes; not an **assignment**, one module put on one node.
- **placement** — which module runs on which node, with its pins, host ports and bindings, and what a person
decided of the node, as one key per node in the state `placement` of the seat `mesh-module-assigner`. It changes only by
a placement proposal the operator approves, and no repository holds it or names a node (ADR 0567). Until ADR
@@ -323,11 +312,8 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
- **mesh-module-assigner** — the seat, held once for the mesh, that keeps placement: its states
`placement`, `proposals` and `candidates`, and its seven verbs `placement`, `proposals`, `propose`, `withdraw`,
`again`, `adopt` and `hand-back`. Only the holder writes its states (ADR 0567, renamed by ADR 0634 §9). Its
contract is in `mesh-placement-contracts` (ADR 0634 §7).
contract is in `mesh-contracts`, module assignment being of this domain (ADR 0641 §1).
*Not:* ~~mesh-placement~~
- **mesh-wants** — the seat, held once for the mesh, that keeps what each node should run, one want
per node and module (`want.<node>.<module>`), and a person's upgrade policy, served as its verb `upgrade`
(ADR 0565 §7, ADR 0571 §8). Its contract is in `mesh-placement-contracts` (ADR 0634 §6, §7).
- **seat holders** — the state `seat-holders` of the seat `mesh-module-assigner`, written by its holder: one
key per seat naming each holder and its node, composed from placement and the manifests' claims as the indexer
holds them, and rewritten only when a key differs. The tool runner and every other reader of who holds a seat
@@ -409,9 +395,9 @@ and Health and repair. **Decided by** ADR 0100, 0126, 0176, 0181, 0207, 0221, 02
**Purpose.** To resolve which module serves a provision for which consumer, to wire the two, and to
place every value a module needs into its files on its node. **Recorded by** the controller and
`mesh-provisioner`. **Upstream of** Data; downstream of Module, Placement, Config and Identity.
`mesh-provisioner`. **Upstream of** Data; downstream of Module, Core, Config and Identity.
**Decided by** ADR 0027, 0084, 0138, 0225, 0230, 0263, 0349.
**Uses:** module, seat, node-engine (Core), declaration (Placement), config value (Config), credential
**Uses:** module, seat, node-engine (Core), declaration (Core), config value (Config), credential
and vault (Identity and access).
- **provision** — a service one module `provides` and others `require`; the mesh resolves a provider
@@ -467,7 +453,7 @@ and vault (Identity and access).
**Purpose.** To issue, hold, rotate and check the credentials and grants by which modules, nodes, agents
and the operator act. **Recorded by** the controller's `identity` and `licences` databases and the vault.
**Upstream of** Provisioning, Delivery, and Operator and conversation.
**Decided by** ADR 0085, 0113, 0183, 0225, 0234, 0386, 0387, 0388, 0411, 0413, 0414, 0550, 0571, 0587, 0634.
**Decided by** ADR 0085, 0113, 0183, 0225, 0234, 0386, 0387, 0388, 0411, 0413, 0414, 0550, 0571, 0587, 0634, 0636, 0656, 0660.
**Uses:** module, node, seat, tool (Module), operator, consumer and provision (Provisioning), agent and ask (Operator and conversation).
- **credential** — anything that proves an identity: a password, a key, a token. A **pair credential**
@@ -514,6 +500,11 @@ and the operator act. **Recorded by** the controller's `identity` and `licences`
is issued. The bus server calls its accounts *users*; the mesh says bus account. Each module's membership
is kept in the grants part's state `memberships` (seat `mesh-grants`), one key `<node>.<module>` written
only when it differs, and the runtime reads its membership there (ADR 0571 §10).
- **mesh-grants** — the seat, held once for the mesh, that composes who may say what on the bus: each module's
membership, the bus's user list and `grants.<module>.<fingerprint>`, applying mesh-sdk's `SeatsToPassOn` for a
seat's pass (ADR 0660 §3). From research 085's milestone it is defined whole in `mesh-identity-and-access-contracts`,
this domain's contracts module (ADR 0636 §5), as an acting part of the step `grant` (ADR 0656 §1), with the events
`wait-held` and `wait-ended` (design 47).
- **rotate** — replacing a credential without a consumer holding one the provider does not know.
- **licence** — a model-access account the licence manager holds and **binds** to a consumer, the
coding agent on a node (ADR 0183).
@@ -535,8 +526,8 @@ and the operator act. **Recorded by** the controller's `identity` and `licences`
back when it fails. The domain is continuous integration and delivery, named **delivery**, and its parts live in
the repository `mesh-delivery` (ADR 0429 §2). **Recorded by** the `mesh-delivery` module (deliveries) and the
controller (the planner, the rollout) until release 6 of ADR 0429; from each release on, by the parts it builds. **Downstream of** Module, Core, Health and repair and Data.
**Decided by** ADR 0162, 0218, 0236, 0237, 0238, 0239, 0250, 0267, 0270, 0276, 0323, 0401–0408, 0428, 0429, 0444–0447, 0524–0530, 0539, 0548, 0551, 0571, 0578, 0579, 0593, 0601, 0644, 0656.
**Uses:** module, node, declaration and send (Placement), health (Health and repair), person.
**Decided by** ADR 0162, 0218, 0236, 0237, 0238, 0239, 0250, 0267, 0270, 0276, 0323, 0401–0408, 0428, 0429, 0444–0447, 0524–0530, 0539, 0548, 0551, 0571, 0578, 0579, 0593, 0601, 0641, 0644, 0656, 0659.
**Uses:** module, node, declaration and send (Core), health (Health and repair), person.
- **merge check** — what a pull request carries before it may merge, judging the merge of its head into a
named **trunk commit**, made in a clone of its own on a build node and never pushed (ADR 0323). One status,
@@ -550,8 +541,18 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
ADR 0656, from which each delivery part orders a source revision by its own rule: provisions, bus state, a served
verb and a reader's capability are waited on; a package, and until research 085's milestone a build module's
change, are triggers that rebuild, never waits; a verb edge on a cycle is left out (ADR 0603 §1, §2, ADR 0614); from research 085's milestone an acting part's edge is a wait within
its step (ADR 0656). Nothing stores the order. Not the **assignment graph** (Placement), computed from it.
its step (ADR 0656). Nothing stores the order. Not the **assignment graph**, computed from it.
*Not:* ~~build graph~~
- **assignment graph** — the module versions placed on nodes at one revision, with the edges between versions that
its inputs give: provisioning, contribution, and the acting parts' versions that are to act on each entry. The
assigner computes it from the catalog graph, the placements and the nodes' capabilities, and nothing else writes it;
it keeps each revision naming the revisions of its inputs, served by the seat `mesh-wants`, and writes the wants
from a trunk revision's alone (ADR 0656). Not the **catalog graph**, whose entries are modules, not
versions on nodes; not an **assignment**, one module put on one node.
- **mesh-wants** — the seat, held once for the mesh, that keeps what each node should run, one want
per node and module (`want.<node>.<module>`), and a person's upgrade policy, served as its verb `upgrade`
(ADR 0565 §7, ADR 0571 §8). Of this domain: the wants are what the delivery asks of the nodes, so its contract is in
`mesh-delivery-contracts` (ADR 0641 §2).
- **acting part** — the holder of a seat whose definition carries a rule: the step its holder acts in and the modules
it acts on (ADR 0656), in the field `acts` (design 47): the indexer, the checker, the build modules, the
node-engine, the grants part, the assigner. Within a revision its new version acts first in its step, a wait with a
@@ -600,7 +601,9 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
to merge there in the order of their Approve, and the check each waits for. It holds new checks off that
repository until the merge is done (ADR 0548 §3). Written only while the check gates merges (the gate's
setting `check-gates-merge`); while it does not, no turn is written and an approved merge goes in at once
(ADR 0551 §1).
(ADR 0551 §1). Goes at research 085's milestone with the hold and the setting, once the record that ends them is
accepted (the operator, 2026-11-09; design 47); the word goes to a *Not:* line with the as-is update after that
delivery.
- **build seat** — a language's node seat, held on a node by that language's build module: `node-build-go`,
`node-build-node` and `node-build-image` (ADR 0525 §2). Its accepted kinds are the **build streams**, and its
verbs `current`, `pause` and `resume` serve that node's pulls. It replaces the seat `node-build-agent`, retired
@@ -809,7 +812,10 @@ controller (the planner, the rollout) until release 6 of ADR 0429; from each rel
nodes; what a lab run declares; and a recorded failure run again to prove a fix (ADR 0016, ADR 0237).
- **git seat** — the seat `git`, held once for the mesh, delivering the provision `git`: the
repositories a build comes from ([26 — The seats](../03-DESIGN/01-to-be/26-the-seats.md) *The git seat*). A seat of
this domain.
this domain, defined in `mesh-delivery-contracts`. From research 085's milestone its verbs are the one way a
delivery part reaches the forge: reads (`pull`, `open-pulls`, `tags`, `trees`, `file`, `commits`, `branches`,
`contains`) for the parts that declare them, and acts (`status`, `comment`, `view`, `note`, `merge-pull`) for the
forge bridge alone (design 47, *The verbs*). Not the **forge** itself, the server, nor the forge module's own tools.
## Health and repair — what is wrong, and putting it right
@@ -1254,18 +1260,18 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
| Word | Sense | Say | Domain |
|---|---|---|---|
| plan | what the controller would send one node, until release 6 | that node's **declaration** (verb `plan`) | Placement |
| plan | what the controller would send one node, until release 6 | that node's **declaration** (verb `plan`) | Core |
| | what a delivery would do to the mesh, until release 6 | **delivery plan** | Delivery |
| | the sending of one batch of commits across nodes, until release 6 | **rollout** (verb `plans`) | Delivery |
| | a step a person starts, like the bus's | **planned step** | Core |
| composition | one module's resources for one node at one fingerprint, signed, from release 6 | **composition** | Placement |
| | the function in `mesh-delivery-sdk` that composes them, which the node agents, the assigner and the grants part run (ADR 0635 §4) | **the composition of `mesh-delivery-sdk`** | Placement |
| composition | one module's resources for one node at one fingerprint, signed, from release 6 | **composition** | Core |
| | the function in `mesh-delivery-sdk` that composes them, which the node agents, the assigner and the grants part run (ADR 0635 §4) | **the composition of `mesh-delivery-sdk`** | Core |
| | whether the machines a change touches still compose | **composition check** | Delivery |
| membership | the subjects a bus account is issued | **membership** | Provisioning |
| binding | the names on the bus of a module's bus state, in its membership | **binding** of bus state | Data |
| | a consumer's tie to the data a provider keeps for it | **sticky binding** | Data |
| | which host ports and addresses a placement gives a module | a placement's **bindings** | Placement |
| | an account in a group of the machine | **account group** | Placement |
| | which host ports and addresses a placement gives a module | a placement's **bindings** | Core |
| | an account in a group of the machine | **account group** | Core |
| domain | an area of the mesh that owns a set of concepts and the one word for each (ADR 0244), the sections of this page; the one sense "domain" keeps bare | **mesh domain** | The record |
| | one of the eight concerns a direction and a design are reviewed against (playbook 01); never written bare | **architectural domain** | The record |
| configuration | the settings of a storage type, which a template fixes or a module gives | **configuration** of a storage type | Data |
@@ -1278,7 +1284,7 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
| | one choice of an ask to a person | an ask's **option** | Operator and conversation |
| effect | what an operation does to a ledger's state | **ledger effect** | Data |
| | a tool's mark: reads, acts or dangerous | a tool's **effect** | Identity and access |
| push | the controller giving nodes their declarations, until release 6 | **send** (verb `push`) | Placement |
| push | the controller giving nodes their declarations, until release 6 | **send** (verb `push`) | Core |
| | a git push | **git push** | The record |
| | a phone notification | **push notification** | Operator and conversation |
| release | a person letting a held delivery go on | **release** | Delivery |
@@ -1288,7 +1294,7 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
| gate | the judgement on a delivery's first node | **first-node gate** | Delivery |
| | the check of what a change makes of the machines it touches, a pull request status until release 4 of ADR 0429 | ~~merge gate~~ (hq); the **composition check** | Delivery |
| | the part that merges a group and moves the source revision | **gate part** (`mesh-delivery-gate`) | Delivery |
| | a failed step stopping its module's later steps (ADR 0136) | *a failed step holds its module* | Placement |
| | a failed step stopping its module's later steps (ADR 0136) | *a failed step holds its module* | Core |
| tier | a level of the mesh | **layer** | Core |
| | a step of a rollout | **tier** | Delivery |
| | how much proof an ask needs | **assurance level** | Identity and access |
@@ -1307,7 +1313,7 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
| | an entry in the build queue | **build request** (an ask on a build stream) | Delivery |
| store | the one database server | **store** | Core |
| | the OCI registry | **artifact store** | Delivery |
| | a node's own copy of its last declaration | **last declaration** | Placement |
| | a node's own copy of its last declaration | **last declaration** | Core |
| | the seat holding the mail accounts | **`mail-store`** | Mail |
| record | a numbered decision | **decision record** | The record |
| | the literal reader of this repository, searched first for a symptom | **the record** (the `records` module) | Operator and conversation |
+17 -4
View File
@@ -15,8 +15,9 @@ code:
- mesh-catalog modules/gitea/module.json
- mesh-controller internal/inventory/migrations/0063-a-machines-names-are-one-seats.sql
- mesh-controller internal/inventory/migrations/0064-the-resolver-file-is-the-uplinks.sql
updated: 2026-11-06
updated: 2026-11-09
decisions:
- "ADR 0641"
- "ADR 0636"
- "ADR 0634"
- "ADR 0635"
@@ -255,14 +256,21 @@ defined whole or at the seat list's grain (ADR 0635 §2). In the milestone of AD
| contracts module | domain | seats | held by |
|---|---|---|---|
| `mesh-delivery-contracts` | Delivery | `mesh-catalog`, `mesh-delivery-checker`, `mesh-delivery`, `node-build-go`, `node-build-image`, `node-build-node`, `npm-package-registry`, `go-package-registry`, `container-image-registry`, `oci-artifact-registry` | the indexer, the checker, the gate part, the three build modules, the forge (two), `distribution` (two) |
| `mesh-placement-contracts` | Placement | `mesh-module-assigner`, `mesh-wants` | the assigner |
| `mesh-delivery-contracts` | Delivery | `mesh-catalog`, `mesh-delivery-checker`, `mesh-delivery`, `mesh-wants`, `node-build-go`, `node-build-image`, `node-build-node`, `npm-package-registry`, `go-package-registry`, `container-image-registry`, `oci-artifact-registry` | the indexer, the checker, the gate part, the assigner, the three build modules, the forge (two), `distribution` (two) |
| `mesh-health-and-repair-contracts` | Health and repair | `mesh-conditions`, `mesh-self-check`, `mesh-healers`, `mesh-watchdogs`, `mesh-hand-acts` | the condition keeper, mesh-self-check, mesh-healers, the watchman, mesh-hand-acts |
| `mesh-provisioning-contracts` | Provisioning | `mesh-provisioner` | mesh-provisioner |
| `mesh-identity-and-access-contracts` | Identity and access | `mesh-vault`, `mesh-node-enroller` | the vault, the module `mesh-enrolment` |
| `mesh-connectivity-contracts` (mesh-networking repository, ADR 0636 §6) | Connectivity | `the-private-network` | `mesh-wireguard` |
| `mesh-operator-and-conversation-contracts` | Operator and conversation | `operator-channel` | the router |
| `mesh-contracts` | Core, and Config | `node-engine`, `mesh-broker`, `mesh-config` | the node-engine, the bus module, mesh-config |
| `mesh-contracts` | Core, and Config | `node-engine`, `mesh-broker`, `mesh-config`, `mesh-module-assigner` | the node-engine, the bus module, mesh-config, the assigner |
ADR 0641 retired the Placement domain: module assignment is Core's, so `mesh-module-assigner` is defined in
`mesh-contracts`, and the wants are Delivery's, so `mesh-wants` is defined in `mesh-delivery-contracts`; the module
`mesh-placement-contracts` is not created (ADR 0641 §1, §2). From research 085's milestone (design 47) the seat
`mesh-grants` is defined whole in `mesh-identity-and-access-contracts` (ADR 0636 §5), and the seat `git` gains in
`mesh-delivery-contracts` the verbs by which every delivery part reaches the forge (*The git seat*, below). How it is
checked: the indexer refuses a definition of these seats from any other contracts module, naming both (ADR 0636 §5),
and its domain check refuses a definition naming the domain Placement (ADR 0641 §5).
**How it is checked**: each of these definitions' conformance fixtures names every event's subject, the seat's and
the holder's own, and a case of the holder's whole-module test takes a fixture from the running holder (an event
@@ -681,6 +689,11 @@ difference: it receives a URL either way.
With the seat unheld, a build from the seat is refused and says why. External builds carry on.
**The seat's verbs, from research 085's milestone.** The delivery parts reach the forge through the seat `git`'s
verbs alone, never by the forge module's own tools: reads for the parts that declare them in their `invokes`, and
acts (a status, a comment, the delivery's view, a line on the commit's note, a merge) for the forge bridge alone.
Design 47, *The verbs*, lists them with their callers and how they are checked.
**Not yet designed:** a credential for cloning a private repository. The mesh's own repositories are
public. The natural place for a clone credential is a `secret` from the vault, and that is a decision
still to take.
@@ -1,11 +1,14 @@
---
layer: to-be
status: in-progress
code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, mesh-contracts, hq 00-META/checks]
updated: 2026-11-06
code: [mesh-controller, mesh-catalog modules/mesh-delivery-gate, mesh-catalog modules/gitea, mesh-delivery, mesh-host, mesh-sdk, mesh-vault, mesh-contracts, hq 00-META/checks]
updated: 2026-11-09
decisions:
- "ADR 0660"
- "ADR 0659"
- "ADR 0656"
- "ADR 0644"
- "ADR 0641"
- "ADR 0639"
- "ADR 0638"
- "ADR 0637"
@@ -14,6 +17,7 @@ decisions:
- "ADR 0634"
- "ADR 0633"
- "ADR 0632"
- "ADR 0625"
- "ADR 0619"
- "ADR 0618"
- "ADR 0615"
@@ -140,7 +144,7 @@ release 6 each node takes a merged change from its wants, the module's canary fi
milestones are features delivered one after another. The trunk is what runs; there is no "release branch"**
(ADR 0401, ADR 0418 §1, ADR 0421 §2).
**From the delivery of issues 1781 to 1783, a milestone is a record of the issue tracker and the unit that is released.** Its issues are linked to it, and pull requests and commits to the issues, by the issue tracker's link verb, never matched from a description; a review is recorded by a verb of the delivery seat; the mesh builds and checks each pull request as it comes in, and asks the operator once to release the milestone when every issue is ready; its pull requests are the delivery group, in whatever repositories and on whatever branches, and nothing ships outside a released milestone (ADR 0493 §1 to §11). Until that delivery the branch-name rules in this design stay what runs, kept by hand (ADR 0493 §12). A change across any repositories, the mesh-sdk included, is one group whose developer orders no release, from R4e's delivery for a group with a mesh-sdk member; until then an SDK change ships before its users (ADR 0482 §1, §7).
**From the delivery of issues 1781 to 1783, a milestone is a record of the issue tracker and the unit that is released.** Its issues are linked to it, and pull requests and commits to the issues, by the issue tracker's link verb, never matched from a description; no part reads a pull request's description to hold, allow or withdraw an ask or a merge, and a review, if a verb records it, gates nothing (ADR 0659 §1, §2); the mesh builds and checks each pull request as it comes in, and asks the operator once to release the milestone when every issue is ready; its pull requests are the delivery group, in whatever repositories and on whatever branches, and nothing ships outside a released milestone (ADR 0493 §1 to §11). Until that delivery the branch-name rules in this design stay what runs, kept by hand (ADR 0493 §12). A change across any repositories, the mesh-sdk included, is one group whose developer orders no release, from R4e's delivery for a group with a mesh-sdk member; until then an SDK change ships before its users (ADR 0482 §1, §7).
**Every step starts on an event, and the state lives on the bus.** The forge's events, the parts' keys and the
nodes' haves move a delivery; nothing collects merges, plans them or orders them in tiers. From release 6 each
@@ -178,8 +182,10 @@ no part calls another, there is no plan object and no orchestrator, and each key
source revision is derived from the keys: every **want** equals its module's **fingerprint**, and every
**have** equals its want and is healthy.
- **The forge bridge** turns the forge's events into stream messages and is the only part that calls the
forge.
- **The forge bridge** turns the forge's events into stream messages and is the only part that acts on the
forge. From research 085's milestone every delivery part reaches the forge through the seat `git`'s verbs alone,
never by the forge module's own tools: the forge bridge for every act and read it makes, the checker and the
indexer for the reads they make (*The seat `git`*, under *The verbs*).
- **The indexer** computes each module's fingerprint at the merge preview and writes the candidates of each
group and the modules of the trunk. It reads no placement: placement is not in any repository, and the forge
bridge carries nothing of placement (ADR 0567). From research 085's milestone it keeps the catalog graph per
@@ -202,12 +208,13 @@ source revision is derived from the keys: every **want** equals its module's **f
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).
- **The gate** merges a group's pull requests once check, review and the operator's Approve agree on the same
heads, and then moves the mesh's source revision in one write. While the check gates merges, it holds an
approved merge for another delivery's running check of the repositories the merge goes into, and keeps the
merge's **merge turn** there (ADR 0548 §2, §3, as ADR 0551 §1 bounds them; *Nothing merges into a repository
under check*, below). From research 085's milestone it keeps one delivery record per milestone's delivery as a
ledger instance (ADR 0656), its `merges` and `turns` carried into the records (*The delivery record*, below).
- **The gate** merges a group's pull requests once the check and the operator's Approve agree on the same
heads, reading no review line (ADR 0659 §1), and then moves the mesh's source revision in one write. While the
check gates merges, it holds an approved merge for another delivery's running check of the repositories the merge
goes into, and keeps the merge's **merge turn** there (ADR 0548 §2, §3, as ADR 0551 §1 bounds them); research 085's
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).
- **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
fingerprint is not held, the node is the module's **canary** or the canary runs it healthy, at most `step`
@@ -238,7 +245,9 @@ source revision is derived from the keys: every **want** equals its module's **f
§3; ADR 0539 §16). Nothing composed crosses the bus, so nothing is signed; of other nodes it reads only their
public records and the manifests wanted on them. On the node holding `mesh-broker` it also writes the bus's user
list, alone and with no want (*The bus's user list*, below).
- **The grants part** (module `mesh-grants`, holding the seat `mesh-grants`) composes who may say what on the bus
- **The grants part** (module `mesh-grants`; from research 085's milestone it claims the seat `mesh-grants`, defined
whole in `mesh-identity-and-access-contracts`, its domain's contracts module, ADR 0636 §5, as an acting part of the
step `grant`, ADR 0656 §1) composes who may say what on the bus
with mesh-sdk's bus composer, whose parts that name a seat or a holder's state are the grants part's own package
(ADR 0635 §4): each module's membership, the buckets, logs and streams a manifest declares, the
bus's user list, and `grants.<module>.<fingerprint>`, written from L7's delivery once the list the bus loaded
@@ -341,7 +350,9 @@ The target (ADR 0547):
- **The forge module** (`gitea`) publishes every forge event on the bus through the forge's system webhook
(issue 729): pull requests updated, synchronized, merged and closed, and commit statuses; no label or comment
moves a delivery, and the gate subscribes to none (ADR 0421 §11). It sets statuses, keeps the delivery's view
as one comment on the pull request, and appends to the commit's note under `refs/notes/mesh-plan`.
as one comment on the pull request, and appends to the commit's note under `refs/notes/mesh-plan`; from research
085's milestone it does these, and answers every read a delivery part makes of the forge, as the verbs of the seat
`git` it claims (*The verbs*).
- **Each node's backup seat** (`node-backup`) backs up the data a module keeps on its node before the node agent
applies a new fingerprint of it, and says on the bus when that backup ended (ADR 0404, ADR 0539 §16).
@@ -381,8 +392,8 @@ Its id is `<owner>/<repository>@<twelve characters of its commit>`. The gate hol
- the pull request (number, base, head branch, description), or none for a commit that reached the trunk
without one;
- its **state** and its **transitions** (the last hundred, each with when, the event, from, to and why);
- its **Approve**: the ask, the operator's answer with its warrant, and the review record the pull request was
opened with (ADR 0421 §5, §8);
- its **Approve**: the ask and the operator's answer with its warrant (ADR 0421 §8); the ask carries no review
record (ADR 0659 §1);
- once merged, **the commit it landed on the trunk as** and the source revision its merge moved. Every member of
a delivery group moves the same source revision (ADR 0429 §11).
@@ -415,7 +426,7 @@ From research 085's milestone the gate, holder of the seat `mesh-delivery`, keep
milestone's delivery, a ledger instance (ADR 0595's template `ledger`, ADR 0597) it alone writes (ADR 0656). It
holds:
- **the group's state**: the heads, the verdicts, the checks and the asks, which `merges` and `turns` hold today;
- **the group's state**: the heads, the verdicts, the checks and the asks, which `merges` holds today;
- **the trace**: the milestone, its issues, its pull requests, their commits, and the graph revisions the delivery
moved between;
- **what happened to each entry on each node**: for every entry of the graph difference, taken in, built, checked,
@@ -466,8 +477,9 @@ ADR 0656.
research 085, not a measurement) the ledger grows about 4 MiB a day, about 360 MiB at the default retention; its cap
is 768 MiB, twice that, so a busier month than estimated still fits. Removing a record at its retention removes its
operations and its snapshot with it, so the ledger's size follows the retention, not the mesh's age.
- **The switch carries today's state in, once.** At the new gate's start, `merges`, `turns` and every group in
flight become records, and from then on the gate writes `merges` and `turns` no more. The switch is safe to run
- **The switch carries today's state in, once.** At the new gate's start, `merges` and every group in flight become
records, and from then on the gate writes `merges` no more; `turns`, which nothing writes while the check gates no
merge, is dropped with the hold (*Nothing merges into a repository under check*). The switch is safe to run
twice: a group in flight becomes a record keyed by its milestone and heads, and a switch that finds that record
already there leaves it as it is, so delivering milestone G again after a revert makes no second record and asks
nothing again. A revert of the gate is the delivery system's restore of its kept data (*A module's kept data on the
@@ -475,14 +487,36 @@ ADR 0656.
- **The forge bridge asks the seat for a group.** It reads a group's members from the seat `mesh-delivery`'s verb
`groups`, never the gate's `merges` state, both to set the group on each merged message and to publish a group's
end again (ADR 0656, which changes ADR 0633 §4 and §5; ADR 0596). Its account holds no grant to read `merges`.
- **What the gate owes the forge is said, not watched.** The forge bridge today performs what the gate's states
`merges` and `owed` ask (a merge, a status, the delivery's view, a comment, a line on the commit's note) by watching
those keys (ADR 0437 §8), a read of another module's bus state ADR 0596 §2 ends when the gate moves. From research
085's milestone the gate says each act it owes as the event `owed` of the seat `mesh-delivery`, carrying the act,
its pull request and head, and an id; only the gate's account publishes it (ADR 0363 §2). The forge bridge hears it
through a durable consumer declared in its `consumes`, performs each id once, keeping which ids it performed in its
own state, and does it through the seat `git`'s verbs. The verb `groups` also answers, per group, the acts the gate
said with their ids, and the bridge's tool `bridge_owed` the ids it performed and when, so a person reads both sides
through their owners and nothing reads the other's state. This
is the design's choice under ADR 0596 §1, §2 and ADR 0656 §7: an event consumed durably loses no act while the
bridge is down and performs none twice, and one verb answers a group and what it owes (lead-47, 2026-11-09: no
second verb). How it is checked: in the forge bridge's whole-module test an `owed` said while it is stopped is
performed once after its restart, an act said twice is performed once, its account cannot read `owed`, and
`bridge_owed` lists what it performed; in the gate's, `groups` answers each act it said for a group, with its id.
- **A merge made at the forge has a record too.** A merge the forge reports that the gate did not make (a person's
merge in the forge's own page, as on 2026-11-07 and 11-09) is taken in like any other merge (*Taken in by the
indexer it names*), and the gate opens a delivery record for it on the forge bridge's merged message, marked
`forge-made`, with no Approve, so its trace and its outcomes on the nodes are kept like every delivery's and no
later merge waits behind a merge the gate never heard. The design's choice under ADR 0656 §7 and ADR 0633 §1 (the
operator, 1921's note of 2026-11-07: "a merge made in the forge is taken in like any other"). How it is checked: in
the gate's whole-module test a merged message with no record of the gate's opens a `forge-made` record, and a later
merge in the same repository is taken in behind it.
- **Its tools**, against the four lines a module's tools answer:
| Line | The gate |
|---|---|
| read everything it holds | `gate_record` (one record whole: the group's state, the trace, each entry's outcome per node, the nodes away), `gate_records` (every record with its fill against the value limit, and the ledger's fill against its cap), `gate_consumer` (its durable consumer: the last event applied per family, the events waiting, the age of the oldest) |
| do by hand what it does itself | `gate_record_repair` (for one record, asks each owner for the outcome of each entry missing one through that owner's read verb: the indexer's `take-in` read, the builder's build read, the checker seat's check read, the seat `mesh-wants`'s `entry`, and the node-engine seat's have read of that node; applies the answers as the consumer would) |
| do by hand what it does itself | `gate_record_repair` (for one record, asks each owner for the outcome of each entry missing one through that owner's read verb: the indexer's `take-in` read, the builder's build read, the checker seat's check read, the seat `mesh-wants`'s `entry`, and the node-engine seat's verb `haves` of that node; applies the answers as the consumer would) |
| recover without help | `gate_record_end` (end a record left open, a node gone for good or an entry that never runs, with the reason, recorded in the hand-act log of the seat `mesh-hand-acts`) |
| one seat, many tools | the seat `mesh-delivery`'s verbs, with `groups` answering a group's members |
| one seat, many tools | the seat `mesh-delivery`'s verbs, with `groups` answering a group's members and the acts said for it |
- **How it is checked.** In the gate's whole-module test: the gate stopped and restarted in the middle of a delivery
leaves the record complete with no outcome counted twice; the events `pinned`, `freed`, `heads-replaced` and
@@ -512,7 +546,7 @@ state has a **bound**: how long it may be held before `stalled` lists it, for a
| proposed | a head was announced and is being checked | 1 hour from when its check is asked; none while its verdict is out of date and no check is asked |
| ready | it passed; its Approve is asked (a group member's once the group is ready), and it waits for it and the merge | none |
| rejected | it failed its check | none |
| held | it waits for a person, a carry or a check: an approved merge whose verdict is being carried to the trunk's head, a conflict, a member the forge refused, and, while the check gates merges, an approved merge waiting on its merge turn for another delivery's running check (ADR 0548 §2, §8, ADR 0551 §1) | 1 day; a merge turn 30 minutes |
| held | it waits for a person, a carry or a check: an approved merge whose verdict is being carried to the trunk's head, a conflict, a member the forge refused, and, until research 085's milestone and while the check gates merges, an approved merge waiting on its merge turn for another delivery's running check (ADR 0548 §2, §8, ADR 0551 §1) | 1 day; a merge turn 30 minutes, until that milestone |
| merged | merged on its trunk; its source revision moved | final |
| closed | closed without a merge | final |
@@ -686,11 +720,28 @@ Findings 11). How each is kept, read and retained is this design's choice under
candidate's view is read only by the parts that judge a candidate, inside the check its manifest validator and
composer, and the indexer's candidate pass (ADR 0656, which changes ADR 0636 §4 in that the candidate pass joins
them).
- **The trunk's heads come from the catalog half.** The checker takes the trunk heads a check merges onto from the
catalog half, which carries the heads, and never reads the gate's state `source` (ADR 0596 §2); with the hold and
the turns removed it reads nothing of the gate at all (*Nothing merges into a repository under check*).
- **The indexer reads every definition before it judges.** At its start the indexer reads the seat definitions of
every contracts module's trunk through the forge (the seat `git`'s verbs) before it judges a manifest or answers
`seat-definitions`, and only then follows the forge bridge's stream; a definition merged while it was down is
therefore never judged against a list that lacks it. The design's choice under ADR 0636 §1 and §4, as the operator
asked it (1921's note of 2026-11-07: "the indexer reads its seat definitions at start"). How it is checked: in the
indexer's whole-module test, started with a definition on a contracts trunk that no event announced, the first
manifest claiming that seat is judged with it.
- **Who holds a seat is applied by one rule, from what each node runs.** The node-engine and the grants part decide a
seat's pass by mesh-sdk's `SeatsToPassOn` (ADR 0660 §3), reading the manifest of the build each assignment runs
(ADR 0660 §2). The build another node runs is read through the node-engine seat's verb `haves` of that node, never
its have key, its want or the assignment half (ADR 0596 §2; *Each part acts on its own entries*). The verb is the
design's choice under ADR 0660 §2: the node that runs a build is the one owner of what it runs. How it is checked:
in the node-engine's and the grants part's whole-module tests a pass is decided from a stand-in seat answering
`haves`, and neither part's account can read another node's have key.
- **A part with no view says it waits.** It names the revision it has no view for, acts on nothing new, and keeps
running what it runs, as ADR 0636 §1 has a reader of the seat list do; the checker, the builder and the grants part
wait too, and wait for the view, not only the seat list (ADR 0656, which changes ADR 0636 §1); the node-engine waits
for the catalog half as ADR 0636 §1 already has it wait for the seat list. Each answers `waits` in its runtime tool
(below) with the revision it waits for and since when, and after five minutes without a view writes the finding
for the catalog half as ADR 0636 §1 already has it wait for the seat list. Each answers in its runtime's first-view
tool (below) the revision it holds, the one it waits for and since when, and after five minutes without a view writes the finding
`view-waits` naming itself and the revision, as a reader of the seat list does, which the condition keeper raises
(ADR 0564 §2); it clears when the view arrives. Five minutes is the bound the seat list's readers already keep, so an
indexer or assigner down for a restart raises nothing. A part restarted while the indexer or the assigner is down
@@ -718,7 +769,18 @@ ADR 0656 leaves how each part is built to this design, under issue 1921; these f
(ADR 0656, Consequences); that is the same rebuild the fingerprint handover makes, so the milestone rebuilds every
module once in all, and no other module's code changes. A definition carrying `acts` reaches only readers built with
that runtime: the seat definitions that gain it are members of milestone G's group, and every reader is rebuilt in
the same delivery.
the same delivery. The bootstrapped definitions every reader carries from its start (ADR 0636 §2), four of which
gain `acts` (`mesh-catalog`, `mesh-delivery-checker`, `node-engine`, `node-backup`), are made again from the new
definitions in the same change, and mesh-sdk's existing test that each bootstrapped copy equals its definition holds
them to it.
- **One wiring of the seat list's reader.** The reader of the seat list and its two tools of ADR 0636 §7 are wired once,
by mesh-sdk's runtime (`go/seatlist`), for every part that reads the list; no part wires its own. Four delivery
parts (the assigner, the checker, the indexer and the grants part) each carry a hand-wired copy today, each with its
own pair of tools, and each copy would have to learn `acts` apart. The design's choice under ADR 0636 §7, which puts
the tools in the runtime bundle: one wiring learns `acts` once, and every part's two tools are the same, named by
their module, with the same callers (any person and the healers to read, the operator and the healers to read
again), the node-engine's among them. How it is checked: mesh-sdk's seat-list test registers both tools for a
fixture part; a search of the delivery parts' code finds no wiring of its own.
- **The fingerprint handover.** The node-engine starts each process, a service or a container alike, with the
environment value `MESH_FINGERPRINT`, the fingerprint of the want it applies; mesh-sdk's runtime reads it once at the
process's start and holds it as the process's own build (ADR 0656). A process started with no value says `own build
@@ -794,7 +856,15 @@ ADR 0656 decides the direction and leaves every choice made in working it out to
| An Approve given held while its heads stand (issue 1972) | the operator approved those heads; a check of them asked again changes nothing they approved (ADR 0441 §1, ADR 0548 §8) |
| The milestone events on a subject of their own | a waiter on one member's pull request otherwise wakes on every member's |
| The issue tracker's link kinds to a decision and a research effort, and the knowledge base's link from a decision to its milestone | the trace from research to the running build is then links all the way, with no text match (research 085, Findings 7; ADR 0493 §4) |
| Two view tools in mesh-sdk's runtime bundle beside ADR 0636 §7's, the finding `view-waits` after five minutes, and `node_process_builds` | every part's view and every process's own build is read and steered by a tool, and a part waiting for the view is raised on the bound the seat list's readers keep |
| The view's state read and asked again by mesh-sdk's `go/views` tools `<module>_first_views` and `<module>_first_view_again`, which gain the revision a part holds and what it waits for; the typed first view and the following of each half in the seats' client packages `meshcatalogclient` and `meshwantsclient`, built on `go/views`; the finding `view-waits` after five minutes; and `node_process_builds` | every part's view and every process's own build is read and steered by a tool; `go/views` already follows an owner's events durably and serves those two tools, so a second follower or a second pair of tools would be two forms of one thing; a view tool typed by the two seats would make mesh-sdk import contracts (ADR 0635 §4), so the typed half sits in the seats' client packages (ADR 0625 §4); a part waiting for the view is raised on the bound the seat list's readers keep |
| The seat list's reader and its two tools wired once by mesh-sdk's runtime | ADR 0636 §7 puts them in the runtime bundle; four hand-wired copies would each learn `acts` apart |
| The trunk's heads from the catalog half, and nothing read of the gate by the checker | ADR 0596 §2; with the hold and turns removed nothing of the gate is left for the checker to read |
| The indexer reads every contracts trunk's definitions at its start, before it judges | a definition merged while it was down is never judged against a list that lacks it (ADR 0636 §1) |
| Another node's running build read through the node-engine seat's verb `haves` | ADR 0660 §2 reads the manifest of the build each node runs, and that node is its one owner (ADR 0596 §2) |
| What the gate owes the forge said as the event `owed`, consumed durably by the forge bridge, and answered by `groups` | ADR 0596 §1, §2 end the bridge's watch of the gate's keys; a durable consumer loses no act and performs none twice; one verb answers a group and what it owes |
| A merge made at the forge opens a `forge-made` delivery record | its trace and outcomes are kept like every delivery's, and no later merge waits behind a merge the gate never heard |
| Every delivery part reaches the forge only through the seat `git`'s verbs | the delivery parts name no other module (ADR 0656 §1, acceptance test 27), and the forge's answers are typed in the seat's contract instead of guessed in each caller |
| A check that failed because a part of the mesh was not heard says `could not run`, naming the part, and is asked again on that part's `running` event | the operator sees a mesh fault apart from a failing change, and the check is asked again on the one event that can change its outcome, never on a timer (issue 1373) |
| Every drop and release tool writes the hand-act log | a hand act that changes what the mesh runs or keeps is recorded with who did it and why, as every hand act is (seat `mesh-hand-acts`) |
Each choice is checked by the tests its section names; the review by architectural domain judges them.
@@ -814,12 +884,12 @@ say another runs a build (ADR 0363 §2); the gate's events are granted to the ga
| Step | Event | Owner: the seat, then the module | Subject | Declared in |
|---|---|---|---|---|
| a catalog graph revision kept | `catalog-revision` | `mesh-catalog`, the indexer | `mesh.seat.mesh-catalog.event.catalog-revision` | the seat's definition in `mesh-delivery-contracts` |
| an assignment graph revision kept | `assignment-revision` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.assignment-revision` | the seat's definition in `mesh-placement-contracts` |
| an assignment graph revision kept | `assignment-revision` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.assignment-revision` | the seat's definition in `mesh-delivery-contracts` (ADR 0641 §2) |
| a difference worked out | `difference` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.difference` | the same |
| an entry taken in | `take-in.taken`, which gains the entries | the indexer's own | `mesh.stream.mesh-delivery-indexer.event.take-in.taken` | the indexer's manifest |
| an entry built | `build.ended` | the builder's own | `mesh.stream.mesh-delivery-builder.event.build.ended` | the builder's manifest |
| an entry checked | `checked` | `mesh-delivery-checker`, the checker | `mesh.seat.mesh-delivery-checker.event.checked` | the seat's definition in `mesh-delivery-contracts` |
| an entry wanted | `wanted` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.wanted` | the seat's definition in `mesh-placement-contracts` |
| an entry wanted | `wanted` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.wanted` | the seat's definition in `mesh-delivery-contracts` (ADR 0641 §2) |
| an entry composed, and running healthy | `composed`, `running` | `node-engine`, the node-engine on each node | `mesh.seat.node-engine.event.composed.<node>`, `.running.<node>` | the seat's definition in `mesh-contracts` |
| a node's capabilities changed | `capabilities-changed` | `node-engine`, the node-engine on that node | `mesh.seat.node-engine.event.capabilities-changed.<node>` | the same |
| a wait held, and ended | `wait-held` (step, acting part, its version, the entry, since when, its bound), `wait-ended` (the same, and how: ran, released) | each holder: `mesh-wants` for the assigner (placing, wanting and composing), `mesh-grants` for the grants part, the builder's own stream | `mesh.seat.<seat>.event.wait-held`, `.wait-ended`; `mesh.stream.mesh-delivery-builder.event.wait-held`, `.wait-ended` | each seat's definition; the builder's manifest |
@@ -847,8 +917,13 @@ on another node's subject is refused by the bus.
Every drop and release tool writes its act, who did it and why, in the hand-act log of the seat `mesh-hand-acts`.
Beside ADR 0636 §7's two tools in mesh-sdk's runtime bundle, which read a reader's seat list and make it read the
list again, the bundle gains two for the view: `waits`, which reads which view revision a part holds and what it
waits for and since when, and one, granted as ADR 0636 §7's second is, that makes it read the view again now. A tool
list again, the view is read and steered by the two tools mesh-sdk's `go/views` already serves every part that takes a
first view: `<module>_first_views` gains which view revision the part holds, what it waits for and since when, beside
what it heard and how far it is behind, and `<module>_first_view_again`, granted as ADR 0636 §7's second is, makes it
read the view again now. `go/views` stays seat-neutral, naming no seat and no seat's type (ADR 0635 §4); the typed
first view of each half and the following of its events are the seats' client packages, `meshcatalogclient` for
`mesh-catalog` and `meshwantsclient` for `mesh-wants`, each built on `go/views` (ADR 0625 §4), so no part follows the
view by a follower of its own. A tool
of the node-engine, `node_process_builds`, reads the build each process was started with. The tools answer the four
lines every module's tools answer (design 26), so that every state these parts keep is read and every act they do is
steered by a tool.
@@ -874,9 +949,11 @@ places; the builder and the grants part read their entries only through the seat
the node-engine reads its want and the catalog half and never the assignment half. Whole (node-engine): a part started
while its node's want differs from what runs reports the build it was started with. Live: a search of the readers'
code finds none of the reads the revision view replaces, each by name: the indexer's read of the checker's previews,
the checker's watch of the indexer's `candidates.<try id>`, the forge bridge's read of the gate's `merges`, the
checker's validator request with no seat definitions, and a seat list compiled into the node-engine, the checker, the
builder or the grants part; an old node-engine that wakes takes its new build in a form it reads.
the checker's watch of the indexer's `candidates.<try id>`, the forge bridge's read of the gate's `merges` and `owed`,
the checker's read of the gate's `source` and `turns`, the grants part's read of the assigner's state `wants`, the
checker's validator request with no seat definitions, a seat list compiled into the node-engine, the checker, the
builder or the grants part, a seat list's reader wired by a part itself, and a call of the forge module's own tools by
a delivery part; an old node-engine that wakes takes its new build in a form it reads.
## Order without a person
@@ -899,7 +976,8 @@ per module and node from the keys:
- **An SDK change ships with its users.** mesh-sdk is a library built into the modules that use it, so no
module waits for it to be sent anywhere (ADR 0482 §1).
- **No `after:` line is read.** The gate reads no `after:` line, no refusal asks for one, and a description
that holds one is told once on its pull request that the line is not read (ADR 0419 §2).
that holds one is told once on its pull request that the line is not read (ADR 0419 §2), until milestone G, in
which that notice goes with the gate's last read of a description (ADR 0659 §4; *The Approve and the merge*).
### An acting part's new version acts first, a wait with a bound
@@ -1041,7 +1119,13 @@ commit on the SDK's trunk or the head of an SDK pull request the forge holds, op
request's key and stops when the head in it moves, without asking the forge (issue 726); an ended check
delivers no verdict, so none of its builds is reused. A trunk move never ends a check: its verdict goes out of
date when it ends, and is carried. A check that failed because a part of the mesh was not heard is still asked
again when the nodes change, which judges heads no check judged.
again when the nodes change, which judges heads no check judged. From research 085's milestone its verdict says
`could not run`, naming the part not heard, and it is asked again on that part's `running` event of the
node-engine seat (*What each step says*), never on a timer; a second check of the same heads asked while one runs,
or one erred, claims nothing and writes no status, by the claim above (issue 1373; ADR 0548 §1, ADR 0656 §5). How
it is checked: in the checker's whole-module test a check whose composer's node does not answer says `could not
run` naming it, and is asked again once a fixture `running` event of that node is said; a second ask of the same
heads writes no status.
- **A failed build node loses nothing.** An ask a build module took and never acknowledged goes to another node by the
stream's own acknowledgement wait, with no timer of a part; a step's end is written on the build module's step key named
by the ask's id (ADR 0525 §6).
@@ -1103,7 +1187,22 @@ the check gates merges.*
### Nothing merges into a repository under check
*ADR 0548 §2 to §4, §9, §10, as ADR 0551 bounds them.*
*ADR 0548 §2 to §4, §9, §10, as ADR 0551 bounds them; from research 085's milestone removed, by the operator's word,
its record still to be written (below).*
**Removed at research 085's milestone.** The hold, the merge turns, their stalled line, the gate's tools for them and
the setting `check-gates-merge` go in milestone G (the operator, on Telegram, 2026-11-09 01:11 UTC, choosing "Remove them
in G"). The setting has been false since 2026-10-25, so the gate wrote no turn and held no merge in that time, and the
operator's word for G is that no check gates delivery (1921's note of 2026-11-07). From G's delivery an approved merge
is handed to the forge bridge at once; a check running on a repository the merge goes into ends on the commit it read,
and its verdict is carried (*A move of the trunk carries every verdict*); the checker reads nothing of the gate, and
the gate no longer watches the checker's verdicts for a hold. **No record carries this yet:** ADR 0548 §2 to §4, §9
and §10 and ADR 0551 are in force, and a record that ends them is written before this design is merged; until it is
accepted, the rule below holds as those records have it. How it is checked: in the gate's whole-module test an approved merge into a
repository under a running check is handed at once, and the gate's manifest declares no `turns` and no setting
`check-gates-merge`; in the checker's, a check claims at once with no gate state granted to read.
Until milestone G's delivery:
**Only while the check gates merges.** The hold, the merge turns and their stalled line hold only while the
setting `check-gates-merge` of mesh-delivery-gate, set together with the forge module's, is true. While it is
@@ -1374,12 +1473,12 @@ pull request, and it owes the forge nothing.
## The Approve and the merge
*ADR 0421, ADR 0398 §3, ADR 0406 §1.*
*ADR 0421, ADR 0398 §3, ADR 0406 §1, ADR 0659.*
- **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
merge into main at once, on a channel that proves who answered (ADR 0274; Telegram today). The ask names the
pull request, its issues, the reviewer's verdict, the modules it moves and the trunk commit the checks judged. A
pull request, its issues, the modules it moves and the trunk commit the checks judged, and no review (ADR 0659 §1). A
verdict that names a trunk commit the trunk had already left raises no ask: the checker carries it to the
trunk's head, and the carried verdict raises the ask (ADR 0421 §1, as ADR 0548 §8 changes it).
- **A group is asked once.** One ask names every member and its head, once every member is `ready` and the
@@ -1388,15 +1487,23 @@ pull request, and it owes the forge nothing.
milestone is not asked (ADR 0493 §9, §11, which change ADR 0421 §1 and §2); the Approve it asks is also written
into the wait list of the session a `Waited-by: <name>@<node>` line on the pull request names, and only when the
pull request carries that line; without it the pull request is asked as today (ADR 0491 §3, §5).
- **The reviewer's verdict is attached, not a gate.** The review finishes before the push (playbook 07), and the
session that opens a pull request gives its review record: who reviewed it, the commit the review approved and
the verdict; from the delivery of issue 1782 a verb of the delivery seat records it at the head it judged, and no
description is read (ADR 0493 §5, §6). The ask carries it; with none, or one naming another commit, the ask says so in its first line and
the operator decides (ADR 0421 §5).
- **The review is the session's, and no part reads it.** The review finishes before the push (playbooks 07 and 08);
the session may name its reviewer in the description for people, and nothing reads it: the gate raises the ask
without any review line, the ask carries no review record, and an edit of the description withdraws nothing
(ADR 0659 §1 to §3, which supersedes ADR 0496 and changes ADR 0493 §5, §9, §12). A review verb of the delivery
seat, if issue 1782 builds it, records a review people may read and gates nothing (ADR 0659 §2). Every wait of the
gate is on a state or an event of the bus (ADR 0659 §5).
- **The description's last three reads go in milestone G.** The issue numbers the ask names, the author a stalled
line names and the one notice that `after:` lines are not read are the three reads of a description ADR 0659 §4
leaves until they move to the bus. In milestone G the issue numbers come from the issue tracker's links of the
milestone (ADR 0493 §4, issue 1783), the author from the forge's pull request record, read through the seat
`git`'s verb `pull`, and the notice goes, so no part of the mesh reads a description at all. How it is checked: a
test over the gate's code, beside ADR 0659 §6's rows, finds no read of a description field.
- **The merge.** mesh-delivery merges through the forge's merge tool at the heads the Approve names, only while
they are still the heads, their check passed against the trunk's head, and, while the check gates merges, no
check of other heads runs on a repository the merge goes into (*Nothing merges into a repository under check*,
above). When the trunk moved, the merge waits for the carried verdict, and the event of its line asks the merge
above, which milestone G removes). From milestone G the forge bridge merges through the seat `git`'s verb
`merge-pull`, which keeps the merge tool's judgement of ADR 0534 §4. When the trunk moved, the merge waits for the carried verdict, and the event of its line asks the merge
again; no timer asks it, no person rechecks, and the Approve is not asked again (ADR 0421 §3, §12, as ADR 0548
§8 changes them). The merge tool still refuses a verdict naming a trunk commit other than the trunk's head and
asks nothing (ADR 0534 §4); the carry makes the verdict current.
@@ -1405,7 +1512,7 @@ pull request, and it owes the forge nothing.
is said once (ADR 0421 §6).
- **A failure is said, never merged past.** An approved head whose check failed is said once on the pull request
and listed by `stalled`; so is a merge the merge tool kept refusing for an hour (ADR 0421 §7).
- **Recorded.** The ask, the answer with its warrant and the review record are kept on the delivery, shown by
- **Recorded.** The ask and the answer with its warrant are kept on the delivery, shown by
`show` and said in mesh-delivery's log; the merge's transition names the Approve (ADR 0421 §8).
## After the merge: the source revision and the wants
@@ -1498,6 +1605,15 @@ timer. A group's merges arrive together.
held group (ADR 0441 §3, §4); the gate passes the group's end by without counting it a refusal. A later merge in
a member's repository waits behind the group; a merge in another repository is taken in alone, unless a revision
is pending for its indexer (ADR 0633 §4, which builds ADR 0429 §11 for take-in).
- **A merge the gate did not make is taken in like any other.** When the forge says a pull request merged and the
gate holds no merge of it (a person merged it in the forge's own page), the forge bridge reads that pull request
by its merge commit (from milestone G through the seat `git`'s verb `pull`) and publishes its merged message with
the merge's trees as for any merge; the indexer takes it in under the bullets above, and a later merge's take-in
that its repository's taken merge covers ends with it, so nothing waits behind it. The gate opens a `forge-made`
record for it (*The delivery record*). The design's choice under ADR 0633 §1 and §4, as the operator asked it (1921's
note of 2026-11-07); built in the issue 1966 recovery (mesh-delivery #185, #187), kept whole in milestone G. How it is
checked: in the forge bridge's whole-module test a merge with no merge of the gate's publishes its merged message,
and in the indexer's take-in table a merge its taken merge covers is ended.
- **A wait is bounded, said and recoverable.** The indexer's tool `indexer_pending` reads the pending revisions and
the members still gathered, each with its merges, the indexer build it waits for, since when and `refused`; the
view names a module waiting for its revision's indexer through that tool (ADR 0633 §5, which changes ADR 0603
@@ -1682,7 +1798,7 @@ later change of a kept data's form, not as a case of this milestone.
- **How placement is changed.** The seat `mesh-module-assigner`, held once for the mesh by the assigner, keeps three
states: `placement`, one key `placement.<node>` per node; `proposals`; and `candidates`. Only the holder's
credential writes them, and the contract (the states' layouts among it) is the seat's, in
`mesh-placement-contracts` (ADR 0634 §6, §7). No repository holds
`mesh-contracts`, module assignment being of the Core domain (ADR 0634 §6, ADR 0641 §1). No repository holds
placement and none names a node: what differs between nodes is bus state, and a build module's capacity and
build hours are values on each node's layer of mesh-config. A key holds what a person decides of the node and
nothing a machine observes:
@@ -1726,7 +1842,7 @@ later change of a kept data's form, not as a case of this milestone.
holder hears that key's change; nothing polls. The nodes that must answer are each node whose key the proposal
changes and each node whose composition the holder finds changed with the current inputs on both sides, not every
placed node, so a node gone for good or asleep blocks only a proposal that touches it. The contract (the state,
its key, the answer) is the seat's, in `mesh-placement-contracts` (ADR 0567, ADR 0634 §6, §7); the composition with
its key, the answer) is the seat's, in `mesh-contracts` (ADR 0567, ADR 0634 §6, ADR 0641 §1); the composition with
a given placement is the composition of `mesh-delivery-sdk` (ADR 0635 §4), and the comparison is the node-engine's
own package (ADR 0634 §1).
- **The holder judges the answers and the operator approves.** The holder computes, by node, the modules the
@@ -1767,6 +1883,13 @@ later change of a kept data's form, not as a case of this milestone.
the node composing it keeps what runs until the vault holds it. Likewise a consumer of `model-access` answered by a
licence record, placed before the vault serves licences (ADR 0550 §3, issue 569), is refused by the same guard and
its node keeps what runs; none is placed today.
- **A claim problem holds its module, never the node's pass.** When a module's claim cannot be held (its seat's
definition missing, removed or refused, a claim another holder keeps, a credential the vault refuses), the node agent
composes that module as left out, keeping its openings, says why in its have, and composes and applies every other
module of the node; it never refuses the whole pass for one module's claim (ADR 0636 §3: a refused definition blocks
new claims of that seat only). Met on 2026-11-08, when one claim problem refused a node's every module (issue 1966).
How it is checked: in the node-engine's composition table a node with one module whose claim is refused applies the
others, and that module's have names why.
- **The order a node takes to composing its own.** One delivery group carries every part: the seat `mesh-module-assigner`
on the assigner, the controller's verb `placement-export` (as it is) and the controller's pin only, the node-engine
(its record and its own composer), the vault's `own`, the grants part's reads, and mesh-config's reading of
@@ -1975,7 +2098,7 @@ forge module's files of what it announced (ADR 0406 §6).
| Verb | Answers or does |
|---|---|
| `deliveries` | every delivery not final, the final ones of the last day, and every one `stalled` still lists |
| `show` | one delivery or group whole: the Approve, transitions, the review record, the source revision its merge moved |
| `show` | one delivery or group whole: the Approve, transitions, the source revision its merge moved; no review record from milestone G (ADR 0659 §1) |
| `groups` | every group with its members and its derived state |
| `table` | the state table, with its bounds |
| `stalled` | every merge or check held past its bound |
@@ -1989,8 +2112,9 @@ From research 085's milestone the seat gains:
| Verb or event | Answers or does |
|---|---|
| `groups` with a group | that group's members, which the forge bridge reads in place of the gate's `merges` state (ADR 0656) |
| `milestone.asked`, `milestone.withdrawn`, `milestone.answered` | the one Approve ask per milestone (ADR 0493 §9 as ADR 0496 §2 changes it, issue 1783), held until it is answered, or withdrawn by a new head and asked again (ADR 0441 §1); said on `mesh.seat.mesh-delivery.event.milestone.<milestone>.<event>`, apart from each delivery's `transition`, which stays as it is, so a waiter on one member's pull request wakes only on that member's `transition` |
| `groups` with a group | that group's members, which the forge bridge reads in place of the gate's `merges` state (ADR 0656), and the acts the gate said it owes the forge for it, each with its id (*The delivery record*) |
| `owed` | an act the gate owes the forge (a merge, a status, the delivery's view, a comment, a line on the commit's note), with its pull request, head and id, said only from the gate's account and heard by the forge bridge through a durable consumer (*The delivery record*) |
| `milestone.asked`, `milestone.withdrawn`, `milestone.answered` | the one Approve ask per milestone (ADR 0493 §9 as ADR 0659 §1 changes it, issue 1783), held until it is answered, or withdrawn by a new head and asked again (ADR 0441 §1); said on `mesh.seat.mesh-delivery.event.milestone.<milestone>.<event>`, apart from each delivery's `transition`, which stays as it is, so a waiter on one member's pull request wakes only on that member's `transition` |
| `pinned`, `freed`, `heads-replaced` | the events by which the indexer and the assigner keep or drop graph revisions, said only from the gate's account (*The delivery record*) |
| `record-ended`, `filling`, `full`, `room` | a delivery record ended; the ledger past 80 % of its cap; the ledger full; the ledger back below its cap (*The delivery record*) |
@@ -1998,8 +2122,42 @@ From research 085's milestone the seat gains:
of the revision view, ADR 0656), and `entry` and `difference` on `mesh-wants` (ADR 0656), with the events of *What
each step says*.
**Links of the trace.** A review stays the line in a pull request's description, as ADR 0496 §3 has it, until issue
1782 builds the review verb and settles who may review and its grant, outside milestone G. The trace's links are this
**The seat `node-engine`** gains, from research 085's milestone, the verb `haves`: what its node runs of each module,
the fingerprint and its phase, which the node-engine of another node and the grants part ask to decide a seat's pass
(ADR 0660 §2; *Who holds a seat is applied by one rule*), and the gate's `gate_record_repair` asks for a missing
outcome. It answers from the node's own haves, and every node's account may call it.
**The seat `git`.** The seat `git` (design 26, *The git seat*), of the Delivery domain, defined in
`mesh-delivery-contracts`, holds no verb today, and the delivery parts reach the forge by naming the forge module's own
tools and guessing the shape of their answers (on 2026-11-09 one guess, an answer wrapped in a `result` field, made
316 conditions stand, issue 1966). From research 085's milestone the seat's definition carries the verbs below, their
inputs and answers typed in its contract, served by the module that claims the seat; every delivery part calls the
seat, never the forge module by name (acceptance test 27). The verbs are this design's choice under ADR 0596 §2 (a
module's data is asked through its seat verbs) and ADR 0625 §1 (a seat's contract is generated from its definition),
each for a call a delivery part makes of the forge today:
| Verb | Answers or does | Called by |
|---|---|---|
| `pull` | one pull request, by its repository and number or by its merge commit: number, base, head branch, head, merge commit, author, state | the forge bridge (a merge the gate did not make), the gate's author of a stalled line (*The Approve and the merge*) |
| `open-pulls` | every open pull request of every repository, its head and base, the statuses its base requires and those its head has | the forge bridge, at its start and each reconnect (ADR 0443 §5) |
| `tags` | a repository's tags, paged, with the page's bound said when more exist | the forge bridge, for the builder's floor |
| `trees` | the trees of one commit | the forge bridge (a merged message's trees), the checker, the indexer (the definitions at its start) |
| `file` | one file at one commit | the checker, the indexer |
| `commits` | the commits between two commits of a repository | the checker |
| `branches` | a repository's branches with their heads | the checker |
| `contains` | whether one commit contains another | the indexer |
| `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` | the forge bridge alone, performing the gate's `owed` |
| `merge-pull` | merges a pull request at a head, judging what the forge module's merge tool judges today (ADR 0534 §4) | the forge bridge alone |
The verbs that act are granted to the forge bridge's account alone, so the bridge stays the one part that acts on
the forge; the reads are granted to each part that declares them in its `invokes`. A verb's answer is the contract's
type, never a wrapper a caller unwraps. How it is checked: the seat definition's conformance fixtures hold one answer
of each verb, and the forge module's tool tests answer each fixture; the forge bridge's, the checker's and the
indexer's unit fakes answer from the same fixtures; a call of a verb that acts from an account other than the forge
bridge's is refused by the bus; live, a search of the delivery parts' code finds no name of the forge module's tools.
**Links of the trace.** No part reads a review line (ADR 0659 §1 to §3); who may review and the review verb's grant
stay issue 1782's, outside milestone G, and that verb gates nothing (ADR 0659 §2). The trace's links are this
design's choices under ADR 0656, so that one call traces research to the running build
with no text match (research 085, Findings 7). The issue tracker gains link kinds from an issue to the decision and to the research effort
it carries, made by a tool call and never by text, as ADR 0493 §4 has every link made; the knowledge base gains a
@@ -2011,6 +2169,14 @@ an issue linked to a decision and to a research effort reads both back; a decisi
back. Live: research 085's milestone's record reads back research 085 to its decisions, its milestone, its issues and
its pull requests with no text match.
**A session hears that a record was accepted** (issue 595). The knowledge base already says, on its holder's own
stream, the event `reviewed` for every judgement of a record; from milestone G that event carries, when the operator's
Approve accepts a record, that it was accepted and by the operator, with the warrant, and the tool runner's account is
granted to hear it, so a session waiting on a record wakes on it. The design's choice under ADR 0596 §1 (a module's
events are subscribed to): a new event of the seat `knowledge-base` would be a second path for the same fact (lead-47,
2026-11-09). How it is checked: in the knowledge base's whole-module test an Approve that accepts a record says
`reviewed` with what was accepted and by whom, and the tool runner's account hears it.
**The status view's tools** read the keys and change nothing: `assigner_wants`, `assigner_want`,
`assigner_differences` and `node_haves`, beside the indexer's and the builder's. Its events are `delivered`,
`moving`, `settled` and `stuck` (*A delivery* above).
@@ -2179,7 +2345,8 @@ development, the check's share about a minute):
From ADR 0548 and ADR 0551 (issue 568):
25. **One check per delivery.** A delivery group of two repositories is under check, and a lone pull request into
one of them is approved during the run. While the check gates merges, it waits, `mesh-delivery.show` says
one of them is approved during the run. From milestone G it merges at once, as it does today with the setting
false, and nothing of the hold is left to read (test 52). Until then: while the check gates merges, it waits, `mesh-delivery.show` says
what it waits for, and it merges when the group's verdict is written; while it does not, it merges at once and
the group's running check ends on the commit it read. Either way the group's verdict is then carried to the
new trunk commit with no test run for an unchanged digest, and the group merges on its Approve with no second
@@ -2268,7 +2435,7 @@ Each change ADR 0656 makes in an earlier record, and its test:
their check naming the part, and no module of them is composed from its manifest (whole, checker).
47. **A part waits for the revision view** (ADR 0636 §1, §4). With the indexer stopped, then with the assigner stopped,
and on a cold control-node whose parts all start with no view, the checker, the builder and the grants part each
keep running what they run, answer `waits` with the revision and since when, write `view-waits` after five minutes,
keep running what they run, answer in `<module>_first_views` the revision they wait for and since when, write `view-waits` after five minutes,
and act once the view is back, clearing it; the node-engine waits only for the catalog half; a candidate's heads
are read by the indexer's candidate pass and by no running part (whole).
48. **A process reports its handed build** (ADR 0639 §7). A part started while its node's want differs from what runs
@@ -2277,6 +2444,28 @@ Each change ADR 0656 makes in an earlier record, and its test:
merged message and publishes a group's end again from the seat `mesh-delivery`'s verb `groups`, and its account
holds no read of the gate's `merges` state, so a read of it is refused (whole, forge bridge).
What milestone G's prepare found, and its test:
50. **No description is read** (ADR 0659 §4). The Approve ask names the issues read from the milestone's links and a
stalled line the author read through the seat `git`, no notice of an `after:` line is said, and a test over the
gate's code finds no read of a description field (whole, gate).
51. **The forge is reached through its seat.** Every act the forge bridge performs and every read the forge bridge,
the checker and the indexer make of the forge goes through a verb of the seat `git`, each answer decoded as its
contract's type; an act called from an account other than the forge bridge's is refused; a search of the
delivery parts' code finds no name of the forge module's tools (whole, forge bridge; live).
52. **Nothing holds an approved merge for another check.** An approved merge into a repository under a running check
is handed at once; the gate declares no `turns` and no setting `check-gates-merge`, and the checker is granted no
read of the gate's state (whole, gate and checker; its record first, *Nothing merges into a repository under
check*).
53. **What the gate owes is said, and a forge-made merge is kept.** An `owed` said while the forge bridge is stopped
is performed once after its restart; a merge made at the forge opens a `forge-made` record and is taken in, and a
later merge in its repository follows it (whole, gate and forge bridge).
54. **One reader of the seat list per part, and one view machinery.** Every part that reads the seat list has the two
tools of ADR 0636 §7 from the runtime and no wiring of its own; every part that takes a first view answers its
held and awaited revision in `<module>_first_views` (unit, mesh-sdk; live search).
55. **A claim problem holds one module.** A node with one module whose claim is refused applies the others, and that
module's have names why (unit, node-engine).
## What retires
- The "release branches" and the controller's check of them (ADR 0358, superseded by ADR 0401).
@@ -2326,8 +2515,11 @@ Each change ADR 0656 makes in an earlier record, and its test:
from manifests a module whose changed build module the check cannot run (ADR 0603 §10 and ADR 0614 §7, as ADR 0656
changes them); the module graph's one key per module with five past values as what parts read (ADR 0603 §2, as
ADR 0656 changes it); the tiers worked out from five live sources (ADR 0603 §6, as ADR 0656 changes it); a seat
list compiled into a part, and every read of another module's bus state the revision view replaces (ADR 0656); and
the gate's `merges` and `turns`, carried into the delivery records and written no more.
list compiled into a part, and every read of another module's bus state the revision view replaces (ADR 0656); the
gate's `merges`, carried into the delivery records and written no more, and its `owed`, said as events; the hold,
the merge turns, their stalled line and tools and the setting `check-gates-merge`, once their record is accepted;
the last three reads of a pull request's description (ADR 0659 §4); every delivery part's call of the forge module's
own tools, for the seat `git`'s verbs; and the four seat-list readers the delivery parts wire by hand.
## Milestones
@@ -2378,7 +2570,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.<module>.<fingerprint>` 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); the registry milestone's reviewed heads are joined to its group as members | 26 to 49 | mesh-sdk (the runtime: the fingerprint, the view, the definition reader), mesh-contracts and the domains' contracts modules (`acts`, the new verbs and events), mesh-delivery (indexer, assigner, checker, builder, grants part, gate's view, forge bridge), mesh-catalog (the gate, the build modules, mesh-issues, mesh-knowledge, the `node-backup` holder, nats: a module's kept data on the bus as a backed-up item), the node-engine (`mesh-host`), hq | 1966 (with the registry milestone's heads), 1961, 1660, 1962, 1972, 1721, 1783, 1785, 1794, 1791, 1373 |
| 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 | 26 to 55 | 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, builder, grants part, gate's view, forge bridge, watchman), mesh-catalog (the gate, the build modules, the forge module, mesh-issues, mesh-knowledge, the `node-backup` holder, nats: a module's kept data on the bus as a backed-up item), 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
@@ -2456,10 +2648,10 @@ order inside one milestone, for this one case (ADR 0644).
the first seat G defines; a program built from the heads reads what the heads define.
- **Where its types live.** B0 adds the ask `run`, its answer and the verdict's record of which checking program
judged it where the seats' types live on today's trunk, mesh-sdk's `go/delivery`, and the request's `seats` where the
composer's request lives, mesh-sdk's `go/composer`. `mesh-delivery-contracts` and `mesh-delivery-sdk` are created by
the registry group, which joins milestone G (ADR 0634 §7, §8), so they exist on no trunk before G; G's merge carries
these types with `go/delivery` into the seats' contracts in `mesh-delivery-contracts` (ADR 0634 §4) and the request
with `composer` into `mesh-delivery-sdk` (ADR 0635 §4), and mesh-sdk keeps no copy. The checking program, its rules
composer's request lives, mesh-sdk's `go/composer`. The registry milestone, merged after B0 and before milestone G,
made `mesh-delivery-contracts` and `mesh-delivery-sdk` (ADR 0634 §7, §8) and carried these types with `go/delivery`
into the seats' contracts in `mesh-delivery-contracts` (ADR 0634 §4) and the request with `composer` into
`mesh-delivery-sdk` (ADR 0635 §4); mesh-sdk keeps no copy, and milestone G builds on them where they are. The checking program, its rules
and its command `mesh-checking-program` are the checker module's own package in mesh-delivery, and the run step is
mesh-build-go's own (ADR 0634 §1).
- **The trunk's validator still judges inside a check.** The indexer's new manifest is also validated with the
@@ -2494,8 +2686,7 @@ B0's own choices, each checked by the rows of *How it is checked* below:
checking program (ADR 0644, Consequences), and every check costs one more ask in the build seat, within the
checker's step bound (ADR 0639 §5), the program built once per build and reused.
- **Milestone G keeps the rest**: the first tier for every acting part, the verdict that fails by name, the revision
view, the two graphs, the difference, the acting rules, the delivery record and the trace's links, with the
registry milestone's reviewed heads joined to its group. It is one milestone, one group and one check, its fixtures
view, the two graphs, the difference, the acting rules, the delivery record and the trace's links. It is one milestone, one group and one check, its fixtures
folded into the existing whole-module tests of the checker, the gate, the indexer and the assigner, and it ends with
no higher test count in any repository than it starts with (research 085, Direction, One milestone).
- **The order inside milestone G is the module graph's**, never a delivery ahead: each acting part's new version acts
@@ -2521,8 +2712,18 @@ B0's own choices, each checked by the rows of *How it is checked* below:
## What is not decided here
- Who may review a change, and the review verb's grant: issue 1782, outside milestone G; until it is built the review
stays the line in a pull request's description (ADR 0496 §3).
- Who may review a change, and the review verb's grant: issue 1782, outside milestone G; no part reads a review line
meanwhile, and the verb, if built, gates nothing (ADR 0659 §2, §3).
- **A session's merge of a recovery fix.** The operator asked that a session merge a recovery fix through a verb of
the seat `mesh-delivery`, recorded in the gate like any merge and said as an event, with no Approve (1921's note of
2026-11-07; the instruction the operator approved on 2026-11-09 says the session uses that verb once the seat serves
it). No record decides a merge without the operator's Approve: ADR 0421 §1 and ADR 0398 §3 ask it for every merge,
and the forge's merge tool merges only a head the operator approved (ADR 0534 §4). The shape this design would give
it, once a record decides it: the verb `merge` of the seat `mesh-delivery`, taking the pull requests at their heads
and the reason, refused unless their check passed, opening a delivery record marked `recovery` with the caller as
the runtime proves it, and saying the event `recovery-merged`, which the teller tells the operator on every channel,
so a recovery merge cannot go untold. Until that record is accepted it is not built, and a recovery fix is asked the
operator's Approve like any change.
- 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
@@ -2566,6 +2767,17 @@ on the step key, the wording of a failed program's verdict as an exception until
verdict's program is built; each is now written as built, with its reason. The lead's rulings on that round then moved
the input onto the checker's verb `input` (ADR 0596 §2) and the cycle rule into the checking program (ADR 0656 §5).
The amendment for milestone G's prepare (2026-11-09) writes what that prepare found where the records and the code
or this design disagreed: the homes of `mesh-module-assigner` and `mesh-wants` after ADR 0641; ADR 0659's end of every
description read and ADR 0660's one rule for a seat's pass; the checker's and the forge bridge's reads of the gate's
state replaced (the trunk's heads from the catalog half, `owed` said as an event and answered by `groups`); the hold
and the merge turns removed by the operator's word, their record still to be written; a merge made at the forge taken
in and recorded; the indexer reading every definition at its start; the seat `mesh-grants` defined in its domain's
contracts module; the seat `git`'s verbs for every call the delivery parts make of the forge; the seat list's reader
wired once by the runtime; `go/views` as the view's machinery, with the seats' client packages typed over it; a check
that could not run asked again on the missing part's `running`; and a claim problem holding one module. Its review by
architectural domain is still to come, and this section is rewritten with its findings.
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
the catch-up call; the hold's bound while a large backup is taken; the granting and placing bound read from the first