Design 51: keep the node-engine's own build readable by away nodes (ADR 0623)
mesh/delivery closed: a newer head of the same pull request
mesh/check pass 01d4f2781ef0 on 6cd965b3cdf6 | unit 39 run, 0 kept, 1 skipped | integration 39 run, 0 kept, 1 skipped | composition passed in 33s on 4…

Under ADR 0618 alone a node away with an old node-engine would be held
from the node-engine's own build in the new form and could never update
itself. ADR 0623 keeps every counted node-engine's form in those builds
and moves them to a node that reads any one of them.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 09:48:56 +01:00
parent 48fa0a5a48
commit 01d4f2781e
@@ -19,6 +19,7 @@ decisions:
- "ADR 0613" - "ADR 0613"
- "ADR 0617" - "ADR 0617"
- "ADR 0618" - "ADR 0618"
- "ADR 0623"
- "ADR 0606" - "ADR 0606"
- "ADR 0607" - "ADR 0607"
- "ADR 0610" - "ADR 0610"
@@ -379,25 +380,30 @@ publish of mesh-sdk or `mesh-contracts` triggers their users (ADR 0614 §6). The
build and adds none (ADR 0613 §1). ADR 0614 bounds nothing here; a bound, such as a settle before building a build and adds none (ADR 0613 §1). ADR 0614 bounds nothing here; a bound, such as a settle before building a
fingerprint whose inputs still move, is a question for a record, put to the operator, and is not designed here. fingerprint whose inputs still move, is a question for a record, put to the operator, and is not designed here.
**The node-engine's own build keeps the old reference form** until every present node-engine states the capability **The node-engine's own build keeps the old reference form** while any node-engine the mesh counts states only it,
to read the new one (ADR 0618 §2): the builder writes a new reference form, in the node-engine's done key as in every away ones included (ADR 0623 §1-2). For the module that holds the seat `node-engine`, the builder writes into each
other build's, only once every node-engine on a node present states it, so no build, the node-engine's own included, build key every reference form a counted node-engine states, beside the new form, which it writes there as in every
needs a form no running node-engine reads (ADR 0603 §7, §9). Each build names with it the reader capabilities its other build only once every present node-engine states it (ADR 0618 §2); a node leaves the count only when it is
forms need, and the assigner holds a node's want while that node's engine does not state one (ADR 0618 §1), so a node retired, never because it is away (ADR 0623 §1). The assigner moves the node-engine's own build to a node once that
that was away is held, never handed a form it cannot read. This is a window like the old seat name's. The builder node's engine states any one form the build carries (ADR 0623 §2), so a node back from being away moves to the new
reads each node's stated capabilities through the node-engine seat's verb `manifest-reads` (ADR 0618 §3) at its start, node-engine through the old form, states the new capabilities from then on, and can always update itself (ADR 0603
and wakes on the seat's event `mesh.seat.node-engine.event.manifest-reads-changed`, said when a node's stated §7, §9). Every other module's builds keep ADR 0618 §1-2: they carry the new form once every present node-engine
capabilities change and when the node returns after being away (ADR 0618 §4), never on a watch of the node-engine's states it, each names the reader capabilities its forms need, and the assigner holds a node's want while that node's
have state (ADR 0596) and never on a timer. The builder declares `seat:node-engine.manifest-reads` in its `invokes`: engine does not state one, so a node that was away is held from them, never handed a form it cannot read, until its
that is the grant the grants part composes, and with it the grants part grants the builder the subscription to the new node-engine states the form. The old form in the node-engine's own builds is a window like the old seat name's:
event's subject. A node-engine that does not yet serve `manifest-reads` counts as stating nothing: the window stays it closes when no counted node-engine states the old form alone, and the builder then drops it from those builds. The
open and names the node. Only a present node-engine that has not updated holds this window; a node away is held by the builder reads each node's stated capabilities through the node-engine seat's verb `manifest-reads` (ADR 0618 §3) at
assigner instead and is not listed as holding it. Its tool `builder_old_form` lists whether the window is open and the its start, and wakes on the seat's event `mesh.seat.node-engine.event.manifest-reads-changed`, said when a node's
present nodes whose node-engine does not yet state the capability, and drops a retired node from it by hand, recorded stated capabilities change and when the node returns after being away (ADR 0618 §4), never on a watch of the
as a hand act; a present node holding it open for seven days is the builder's finding naming the node, cleared when node-engine's have state (ADR 0596) and never on a timer. The builder declares `seat:node-engine.manifest-reads` in
the window closes. Closing it says so in the build log and emits `old-form-closed` (the time, the nodes that held its `invokes`: that is the grant the grants part composes, and with it the grants part grants the builder the
it last, the nodes dropped by hand) on the builder's own family beside `numbered`; a waiter on a build's end does not subscription to the event's subject. A node-engine that does not yet serve `manifest-reads` counts as stating
wake on it. nothing: the window stays open and names the node. Its tool `builder_old_form` lists whether the window is open and
the counted nodes, present or away, whose node-engine states only the old form, and drops a retired node from the
count by hand, recorded as a hand act; a node holding it open for seven days is the builder's finding naming the node,
cleared when the window closes. Closing it says so in the build log and emits `old-form-closed` (the time, the nodes
that held it last, the nodes dropped by hand) on the builder's own family beside `numbered`; a waiter on a build's end
does not wake on it.
**When the group is pushed.** Only once the release that adds the node-engine's stated capability (design 47) runs on **When the group is pushed.** Only once the release that adds the node-engine's stated capability (design 47) runs on
every node, read from the status view's haves before the push, and once the progressive insights of ADR 0595 and every node, read from the status view's haves before the push, and once the progressive insights of ADR 0595 and
@@ -487,14 +493,15 @@ test).
source other than the publish target) the floor finding is written and cleared once it answers, and with source other than the publish target) the floor finding is written and cleared once it answers, and with
`bridge_tags` still silent after the by-digest publish, the build stays unnumbered until the forge bridge's health `bridge_tags` still silent after the by-digest publish, the build stays unnumbered until the forge bridge's health
clears (no timer runs), and is then numbered and published by version; `builder_floor_again` asks the three clears (no timer runs), and is then numbered and published by version; `builder_floor_again` asks the three
sources at once and records the hand act; the node-engine's done key stays in the old form while one present node's sources at once and records the hand act; a build key carries only the old form while one present node's
node-engine lacks the capability, or does not serve `manifest-reads`, and is written in the new form once every node-engine lacks the capability, or does not serve `manifest-reads`, and carries the new form once every present
present node states it, `builder_old_form` naming that node meanwhile and dropping it by hand with a hand act; with node states it (ADR 0618 §2); with one node away whose node-engine lacks the capability, the node-engine's own build
one node away whose node-engine lacks the capability, the new form is written, the assigner holds that node's want, still carries the old form beside the new and is moved to that node, while another module's build in the new form
and `builder_old_form` does not list it (ADR 0618 §1, §2); a present node gaining the capability closes is held by the assigner for it (ADR 0623 §1-2, ADR 0618 §1), `builder_old_form` naming that node meanwhile and
that window on its `manifest-reads-changed` event with no `delivered` and no timer (ADR 0618 §2, §4), while a node dropping a retired one from the count by hand with a hand act; that node, back with the new node-engine, says
away is held by the assigner from builds in the new form (ADR 0618 §1), with `old-form-closed` emitted `manifest-reads-changed` and the window closes with no `delivered` and no timer (ADR 0618 §4), the old form dropped
and its build-log line written, and a waiter on a build's end does not wake on it; with the image's own seat silent from the node-engine's own builds, with `old-form-closed` emitted and its build-log line written, and a waiter on a
build's end does not wake on it; with the image's own seat silent
at the claim of `distribution`'s own image, the image is still built, published by its digest, and numbered once at the claim of `distribution`'s own image, the image is still built, published by its digest, and numbered once
its new build answers (ADR 0617 *How it is checked*). its new build answers (ADR 0617 *How it is checked*).
- **Builder, added for the milestone, unit** (cases of the builder's numbering): a second trunk build of a package's - **Builder, added for the milestone, unit** (cases of the builder's numbering): a second trunk build of a package's