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