Issue 340: the home scope reached the operator's own home, and bus text still renders

The confirmation review found the home scope wrote the operator's own
~/.claude on nodes where the agent is the operator, and that text put
straight on the bus at the mesh or node scope still renders; record both,
the fix for the first, and what closes the second.
This commit is contained in:
jochen
2026-10-09 09:43:03 +02:00
parent 8a6f19e457
commit 523bb9c55a
2 changed files with 45 additions and 7 deletions
@@ -72,7 +72,8 @@ own settings file. It does not see a tool call that changes the managed files of
`"trusted": false` takes its settings at the controller's terminal alone.
2. **Shared agent text is the terminal's, for now.** Instruction sections, output styles, skills, commands and
subagents for every node or some are set at the controller's terminal, in the agent module's settings, and
refused through the tools. A person's own home stays free. In the operator's words: "once we build a UI, we
refused through the tools. A person's own home stays free where it is an agent account's own; the
operator's own home is not written from the tools (see "How it is checked"). In the operator's words: "once we build a UI, we
can also update the context through it". A surface of the operator's own, which can tell the operator from
an agent, is the intended way back.
3. **Passwords are not settings.** They come from the key vault and can be rotated. Every module found taking
@@ -80,6 +81,15 @@ own settings file. It does not see a tool call that changes the managed files of
[issue 342](../342-a-password-is-taken-as-a-setting-and-outranks-the-vaults/00-report.md), to move to
vault-held secrets, not to stay terminal-only settings.
## Still open after these pull requests
- Text at the mesh or node scope written straight into the bus state still renders. It needs a tool runner's
credential. It closes once the three instruction sections are set at the terminal and text is no longer
rendered from the bus.
- The tool servers left on the bus stop rendering with their own pull request, after the laptop's tool server
is set at the terminal.
- Passwords taken as settings: [issue 342](../342-a-password-is-taken-as-a-setting-and-outranks-the-vaults/00-report.md).
## Ordering
**This must land before ADR 0266's agent account is switched on** (hq pull request 225). Until it lands, the
@@ -110,7 +120,9 @@ at the controller's terminal. An agent's attempt through any mesh tool is refuse
the module's `managed_settings`, `mcp_servers` or `role` through the `settings` verb, for one machine or
the mesh, and through the `command` verb, is refused with an error naming this issue. Text for every node or
some, of each kind, is refused through the tools and the import tool, and lands when set in the module's
settings at the terminal; the home scope is still registered. So is a new `url` on a
settings at the terminal. The home scope is refused for any node but the one serving the call, and there
wherever the home is the operator's own; it is taken only where the home is an agent account's own, and a
home item on the bus is never placed in the operator's home. So is a new `url` on a
module whose mergeable runtime configuration starts empty, while a file marked `"trusted": false` stays the
verb's. The layer is
unchanged after every refusal. At the terminal the same is taken. These tests fail on the commit before
@@ -38,10 +38,11 @@ documentation of skills, subagents, plugins, output styles and memory, read 2026
| output style, instructions, rule file | the plugin, the managed instruction file, a home | text the model reads; no field runs anything | still registered |
| a script beside a skill | the plugin, or a home | only when the agent runs it, through the session's own rules and the guard | still registered |
**Text is a lower class, and stays registrable through a verb. This is a risk, and it is the operator's to
take or close.** At the mesh and node scopes, an instruction section, an output style, and a skill, command or
subagent without the fields above are still registered through the module's tools, so any caller of the mesh
MCP server can register them, an agent confined on the control node included. They reach every session on the
**Text is a lower class. As the review first left it, it was still registrable through a verb, which was a
risk for the operator to take or close; the operator closed it (below).** Before that decision, at the mesh and
node scopes, an instruction section, an output style, and a skill, command or subagent without the fields above
were still registered through the module's tools, so any caller of the mesh
MCP server could register them, an agent confined on the control node included. They reach every session on the
nodes they name, as text the model reads:
- the instruction sections land in the managed instruction file, which every session reads first and treats
@@ -60,9 +61,30 @@ repository, a tool's answer).
**The operator decided on 2026-10-09: this text is the terminal's, for now.** At the mesh and node scopes every
kind is refused through the tools and set at the controller's terminal. The home scope, one account's own
directory, stays registrable. In the operator's words: "once we build a UI, we can also update the context
directory, stays registrable where that account is an agent's own (the next section). In the operator's words: "once we build a UI, we can also update the context
through it". A surface of the operator's own, which knows who is using it, is the intended way back.
### The home scope reached the operator's own home
The confirmation review found the home scope a way round the rest. `scope: home` takes a list of nodes. On the
laptop, the workstation and the home server the agent runs as the operator, so the home there is the operator's
own `~/.claude`, and its `rules/` and `skills/` load in every session the operator starts. An agent on the
control node could reach it two ways: by naming those nodes in `nodes`, or by addressing the other node's own
tool (`<node>/claude-code.<tool>`), which serves it there as if the operator had called.
The fix, in the module:
- the home scope is taken only for the node whose module serves the call, and only where its home belongs to an
agent account of its own: the agent runs there as an account that is not the operator's (ADR 0266), and the home
the module writes is that account's. Any other node is refused, because whose home it is cannot be judged from
elsewhere; that node's own module judges it;
- a home item on the bus is never placed in the operator's own home, whoever put it there, and what the module
placed there before is taken back unless the person changed it;
- every node a call names is judged before anything is put, and a list naming one refused node is refused whole.
Until ADR 0266's account is switched on, no node has an agent account of its own, so the home scope is refused
everywhere. Nothing is registered at the home scope today.
### The routes that write the same files
- **The module's tools**: refused (below).
@@ -78,6 +100,10 @@ through it". A surface of the operator's own, which knows who is using it, is th
through the tool runner's credential. On the control node, under ADR 0266, the agent account cannot read
it. On the other nodes an agent runs as the operator already. The module still judges every item it takes
from the state, so a hook, settings or an item that runs something is never rendered, whoever put it there.
**A gap stays open here:** the item check (`Problem`) refuses hooks and settings at every scope, but text at the
mesh or node scope is refused only by `Register`, the tools' path. Text put straight into the state at those
scopes still renders. Doing so needs a tool runner's credential, as with the tool servers. What closes it: the
three instruction sections set at the controller's terminal, then text no longer rendered from the bus.
- **The `nox-mesh` plugin** is the module's own render. It carries the guard's hook and nothing else that runs.
### The fix