git-guardian
Skill0 starsChanged 15 days agoApache-2.0View on GitHub
Safety gate for destructive git/main commits. Triggers: force-push, reset, branch delete, clean, main commit.
- Reads credentials
- Deletes or force-pushes
- Commits and pushes
1 other project uses a version of this.
Adopted by
Most recently taken up by
- suryast/free-ai-agent-skillstheir own version, first seen Oct 10, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- suryast/free-ai-agent-skills★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository64 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- verify-lead-waitSkill
- verify-merge-receiptsSkill
- branded-docSkill
- explanatory-docSkill
- 1passwordSkill
- agada-benchSkill
- agent-browserSkill
- agent-routingSkill
- architectural-conformance-auditSkill
- audio-dashboardSkill
- brain-store-fallbackSkill
- claude-desktop-researchSkill
- cmux-agentsSkill
- cmuxSkill
- coachSkill
- coderabbitSkill
- codex-workflowsSkill
- collab-monitorSkill
- content-demo-creationSkill
- convention-auditSkill
- cursor-workflowsSkill
- cyberSkill
- deploy-verifySkill
- drive-filingSkill
- eas-prebuild-checkSkill
- ecosystem-healthSkill
- eli5Skill
- false-green-gateSkill
- figma-loopSkill
- fleet-wrap-gateSkill
- fleet-wrapSkill
- frustration-captureSkill
- gemini-researchSkill
- github-researchSkill
- golem-installSkill
- grill-meSkill
- heredoc-guardSkill
- html-dashboardSkill
- human-confirm-gateSkill
- i-have-adhdSkill
- install-runbook-linterSkill
- large-planSkill
- m1-window-gateSkill
- model-pin-gateSkill
- never-fabricateSkill
- orcSkill
- plan-councilSkill
- pr-loopSkill
- qa-verdict-gateSkill
- qa-videoSkill
- repogolemSkill
- research-lifecycleSkill
- reviewer-order-gateSkill
- session-handoffSkill
- skill-creatorSkill
- stitch-designSkill
- t3-visualsSkill
- tmp-blockSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. About 0 are common, 16 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈16
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 35
If on
mainormaster: STOP. Do not proceed with force-push, reset --hard, or unprotected commits. - Distinctive: line 46
If there are uncommitted changes: name them explicitly before asking for confirmation.
- Distinctive: line 47
Never silently proceed past uncommitted changes.
- Distinctive: line 69
Check current branch — block if main/master unconditionally.
- Very specific: line 70
Run git log origin/<branch>..HEAD --oneline to show what will be overwritten.
- Distinctive: line 75
Treat remote branch or tag deletion like force push: inspect the impact and require explicit user confirmation.
- Very specific: line 81
Run git log HEAD~<N>..HEAD --oneline to list commits being dropped.
- Distinctive: line 82
Run git status --short to show uncommitted work that will be lost.
- Distinctive: line 83
If uncommitted changes exist: explicitly list each file.
- Distinctive: line 87
Run git branch --merged to check if the branch is merged.
- Distinctive: line 88
If not merged: list the N commits that exist only on this branch.
- Distinctive: line 90
Ask for explicit confirmation.
- Distinctive: line 98
Run git clean -n (dry run) to list files that would be deleted.
- Distinctive: line 100
Ask for explicit confirmation.
- Distinctive: line 105
Do NOT commit or push. Redirect the user.
- Very specific: line 108
Never run any git command with --no-verify.
- Distinctive: line 109
Instead: investigate why the hook is failing and fix the root cause.
- Distinctive: line 110
If user insists, surface this as a hard stop: "The hook failure is protecting you.
- Very specific: line 115
NEVER: use --no-verify to bypass hooks.
- Distinctive: line 117
NEVER: delete an unmerged branch without explicit confirmation.
- Distinctive: line 118
If user overrides a warning ("I know, just do it"), proceed — but log what was overridden.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Git Guardian
Prevents git footguns by checking blast radius, uncommitted state, and branch safety before any destructive operation.
Trigger Operations
Invoke this skill when about to run ANY of these:
| Operation | Risk |
git push --force / git push -f | Overwrites upstream history |
git reset --hard | Destroys local changes permanently |
git branch -D / git branch -d | May lose unmerged commits |
git checkout . / git restore . | Destroys uncommitted local changes |
git clean -f / git clean -fd | Permanently deletes untracked files |
git rebase on a shared branch | Rewrites shared history |
Commit or push while on main/master | Pollutes main branch history |
--no-verify on any command | Bypasses safety hooks |
Protocol
For every destructive operation, run these checks in order:
1. Branch Safety Check
git branch --show-current- If on
mainormaster: STOP. Do not proceed with force-push, reset --hard, or unprotected commits. Redirect to a feature branch. - Exception:
git pull --rebaseandgit mergeare safe on main.
2. Uncommitted Changes Check
git status --short
git stash list- List any modified, staged, or untracked files that would be destroyed.
- If there are uncommitted changes: name them explicitly before asking for confirmation.
- Never silently proceed past uncommitted changes.
3. Impact Summary
Before executing, show:
⚠️ Git Guardian — [OPERATION] on [BRANCH]
Commits to be lost: [N commits, with short hashes + messages]
Files to be lost: [list of modified/untracked files]
Branch status: [merged | UNMERGED — N commits only here]
Upstream: [N commits ahead/behind origin/branch]
Proceed? [y/N]Only proceed after explicit user confirmation — or if user explicitly says "yes, proceed", "force it", "I know".
4. Specific Rules by Operation
Force Push (--force / -f)
- Check current branch — block if
main/masterunconditionally. - Run
git log origin/<branch>..HEAD --onelineto show what will be overwritten. - Show confirmation summary. Proceed only after user confirms.
- Never suggest
--force-with-leaseas a workaround to silently bypass this check.
Remote reference deletion
Treat remote branch or tag deletion like force push: inspect the impact and require explicit user confirmation. The shared policy blocks deletion options, empty-source reference mappings, and bulk pruning or mirroring capabilities. Preview mode retains the same gate. Repository addresses and transport option values are not references.
Reset Hard (reset --hard)
- Run
git log HEAD~<N>..HEAD --onelineto list commits being dropped. - Run
git status --shortto show uncommitted work that will be lost. - If uncommitted changes exist: explicitly list each file. Ask for confirmation.
- Proceed only after explicit confirmation.
Branch Delete (-D / -d)
- Run
git branch --mergedto check if the branch is merged. - If not merged: list the N commits that exist only on this branch.
- Warn: "These commits are not in any other branch. Deleting will make them unrecoverable without
git reflog." - Ask for explicit confirmation.
Checkout/Restore (. or path)
- List the files that will be reverted.
- Show which files have staged changes that would also be dropped.
- Ask for confirmation.
Clean (-f)
- Run
git clean -n(dry run) to list files that would be deleted. - Flag any
.env*or secret-looking files prominently. - Ask for explicit confirmation. Never auto-clean.
Commit/Push on main/master
- Detect current branch =
mainormaster. - Suggest: "Create a feature branch first:
git checkout -b feat/<name>" - Do NOT commit or push. Redirect the user.
--no-verify
- Never run any git command with
--no-verify. - Instead: investigate why the hook is failing and fix the root cause.
- If user insists, surface this as a hard stop: "The hook failure is protecting you. What does the error say?"
Non-Negotiables
- NEVER force-push to
main/masterunder any circumstances. - NEVER use
--no-verifyto bypass hooks. - NEVER silently proceed past uncommitted changes.
- NEVER delete an unmerged branch without explicit confirmation.
- If user overrides a warning ("I know, just do it"), proceed — but log what was overridden.
Mechanical checks (gen-18 Track 6 D6 — build the gate, not the prose)
The mechanical rules are pure, importable, replayably-tested functions in
git_safety.py (RED→GREEN fixtures in tests/test_git_safety.py,
run python3 -m pytest tests/). The active ~/.claude/hooks/pre_tool_use.py imports these
instead of re-deriving the rules as prose:
| Function | Catches |
is_destructive_restore(command, owned_paths) | git checkout -- … / git restore … / git checkout . that would discard UNOWNED in-session changes — returns a git stash suggestion. Distinguishes a working-tree discard from a bare branch switch. |
pr_body_is_empty(body) | gh pr create with a blank / template-only body (post-create non-empty assert). |
is_unauthorized_no_verify(command, authorized) | --no-verify on commit/push without authorization (git push -n = --dry-run is correctly NOT flagged). |
is_dangerous_rm(command, cwd, env) | Resolves shell assignments and cwd before judging recursive-delete breadth; a repo-contained literal prefix suppresses false blocks when a suffix remains dynamic. |
shell_text_without_heredoc_bodies(command) | Removes file-write heredoc prose from destructive scans while retaining executable substitutions in unquoted heredocs. |
dangerous_shell_reason(command, cwd, env) | Combined hook-facing F8 verdict for rm breadth and destructive command patterns. |
#501 denies recursive rm (with or without force) of ~/Gits, ancestors
of the active checkout, direct child directories of $HOME, and directory entries at the first level of
~/.claude, ~/.codex, ~/.cmux, ~/.config, ~/.ssh and ~/Library.
Existing paths use filesystem identity (including case and volume aliases);
unavailable identity falls back to case-folded physical spelling. Known regular
files remain eligible for cleanup and atomic moves. Inside ~/Gits, targets outside a checkout
are probed for .git at depth at most 3 with a 5,000-entry cap; cap or filesystem
errors fail closed. The initial checkout stays protected after cd; ~, ~+
and ~- use tracked HOME/cwd/oldpwd, and other tilde prefixes fail closed.
An exact recursive rm operand at repo depth 1 can pass when its existing
directory is not a symlink, resolves within the same checkout, is Git-ignored,
has no tracked index entries beneath it, and contains no worktree listed by
git worktree list --porcelain -z. Its resolved basename must exactly match
this case-sensitive build-output allowlist: .build, .build.noindex, build,
dist, node_modules, .next, .turbo, .parcel-cache, DerivedData, target,
__pycache__, .pytest_cache, .mypy_cache, .ruff_cache, .gradle, coverage.
Other ignored names, including docs.local, .worktrees, .env.d, and scratch,
retain the breadth denial. Git inspection errors retain that denial as well.
Protected roots and metadata, globs, loop-driven
cleanup, and other deletion tools receive no new exception.
The same target policy covers find -delete roots and local rsync --delete*/--del
destinations. Find follows its selected -H/-L/-follow policy (last
-P overrides earlier flags); local rsync destinations are evaluated physically.
Both also fail closed for targets affected by earlier path creation. Rsync
option values are separated from operands; unknown trailing long options fail
closed when the destination becomes ambiguous.
Find collects BSD/bfs root operands throughout the expression, separating primary
values and nested command operands; unknown primaries fail closed. Selective
in-repo filters can permit cleanup while retaining home/config/container and
active-ancestor protections. Unfiltered, broad, negated or ambiguous branches
retain breadth checks. Regex dialects and wildcard-only filename classes do
not qualify for a breadth exemption. Positive age filters below a top-level
directory retain the repo-root boundary.
Filename waivers preserve repository metadata: fixed names and object-name shapes
stay protected, and a read-only traversal checks actual metadata names below
selected roots and followed directory aliases. Outer depth limits come from the
root parser. Directory/metadata discovery refuses above one million entries, two seconds or 64
levels, on cycles, or on filesystem errors. Regular Finder litter is exempt;
directories and aliases with the same spelling remain protected. A grouped
prune arm retains the positive deletion filter, but deletion implies depth-first
traversal, so descendant metadata is still inspected. Ordinary nonmetadata regular files
do not consume that discovery budget.
Discovery reuses directory-entry information; dependency and worktree names never
waive nested metadata. Limit cleanup to literal subtrees and explicit depth limits
when an unbounded repository walk exceeds the fixed policy budget.
An over-budget refusal explains that the cleanup target is too large to verify
and suggests -maxdepth N or a narrower root. It remains a normal policy deny.
Moving protected roots is denied; deleting a path affected by an
earlier ln, mv or recursive cp fails closed. Removing an existing symlink
itself, safe deep cleanup and sanctioned disposable fixtures remain allowed.
Earlier mkdir retains protected directory roles while permitting known deep cleanup.
The opt-in scripts/cleanup_corpus_gate.py compares decision functions on exactly
200 frozen local commands. Capture requires --capture-projects; CI uses only
synthetic fixtures. It never executes commands and retains hashes plus private
source references. Each new denial requires a true-positive reason and evidence;
unclassified denials, missing frozen rows or a truncated sample fail the gate.
An exact in-repo find . -name __pycache__ -type d -prune -exec rm -r {} +
cache cleanup also remains allowed (including -R, -rf, -fr).
This is a bounded shell model, not a shell interpreter. Nonstandard containers
outside ~/Gits and the active checkout, remote rsync destinations, trash,
interpreter deletion one-liners and filesystem changes between evaluation and
execution remain outside its boundary. The lead tracks interpreter deletion
as a separate issue; passing this policy is not permission to delete.
Heredoc data masking also recognizes known stdin-preserving wrappers and one simple SSH remote interpreter or literal cat/tee file write. Shell readers, compound/uncertain remote commands and piped output retain body scanning; unquoted heredocs retain executable substitutions. Parse failures deny with a parse-failure explanation, without claiming a destructive git operation.
Wrapper evaluation is capped at 64 nested commands. Deeper input and any
RecursionError fail closed with a value-free reason. The hook also converts
unexpected policy-evaluation exceptions to a value-free block. The installed
git-guardian gate is pre_tool_use.py (source hooks/pre_tool_use.py), which
imports this skill's git_safety.py; it is distinct from the project
block-dangerous-commands.py and the human-confirm gate. Both host manifests
run it through golems-fail-open.py --fail-closed (#488). A missing, unreadable,
syntax-broken or crashed hook denies with the plain refusal: "Blocked: a golems safety
check couldn't run. Ask the lead to reinstall the hooks." Recovery uses
! bash ~/Gits/golems/scripts/hooks/install-hooks.sh --host <host> --update --apply.
Blocked Bash cannot perform agent recovery. A human uses
the prompt or an outside terminal (omit ! there). The installer clears the
missing pin's locked registration, and --update moves a broken pin to a healthy
commit. Local damage inside hooks-live refuses (tamper evidence) until a human
inspects it and re-runs with --restore-live.
The prompt's ! bypass remains the #411 assumption, not live-verified here.
Legitimate allow/deny results pass through. Other gates keep the default
fail-open launcher mode; tmp-block and human-confirm are the other policy gates.
The launcher is an installed copy so it survives a dangling hooks-live tree.
The registered command wraps it in a /bin/sh guard, so a missing pinned
interpreter or a launcher that cannot start also denies; a skipped harness
registration remains outside its own enforcement boundary. Lead installs through hooks-live after review/merge.
A hang (import-time included) is cut by the launcher's --budget watchdog,
registered 1 s under the manifest timeout (5 s timeout, 4 s budget): the hook's
process group is killed and the call denied before the harness timeout, which
would allow. Known residuals: registration/launcher edits can disable
enforcement, a hook subprocess that leaves the process group outlives the
kill, and only Python-level stdout/stderr is captured.
The "discard only what THIS session owns" rule is the key nuance: discarding your own
in-session edits is fine; discarding another agent's or the user's uncommitted work is the
footgun — prefer git stash so it is recoverable.
Integration
/pr-loopstep 5 — git-guardian's branch check is a prerequisite to commit; pr-loop handles CodeRabbit review./pr-loop— calls git-guardian before any force-push during rebase/fixup cycle.- Native
git worktree— worktrees always operate on non-main branches; git-guardian still applies for reset/clean inside worktrees.
Bare repositories are recognized by their HEAD file and object/reference directories. Their roots, containing repository folders, and selected metadata receive the same protection as checkout metadata. Multi-root selective cleanup shares one two-second traversal deadline; exhaustion keeps the actionable narrowing guidance. The three-second hook deadline remains unchanged.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

