ADR 0213: the operator sets the agent's managed settings through the agent module
Rules for what the agent may do were set by hand per machine, invisible to the mesh, and a session cannot loosen its own permissions; design 36 now takes them as a module setting under the mesh's own keys.
This commit is contained in:
+71
@@ -0,0 +1,71 @@
|
||||
---
|
||||
topic: what runs on it
|
||||
status: accepted
|
||||
date: 2026-10-04
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
extends: 02-DECISIONS/0183-the-anthropic-licence-manager-is-a-module-and-hands-tokens-to-the-agent-over-the-bus.md
|
||||
---
|
||||
|
||||
# 213. The operator sets the agent's managed settings through the agent module, under the mesh's own keys
|
||||
|
||||
## Context
|
||||
|
||||
The agent module writes the agent's machine-wide managed settings file
|
||||
([to-be 36](../03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md) §2). It carries the mesh's
|
||||
own keys only: the attribution convention of its repositories, the connectors kept beside the managed
|
||||
tool servers, and the key-helper for an API-key licence. Every other key was left to the person's own
|
||||
settings, so that the mesh never reverts a person's choice on a push.
|
||||
|
||||
That left no place for a rule the **operator** wants to hold in every session on a machine: what the
|
||||
agent may do without asking, what it must never do, and what its unattended mode allows. These keys
|
||||
are not preferences. They are policy about what an agent may do on the mesh. Set by hand in one
|
||||
person's settings on each machine, they are unmanaged state the mesh cannot see, and the agent refuses
|
||||
to change them itself, as it should.
|
||||
|
||||
## Considered Options
|
||||
|
||||
1. **Leave them to each person's settings.** Rejected: policy by hand on each machine, invisible to
|
||||
the mesh, and a session cannot be asked to loosen its own permissions.
|
||||
2. **A field per vendor key** (permissions, auto mode, environment, hooks) in the module's settings.
|
||||
Rejected: the vendor adds keys, and every one would be a change to the module.
|
||||
3. **One setting holding managed-settings keys, laid under the mesh's own.** The operator sets it
|
||||
for the mesh or for one node through the controller's settings verb. The module copies its keys into
|
||||
the managed settings file, then lays the mesh's keys over them.
|
||||
|
||||
## Decision
|
||||
|
||||
Option 3.
|
||||
|
||||
1. The agent module takes a setting, `managed_settings`: an object in the vendor's settings shape. It
|
||||
is set for the whole mesh or for one node, like the module's other settings, through the
|
||||
controller's settings verb.
|
||||
2. The managed settings file is that object with **the mesh's keys laid last**: the attribution
|
||||
convention, the connectors kept beside the managed servers, and the key-helper. A setting can
|
||||
neither replace one of these nor add a key-helper that the binding did not ask for.
|
||||
3. Only the operator sets it, and it is declared state like the role and the extra tool servers. A
|
||||
person's preferences stay in their own settings; the mesh still sets none of them by itself.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The operator's rules for the agent are declared once, for the mesh or per node, and reach every
|
||||
node at the next push. A rule set in the managed settings outranks every other scope, so it holds
|
||||
in every session on the node.
|
||||
- A setting layer is replaced whole by the controller's verb. Setting this key without the role or
|
||||
the extra tool servers clears those in that layer; the module's documentation says so.
|
||||
- **What got harder:** a person cannot override a rule set here, which is the point. A rule that is
|
||||
wrong is wrong on every session of the node until the operator changes the setting.
|
||||
|
||||
## How it is checked
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| The operator's keys reach the managed settings file | the agent module's test: an auto-mode allow list and a permissions list set in the setting appear in the rendered file |
|
||||
| The mesh's keys always win | the same test: a setting naming the attribution, the connectors key or a key-helper is overridden, and a key-helper appears only for an API-key binding |
|
||||
| Live | the setting given for the mesh; the managed settings file on each node carries the key after the next push |
|
||||
|
||||
## References
|
||||
|
||||
- [ADR 0183](0183-the-anthropic-licence-manager-is-a-module-and-hands-tokens-to-the-agent-over-the-bus.md) — the agent module and the files it writes
|
||||
- [to-be 36](../03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md) — the design this amends (§2, §6)
|
||||
- the vendor's documentation on managed settings and their precedence
|
||||
@@ -311,6 +311,7 @@ python3 00-META/checks/index.py fail if stale
|
||||
- **0208** — [The graphical session is one module per piece, on the mesh's seats](0208-the-graphical-session-is-one-module-per-piece-on-the-meshs-seats.md)
|
||||
- **0209** — [A login on a node moves that node to the account it logged in to; an API key is added from any node, sealed](0209-a-login-on-a-node-moves-that-node-to-its-account-and-an-api-key-is-added-from-any-node-sealed.md)
|
||||
- **0211** — [A machine's power is a node seat, its moments take contributions, and its states are events](0211-a-machines-power-is-a-node-seat-its-moments-take-contributions-and-its-states-are-events.md)
|
||||
- **0213** — [The operator sets the agent's managed settings through the agent module, under the mesh's own keys](0213-the-operator-sets-the-agents-managed-settings-through-the-agent-module.md)
|
||||
|
||||
### How it is built
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: implemented
|
||||
status: in-progress
|
||||
code: [mesh-catalog modules/claude-code]
|
||||
updated: 2026-10-04
|
||||
decisions:
|
||||
- 02-DECISIONS/0213-the-operator-sets-the-agents-managed-settings-through-the-agent-module.md
|
||||
- 02-DECISIONS/0209-a-login-on-a-node-moves-that-node-to-its-account-and-an-api-key-is-added-from-any-node-sealed.md
|
||||
- 02-DECISIONS/0206-a-node-reports-the-anthropic-grant-it-holds-and-the-licence-manager-adopts-a-licence-by-refreshing-it.md
|
||||
- 02-DECISIONS/0181-the-operator-account-is-a-node-fact-and-a-home-is-a-placement-root.md
|
||||
@@ -50,7 +51,7 @@ instruction file and the manager's tools:
|
||||
|---|---|
|
||||
| `~/.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/settings.json`, merged | the managed settings file: the mesh's keys, and the rules the operator set for the agent (§2) |
|
||||
| `~/.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) |
|
||||
@@ -68,7 +69,7 @@ lists them, and until they go the agent reads stale instructions beside the mesh
|
||||
|
||||
**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
|
||||
role, the extra tool servers and the operator's managed-settings keys, 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
|
||||
@@ -79,7 +80,7 @@ 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 settings file | the keys the operator set in the module's `managed_settings` setting, with the mesh's keys laid over them: 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) |
|
||||
@@ -94,6 +95,14 @@ requires. The model, the spinner, the drafts and every other preference are 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.
|
||||
|
||||
**The operator's rules for the agent** ([ADR 0213](../../02-DECISIONS/0213-the-operator-sets-the-agents-managed-settings-through-the-agent-module.md)).
|
||||
What the agent may do without asking, what it must never do and what its unattended mode allows are
|
||||
not preferences: they are policy about an agent on the mesh, and a session must not loosen its own. The
|
||||
operator sets them in the module's `managed_settings` setting, in the vendor's settings shape, for the
|
||||
mesh or one node. The module copies those keys into the managed settings file and lays the mesh's keys
|
||||
last, so a setting can never replace the attribution convention, the connectors key or the key-helper,
|
||||
and a key-helper appears only for an API-key binding. The mesh still sets no preference by itself.
|
||||
|
||||
## 3. What the instruction file says
|
||||
|
||||
Prose, not a paste; the file is the module's.
|
||||
@@ -177,7 +186,8 @@ a token is fetched by request when the state says it changed.
|
||||
|
||||
**Every node with an operator account** ([ADR 0181](../../02-DECISIONS/0181-the-operator-account-is-a-node-fact-and-a-home-is-a-placement-root.md)).
|
||||
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.
|
||||
extra tool servers, and the operator's managed-settings keys (§2). The controller's verb replaces a
|
||||
setting layer whole, so a layer set for one of these keeps the others it already held. **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
|
||||
@@ -204,6 +214,7 @@ installer is rejected: it puts a self-updating binary under the person's home, i
|
||||
| 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 module's test: keys set in `managed_settings` (an auto-mode allow list, a permissions list) appear in the rendered managed settings file, a setting naming the attribution, the connectors key or a key-helper is overridden, and a key-helper appears only for an API-key binding | ADR 0213 |
|
||||
| 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](../../02-DECISIONS/0195-the-meshs-tools-are-found-by-address-not-announced-whole.md)) and answers "which node am I" from the instruction file | the exit of the build |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user