Take in round 2 of design 47's G review: running kept per subject, the merge waits on the Approve alone, ADR 0661 named

Round 2 found the pass's running events could age out of a new consumer's reach, the merge bullet still
holding for a carry, the checker's own owed acts unanswered, findings that never cleared, and
kept-artifact open to any module and caller. Each is now written as the lead ruled, with its test row.

Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
This commit is contained in:
2026-11-09 13:14:19 +01:00
parent 86c908b229
commit 2d8947fa04
@@ -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, 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, hq 00-META/checks]
updated: 2026-11-09 updated: 2026-11-09
decisions: decisions:
- "ADR 0661"
- "ADR 0660" - "ADR 0660"
- "ADR 0659" - "ADR 0659"
- "ADR 0656" - "ADR 0656"
@@ -542,7 +543,9 @@ checker's `mesh/check` from a watch of the checker's state `owed`: reads of anot
performed` (the forge did not answer within the call's bound, with the error) or `undecodable` (an act it cannot performed` (the forge did not answer within the call's bound, with the error) or `undecodable` (an act it cannot
read, with why): an act it cannot decode is said, never only logged. The gate hears the stream `forge` through its read, with why): an act it cannot decode is said, never only logged. The gate hears the stream `forge` through its
durable consumer, writes the outcome into the delivery record, and says an act's id is answered only once an durable consumer, writes the outcome into the delivery record, and says an act's id is answered only once an
outcome is recorded. outcome is recorded. The checker does the same for its own acts: it hears `owed.ended` for its own ids, records each
outcome in its own state (it watches only its own state), says again at its start, under the same id, every act of
its own still unanswered, and lists one unanswered past 15 minutes in its own stalled read.
- **What is unanswered is said again, and stalls by a bound.** At its start the gate says again, under the same id, - **What is unanswered is said again, and stalls by a bound.** At its start the gate says again, under the same id,
every act its records hold unanswered. An act unanswered 15 minutes after it was said is listed by `stalled`, which every act its records hold unanswered. An act unanswered 15 minutes after it was said is listed by `stalled`, which
the condition keeper raises as the stalled line (ADR 0421 §7, ADR 0564 §2): fifteen minutes is many times a the condition keeper raises as the stalled line (ADR 0421 §7, ADR 0564 §2): fifteen minutes is many times a
@@ -778,8 +781,11 @@ Findings 11). How each is kept, read and retained is this design's choice under
- **Who holds a seat is applied by one rule, from what each node runs.** The node-engine and the grants part decide a - **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 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 (ADR 0660 §2). What each node runs is heard, never asked: each part keeps it from the node-engine seat's events
`running.<node>` (*What each step says*), through a durable consumer of its own declared in its `consumes`, so a `running.<node>.<module>` (*What each step says*), through a durable consumer of its own declared in its `consumes`,
pass is decided with no call to a node that may be away. The event carries the module, the fingerprint and the 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,
and each part's durable consumer starts from the last message per subject, never from now: a consumer made after a
node's last `running`, and two parts' consumers made at different times, hold the same builds. The event carries the module, the fingerprint and the
digest of the build's manifest, which is the indexer's manifest of that build (ADR 0660 §2's "the indexer's 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 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 digest it would give. A node that has said no `running` for a module since the part's consumer began counts by
@@ -944,7 +950,7 @@ say another runs a build (ADR 0363 §2); the gate's events are granted to the ga
| an entry built | `build.ended` | the builder's own | `mesh.stream.mesh-delivery-builder.event.build.ended` | the builder's manifest | | an entry built | `build.ended` | the builder's own | `mesh.stream.mesh-delivery-builder.event.build.ended` | the builder's manifest |
| an entry checked | `checked` | `mesh-delivery-checker`, the checker | `mesh.seat.mesh-delivery-checker.event.checked` | the seat's definition in `mesh-delivery-contracts` | | an entry 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 wanted | `wanted` | `mesh-wants`, the assigner | `mesh.seat.mesh-wants.event.wanted` | the seat's definition in `mesh-delivery-contracts` (ADR 0641 §2) |
| an entry composed, and running healthy | `composed`, `running` | `node-engine`, the node-engine on each node | `mesh.seat.node-engine.event.composed.<node>`, `.running.<node>` | the seat's definition in `mesh-contracts` | | 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 | `capabilities-changed` | `node-engine`, the node-engine on that node | `mesh.seat.node-engine.event.capabilities-changed.<node>` | the same |
| a wait held, and ended | `wait-held` (step, acting part, its version, the entry, since when, its bound), `wait-ended` (the same, and how: ran, released) | each holder: `mesh-wants` for the assigner (placing, wanting and composing), `mesh-grants` for the grants part, the builder's own stream | `mesh.seat.<seat>.event.wait-held`, `.wait-ended`; `mesh.stream.mesh-delivery-builder.event.wait-held`, `.wait-ended` | each seat's definition; the builder's manifest | | 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 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 |
@@ -1064,7 +1070,7 @@ names go, since every new acting part needed code changes elsewhere (research 08
event says. event says.
- **Composing waits per node, by the assigner.** A node's wants wait only for that node's own node-engine, never for - **Composing waits per node, by the assigner.** A node's wants wait only for that node's own node-engine, never for
another node's, so a node away holds only itself (ADR 0603 §7). The want gains no field: the assigner, which writes another node's, so a node away holds only itself (ADR 0603 §7). The want gains no field: the assigner, which writes
the wants, holds a node's other wants until the node-engine seat's `running.<node>` says the new node-engine version the wants, holds a node's other wants until the node-engine seat's `running.<node>.<module>` says the new node-engine version
runs on that node, and writes that node-engine's own want first. A node-engine of before milestone G thus gets its runs on that node, and writes that node-engine's own want first. A node-engine of before milestone G thus gets its
own want first and every other want once it runs the new one, so an old node-engine never composes a module it own want first and every other want once it runs the new one, so an old node-engine never composes a module it
cannot read. The clock of that node's bound starts when the node is present and its node-engine's want is written, cannot read. The clock of that node's bound starts when the node is present and its node-engine's want is written,
@@ -1087,16 +1093,27 @@ names go, since every new acting part needed code changes elsewhere (research 08
never waited for: the running build module builds the shared contracts and the registry holder, then the new build never waited for: the running build module builds the shared contracts and the registry holder, then the new build
module builds the rest, so ADR 0614 §6's cycle through them stays allowed, now for that reason. module builds the rest, so ADR 0614 §6's cycle through them stays allowed, now for that reason.
- **The artifact store's holder takes its own new build even when its seat is the one broken.** A build module - **The artifact store's holder takes its own new build even when its seat is the one broken.** A build module
stores what it builds through the seat `oci-artifact-registry` (or `container-image-registry` for an image), so the stores the artifacts it builds through the seat `oci-artifact-registry`, so the
holder of that seat is in its own build's path: its new build needs the store it replaces. As every holder's own holder of that seat is in its own build's path: its new build needs the store it replaces. As every holder's own
inputs are (above), that store is acted on by the running holder: the running holder stores its new build, and only inputs are (above), that store is acted on by the running holder: the running holder stores its new build, and only
then is the new one wanted. When the running holder is what is broken (the seat refuses or does not answer a store, then is the new one wanted. When the running holder is what is broken (the seat refuses or does not answer a store,
as in the hand bootstrap of 2026-11-07 to 11-09), the build module keeps that one build on its own node among its as in the hand bootstrap of 2026-11-07 to 11-09), the build module keeps that one build on its own node among its
kept builds (*The bootstrap delivery*: `build_go_kept`), says in its step key that it is kept on that node, and the kept builds (*The bootstrap delivery*: `build_go_kept`), says in its step key that it is kept on that node, and the
builder's done key names it so; the node-engine composing the holder fetches it by its digest through the build builder's done key names it so with its digest; the node-engine composing the holder fetches it through the build
seat's verb `kept-artifact` of that node, and the new holder, once it runs, takes the store of every build after seat's verb `kept-artifact` of that node, and the new holder, once it runs, takes the store of every build after it.
it. This is the one artifact the mesh delivers from a build node instead of the store, and only for a holder of a - The verb sits in the build seats' definitions (`node-build-go`, `node-build-node`, `node-build-image`, in
store seat; the design's choice under ADR 0656 §3 (a wait skips what the holder's own new version needs) and ADR `mesh-delivery-contracts`), and its callers are the node-engines alone: the definition names them, and the grants
part grants it to no other account.
- It answers only for a module that claims the seat `oci-artifact-registry`, and refuses every other, naming the
module, so a store outage never turns into delivering from build nodes.
- The bytes go as an object by digest on the bus (the old `objects` form, ADR 0619 §2), never in a value, since an
artifact is over the bus's value limit; the node-engine checks the bytes it fetched against the digest in the
builder's done key and applies nothing that differs.
- While the keeping node is away, or its sweep removed the build, the want waits, and the node-engine says in its
have that it waits for that node or for a build no longer kept.
This is the one artifact the mesh delivers from a build node instead of the store, and only for the holder of
`oci-artifact-registry`; the design's choice under ADR 0656 §3 (a wait skips what the holder's own new version needs) and ADR
0526 §2, whose build by a session's call it makes a step of the delivery instead of a hand act. How it is checked: 0526 §2, whose build by a session's call it makes a step of the delivery instead of a hand act. How it is checked:
test 60. test 60.
- **The check refuses a cycle among the waits within one step** (ADR 0656, which changes ADR 0603 §2's refusal of a - **The check refuses a cycle among the waits within one step** (ADR 0656, which changes ADR 0603 §2's refusal of a
@@ -1191,12 +1208,13 @@ commit on the SDK's trunk or the head of an SDK pull request the forge holds, op
again when the nodes change, which judges heads no check judged. From research 085's milestone its verdict says again when the nodes change, which judges heads no check judged. From research 085's milestone its verdict says
`could not run`, naming the part not heard, and the check releases its claim on the verdict key, so the heads can `could not run`, naming the part not heard, and the check releases its claim on the verdict key, so the heads can
be judged again. The part's return is the one event that can change the outcome: the node-engine seat's be judged again. The part's return is the one event that can change the outcome: the node-engine seat's
`running.<node>` naming that part (a node waking, the forge module or a build module starting again alike), on which `running.<node>.<module>` naming that part (a node waking, the forge module or a build module starting again alike), on which
the check is asked again, once per set of heads and per part returning, never on a timer; a `running` of the same the check is asked again, once per set of heads and per part returning, never on a timer; a `running` of the same
part at the same fingerprint after that asks nothing. A `could not run` verdict not asked again within 60 minutes part at the same fingerprint after that asks nothing. A `could not run` verdict not asked again within 60 minutes
becomes the checker's finding `check-could-not-run`, naming the heads and the part, which the condition keeper becomes the checker's finding `check-could-not-run`, naming the heads and the part, which the condition keeper
raises (ADR 0564 §2): an hour is the check's own bound. A second check of the same heads asked while one runs, or raises (ADR 0564 §2): an hour is the check's own bound. The finding clears when the heads are checked again or
one erred, claims nothing and writes no status, by the claim above (issue 1373; ADR 0548 §1, ADR 0656 §5). How it replaced, or their pull request closes. A second check of the same heads asked while one runs, or after one that
erred without releasing its claim, claims nothing and writes no status, by the claim above (issue 1373; ADR 0548 §1, ADR 0656 §5). How it
is checked: test 58. is checked: test 58.
- **A failed build node loses nothing.** An ask a build module took and never acknowledged goes to another node by the - **A failed build node loses nothing.** An ask a build module took and never acknowledged goes to another node by the
stream's own acknowledgement wait, with no timer of a part; a step's end is written on the build module's step key named stream's own acknowledgement wait, with no timer of a part; a step's end is written on the build module's step key named
@@ -1259,8 +1277,8 @@ the check gates merges.*
### Nothing merges into a repository under check ### Nothing merges into a repository under check
*ADR 0548 §2 to §4, §9, §10, as ADR 0551 bounds them; from research 085's milestone removed, by the operator's word, *ADR 0548 §2 to §4, §9, §10, as ADR 0551 bounds them; from research 085's milestone removed by ADR 0661 (proposed,
its record still to be written (below).* needs the operator's Approve; below).*
**Removed at research 085's milestone.** The hold, the merge turns, their stalled line, the gate's tools for them and **Removed at research 085's milestone.** The hold, the merge turns, their stalled line, the gate's tools for them and
the setting `check-gates-merge` go in milestone G, the gate's and the forge module's alike (the operator, on Telegram, the setting `check-gates-merge` go in milestone G, the gate's and the forge module's alike (the operator, on Telegram,
@@ -1269,9 +1287,9 @@ operator's word for G is that no check gates delivery (1921's note of 2026-11-07
is handed to the forge bridge at once; a check running on a repository the merge goes into ends on the commit it read, is handed to the forge bridge at once; a check running on a repository the merge goes into ends on the commit it read,
and its verdict is carried (*A move of the trunk carries every verdict*); the checker reads nothing of the gate, and and its verdict is carried (*A move of the trunk carries every verdict*); the checker reads nothing of the gate, and
the gate no longer watches the checker's verdicts for a hold. **Its record is to be accepted before the push:** ADR the gate no longer watches the checker's verdicts for a hold. **Its record is to be accepted before the push:** ADR
0548 §2 to §4, §9 and §10, ADR 0551 and ADR 0534 §4's judgement of `mesh/check` by the merge are in force, and the 0548 §2 to §4, §9 and §10, ADR 0551 and ADR 0534 §4's judgement of `mesh/check` by the merge are in force, and ADR
record that ends the first two and changes the third (needs the operator's Approve) is to be accepted before milestone 0661, which ends the first two and changes the third (proposed, needs the operator's Approve), is to be accepted before
G's pull requests are pushed; until it is accepted, the rule below holds as those records have it. How it is checked: in the gate's whole-module test an approved merge into a milestone G's pull requests are pushed; until it is accepted, the rule below holds as those records have it. How it is checked: in the gate's whole-module test an approved merge into a
repository under a running check is handed at once, and the gate's manifest declares no `turns` and no setting repository under a running check is handed at once, and the gate's manifest declares no `turns` and no setting
`check-gates-merge`; in the checker's, a check claims at once with no gate state granted to read. `check-gates-merge`; in the checker's, a check claims at once with no gate state granted to read.
@@ -1575,11 +1593,13 @@ pull request, and it owes the forge nothing.
- **The merge.** mesh-delivery merges through the forge's merge tool at the heads the Approve names, only while - **The merge.** mesh-delivery merges through the forge's merge tool at the heads the Approve names, only while
they are still the heads, their check passed against the trunk's head, and, while the check gates merges, no they are still the heads, their check passed against the trunk's head, and, while the check gates merges, no
check of other heads runs on a repository the merge goes into (*Nothing merges into a repository under check*, check of other heads runs on a repository the merge goes into (*Nothing merges into a repository under check*,
above, which milestone G removes). From milestone G the forge bridge merges through the seat `git`'s verb above, which milestone G removes). Until milestone G, when the trunk moved, the merge waits for the carried
`merge-pull`, which judges the Approve's heads and no check (*The seat `git`*, under *The verbs*). When the trunk moved, the merge waits for the carried verdict, and the event of its line asks the merge verdict, and the event of its line asks the merge again; no timer asks it, no person rechecks, and the Approve is
again; no timer asks it, no person rechecks, and the Approve is not asked again (ADR 0421 §3, §12, as ADR 0548 not asked again (ADR 0421 §3, §12, as ADR 0548 §8 changes them); and the merge tool refuses a verdict naming a trunk
§8 changes them). The merge tool still refuses a verdict naming a trunk commit other than the trunk's head and commit other than the trunk's head and asks nothing (ADR 0534 §4), the carry making the verdict current. From
asks nothing (ADR 0534 §4); the carry makes the verdict current. milestone G the merge waits on nothing but the Approve's heads and a trunk that takes no push: the forge bridge
merges through the seat `git`'s verb `merge-pull`, which judges those two and no check, and a trunk move holds no
merge for its carry (ADR 0661, to be accepted before the push; *The seat `git`*, under *The verbs*).
- **A push or a Decline ends the Approve.** A new head ends its ask or its Approve, for a group every member's, and - **A push or a Decline ends the Approve.** A new head ends its ask or its Approve, for a group every member's, and
is said once on the pull request; the new head is asked again once its checks pass. A Decline merges nothing and is said once on the pull request; the new head is asked again once its checks pass. A Decline merges nothing and
is said once (ADR 0421 §6). is said once (ADR 0421 §6).
@@ -1962,8 +1982,8 @@ later change of a kept data's form, not as a case of this milestone.
module of the node; it never refuses the whole pass for one module's claim (ADR 0636 §3: a refused definition blocks module of the node; it never refuses the whole pass for one module's claim (ADR 0636 §3: a refused definition blocks
new claims of that seat only). Met on 2026-11-08, when one claim problem refused a node's every module (issue 1966). new claims of that seat only). Met on 2026-11-08, when one claim problem refused a node's every module (issue 1966).
A module held so is no silent leave-out: the node-engine writes the finding `module-held` naming the node, the A module held so is no silent leave-out: the node-engine writes the finding `module-held` naming the node, the
module and why, and the condition keeper keeps the condition (ADR 0564 §2) until the module is composed again, when module and why, and the condition keeper keeps the condition (ADR 0564 §2) until the module is composed again or is
the node-engine clears the finding. How it is checked: test 55. no longer wanted on that node, when the node-engine clears the finding. How it is checked: test 55.
- **The order a node takes to composing its own.** One delivery group carries every part: the seat `mesh-module-assigner` - **The order a node takes to composing its own.** One delivery group carries every part: the seat `mesh-module-assigner`
on the assigner, the controller's verb `placement-export` (as it is) and the controller's pin only, the node-engine on the assigner, the controller's verb `placement-export` (as it is) and the controller's pin only, the node-engine
(its record and its own composer), the vault's `own`, the grants part's reads, and mesh-config's reading of (its record and its own composer), the vault's `own`, the grants part's reads, and mesh-config's reading of
@@ -2196,7 +2216,7 @@ From research 085's milestone the seat gains:
of the revision view, ADR 0656), and `entry` and `difference` on `mesh-wants` (ADR 0656), with the events of *What of the revision view, ADR 0656), and `entry` and `difference` on `mesh-wants` (ADR 0656), with the events of *What
each step says*. each step says*.
**The seat `node-engine`**'s event `running.<node>` carries, from research 085's milestone, the module, its **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 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 it (ADR 0660 §2; *Who holds a seat is applied by one rule*). No verb is added.
@@ -2257,14 +2277,15 @@ Each is said on `mesh.seat.git.event.<event>`, declared in the seat's definition
still calls the retired acting tools, the old bridge's acts fail loudly and stay unperformed in the old gate's keys, still calls the retired acting tools, the old bridge's acts fail loudly and stay unperformed in the old gate's keys,
and the switch carries them (*What the gate owes the forge*). A revert goes back in the other order: the gate, then and the switch carries them (*What the gate owes the forge*). A revert goes back in the other order: the gate, then
the bridge, then the forge, each wanted only once the one after it in the forward order runs its reverted build, so the bridge, then the forge, each wanted only once the one after it in the forward order runs its reverted build, so
no part calls a verb nobody serves. no part calls a verb nobody serves. ADR 0656 §3 stands beside it: the acting parts' new versions act first in their
own steps. Two things cover the gap while the forge is still on its old build and serves no verb of the seat: the
indexer starts on its kept definitions (below), and a check whose read through the seat `git` fails says `could not
run`, naming the forge, and is asked again on the forge module's `running` (*A check runs to its end*).
- **A part that cannot read the forge keeps what it has, and says so.** The indexer, at its start, waits for the - **A part that cannot read the forge keeps what it has, and says so.** The indexer, at its start, waits for the
seat `git` at most 2 minutes; with no answer it judges from the last definitions it kept, says in its seat `git` at most 2 minutes; with no answer it judges from the last definitions it kept, says in its
`<module>_first_views` that it waits for `git` and since when, writes `view-waits` after five minutes, and reads the `<module>_first_views` that it waits for `git` and since when, writes `view-waits` after five minutes, and reads the
definitions once the seat answers. Two minutes is longer than a forge's restart, and short enough that a start is definitions once the seat answers; it then judges again every manifest it judged from kept definitions. Two minutes is longer than a forge's restart, and short enough that a start is
not held behind a forge down for good. How it is checked: in the indexer's whole-module test with a fixture forge on not held behind a forge down for good. How it is checked: test 54.
its old build, which serves no verb of the seat, the indexer starts, judges from its kept definitions, and raises
`view-waits` after five minutes.
- **How it is checked.** The seat definition's conformance fixtures hold one answer and one error of each verb and one - **How it is checked.** The seat definition's conformance fixtures hold one answer and one error of each verb and one
of each event, and the forge module's tool tests answer each fixture; the forge bridge's, the checker's, the of each event, and the forge module's tool tests answer each fixture; the forge bridge's, the checker's, the
indexer's and the gate's unit fakes answer from the same fixtures; a call of an act verb from an account other than indexer's and the gate's unit fakes answer from the same fixtures; a call of an act verb from an account other than
@@ -2570,9 +2591,10 @@ What milestone G's prepare found, and its test:
grants composed from the holder's `callers` give the act verbs to the forge bridge's account alone, a call of one grants composed from the holder's `callers` give the act verbs to the forge bridge's account alone, a call of one
from another account is refused, and the forge module serves none of its retired acting tools (whole, forge bridge, from another account is refused, and the forge module serves none of its retired acting tools (whole, forge bridge,
grants part; live, the grants read with `grants_bindings`). grants part; live, the grants read with `grants_bindings`).
52. **Nothing holds an approved merge for another check.** Once the record that ends ADR 0551 and ADR 0548 §2 to §4, 52. **Nothing holds an approved merge for another check.** Once ADR 0661 (proposed, needs the operator's Approve; to
§9, §10 and changes ADR 0534 §4 is accepted (to be accepted before the push): an approved merge into a repository be accepted before the push), which ends ADR 0551 and ADR 0548 §2 to §4, §9, §10 and changes ADR 0534 §4, is
under a running check is handed at once and merged whatever that check says; neither the gate nor the forge module accepted: an approved merge into a repository under a running check is handed at once and merged whatever that
check says; a merge after a trunk move is not held for the carry; neither the gate nor the forge module
declares `check-gates-merge`, the gate declares no `turns`, and the checker is granted no read of the gate's state declares `check-gates-merge`, the gate declares no `turns`, and the checker is granted no read of the gate's state
(whole, gate, checker and forge module). (whole, gate, checker and forge module).
53. **What is owed is said, answered and kept.** An `owed` said while the forge bridge is stopped is performed once after 53. **What is owed is said, answered and kept.** An `owed` said while the forge bridge is stopped is performed once after
@@ -2580,35 +2602,44 @@ What milestone G's prepare found, and its test:
undecodable act is said `undecodable`; an act unanswered 15 minutes is listed by `stalled`; the switch with a merge undecodable act is said `undecodable`; an act unanswered 15 minutes is listed by `stalled`; the switch with a merge
handed and not yet merged opens no `forge-made` record; a merge made at the forge opens one, said as `transition` handed and not yet merged opens no `forge-made` record; a merge made at the forge opens one, said as `transition`
with why `forge-made`, and a later merge in its repository follows it; the checker's `mesh/check` is performed by with why `forge-made`, and a later merge in its repository follows it; the checker's `mesh/check` is performed by
the bridge from the checker's `owed` (whole, gate and forge bridge). the bridge from the checker's `owed`, and a checker status the forge refuses is recorded in the checker's own
state and listed in its stalled read (whole, gate, checker and forge bridge).
54. **One reader of the seat list per part, and one view machinery.** Every part that reads the seat list has the two 54. **One reader of the seat list per part, and one view machinery.** Every part that reads the seat list has the two
tools of ADR 0636 §7 from the runtime and no wiring of its own; every part that takes a first view answers its tools of ADR 0636 §7 from the runtime and no wiring of its own; every part that takes a first view answers its
held and awaited revision in `<module>_first_views`; the indexer with the forge on its old build, serving no verb of held and awaited revision in `<module>_first_views`. With the forge on its old build, serving no verb of the seat
the seat `git`, starts within 2 minutes on its kept definitions and raises `view-waits` after five (unit, mesh-sdk; `git`: the indexer starts within 2 minutes on its kept definitions, raises `view-waits` after five, and once the
whole, indexer; live search). seat answers judges again every manifest it judged from kept definitions; a check whose read through the seat
fails says `could not run` naming the forge, and is asked again on the forge module's `running` (unit, mesh-sdk;
whole, indexer and checker; live search).
55. **A claim problem holds one module, and says so.** A node with one module whose claim is refused applies the 55. **A claim problem holds one module, and says so.** A node with one module whose claim is refused applies the
others; that module's have names why, and `mesh-conditions.conditions` reads its `module-held` condition until the others; that module's have names why, and `mesh-conditions.conditions` reads its `module-held` condition until the
module is composed again, when it clears (whole, node-engine and condition keeper). module is composed again or no longer wanted on that node, when it clears (whole, node-engine and condition
keeper).
56. **One rule picks a seat's holder, also with a node away** (ADR 0660 §1 to §3). With one node away whose last 56. **One rule picks a seat's holder, also with a node away** (ADR 0660 §1 to §3). With one node away whose last
`running` named a build that no longer claims the seat, and one node that has said nothing since the parts' `running` named a build that no longer claims the seat, and one node that has said nothing since the parts'
consumers began, the node-engine and the grants part each pick the same holder, the silent node counted by the consumers began, the node-engine and the grants part each pick the same holder, the silent node counted by the
trunk's manifest; neither reads another node's have key, and neither calls a node (whole, node-engine and grants trunk's manifest; a consumer made after a node's last `running`, and the two parts' consumers made at different
part). times, still apply that build's manifest and pick the same holder; neither reads another node's have key, and
neither calls a node (whole, node-engine and grants part).
57. **The indexer reads every definition at its start.** Started with a definition on a contracts trunk that no event 57. **The indexer reads every definition at its start.** Started with a definition on a contracts trunk that no event
announced, the indexer judges the first manifest claiming that seat with it, and answers it in announced, the indexer judges the first manifest claiming that seat with it, and answers it in
`seat-definitions` (whole, indexer). `seat-definitions` (whole, indexer).
58. **A check that could not run says so and is asked once more.** A check whose composer's node does not answer 58. **A check that could not run says so and is asked once more.** A check whose composer's node does not answer
reads `could not run` and names that node in `mesh-delivery.show`; the claim is released; the node's `running` asks reads `could not run` and names that node in `mesh-delivery.show`; the claim is released; the node's `running` asks
the check again once, and a second `running` of the same part at the same fingerprint asks no second check; a the check again once, and a second `running` of the same part at the same fingerprint asks no second check; a
`could not run` not asked again within 60 minutes raises `check-could-not-run` (whole, checker; live, read through `could not run` not asked again within 60 minutes raises `check-could-not-run`, which reads cleared once the heads
are checked again, replaced, or their pull request closes (whole, checker; live, read through
`mesh-delivery.show`). `mesh-delivery.show`).
59. **A session hears an accepted record** (issue 595). An Approve that accepts a record makes the knowledge base say 59. **A session hears an accepted record** (issue 595). An Approve that accepts a record makes the knowledge base say
`reviewed` with what was accepted, by the operator and with the warrant, and the tool runner's account hears it, so `reviewed` with what was accepted, by the operator and with the warrant, and the tool runner's account hears it, so
a session waiting with `mesh_wait` wakes on it (whole, knowledge base; live). a session waiting with `mesh_wait` wakes on it (whole, knowledge base; live).
60. **The store's holder takes its own build when its seat is broken.** With a fixture holder of `oci-artifact-registry` 60. **The store's holder takes its own build when its seat is broken.** With a fixture holder of `oci-artifact-registry`
that refuses every store, its new build is kept on the build node, named in the builder's done key, fetched by the that refuses every store, its new build is kept on the build node, named in the builder's done key, fetched by the
node-engine through `kept-artifact`, and once it runs the next build is stored through the seat, with no hand act node-engine through `kept-artifact`, and once it runs the next build is stored through the seat, with no hand act;
(whole, builder, build module and node-engine). a call of `kept-artifact` from an account other than a node-engine's is refused; it is refused for a module that
does not claim `oci-artifact-registry`; fetched bytes that differ from the done key's digest are not applied; an
artifact over the bus's value limit is fetched whole as an object; with the keeping node away, or the build swept,
the want waits and the have says why (whole, builder, build module and node-engine).
## What retires ## What retires