skills/git-guardrails/SKILL.md
Safety net that blocks destructive git commands and suggests safer alternatives. Background knowledge for configuring pre_tool_use hooks.
npx skillsauth add RonanCodes/ronan-skills git-guardrailsInstall 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.
Hook configuration that intercepts destructive git commands before they execute, warns the user, and suggests safer alternatives.
| Command | Risk | Safer Alternative |
|---------|------|-------------------|
| git push --force | Overwrites remote history, can destroy teammates' work | git push --force-with-lease |
| git push --force to main/master | Never do this — can break CI, deployments, everyone's local | Create a PR instead |
| git reset --hard | Discards all uncommitted changes permanently | git stash then git reset --soft |
| git clean -f | Deletes untracked files permanently | git clean -n (dry run first) |
| git branch -D | Force-deletes branch even if unmerged | git branch -d (safe delete, warns if unmerged) |
| git checkout -- . | Discards all unstaged changes | git stash to preserve changes |
| git restore . | Discards all working tree changes | git stash or restore specific files |
Add this to .claude/settings.json or ~/.claude/settings.json:
{
"hooks": {
"pre_tool_use": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash -c 'CMD=\"$CLAUDE_TOOL_INPUT\"; BLOCKED=\"\"; if echo \"$CMD\" | grep -qE \"git\\s+push\\s+.*--force\" && ! echo \"$CMD\" | grep -qE \"\\-\\-force-with-lease\"; then BLOCKED=\"git push --force\"; elif echo \"$CMD\" | grep -qE \"git\\s+reset\\s+--hard\"; then BLOCKED=\"git reset --hard\"; elif echo \"$CMD\" | grep -qE \"git\\s+clean\\s+-[a-zA-Z]*f\"; then BLOCKED=\"git clean -f\"; elif echo \"$CMD\" | grep -qE \"git\\s+branch\\s+-D\"; then BLOCKED=\"git branch -D\"; elif echo \"$CMD\" | grep -qE \"git\\s+checkout\\s+--\\s+\\.\"; then BLOCKED=\"git checkout -- .\"; elif echo \"$CMD\" | grep -qE \"git\\s+restore\\s+\\.\"; then BLOCKED=\"git restore .\"; fi; if [ -n \"$BLOCKED\" ]; then echo \"BLOCKED: $BLOCKED detected. See git-guardrails skill for safer alternatives.\"; exit 1; fi'"
}
]
}
]
}
}
Bash tool call before executiongit push with --force (but NOT --force-with-lease, which is safe)git reset --hardgit clean with -f flaggit branch -D (uppercase D = force delete)git checkout -- . (discard all changes)git restore . (discard all changes)If you genuinely need to run a blocked command, you can:
git checkout -- single-file.txt instead of git checkout -- .Copy the hook configuration above into your preferred settings file:
.claude/settings.json (committed, team-wide)~/.claude/settings.json (applies to all projects)The Claude-side pre_tool_use hook above blocks destructive commands. The repo-side git hooks are the other half of the safety net and EVERY app must ship with them from day one. They are owned and installed by the scaffold skill (/ro:new-tanstack-app § 6), but documented here so an audit or a manual setup knows the standard:
.husky/pre-commit → pnpm exec lint-staged — Prettier (and eslint --fix where cheap) on STAGED files only. Kills the "CI fails on formatting" class of PR..husky/commit-msg → pnpm exec commitlint --edit "$1" — enforces emoji + conventional commit format..husky/pre-push → pnpm quality (typecheck + lint + format-check + build + test) — the FULL local CI gate. Because remote CI is billing-capped and skipped (the user's CI & Shipping Policy), this pre-push hook is the real gate: a green push means the code is good. Bypassable with git push --no-verify for genuine emergencies only.Bootstrap with pnpm exec husky init + "prepare": "husky" in package.json so hooks reinstall on every pnpm install. Canon: [[code-hygiene-stack]] and [[ideal-tech-setup]] in the llm-wiki-research vault.
testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".