Awaited at import, a bucket not yet on the bus — or a grant the bus had not reloaded — answered after the runtime's 10s handshake, and the module was left unserved on its first assignment. Also cites module state as ADR 0201, as hq main numbers it (folds #256).
claude-code
The operator's agent on a machine (novox/hq design 36): its package, its machine-wide managed configuration, and the consumer side of the Anthropic licence manager (design 39, ADR 0183).
What it owns
Two directories, declared, so the mesh refuses a second module owning either:
/etc/claude-code, the agent's machine-wide managed directory, root's,0755.~/.claudeunder the operator account's home, the operator's,0700. The module owns the directory — that it exists, who owns it, its mode — and of what is inside only what it writes. Everything else in it (memory, history, projects, local settings, a person's own rules and skills) is the person's and is never read or written (hq ADR 0182). Unassigned, the module leaves the directory: the host removes a directory only when it is empty.
What it writes
Under the agent's managed directory, /etc/claude-code, owned whole by this module and rewritten
whenever the node's tool runtime collects the module's tools:
| file | holds |
|---|---|
managed-mcp.json |
the tool servers every session loads: the mesh's console as mesh, and the servers set in this module's mcp_servers setting. Exclusive: a server not listed here does not load — not one added with claude mcp add, not a project's .mcp.json, not a plugin's |
managed-settings.json |
the repositories' attribution convention, the claude.ai connectors kept beside the managed servers, and the key-helper while the node holds an API-key licence |
CLAUDE.md |
how a session on this mesh works, this node's name and role, the conventions |
Under the operator's home, only ~/.claude/.credentials.json, and only when the licence manager hands
this node a subscription token. Nothing else under the home is read or written.
Over NATS
Everything between this module and the rest of the mesh is NATS, in three kinds: an event says that something happened and carries no secret, because a stream keeps it; a request carries a token, because nothing keeps it (hq design 32 §10); and state is the current value of something every node must see, a node that joins later included — kept, so it carries no secret either (hq ADR 0201).
| what | how |
|---|---|
| the licence manager rotated a licence, or switched this node | its licence.rotated / licence.switched event; this module then asks anthropic-licence-manager.current for its token, sealed to the key it sends |
| this node starts | it asks current once, so a node that was off catches up |
a person ran /login here |
the credentials file gains a refresh token this module never writes; it asks anthropic-licence-manager.adopt at once with the grant sealed to the manager's key — the one time a refresh token travels, because the login made the manager's stale |
| an MCP server registered through this module | a key in the module's servers state — all.<server> for every node, <node>.<server> for one; every node watches it and renders what applies to it, a node's own entry over the one for every node. A node that joins later, or was off, reads the whole current set at start; unregistering is a delete. An entry with a secret in its env or headers is refused by the runtime |
Tools
claude_code_status, claude_code_render, claude_code_pull, claude_code_mcp_list,
claude_code_mcp_register (this node by default; nodes: "all" or a list for more — called for this
node alone, its answer names the other nodes running claude-code), claude_code_mcp_unregister.
Settings
Per node or for the whole mesh, through mesh-controller.settings module=claude-code:
role— what this node is, in a few words; shown to every session.mcp_servers— extra tool servers, set by the operator for the mesh or a node, beside the ones registered through the tools; keyed by name, in the vendor's.mcp.jsonentry shape ({"type":"http","url":…}or{"type":"stdio","command":…,"args":[…]}). The namemeshis the module's own and cannot be set. Put a person's own servers here, or they stop loading.
On a machine that carried the predecessor
Remove these by hand, once; the mesh removes nothing it did not make (ADR 0182):
~/.claude/CLAUDE.md~/.claude/rules/00-hal-mesh.md,~/.claude/rules/conventions.md~/.claude/skills/cleanup/,~/.claude/skills/hal-switch-license/- the hand-made console entry in
~/.claude.jsonundermcpServers— it is ignored now anyway
Escalation
Writing /etc/claude-code needs root. The runtime runs as the operator account, and the module uses
that account's passwordless sudo; on a machine without it, claude_code_render says so and nothing
is written.