ADR 0273: the agent's home is the module's, and the operator's personal rules and lessons are registered through it
Research 040 measured the homes on four nodes: a skill retired a week ago on all four, the operator's rules on one, nothing raised. The module now owns every configuration file under the agent's home, excludes the program's working state by name, and raises agent-home-drift on a hand edit; a fourth scope carries the operator's personal rules to every node; an agent proposes a lesson when corrected and the operator accepts it at the terminal or on a warrant. To-be 36 §10 and to-be 40 WP7–WP10 say what is built; ADR 0216 and 0243 gain notes.
This commit is contained in:
@@ -495,6 +495,15 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272.
|
||||
of them (a path, an address); opened with `detail` only on a `private` channel or through the mesh MCP server.
|
||||
- **agent** — a coding agent: the operator's, or one the mesh runs. Not the node-engine, and not the
|
||||
build seat's holder, whose seat name `node-build-agent` is an identifier to rename.
|
||||
- **personal rule** — one short text in the operator's own words about how the operator wants their agent
|
||||
to work with them, registered for the operator (the **operator scope** of the agent module) and rendered
|
||||
into the agent's home on every node that names an operator account. Not a mesh-wide instruction section,
|
||||
which is the mesh's word about the mesh, set at the controller's terminal
|
||||
([ADR 0273](../02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md)).
|
||||
- **lesson** — an agent's proposal, recorded when the operator expresses frustration or corrects a way of
|
||||
working: the trigger (the operator's words), the cause (what the agent did) and the rule that would
|
||||
prevent it. A lesson is `proposed`, `accepted` or `declined`; an accepted lesson is a personal rule, and a
|
||||
proposed one is never read as one (ADR 0273).
|
||||
|
||||
## The record — how this repository works
|
||||
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
---
|
||||
status: graduated
|
||||
initiated: 2026-10-09
|
||||
touches:
|
||||
- 03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md
|
||||
- 03-DESIGN/01-to-be/40-building-the-operators-agent-and-its-licence-manager.md
|
||||
- 03-DESIGN/00-as-is/15-the-agent-and-its-licences.md
|
||||
- 02-DECISIONS/0216-the-agents-configuration-is-registered-through-its-module-at-three-scopes-and-served-as-one-plugin.md
|
||||
- 02-DECISIONS/0182-inside-a-home-the-mesh-owns-what-it-places-and-holds-the-rest-as-found.md
|
||||
- 02-DECISIONS/0243-the-agent-module-removes-a-home-item-it-did-not-place-only-on-the-persons-word-and-keeps-a-copy.md
|
||||
- 02-DECISIONS/0245-a-verb-says-what-it-replaces-and-the-agent-is-guarded-from-working-round-the-mesh.md
|
||||
- 02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md
|
||||
- 04-ISSUES/340-an-agent-can-plant-a-hook-in-every-agent-session-on-the-mesh/00-report.md
|
||||
became:
|
||||
- 02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md
|
||||
- 03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md
|
||||
---
|
||||
|
||||
# 040 — The agent's home is the module's, and the operator's rules and lessons are registered through it
|
||||
|
||||
## What
|
||||
|
||||
Three things about the coding agent's own directory under a person's home (`~/.claude`), investigated
|
||||
together because the operator raised them as one on 2026-10-09:
|
||||
|
||||
1. **Who owns the configuration files in that directory.** [ADR 0216](../../02-DECISIONS/0216-the-agents-configuration-is-registered-through-its-module-at-three-scopes-and-served-as-one-plugin.md)
|
||||
gave the agent module a home scope that "owns only what it placed"; everything else there is held as
|
||||
found ([ADR 0182](../../02-DECISIONS/0182-inside-a-home-the-mesh-owns-what-it-places-and-holds-the-rest-as-found.md)).
|
||||
The operator's direction reverses that for the configuration: *"the home-scope does own ~/.claude, so
|
||||
it should be completely empty and manual edits should be forbidden."*
|
||||
2. **Whose the rules in that directory are.** The rule files a person writes there today are the
|
||||
person's own, on one machine. The operator's direction: *"Rules in my home directory are my 'personal
|
||||
rules' which should also end up under control of the claude-code module and all other changes to
|
||||
~/.claude should go through the claude-code module's mcp tools."*
|
||||
3. **How an agent learns from a correction.** The operator's direction: *"register the decision, but make
|
||||
sure it's clear and that you can/should be pro-active about it. For example, if I'm frustrated, try to
|
||||
see why and try to prevent it in the future by warning yourself about stuff not to do to frustrate me
|
||||
— kind of like a self-learning process."*
|
||||
|
||||
## Why
|
||||
|
||||
The home is the one place the agent's configuration still drifts. [01](01-what-the-home-holds-and-the-options.md)
|
||||
measured it on 2026-10-09 across the four nodes: a skill to-be 36 retired in its first version is still on
|
||||
all four; a person's instruction file is on three; the operator's two hand-written rules are on one; and
|
||||
nothing in the mesh places, watches or raises anything about any of it. The corrections the operator has
|
||||
given the agent live in the agent's own memory for one repository on one machine, 45 notes of which at least
|
||||
9 are a correction of a way of working, shown to nobody and reaching no other node.
|
||||
|
||||
[Issue 340](../../04-ISSUES/340-an-agent-can-plant-a-hook-in-every-agent-session-on-the-mesh/00-report.md)
|
||||
closed the tools' route into the operator's home for the right reason: a tool cannot tell the operator from
|
||||
an agent, so an agent could plant something every session obeys. Whatever owns the home must keep that
|
||||
protection. The two routes the mesh now has for the operator's own word, the controller's terminal
|
||||
([ADR 0272](../../02-DECISIONS/0272-the-operator-reaches-the-controller-with-mesh-cli-on-every-node-and-a-node-is-the-terminal-only-where-no-agent-runs-as-its-operator.md))
|
||||
and a warrant on an ask ([ADR 0259](../../02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md)),
|
||||
make it possible to write into the operator's home without trusting a tool's caller.
|
||||
|
||||
The record was searched first: `records_search` for "personal rules lessons frustration self-learning" and
|
||||
for "hand edit home .claude drift condition" found nothing on 2026-10-09.
|
||||
|
||||
## What it touches
|
||||
|
||||
- **The agent module's design** ([to-be 36](../../03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md)
|
||||
§1 and §8): what under the home is the module's, and the scopes.
|
||||
- **ADR 0216 §5 and §6** (the home scope owns only what it placed; what it did not place is reported) and
|
||||
**ADR 0243** (removal on the person's word): the mechanism changes, the decisions stand.
|
||||
- **ADR 0182**: the class table holds; what changes is which class the configuration files are in.
|
||||
- **ADR 0245**: the guard gains a refusal, and the session gains a reminder.
|
||||
- **ADR 0259**: the module becomes an asker, for the operator's yes.
|
||||
- **Issue 340**: the protection stands; the terminal and the warrant are the two ways in.
|
||||
|
||||
## Documents
|
||||
|
||||
- [01 — What the home holds, and the options](01-what-the-home-holds-and-the-options.md): the measurement
|
||||
on four nodes, the agent's own memory as it stands, and the options weighed.
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
# 040 — What the home holds, and the options
|
||||
|
||||
## 1. The agent's directory on the laptop, 2026-10-09
|
||||
|
||||
Read by name on the laptop's own disk, contents not read. The directory holds 33 entries.
|
||||
|
||||
**Configuration, written by a person or by the program on a person's choice:**
|
||||
|
||||
| path | what | how it got there |
|
||||
|---|---|---|
|
||||
| `rules/` | 2 rule files (1779 and 755 bytes): how text meant to be pasted elsewhere is handed over; how git is used in a second forge's repositories | written by hand |
|
||||
| `skills/` | 5 skills of the operator's own, for the operator's other work; and `skills/synced/`, 2 folders the vendor's own sync placed | by hand; by the program |
|
||||
| `commands/` | empty | — |
|
||||
| `settings.json` | 6 keys: the attribution, auto mode, feedback drafts, the model, the spinner tips, the model switch on a flag | by hand, and by the program on a `/model` or `/config` choice |
|
||||
| `settings.local.json` | 1 key, `permissions`: the rules the program writes when a person answers "always allow" in a session | by the program, on a person's answer |
|
||||
| `plugins/` | the program's record of its marketplaces (the vendor's and the mesh's `nox-mesh`) and installed plugins, and its cache | by the program |
|
||||
| no `CLAUDE.md`, no `agents/`, no `hooks/` | the instruction file was removed on 2026-10-07 through the module's removal tool, with a copy kept (ADR 0243) | — |
|
||||
|
||||
**Working state, written by the program for itself** (24 entries): the credentials file (the module's own
|
||||
code writes it, ADR 0183), `history.jsonl` (5 MB), `projects/` (30 directories, 1.5 GB, holding every
|
||||
project's sessions and the agent's own memory), `sessions/`, `session-env/`, `shell-snapshots/`,
|
||||
`file-history/`, `debug/`, `cache/`, `paste-cache/`, `telemetry/`, `stats-cache.json`, the daemon's lock,
|
||||
log and status files, `state/`, `ide/`, `jobs/`, `feedback/`, `backups/`, `worktrees/`, and a few markers.
|
||||
|
||||
**The managed directory under `/etc`**, by contrast, holds exactly what the module renders: the instruction
|
||||
file, the managed settings, the managed tool-server file, and the marketplace with the `nox-mesh` plugin.
|
||||
|
||||
## 2. The homes on four nodes, 2026-10-09
|
||||
|
||||
Read through each node's `claude_code_config_status` (the module's own status tool), the field listing the
|
||||
home's own items beside what the mesh placed:
|
||||
|
||||
| node | home items the mesh did not place | placed by the mesh at home |
|
||||
|---|---|---|
|
||||
| the laptop | 2 rule files, 5 skills | none |
|
||||
| the workstation | an instruction file, a `cleanup` skill, a subagent (a module reviewer) | none |
|
||||
| the home server | an instruction file, a `cleanup` skill | none |
|
||||
| the control-node | an instruction file, a `cleanup` skill | none |
|
||||
|
||||
Three things follow:
|
||||
|
||||
- **The retired skill is still everywhere.** To-be 36 §1 said on 2026-10-02 that the `cleanup` skill
|
||||
becomes "nothing; it named the predecessor's forge". It is on all four nodes on 2026-10-09. Nothing
|
||||
owns it, so nothing removed it.
|
||||
- **The operator's rules exist on one node.** A rule about how the operator wants text handed over is as
|
||||
true on the workstation as on the laptop. It is on the laptop alone, because the only way to put it
|
||||
anywhere is to write the file there.
|
||||
- **Nothing is raised about any of it.** The status tool lists these items when asked. No condition says
|
||||
the laptop's rules are missing elsewhere, or that a skill the design retired is still loaded in every
|
||||
session on four machines. The three mesh-wide instruction sections and the `nox-mesh` plugin (holding
|
||||
the guard alone) are the only things the mesh renders for a session, and both are in the managed
|
||||
directory, not the home.
|
||||
|
||||
## 3. The agent's own memory, 2026-10-09
|
||||
|
||||
The agent keeps notes for itself in the program's memory directory under `projects/` for one repository
|
||||
on the laptop: 45 notes on 2026-10-09. At least 9 of them are a correction of a way of working that the
|
||||
operator gave in a session, for example: finish a module before pushing it; use the mesh's tools, not
|
||||
ssh; read the merge gate's verdict before merging; what is done is what the operator sees working;
|
||||
no work-arounds when a tool is missing; a language choice the operator insists on. Each was learned once,
|
||||
after the operator said it, sometimes with irritation.
|
||||
|
||||
Those notes:
|
||||
|
||||
- are on one machine, for one repository: a session on the workstation, or in another repository on the
|
||||
laptop, starts without them;
|
||||
- are written by the agent for itself, in its own words, and shown to nobody: the operator cannot see
|
||||
what the agent taught itself, or correct it;
|
||||
- are not read before a tool runs: a note saying "read the merge gate first" is read at session start,
|
||||
if the agent opens it, and nothing says it again at the moment a merge is about to be called.
|
||||
|
||||
The mesh keeps one related record: the guard's record of every refusal and override
|
||||
([ADR 0245](../../02-DECISIONS/0245-a-verb-says-what-it-replaces-and-the-agent-is-guarded-from-working-round-the-mesh.md) §5),
|
||||
which is how a habit that found a way round is seen. It records what the guard refused, not what the
|
||||
operator corrected.
|
||||
|
||||
## 4. What the vendor loads from the home
|
||||
|
||||
As documented by the vendor and confirmed on the laptop on 2026-10-09 (a session's own context names the
|
||||
two rule files as "the user's private global instructions for all projects"): the home's `CLAUDE.md` and
|
||||
every file under `rules/` are read into every session the account starts, in every project; `skills/`,
|
||||
`commands/` and `agents/` are offered under their own names; `settings.json` is the account's settings,
|
||||
below the managed settings; hooks come from `settings.json` and from a plugin. None of it is read for
|
||||
another account, and none of it reaches another machine.
|
||||
|
||||
## 5. The options
|
||||
|
||||
### Who owns the configuration under the home
|
||||
|
||||
1. **As today: the module owns what it placed, the rest is found** (ADR 0216 §5, ADR 0182). Rejected by
|
||||
the operator's direction, and by §2: a rule on one node reaches no other, a retired skill stays on
|
||||
four, and nothing is raised. There is a second reason: the guard refuses an agent that reaches a
|
||||
machine by ssh, and refuses nothing that writes `~/.claude/rules/x.md`. On a node where the agent
|
||||
runs as the operator, that is a rule planted in every later session, by hand, with no record.
|
||||
2. **The module owns the whole directory and regenerates it.** Rejected in ADR 0182 (option 1), and still:
|
||||
the working state is the program's, and a render that touched `projects/` would erase a season of
|
||||
memory.
|
||||
3. **The module owns every configuration file by name, excludes the program's working state by name,
|
||||
renders the configuration from registrations, and reports a hand edit as a condition.** Chosen.
|
||||
|
||||
### Whose the rules are
|
||||
|
||||
1. **Per node** (the home scope as ADR 0216 defines it: one account's directory on one machine). Rejected
|
||||
as the only scope: the operator is one person on four nodes, and §2 shows what one-node rules give.
|
||||
2. **Mesh-wide instruction sections**, which already reach every node. Rejected as the place for them:
|
||||
those are the mesh's word to every session, written at the controller's terminal, about the mesh.
|
||||
A personal rule is the operator's word about the operator: how to hand over text, which tools their
|
||||
other employer's repositories need. It belongs to the person and follows the person's agent, into the
|
||||
home, under the person's own names.
|
||||
3. **A new kind, the personal rule, registered for the operator and rendered into the agent's home on
|
||||
every node.** Chosen. The same scope serves the operator's own skills, commands, subagents and settings.
|
||||
|
||||
### How a lesson becomes a rule
|
||||
|
||||
1. **The agent writes the rule itself.** Rejected: an agent that writes its own rules can loosen them, the
|
||||
operator never sees what it taught itself, and issue 340's reasoning holds — text that every session
|
||||
reads is written on the operator's word, never on an agent's.
|
||||
2. **Lessons stay in the agent's memory.** Rejected by §3.
|
||||
3. **A lessons register in the module. An agent proposes a lesson; the operator says yes or no; a yes
|
||||
makes it a personal rule, rendered everywhere; the agent is reminded of the rules that bear on what it
|
||||
is about to do.** Chosen.
|
||||
|
||||
### How the operator's yes reaches the operator's home
|
||||
|
||||
1. **Trust the tool's caller.** Rejected in issue 340.
|
||||
2. **The controller's terminal only.** Safe; kept as one of two ways. It makes a yes in a session a trip
|
||||
to the control-node, which is what the operator asked to avoid.
|
||||
3. **A warrant on an authorising ask** (ADR 0259): the module asks the operator, with the exact text
|
||||
bound in the ask, and acts on the warrant alone. Chosen beside 2. The approve option needs a channel
|
||||
that proves its sender; until one answers, the terminal is the way.
|
||||
+11
@@ -118,6 +118,17 @@ ADR 0213's setting, then the mesh scope, then the node scope, then the mesh's ow
|
||||
state. It writes, changes and removes only those. It refuses to register a name the person already
|
||||
uses there, rather than overwrite it.
|
||||
|
||||
> **The mechanism changed — 2026-10-09, by [ADR 0273](0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md).**
|
||||
> What stands: one plugin, three scopes, registration through the module's tools and state on the bus (§1
|
||||
> to §4). What moved: §5 and §6. The module now owns every configuration file under the agent's home,
|
||||
> rendered from registrations, with the program's working state excluded by name; a file it did not render
|
||||
> is a condition, `agent-home-drift`, rather than an item listed on request, and a hand edit of a rendered
|
||||
> file is written back with the hand version kept. A fourth scope, the operator's, carries the operator's
|
||||
> personal rules, skills, commands, subagents and settings into the agent's home on every node. Why: the
|
||||
> homes measured on 2026-10-09 held a skill retired a week before on all four nodes and the operator's rules
|
||||
> on one, and nothing was raised. Who may register into the operator's home is issue 340's rule, kept: the
|
||||
> controller's terminal, or a warrant on an ask.
|
||||
|
||||
**6. What the module did not place, it reports and can import.**
|
||||
|
||||
- A status tool lists the home's items and says which the mesh placed. It also names any that
|
||||
|
||||
+7
@@ -53,6 +53,13 @@ Option 3.
|
||||
This extends rule 5 of ADR 0216: the module removes what it placed, and also, on the person's
|
||||
word, what it did not place. Rule 6 stands as written.
|
||||
|
||||
> **The mechanism changed — 2026-10-09, by [ADR 0273](0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md).**
|
||||
> What stands: a found item leaves the home only on the person's word, with a reason, a copy kept, and a
|
||||
> way back. What moved: a found item is now a condition the module raises (`agent-home-drift`), and this
|
||||
> removal and the import are the operator's two answers to it; and for the operator's own home "the
|
||||
> person's word" is no longer the caller's say-so (the consequence below) but one of two proofs, the
|
||||
> controller's terminal or a warrant on an ask, as issue 340 requires.
|
||||
|
||||
## Consequences
|
||||
|
||||
- An item the mesh did not place can now leave a machine with its reason recorded and its content
|
||||
|
||||
+351
@@ -0,0 +1,351 @@
|
||||
---
|
||||
topic: what runs on it
|
||||
status: accepted
|
||||
date: 2026-10-09
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
extends: 02-DECISIONS/0216-the-agents-configuration-is-registered-through-its-module-at-three-scopes-and-served-as-one-plugin.md
|
||||
---
|
||||
|
||||
# 273. The agent's home is the module's, and the operator's personal rules and lessons are registered through it
|
||||
|
||||
## Context
|
||||
|
||||
[ADR 0216](0216-the-agents-configuration-is-registered-through-its-module-at-three-scopes-and-served-as-one-plugin.md)
|
||||
put the coding agent's configuration under its module at three scopes, and gave the home scope the lightest
|
||||
touch: the module "owns only what it placed" (§5), reports what it did not place and can import it (§6), and
|
||||
"the stale files already in the homes stay until the person removes them". That followed
|
||||
[ADR 0182](0182-inside-a-home-the-mesh-owns-what-it-places-and-holds-the-rest-as-found.md): inside a home, the
|
||||
person's own rules and skills are *found*, never read, rewritten or removed.
|
||||
[ADR 0243](0243-the-agent-module-removes-a-home-item-it-did-not-place-only-on-the-persons-word-and-keeps-a-copy.md)
|
||||
added the one channel for removing a found item, on the person's word, with a copy kept.
|
||||
|
||||
[Issue 340](../04-ISSUES/340-an-agent-can-plant-a-hook-in-every-agent-session-on-the-mesh/00-report.md) then
|
||||
found that the module's tools could not tell the operator from an agent, so an agent confined on the
|
||||
control-node could register a hook, or a rule, that the operator's next session on another node would run or
|
||||
obey. The operator closed it on 2026-10-09: shared text and everything that runs is set at the controller's
|
||||
terminal alone, and the home scope is written only into the home of an agent account of its own
|
||||
([ADR 0266](0266-on-the-control-node-agents-run-under-an-account-of-their-own-that-cannot-become-root-without-a-person.md)),
|
||||
never into the operator's. The same day
|
||||
[ADR 0272](0272-the-operator-reaches-the-controller-with-mesh-cli-on-every-node-and-a-node-is-the-terminal-only-where-no-agent-runs-as-its-operator.md)
|
||||
gave the operator a way to that terminal, and
|
||||
[ADR 0259](0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md) gave
|
||||
any module a way to ask the operator a question and act on the answer with a warrant.
|
||||
|
||||
**What the homes hold**, measured on 2026-10-09 through each node's own status tool
|
||||
([research 040](../01-RESEARCH/040-the-agents-home-is-the-modules-and-the-operators-rules-and-lessons/01-what-the-home-holds-and-the-options.md) §2):
|
||||
|
||||
- a skill [to-be 36](../03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md) §1 retired on 2026-10-02
|
||||
("nothing; it named the predecessor's forge") is still in the home on **all four nodes**;
|
||||
- a person's instruction file is on three; a subagent on one;
|
||||
- the operator's two hand-written rule files, about how the operator wants text handed over and how a second
|
||||
forge's repositories are worked in, are on **the laptop alone**;
|
||||
- the mesh has placed nothing in any home, and raises no condition about any of it.
|
||||
|
||||
On the laptop the directory holds 33 entries: 7 are configuration (the two rules, five skills and a synced
|
||||
folder, an empty commands folder, a settings file with 6 keys, a local settings file the program writes with
|
||||
the permission answers a person gives, the program's plugin records), and the rest is the program's own
|
||||
working state — history, sessions, the memory of 30 projects (1.5 GB), caches, the credentials file
|
||||
([research 040](../01-RESEARCH/040-the-agents-home-is-the-modules-and-the-operators-rules-and-lessons/01-what-the-home-holds-and-the-options.md) §1).
|
||||
|
||||
**What the agent learns, and where it keeps it.** The agent keeps notes for itself in the program's memory
|
||||
for one repository on the laptop: 45 on 2026-10-09, at least 9 of them a correction the operator gave of how
|
||||
the agent works — finish a module before pushing, use the mesh's tools and not ssh, read the merge gate before
|
||||
merging, no work-arounds for a missing tool. Each was said once, sometimes with irritation, written by the
|
||||
agent in its own words, shown to nobody, read on no other node and in no other repository, and not said again
|
||||
at the moment it matters ([research 040](../01-RESEARCH/040-the-agents-home-is-the-modules-and-the-operators-rules-and-lessons/01-what-the-home-holds-and-the-options.md) §3).
|
||||
|
||||
**The operator's direction, 2026-10-09**, in their words:
|
||||
|
||||
> "the home-scope does own ~/.claude, so it should be completely empty and manual edits should be forbidden.
|
||||
> Rules in my home directory are my 'personal rules' which should also end up under control of the
|
||||
> claude-code module and all other changes to ~/.claude should go through the claude-code module's mcp tools"
|
||||
|
||||
> "register the decision, but make sure it's clear and that you can/should be pro-active about it. For
|
||||
> example, if I'm frustrated, try to see why and try to prevent it in the future by warning yourself about
|
||||
> stuff not to do to frustrate me — kind of like a self-learning process."
|
||||
|
||||
The record was searched first ("personal rules lessons frustration self-learning"; "hand edit home .claude
|
||||
drift condition"): nothing.
|
||||
|
||||
### Against GENESIS
|
||||
|
||||
- **The mesh owns the truth.** "State lives in the mesh and is derived onto nodes. A file edited on a node
|
||||
is a bug with a delay on it." A rule file written by hand into the agent's home is that file.
|
||||
- **The mesh remembers.** "Nothing has to be explained twice." A correction the operator gives once reaches
|
||||
every session of theirs, and is said again where it applies.
|
||||
- **Failure must be loud.** A hand edit is a condition, not a silent difference the next render erases.
|
||||
- **Nodes are personal; the mesh is a guest.** The program's own working state — memory, history,
|
||||
sessions — stays the program's, excluded by name, exactly as ADR 0182 drew the line.
|
||||
|
||||
## Considered Options
|
||||
|
||||
The options are weighed in full in
|
||||
[research 040 §5](../01-RESEARCH/040-the-agents-home-is-the-modules-and-the-operators-rules-and-lessons/01-what-the-home-holds-and-the-options.md);
|
||||
in short:
|
||||
|
||||
### Who owns the configuration under the home
|
||||
|
||||
1. **As today: the module owns what it placed, the rest is found** (ADR 0216 §5). Rejected by the operator,
|
||||
and by the measurement: a rule on one node reaches no other, a retired skill stays on four, nothing is
|
||||
raised. And the guard refuses ssh to a machine but not a write to `~/.claude/rules/`: on a node where the
|
||||
agent runs as the operator, that is a rule planted in every later session, by hand, with no record.
|
||||
2. **The module owns the whole directory and regenerates it.** Rejected, as ADR 0182 rejected it: the
|
||||
working state is the program's, and a render touching the projects' memory erases a season of it.
|
||||
3. **The module owns every configuration file by name, excludes the working state by name, renders the
|
||||
configuration from registrations, and reports a hand edit as a condition.** Chosen.
|
||||
|
||||
### Whose the rules are
|
||||
|
||||
1. **Per node only**, the home scope as ADR 0216 defines it. Rejected as the only scope: the operator is
|
||||
one person on four nodes.
|
||||
2. **Mesh-wide instruction sections.** Rejected as their place: those are the mesh's word about the mesh,
|
||||
written at the terminal. A personal rule is the operator's word about the operator, and follows the
|
||||
person's agent into the home under the person's own names.
|
||||
3. **A new kind, the personal rule, registered for the operator, rendered into the agent's home on every
|
||||
node.** Chosen; the same scope carries the operator's own skills, commands, subagents and settings.
|
||||
|
||||
### How a lesson becomes a rule
|
||||
|
||||
1. **The agent writes the rule itself.** Rejected: an agent that writes its own rules can loosen them, the
|
||||
operator never sees what it taught itself, and text every session reads is written on the operator's
|
||||
word, never an agent's (issue 340).
|
||||
2. **Lessons stay in the agent's memory.** Rejected by the measurement above.
|
||||
3. **A lessons register in the module; a lesson is proposed by an agent, accepted or declined by the
|
||||
operator, rendered as a personal rule on a yes, and said again before the act it bears on.** Chosen.
|
||||
|
||||
### How the operator's yes reaches the operator's home
|
||||
|
||||
1. **Trust the tool's caller.** Rejected in issue 340.
|
||||
2. **The controller's terminal only.** Safe, and kept as one of two ways; alone, it makes a yes in a
|
||||
session a trip to the control-node.
|
||||
3. **A warrant on an authorising ask** (ADR 0259), the exact text bound in the ask. Chosen beside 2.
|
||||
|
||||
## Decision
|
||||
|
||||
### 1. The configuration under the agent's home is the module's, whole
|
||||
|
||||
**The `claude-code` module owns every configuration file under the agent's home directory** (`~/.claude` of
|
||||
the account the agent runs as, ADR 0266 §5): the home instruction file, `rules/`, `skills/`, `commands/`,
|
||||
`agents/`, `hooks/`, and `settings.json`. **Nothing there is written by hand.** Each is rendered by the
|
||||
module's code from registrations, on every node, whenever a registration changes, and nothing else writes
|
||||
them. A configuration file the vendor adds later joins the list by name, in the module, before the module
|
||||
renders anything into it.
|
||||
|
||||
**The program's working state is excluded by name**, and stays the program's, in ADR 0182's *found* class
|
||||
or *written by the module's own process*: the credentials file (ADR 0183), the history, the sessions and
|
||||
their environments, the projects directory with every project's memory, the shell snapshots, the file
|
||||
history, the debug, cache, paste and telemetry directories, the statistics, the daemon's files, the
|
||||
program's own plugin records and cache (`plugins/`), the vendor's synced skills (`skills/synced/`), the
|
||||
backups, worktrees, jobs, feedback, state and IDE directories, and `settings.local.json`, which the program
|
||||
writes with the permission answers a person gives in a session. The module never reads, writes or removes
|
||||
any of these. It names the list in its manifest's documentation, and the status tool shows an entry it does
|
||||
not know under either heading, so a new vendor file is seen rather than guessed about.
|
||||
|
||||
**The keys the program itself writes into `settings.json` on a person's choice** — the model, the spinner,
|
||||
the drafts and the other preferences the vendor's own `/model` and `/config` commands set — are not hand
|
||||
edits. The module keeps a short list of them. When the program changes one of those keys, the module takes
|
||||
the new value over into the operator's registered settings (§2), reports it in the status tool, and the
|
||||
change follows the operator to every node. That is ADR 0182's *written into* class, applied the other way
|
||||
round: the file is the module's, and the program is allowed into a few named keys of it. This is the
|
||||
mechanism that keeps a `/model` choice from being reverted on the next render, the failure ADR 0182's context
|
||||
records.
|
||||
|
||||
### 2. A fourth scope, the operator's, and a new kind, the personal rule
|
||||
|
||||
ADR 0216's three scopes stand. A fourth joins them: **operator**. An item registered at the operator scope
|
||||
is rendered into the agent's home on **every node that names an operator account** (ADR 0181): into the
|
||||
operator's own home where the agent runs as the operator, and into the agent account's home where the node
|
||||
names one (ADR 0266). The mesh has one operator; the scope is the person, not a machine.
|
||||
|
||||
The kinds at the operator scope:
|
||||
|
||||
- **personal rule** (new): one short text in the operator's words about how the operator wants the agent
|
||||
to work with them, rendered as one file under `rules/` and listed in the home instruction file, which the
|
||||
module renders as the index of the personal rules, each with where it came from (the terminal, or the
|
||||
lesson it was accepted from) and when. The vendor reads both into every session of that account;
|
||||
- the operator's own **skills, commands and subagents**, under the person's own names, without the plugin's
|
||||
prefix;
|
||||
- the operator's **settings** (`settings.json`), as one registered object, laid under the managed settings
|
||||
as the vendor lays them.
|
||||
|
||||
**Never at the operator scope: a hook, a permission rule, a tool server, or an item that runs anything.**
|
||||
Those stay the terminal's, in the managed settings and the managed tool-server file (issue 340). A personal
|
||||
rule, skill, command or subagent that holds a shell line or the front matter issue 340 refuses is refused at
|
||||
the operator scope too.
|
||||
|
||||
**The operator's existing items are imported as the first registrations**, through the import tool ADR 0216
|
||||
§6 named, at the operator scope: the two rule files on the laptop become the first two personal rules; the
|
||||
laptop's skills and the workstation's subagent are imported or removed, each on the operator's word
|
||||
(ADR 0243); `settings.json` on the laptop becomes the operator's registered settings; the retired `cleanup`
|
||||
skill and the three instruction files are removed with a copy kept. Until each item is imported or removed it
|
||||
is a condition (§4).
|
||||
|
||||
### 3. Who may register into the operator's home, and issue 340's protection stands
|
||||
|
||||
A registration at the operator scope, and a registration at the home scope into an operator's own home, is
|
||||
taken **only** by one of two routes, and refused through any other:
|
||||
|
||||
1. **At the controller's terminal** (ADR 0272), as issue 340 made shared text: the module's settings gain
|
||||
`personal_rules`, `personal_skills`, `personal_commands`, `personal_agents` and `personal_settings`, set
|
||||
with `nox settings set claude-code …` on the control-node. The module's whole layer is already the
|
||||
terminal's, because its settings file is a mergeable file issue 340 counts as trusted.
|
||||
2. **On a warrant** (ADR 0259): the module is an asker. Its register, import and remove tools, called at the
|
||||
operator scope or for an operator's home, do not act; they publish an **approve** ask whose words show the
|
||||
item in full and whose digest binds the exact text, name, kind and scope, and they act once on the warrant
|
||||
for that ask, recording it. Until a channel that proves its sender answers approve for the module, the
|
||||
ask is refused at once with the reason and names the terminal's line.
|
||||
|
||||
The home scope into **an agent account's own home** stays as issue 340 left it: that node's own tools take
|
||||
it, because that home is no person's. A home-scope item never shadows a personal rule: the module renders
|
||||
the operator's items first and refuses a home-scope name an operator-scope item already uses.
|
||||
|
||||
So an agent still cannot plant anything in the operator's home: a tool call without a warrant writes
|
||||
nothing there, a warrant is the router's record of the operator's own answer, and the terminal is the
|
||||
operator's own account on a node where no agent runs as it.
|
||||
|
||||
### 4. A hand edit is a condition, and the guard refuses it
|
||||
|
||||
**On every look**, and within a minute of a change on disk, the module compares the configuration paths of
|
||||
§1 with what it last rendered. Any difference is a **finding**, said as the module's own health (ADR 0240)
|
||||
on that node, and the controller raises the condition **`agent-home-drift`** for it, a warning that needs the
|
||||
operator, naming each path and what differs:
|
||||
|
||||
- **a file nobody rendered** (a hand-written rule, a copied skill, a file left by a retired generator): left
|
||||
in place and reported, never removed by the module. The operator's answers are the import tool (register
|
||||
it at a scope) or the removal tool (ADR 0243: a reason, a copy kept). A file the operator neither imports
|
||||
nor removes keeps the condition open;
|
||||
- **a rendered file changed by hand**: written back at the next render, the hand version kept as a copy in
|
||||
the module's state and shown by the status tool, so the operator's words are not lost — the mesh owns the
|
||||
truth, and the way to change the file is to change the registration;
|
||||
- **a rendered file missing**: rendered again, and reported once.
|
||||
|
||||
The condition clears on the first look that finds no difference. It is never urgent, and the first-node gate
|
||||
never reads it as a fault of a build (as
|
||||
[ADR 0254](0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md)
|
||||
treats a wait for a person).
|
||||
|
||||
**The guard on the agent's shell** (ADR 0245) refuses, before it runs, any shell command or file edit whose
|
||||
target is under a configuration path of §1 — a write, an append, a copy or move into it, an in-place edit,
|
||||
a removal — naming the module's tool that does the job, and saying that a rule the agent wants is a lesson
|
||||
(§5). The operator's override of ADR 0245 §5 applies and is recorded. The guard does not watch the
|
||||
working state.
|
||||
|
||||
### 5. Lessons: an agent proposes, the operator decides, and the agent is reminded
|
||||
|
||||
**The module keeps a lessons register** in its state (ADR 0201): one record per lesson, holding when and on
|
||||
which node it was proposed, the session that proposed it where the agent gave it, the **trigger** (the
|
||||
operator's words, quoted), the **cause** (what the agent did, in one or two sentences), the **rule** that
|
||||
would prevent it (written as a personal rule, in the operator's second person: "do not…", "always…"), an
|
||||
optional **before** (a tool name, a command prefix or a path pattern the rule bears on), and its state:
|
||||
`proposed`, `accepted` or `declined`, with who decided, how and when.
|
||||
|
||||
**When an agent records a lesson.** The mesh's instruction section tells every agent: when the operator
|
||||
expresses frustration (repeats a request, says they have asked before, says "again", "stop", "why did you";
|
||||
irritation in any words), or corrects a way of working ("don't", "always", "from now on", "never"), the agent
|
||||
first works out why — what it did, and what the operator wanted instead — and then records a lesson with
|
||||
the trigger, the cause and the rule, in the same turn, before going on. It says in its answer that it did,
|
||||
in one line. An agent that is unsure whether a correction is a lesson records it; the operator declines what
|
||||
is not.
|
||||
|
||||
**A proposed lesson is not a rule.** It is rendered nowhere and reaches no session as an instruction. The
|
||||
module shows it to the operator for a yes: an approve ask (§3 route 2) whose words carry the trigger, the
|
||||
cause and the rule, with Accept and Decline as its options; or, until a channel answers approve, the list
|
||||
tool names the proposed lessons and the operator accepts or declines each at the terminal (`nox settings
|
||||
set claude-code …` with the lesson's id in `lessons_accepted` or `lessons_declined`). A proposed lesson
|
||||
expires after 30 days, declined with that reason.
|
||||
|
||||
**An accepted lesson is a personal rule.** The module registers it at the operator scope with the lesson's
|
||||
id as its source, so it renders into the agent's home on every node like any personal rule, and the home
|
||||
instruction file names it as "accepted from lesson N on <date>". **A declined lesson stays in the register
|
||||
with its reason**, and the list tool shows it, so an agent does not propose it again; a new lesson whose rule
|
||||
matches a declined one's is refused with the reason, and the agent is told to say so to the operator rather
|
||||
than record it again.
|
||||
|
||||
**The agent is reminded, before it acts.** Two things make the lessons proactive rather than a file the agent
|
||||
may or may not open:
|
||||
|
||||
- **at session start**, the plugin's session-start hook (the module's own binary, beside the guard) prints
|
||||
the personal rules accepted from lessons in the last 30 days and the ones whose `before` matches the
|
||||
session's working directory or repository, each in one line, so the session begins knowing them;
|
||||
- **before a tool runs**, the guard (ADR 0245 §4, asked about every tool) prints the rule of every accepted
|
||||
lesson whose `before` matches the tool, the command or the path about to be used — a reminder, never a
|
||||
refusal; a refusal is a guard rule and nothing else. The reminder is printed once per session per rule.
|
||||
|
||||
**The register is readable by any agent on any node** through the list tool, and shows `proposed`,
|
||||
`accepted` and `declined` apart, each marked, so a session reading it cannot take a proposal for a rule.
|
||||
Recording a proposal needs no yes: it writes the register and nothing a session obeys.
|
||||
|
||||
### 6. What this changes in the earlier records
|
||||
|
||||
- **ADR 0216 §5 and §6**: the mechanism changes (that record gains a note). The home scope owns the
|
||||
configuration whole; a found item is reported as a condition rather than listed on request; import stays
|
||||
the way in; the plugin's hook file holds the module's own hooks, the guard and the session-start
|
||||
reminder, and nothing registered.
|
||||
- **ADR 0243** stands as the removal on the person's word, now on a warrant or at the terminal for an
|
||||
operator's home, and is the operator's one answer to a found item beside importing it.
|
||||
- **ADR 0182** stands: the class table holds, with the configuration files in the *owned* class and the
|
||||
working state *found*, each named.
|
||||
- **ADR 0245**: the guard gains a refusal (§4) and a reminder (§5).
|
||||
- **Issue 340**: the protection stands; the terminal and the warrant are the two ways into the operator's
|
||||
home.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The operator's rules follow the operator: a rule written once reaches the agent's home on every node
|
||||
within a minute, and a session on any node starts with it.
|
||||
- A hand edit under `~/.claude` comes back at the next render, with the hand version kept, and is said as a
|
||||
condition: no silent difference, and no lost words.
|
||||
- The retired skill and the three stale instruction files, found on four nodes since 2026-10-02, are
|
||||
removed on the operator's word with copies kept, and nothing like them can stay unnoticed again.
|
||||
- A correction the operator gives once becomes a rule everywhere on one yes, and is said again before the
|
||||
act it bears on. The operator sees every rule the agent proposes, and can decline it.
|
||||
- **What got harder:**
|
||||
- a new rule for the agent is no longer a file: it is a registration at the terminal or a warrant on an
|
||||
ask. Until a channel answers approve for the module, every yes is typed on the control-node;
|
||||
- the module watches the home on every node, and its state holds the lessons register and the copies of
|
||||
hand versions. Clearing old copies is not decided here, as ADR 0243 left it;
|
||||
- a vendor file the module does not know is a condition until it is classified, which is the point: an
|
||||
unknown file in the agent's home is a question, not a default;
|
||||
- an agent is expected to notice frustration and record a lesson in the same turn, which costs the turn a
|
||||
tool call. A lesson recorded late, or not at all, is found by reading the session against the register.
|
||||
- **Not decided here:** a per-project lesson (one bound to a repository rather than the operator); lessons
|
||||
for an agent the mesh runs rather than the operator's; and a channel of the operator's own that can
|
||||
tell the operator from an agent (issue 340's "once we build a UI"), which would become a third route.
|
||||
|
||||
## How it is checked
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| Every configuration path of §1 is rendered from registrations and nothing else; the working state is never read, written or removed | the module's render test over a seeded home: the configuration files match the registrations byte for byte; every excluded entry is byte-identical before and after; an unknown entry is reported |
|
||||
| A program-written key of `settings.json` is taken over, not reverted | the module's test: the model key changed on disk appears in the operator's registered settings on the next look and in the rendered file on every node; a key outside the list changed on disk is drift |
|
||||
| A personal rule renders into the agent's home on every node naming an operator account, under `rules/` and in the home instruction file | the module's render test for one machine of three: the operator's own home on two, the agent account's home on the one naming one; live: a rule set at the terminal is in a new session's context on each node |
|
||||
| Nothing that runs is taken at the operator scope | the module's tests: a hook, a permission rule, a tool server, and a skill, command or subagent holding a shell line or the refused front matter are each refused at the operator scope with issue 340's reason |
|
||||
| A registration into an operator's home is taken only at the terminal or on a warrant | the module's tests through its real tool dispatch: each register, import and remove tool at the operator scope, or for an operator's home, publishes an ask and writes nothing; the same with a warrant for that ask acts once; a warrant for another ask, or a replayed one, is refused; while no channel answers approve the ask is refused at once naming the terminal's line. The controller's test: the module's layer is the terminal's (issue 340's) |
|
||||
| A hand edit is a condition, and nothing found is removed by the module | the module's tests: a file nobody rendered is reported and left; a rendered file changed by hand is written back, its hand version kept and shown; a missing one is rendered again; the condition clears on a clean look; the controller's test that `agent-home-drift` is a warning the first-node gate never reads as a fault |
|
||||
| The guard refuses a write under a configuration path and lets the working state alone | the module's guard tests: a redirect, append, copy, move, in-place edit and removal under each path refused naming the tool; the same under `projects/` passes; the operator's override honoured and recorded |
|
||||
| A lesson is recorded with its trigger, cause and rule; a proposal renders nowhere; an accepted one is a personal rule; a declined one is not proposed again | the module's tests over the register: register, list, accept, decline, expiry; the render test that only accepted lessons reach `rules/`; a second proposal matching a declined rule refused with the reason |
|
||||
| The agent is reminded at session start and before a matching tool | the module's hook tests: the session-start hook prints the recent and matching rules; the guard prints a matching lesson's rule once per session and refuses nothing for it |
|
||||
| An agent records a lesson when corrected | the mesh's instruction section says so (`working-on-the-mesh`), checked by reading it on each render; live: a correction given in a session is in the register within that turn, and the ask reaches the operator |
|
||||
| Live, at acceptance (the operator's view) | on the laptop: `~/.claude` holds the rendered configuration and the program's working state and nothing else; a rule written by hand into `rules/` raises `agent-home-drift` within a minute and is listed by the status tool; `nox settings set claude-code '{"personal_rules": …}'` on the control-node puts the rule into a new session on every node; a correction given in a session appears in the lessons list, is accepted at the terminal, and the next session on another node names it at start |
|
||||
|
||||
## References
|
||||
|
||||
- [Research 040](../01-RESEARCH/040-the-agents-home-is-the-modules-and-the-operators-rules-and-lessons/00-overview.md):
|
||||
the measurement on four nodes, the agent's memory, the options.
|
||||
- [ADR 0216](0216-the-agents-configuration-is-registered-through-its-module-at-three-scopes-and-served-as-one-plugin.md),
|
||||
[ADR 0182](0182-inside-a-home-the-mesh-owns-what-it-places-and-holds-the-rest-as-found.md),
|
||||
[ADR 0243](0243-the-agent-module-removes-a-home-item-it-did-not-place-only-on-the-persons-word-and-keeps-a-copy.md):
|
||||
the home before this record.
|
||||
- [ADR 0245](0245-a-verb-says-what-it-replaces-and-the-agent-is-guarded-from-working-round-the-mesh.md): the guard.
|
||||
- [ADR 0259](0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md),
|
||||
[ADR 0272](0272-the-operator-reaches-the-controller-with-mesh-cli-on-every-node-and-a-node-is-the-terminal-only-where-no-agent-runs-as-its-operator.md):
|
||||
the two ways the operator's word reaches the mesh.
|
||||
- [ADR 0266](0266-on-the-control-node-agents-run-under-an-account-of-their-own-that-cannot-become-root-without-a-person.md),
|
||||
[ADR 0181](0181-the-operator-account-is-a-node-fact-and-a-home-is-a-placement-root.md): whose home the agent's is.
|
||||
- [ADR 0240](0240-a-module-says-how-it-is-healthy-and-the-node-engine-judges-it.md),
|
||||
[ADR 0254](0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md):
|
||||
the condition and the gate.
|
||||
- [Issue 340](../04-ISSUES/340-an-agent-can-plant-a-hook-in-every-agent-session-on-the-mesh/00-report.md): the protection kept.
|
||||
- [To-be 36](../03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md) §1, §8 and §10,
|
||||
[to-be 40](../03-DESIGN/01-to-be/40-building-the-operators-agent-and-its-licence-manager.md) WP7–WP10: the design and the build.
|
||||
@@ -4,6 +4,7 @@ status: in-progress
|
||||
code: [mesh-catalog modules/claude-code]
|
||||
updated: 2026-10-09
|
||||
decisions:
|
||||
- 02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md
|
||||
- 02-DECISIONS/0266-on-the-control-node-agents-run-under-an-account-of-their-own-that-cannot-become-root-without-a-person.md
|
||||
- 02-DECISIONS/0243-the-agent-module-removes-a-home-item-it-did-not-place-only-on-the-persons-word-and-keeps-a-copy.md
|
||||
- 02-DECISIONS/0245-a-verb-says-what-it-replaces-and-the-agent-is-guarded-from-working-round-the-mesh.md
|
||||
@@ -63,12 +64,21 @@ instruction file and the manager's tools:
|
||||
|
||||
**The home.** Under [ADR 0182](../../02-DECISIONS/0182-inside-a-home-the-mesh-owns-what-it-places-and-holds-the-rest-as-found.md)
|
||||
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.
|
||||
`0700` — and declares it, so the mesh refuses a second module owning it.
|
||||
|
||||
> **Revised 2026-10-09 by [ADR 0273](../../02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md).**
|
||||
> This paragraph said the module owns only the credentials file inside the directory and holds every other
|
||||
> path as found, the person's own rules and skills included. Now **every configuration file under the
|
||||
> directory is the module's** — the home instruction file, `rules/`, `skills/`, `commands/`, `agents/`,
|
||||
> `hooks/` and `settings.json` — rendered from registrations and never written by hand; and **the program's
|
||||
> working state is excluded by name** and stays found: the credentials file (written by the module's own
|
||||
> code, §5), the history, the sessions, the projects and their memory, the caches, the program's own plugin
|
||||
> records, the vendor's synced skills, and the local settings file the program writes with a person's
|
||||
> permission answers. §10 says how, and what a hand edit becomes. The six predecessor files are no longer
|
||||
> the operator's to remove by hand: a file nobody rendered is a condition, and the operator imports or
|
||||
> removes it through the module's tools.
|
||||
|
||||
The person's memory, history and projects are never read or written by the mesh.
|
||||
|
||||
## 2. What the module declares and what its code writes
|
||||
|
||||
@@ -244,28 +254,37 @@ machine. A machine that joins later takes it at its first start.
|
||||
The managed settings name the marketplace and enable the plugin. Those two keys are the mesh's, laid
|
||||
last with the attribution key, and no setting replaces them.
|
||||
|
||||
**Three scopes.** Every registration names one:
|
||||
**Three scopes, and a fourth since 2026-10-09.** Every registration names one:
|
||||
|
||||
- **mesh:** every machine running the agent;
|
||||
- **node:** one machine or a list of them, rendered into the same plugin and files there only;
|
||||
- **home:** the operator account's own agent directory on one machine, where the item sits as if
|
||||
written there by hand.
|
||||
- **home:** the agent account's own agent directory on one machine, where the item sits as if
|
||||
written there by hand. Since [issue 340](../../04-ISSUES/340-an-agent-can-plant-a-hook-in-every-agent-session-on-the-mesh/00-report.md)
|
||||
it is taken only for the node serving the call, and only where that home is an agent account's own
|
||||
(§9), never the operator's;
|
||||
- **operator** (ADR 0273, §10): the operator's own items, rendered into the agent's home on every node that
|
||||
names an operator account — the operator's own home where the agent runs as the operator, the agent
|
||||
account's home where the node names one.
|
||||
|
||||
Settings take the first two scopes only. In the managed settings file they are laid in this order:
|
||||
the operator's `managed_settings` setting (§2), then the mesh scope, then the node scope, then the
|
||||
mesh's own keys.
|
||||
Settings take the mesh and node scopes into the managed settings file, laid in this order: the operator's
|
||||
`managed_settings` setting (§2), then the mesh scope, then the node scope, then the mesh's own keys. The
|
||||
operator's own settings take the operator scope, into the home's `settings.json` (§10). **Since issue 340,
|
||||
hooks, permission rules, tool servers and every kind of shared text for the mesh or a node are set at the
|
||||
controller's terminal alone**, in the module's settings; the tools refuse them and say so.
|
||||
|
||||
**Instructions follow the scopes.** The managed instruction file holds the mesh's piece, then the node's
|
||||
piece: its role, and the sections registered for it. Further customisation per machine is a rule file
|
||||
placed at the home scope. The agent concatenates these and does not override, so the status tool names
|
||||
a section that contradicts another, or that calls a tool the mesh no longer serves.
|
||||
|
||||
**The home scope owns only what it placed.** The module records each home path it placed and touches
|
||||
only those (ADR 0182). It refuses to register a name the person already uses there.
|
||||
**The home is the module's** (ADR 0273, replacing "the home scope owns only what it placed"). The module
|
||||
renders every configuration file under the agent's home from the registrations that apply there, at the
|
||||
operator and home scopes, and records what it rendered. A name registered twice is refused: an operator-scope
|
||||
item is rendered first, and a home-scope item may not take its name.
|
||||
|
||||
The one exception is a removal the person asks for ([ADR 0243](../../02-DECISIONS/0243-the-agent-module-removes-a-home-item-it-did-not-place-only-on-the-persons-word-and-keeps-a-copy.md)).
|
||||
On the person's word, with a reason, the module removes an item it did not place. It keeps a checked copy in its own
|
||||
state and logs the removal, and can put the item back.
|
||||
A removal the person asks for ([ADR 0243](../../02-DECISIONS/0243-the-agent-module-removes-a-home-item-it-did-not-place-only-on-the-persons-word-and-keeps-a-copy.md))
|
||||
is now the operator's answer to a file nobody rendered (§10). On the person's word, with a reason, the
|
||||
module removes it, keeps a checked copy in its own state, logs the removal, and can put the item back.
|
||||
|
||||
**The tools.**
|
||||
|
||||
@@ -281,7 +300,7 @@ An item and its files are one value in the state, refused above 256 KiB.
|
||||
|
||||
**Changing the agent's own settings is the operator's act.** The vendor refuses an agent that loosens its
|
||||
own settings, and the module does not route around that refusal. A settings tool is called on the
|
||||
operator's word.
|
||||
operator's word — and, for the operator's own home, only at the terminal or on a warrant (§10).
|
||||
|
||||
## 9. The account the agent runs as
|
||||
|
||||
@@ -363,6 +382,99 @@ terminal. The next send names the operator account again: the guard lets the ope
|
||||
and the licence is fetched into the operator's home. The agent account is kept (the node-engine never deletes
|
||||
a login).
|
||||
|
||||
## 10. The home is the module's: personal rules, and the lessons an agent proposes
|
||||
|
||||
*Added 2026-10-09 by [ADR 0273](../../02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md).*
|
||||
|
||||
**What the module renders under the agent's home**, on every node, as the account the agent runs as (through
|
||||
the helper of §9 where that is an agent account):
|
||||
|
||||
| path | rendered from |
|
||||
|---|---|
|
||||
| the home instruction file | the index of the operator's personal rules: each rule's name, where it came from (the terminal, or the lesson it was accepted from) and when; a first line saying the file is the module's and names the tools that change it |
|
||||
| `rules/<name>.md` | one personal rule each |
|
||||
| `skills/<name>/`, `commands/<name>.md`, `agents/<name>.md` | the operator's own skills, commands and subagents at the operator scope, under their own names; and the home-scope items where the home is an agent account's own |
|
||||
| `hooks/` | nothing: a hook is the terminal's, in the managed settings. The directory is kept empty |
|
||||
| `settings.json` | the operator's registered settings, with the keys the program itself writes on a person's choice (the model, the spinner, the drafts, the other preferences the vendor's own commands set) taken over into the registration when the program changes them, so a choice made in one session follows the operator |
|
||||
|
||||
Everything else under the directory is the program's working state, excluded by name in the module's
|
||||
documentation and never read, written or removed: the credentials file (§5), the history, the sessions and
|
||||
their environments, the projects and their memory, the shell snapshots, the file history, the debug, cache,
|
||||
paste and telemetry directories, the statistics, the daemon's files, `plugins/`, `skills/synced/`, the
|
||||
backups, worktrees, jobs, feedback, state and IDE directories, and `settings.local.json`. An entry the module
|
||||
knows under neither heading is reported by the status tool, so a vendor's new file is a question, not a
|
||||
default.
|
||||
|
||||
**Who may register into the operator's home.** A registration at the operator scope, or at the home scope
|
||||
into a home that is the operator's own, is taken by two routes and refused through any other:
|
||||
|
||||
1. **at the controller's terminal** ([ADR 0272](../../02-DECISIONS/0272-the-operator-reaches-the-controller-with-mesh-cli-on-every-node-and-a-node-is-the-terminal-only-where-no-agent-runs-as-its-operator.md)):
|
||||
the module's settings `personal_rules`, `personal_skills`, `personal_commands`, `personal_agents`,
|
||||
`personal_settings`, `lessons_accepted` and `lessons_declined`, set with `nox settings set claude-code …`.
|
||||
The module's whole layer is already the terminal's (issue 340);
|
||||
2. **on a warrant** ([ADR 0259](../../02-DECISIONS/0259-an-ask-is-a-message-on-the-bus-any-channel-answers-it-and-the-asker-acts-on-a-warrant.md)):
|
||||
the module uses the `operator-channel` seat as an asker. A register, import or remove tool called for the
|
||||
operator's home acts on nothing: it publishes an approve ask showing the item in full, its digest binding
|
||||
the text, name, kind and scope, and acts once on the warrant for that ask. While no channel answers approve
|
||||
for the module, the ask is refused at once with the reason, naming the terminal's line.
|
||||
|
||||
Nothing that runs — a hook, a permission rule, a tool server, a skill or command holding a shell line or the
|
||||
front matter issue 340 refuses — is taken at the operator scope by either route. Issue 340's protection
|
||||
stands: a tool call without a warrant writes nothing into the operator's home.
|
||||
|
||||
**A hand edit is a condition.** On every look, and within a minute of a change on disk, the module compares
|
||||
the rendered paths with the disk. Any difference is said in its health as a finding on that node, and the
|
||||
controller raises **`agent-home-drift`**, a warning that needs the operator, naming each path:
|
||||
|
||||
- a file nobody rendered is left and reported; the operator imports it (the import tool, at a scope) or
|
||||
removes it (ADR 0243's tool, reason given, copy kept);
|
||||
- a rendered file changed by hand is written back on the next render, and the hand version is kept as a
|
||||
copy in the module's state, shown by the status tool;
|
||||
- a rendered file missing is rendered again.
|
||||
|
||||
The condition clears on the first clean look; the first-node gate never reads it as a fault of a build
|
||||
([ADR 0254](../../02-DECISIONS/0254-a-wait-for-a-persons-new-login-is-not-a-gates-failure-and-each-module-of-a-send-keeps-its-own-pass.md)'s
|
||||
exemption). **The guard** (§3) refuses any shell command or file edit that writes, appends to, copies or
|
||||
moves into, edits in place or removes a rendered path, naming the module's tool and saying a rule the agent
|
||||
wants is a lesson. It does not watch the working state. The operator's override (ADR 0245 §5) applies.
|
||||
|
||||
**The first registrations** are imports: the operator's two rule files on the laptop as the first personal
|
||||
rules; the laptop's skills and the workstation's subagent imported or removed on the operator's word; the
|
||||
laptop's `settings.json` as the operator's settings; the retired `cleanup` skill and the three stale
|
||||
instruction files found on four nodes on 2026-10-09 removed with copies kept. Each is a condition until
|
||||
imported or removed.
|
||||
|
||||
**Lessons.** The module keeps a `lessons` register in its state: per lesson, when and on which node it was
|
||||
proposed, the session where known, the **trigger** (the operator's words), the **cause** (what the agent did),
|
||||
the **rule** (a personal rule in the operator's second person), an optional **before** (a tool name, command
|
||||
prefix or path pattern), and its state — `proposed`, `accepted` with who, how and when, or `declined` with the
|
||||
reason. The mesh's instruction section tells every agent to record a lesson, in the same turn, when the
|
||||
operator expresses frustration or corrects a way of working, after first working out why, and to say in one
|
||||
line that it did.
|
||||
|
||||
- **A proposed lesson is not a rule.** It is rendered nowhere. The module shows it to the operator for a yes:
|
||||
an approve ask with Accept and Decline, or, while no channel answers approve, the list tool shows it and the
|
||||
operator accepts or declines at the terminal (`lessons_accepted`, `lessons_declined`). A proposal expires
|
||||
after 30 days, declined with that reason.
|
||||
- **An accepted lesson is a personal rule**, registered at the operator scope with the lesson as its source,
|
||||
rendered into every agent's home, and named in the home instruction file as accepted from that lesson.
|
||||
- **A declined lesson stays**, with its reason; a new proposal whose rule matches a declined one is refused
|
||||
with that reason, and the agent is told to raise it with the operator instead.
|
||||
- **The agent is reminded.** The plugin's session-start hook (the module's own binary, beside the guard)
|
||||
prints at session start the rules accepted from lessons in the last 30 days and those whose `before`
|
||||
matches the working directory or repository. Before a tool runs, the guard prints the rule of every
|
||||
accepted lesson whose `before` matches the tool, command or path — a reminder, once per session per rule,
|
||||
never a refusal.
|
||||
- **The register is readable by any agent on any node** through the list tool, each state marked, so a
|
||||
proposal is never read as a rule. Recording a proposal needs no yes.
|
||||
|
||||
**The tools of this section**: `claude_code_personal_rule_register`, `_list`, `_unregister`;
|
||||
`claude_code_personal_settings_get`, `_set`; the existing register tools with `scope: operator` for skills,
|
||||
commands and subagents; `claude_code_config_import` taken again, at the operator scope, by the two routes;
|
||||
`claude_code_config_status` extended with the drift findings and the unknown entries;
|
||||
`claude_code_lesson_register`, `_list`, `_accept`, `_decline`. Every tool that writes into the operator's
|
||||
home goes through the two routes above.
|
||||
|
||||
## How it is checked
|
||||
|
||||
| Check | Defends |
|
||||
@@ -373,8 +485,14 @@ a login).
|
||||
| a switch asked of the seat through the mesh MCP server 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 module's render test: a registered skill, subagent, command, hook and output style land in the `nox-mesh` plugin; a tool server, a setting and an instruction section in their managed files; for one machine of two, a mesh item on both, a node item on one, a home item only in that home; a setting naming the marketplace keys is overridden | ADR 0216 |
|
||||
| the module's test: a home name the person already uses is refused, unregistering removes only the placed path, and an item above 256 KiB is refused | ADR 0216, ADR 0182 |
|
||||
| the module's render test: a registered skill, subagent, command and output style land in the `nox-mesh` plugin (a hook and a setting are refused since issue 340, and the terminal's land from the module's settings); a tool server and an instruction section in their managed files; for one machine of two, a mesh item on both, a node item on one, a home item only in that home; a setting naming the marketplace keys is overridden | ADR 0216, issue 340 |
|
||||
| the module's test: a name registered twice is refused, unregistering removes only the rendered path, and an item above 256 KiB is refused | ADR 0216, ADR 0182 |
|
||||
| the module's render test over a seeded home: every configuration path of §10 matches the registrations byte for byte, every excluded entry is byte-identical before and after, an unknown entry is reported; a program-written key of `settings.json` is taken over into the operator's settings, a key outside the list is drift | ADR 0273 §1 |
|
||||
| the module's render test for one machine of three: a personal rule lands under `rules/` and in the home instruction file in the operator's own home on two and in the agent account's home on the third; a hook, a permission rule, a tool server and an item holding a shell line are refused at the operator scope | ADR 0273 §2 |
|
||||
| the module's tests through its real tool dispatch: a register, import or remove at the operator scope, or for an operator's home, publishes an ask and writes nothing; with a warrant for that ask it acts once; another ask's warrant, or a replayed one, is refused; while no channel answers approve the ask is refused naming the terminal's line | ADR 0273 §3, issue 340 |
|
||||
| the module's tests: a file nobody rendered is reported and left; a rendered file changed by hand is written back and its hand version kept and shown; a missing one is rendered again; the condition clears on a clean look; the controller's test that `agent-home-drift` is a warning the first-node gate never reads as a fault; the guard refuses a write, append, copy, move, in-place edit and removal under each rendered path naming the tool, and lets `projects/` alone | ADR 0273 §4 |
|
||||
| the module's tests over the lessons register: register, list, accept, decline, expiry; only accepted lessons reach `rules/`; a proposal matching a declined rule is refused with the reason; the session-start hook prints the recent and matching rules; the guard prints a matching rule once per session and refuses nothing for it | ADR 0273 §5 |
|
||||
| live: on the laptop, `~/.claude` holds the rendered configuration and the working state and nothing else; a rule written by hand into `rules/` raises `agent-home-drift` within a minute; a rule set at the terminal is in a new session on every node; a correction given in a session is in the lessons list in that turn, accepted at the terminal, and named at the start of the next session on another node | ADR 0273, the exit of WP7–WP9 |
|
||||
| live: a skill registered at the mesh scope is offered as `nox-mesh:<name>` in a new session on each machine | ADR 0216 |
|
||||
| the module's test: the "instead of" table is generated from the controller's answers, ordered and cut; the guard refuses ssh to a mesh machine by name, domain, internal name, address, alias and jump, and the local work-arounds for a mesh name, naming the tool — and lets git to the forge, ssh beyond the mesh and a command merely mentioning ssh through; the override is honoured only from the session's start and only when recorded | ADR 0245 |
|
||||
| the mesh MCP server's provision resolves by co-location; a machine without the mesh MCP server refuses the module by name | ADR 0027, ADR 0152 |
|
||||
@@ -392,6 +510,8 @@ a login).
|
||||
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).
|
||||
- **A per-project lesson, lessons for an agent the mesh runs, and a surface of the operator's own** that can
|
||||
tell the operator from an agent, which would be a third route into the operator's home (ADR 0273).
|
||||
- **How the module's tools are run** is decided: the node's tool runner, host-side
|
||||
([ADR 0175](../../02-DECISIONS/0175-one-tool-runtime-per-node-serves-every-modules-tools-on-the-host-side.md)).
|
||||
The managed files and the credential write are tools of this module that runtime serves. Until the
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
---
|
||||
layer: to-be
|
||||
status: implemented
|
||||
status: in-progress
|
||||
code: [mesh-catalog modules/claude-code, mesh-catalog modules/claude-licence-manager]
|
||||
updated: 2026-10-04
|
||||
updated: 2026-10-09
|
||||
decisions:
|
||||
- 02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.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/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
|
||||
@@ -194,6 +195,109 @@ designs 36 and 39 set to `implemented` with the as-is written
|
||||
**Proof.** `claude_code_status` answers on every node; the refusal's notification arrived; the catalogue
|
||||
has no module built on the old placement.
|
||||
|
||||
## The home, personal rules and lessons — WP7 to WP10
|
||||
|
||||
*Added 2026-10-09 by [ADR 0273](../../02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md);
|
||||
design 36 §10 is the authority on what is built.* WP0–WP6 ran and stay as recorded above; these four packages
|
||||
open the document again. All of it is in `mesh-catalog`, in the `claude-code` module, except where a line
|
||||
says otherwise. The controller needs nothing new: the module's settings layer is already the terminal's
|
||||
(issue 340), and the asker's client is the shared library's (ADR 0259 §10 step 3).
|
||||
|
||||
```
|
||||
WP7 the home is the module's: render, drift, guard (mesh-catalog) ── two days
|
||||
WP8 personal rules and the operator's items, live (the live mesh) ── half a day, the operator's
|
||||
WP9 lessons: register, ask, reminders, the instruction section (mesh-catalog) ── two days
|
||||
WP10 the rest of the nodes, and the as-is (the live mesh) ── half a day
|
||||
```
|
||||
|
||||
### WP7 — The home is the module's
|
||||
|
||||
*mesh-catalog. Two days.*
|
||||
|
||||
1. **The manifest.** The module `uses` the `operator-channel` seat, as an asker. New settings, each a list
|
||||
of items whose text is a list of lines (a setting holds no line break, issue 339): `personal_rules`,
|
||||
`personal_skills`, `personal_commands`, `personal_agents`, `personal_settings`, `lessons_accepted`,
|
||||
`lessons_declined`. New state buckets: `personal` (the operator-scope registrations and the lessons
|
||||
accepted into them), `lessons` (WP9), `home-copies` (the hand versions and the removal copies ADR 0243
|
||||
already keeps). The documentation gains the two lists of design 36 §10: the rendered paths and the
|
||||
excluded working state.
|
||||
2. **The renderer.** From the operator-scope registrations and the terminal's settings, the home instruction
|
||||
file, `rules/`, `skills/`, `commands/`, `agents/`, an empty `hooks/` and `settings.json`, written as the
|
||||
agent's account (through §9's helper where that is an agent account), only when content changed, and a
|
||||
record of what was rendered. The program-written keys of `settings.json` taken over into `personal_settings`
|
||||
when the program changes them.
|
||||
3. **Drift.** A comparison on every look and on a file watch, bounded to the rendered paths; findings in the
|
||||
module's health statement (ADR 0240) naming each path and what differs; the hand version of a changed file
|
||||
kept in `home-copies` before it is written back; a file nobody rendered left and reported. The controller:
|
||||
the condition kind `agent-home-drift`, a warning that needs the operator, exempt at the first-node gate as
|
||||
the relogin and directory-used-as-found kinds are (one small change in `mesh-controller`).
|
||||
4. **The two routes.** Every register, import and remove tool at the operator scope or for an operator's
|
||||
home publishes an approve ask through the asker's client, with the item in full and a digest over text,
|
||||
name, kind and scope, and acts once on the warrant; while the router carries no channel that answers
|
||||
approve for this module, it refuses at once naming the terminal's line. The home scope into an agent
|
||||
account's own home stays as issue 340 built it.
|
||||
5. **The guard.** A refusal of any shell command or file edit whose target is under a rendered path (a
|
||||
redirect, append, copy, move, in-place edit, removal), naming the tool; nothing for the working state;
|
||||
the override of ADR 0245 §5.
|
||||
6. **The tools.** `claude_code_personal_rule_register`, `_list`, `_unregister`;
|
||||
`claude_code_personal_settings_get`, `_set`; `scope: operator` on the skill, command and agent register
|
||||
tools; `claude_code_config_import` taken again at the operator scope by the two routes;
|
||||
`claude_code_config_status` extended with the drift findings and the entries the module knows under
|
||||
neither list.
|
||||
|
||||
**Proof, before anything runs live.** The module's tests of design 36 "How it is checked" for ADR 0273 §1,
|
||||
§2, §3 and §4, each failing on the commit before. The catalogue's checks pass.
|
||||
|
||||
### WP8 — Personal rules and the operator's items, live
|
||||
|
||||
*The live mesh. Half a day, and it is the operator's.* One workstation first, as every package here.
|
||||
|
||||
1. The module with WP7 reaches the laptop. `agent-home-drift` is raised there, naming the two rules, the
|
||||
five skills, `settings.json` and nothing else.
|
||||
2. At the terminal the operator sets `personal_rules` with the two rules, `personal_settings` with the six
|
||||
keys, and `personal_skills` with the skills they keep; removes the rest with the removal tool, copy kept.
|
||||
The condition clears.
|
||||
3. The module reaches the other three nodes. On each, the condition names the retired `cleanup` skill and
|
||||
the instruction file (and the workstation's subagent); the operator removes or imports each, once.
|
||||
|
||||
**Proof.** On every node `~/.claude` holds the rendered configuration and the program's working state and
|
||||
nothing else; a new session on the workstation has the laptop's two rules in its context; a rule written by
|
||||
hand into `rules/` on the laptop raises the condition within a minute and is written back on the next render
|
||||
with the hand version shown by the status tool.
|
||||
|
||||
### WP9 — Lessons
|
||||
|
||||
*mesh-catalog. Two days.*
|
||||
|
||||
1. **The register**: the `lessons` bucket; `claude_code_lesson_register` (trigger, cause, rule, optional
|
||||
before; refused when its rule matches a declined lesson's, with the reason), `_list` (the three states
|
||||
marked apart), `_accept` and `_decline` (the two routes of WP7 step 4, since they write into the
|
||||
operator's home); expiry of a proposal after 30 days; `lessons_accepted` and `lessons_declined` read
|
||||
from the terminal's settings.
|
||||
2. **Accepted lessons as personal rules**: registered at the operator scope with the lesson as their source;
|
||||
the home instruction file names each as accepted from its lesson.
|
||||
3. **The reminders**: a session-start hook in the `nox-mesh` plugin, the module's own binary, printing the
|
||||
rules accepted in the last 30 days and those whose `before` matches the working directory or repository;
|
||||
the guard printing the rule of a matching accepted lesson once per session before the tool runs,
|
||||
refusing nothing for it.
|
||||
4. **The instruction section**: the mesh's `working-on-the-mesh` section gains the paragraph of design 36
|
||||
§10 on when an agent records a lesson, and the `talking-to-the-operator` section one line saying the agent
|
||||
says in one line that it did. Both are set at the terminal, as every mesh-wide section is since issue 340.
|
||||
|
||||
**Proof, before anything runs live.** The module's tests for ADR 0273 §5 in design 36 "How it is checked".
|
||||
|
||||
**Proof, live, on one workstation.** In a session, the operator corrects a way of working; the lesson is in
|
||||
`claude_code_lesson_list` in that turn; the operator accepts it at the terminal; the next session on another
|
||||
node names it at start; a tool whose name matches its `before` is preceded by the rule once.
|
||||
|
||||
### WP10 — The rest of the nodes, and the as-is
|
||||
|
||||
*The live mesh. Half a day.* WP9 on every node; the as-is of the agent
|
||||
([00-as-is/15](../00-as-is/15-the-agent-and-its-licences.md)) rewritten to say what the home holds and how
|
||||
a lesson travels; design 36 and this document set to `implemented` ([playbook 02](../../00-META/process/02-graduation.md)).
|
||||
|
||||
**Proof.** The live line of ADR 0273's "How it is checked", on every node.
|
||||
|
||||
## What is deliberately not here
|
||||
|
||||
- **The package repository seat** for a distribution that does not carry the agent's package (design 36
|
||||
@@ -213,4 +317,5 @@ Each package's proof is run when the package is finished and its line here gains
|
||||
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 WP2's live proof runs, design 36 moves to `in-progress` with its owning
|
||||
repository; when WP5's does, design 39 does too; and when WP6's does, both move to `implemented`, with
|
||||
the as-is written.
|
||||
the as-is written. WP6's did, on 2026-10-04. ADR 0273 opened WP7–WP10 on 2026-10-09, so design 36 and this
|
||||
document are `in-progress` again until WP10's proof runs.
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ status: located
|
||||
opened: 2026-10-09
|
||||
located-in: [mesh-catalog (modules/claude-code), mesh-controller (internal/catalogue/terminal_keys.go)]
|
||||
fixed-by:
|
||||
amended-design:
|
||||
amended-design: 03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md
|
||||
---
|
||||
|
||||
# 340. An agent can plant a hook in every agent session on the mesh
|
||||
|
||||
Reference in New Issue
Block a user