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.
15 KiB
layer, status, code, updated, decisions
| layer | status | code | updated | decisions | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| to-be | designed | 2026-10-02 |
|
40. Building the operator's agent and its licence manager
The work of design 36 and design 39, broken into packages that each end at something a person can see run, in the order their dependencies allow. The two designs are the authority on what is built; this document holds the packages, their order, their sizes and their proofs, and is wrong the moment it disagrees with them. It is the shape design 38 gave the operator's machine, applied to the two modules that make its agent work.
How this is built, and where it is run
On the live mesh, by the operator's decision (ADR 0149, and design 38's words on the same day). Every package is written with unit tests, committed on one branch per repository (playbook 07), and proven on the machines: the control node first for the manager, one workstation first for the agent, then the rest. The cost accepted: a broken agent module leaves a workstation's agent without the mesh's instructions or with a stale token until the next push; the person's own files under the home are never in reach of the failure, by ADR 0182.
Each package names what proves it. A package that cannot name its proof is divided until it can.
What exists already, measured
Counted 2026-10-02 in the repositories and on the machines. Nothing here is new ground; every package reshapes something standing.
| Piece | Today | Becomes |
|---|---|---|
| the vendor's refresh, the sealed box, the grant file | anthropic-manager in the catalogue: a token-endpoint client, a sealed-box primitive, adoption of a grant sealed to a node's key; assigned to nothing |
the manager's refresh and adoption, with the lease, the floor and the cadence the predecessor's manager had |
| the credentials write, the refresh-token strip, the identity read | anthropic-consumer in the catalogue: tested; assigned to nothing |
the agent module's write, unchanged in shape |
| the predecessor's manager and consumer | two modules in the retired system: the lease per licence, the expiry floor, the lineage comparison, the identity guard, three touchpoints with fallbacks, cooldowns on alarms | ported as logic with its tests; nothing of its registry or its bus |
the host's process and archive shapes |
fetch a bundle by digest and run it supervised; fetch and unpack an artifact | unchanged — the manager's daemon is one process; both modules' tools are bundles |
the manifest's uses, claims, invokes seat:<seat>.<verb>, node-scoped provides with serves: {port} |
all four exist and are used by other modules | unchanged — the agent uses the seat and invokes its verbs; the console provides its endpoint |
| the console | a container per node, MCP on loopback, no provision | gains one provision; becomes the node-tools runtime's serving mode under design 38's WP3 |
| the agent's package | present on both workstations from a build the predecessor's helper made; the distribution's repositories do not carry it | declared; satisfied where present, refused where not, until a package repository seat exists |
| the operator account | a column on every node record, empty on all four | stated by the operator, before anything home-scoped lands |
One dependency decides the order. Both modules serve tools and the agent module's tools write
under /etc and, as the operator, under the home. Under ADR 0175
tools run in the node's tool runtime, host-side, which design 38 builds in its WP1–WP3. Writing a
per-module tool container for these two modules would be building the pattern that record retires, so
the live proofs of WP3 to WP5 below wait for design 38's WP3. Everything before a live proof —
manifests, code, tests — does not, and is written now.
The order the work allows
WP0 the operator states the facts (the live mesh) ── accounts, roles, licences to adopt
WP1 the console provides its endpoint (mesh-catalog) ── small, independent
WP2 the licence manager, built and tested (mesh-catalog) ──┐ independent of each other;
WP3 the agent module, built and tested (mesh-catalog) ──┘ both wait on design 38 WP3 to run
│
WP4 the manager live on the control node (the live mesh) ── three licences adopted, a refresh seen
WP5 the agent live on one workstation (the live mesh) ── the hand-over, the switch, the instructions
WP6 the rest of the nodes, and the predecessor's remains ── adoption from a login, the retirements
WP1, WP2 and WP3 touch different directories of one repository and meet only at the seat's name and the provision's name; they are built in parallel. WP4 is the first time anything on a machine changes. WP5 is the proof of the whole.
WP0 — The operator states the facts
The live mesh. An hour, and it is the operator's.
The account on each node record, through the controller's node command — none is stated today, and ADR 0181 refuses a home-scoped module without one. The role of each node, as the agent module's setting on the node layer, once the module exists. Which three licences exist and what each is called.
Proof. The controller's node command lists an account for every node.
WP1 — The console provides its endpoint
mesh-catalog. Half a day.
What changes. The console's manifest gains a node-scoped provision — working name
console-endpoint, fixed when the manifest is written — serving the port the machine gave it, as the
local model server already does for its API. Co-location resolves it
(ADR 0027,
to-be 34 as amended). When design 38's WP3 moves the console into the node-tools
module, the provision moves with it; it is a line in a manifest either way.
Proof. The controller's plan for a workstation shows a consumer of the provision bound to the console's port; the same consumer on a machine without the console is refused naming the provision; the catalogue's tests pass.
WP2 — The licence manager, built and tested
mesh-catalog. Two to three days; the largest package.
What is written, as design 39 says:
- The manifest. Claims the mesh-scoped seat
anthropic-licence-managerwith its verbs; requires a database, asecretfor the key its grants are encrypted with, and the bus; abundleof tools; aprocessfor the daemon that refreshes, collects usage and notifies, on a schedule; declared settings for the cadence, the usage threshold and the cooldown, each with a default;invokesthe agent module'sapply. - The store. Migrations for licences, bindings, usage and audit, with the lease and the notification slot as columns, numbered and idempotent.
- The refresh. The token-endpoint client and the sealed box from
anthropic-manager; the plan (floor, cadence, forced, cannot) and the lease from the predecessor, as pure functions with their tests; the vendor's reason logged on failure; counted failures, one notification per cooldown. - Adoption. From a file on the manager's node for the API key; from a sealed grant a node offers; the identity guard that refuses a mismatch and notifies.
- Usage. The vendor's reading per licence on a schedule, stored raw and normalised (ADR 0054), one notification per threshold crossing.
- The verbs:
licences,bindings,bind,switch,release,refresh,usage,adopt,register,current— the last answering a consumer's token sealed to the key that consumer registered. - The hand-over: on rotation or switch, one call to
claude-code.apply@<node>per bound node, the token sealed to that node's key, the answer recorded.
Proof, before anything runs live. Unit tests: two refresh runs started together rotate one grant once; a grant with a mismatching identity is refused; a worker bound to a dead licence is refused and never lent another; every event the daemon emits is free of a token; the hand-over payload opens only with the registered key. The catalogue's checks: no installation named, no secret in a declared file.
WP3 — The agent module, built and tested
mesh-catalog. Two days.
What is written, as design 36 says:
- The manifest. The agent's package; the state directory; the facts file carrying the node's
name, the operator account and its home, the console's bound port, the role and the extra tool
servers from settings; requires the console's endpoint and the bus;
usesthe seat andinvokesitsregister,currentandadopt; abundleof tools. No file resource under a home or under/etc. - The renderer. From the facts file and the current binding, the managed settings file (the tool
servers under the entry
mesh, the attribution trailers, and the key-helper for an API-key binding) and the managed instruction file (§3 of design 36), written under the agent's managed directory with the escalation the tool performs for itself; idempotent; re-run when the facts file changes. - The keypair, made once in the state directory, the public half registered with the seat at start and at every start.
- The consumer side:
apply(a rotation applied only if newer within one lineage, a switch applied regardless, the answer naming the outcome and never a token); the pull at start and near expiry; the credentials write as the operator, access-token-only, fromanthropic-consumerwith its tests; the key-helper program for the API key; the offer of a login to the seat, sealed, after reading the account's identity. - The tools:
apply,licence_status,mcp_configure(validates a server, sets the module's setting through the controller's settings verb),render(re-render now, for a person). - The documentation: the six predecessor files and the hand-made console entry a person removes on a workstation that carried the predecessor.
Proof, before anything runs live. Unit tests: the renderer writes only the mesh's keys and leaves every other key of a seeded settings file; the credentials write strips a refresh token and is atomic; the lineage comparison from the predecessor, with its cases; a login offer carries the identity it read. The catalogue's checks pass.
WP4 — The manager live on the control node
The live mesh. Half a day, after design 38's WP3.
Order. Assign the manager on the control node; push. Adopt the API key from a file there. Adopt the two subscription grants: a login in a throwaway home on the control node, offered to the seat the way a node's agent module will. Bind each node's agent to a licence.
Proof. Through the console: anthropic-licence-manager.licences lists three licences with
identity and expiry; within the cadence, the audit shows a rotation and licences shows a later
expiry; a forced refresh on one licence is logged with the vendor's answer; the two retired catalogue
modules are still assigned to nothing.
WP5 — The agent live on one workstation
The live mesh. Half a day. The proof of the whole.
Order. Set the workstation's role in the module's settings. Record the checksums of everything under the person's agent directory. Assign the module; push. Remove the six predecessor files and the hand-made console entry. Start a new session.
Proof. The managed directory holds the settings and instruction files, owned by root. Everything
under the person's agent directory is byte-identical to before except the credentials file, which is
owned by the operator, readable by nobody else, and names no refresh token. The new session lists the
mesh's tools under mesh once, answers which node am I from the instruction file, and makes a model
request. anthropic-licence-manager.switch to the second subscription licence changes the token on
the workstation within a minute, and neither the verb's answer nor either module's log holds a token.
Switched to the API-key licence, the credentials file is left as it was and the agent authenticates
through the key-helper. Switched back.
WP6 — The rest of the nodes, and the predecessor's remains
The live mesh and mesh-catalog. One day.
Order. Assign the module on the second workstation and on the servers whose account is stated;
remove the predecessor's files on the second workstation. Log in on a workstation under a licence's
account and watch the offer be adopted — and under the wrong account, and watch it refused and
notified. Retire anthropic-manager and anthropic-consumer from the catalogue. Set designs 36 and
39 to implemented for what runs, with the as-is written
(playbook 02).
Proof. Every node with an account runs the module and licence_status answers on each; the
refused login's notification arrived; the catalogue has no module built on the old placement.
What is deliberately not here
- The package repository seat for a distribution that does not carry the agent's package (design 36 §7). A fresh node refuses the module in the package manager's words until it exists.
- An automated switch on exhaustion. The readings are kept from WP4; the policy is a later record.
- Workers and the mesh's own sessions as consumers. The manager's bindings and fallbacks know them from WP2; the consumers themselves do not exist yet (to-be 15, ADR 0003).
- Whether a refresh token is single-use. WP4 may measure it on a licence deliberately refreshed twice; the design holds either way.
How this list is kept true
Each package's proof is run when the package is finished and its line here gains the date and the
commit, as design 38 does. A package whose proof fails is not reworded; the failure is recorded under
it and the package stays open. When WP5 is proven, designs 36 and 39 move to in-progress with their
owning repository, and when WP6 is proven to implemented, with the as-is written.