Answer milestone G's sixth develop batch in design 47 so develop builds without choosing

Eight questions met in the join and develop after batch 5 are written as
lines §587 to §594 of a new part G-16, each of internal form within the
records and lines it cites: the ledger's upkeep calls' shapes, publishing
again every unpublished reserved version, a whole read of a module's build
keys, one event of a node's capabilities (manifest-reads-changed, ADR 0618
§4, ADR 0673 §2), the object stores' caps, the gate's merge path from G's
delivery, the gate's dropped Approve-per-merge reads, and the manifest
readers on the catalog graph entry. §568 now cites ADR 0673 in place of
"number to come". The automatic publish on a registry holder's running is
left to the operator: no record decides it.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 15:23:04 +01:00
parent 108a56fbc7
commit 0cdd66f945
9 changed files with 220 additions and 35 deletions
@@ -4,6 +4,7 @@ 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, mesh-tools, mesh-networking, hq 00-META/checks]
updated: 2026-11-11
decisions:
- "ADR 0673"
- "ADR 0667"
- "ADR 0666"
- "ADR 0664"
@@ -117,8 +117,8 @@ each the design's choice with its reason, §468 to §479 those of the runner's,
says no set; §383's and §384's checks.
- §462 **Where the bus state calls and their capabilities land.** (§488) The calls' names and shapes are in mesh-sdk's
`go/buscalls`, which holds only those (its package's own rule): §408's ledger calls are `mesh/ledger.fill` (one
ledger's fill against its cap, as `buscalls.Fill`) and `mesh/ledger.remove` (one instance removed with its
operations and its snapshot, §155), and §407's `mesh/objects.sent-get`. The capability each belongs to is listed
ledger's history's fill against its cap, as `buscalls.Fill`, §587) and `mesh/ledger.remove` (one instance removed with its
operations and its snapshot, §155, its request and answer §587's), and §407's `mesh/objects.sent-get`. The capability each belongs to is listed
where the capabilities are today, in the tool runner in mesh-tools (its families of calls per capability): the two
ledger calls under `ledger-calls`, `mesh/objects.sent-get` under `bus-state-calls`. mesh-sdk gains no capability
list. This amends §347 ("mesh-sdk lists") and §408. Why: the tool runner states the capabilities of the calls it
@@ -295,9 +295,8 @@ reason. What a question of another kind leaves open waits for the operator and i
`wait-held` with `step: delivery` (§498) and `version-delivered`'s machines away. Why: §186 has the tiers worked out
from the difference and the owners' waits (develop questions VW2, VW3 and on §431). How it is checked: test 45; test
106 for the delivery wait.
- §513 **A state's objects store has a cap of 256 MiB, and the binding is mesh-sdk's.** (§607) The bus module plans each
`<state>-objects` (§58) with a cap of 256 MiB, as a sent store (§477), unless the state's `requires` names
`objects-max-mib`. The binding's `objects` and `sent-objects` (§399) are fields of mesh-sdk's
- §513 **A state's objects store has a cap, and the binding is mesh-sdk's.** (§607, §547, §591: the cap is §591's) The bus module plans each
`<state>-objects` (§58) with the cap §591 names, unless the state's `requires` names `objects-max-mib`. The binding's `objects` and `sent-objects` (§399) are fields of mesh-sdk's
`membership.BusBinding`, built in mesh-sdk. Why: the objects template has no default (develop questions NATS1 and
on §399). How it is checked: unit (bus module's plan), each planned objects store has its cap; unit (membership),
both fields read.
@@ -5,8 +5,10 @@ design: 47
milestone: G
updated: 2026-11-11
decisions:
- "ADR 0673"
- "ADR 0672"
- "ADR 0668"
- "ADR 0618"
- "ADR 0667"
- "ADR 0666"
- "ADR 0664"
@@ -247,7 +249,7 @@ form only. A note that corrects a line of G-12 or G-14 is written in that line;
## The builder
- §568 **A transport fault in the builder's own read ends no build key, and a key's error says which kind of fault it
is.** (ADR 0664 §1 to §3, ADR 0668 §1 to §3; issue 1612, met again 2026-11-11)
is.** (ADR 0664 §1 to §3, ADR 0668 §1 to §3, ADR 0673 §1 to §4; issue 1612, met again 2026-11-11)
- **The builder's own reads.** The builder's reads of the build seats' state `steps` (its own step keys, §467,
§481) are kept calls (ADR 0668 §1, §2). A read that meets a transport fault, of ADR 0664 §1's classes or the
read's own deadline, changes nothing the builder holds and writes no build key. The builder's watch of `steps`
@@ -261,12 +263,13 @@ form only. A note that corrects a line of G-12 or G-14 is written in that line;
build's own words) and never opens `transport fault:`. The builder's read tools show the error whole, so a reader
tells a passing cause from a real one without the journal.
- **What builds such a key again.** The operator, 2026-11-11 about 14:15 CET at lead-47's terminal, decided by the
record of the builder's retry (number to come), which changes ADR 0664 §3: a key whose error opens `transport
record of the builder's retry, ADR 0673 §1 to §3, which changes ADR 0664 §3: a key whose error opens `transport
fault:` is built again, once, as a new revision of the key (ADR 0429 §18), on the first event after its failure
that says its cause passed. Two events say so: the node-engine seat's `running.<node>.<module>` saying `running`
for a module whose catalog graph entry claims the build seat the failed step ran on (§546), on any node; and the
node-engine's `manifest-reads-changed` of the node the failed step ran on (ADR 0668 §4), which it says when that
node is heard again. The builder hears both through its consumers of the node-engine seat, read as §556 has it.
that says its cause passed. Two events say so (ADR 0673 §2): the node-engine seat's `running.<node>.<module>`
saying `running` for a module whose catalog graph entry claims the build seat the failed step ran on (§546), on
any node; and the node-engine seat's `manifest-reads-changed` of the node the failed step ran on with `why`
`returned` (ADR 0618 §4, ADR 0668 §4; §590), which it says when that node is heard again after being away. One
saying `why` `started` builds nothing again. The builder hears both through its consumers of the node-engine seat, read as §556 has it.
It builds a key again at most once per event heard, and only while the key's newest revision is that failure, so
one event starts one revision. A revision that fails again on a transport fault is said as every failed key is,
its error opening `transport fault:` again, and waits for the next such event. The builder's manifest `consumes`
@@ -280,18 +283,16 @@ form only. A note that corrects a line of G-12 or G-14 is written in that line;
*Leave it*, a decline or the ask's expiry leaves the key failed until `builder_build_again` or a new
fingerprint. The failure stays said throughout. A key failed for any other cause
is never built again on these events. `builder_build_again` (ADR 0668 §5) and the builder's next start build it
again too, as before. The builder's read tool of a key names the event that built its newest revision again,
`event-builds`, and the open ask.
- **Before develop.** These lines rest on the record of the builder's retry, which changes ADR 0664 §3 (in force);
it is accepted before G's builder is built from them, and its number replaces "number to come" here.
again too, as before. The builder's read tool of a key, `builder_build` (§589), names the event that built its
newest revision again, `event-builds`, and the open ask.
Why: a read the builder made met `no responders` and failed a key, which then stayed failed for about 45 minutes
(issue 1612, 2026-11-11), against ADR 0664 §3 (a key is not written failed while its step runs on); the retry on an
event is the operator's answer. How it is checked: unit (builder), a `no responders` read of `steps` leaves the key
`building` and the next revision ends it; a third-run transport fault's key error opens `transport fault: no
responders`, and a compile error's does not; a `running` of a holder of that build seat builds the key again once,
and a second `running` while the new revision builds starts nothing; a node's `manifest-reads-changed` builds again
a key failed on that node; a key failed on a compile error is not built again on either event; after three failed
and a second `running` while the new revision builds starts nothing; a node's `manifest-reads-changed` with `why`
`returned` builds again a key failed on that node, and one with `why` `started` does not; a key failed on a compile error is not built again on either event; after three failed
event-started revisions the fourth event asks the operator once and builds nothing, and *Build once more* builds
one.
@@ -0,0 +1,186 @@
---
layer: to-be
status: in-progress
design: 47
milestone: G
updated: 2026-11-11
decisions:
- "ADR 0673"
- "ADR 0672"
- "ADR 0668"
- "ADR 0667"
- "ADR 0666"
- "ADR 0664"
- "ADR 0656"
- "ADR 0618"
- "ADR 0615"
- "ADR 0614"
- "ADR 0597"
- "ADR 0596"
- "ADR 0595"
- "ADR 0441"
- "ADR 0429"
---
# 47, milestone G: develop's sixth batch
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".
*§587 to §594 answer develop's sixth batch (lead-47's input of 2026-11-11, met in the join and develop after §560 to
§586). Each is of internal form only, within what the records and the lines it cites decide; §588 leaves one question
to the operator, said in it. A line of another file that one of them corrects is corrected in that line (§169, §170,
§171, §177, §226, §404, §462, §513, §568, and the event table of G-4); here only what is new.*
## The ledger's upkeep calls
- §587 **`mesh/ledger.fill` answers the history's fill, and `mesh/ledger.remove` has a request and an answer of its
own.** (§408, §462, §488, §155; ADR 0597 §1, §8, §10, §13) Both calls are in mesh-sdk's `go/buscalls`, as the
constants `LedgerFill` (`mesh/ledger.fill`) and `LedgerRemove` (`mesh/ledger.remove`), under the capability word
`ledger-upkeep-calls` (§488), served by the tool runner for the calling module's own ledgers alone, as every call of
the package is.
- **The fill.** The request is `LedgerRequest`, `{ledger}`, the ledger's local name in `requires`. The answer is
`buscalls.Fill` of the ledger's history alone: its messages, its bytes and the ledger's `cap` in bytes. The
history holds every operation and each instance's snapshot subject (ADR 0597 §1, §8), and the ledger's cap is
its history's (design 25's template row for a ledger, its state and index buckets being states), so neither the
fullest of the parts nor their sum is answered. A full state bucket is said by `apply`'s `state_behind` (ADR 0597
§6), not by this call. The gate's `filling`, `full` and `room` (§181) and `gate_records` (§159) judge this answer
against the 768 MiB of §155.
- **The removal.** The request is `LedgerRemoveRequest`, `{ledger, instance}`. The tool runner removes the
instance's operations and its snapshot from the history (by the instance's subjects), its key in the state bucket
and its keys in every declared index, and answers `LedgerRemoved`, `{instance, operations, bytes}`: the number of
operations removed and the bytes the history held less after the removal. An instance the ledger does not hold
answers `operations` 0 and `bytes` 0, so a removal said twice changes nothing. `Applied` gains no field: a
removal is no operation of the history and has no author. Only the owner's bundle calls it, through its tool
runner (ADR 0597 §13 leaves any other caller to the design, and the design names none); the gate calls it for a
record past its retention (§154).
This amends §462's "as `buscalls.Fill`" and its removal, which named no shape. Why: one cap, the history's, is
the ledger's, and a removal is not an operation (develop questions on §462 and §408, join of the tool runner). How
it is checked: unit (`buscalls`), each request and answer read; unit (tool runner), a fill answers the history's
bytes against the cap with snapshots counted, a removal answers the operations it removed, and a removal of an
unknown instance answers 0; whole (gate), a record past its retention is removed and the next fill is lower.
## The builder's publishes and its reads
- §588 **`builder_publish_again` publishes again every reserved version left unpublished, one module at a time.**
(§52, §369, §381; *Tools are how a module is spoken to*) The builder's tool `builder_publish_again` (class `act`,
its callers and its writing in the hand-act log as they are) takes `module`
and `version`, each optional, and `why`:
- **With both**, it publishes again that reserved version's missing artifacts, as §52 has it.
- **With `module` alone**, it publishes again each reserved version of that module whose artifacts are not all
published: at most one per `MAJOR.MINOR`, since §369 keeps one key per module and `MAJOR.MINOR` and a
superseded build's version is never released.
- **With neither**, it does so for every module whose reserved version the finding `version-unreleased` names
(§369), one module after another, the newest key first.
- **Its bound.** A publish sends the artifacts the build stored, by their digests, to the holder of the registry
seat of their kind, and builds nothing, so it takes no build capacity. An artifact no store holds is not built
by this tool: the tool names it, and its build key is built again by `builder_build_again`. The builder sends one
publish at a time to each registry seat holder, each bounded by §369's 10 minutes. The tool answers at once with
the versions it started, and each outcome is said as `package-published`, or left in `version-unreleased` with
the holder's words.
Why: §369 gave the tool one version, and a recovery of a registry holder away for hours left many (lead-47 in the
registry recovery, issue 1966 note 206). How it is checked: whole (builder, with a fake registry holder), a holder
that refused three modules' publishes, then answers: one call with neither argument publishes the three, one at a
time, and clears their `version-unreleased`; an artifact no store holds is named and not built.
**Left to the operator:** whether the builder also publishes these again by itself, on the node-engine seat's
`running` of a module whose catalog graph entry claims a registry seat (as ADR 0673 §1 to §3 builds a key again on
a build seat holder's `running`), once per event heard. No record decides an automatic publish: ADR 0673 covers
build keys only. It changes what the operator sees (findings that clear themselves) and what the registries keep.
Lead-47 asks it; until it is answered, G's builder publishes again only on this tool.
- §589 **`builder_build` answers a module's build keys whole.** (§348, §568, §575; *one-question-one-tool*) The
builder's tool `builder_build` (class `read`) takes `module` and, optional, `fingerprint`. With `fingerprint`, it
answers that key whole; with `module` alone, the module's build keys newest first, at most 20, each with its
`fingerprint` whole (the build-input fingerprint as the catalog graph entry carries it, never cut), `state`
(`queued`, `building`, `done` or `failed`), the key's revision and since when, the step and its node, the error
whole, `event-builds` and the open ask (§568), and `newest: <branch>` for each watched branch whose newest catalog
graph entry of the module names that fingerprint, read from the builder's own view of the catalog half (§348). A
module none of whose keys the newest entry names says so, naming the entry's fingerprint. Beside it,
`builder_builds_since` gains `module`, which narrows its answer to that module's builds, and `builder_stuck`
answers each key's fingerprint whole. Which node wants which fingerprint is the assigner's to answer, through the
seat `mesh-wants`, never the builder's (ADR 0596); the words of a want's hold (§575) may shorten a fingerprint for
reading, while every field named `fingerprint` in a tool's answer is whole. Why: no read answered a module's
wanted build whole in one call (lead-47, issue 1966). How it is checked: unit (builder), `builder_build` by module
answers its keys with whole fingerprints and marks the one the newest entry names; `builder_builds_since` with
`module` answers that module's builds alone.
## A node's capabilities, said once
- §590 **One event says a node's capabilities: `manifest-reads-changed`.** (§177, §226, §404; ADR 0618 §3, §4, ADR
0673 §2, ADR 0614 §4) The node-engine seat's event `manifest-reads-changed`, on
`mesh.seat.node-engine.event.manifest-reads-changed.<node>`, published only by that node's node-engine (ADR 0363
§2), is the one event of a node's stated capabilities. It carries, as the seat's definition already has it,
`node`, `manifest-reads` (every capability the engine states now, whole), `at`, and `why`: `started` when the
engine started or what it states changed, `returned` when its node is heard again after being away (ADR 0673 §2).
G adds no event `capabilities-changed`: §177, §226, §404 and G-4's event table name `manifest-reads-changed` in
its place.
- **The assigner** consumes it, asks the seat's `manifest-reads` of that node again (ADR 0618 §3, §4), and makes a
new assignment graph revision only when the capabilities answered differ from those its newest revision placed
on, so a `returned` that changes nothing makes no revision.
- **The builder** consumes it as ADR 0618 §4 and §568 have it, and builds a key again only on `returned`.
Why: two events of one fact, one decided (ADR 0618 §4) and one the design's (§226), are a second source of the
same fact, and ADR 0673 §2 builds on the decided one's `why` (lead-47, on ADR 0673). How it is checked: unit
(assigner), a `started` with new capabilities makes a revision and a `returned` with the same ones makes none;
the code review finds no `capabilities-changed` in any module or seat definition at G's heads.
## The bus's object stores
- §591 **Which cap governs which object store.** (§58, §477, §513, §547, §607) The bus module plans:
- **each `<state>-objects`** with 16 MiB, unless the state's `requires` names `objects-max-mib` (§547, which
replaced §607's 64 MiB, which replaced §513's 256 MiB);
- **each `<module>_sent-objects`** with 256 MiB (§477, kept by §607);
- **a foundation part's old `objects` section** with the `max-mib` it declares, `sent-objects` 256 (§477).
No store is planned with 1024 MiB; the bus module's earlier commit that did is changed to these. Every one of
them counts in §547's sum against the account's limit. Why: three lines in sequence named three caps for one
store (develop question NATS1, join of the bus module). How it is checked: unit (bus module's plan), a table of the
three kinds with their caps, and a state naming `objects-max-mib` planned at that size.
## The gate from G's delivery
- §592 **The gate's merge path from G's delivery, whole.** (§97, §150, §151, §156, §162, §164, §166, §167, §169,
§542; ADR 0666 §10, §11, ADR 0596) The gate makes no merge and hands none to the forge:
- **Who merges.** A session merges through the seat `git`'s `merge-pull` (ADR 0666 §11). The gate calls no
`merge-pull`, its manifest `invokes` none, and it says no `owed` act `merge`: `owed`'s acts are the delivery's
view, a comment and the note's line (§167). The merge as an owed act is not built.
- **How the gate learns a merge.** From the indexer's `take-in.taken`, one record per source revision of a
watched branch the indexer takes in, a group's members in one (§151). The gate does not consume the forge
bridge's `merged` and `pushed` messages on its stream `forge` (§509); those are the indexer's. It consumes from
that stream only `owed.ended` (§164), through a durable consumer its manifest's `consumes` declares and its
binding names, so the gate's code names no module: the forge bridge's module name leaves the gate's code.
- **A group.** Its members land one by one (*Groups*), its end the runner's `group-ended` (§431); §166's order of a
group's merges ends at G's delivery.
- **What was owed at the switch.** Each `owed` key the old bridge had not performed becomes an act (§169). Each
`merges` key it had not performed is said once as `approval-carried` (§542) and becomes no act. The gate writes
`merges` no more (§156) and reads it no more, and keeps it until §97's removal (§542).
- **The approval.** No Approve is asked per merge (§150); an `approval` step's answer is the runner's (ADR 0666
§10, §542).
This replaces the merge parts of §169 and §171, and §170 from G's delivery. Why: the join kept the old hand-off
(`merges`, the bridge's messages, the bridge named in code) beside the owed acts, and the lines were spread over
four places (join of the gate). How it is checked: unit (gate's manifest), no `invokes` of `merge-pull` and no
`consumes` of `merged` or `pushed`; the code review finds no module name of the forge bridge in the gate's code
and no act `merge`; whole (gate, bridge), a merge made through `merge-pull` opens one record from `take-in.taken`,
and a `merges` key at the switch is said `approval-carried` and performed by nobody.
- §593 **The gate hears neither the teller's answers nor the view's reach.** (§150, §431, §512) The gate's reads of
the teller's `answered` and the status view's `reached`, and its calls of `teller_answers` and `view_reach`, served
the Approve per merge, which goes at G's delivery (§150, §431): the gate's `asks` go with it. So the gate's
manifest declares neither event in `consumes` nor either tool in `invokes`, and its code calls neither; the commit
that added those calls is undone. `view_reach` stays the status view's own read tool, answered from the catalog
half (§196, test 61). Why: §431's "by their events" named the readers that stay, and the gate is not one of them
(join of the gate). How it is checked: unit (gate's manifest), neither event nor tool named.
## Readers of a module's manifest
- §594 **The readers take a module's manifest from its catalog graph entry.** (§196, §421, §443, §445; ADR 0656 §6,
ADR 0615 §1) The holders of `mesh-config`, `mesh-provisioner` and `mesh-self-check`, and the claude-code module,
read a module's manifest from the catalog graph entry that carries it whole (§443), taken through
`meshcatalogclient`'s view of the catalog half, which follows each watched branch's newest `catalog-revision` and
asks `revision` again on a gap (§196). None reads a manifest by digest from the indexer, its state `manifests` or
its tools: `manifests` is kept only for node-engines from before G (§445). Why: test 61's "no call of the indexer
by name" holds for every reader of which modules exist, and the entry carries the manifest (join of these readers,
RDR1 to RDR4). How it is checked: test 61, a row for each of the four readers; the code review finds no read of
`manifests` in them.
@@ -194,12 +194,12 @@ checker's `mesh/check` from a watch of the checker's state `owed`: reads of anot
consumer's backlog: the last event applied, the events waiting, the age of the oldest), `bridge_owed_again`
(perform one id again now) and `bridge_owed_drop` (drop one id with its reason, written in the hand-act log of the
seat `mesh-hand-acts`, and said as `owed.ended` with the outcome `dropped`).
- §169 **The switch carries what is owed.** (§510) At the new gate's start (*The switch carries today's state in, once*) every key
of `owed` and `merges` the old bridge has not performed becomes an act of its record, with an id made of the key and
- §169 **The switch carries what is owed.** (§542, §592) At the new gate's start (*The switch carries today's state in, once*) every key
of `owed` the old bridge has not performed becomes an act of its record, with an id made of the key and
its revision; the new bridge counts as performed every id whose key and revision the old bridge's own bookkeeping
names, so nothing is done twice and nothing dropped. A merge handed to the forge during the switch is such an act:
its merged message finds the record holding it, so it opens no `forge-made` record.
- §170 **A merge made at the forge has a record too.** A merge the forge reports for which no record holds a `merge-pull`
names, so nothing is done twice and nothing dropped. A key of `merges` becomes no act: §542 says it as
`approval-carried`, and §592 has the whole merge path from G's delivery.
- §170 **A merge made at the forge has a record too, until G's delivery** (from it, §151 and §592). A merge the forge reports for which no record holds a `merge-pull`
of that pull request at that head (a person merged it in the forge's own page, as on 2026-11-07 and 11-09) is taken
in like any other merge (*Taken in by the indexer it names*), and the gate opens a delivery record for it, marked
`forge-made`, with no Approve, so its trace and its outcomes on the nodes are kept like every delivery's and no
@@ -211,11 +211,8 @@ checker's `mesh/check` from a watch of the checker's state `owed`: reads of anot
restart and the forge holds it once (the comment and the note by their id); an act said twice is performed once; an
undecodable act is said `undecodable`; `bridge_owed`, `bridge_owed_again` and `bridge_owed_drop` answer, the drop
writing the hand-act log; its account cannot read the gate's or the checker's state. In the gate's: an act left
unanswered is said again at the gate's start under its id and listed by `stalled` after 15 minutes; a group's second
`merge-pull` is said only after the first member's merged message; the switch with a merge handed and not yet
merged makes no `forge-made` record; a merged message with no record's merge opens a `forge-made` record, said as
`transition` with why `forge-made`, and a later merge in the same repository is taken in behind it. Acceptance
tests 53 and 51.
unanswered is said again at the gate's start under its id and listed by `stalled` after 15 minutes; the merge path
of G's gate is checked as §592 says. Acceptance tests 53 and 51.
## The state table, from milestone G's delivery
@@ -271,8 +268,8 @@ Findings 11). How each is kept, read and retained is this design's choice under
- §177 **A revision is made by a merge, and also with no merge.** The indexer makes a catalog graph revision when it
takes a source revision in. The assigner makes an assignment graph revision on each new catalog graph revision, on
the seat `mesh-module-assigner`'s event `assignments-changed` (ADR 0567 §5, ADR 0641), and on the node-engine seat's event
`capabilities-changed`, which a node-engine says when the capabilities it states in its node record change
(ADR 0614 §4), so the assigner follows an event and never reads a node record across the seam (ADR 0596). A
`manifest-reads-changed`, which a node-engine says when the capabilities it states change and when its node returns
(ADR 0614 §4, ADR 0618 §3, §4; §590), so the assigner follows an event and never reads a node record across the seam (ADR 0596). A
placement change is traced like a merge. At its first start with no revision kept, the indexer takes in the head the
gate's source names for every repository by its catch-up path and keeps that as revision 1, and its verb `revision`
answers that it waits until then (lead-47's ruling in G's prepare: a first start has no merge to make a revision).
@@ -223,7 +223,7 @@ One file of milestone G's part of [design 47](../47-delivery-from-commit-to-deli
| §223 The verbs `revision`, `entry` and `difference` on the two seats | each half of the view, and the difference, is served by its one owner through its seat, never read from its state |
| §224 The node-engine reads its want and the catalog half, never the assignment half | the want is the one record a node reads; the assignment half would have each node read every node's placements |
| §225 Composing waits per node, held by the assigner, with no new field in the want: a node's node-engine want first, its other wants once its new node-engine runs | a node away holds only itself (ADR 0603 §7); an old node-engine reads its want as it is, so it is reached with no form it cannot read |
| §226 Capability changes said as the node-engine seat's event `capabilities-changed` | the assigner follows an event instead of reading node records across the seam (ADR 0596) |
| §226 Capability changes said as the node-engine seat's event `manifest-reads-changed` (ADR 0618 §4; §590) | the assigner follows an event instead of reading node records across the seam (ADR 0596) |
| §227 The step events, their fields and their subjects, with the node in the subject of every event a node publishes | every outcome reaches the delivery record as the event of the part that did it (research 085, Findings 7), and a node's account can be granted only its own node's subjects (ADR 0363 §2) |
| §228 A first tier of only the changed acting parts, bounded at 20 minutes, its verdict telling `waiting for a build node` from `did not build` | an ordinary change pays nothing more; a bound turns a build that never ends into a named failure, and the two words tell the operator which act frees it |
| §229 The build seat's ask `run`, published only by the checker's account, its step keys starting with the asker's name | the program is a long job pulled where capacity is, run in the sandbox every check already uses (ADR 0448 §2), and no other part can have a program run or read its verdict |
@@ -284,7 +284,7 @@ say another runs a build (ADR 0363 §2); the gate's events are granted to the ga
| an entry checked | `checked` | `mesh-delivery-checker`, the checker | `mesh.seat.mesh-delivery-checker.event.checked` | the seat's definition in `mesh-delivery-contracts` |
| an entry wanted | `wanted` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.wanted` | the seat's definition in `mesh-delivery-contracts` (ADR 0641 §2) |
| an entry composed, and running healthy | `composed`, `running` | `node-engine`, the node-engine on each node | `mesh.seat.node-engine.event.composed.<node>`, `.running.<node>.<module>`, the latter on a stream kept last per subject with no age limit | the seat's definition in `mesh-contracts` |
| a node's capabilities changed | `capabilities-changed` | `node-engine`, the node-engine on that node | `mesh.seat.node-engine.event.capabilities-changed.<node>` | the same |
| a node's capabilities changed, or its node returned | `manifest-reads-changed` (ADR 0618 §4; §590) | `node-engine`, the node-engine on that node | `mesh.seat.node-engine.event.manifest-reads-changed.<node>` | the same |
| a wait held, and ended | `wait-held` (step, acting part, its version, the entry, since when, its bound), `wait-ended` (the same, and how: ran, released) | each holder: `mesh-wants` for the assigner (placing, wanting and composing), `mesh-grants` for the grants part, the builder's own stream | `mesh.seat.<seat>.event.wait-held`, `.wait-ended`; `mesh.stream.mesh-delivery-builder.event.wait-held`, `.wait-ended` | each seat's definition; the builder's manifest |
| a store filling, full, and back below its cap | `filling`, `full`, `room` | `mesh-catalog`, `mesh-wants`, `mesh-delivery` | `mesh.seat.<seat>.event.filling`, `.full`, `.room` | each seat's definition |
| a record pins or frees a revision; a candidate's heads replaced; a record ended | `pinned`, `freed`, `heads-replaced`, `record-ended` | `mesh-delivery`, the gate | `mesh.seat.mesh-delivery.event.<event>` | the seat's definition in `mesh-delivery-contracts` |
@@ -336,7 +336,7 @@ two records pin stays until both free it; one neither pinned nor current is remo
was stopped is applied after its restart; a candidate's graphs are dropped on `heads-replaced`; a store past 80 % says
`filling` and raises `store-filling`, and a full one says `full` and refuses its next revision naming itself; for a
candidate's heads both `revision` verbs answer, the assigner's half named by its own revision and naming its inputs; a
placement change with no merge, and a `capabilities-changed`, each give a new assignment half on the same catalog half,
placement change with no merge, and a `manifest-reads-changed` that changes what a node states (§590), each give a new assignment half on the same catalog half,
whose difference moves only the module concerned, and a part takes that pair as its view; after its first view a part
acts on a seat event without asking a verb again; a running part does not act on a candidate's view; a pull request
that adds a seat and a module using it is validated by the indexer's candidate pass and checked by the checker with
@@ -108,8 +108,7 @@ line says so.*
(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.** (§520) `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
- §404 **The node-engine's events' bodies.** (§520) `manifest-reads-changed` carries what §590 says; `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, its input being §459's. 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.
+3 -1
View File
@@ -6,6 +6,7 @@ milestone: G
updated: 2026-11-11
decisions:
- "ADR 0500"
- "ADR 0673"
- "ADR 0672"
- "ADR 0436"
- "ADR 0670"
@@ -81,7 +82,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 fifteen files, each read whole, its design lines numbered across them:
The part is sixteen 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.
@@ -98,3 +99,4 @@ The part is fifteen files, each read whole, its design lines numbered across the
- [G-13-review-round-3](G-13-review-round-3.md): the review of §480 to §515, rounds 2 and 3 (§600 on).
- [G-14-recovery-module-and-review](G-14-recovery-module-and-review.md): the recovery module, the operator's answer of 2026-11-11 12:55 CET, and the review of §516 to §553 (§554 to §559).
- [G-15-develop-answers-fifth](G-15-develop-answers-fifth.md): develop's fifth batch, round 3's notes on §516 to §559, the knowledge base's review of the recovery module's record, and the operator's answers of 2026-11-11 about 14:05, 14:15 and 14:30 CET (§560 to §586).
- [G-16-develop-answers-sixth](G-16-develop-answers-sixth.md): develop's sixth batch: the ledger's upkeep calls, the builder's publishes again and its read of a module's builds, one event of a node's capabilities, the object stores' caps, the gate's merge path from G's delivery, and the readers of a module's manifest (§587 to §594).