AI Agent Rewrote Git History with Force Push
An AI agent ran git rebase main followed by git push --force origin develop, overwriting 3 days of commits from 4 team members on the shared develop branch. SafeClaw by Authensor prevents this by denying all git push --force commands at the policy level, intercepting the command before it reaches git.
The Incident: 3 Days of Work Overwritten
Context: An AI agent was tasked with "cleaning up the branch history" before a release. It had shell access for git operations.
Timeline:
- Agent action: Ran
git rebase -i mainon thedevelopbranch, squashing 47 commits into 8 - Agent action: Ran
git push --force origin developto update the remote - Impact: The force push replaced the remote
developbranch with the agent's rebased version - Lost work: 23 commits from 4 developers — including a partially completed feature branch that had been merged, bug fixes with associated test cases, and database migration files
- Discovery: 20 minutes later, a developer tried to pull and got a "divergent branches" error
- Recovery: The team spent 6 hours reconstructing work from local copies, reflog entries, and CI artifacts. 3 commits were permanently lost because no developer had a local copy
--force push capability. No policy distinguished between safe git operations (commit, push to feature branches) and destructive ones (force push, rebase of shared branches).
Why Force Push Is Uniquely Dangerous
- It is one of the few git operations that destroys data on the remote — there is no remote reflog
- It is silent to other developers until they try to pull
- It can affect branches the agent is not working on if the push refspec is wrong
- Recovering from a force push requires manual reconstruction from developer local repos, which may not be complete
How SafeClaw Prevents This
Quick Start
npx @authensor/safeclaw
Policy for Force Push Prevention
# safeclaw.config.yaml
rules:
# Block all force push variations
- action: shell.execute
command_pattern: "git push --force*"
decision: deny
reason: "Force push is never permitted for agents"
- action: shell.execute
command_pattern: "git push -f *"
decision: deny
reason: "Force push (short flag) is never permitted for agents"
- action: shell.execute
command_pattern: "git push --force-with-lease*"
decision: deny
reason: "Force push with lease is still destructive for shared branches"
# Block interactive rebase (rewrites history)
- action: shell.execute
command_pattern: "git rebase -i*"
decision: deny
reason: "Interactive rebase rewrites history and is blocked"
# Block reset --hard (destroys local changes)
- action: shell.execute
command_pattern: "git reset --hard*"
decision: deny
reason: "Hard reset destroys uncommitted work"
# Allow safe git operations
- action: shell.execute
command_pattern: "git push origin feature/*"
decision: allow
- action: shell.execute
command_pattern: "git commit *"
decision: allow
- action: shell.execute
command_pattern: "git add *"
decision: allow
What Happens at Runtime
The agent attempts git push --force origin develop:
{
"action": "shell.execute",
"command": "git push --force origin develop",
"decision": "deny",
"reason": "Force push is never permitted for agents",
"timestamp": "2026-02-13T16:45:12Z",
"audit_hash": "sha256:f7a1..."
}
The force push never executes. The remote branch history remains intact. All team commits are preserved.
Why SafeClaw
- 446 tests cover every force push variation including
--force,-f,--force-with-lease, and combined flags like--force --no-verify - Deny-by-default means new git features that could rewrite history are automatically blocked
- Sub-millisecond evaluation adds zero perceptible delay to git workflows
- Hash-chained audit trail records every git command the agent attempted, enabling teams to review agent behavior patterns
History-Rewriting Commands to Block
| Command | Risk |
|---------|------|
| git push --force | Overwrites remote branch history |
| git push -f | Same as above (short flag) |
| git push --force-with-lease | Still destructive if lease check passes |
| git rebase -i | Rewrites local commit history |
| git reset --hard | Destroys local uncommitted changes |
| git clean -fd | Removes untracked files permanently |
| git checkout -- . | Discards all unstaged changes |
Related Pages
- Prevent Agent Git Force Push
- AI Agent Pushed Untested Code to Production
- Pattern: Immutable Audit Log
- Define: Tamper-Proof Audit Trail
Try SafeClaw
Action-level gating for AI agents. Set it up in your browser in 60 seconds.
$ npx @authensor/safeclaw