plugins/build/skills/check-hook/SKILL.md
Audits Claude Code hooks configuration for event coverage, script safety, async and blocking contradictions, Stop hook loop risks, rule overlap, and idempotency. Use when the user wants to "audit hooks", "review hooks", or "are my hooks safe".
npx skillsauth add bcbeidel/wos check-hookInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit a project's Claude Code hooks configuration against the rubric in hook-best-practices.md. Read-only until the opt-in Repair Loop.
This skill follows the check-skill
pattern. It is a
pure-judgment skill — no Tier-1 detection scripts of its own; the
18 rules live as references/check-*.md files read inline by the
primary agent during Tier-2. Tier-3 (cross-entity collision) does not
apply (single configuration scope per audit).
Also fires when the user phrases the request as:
If $ARGUMENTS is non-empty, read the settings file at that path.
Otherwise, read from both default locations (use whichever exist):
.claude/settings.json.claude/settings.local.jsonIf neither exists, or neither has a hooks: key, the first finding
is:
No hooks configured (warn) — PreToolUse hooks provide deterministic enforcement CLAUDE.md instructions cannot guarantee.
The check-primitive-routing-coverage rule (Tier-2 below) will also
fire if CLAUDE.md carries advisory rules that should be hooks.
Evaluate each configured hook against the 18 judgment rules in
references/check-*.md. Read each rule body once, then evaluate
every hook against it as a unified rubric pass.
The 18 dimensions:
| File | Dimension | Severity |
|---|---|---|
| check-event-matcher-fit.md | Event-matcher fit (right event, canonical casing, matcher syntax) | fail |
| check-exit-code-contract.md | Exit code contract (exit 2 for blocks; explicit Python handlers) | fail |
| check-stdin-consumption.md | Stdin consumption (INPUT=$(cat); executable bit) | warn |
| check-json-output-contract.md | JSON output contract (exit-0 only; hookEventName; <10 KB) | warn |
| check-async-blocking-coherence.md | Async-blocking coherence (no async: true + exit 2) | fail |
| check-command-path-expansion.md | Command path expansion ($CLAUDE_PROJECT_DIR, never $HOME/~) | warn |
| check-stop-loop-guard.md | Stop-loop guard (re-entry guard for blocking Stop / SubagentStop) | fail |
| check-destructive-operations.md | Destructive operations (no rm -rf, git reset --hard, git push --force) | fail |
| check-injection-safety.md | Injection safety (no eval on payload; quoted expansions) | fail/warn |
| check-jq-handling.md | jq handling (availability, field paths, cross-platform) | fail/warn |
| check-shell-hygiene.md | Shell hygiene (set -Eeuo pipefail, output routing, [[) | warn |
| check-attack-surface.md | Attack surface (CVE-2025-59536-aware placement) | warn |
| check-latency.md | Latency (under 1s synchronous; no recursive claude invocation) | fail/warn |
| check-idempotency.md | Idempotency (running twice produces same outcome) | warn |
| check-static-analysis.md | Static analysis (ShellCheck and shfmt integration) | warn |
| check-claude-md-overlap.md | CLAUDE.md overlap (surface for user; never auto-resolve) | warn |
| check-brief-presence-and-content.md | Brief presence + content (5 H2 sections; specific So-what) | warn |
| check-primitive-routing-coverage.md | CLAUDE.md → hook conversion candidates | warn |
Evaluator policy: see check-skill-pattern.md §Evaluator policy. Read all 18 rule files first, then evaluate each hook in turn against the unified rubric.
Skill-specific severity floor exceptions. The default WARN floor is
overridden for the 7 rules documented as fail:
event-matcher-fit, exit-code-contract, async-blocking-coherence,
stop-loop-guard, destructive-operations, injection-safety, jq-handling
(Copilot field-path mismatch), and latency (recursive claude
invocation).
For each finding, capture: dimension name, offending hook / command /
file, specific issue, severity. The finding's recommended_changes
copies through from the rule body's How to apply section + example.
These checks target Claude Code (settings.json /
settings.local.json). If the project's hooks may run on additional
platforms beyond Claude Code, read
platform-limitations.md and
append platform-specific findings as a separate report section.
Present findings as a summary count plus a table, severity-sorted
(fail → warn → inapplicable):
N issues across M hooks (X fail, Y warn)
event | hook command | dimension | finding
---------------+-----------------------+---------------------------+---------------------------
PostToolUse | .claude/hooks/gate.sh | event-matcher-fit | PostToolUse cannot block; use PreToolUse
Stop | .claude/hooks/stop.sh | stop-loop-guard | No re-entry guard — infinite loop risk
PostToolUse | lint-after-write.sh | async-blocking-coherence | async:true + exit 2 — never blocks
If Platform Scope added findings, append:
**Cross-platform limitations:** [list per platform]
If no issues: "Hooks look well-configured."
Ask exactly once:
"Apply fixes? Enter
y(all),n(skip), or comma-separated numbers."
For each selected finding, route per the recipe in
recommended_changes (the rule body's How to apply section + code
example). Most fixes fall into three buckets:
INPUT=$(cat), fix matcher casing, swap
$HOME for $CLAUDE_PROJECT_DIR, add set -Eeuo pipefail. Show
diff; write on confirmation./build:build-hook. Pair-level integrity issues →
recommend /build:check-skill-pair hook.claude-md-overlap (keep both vs.
drop one), attack-surface placement decisions, intentional
advisory rules from primitive-routing-coverage.Show the diff before writing. Terminate when the user selects no
further findings, enters n, or confirms done.
check-primitive-routing-coverage when no hooks
exist. Absence of hooks is itself a coverage gap worth
surfacing — the rule fires regardless of the configured-hook count..claude/settings.json and .claude/settings.local.json under
the current project root, unless the user passes an explicit path.stop-loop-guard against a PreToolUse hook), return
inapplicable silently — do not pad the report with "N/A" rows.recommended_changes; do not paraphrase or expand.check-primitive-routing-coverage rule fires whether or not
hooks are configured — absence of hooks against a CLAUDE.md
carrying convertible rules is the coverage gap it surfaces.stop-loop-guard findings are fail, not warn — unguarded
blocking Stop hooks require a session kill to recover.inapplicable silently.git diff / git checkout.Chainable to: /build:build-hook (create a new hook or
substantially rewrite one flagged by the audit);
/build:check-skill-pair hook (audit pair-level integrity).
tools
Use when the user wants to "audit a help skill", "review my plugin index", or "verify my help-skill is up to date". Audits a plugins/<plugin>/skills/help/SKILL.md against the help-skill rubric — coverage, freshness, frontmatter fidelity, plus five judgment dimensions and a trigger-collision check.
tools
Use when the user wants to "scaffold a help skill", "add a /<plugin>:help command", or "build a plugin index skill", or wants to give a plugin an orientation surface that lists its skills and common workflows. Produces a SKILL.md at plugins/<plugin>/skills/help/SKILL.md.
tools
Audits pair-level integrity of a primitive-pair (the artifact `/build:build-skill-pair` produces) by walking the four required artifact slots — principles doc, `build-<primitive>/SKILL.md`, `check-<primitive>/SKILL.md`, and the `primitive-routing.md` registration — and reports cross-artifact issues a per-SKILL.md checker cannot see: missing principles doc, divergent principles paths between halves, absent routing registration, missing build→check handoff. Per-half structural compliance with the unified pattern (`check-skill-pattern.md`) is delegated to `plugins/build/_shared/scripts/check_skill_pattern.py`. Use when the user wants to "audit a skill pair", "review a primitive pair", or "validate the skill pair for X". Not for auditing a single SKILL.md — route to `/build:check-skill`. Not for re-distilling a stale principles doc — route to `/build:build-skill-pair`.
testing
Audit a root-level resolver — verify AGENTS.md pointer, managed-region integrity, filing-table coverage against disk, context-table actionability, and trigger-eval pass rate. Use when the user wants to "audit a resolver", "validate routing table", or "find dark capabilities".