Purpose
Setup per the uniform setup contract (docs/PLUGIN-PHILOSOPHY.md "Setup is explicit and repeatable" in
the marketplace repository): check inspects and reports, apply resolves. This plugin declares no
userConfig, and has two setup concerns:
- the external command-line tools its bundled scripts require, where
apply is guidance-and-verify
with no write path: it points at platform install instructions and never installs a system package;
- the tracked consumer-project configuration
audit-pass reads, the suppression record at
.claude/audit-pass.md, the one surface apply may write.
Action routing: no argument or check runs the check; apply runs the check first, then remediation.
Both are non-interactive, so never prompt when the action is given.
check (read-only)
The bundled scripts are the single source of truth for what this plugin requires.
Read it first. Probe what it actually does, don't recite this file. Then run each probe via
Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything.
The runtime scripts and their tools:
${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/check-plugin-drift.sh: jq and curl, plus awk and sort
${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/check-structure.sh and check-hook-coverage.sh: jq; fix-plugin-drift.sh: jq plus sort
${CLAUDE_PLUGIN_ROOT}/skills/audit-automation-gaps/scripts/inventory.sh: jq
${CLAUDE_PLUGIN_ROOT}/skills/audit-permission-grants/scripts/permission-rule-check.sh: jq plus awk and sort
${CLAUDE_PLUGIN_ROOT}/skills/audit-permission-state/scripts/*.sh: jq (required; permission-state.sh exits 2 without it), awk and sort; automode-block-lint.sh and automode-entry-diff.sh add python3 for an optional lane
${CLAUDE_PLUGIN_ROOT}/skills/draft-auto-mode-rules/scripts/draft-automode-block.sh: jq plus awk
${CLAUDE_PLUGIN_ROOT}/skills/audit-pass/scripts/run-state.sh and ${CLAUDE_PLUGIN_ROOT}/lib/check-retirements.sh: jq (run-state.sh falls back to python3, then to a scan that announces itself)
${CLAUDE_PLUGIN_ROOT}/skills/audit-instructions/scripts/instruction-scan.sh: grep only (POSIX; no jq)
${CLAUDE_PLUGIN_ROOT}/skills/audit-instructions/scripts/conflict-scan.sh: awk and sort (no jq)
Only conflict-scan.sh and permission-state.sh probe for their tools; the rest call them with no
guard, so read each script's actual calls rather than trusting a single script's prerequisite block to
speak for the plugin.
jq, via command -v jq. FAIL if absent: the JSON-parsing scripts need it (inventory.sh degrades
to an empty inventory; the others exit 2 with an install remediation). Missing jq blocks every
skill whose scripts parse JSON (audit, audit-automation-gaps, audit-permission-grants,
audit-permission-state, draft-auto-mode-rules, and audit-pass's run-state and retirement
helpers); audit-instructions scans markdown and is unaffected.
curl, via command -v curl. FAIL if absent, but scoped: only the plugin-drift check
(check-plugin-drift.sh) uses it and exit 2s without it. The rest of audit and every other
skill still run; say so in the remediation line.
awk and sort, via command -v awk and command -v sort. FAIL if either is absent, and not
scoped to one skill: conflict-scan.sh executes both and exit 2s naming the missing one, while
check-plugin-drift.sh (both), permission-rule-check.sh (both), and fix-plugin-drift.sh
(sort) reach them with no prerequisite check at all, so audit and audit-permission-grants
fail mid-run on a bare command not found rather than on a named prerequisite. Say in the
remediation line that this FAIL reaches three skills, not just audit-instructions. Report awk
and sort by name rather than as one row, since a minimal shell can carry one and not the other.
- Bash shell, INFO: the scripts are bash (arrays,
[[ ]], process substitution, BASH_SOURCE),
run through Claude Code's Bash tool, which is the bash shell on every platform and Git Bash on native Windows.
Report the resolved interpreter; FAIL only if no bash is resolvable.
- Network reachability, INFO only:
audit's drift/freshness fetches read
raw.githubusercontent.com, and a failed fetch degrades to SKIP rather than a setup failure. Do not
fetch here; check performs no network call.
The audit-pass suppression record
audit-pass reads a tracked suppression record layered per the marketplace's config-cascade
convention. Read the operative shape from
${CLAUDE_PLUGIN_ROOT}/skills/audit-pass/reference/suppression.md rather than inferring it. That
reference ships inside this plugin, so it resolves in an installed cache where a path out to the
marketplace's own docs does not. The cross-consumer key contract is the marketplace's published
finding-suppression convention, which is not a runtime dependency of this plugin. All layers
absent is a valid state (no suppressions), so report INFO, never FAIL, when none exists.
Anchor at the repo root (${CLAUDE_PROJECT_DIR}, else git rev-parse --show-toplevel), never a
CWD-relative read, which resolves a different (or missing) file depending on the subdirectory or
nested worktree the skill was invoked from, then report one row per layer. The same
tracked/ignored question has opposite correct answers per layer, so verify each on its own terms:
- user-global
~/.claude/audit-pass.md: outside the worktree; no git command applies. INFO only.
- team
.claude/audit-pass.md: must be tracked, probed as the pair —
git check-ignore -v reports no match (a match is FAIL with the pattern) AND
git ls-files --error-unmatch exits 0. Untracked while present is a hard STOP:
teammates never receive the shared suppressions.
- local overlay
.claude/audit-pass.local.md: must be gitignored and never staged. Staged or
tracked is a FAIL: a personal deviation can reach team history.
Parse each present layer and report as malformed any entry missing any of its five required
keys: check, claim, sites, reason, date. Checking only reason and date would pass an
entry that audit-pass itself rejects, so readiness would report green on configuration that cannot
suppress anything. Report as malformed too an entry whose stored constituents do not hash to its own
key: the constituents are authoritative and the key is derived from them. A malformed entry does not
suppress, and a silent partial parse would turn a formatting slip into a lost check.
Report a user-global or overlay entry for an id the team layer does not carry as INFO
personal-only, not applied, naming promotion to the team layer as what makes it take effect. The
team layer is the only one that enacts a suppression, so a personal-only entry that looks live is a
finding the operator believes is accepted and is not.
apply (idempotent)
Run check, then for each FAIL give the platform install instructions from the README Requirements.
This skill never installs system packages:
- missing
jq: the platform's jq install (for example winget install jqlang.jq, brew install jq, or apt-get install jq); rerun check after.
- missing
curl: the platform's curl install. Modern Windows and Git Bash already ship curl.
Only the plugin-drift check needs it, so the rest of the plugin works meanwhile.
- missing
awk or sort: both ship with every POSIX userland, so absence means the shell
environment is minimal rather than that one package is missing. Git Bash and Windows busybox
shims are where this shows up. Remediate by installing a full userland rather than the single tool:
Git for Windows, which bundles both; the distribution's gawk/mawk and coreutils on Linux;
brew install gawk coreutils on macOS. Report the two separately, since a minimal shell can carry
one and not the other. Five skills depend on them (audit, audit-permission-grants,
audit-permission-state, draft-auto-mode-rules, and audit-instructions), and only
conflict-scan.sh and permission-state.sh exit 2 cleanly, so do not offer the others as still
working meanwhile.
- no resolvable bash: also not remediable by one package. The scripts use arrays,
[[ ]],
process substitution, and BASH_SOURCE, so they need a real bash on PATH: Git for Windows on
native Windows, the distribution's bash elsewhere. Nothing bundled runs until it resolves, so
say that this FAIL blocks the plugin rather than offering a partial workaround.
The network row stays INFO and has no apply entry on purpose: a failed fetch degrades to SKIP by
design, so there is nothing to remediate.
After any install, re-run the relevant check probe and report its actual result. Never claim resolved
on the install command's exit code alone. Re-running apply once every probe passes changes nothing and
reports "already configured".
Then converge the one surface this plugin owns, conservatively:
- No suppression record anywhere: leave it that way and say so. Absent is valid; an empty
scaffold is noise. Scaffold the team layer with the documented shape only on an explicit request.
- Team layer present but untracked: report the STOP and the exact
git add the operator should
run. Never stage on their behalf.
- Overlay present but not ignored: recommend the recursive
.claude/**/*.local.* line and leave
the .gitignore edit to the consumer.
- Malformed or unrecognized entries: report them and stop. Never rewrite, reorder, or drop an
operator's suppression: an entry this skill cannot reconcile is a question for the operator, and a
silent rewrite would hide the very finding the entry was suppressing.
Every write names the file and the exact change before making it, and preserves unrelated content.
Gotchas
- Never run a git command against the user-global layer.
~/.claude/audit-pass.md is outside the
worktree, so git check-ignore and git status return a meaningless verdict there, or a
confidently wrong one when the home directory is itself a git repository.
- Missing config is not a failure. All three suppression layers absent means no suppressions,
which is the normal state for a repo that has never suppressed a finding. INFO, never FAIL.
- Recommend the recursive gitignore line, and leave the edit to the consumer.
.claude/**/*.local.*
covers flat, folder-form, and profiled overlays alike; the narrower .claude/*.local.* silently
misses any nested overlay. The consumer's ignore file is their artifact; this skill never writes it.
- An install command's exit code is not verification. After any install, re-run the probe and
report its actual result.
What this skill does NOT do
- Run an audit; that is the plugin's audit and drafting skills (
/claude-config:audit,
audit-automation-gaps, audit-instructions, audit-pass, audit-permission-grants,
audit-permission-state, audit-prompting-postures, draft-auto-mode-rules, unhobble).
- Write the plugin cache, Claude Code user settings, or
pluginConfigs.
- Install system packages.
- Write the consumer's
.gitignore, stage anything, or edit an operator's suppression entries.
- Download anything.
check makes no network call; the audit skills' own doc/marketplace fetches are
theirs, not setup's.
1---2name: setup-393description: Verify claude-config's readiness for this repository: the external CLI prerequisites its audit scripts need, jq (the JSON-parsing audit scripts) and curl (the plugin-drift check), and the tracked suppression record audit-pass reads at .claude/audit-pass.md, so the audit skills run instead of failing. Use when: 'set up claude-config', 'configure claude-config', 'is claude-config working', 'set up audit-pass suppressions', or an audit skill reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe.4---56## Purpose78Setup per the uniform setup contract (`docs/PLUGIN-PHILOSOPHY.md` "Setup is explicit and repeatable" in9the marketplace repository): `check` inspects and reports, `apply` resolves. This plugin declares no10`userConfig`, and has two setup concerns:1112- the external command-line tools its bundled scripts require, where `apply` is guidance-and-verify13 with no write path: it points at platform install instructions and never installs a system package;14- the **tracked consumer-project configuration** `audit-pass` reads, the suppression record at15 `.claude/audit-pass.md`, the one surface `apply` may write.1617Action routing: no argument or `check` runs the check; `apply` runs the check first, then remediation.18Both are non-interactive, so never prompt when the action is given.1920## `check` (read-only)2122The bundled scripts are the single source of truth for what this plugin requires.2324**Read it first.** Probe what it actually does, don't recite this file. Then run each probe via25Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything.2627The runtime scripts and their tools:2829- `${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/check-plugin-drift.sh`: jq **and** curl, plus awk and sort30- `${CLAUDE_PLUGIN_ROOT}/skills/audit/scripts/check-structure.sh` and `check-hook-coverage.sh`: jq; `fix-plugin-drift.sh`: jq plus sort31- `${CLAUDE_PLUGIN_ROOT}/skills/audit-automation-gaps/scripts/inventory.sh`: jq32- `${CLAUDE_PLUGIN_ROOT}/skills/audit-permission-grants/scripts/permission-rule-check.sh`: jq plus awk and sort33- `${CLAUDE_PLUGIN_ROOT}/skills/audit-permission-state/scripts/*.sh`: jq (required; `permission-state.sh` exits 2 without it), awk and sort; `automode-block-lint.sh` and `automode-entry-diff.sh` add python3 for an optional lane34- `${CLAUDE_PLUGIN_ROOT}/skills/draft-auto-mode-rules/scripts/draft-automode-block.sh`: jq plus awk35- `${CLAUDE_PLUGIN_ROOT}/skills/audit-pass/scripts/run-state.sh` and `${CLAUDE_PLUGIN_ROOT}/lib/check-retirements.sh`: jq (`run-state.sh` falls back to python3, then to a scan that announces itself)36- `${CLAUDE_PLUGIN_ROOT}/skills/audit-instructions/scripts/instruction-scan.sh`: grep only (POSIX; no jq)37- `${CLAUDE_PLUGIN_ROOT}/skills/audit-instructions/scripts/conflict-scan.sh`: awk **and** sort (no jq)3839Only `conflict-scan.sh` and `permission-state.sh` probe for their tools; the rest call them with no40guard, so read each script's actual calls rather than trusting a single script's prerequisite block to41speak for the plugin.42431. **`jq`**, via `command -v jq`. FAIL if absent: the JSON-parsing scripts need it (`inventory.sh` degrades44 to an empty inventory; the others `exit 2` with an install remediation). Missing `jq` blocks every45 skill whose scripts parse JSON (`audit`, `audit-automation-gaps`, `audit-permission-grants`,46 `audit-permission-state`, `draft-auto-mode-rules`, and `audit-pass`'s run-state and retirement47 helpers); `audit-instructions` scans markdown and is unaffected.482. **`curl`**, via `command -v curl`. FAIL if absent, but scoped: only the plugin-drift check49 (`check-plugin-drift.sh`) uses it and `exit 2`s without it. The rest of `audit` and every other50 skill still run; say so in the remediation line.513. **`awk` and `sort`**, via `command -v awk` and `command -v sort`. FAIL if either is absent, and **not**52 scoped to one skill: `conflict-scan.sh` executes both and `exit 2`s naming the missing one, while53 `check-plugin-drift.sh` (both), `permission-rule-check.sh` (both), and `fix-plugin-drift.sh`54 (`sort`) reach them with no prerequisite check at all, so `audit` and `audit-permission-grants`55 fail mid-run on a bare `command not found` rather than on a named prerequisite. Say in the56 remediation line that this FAIL reaches three skills, not just `audit-instructions`. Report `awk`57 and `sort` by name rather than as one row, since a minimal shell can carry one and not the other.584. **Bash shell**, INFO: the scripts are bash (arrays, `[[ ]]`, process substitution, `BASH_SOURCE`),59 run through Claude Code's Bash tool, which is the bash shell on every platform and Git Bash on native Windows.60 Report the resolved interpreter; FAIL only if no bash is resolvable.615. **Network reachability**, INFO only: `audit`'s drift/freshness fetches read62 `raw.githubusercontent.com`, and a failed fetch degrades to SKIP rather than a setup failure. Do not63 fetch here; `check` performs no network call.6465### The `audit-pass` suppression record6667`audit-pass` reads a tracked suppression record layered per the marketplace's config-cascade68convention. Read the operative shape from69`${CLAUDE_PLUGIN_ROOT}/skills/audit-pass/reference/suppression.md` rather than inferring it. That70reference ships inside this plugin, so it resolves in an installed cache where a path out to the71marketplace's own docs does not. The cross-consumer key contract is the marketplace's published72**finding-suppression** convention, which is not a runtime dependency of this plugin. All layers73absent is a valid state (no suppressions), so report INFO, never FAIL, when none exists.7475Anchor at the repo root (`${CLAUDE_PROJECT_DIR}`, else `git rev-parse --show-toplevel`), never a76CWD-relative read, which resolves a different (or missing) file depending on the subdirectory or77nested worktree the skill was invoked from, then report one row per layer. The same78tracked/ignored question has opposite correct answers per layer, so verify each on its own terms:7980- **user-global** `~/.claude/audit-pass.md`: outside the worktree; no git command applies. INFO only.81- **team** `.claude/audit-pass.md`: must be tracked, probed as the pair —82 `git check-ignore -v` reports no match (a match is FAIL with the pattern) AND83 `git ls-files --error-unmatch` exits 0. Untracked while present is a hard STOP:84 teammates never receive the shared suppressions.85- **local overlay** `.claude/audit-pass.local.md`: must be gitignored and never staged. Staged or86 tracked is a FAIL: a personal deviation can reach team history.8788Parse each present layer and report as malformed any entry missing **any** of its five required89keys: `check`, `claim`, `sites`, `reason`, `date`. Checking only `reason` and `date` would pass an90entry that `audit-pass` itself rejects, so readiness would report green on configuration that cannot91suppress anything. Report as malformed too an entry whose stored constituents do not hash to its own92key: the constituents are authoritative and the key is derived from them. A malformed entry does not93suppress, and a silent partial parse would turn a formatting slip into a lost check.9495Report a **user-global or overlay entry for an id the team layer does not carry** as INFO96`personal-only, not applied`, naming promotion to the team layer as what makes it take effect. The97team layer is the only one that enacts a suppression, so a personal-only entry that looks live is a98finding the operator believes is accepted and is not.99100## `apply` (idempotent)101102Run `check`, then for each FAIL give the platform install instructions from the README Requirements.103This skill never installs system packages:104105- **missing `jq`:** the platform's jq install (for example `winget install jqlang.jq`, `brew install106 jq`, or `apt-get install jq`); rerun `check` after.107- **missing `curl`:** the platform's curl install. Modern Windows and Git Bash already ship `curl`.108 Only the plugin-drift check needs it, so the rest of the plugin works meanwhile.109- **missing `awk` or `sort`:** both ship with every POSIX userland, so absence means the shell110 environment is minimal rather than that one package is missing. Git Bash and Windows `busybox`111 shims are where this shows up. Remediate by installing a full userland rather than the single tool:112 Git for Windows, which bundles both; the distribution's `gawk`/`mawk` and `coreutils` on Linux;113 `brew install gawk coreutils` on macOS. Report the two separately, since a minimal shell can carry114 one and not the other. Five skills depend on them (`audit`, `audit-permission-grants`,115 `audit-permission-state`, `draft-auto-mode-rules`, and `audit-instructions`), and only116 `conflict-scan.sh` and `permission-state.sh` `exit 2` cleanly, so do not offer the others as still117 working meanwhile.118- **no resolvable bash:** also not remediable by one package. The scripts use arrays, `[[ ]]`,119 process substitution, and `BASH_SOURCE`, so they need a real bash on `PATH`: Git for Windows on120 native Windows, the distribution's `bash` elsewhere. Nothing bundled runs until it resolves, so121 say that this FAIL blocks the plugin rather than offering a partial workaround.122123The network row stays INFO and has no `apply` entry on purpose: a failed fetch degrades to SKIP by124design, so there is nothing to remediate.125126After any install, re-run the relevant `check` probe and report its actual result. Never claim resolved127on the install command's exit code alone. Re-running `apply` once every probe passes changes nothing and128reports "already configured".129130Then converge the one surface this plugin owns, conservatively:131132- **No suppression record anywhere**: leave it that way and say so. Absent is valid; an empty133 scaffold is noise. Scaffold the team layer with the documented shape only on an explicit request.134- **Team layer present but untracked**: report the STOP and the exact `git add` the operator should135 run. Never stage on their behalf.136- **Overlay present but not ignored**: recommend the recursive `.claude/**/*.local.*` line and leave137 the `.gitignore` edit to the consumer.138- **Malformed or unrecognized entries**: report them and stop. Never rewrite, reorder, or drop an139 operator's suppression: an entry this skill cannot reconcile is a question for the operator, and a140 silent rewrite would hide the very finding the entry was suppressing.141142Every write names the file and the exact change before making it, and preserves unrelated content.143144## Gotchas145146- **Never run a git command against the user-global layer.** `~/.claude/audit-pass.md` is outside the147 worktree, so `git check-ignore` and `git status` return a meaningless verdict there, or a148 confidently wrong one when the home directory is itself a git repository.149- **Missing config is not a failure.** All three suppression layers absent means no suppressions,150 which is the normal state for a repo that has never suppressed a finding. INFO, never FAIL.151- **Recommend the recursive gitignore line, and leave the edit to the consumer.** `.claude/**/*.local.*`152 covers flat, folder-form, and profiled overlays alike; the narrower `.claude/*.local.*` silently153 misses any nested overlay. The consumer's ignore file is their artifact; this skill never writes it.154- **An install command's exit code is not verification.** After any install, re-run the probe and155 report its actual result.156157## What this skill does NOT do158159- Run an audit; that is the plugin's audit and drafting skills (`/claude-config:audit`,160 `audit-automation-gaps`, `audit-instructions`, `audit-pass`, `audit-permission-grants`,161 `audit-permission-state`, `audit-prompting-postures`, `draft-auto-mode-rules`, `unhobble`).162- Write the plugin cache, Claude Code user settings, or `pluginConfigs`.163- Install system packages.164- Write the consumer's `.gitignore`, stage anything, or edit an operator's suppression entries.165- Download anything. `check` makes no network call; the audit skills' own doc/marketplace fetches are166 theirs, not setup's.