bash + jq only for hooks. No Node.js. No external APIs. Python stdlib is OK for non-time-critical scripts (analysis, reports, learnings).
Before submitting a PR, verify:
- Never use
flock— macOS doesn't have it. Use atomicmkdirfor locks. - Never use
$CLAUDE_SESSION_IDfor cache keys — doesn't reset after /clear. - Never use
jq -son growing files — slurps entire file into RAM. Safe on bounded inputs. - Every hook has
trap 'exit 0' ERR INT TERM— hooks must never break Claude. - 64KB stdout limit — write large output to tmpfiles under
/tmp/hydra-*. - Validate JSON before parsing with
jq empty. - Block URL-encoded path traversal — decode
%2e%2ebefore checking. - Rotation at 10MB not 1MB.
- Use
jq -n --argfor JSON construction — never printf/sed chains. - NEVER log actual secret values — masked form only (first 4 + last 4 chars).
- Every pattern addition needs positive AND negative test cases.
- All CWE/CVE references must be verified against official databases.
- False positive hints are required for every secret pattern.
- Secret masking is enforced —
mask_secret()in sanitize.sh,mask_value()in Python. - action-guard is the ONLY hook that may exit 2 — all others exit 0 always.
shellcheck -xpasses on all.shfiles- Use
printf "%s"overechofor variable content - Use
localfor function variables - Quote all variable expansions (
"$var"not$var) - Use
[[ ]]over[ ]for conditionals - Use
$(command)over backticks - Keep hook scripts under 200 lines
bash tests/run-all.shTests pipe mock JSON to hooks via stdin and verify exit codes and output. Tests must clean up all temp files and state files after running.
-
Add to the appropriate file in
shared/patterns/:secrets.json— secret patternsvulns.json— vulnerability patterns (must include CWE)dangerous-ops.json— command patterns (action: block or warn)config-attacks.json— config file patterns (include CVE if known)slopsquatting.json— hallucinated package names
-
Each pattern needs:
- Unique
id - Valid regex
pattern severitylevel- For secrets:
false_positive_hintsarray - For vulns:
cweandowaspreferences - For commands:
action(block or warn)
- Unique
-
Add test cases in
tests/<plugin>/test-*.sh
plugins/<name>/
├── .claude-plugin/plugin.json
├── skills/<skill>/SKILL.md
├── agents/<agent>.md
├── commands/<command>.md
├── hooks/
│ ├── hooks.json
│ └── <hook-point>/<script>.sh
├── state/.gitkeep
└── README.md
Register in .claude-plugin/marketplace.json.
shellcheck -xpasses on all.shfilestests/run-all.shexits 0- No banned patterns (
flock,jq -son unbounded files) - Every SKILL.md has
allowed-toolsfrontmatter - Every agent has
model,context: fork, andallowed-tools - Secret values are NEVER logged in any form
- New patterns have corresponding positive and negative tests