From 302ab2856a1739d26e8c26c73c5144515babebcc Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 21 Oct 2026 19:27:33 +0200 Subject: [PATCH 1/3] Design 36: the plugin's session-start and Stop hooks beside the guard (ADR 0489, ADR 0490) Delivered in mesh-catalog#420 on 2026-10-21; the design said the guard was the plugin's only hook. --- .../01-to-be/36-the-operators-agent-on-a-machine.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md b/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md index cd987d6e..62da3317 100644 --- a/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md +++ b/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md @@ -157,6 +157,16 @@ does the job, or with the rule that a missing tool is created in its owning modu managed directory, so a session cannot change it, judges with the machines and replaced commands the module last asked of the controller, and records every refusal and every operator's override in the module's state. +**The wait list and the Stop hook** (ADR 0489, ADR 0490). Beside the guard the plugin carries two more of the +module's own commands as hooks. At every session start the session-start hook prints the session's id and every +open wait on the machine by the name it is kept under, with the call that takes a name back after a /clear (which +gives a session a new id). At every stop the Stop hook reads the session's waits, which `claude_code_wait` keeps +in the module's state under the session's name (who@node) and mirrors into the agent's home, and refuses the stop +while a wait is within its bound and nothing follows it, or past its bound and not yet told to the operator; it +lets the stop through silently when there are no waits, says so on the screen when the list cannot be read, and +refuses the same stop at most three times. Like the guard, both hooks ship in the plugin only: the hook +registration tools still refuse every hook (issue 340). + ## 4. The mesh MCP server > **Revised 2026-10-03, building it.** The vendor's managed-settings key for tool servers refuses any -- 2.54.0 From 9483caae2d57ea9be87a79595d36644fbcdf570b Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 21 Oct 2026 19:29:38 +0200 Subject: [PATCH 2/3] Design 36: the waits mirror is the module's own entry in the agent's home; the hook tools refuse mesh and node scope Review of the hooks paragraph: the mirror in the agent's home was not in the home's table, so the home look would count it as drift. --- 03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md b/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md index 62da3317..2017e33f 100644 --- a/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md +++ b/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md @@ -165,7 +165,7 @@ in the module's state under the session's name (who@node) and mirrors into the a while a wait is within its bound and nothing follows it, or past its bound and not yet told to the operator; it lets the stop through silently when there are no waits, says so on the screen when the list cannot be read, and refuses the same stop at most three times. Like the guard, both hooks ship in the plugin only: the hook -registration tools still refuse every hook (issue 340). +registration tools refuse a hook at mesh or node scope (issue 340). ## 4. The mesh MCP server @@ -415,6 +415,7 @@ the helper of §9 where that is an agent account): | `rules/.md` | one personal rule each | | `skills//`, `commands/.md`, `agents/.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 | +| `nox-mesh/waits/.json`, `nox-mesh/waits/_index.json` | the module's own mirror of each session's waits and the machine's open names (ADR 0489, ADR 0490), written whole by `claude_code_wait` and read by the plugin's session-start and Stop hooks; rebuilt from the module's state, never a person's | | `output-styles/.md`, `keybindings.json` | the operator's output styles and keybindings at the operator scope | | `settings.json` | the operator's registered settings, preference keys only, 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. A key that decides what runs (`hooks`, `permissions`, `mcpServers`, `env`, `apiKeyHelper`, `statusLine`, `autoMode`, any key not on the list) is never taken over: changed on disk, it is written back on the look that finds it. `autoMode` is a permission rule, so it lives in the managed settings at the terminal | -- 2.54.0 From ac72fe64222911b868530b02bd1028f22e58483c Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 21 Oct 2026 19:30:21 +0200 Subject: [PATCH 3/3] Design 36: the waits mirror's file is named by Claude Code's session id --- 03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md b/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md index 2017e33f..0c1652fa 100644 --- a/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md +++ b/03-DESIGN/01-to-be/36-the-operators-agent-on-a-machine.md @@ -415,7 +415,7 @@ the helper of §9 where that is an agent account): | `rules/.md` | one personal rule each | | `skills//`, `commands/.md`, `agents/.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 | -| `nox-mesh/waits/.json`, `nox-mesh/waits/_index.json` | the module's own mirror of each session's waits and the machine's open names (ADR 0489, ADR 0490), written whole by `claude_code_wait` and read by the plugin's session-start and Stop hooks; rebuilt from the module's state, never a person's | +| `nox-mesh/waits/.json`, `nox-mesh/waits/_index.json` | the module's own mirror (ADR 0489, ADR 0490): per Claude Code session id, the open waits of every name bound to that id; and the machine's open names, written whole by `claude_code_wait` and read by the plugin's session-start and Stop hooks; rebuilt from the module's state, never a person's | | `output-styles/.md`, `keybindings.json` | the operator's output styles and keybindings at the operator scope | | `settings.json` | the operator's registered settings, preference keys only, 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. A key that decides what runs (`hooks`, `permissions`, `mcpServers`, `env`, `apiKeyHelper`, `statusLine`, `autoMode`, any key not on the list) is never taken over: changed on disk, it is written back on the look that finds it. `autoMode` is a permission rule, so it lives in the managed settings at the terminal | -- 2.54.0