Designs 51 and 32: answer the third review (publish-part listed with its callers, the node-engines' reports through the status view, C24 tested)
mesh/delivery merged: source.main moved to novox/hq@276cbef0c476
mesh/check pass 5b2cead5e3bc on 276cbef0c476 | carried from f6bd4246b0d7 | unit 39 run, 0 kept, 1 skipped | integration 39 run, 0 kept, 1 skipped | co…

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-03 18:10:19 +01:00
parent 9845b78e5b
commit 5b2cead5e3
2 changed files with 22 additions and 16 deletions
@@ -504,11 +504,11 @@ value it holds under the old name to the new name in its own state, without the
the value's trust: a value set without the operator's Approve stays untrusted under its new name (ADR 0348 §8), and
the checker refuses a rename that would change a value's trust.
- **How long the old name is read**: until every node-engine whose node has a want of the module reports applied a
build of it that reads the new name: mesh-config hears the node-engine seat's `applied` events, and asks each node's
`node-engine.haves` at its start; until then mesh-config answers both names. A later change may drop
build of it that reads the new name: mesh-config hears the status view's `delivered` events, and asks its
`node_haves` at its start (design 47); until then mesh-config answers both names. A later change may drop
`renamed-from` only after that, and the checker refuses it before. The checker also refuses `renamed-from` in any
manifest until a build of mesh-config that understands it is delivered, which it learns from the node-engine seat's
`applied` events for mesh-config. `config_renames` names, per rename, the nodes still holding the old name open.
manifest until a build of mesh-config that understands it is delivered, which it learns from the status view's
`delivered` events for mesh-config. `config_renames` names, per rename, the nodes still holding the old name open.
- **A refused move** (the old name holds nothing, or a secret) is mesh-config's finding, from which the condition keeper
raises the condition. **Tools of mesh-config**: `config_renames` (what moved, from which name, when) and
`config_rename_again` (move one value by hand when a move was refused).
@@ -535,7 +535,7 @@ each a case of its module's one whole-module integration test unless it says liv
| C18, a new required config value with no default | the check names the nodes that lack it; the want waits; the operator is asked once | live: a module gaining such a value waits on each node lacking it, the operator is asked once naming the nodes, and once given the module is applied |
| C20, a config value renamed | the value moves, keeps its trust, both names read until every node runs the new build | mesh-config: a renamed value is present under the new name with no operator input and its trust; the old name answers until the node-engines report the new build; dropping `renamed-from` early, or changing trust, is refused; a refused move writes its finding |
| C22, a secret only a person can give | the want waits; the operator is asked once what to give and where | live: a module requiring such a secret waits, one ask names it and where, and once given the module starts |
| C24, a config value or secret no longer read | it is retiring, the operator is asked, removed only on the Approve | mesh-config: a value no manifest reads is marked retiring, `retiring` is emitted, one ask reaches the operator, and it stays until an Approve removes it |
| C24, a config value or secret no longer read | it is retiring, the operator is asked, removed only on the Approve | mesh-config: with one node-engine still reporting a build that reads the value it is not marked retiring and no ask is sent; once that node reports the new build it is marked retiring, `retiring` is emitted and one ask reaches the operator; an ask unanswered seven days is asked once more, then written as a finding; the value stays until an Approve removes it |
## 9. Provisioning over the bus
@@ -737,6 +737,6 @@ as well as `drop`. Each is noted on issue 1966.
The amendment of 2026-11-03 for research 081 (ADR 0606, ADR 0609; the package, rename, retiring and delivery-case
sections of § 8) was reviewed with designs 51 and 26 by the four reviewers by architectural domain; the findings and
what answers them are listed in design 51's *Reviewed by architectural domain*. For this design: a rename keeps a
value's trust (security), `packages` is a section of its own, not `uses`, and mesh-config hears the node-engines'
`applied` events (seams), a value retires only once no node-engine runs a build reading it (security), and `renamed`
value's trust (security), `packages` is a section of its own, not `uses`, and mesh-config hears the status view's
`delivered` events (seams), a value retires only once no node-engine runs a build reading it (security), and `renamed`
and `retiring` have a family and an ask that is asked again (events).
@@ -12,6 +12,7 @@ decisions:
- "ADR 0606"
- "ADR 0607"
- "ADR 0610"
- "ADR 0611"
- "ADR 0311"
- "ADR 0251"
- "ADR 0189"
@@ -48,13 +49,13 @@ asks work of another by an event of its own (ADR 0610 §1).
Each is held once for the mesh. The last two replace the seat `mesh-artifact-store` and front the one artifact store;
while one module holds both, both deliver the provision `artifact-store`, and splitting them between two holders takes a
decision of its own. `mesh-artifact-store` stays served until every node-engine reports applied a build that reads the
new names (ADR 0610 §4); a sleeping node holds it open. `distribution` closes it itself: it hears the node-engine
seat's `applied` events (and asks each node's `node-engine.haves` at its start), stops serving the old name once every
new names (ADR 0610 §4); a sleeping node holds it open. `distribution` closes it itself: it hears the status view's
`delivered` events (and asks the status view's `node_haves` at its start, design 47), stops serving the old name once every
node whose declaration names an artifact reports the new build, and its tool `registry_old_name` lists the nodes still
holding it open. `cargo-package-registry` stays named, without a holder, until a
build module publishes cargo packages.
**One contract, a seat definition** (design 26, *A seat's definition*). Verbs: `publish`, `versions`, `remove` (a
**One contract, a seat definition** (design 26, *A seat's definition*). Verbs: `publish`, `publish-part` (ADR 0611), `versions`, `remove` (a
tagged version only; the holder itself refuses `remove` of a version with no tag), and on `container-image-registry`
`mirror` and `tags`. Events: `published`, `refused` (added to ADR 0605 §2's two, additively) and `removed`, each
carrying the name, version, kind, tag, digest, fingerprint, commit and holder, and `refused` its reason; each seat's
@@ -62,7 +63,8 @@ events are its own family, `<seat>.events`, kept seven days. A holder stores
under the version it is given and counts nothing.
**Who may call which verb is the holder's to say**, in a trusted config value of the holder listing its callers, the
form ADR 0363 gives a restricted family: `publish` the build modules; `mirror` mesh-build-image; `remove` the builder.
form ADR 0363 gives a restricted family: `publish` and `publish-part` the build modules, and a part only from the
proved caller that opened its transfer; `mirror` mesh-build-image; `remove` the builder.
Declaring `invokes` alone grants nothing. The holder checks the caller identity the tool runner proved and stamps on
the request (design 25 § 12.4), never a name in the request's body, and answers any other caller with a refusal naming
the verb.
@@ -92,9 +94,11 @@ the verb.
with `refused` naming the cap. Its tool `registry_incoming` lists open transfers and the fill, and drops one by hand.
- **The holder asks the builder**, through `builder_versions`, whether the name, version and digest are recorded, and
refuses loudly otherwise (ADR 0605 §4). A rebuild of a held fingerprint answers the held version and stores nothing.
- **How a publish ends**: the holder emits `published` or `refused`. The build module waits for one of them, at most
- **How a publish ends**: the holder emits `published` or `refused`. The build module waits for one of them, matching
on its transfer, name and version, at most
10 minutes, narrating "waiting on <seat>" at least every five minutes; past the bound it writes the key refused,
naming the seat, and the builder writes the finding for a refused publish. A `published` that arrives after that is still heard by the builder on its durable consumer: the
naming the seat, and the builder, hearing that build's end event as it does every build's, writes the finding for a
refused publish. A `published` that arrives after that is still heard by the builder on its durable consumer: the
entry turns `published` and the builder writes the done key then, so a late store is never lost.
- **What is published when**: a package or an image from a trunk build under its version, or as a tagged version; a
bundle or an archive from every done key by its digest alone, a candidate's included, and at the trunk's claim the
@@ -213,7 +217,8 @@ test).
numbered at once; a build module's bound running out writes the builder's finding, and a later version of the name
clears it; `builder_publish_again` after a `published` takes a new number.
- **Holder (gitea, distribution).** A caller not on the caller list is refused for each verb, and one module naming
another as the caller in the request's body is refused; a transfer cut in the middle resumes from the parts held,
another as the caller in the request's body is refused; a part sent by a module other than its transfer's opener is
refused; a transfer cut in the middle resumes from the parts held,
and one left 24 hours is dropped; at the cap a new transfer is refused naming the cap; a version a `go.mod` requires
survives retention, and an unreadable `go.mod` stops the run; a part whose bytes do
not match its digest is refused; only the missing layers are sent; `remove` of a version with no tag is refused;
@@ -222,7 +227,8 @@ answers (a holder down whole is its module's own health check's); `registry_inco
lists and drops.
- **Vault.** Reverting step 4 mints the build modules' credentials again; the bootstrap's one-off credential is gone
once the holders serve `publish`.
- **Live.** Step 2 waits while one node-engine has not reported step 1's build; `registry_old_name` names the nodes
- **Live.** Step 2 waits while one node has not got step 1's build, as `node_haves` shows (the lead's gate before
step 2's merge); `registry_old_name` names the nodes
holding the old name open.
## Reviewed by architectural domain
@@ -237,7 +243,7 @@ and ADR 0611 (the file travels in parts through the seat). What was found, and w
|---|---|---|
| security | caller lists named only on the caller's side; the handed object's bytes unchecked; no caller identity; pull request seat definitions served as contracts; the bootstrap's credential | *Who may call which verb* (holder-side lists, the identity the tool runner proved); *Publishing* (parts hashed); design 26 (only the trunk's entry is the contract); *The move* (a one-off bootstrap credential) |
| upgrade | the steps moved no image, bundle or archive before their credentials went; Go users between steps 2 and 3; no node-engine reading the new forms before step 2 | *The move* (every move in step 2, a node-engine reading both forms in step 1, step 2 waiting on the node-engines' reports, git tags for Go, reverse-order rollback) |
| seams | five reaches into another module's bus state; a shared hand-off store; how a publish ends; how the indexer learns out-of-step types; no named path for the node-engines' reports | ADR 0610, ADR 0611; *Publishing* (`published` or `refused`); design 26 (the check's verdict event); `applied` and `node-engine.haves` |
| seams | five reaches into another module's bus state; a shared hand-off store; how a publish ends; how the indexer learns out-of-step types; no named path for the node-engines' reports | ADR 0610, ADR 0611; *Publishing* (`published` or `refused`); design 26 (the check's verdict event); the status view's `delivered` events and `node_haves` |
| tools | no read or drop tool for asks, transfers, the old name's window | `builder_tag_asks`, `registry_incoming`, `registry_old_name`, design 32's `config_renames` and `config_retiring` |
| running qualities | the versions value growing; the floor with a part down; merge order and a replaced merge; windows closing on wants; retention against "never removed"; a Go reference undefined; the in-transit cap | *The versions* (one key per version, a cap, the floor's wait, merge order skipping a replaced fingerprint); *Retention* (a Go reference); *Publishing* (the cap refused) |
| testing | failure paths untested; the test budget | cases of each module's one whole-module integration test, listed under *Acceptance tests* |