Use for safety rails in a Stacks project - detecting destructive commands (rm -rf, DROP TABLE, force-push, git reset --hard, migrate:fresh against production), installing a PreToolUse hook that blocks them before they run, freeze mode for focused debugging, and a pre-commit safety scan. Invoke with /stacks-guard.
Resources
3Install
npx skillscat add stacksjs/stacks/stacks-guard Install via the SkillsCat registry.
/stacks-guard - Safety Rails
Prevent destructive actions and enforce focus during debugging sessions.
Destructive Command Detection
🔴 CRITICAL - Block and require confirmation
| Pattern | Risk |
|---|---|
rm -rf /, rm -rf ~, rm -rf . |
Catastrophic file deletion |
DROP TABLE, DROP DATABASE, TRUNCATE |
Irreversible data loss |
git push --force to main/master |
Overwrites shared history |
git reset --hard with uncommitted changes |
Loses uncommitted work |
git clean -fd |
Deletes untracked files permanently |
buddy migrate:fresh on production |
Drops ALL tables |
buddy seed --fresh on production |
Truncates all data |
Response:
🔴 GUARD: Destructive command detected
Command: [command]
Risk: [what will be destroyed]
Reversible: [yes/no]🟡 WARNING - Warn but allow
| Pattern | Risk |
|---|---|
git push --force (non-main) |
Overwrites remote branch |
rm -rf [specific dir] |
Deletes directory tree |
bun remove [core dep] |
May break build |
git checkout -- . |
Discards all unstaged changes |
| Bulk file moves/renames | May break imports/aliases |
Modifying config/services.ts |
Contains API keys |
Modifying storage/framework/core/*/src/index.ts |
Public package API |
🟢 INFORMATIONAL - Note but don't block
| Pattern | Note |
|---|---|
git rebase |
History rewrite - ensure not shared |
bun update (major versions) |
May introduce breaking changes |
| Modifying CI/CD config | Affects deployment pipeline |
| Changing auth/permissions code | Security-sensitive |
| Modifying migration files | Database schema change |
Freeze Mode
Restrict edits during focused debugging.
Activate
/stacks-guard freeze [file or directory pattern]When active:
- Block edits outside the freeze scope
- Track all changes made during the session
- Warn if changes grow large (>5 files or >50 lines)
Deactivate
/stacks-guard thawProduces a summary of all changes.
Pre-Commit Safety
Before commits, scan for:
- Secrets: API keys, tokens, passwords in staged files
- Debug artifacts:
console.log,debugger,TODO: remove - Large files: >1MB being committed
- Lockfile consistency:
package.jsonchanged →bun.lockshould too
Stacks-Specific Guards
- Don't edit
storage/framework/types/*.d.ts- these are auto-generated - Don't edit
storage/framework/defaults/app/Models/without also generating migrations - Don't modify
config/services.tsin commits - contains API keys - Check
storage/framework/core/*/package.jsonversions - workspace packages should stay in sync
Make it enforcing
Everything above is advisory: it works only while the agent is paying attention.
A PreToolUse hook turns it into enforcement, because the harness runs it on
every Bash call before the command executes.
scripts/block-destructive.sh is the hook. It
reads the tool call on stdin, exits 2 with a message on stderr when the command
matches a blocked pattern, and exits 0 otherwise. It blocks two lists: commands
that are unrecoverable anywhere (rm -rf / or ~ or ., force-push,reset --hard, clean -f, branch -D, DROP TABLE, TRUNCATE TABLE), and
commands that are routine locally but destructive against production
(migrate:fresh, seed --fresh, cloud:remove, cloud:cleanup, gated on the
command naming a production env).
Deliberately not blocked: a plain git push, rm -rf node_modules,buddy migrate:fresh locally. A guard that fires on regenerable things gets
turned off, and a guard that is off protects nothing.
Credit: adapted from Matt Pocock's git-guardrails-claude-code skill (MIT),
https://github.com/mattpocock/skills.
Install
Ask the scope. This project (
.claude/settings.json) or every project
(~/.claude/settings.json)?Copy the script to
.claude/hooks/block-destructive.shor~/.claude/hooks/block-destructive.sh, andchmod +xit.Register it. Merge into the existing
hooks.PreToolUsearray rather than
overwriting the file:{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-destructive.sh" } ] } ] } }For the global install, the command is
~/.claude/hooks/block-destructive.sh.Tune the lists. Ask the user what to add or remove. A repo that never
deploys does not need the production list. A repo with a protectedmainmay
want a plaingit pushblocked too.Verify. Each of these should print a BLOCKED line and exit 2:
echo '{"tool_input":{"command":"git push --force origin main"}}' | .claude/hooks/block-destructive.shAnd each of these should exit 0 silently:
echo '{"tool_input":{"command":"rm -rf node_modules"}}' | .claude/hooks/block-destructive.sh
.claude/ is gitignored in a Stacks project, so a project-scope install is
per-developer. To make it a team rule, commit the script under scripts/ and
have buddy setup:ai users point their hook at that path.
Rules
- Never silently allow destructive commands.
- Don't be annoying.
rm file.txtdoesn't need a warning.rm -rf node_modulesis fine - it's regenerable. - Respect user intent. After warning once, if confirmed, proceed.
- Context matters. Force-push to a personal branch is not force-push to main.
Downstream
Guard installed?
/stacks-retrois where a near-miss becomes a permanent
check, and/stacks-wizardis for the production steps a human should be
doing by hand anyway.
Upstream provenance
The reviewed source revision and MIT notice are in NOTICE.md and
LICENSE. Read the Stacks adaptation rules
with this workflow. Existing Stacks APIs and supporting helpers remain authoritative.