Files
hq/03-DESIGN/01-to-be/40-building-the-operators-agent-and-its-licence-manager.md
T
jochen 8a5dbaeb98 To-be 40 revised for the tools refactor; the manager starts every exchange (ADR 0183 dated note, designs 36 and 39)
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.
2026-10-03 16:01:37 +02:00

14 KiB
Raw Blame History

layer, status, code, updated, decisions
layer status code updated decisions
to-be designed
2026-10-03
02-DECISIONS/0183-the-anthropic-licence-manager-is-a-module-and-hands-tokens-to-the-agent-over-the-bus.md
02-DECISIONS/0181-the-operator-account-is-a-node-fact-and-a-home-is-a-placement-root.md
02-DECISIONS/0182-inside-a-home-the-mesh-owns-what-it-places-and-holds-the-rest-as-found.md
02-DECISIONS/0175-one-tool-runtime-per-node-serves-every-modules-tools-on-the-host-side.md
02-DECISIONS/0188-a-modules-own-code-is-bundles-in-any-language-and-a-tools-bundle-speaks-mcp-to-the-runtime.md
02-DECISIONS/0192-a-tools-bundle-declares-what-it-is-given-and-the-runtime-hands-it-to-that-bundle-alone.md
02-DECISIONS/0149-the-live-mesh-is-the-test-bed.md
02-DECISIONS/0027-a-provision-names-what-the-consumer-is-coupled-to.md

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 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 machines, tools are bundles it serves and each is given only the words its artifact declares, and a bundle has no bus credential of its own. Three things in the first version of this plan changed with that: the wait on design 38's WP3 is over; the agent module calls nothing, so the manager starts every exchange (ADR 0183's dated note); and the manager's own process now waits on a different question, named under WP4.

How this is built, and where it is run

On the live mesh, by the operator's decision (ADR 0149). Every package is written with unit tests, committed on one branch per repository (playbook 07), and proven on the machines: one workstation first for the agent, the control node first for the manager, then the rest. 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 out of the failure's reach, 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

Measured 2026-10-03 on the four machines and in the repositories.

Piece Today Becomes
the node's tool runtime live on all four, a host process; runs as the operator account; listens for the console on loopback at a port its own code fixes; launches or imports every assigned module's tools bundle and hands each its declared words serves the agent module's tools; gains one provision for its endpoint (WP1)
the operator account stated on all four — the runtime runs as it read by the agent module from the runtime's own words
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
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 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)
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 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 order the work allows

WP0  the operator names the licences and each node's role   (the live mesh)   ── an hour
WP1  the runtime provides its endpoint                       (mesh-tools)       ── small
WP2  the agent module                                        (mesh-catalog)     ──┐ WP2 needs WP1;
WP3  the manager's code, built and tested                    (mesh-catalog)     ──┘ WP3 is independent
                                                                                  │
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)
WP5  the licence end to end on one workstation
WP6  the rest of the nodes, and the predecessor's remains

WP0 — The operator names the licences and each node's role

The live mesh. An hour, and it is the operator's. The accounts are stated already. What remains: the names of the two subscription licences and the API key; each node's role, as the agent module's setting on the node layer once the module is registered.

Proof. The module's settings list a role for every node; the licences have names.

WP1 — The runtime provides its endpoint

mesh-tools. An hour.

What changes. The node-tools manifest provides a node-scoped provision, mcp-endpoint, serving the port its code listens on, the way the local model server serves its API (ADR 0027). Co-location resolves it. The runtime's port stays what its code fixes; assigning it is issue 192's second question and not this package's.

Proof. The plan for a workstation carrying a consumer of mcp-endpoint shows it bound to the runtime's port; the controller's tests and the catalogue's checks pass.

WP2 — The agent module

mesh-catalog. A day and a half.

What is written, as design 36 says:

  1. The manifest. The agent's package. A state directory. A facts file in it, rendered by the mesh: the node's name and the console's address from mcp-endpoint. A settings file in it, merged from the module's settings layers: the node's role and the extra tool servers. A tools bundle whose words name the two files, the state directory and nothing else. No file resource under a home or under /etc.
  2. The renderer, run whenever the runtime collects the module's tools: from the two files, the managed settings file (the tool servers under the entry mesh, the attribution trailers, the key-helper for an API-key binding) and the managed instruction file, written under the agent's managed directory through the account's escalation, only when their content changed.
  3. The keypair, made once in the state directory; X25519 and an authenticated cipher from the language's own library, so the bundle carries no dependency.
  4. The tools: claude_code_status (what is rendered, what licence is held, when its token expires, fingerprints only); claude_code_render (render now); claude_code_public_key; claude_code_apply (a sealed token, applied only if newer within one lineage unless it is a switch; the credentials write as the operator, access-token-only, atomic; the key-helper program for an API key); claude_code_pending_login (a full grant found in the credentials file, sealed to the key the caller gives, with the account's identity).
  5. The documentation: the six predecessor files and the hand-made console entry a person removes.

Proof, before anything runs live. Unit tests: the renderer writes the mesh's keys and nothing else; it writes nothing when nothing changed; the credentials write strips a refresh token and is atomic; the lineage cases from the predecessor; a sealed hand-over opens only with the module's key; no tool's answer contains a token. The catalogue's checks pass.

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 byte-identical to before; a new session lists the mesh's tools under mesh and answers which node am 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.

WP3 — The manager's code, built and tested

mesh-catalog. Two to three days.

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 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 login with the identity guard; usage and its threshold; the visit — key, hand-over, waiting login — per bound node; the seat's verbs.

Proof, before anything runs live. Unit tests: two refresh runs started together rotate one grant once; a mismatching identity is refused; a worker bound to a dead licence is refused and never lent another; nothing the daemon emits carries a token; a hand-over sealed for one node opens with no other node's key.

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 process is given a bus credential and its subscriptions — because the daemon must call the agent module on every node. Until that record exists, nothing in this plan works around it: no tool container, no credential copied by hand.

Order. Assign the manager on the control node; push. Adopt the API key from a file there. Adopt the two subscription grants: a login on a workstation carrying the agent module, collected by the manager's visit. 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 a later expiry; a forced refresh is logged with the vendor's answer.

WP5 — The licence end to end on one workstation

The live mesh. Half a day. The proof of the whole.

Order. Record the checksums under the person's agent directory. Bind the workstation to a subscription licence. Remove the six predecessor files and the hand-made console entry. Start a session.

Proof. Everything under the person's agent directory is byte-identical but the credentials file, which is owned by the operator, readable by nobody else, and names no refresh token. A session makes a model request. 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, 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. The module on every node, the predecessor's files removed on the second workstation; a login under a licence's account collected and adopted, and one under the wrong account refused and notified; anthropic-manager and anthropic-consumer retired from the catalogue; designs 36 and 39 set to implemented with the as-is written (playbook 02).

Proof. claude_code_status answers on every node; the refusal'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). The four machines have the package; a fifth would refuse the module in its package manager's words.
  • Escalation as a checked fact. The agent module's write under /etc relies on the operator account's passwordless sudo, true on all four and checked by nothing. A machine without it refuses the render in the tool's own words; making escalation a reported capability is design 38's to decide.
  • 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 knows them from WP3; the consumers do not exist yet (to-be 15).
  • Whether a refresh token is single-use. WP4 may measure it; 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 WP2's live proof runs, design 36 moves to in-progress with its owning repository; when WP5's does, design 39 does too; and when WP6's does, both move to implemented, with the as-is written.