Skip to content
Back to skills

Guard Change

BSecurity

Procedure for changing a guard so the PR fixes the whole bypass class and loosens nothing unplanned. Use when editing roles/hooks/*, a deny rule in roles/settings/*.json, a CLI refusal, or when retrying a PR after a reviewer or QA bypass finding.

  • 8 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 5, 2026
ai-agentspythongogit

Works with

  • cli

Security analysis

B75/100
  • criticalSends environment variables or credentials to an external URL

Pro shows the line behind each finding and how to fix it

Scanned November 5, 2026

npx -y skills add volekerb/hivemill --skill guard-change --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Guard Change?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Guard Change
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/volekerb-guard-change/badge)](https://www.skillsdirectory.com/skills/volekerb-guard-change)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: guard-change
description: Procedure for changing a guard so the PR fixes the whole bypass class and loosens nothing unplanned. Use when editing roles/hooks/*, a deny rule in roles/settings/*.json, a CLI refusal, or when retrying a PR after a reviewer or QA bypass finding.
---

Purpose: a guard PR must close the bypass class and must not loosen a block that main has (G-013, T-0147, L-026).

Follow these steps in order.

1. Name the bypass CLASS of each finding before coding. One sentence per finding, for example "variable-writing builtin", not "export FOO=herdr".
2. Walk the variant list for each class: quoting and escapes; metacharacters with no spaces (`;x`, `&&x`, `|x`, `$(x)`, backticks); wrappers with operands (env, nohup, timeout, xargs, command, exec, time); path-qualified and glob command words (`/usr/bin/x`, `/usr/b*/x`); variable-writing builtins (export, declare, read, printf -v, for, mapfile, getopts); aliases; functions and script files; write-then-run heredocs; git and gh options that run code.
3. Add every variant you listed to `ci/guard_corpus.json`: blocked forms to `must_block`, realistic look-alikes that must keep working to `must_allow` (commit and PR heredoc bodies, grep/rg, git log with PAGER, factory msg/verdict).
4. Prefer a fail-closed rule for the whole class over enumerating each writer. A check that cannot decide blocks, never allows.
5. Add tests through the real entry point (the hook as invoked, the CLI as a subprocess): one it must reject and one it must accept per rule. Run each new test once with the fix removed and see it fail.
6. Do not run `ci/guard_diff.py` locally (load, M16816). The PR CI `guard-diff` job has a real-corpus step that runs it against the real corpus (base tool, `--mode both` and `--mode worker --role evaluator`). Add `{"cmd": ..., "role": "evaluator"}` corpus entries for a rule that needs a temp FACTORY_HOME; read the job log once CI has run.
7. Paste the `guard-diff:` summary lines and every LOOSENED and TIGHTENED line from the `guard-diff` job's real-corpus step log into the PR body.
8. Expect zero LOOSENED lines. A planned loosening needs the spec to name it. Otherwise it ships as its own task (L-026): do not add a `ci/allow_loosen_*.json` yourself (CI passes it to `--allow-loosen` and prints it for the reviewer).
9. On a retry, list the variants you tested per class in the PR body, and say which of them the previous round missed.
10. Merge origin/main and rerun the tests right before updating the PR and re-read the `guard-diff` job's real-corpus step log on the new head.

11. Python-only guard changes run under `guard-equiv` (Go vs Python, strict, stderr included; details in docs/guard-diff.md). Pick the rule that fits:
    - (a) Reason text of an existing rule changed in the Python guard: the same PR changes the Go string, text only.
    - (b) New Python-only rule: its test module carries `GUARD_IMPL_PYTHON_ONLY`, its forms stay out of `ci/guard_corpus.json` until the Go mirror lands, and the Go mirror task is filed at merge (M21163: every Python-only rule needs its mirror merged before any `impl=go` or shadow flip).
    - (c) A corpus line red only because of a different Python-only rule: tag it with the role where both guards agree (for example `"role": "coder"`), or leave it out, and hand the form to that rule's mirror task. Never allowlist, never drop `--strict`.

Stop and tell your lead if a probe command is blocked by your own guard (do not rephrase around it), or if the spec asks for a loosening without naming it.

Sources: T-0147 retro notes 1-4, L-026.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.