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 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.
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.
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.
ADR 0194 rejected sending every query to the mesh's resolver because a node with its tunnel down
would resolve nothing; a public resolver listed second answers exactly then. That drops the
systemd-resolved stub and the runtime's dns: containers copy the machine's resolvers. Narrows 0194;
amends connectivity §2.
Every resolution fault found on 2026-10-03 was a per-node copy disagreeing with the truth: a hosts
file read once, an operator's old line beside the mesh's, a node's resolver lent to a LAN. Every
tunnel already converges on one node. Retires node-dns-resolver for a mesh-scoped mesh-resolver;
nodes route only the mesh's suffix to it. Narrows 0121; amends connectivity §2 and the seats.
Publishing every routed public name at a private address turned ace's LAN-facing resolver into an
outage for non-members: a phone got the control-node's tunnel address for the mail server. Routes
have internal names since 0151 and the proxy certifies public names publicly, so nothing needs the
private answer. Narrows 0066 and 0151; amends connectivity §2 and §5.
The build role was a mesh seat with one holder and its worker a push consumer with one delivery in
flight, so thirty-five images rebuilt serially on one machine while three others idled. The bus was
drawn for the alternative — a seat's accept subjects on a queue group of holders (design 25) — and
0190 uses it as one pattern for every role: a node seat with accepts, every holder pulling one ask
when idle, the asker addressing the role. Building is the first use: node-build-agent, held by the
build-agent module on every machine with a container runtime. Notes in 0121 and 0162 where their
facts went stale.
The operator's direction, absent from every record until now: the SDK must not limit who writes a
module; tools and services may be written in any language; one module may ship several bundles
(tools, a seat's implementation, a daemon); skeleton first, a full implementation when the work
requires it. ADR 0175 had the runtime import a bundle, which only JavaScript can be.
0187 makes a tools bundle a process the node's runtime launches and speaks MCP over stdio to —
the vocabulary the runtime already speaks outward — so any language with an MCP library can write
one today and the mesh's SDK per language is thin; the transport stays in the runtime (0039's
refusal, kept). Importing a TypeScript bundle is the shortcut, not the contract. Notes in 0175,
0039 and 0150 say where their mechanism moved; design 38 records WP1 as built and adds WP1b (the
launcher and the skeleton SDKs); the glossary's bundle widens.
The predecessor's agent module was retired and its six files stayed on both workstations telling
every session to use tools that no longer exist. This is its successor's design, revised during
review on the operator's directions: the host is module-agnostic, the controller has no part, and a
real licence manager hands out the correct licence in every situation.
- ADR 0181 (reconstructed): the operator account is a node fact stated by the operator; the home is
derived unless stated; a resource may be placed under it owned by the account; a node with no
account refuses one. What the controller shipped on 2026-09-27 without a record.
- ADR 0182: inside a home the module owns the directory and the files it places, writes into the
tool's own files for its few keys, never declares a credential's content, and holds everything
else as found; a predecessor's leftovers are the operator's to remove once.
- ADR 0183: claude-licence-manager holds the mesh seat anthropic-licence-manager and owns the
Anthropic licences, grants (encrypted with a key the vault made for it), bindings per touchpoint,
usage and audit; one rotation source under a lease; a token travels module to module sealed to
each node's module key on request/reply, never as an event; the agent module alone writes what
the agent reads; the host delivers package and state and knows nothing else. A bounded exception
to ADR 0113; dated mechanism notes on ADR 0050 and 0113.
- To-be 36 (claude-code): the mesh's part of the agent's configuration lives in the agent's
machine-wide managed directory, owned whole by the module and written by its code; nothing under
the home but the credentials file of a subscription licence; the API-key licence through the
key-helper; the console as a node-scoped provision (to-be 34 amended); MCP servers as settings
with an mcp_configure tool; one agent directory per machine shared by every session.
- To-be 39 (claude-licence-manager): store, the two licence kinds, keeping a grant alive, the
hand-over, who gets which licence with the predecessor's fallbacks, adoption with the identity
guard, the seat's verbs.
Numbers taken across main and every open branch at the time of the merge; to-be 14, 29 and 34
carry dated notes; the glossary gains "operator account".
The runtime work of design 37 broken down the way design 28 broke down the
bus: what exists measured (the host needs no change — a process and an
archive are what the runtime and a bundle are; the runtime does the job for
one module and must do it for a list), the order the dependencies allow, and
eight packages each ending at a proof on the live mesh — the lab skipped by
the operator's decision, ADR 0149 cited. WP1 the runtime serves many modules;
WP2 the controller composes one per node (a node principal, bundle archives,
the runtime's process, the gate); WP3 the runtime is a module and the console
its serving mode; WP4 the packet filter moves first; WP5 the shell on a
server; WP6 the service manager on a workstation; WP7–8 named and not broken
down.
Main carried two records numbered 0175 and cycle.py refused it: the one that
landed last (the found front end is uninstalled) takes 0180, the next free
across main and the open changes, with a dated note; design 08's citation
follows it; the index is regenerated.
Every configurable thing on a node is a module, the home included, and a
module is whatever it declares (0173, extending 0040). A node varies a module
only through a setting rendered into the file or a kept region, never an edit
(0174, extending 0011; issue 168 first). One tool runtime per node serves every
module's tools on the host side, never in a container; the console is its
serving mode, renamed node-tools (0175, extending 0150; 0047/0150/0152 carry
dated notes). The login shell is a node seat held by one shell module with
`execute` as its contract (0176). A unit may be user-scoped and the service
manager is a node seat held by systemd (0177).
To-be 37 is handed off in-progress to mesh-host, mesh-controller, mesh-tools
and mesh-catalog, with the build in order: the account on every node, the
runtime, zsh, systemd, then the graphical stack. To-be 29 keeps ~/.ssh and
points at 37; 33 §6 and 34 are amended; the glossary gains node tools, bundle,
kept region, installed/holding, and retires flavor.
Another session's 0169 landed first. The collision check from issue 155
covered issue folders only; it covers decision records now, and would have
refused this.
Designs 33 and 08 revised. The first node-scoped seat with verbs: rules,
reload, remove; the nftables module holds it from a runtime with NET_ADMIN,
the first container to declare a capability.
The bus was public only so a new machine could enrol before it had a
tunnel. The machine now makes its tunnel key first, the token is issued
for it and makes it a peer of the hub, and enrolment happens over the
tunnel.
Designs 08 and 05 revised; 141 resolved by ADR 0140 and 084 by ADR 0102 and
issue 128, both by reading; 143 and 144 decided, built on the matching
branches in mesh-host and mesh-controller, resolved when the home server's
record names the predecessor's chain.
Issue 191's route proxy needs to know who the mesh is to serve an
internal name correctly, and the first fix had it work that out alone.
The membership on the bus now carries it, from the same list the filter
uses. ADR 0138 gains an insight that the proxy is where internal reach
is kept; designs 08 and 25 say how.
Proposed for the operator's review: settings declared with defaults and cost (0164),
container-runtime as a kernel capability (0165), node-container-runtime seat with the
host creating containers through its holder (0166), and the runtime's file written by
modules that are not its own (190).