From 064d77217a145a081b18d96c1071cc624925f20d Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Mon, 21 Sep 2026 17:46:39 +0200 Subject: [PATCH] fix(setup): recognise the agent-guard plugin as a complete install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check 3 of `setup-isolated-setup-update` diffs `~/.claude/scripts/agent-guard.py` and `~/.claude/scripts/guards.d/` against the framework, and check 4 looks for an agent-guard `hooks.PreToolUse` entry in `settings.json`. Neither exists on the install path the tool's own README calls "the whole installation": the `magpie-agent-guard` plugin registers the hook from its manifest and resolves the engine and every skill-owned guard under `${CLAUDE_PLUGIN_ROOT}`. A drift run against a working plugin install therefore reports the guard as missing and sends the operator installing a second copy of something already running. Observed on an install where the plugin was enabled and both guards demonstrably fired. Establish the wiring first: read `enabledPlugins`, and on a plugin install report the plugin's version against the framework's and any leftover user-scope copy, rather than the absence of a script that belongs to the other wiring. Keep the script/`guards.d` diff for the user-scope path, and give both a behavioural canary — a `git commit` carrying a `Co-Authored-By:` trailer must be denied — so the check rests on the guard denying rather than on files being present. Generated-by: Claude Opus 5 --- docs/mode-economics.md | 4 +-- docs/vendor-neutrality.md | 4 +-- .../skills/isolated-setup-update/SKILL.md | 35 ++++++++++++++++--- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/docs/mode-economics.md b/docs/mode-economics.md index fe6c2bc3..be23f347 100644 --- a/docs/mode-economics.md +++ b/docs/mode-economics.md @@ -92,7 +92,7 @@ special-token spellings counted as ordinary text. Coverage: **75 of 75 local `skills/*/SKILL.md` files**. External `source.md` redirects and harness symlinks are excluded. -Measurement manifest SHA-256: `d4084d97d203d0df2895a57eea81b74334fcb357c4ca6db7a8b2918ab579a026`. +Measurement manifest SHA-256: `eba45d94594422dcafe69f05a325439ac695e06487ac25cae6e753d2259de9f6`. | Skill file | Measured tokens | Source SHA-256 (first 16 characters) | |---|---:|---| @@ -161,7 +161,7 @@ Measurement manifest SHA-256: `d4084d97d203d0df2895a57eea81b74334fcb357c4ca6db7a | [setup](../skills/setup/SKILL.md) | 8,724 | `82788542bb240309` | | [setup-isolated-setup-doctor](../skills/setup-isolated-setup-doctor/SKILL.md) | 7,950 | `3fa5d728fa080ed0` | | [setup-isolated-setup-install](../skills/setup-isolated-setup-install/SKILL.md) | 11,278 | `418ea9794077c6e9` | -| [setup-isolated-setup-update](../skills/setup-isolated-setup-update/SKILL.md) | 5,214 | `97dabfc08b915b4a` | +| [setup-isolated-setup-update](../skills/setup-isolated-setup-update/SKILL.md) | 5,561 | `a49d7d987bf50109` | | [setup-isolated-setup-verify](../skills/setup-isolated-setup-verify/SKILL.md) | 8,502 | `6f0a2594801bdf27` | | [setup-override-upstream](../skills/setup-override-upstream/SKILL.md) | 4,012 | `fb583feb56b7f77c` | | [setup-privacy-llm](../skills/setup-privacy-llm/SKILL.md) | 2,145 | `0e27b542a1656846` | diff --git a/docs/vendor-neutrality.md b/docs/vendor-neutrality.md index f0b9623d..10b1f9f5 100644 --- a/docs/vendor-neutrality.md +++ b/docs/vendor-neutrality.md @@ -584,8 +584,8 @@ generated block below. | Skill neutrality | Count | |---|---| -| capability-pure (names no backend) | 14 | -| portable (named backends are swappable) | 61 | +| capability-pure (names no backend) | 13 | +| portable (named backends are swappable) | 62 | | vendor-coupled (sole-backend dependency) | 0 | Organization scope (declared, orthogonal to vendor): ASF = 14, agnostic = 61. diff --git a/plugins/magpie-setup/skills/isolated-setup-update/SKILL.md b/plugins/magpie-setup/skills/isolated-setup-update/SKILL.md index ac68f560..88501d89 100644 --- a/plugins/magpie-setup/skills/isolated-setup-update/SKILL.md +++ b/plugins/magpie-setup/skills/isolated-setup-update/SKILL.md @@ -224,7 +224,23 @@ Walk each: [`setup-isolated-setup-install`](../isolated-setup-install/SKILL.md) re-run on the affected Step P sub-step. - Also diff the agent-guard hook the same way: + **The agent-guard hook — establish which wiring is in use before + diffing anything.** Read `enabledPlugins` in + `~/.claude/settings.json`: when it lists + `magpie-agent-guard@apache-magpie`, the guard runs **from the + installed plugin**, whose manifest registers the `PreToolUse` + hook and resolves the engine and every skill-owned guard under + `${CLAUDE_PLUGIN_ROOT}`. There is then no user-scope copy to diff + and no `guards.d` to sync: an absent + `~/.claude/scripts/agent-guard.py` is the expected shape, **not + drift**, and reporting it as missing sends the user installing a + second copy of a guard that is already running. What is worth + surfacing for a plugin install is the plugin's own version + against the framework's (a refresh is `/plugin`), and any + leftover user-scope copy from an earlier hand-wiring. + + Only when the plugin is **not** enabled does the user-scope + wiring apply, and then diff it the same way as the other scripts: `~/.claude/scripts/agent-guard.py` against the framework's `tools/agent-guard/src/agent_guard/__init__.py`, and the `~/.claude/scripts/guards.d/` directory against the union of the @@ -233,10 +249,16 @@ Walk each: locally-added `*.py` are expected; flag only missing framework/skill guards or stale copies). A new skill guard (or a skill newly adding one) appearing in the framework but absent - from the user's `guards.d` is the most common drift once the hook - is wired — re-syncing `guards.d` activates it with **no + from the user's `guards.d` is the most common drift on that + wiring — re-syncing `guards.d` activates it with **no `settings.json` change**. + Either way, confirm the guard actually denies. A `git commit` + whose message carries a `Co-Authored-By:` trailer is the cheap + canary: the bundled `commit-trailer` guard blocks it before the + commit runs, so a command that goes through means the hook is + not firing, whatever the files and settings say. + **Rename migration — `claude-iso.sh` → `agent-iso.sh`.** The clean-env launcher was renamed (it now isolates **OpenCode** as well as Claude Code, exposing both a `claude-iso` and an @@ -261,8 +283,11 @@ Walk each: `allowedDomains` entries, new `permissions.deny` patterns for newly-discovered exfiltration paths, **or the agent-guard `hooks.PreToolUse` entry** (matcher `Bash`) if the user wired - the secure setup before the guard shipped. Report new entries - the user does not have; do not auto-merge. + the secure setup before the guard shipped and does not have the + `magpie-agent-guard` plugin enabled — with the plugin, that hook + comes from the plugin manifest and its absence from + `settings.json` is correct. Report new entries the user does not + have; do not auto-merge. Two `sandbox.network.*` settings are worth a look while diffing — but neither is a "missing default" to re-add: