claude-code: point the agent at the mesh's tools and guard its shell against ssh to the mesh (hq ADR 0245)

The agent kept running ssh <machine> journalctl while the journal verb existed. The managed
instructions now carry an "instead of" table generated from what each verb says it replaces, and
the plugin carries a PreToolUse guard that refuses ssh to a mesh machine and local work-arounds for a
mesh name, naming the tool or saying one must be created. The operator's override is read from the
session's start environment and recorded.
This commit is contained in:
jochen
2026-10-07 20:27:31 +02:00
parent ba6058abb9
commit 24a3fac2ba
13 changed files with 2033 additions and 14 deletions
@@ -94,8 +94,9 @@ func TestEachKindLandsInItsOnePlace(t *testing.T) {
} `json:"hooks"`
}
_ = json.Unmarshal([]byte(plugin[root+"hooks/hooks.json"].Content), &hooks)
if pre := hooks.Hooks["PreToolUse"]; len(pre) != 1 || pre[0].Matcher != "Bash" ||
pre[0].Hooks[0].Command != `"${CLAUDE_PLUGIN_ROOT}/hooks/guard"/guard.sh` {
// The mesh's own guard on the shell first (novox/hq ADR 0244), then the hook registered.
if pre := hooks.Hooks["PreToolUse"]; len(pre) != 2 || pre[0].Matcher != GuardMatcher || pre[0].Hooks[0].Command != GuardCommand() ||
pre[1].Matcher != "Bash" || pre[1].Hooks[0].Command != `"${CLAUDE_PLUGIN_ROOT}/hooks/guard"/guard.sh` {
t.Errorf("the hook's command does not name its directory, quoted: %s", plugin[root+"hooks/hooks.json"].Content)
}
if !strings.Contains(w["CLAUDE.md"], "### conventions\n\nCommit in the imperative.") {