Plan and designs after ADR 0193, 0195 and 0198: bundles are launched and the runtime is their bus; the manager's daemon is a long-running bundle; the console's five tools

The dated note on ADR 0183 now rests on ADR 0193 and 0198 rather than on a bundle having no way to
call: the manager starts every exchange by the operator's direction, through mesh/ask. To-be 40's
WP4 no longer waits on a record — ADR 0198 is it — and the live proofs count the console's five
tools (ADR 0195).
This commit is contained in:
jochen
2026-10-03 23:41:38 +02:00
parent 88fd7d9739
commit baf82b1cdb
4 changed files with 37 additions and 32 deletions
@@ -152,18 +152,19 @@ the node is bound to, and refuses with a notification otherwise.
| An unservable binding refuses rather than lends | a manager test: a worker bound to a dead licence is answered with a refusal, never another licence's token | | An unservable binding refuses rather than lends | a manager test: a worker bound to a dead licence is answered with a refusal, never another licence's token |
| A switch through the console changes the token on the node and nothing in the answer is a token | a live check on one workstation | | A switch through the console changes the token on the node and nothing in the answer is a token | a live check on one workstation |
> **The mechanism changed — 2026-10-03, by [ADR 0192](0192-a-tools-bundle-declares-what-it-is-given-and-the-runtime-hands-it-to-that-bundle-alone.md).** > **The mechanism changed — 2026-10-03, by [ADR 0193](0193-every-bundle-the-runtime-serves-is-launched-and-the-runtime-knows-no-language.md)
> and [ADR 0198](0198-a-modules-long-running-code-is-launched-by-the-node-runtime-and-reaches-the-bus-through-it.md).**
> What stands: one manager holding the seat, one rotation source, a token sealed to the receiving > What stands: one manager holding the seat, one rotation source, a token sealed to the receiving
> module's key on request/reply and never an event, the agent module alone writing what the agent > module's key on request/reply and never an event, the agent module alone writing what the agent
> reads, the identity guard, the host knowing nothing. What moved: the agent module's code is now a > reads, the identity guard, the host knowing nothing. What moved: both modules' code is bundles the
> tools bundle the node's runtime serves ([ADR 0175](0175-one-tool-runtime-per-node-serves-every-modules-tools-on-the-host-side.md), > node's runtime launches over stdio and is the bus for — `mesh/ask` for a call made on the module's
> [ADR 0188](0188-a-modules-own-code-is-bundles-in-any-language-and-a-tools-bundle-speaks-mcp-to-the-runtime.md)), > behalf, `mesh/publish` and `mesh/subscribe` beside it — so neither holds a bus credential of its own.
> and a bundle has no bus credential of its own and answers calls rather than making them (ADR 0192's > The manager's refresh and visits are a long-running bundle the control node's runtime launches. And,
> consequences). So **the manager starts every exchange**: it asks each bound node's agent module for > by the operator's direction, **the manager starts every exchange**: it asks each bound node's agent
> its public key, hands it a token, asks it for a login waiting to be adopted, and reconciles every node > module for its public key, hands it a token, asks it for a login waiting to be adopted, and reconciles
> on a schedule — which is what "the agent module asks the seat for its current token" and "offers the > every node on a schedule — which is what "the agent module asks the seat for its current token" and
> grant to the manager" in the decision above now mean in practice. The manager's own process needs a > "offers the grant to the manager" in the decision above now mean in practice. The agent module could
> bus credential to make those calls, which is the question design 38's WP4c leaves to a record. > ask through its runtime; it does not need to.
## References ## References
@@ -124,8 +124,8 @@ the playbooks in the record.
**Other tool servers** a person wants on every machine, or on one, are a declared setting of this module **Other tool servers** a person wants on every machine, or on one, are a declared setting of this module
— mesh layer or node layer — rendered into the same managed file. The person sets them with the — mesh layer or node layer — rendered into the same managed file. The person sets them with the
controller's `settings` verb on this module, so the list stays declared state; a tool of this module controller's `settings` verb on this module, so the list stays declared state; the list is the operator's
cannot set it, because a bundle calls nothing (ADR 0192). The agent's own HTTP-only constraint for managed servers applies; a person's local choice, set where every setting is set. The agent's own HTTP-only constraint for managed servers applies; a person's local
command-based servers stay their own, in their own file. command-based servers stay their own, in their own file.
**The entry's name is `mesh`.** The hand-made entry both workstations carry today is named after this **The entry's name is `mesh`.** The hand-made entry both workstations carry today is named after this
@@ -157,9 +157,9 @@ decides it; to-be 39 is the manager's half. This module:
the file matches what was handed over — by fingerprint, never by value. the file matches what was handed over — by fingerprint, never by value.
Switching is the seat's `switch` verb, asked through the console; this module only applies what it is Switching is the seat's `switch` verb, asked through the console; this module only applies what it is
handed. *2026-10-03:* every exchange is started by the manager, because a tools bundle answers calls and handed. *2026-10-03:* every exchange is started by the manager, by the operator's direction (ADR 0183's dated
has no bus credential to make them ([ADR 0192](../../02-DECISIONS/0192-a-tools-bundle-declares-what-it-is-given-and-the-runtime-hands-it-to-that-bundle-alone.md), note); this module is a bundle the node's runtime launches over stdio and answers what it is asked
ADR 0183's dated note). The tool names follow the catalogue's `<module>_<verb>` form. ([ADR 0193](../../02-DECISIONS/0193-every-bundle-the-runtime-serves-is-launched-and-the-runtime-knows-no-language.md)). The tool names follow the catalogue's `<module>_<verb>` form.
## 6. Scope, settings and the order of assignment ## 6. Scope, settings and the order of assignment
@@ -169,7 +169,7 @@ extra tool servers. **Prerequisite:** the manager holds its seat and has adopted
**Order:** the manager assigned and a refresh observed; the console's provision in the catalogue; this **Order:** the manager assigned and a refresh observed; the console's provision in the catalogue; this
module on one workstation; the six predecessor files and the hand-made console entry removed there; a module on one workstation; the six predecessor files and the hand-made console entry removed there; a
new session read to confirm it sees the mesh's instruction file, the console's tools under `mesh`, and new session read to confirm it sees the mesh's instruction file, the console's five tools under `mesh`, and
its licence; then the rest. its licence; then the rest.
## 7. The package ## 7. The package
@@ -193,7 +193,7 @@ installer is rejected: it puts a self-updating binary under the person's home, i
| a switch asked of the seat through the console changes the licence and the token on the node; no tool answer and no log line holds a token | ADR 0183 | | a switch asked of the seat through the console changes the licence and the token on the node; no tool answer and no log line holds a token | ADR 0183 |
| the API-key binding writes nothing under the home and the agent authenticates through the helper | ADR 0183 | | the API-key binding writes nothing under the home and the agent authenticates through the helper | ADR 0183 |
| the console's provision resolves by co-location; a machine without the console refuses the module by name | ADR 0027, ADR 0152 | | the console's provision resolves by co-location; a machine without the console refuses the module by name | ADR 0027, ADR 0152 |
| a new session on the assigned workstation lists the console's tools under `mesh` and answers "which node am I" from the instruction file | the exit of the build | | a new session on the assigned workstation lists the console's five tools under `mesh` ([ADR 0195](../../02-DECISIONS/0195-the-meshs-tools-are-found-by-address-not-announced-whole.md)) and answers "which node am I" from the instruction file | the exit of the build |
## What this does not settle ## What this does not settle
@@ -74,8 +74,8 @@ Carried from the predecessor, where each rule was earned by an incident:
## 4. Handing a token to a node ## 4. Handing a token to a node
**The manager starts every exchange** (ADR 0183's dated note of 2026-10-03): the agent module is a **The manager starts every exchange** (ADR 0183's dated note of 2026-10-03), by `mesh/ask` through the
tools bundle, which answers and calls nothing. The manager asks each bound node's module for its public runtime that launched it ([ADR 0198](../../02-DECISIONS/0198-a-modules-long-running-code-is-launched-by-the-node-runtime-and-reaches-the-bus-through-it.md)). The manager asks each bound node's module for its public
key the first time and keeps it. From then on: key the first time and keeps it. From then on:
- **On rotation**, the manager calls `claude-code.apply@<node>` on every node bound to the rotated - **On rotation**, the manager calls `claude-code.apply@<node>` on every node bound to the rotated
@@ -23,11 +23,15 @@ packages, their order, their sizes and their proofs, and is wrong the moment it
It is the shape [design 38](38-building-the-operators-machine.md) gives the operator's machine. It is the shape [design 38](38-building-the-operators-machine.md) gives the operator's machine.
*Revised 2026-10-03, after design 38's WP1–WP4b ran:* the node's tool runtime is live on all four *Revised 2026-10-03, after design 38's WP1–WP4b ran:* the node's tool runtime is live on all four
machines, tools are bundles it serves and each is given only the words its artifact declares, and a machines, tools are bundles it serves and each is given only the words its artifact declares, every
bundle has no bus credential of its own. Three things in the first version of this plan changed with bundle is a child the runtime launches over stdio and is the bus for
that: the wait on design 38's WP3 is over; the agent module calls nothing, so the manager starts every ([ADR 0193](../../02-DECISIONS/0193-every-bundle-the-runtime-serves-is-launched-and-the-runtime-knows-no-language.md),
exchange (ADR 0183's dated note); and the manager's own process now waits on a different question, [ADR 0198](../../02-DECISIONS/0198-a-modules-long-running-code-is-launched-by-the-node-runtime-and-reaches-the-bus-through-it.md)),
named under WP4. and the console offers five tools over addresses
([ADR 0195](../../02-DECISIONS/0195-the-meshs-tools-are-found-by-address-not-announced-whole.md)). What changed
in this plan: the wait on design 38's WP3 is over; the manager starts every exchange, by the operator's
direction (ADR 0183's dated note); and the manager's daemon is a long-running bundle the runtime launches,
which ADR 0198 decided the same day — nothing in this plan waits on another record.
## How this is built, and where it is run ## How this is built, and where it is run
@@ -52,8 +56,8 @@ Measured 2026-10-03 on the four machines and in the repositories.
| escalation | passwordless `sudo` for the operator account on all four — a fact about the machines, checked by nobody | how the agent module writes its managed directory under `/etc` | | escalation | passwordless `sudo` for the operator account on all four — a fact about the machines, checked by nobody | how the agent module writes its managed directory under `/etc` |
| the agent itself | installed on all four, at four different versions, all above the one the managed tool-server key needs | declared as the module's package | | the agent itself | installed on all four, at four different versions, all above the one the managed tool-server key needs | declared as the module's package |
| a bundle's words | paths and constants written with `${dir:…}` and `${port:…}` only; a fact the mesh knows reaches a bundle as a file whose path is a word | the agent module's facts file and settings file | | a bundle's words | paths and constants written with `${dir:…}` and `${port:…}` only; a fact the mesh knows reaches a bundle as a file whose path is a word | the agent module's facts file and settings file |
| a bundle calling a tool | **not possible**: a bundle answers calls; it holds no bus credential | the manager starts every exchange | | a bundle calling a tool | `mesh/ask` through the runtime that launched it (ADR 0198); no bundle holds a bus credential | how the manager visits every node |
| a module's own long-running process with a bus credential | **undecided** — design 38's WP4c names it as the question its next record answers | the manager's daemon (WP4) | | a module's own long-running code | a bundle the runtime launches and restarts (ADR 0198); the runtime's subscription and grants built, the modules moving in design 38 WP4c's waves | the manager's daemon (WP3, WP4) |
| the vendor's refresh, the sealed box, the grant file | `anthropic-manager` in the catalogue, built on the controller placement ADR 0183 moved away from; assigned to nothing | its client ported into the manager; the module retired (WP6) | | the vendor's refresh, the sealed box, the grant file | `anthropic-manager` in the catalogue, built on the controller placement ADR 0183 moved away from; assigned to nothing | its client ported into the manager; the module retired (WP6) |
| the credentials write, the strip, the identity read | `anthropic-consumer` in the catalogue; tested; assigned to nothing | ported into the agent module with its tests; the module retired (WP6) | | the credentials write, the strip, the identity read | `anthropic-consumer` in the catalogue; tested; assigned to nothing | ported into the agent module with its tests; the module retired (WP6) |
| the predecessor's manager and consumer | the lease per licence, the expiry floor, the lineage comparison, the identity guard, three touchpoints, cooldowns | ported as logic with its tests | | the predecessor's manager and consumer | the lease per licence, the expiry floor, the lineage comparison, the identity guard, three touchpoints, cooldowns | ported as logic with its tests |
@@ -68,7 +72,7 @@ WP3 the manager's code, built and tested (mesh-catalog)
│ │
WP2 live: one workstation, configuration only — no licence yet ── the first live proof WP2 live: one workstation, configuration only — no licence yet ── the first live proof
│ │
WP4 the manager live on the control node ── waits on design 38 WP4c's record (a process's bus credential) WP4 the manager live on the control node ── its daemon a long-running bundle (ADR 0198)
WP5 the licence end to end on one workstation WP5 the licence end to end on one workstation
WP6 the rest of the nodes, and the predecessor's remains WP6 the rest of the nodes, and the predecessor's remains
``` ```
@@ -127,7 +131,7 @@ contains a token. The catalogue's checks pass.
**Proof, live, on one workstation, configuration only.** Assign the module; set the node's role; push. **Proof, live, on one workstation, configuration only.** Assign the module; set the node's role; push.
The agent's managed directory holds the two files; everything under the person's agent directory is The agent's managed directory holds the two files; everything under the person's agent directory is
byte-identical to before; a new session lists the mesh's tools under `mesh` and answers *which node am byte-identical to before; a new session lists the console's five tools under `mesh` and answers *which node am
I* from the managed instruction file. `claude_code_status` answers through the console. No licence is I* from the managed instruction file. `claude_code_status` answers through the console. No licence is
touched: the module writes the credentials file only when it is handed a token. touched: the module writes the credentials file only when it is handed a token.
@@ -136,7 +140,7 @@ touched: the module writes the credentials file only when it is handed a token.
*mesh-catalog. Two to three days.* *mesh-catalog. Two to three days.*
**What is written**, as design 39 says: the manifest (the seat and its verbs, a database, a `secret` **What is written**, as design 39 says: the manifest (the seat and its verbs, a database, a `secret`
for the key the grants are encrypted with, a tools bundle, a process bundle for the daemon, settings for the key the grants are encrypted with, a tools bundle and a long-running bundle for the daemon, both launched by the runtime, settings
with defaults); the store's migrations; the refresh with its plan, lease, floor and cadence as pure with defaults); the store's migrations; the refresh with its plan, lease, floor and cadence as pure
functions; the vendor client from `anthropic-manager`; adoption from a file and from a node's waiting functions; the vendor client from `anthropic-manager`; adoption from a file and from a node's waiting
login with the identity guard; usage and its threshold; the visit — key, hand-over, waiting login — per login with the identity guard; usage and its threshold; the visit — key, hand-over, waiting login — per
@@ -149,9 +153,9 @@ node's key.
## WP4 — The manager live on the control node ## WP4 — The manager live on the control node
*The live mesh. Half a day.* **Waits on design 38 WP4c's record** — how a module's own long-running *The live mesh. Half a day.* The daemon is a long-running bundle the control node's runtime launches
process is given a bus credential and its subscriptions — because the daemon must call the agent module (ADR 0198); it calls each node's agent module by `mesh/ask`. If the runtime's half of ADR 0198 is not
on every node. Until that record exists, nothing in this plan works around it: no tool container, no yet live on the control node when this package starts, this package waits for it: no tool container, no
credential copied by hand. credential copied by hand.
**Order.** Assign the manager on the control node; push. Adopt the API key from a file there. Adopt the **Order.** Assign the manager on the control node; push. Adopt the API key from a file there. Adopt the