The operator's flow: clients publish what their credentials file holds, the
manager takes in a licence it does not own and rotates it from then on. The
token itself cannot be published (design 32 §10, ADR 0201), so a node reports
fingerprints and identity as state and hands the grant over only when the
manager asks; adopting is refreshing, newest login first; bindings with a
generation replace the rotated/switched events. Designs 36 and 39 and to-be 40
amended; a pointer note on ADR 0183.
ADR 0173 §2: a module is what it declares, and there are no kinds of module. The two records called
a resource under a home and a module placing one home-scoped; the wording is corrected in place,
marked and dated, the decisions unchanged. Design 36 and to-be 40 now say the module declares
/etc/claude-code and ~/.claude as directories, so the ownership check sees both, and declares no file
under either (mesh-catalog #244).
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).
Design 38's WP1-WP4b ran: the node's tool runtime is live on all four machines as the operator
account, tools are bundles given only their declared words, and a bundle has no bus credential.
So the wait on design 38 WP3 is over, the agent module calls nothing and the manager starts every
exchange (key, hand-over, waiting login, reconcile), and the manager's daemon now waits on WP4c's
record instead. Accounts are stated on all four, sudo -n works for each, the agent is installed on
all four; the plan's WP0 shrinks and WP2 gets a configuration-only live proof before any licence.
Designs 36 and 39 say what is built; this says in which order and what proves each step, in the
shape to-be 38 gave the operator's machine. Seven packages: the operator states the facts (accounts,
roles, licences); the console provides its endpoint; the licence manager and the agent module are
built and unit-tested in parallel; the manager goes live on the control node; the agent on one
workstation, with the switch and the predecessor's files removed as the proof of the whole; then the
rest of the nodes and the retirement of the two catalogue modules built on the old placement. The
live proofs wait for to-be 38's WP3, because both modules' tools run in the node's tool runtime
(ADR 0175) and a per-module tool container would rebuild what that record retires.
ADR 0203: the account's environment is one module's (seat node-environment);
every module contributes variables and PATH entries, rendered by the
controller as a POSIX file and as environment.d.
ADR 0204: shell code is contributed to the login shell in named slots, and
login-shell becomes the mesh's node-login-shell.
ADR 0205: software the distribution does not package ships as a pinned
archive of the module.
Issue 225: undeclaring a user stops a node applying; the shell is never
given back or checked.
To-be 41 carries the work packages; to-be 38 WP5 points to it.
The operator's proposal: one module, holding a mesh seat node-environment, is
the only writer of the account's environment. It renders contributed variables
and PATH entries as a POSIX file shells source and as environment.d for the
graphical session. The shell's contribution shrinks to shell code; the shell
render-then-service-manager-again positions become options weighed against it.
Opened after the zsh module's rollout (to-be 38 WP5) was stopped: every machine
carries the same predecessor-written startup file, the module's block would
duplicate it and drop lines, nothing installs the prompt, and execute never
reads .zshrc. Weighs how modules contribute environment and shell code, where
the operator's own lines go, ordering, and what a contribution is addressed to.
The derived-value record is renumbered a second time: the key-value-buckets
record took 0201 while this waited to merge, as the bundles record took 0188
before it. Both times free when chosen, taken by the time it landed. cycle.py
caught it; three repositories cite this record, so the number matters.
225 — a provisioner has not been able to read its grant secrets since 01:30,
when a module's own code left its container and the files stayed root's. Four
thousand refusals, each worded as patience, and two consumers unserved. Not
from ADR 0202 or 0189, which landed hours later; dates in the report.
226 — the store's sweep stops at the first reference recorded with an address
and collects nothing. A guard that cannot tell 'I will not ask about this'
from 'it would not answer' stops the wrong amount of work.
227 — the photo app's admin client asks for the port the proxy holds. A module
pinned months behind carries everything its branch gained, the first time
anything makes it move.
ADR 0201 gains the boundary found reading it back: a consumer keeping several
holders of a deriving provider is refused, because the two ends have no way
to agree. ADR 0189 gains two consequences — the sweep is bounded because it
runs inside a build, and an apply arriving mid-window reopens it.
That last one is issue 224, recorded rather than fixed: the host's rule for a
stopped container is to replace it, and while-stopped is the first thing that
makes a stopped container intentional. Both candidate fixes are decisions with
their own cost. Nothing is worse than it was; the store has never collected.
The bundles refactor took 0188 on main while this waited in a pull request,
and the mesh's own code cites that one, so this record moves. Only the number
moved; the decision is the one taken on 2026-10-02, and the record says so.
Issue 202 re-checked against the refactored main: the fault stands, and the
test that surfaced it now fails one step earlier on issue 203's new credential
guard. Proven again past both — mint the credential, compose twice, and all
eight of dnsmasq's resources appear only with the setting set. ADR 0164 is
noted as the decision that answers half of it, and is not built.
Issue 108: the artifact store has never collected anything. Fifty-three
repositories on the machine that serves everything else, and the only outcome
of leaving it is a full disk reported as somebody else's failure.
The mesh decides what may go — from its own build records, so it never names
a digest it did not put there — and the store reclaims the bytes in a nightly
window with its server held still. Deletion on the one door takes nothing a
push did not already have.
Designs 18 and 20 amended; issue 108 resolved.
Also issue 202, found running the controller's suite: a module whose required
setting nobody set is left out of the machine in silence, and dnsmasq became
that module this morning.
Issue 124: a value the mesh's own rule produced reached neither end as a
statement. The object store's provisioner derived each consumer's bucket in
its own code; all three consumers transcribed the rule into their own
definitions, one of them wrong, and each of the three also named the machine
it happens to run on.
A served value may now name the consumer the mesh is serving. Design 27
amended; issue 124 resolved.
Events miss a machine that joins after them and replay history where only the
latest matters. A module now declares state it owns and reads; the controller
creates the buckets, the runtime serves them on the bundle's channel. Designs 32
and 25 amended; grants measured against a running server.