Files
hq/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md
T
jochen e3755d5b60 There is no home-scoped module: ADR 0181 and 0182 say so as progressive insights; design 36 and to-be 40: the module declares the two directories it owns
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).
2026-10-03 23:50:06 +02:00

17 KiB

layer, status, code, updated, decisions
layer status code updated decisions
to-be designed
2026-10-03
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/0183-the-anthropic-licence-manager-is-a-module-and-hands-tokens-to-the-agent-over-the-bus.md
02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md
02-DECISIONS/0155-a-definition-names-no-installation-and-how-that-is-checked.md
02-DECISIONS/0152-the-operators-surface-is-a-module-the-console.md
02-DECISIONS/0027-a-provision-names-what-the-consumer-is-coupled-to.md
02-DECISIONS/0109-a-package-registry-seat-is-one-per-ecosystem.md
02-DECISIONS/0175-one-tool-runtime-per-node-serves-every-modules-tools-on-the-host-side.md

36 — The operator's agent on a machine: the claude-code module

The agent a person runs at a terminal, put on the machine by the mesh, instructed by the mesh, pointed at the console, and holding the licence the manager hands it. It is a member of the family to-be 29 §2 names, the modules that touch a person's machine, and its counterpart is 39 — The Anthropic licence manager.

What it replaces: the predecessor's module of the same name and a sibling, which placed six files under the operator's home. The predecessor is retired; the six files are still on both workstations telling every session to use tools that no longer exist.

Three rules shape everything below. The host is module-agnostic: it installs the package and gives the module a state directory, and knows no vendor, no agent, no path under a home. The controller has no part beyond resolving what it resolves for every module. And the module handles its own files: the mesh's part of the agent's configuration is written by the module's own code, from what the mesh delivered it and what the manager handed it.

1. Where the mesh's configuration lives: the agent's managed directory, not the home

The agent reads a machine-wide, administrator-owned configuration directory under /etc, documented by the vendor: a managed settings file that outranks every user and project setting; a key in it that adds HTTP tool servers beside a person's own without blocking them; and a managed instruction file every session reads before the user's and the project's. The agent has no machine-wide directory for rules, skills, slash commands or hooks; those exist only under a home or a project.

So the mesh's part of the agent's configuration lives there, owned whole by the module, and the home is left alone. What the predecessor shipped as two rule files and two skills folds into the managed instruction file and the manager's tools:

the predecessor placed becomes
~/.claude/CLAUDE.md the managed instruction file: how a session on this mesh works (§3)
~/.claude/rules/00-hal-mesh.md, ~/.claude/rules/conventions.md sections of the same file: this node's identity, the repositories' conventions
~/.claude/settings.json, merged the managed settings file: the mesh's keys only, outranking nothing a person did not also set
~/.claude/skills/hal-switch-license/SKILL.md the manager seat's switch verb, listed by the console, and a sentence in the instruction file saying to use it
~/.claude/skills/cleanup/SKILL.md nothing; it named the predecessor's forge
the console's entry in the agent's user-scope state the managed settings' tool-server key, from the console's provision (§4)

The home. Under ADR 0182 the module owns the directory ~/.claude — that it exists, that the operator owns it, its mode, 0700 — and declares it, so the mesh refuses a second module owning it. Of what is inside, it owns only the agent's credentials file, which its own code writes for a subscription licence (§5); every other path is found. The person's memory, history, projects, local settings, their own rules, skills and tool servers are never read or written by the mesh. The six predecessor files are the operator's to remove, once, on each workstation; the module's documentation lists them, and until they go the agent reads stale instructions beside the mesh's.

2. What the module declares and what its code writes

Declared, applied by the host: the agent's package (§7); the module's state directory; a facts file in that directory carrying the node's name and the console's endpoint, and a settings file carrying the role and the extra tool servers, merged from the module's settings layers — the bundle is told the two files' paths, because a bundle's words are paths and constants only (ADR 0192); the bus, the console's provision, and that it uses the anthropic-licence-manager seat. Two directories, declared so the ownership check sees them: the agent's managed directory under /etc, root's, and ~/.claude under the operator's home, the operator's. No file resource under either: what is in them is written by the module's code (§2 below) or is the person's.

Written by the module's code, from the facts file and the manager's hand-over, whenever either changes:

path content
the managed settings file the mesh's keys: the tool servers (the console, plus any the operator declared as settings), the attribution trailers, and — for an API-key binding only — the key-helper that serves the key
the managed instruction file §3
the agent's credentials file under the operator's home for a subscription binding only: the access token the manager handed over, as the operator, readable by the operator alone, atomic, no refresh token
the module's keypair in its state made once, the private half never leaves (§5)

Writing under /etc and as the operator under the home are two escalations the module's code performs for itself; the mesh does not run the module as root for everyone, and the caller does not know (ADR 0175).

Which settings keys are the mesh's. A key is the mesh's when it encodes a rule of the mesh: the tool servers that reach the mesh, the attribution convention of its repositories, the key-helper a binding requires. The model, the spinner, the drafts and every other preference are the person's, and the predecessor's experience with the model key is the evidence: a mesh that sets a preference reverts a person's choice on every push.

3. What the instruction file says

Prose, not a paste; the file is the module's.

How a session on this mesh works. The console is the only path to the mesh, and its tools are the vocabulary: the record is asked through the records module, symptom first — the literal error text before a hypothesis (ADR 0153); the mesh is asked and changed through the controller seat's verbs; the forge through the forge module's tools; a licence through the anthropic-licence-manager seat's verbs, never by editing a file. The hard rules in new words: a file the mesh manages is changed through the verb that owns it or through the catalogue, never on disk; a store's database is never written by hand; main is never pushed; the mesh creates no symlinks and nobody else does; a package is declared, not installed by hand. The glossary's words, none of the predecessor's.

Who this node is. The node's name, from the facts file; the node's role, from the module's settings on the node's layer; and that the other nodes are asked of the controller's nodes verb rather than listed here, because a table is a copy that drifts.

The repositories' conventions. Concise commit messages in the imperative, about why; a branch, a pull request and a human approval for every merge; test before pushing, because nodes update unattended; the playbooks in the record.

4. The console

Revised 2026-10-03, building it. The vendor's managed-settings key for tool servers refuses any URL that is not https://, including one on loopback, so it cannot carry the console. The module owns the vendor's exclusive managed tool-server file instead (operator's choice): the console as mesh, over HTTP on loopback, and every server in the module's mcp_servers setting — and no other. A server added by hand, a project's own file and a plugin's servers stop loading; claude.ai's connectors are kept by a managed setting. A person's own servers move into the setting, for the mesh or for one node. Stdio straight to the bus, through the runtime's own client, was weighed and left for later: it needs a verb the delivered runtime does not have, and a session holding its own bus connection breaks on a credential rotation.

Other tool servers a person wants on every machine, or on one, are a declared setting of this module — mesh layer or node layer — rendered into the same managed file. The person sets them with the controller's settings verb on this module, so the list stays declared state; the list is the operator's choice, set where every setting is set. The agent's own HTTP-only constraint for managed servers applies; a person's local command-based servers stay their own, in their own file.

The entry's name is mesh. The hand-made entry both workstations carry today is named after this installation, which a definition may not be (ADR 0155); it is the person's to remove, and until then the agent sees the mesh's tools twice.

5. The licence: the consumer side

ADR 0183 decides it; to-be 39 is the manager's half. This module:

  • makes a keypair in its state the first time it runs, and answers claude_code_public_key with the public half when the manager asks;
  • serves apply: the manager's hand-over, a token sealed to the module's key, with the licence's name and kind. A rotation of the same licence is applied only if newer within one lineage; a switch is applied regardless, because across licences the expiries are unrelated. The answer says applied or refused and why, and never echoes a token;
  • is reconciled, never pulls: the manager asks every bound node on a schedule and after every rotation, so a node that was away receives its token when it is back; between visits it keeps the last token, and licence_status says how long it has left;
  • writes for a subscription licence the credentials file as the operator, access-token-only; for the API-key licence sets the key-helper in the managed settings to a small program that prints the key from the module's state, so no file under the home is touched;
  • holds a login for the manager to collect: when the credentials file holds a full grant it did not write — a person logged in — it answers claude_code_pending_login, when the manager asks, with the grant sealed to the key the manager gives in its request and the account's identity read from the agent's state file; the manager decides, and the next hand-over strips the refresh token;
  • serves licence_status: which licence and kind this node holds, when the token expires, whether the file matches what was handed over — by fingerprint, never by value.

Switching is the seat's switch verb, asked through the console; this module only applies what it is handed. 2026-10-03: every exchange is started by the manager, by the operator's direction (ADR 0183's dated note); this module is a bundle the node's runtime launches over stdio and answers what it is asked (ADR 0193). The tool names follow the catalogue's <module>_<verb> form.

6. Scope, settings and the order of assignment

Every node with an operator account (ADR 0181). All four nodes carry one since 2026-10-03. Per node: the role. Per mesh or per node: extra tool servers. Prerequisite: the manager holds its seat and has adopted the licences.

Order: the manager assigned and a refresh observed; the console's provision in the catalogue; this module on one workstation; the six predecessor files and the hand-made console entry removed there; a new session read to confirm it sees the mesh's instruction file, the console's five tools under mesh, and its licence; then the rest.

7. The package

The module declares the agent's package. The distribution every node runs does not carry it in its repositories: the two workstations have it from a build the predecessor's helper made from the community repository, and nothing updates it since. On those two the declaration is satisfied. On a fresh machine the host's package manager refuses it, in its own words, and the module is not applied there. The answer is a package repository for this ecosystem as a seat (ADR 0109), fed by the builder and trusted by every node's package manager; not built, and not this module's to build. The vendor's own installer is rejected: it puts a self-updating binary under the person's home, invisible to the mesh.

How it is checked

Check Defends
the module's definition names no node, path or login, declares no file under a home or /etc (only the two directories), and no file resource carries a secret ADR 0112, ADR 0155, ADR 0183
on a lab machine with an account and a seeded home holding a person's rule file and the predecessor's leftovers: after assign, the managed directory holds the mesh's files, the home is byte-identical except the credentials file, which is owned by the operator and names no refresh token; after unassign, the managed directory's files are gone and the home is untouched ADR 0182, the host's agnosticism
on a lab machine with no account, the assignment is refused naming the fact ADR 0181
a switch asked of the seat through the console changes the licence and the token on the node; no tool answer and no log line holds a token ADR 0183
the API-key binding writes nothing under the home and the agent authenticates through the helper ADR 0183
the console's provision resolves by co-location; a machine without the console refuses the module by name ADR 0027, ADR 0152
a new session on the assigned workstation lists the console's five tools under mesh (ADR 0195) and answers "which node am I" from the instruction file the exit of the build

What this does not settle

  • Several operator accounts on one node (ADR 0181 decides one).
  • A worker's own licence on a machine. Every interactive session shares the node's one agent directory and its licence, however many run. A worker runs from a home of its own with an agent directory in it, bound to its own licence through the manager (to-be 39 §5); that is for when workers exist, and nothing here changes for it.
  • The package repository seat (§7).
  • How the module's tools are run is decided: the node's tool runtime, host-side (ADR 0175). The managed files and the credential write are tools of this module that runtime serves. Until the runtime exists on every node, the module's code runs as a supervised process of its own (ADR 0150), which changes nothing in what it writes.

References