Files
hq/03-DESIGN/01-to-be/40-building-the-operators-agent-and-its-licence-manager.md
T
jochen 6e306fcb4c To-be 40: building the operator's agent and its licence manager as work packages
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.
2026-10-02 17:26:48 +02:00

15 KiB
Raw Blame History

layer, status, code, updated, decisions
layer status code updated decisions
to-be designed
2026-10-02
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/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 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:

  1. The manifest. Claims the mesh-scoped seat anthropic-licence-manager with its verbs; requires a database, a secret for the key its grants are encrypted with, and the bus; a bundle of tools; a process for 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; invokes the agent module's apply.
  2. The store. Migrations for licences, bindings, usage and audit, with the lease and the notification slot as columns, numbered and idempotent.
  3. 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.
  4. 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.
  5. Usage. The vendor's reading per licence on a schedule, stored raw and normalised (ADR 0054), one notification per threshold crossing.
  6. 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.
  7. 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:

  1. 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; uses the seat and invokes its register, current and adopt; a bundle of tools. No file resource under a home or under /etc.
  2. 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.
  3. The keypair, made once in the state directory, the public half registered with the seat at start and at every start.
  4. 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, from anthropic-consumer with 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.
  5. 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).
  6. 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.