git-safety-guard
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGit Safety Guard
Git安全防护
Use this skill when setting up or configuring protection against destructive git/filesystem commands in Claude Code.
当你在Claude Code中设置或配置针对破坏性Git/文件系统命令的防护时,请使用此技能。
Overview
概述
Git Safety Guard intercepts Bash commands before execution and blocks dangerous operations that could permanently destroy uncommitted work or important files. The guard uses regex pattern matching with an allowlist to distinguish between safe and dangerous variants of commands.
Key Features:
- - CLI command for pattern checking
terraphim-agent guard - PreToolUse hook - Intercept Claude Code tool calls before execution
- Allowlist support - Safe patterns override dangerous patterns
- Fail-open semantics - If guard fails, commands pass through
Git安全防护会在执行前拦截Bash命令,并阻止可能永久销毁未提交工作内容或重要文件的危险操作。该防护使用正则表达式模式匹配结合白名单来区分命令的安全变体和危险变体。
核心功能:
- - 用于模式检查的CLI命令
terraphim-agent guard - PreToolUse钩子 - 在执行前拦截Claude Code的工具调用
- 白名单支持 - 安全模式可覆盖危险模式
- 故障开放语义 - 若防护失效,命令将直接通过
Architecture
架构
Claude Code PreToolUse
|
v
git_safety_guard.sh (shell wrapper)
|
v
terraphim-agent guard --json "$COMMAND"
|
v
Pattern Matching (Regex)
|
+---> SAFE_PATTERNS (allowlist) -> Allow
|
+---> DESTRUCTIVE_PATTERNS -> Block with reason
|
+---> No match -> AllowClaude Code PreToolUse
|
v
git_safety_guard.sh (shell wrapper)
|
v
terraphim-agent guard --json "$COMMAND"
|
v
Pattern Matching (Regex)
|
+---> SAFE_PATTERNS (白名单) -> 允许
|
+---> DESTRUCTIVE_PATTERNS -> 拦截并给出原因
|
+---> 无匹配 -> 允许Commands Blocked
被拦截的命令
| Command Pattern | Reason |
|---|---|
| Discards uncommitted changes permanently |
| Discards uncommitted changes (except --staged) |
| Destroys all uncommitted changes |
| Can lose uncommitted changes |
| Removes untracked files permanently |
| Destroys remote history |
| Same as --force |
| Force-deletes branch without merge check |
| Recursive file deletion |
| Permanently deletes stashed changes |
| Deletes ALL stashed changes |
| Bypasses pre-commit and commit-msg hooks |
| Same as --no-verify |
| Bypasses pre-push hooks |
| 命令模式 | 原因 |
|---|---|
| 永久丢弃未提交的更改 |
| 丢弃未提交的更改( |
| 销毁所有未提交的更改 |
| 可能丢失未提交的更改 |
| 永久移除未跟踪的文件 |
| 销毁远程仓库历史 |
| 与 |
| 强制删除分支,不进行合并检查 |
| 递归删除文件 |
| 永久删除暂存的更改 |
| 删除所有暂存的更改 |
| 绕过pre-commit和commit-msg钩子 |
| 与 |
| 绕过pre-push钩子 |
Commands Explicitly Allowed
明确允许的命令
| Command Pattern | Why Safe |
|---|---|
| Creates new branch, doesn't modify files |
| Creates orphan branch |
| Only unstages files, doesn't discard changes |
| Preview only, no actual deletion |
| Safer force push with remote check |
| Temp directories are designed for ephemeral data |
| System temp directory |
| User's temp directory |
| 命令模式 | 安全原因 |
|---|---|
| 创建新分支,不修改文件 |
| 创建孤立分支 |
| 仅取消暂存文件,不丢弃更改 |
| 仅预览,不实际删除 |
| 更安全的强制推送,包含远程仓库检查 |
| 临时目录用于存储临时数据 |
| 系统临时目录 |
| 用户临时目录 |
For Humans
面向人类用户
Quick Start
快速开始
bash
undefinedbash
undefinedInstall terraphim-agent from GitHub releases (latest version)
从GitHub Releases安装terraphim-agent(最新版本)
macOS ARM64 (Apple Silicon)
macOS ARM64(Apple Silicon)
gh release download --repo terraphim/terraphim-ai
--pattern "terraphim-agent-aarch64-apple-darwin" --dir /tmp chmod +x /tmp/terraphim-agent-aarch64-apple-darwin mv /tmp/terraphim-agent-aarch64-apple-darwin ~/.cargo/bin/terraphim-agent
--pattern "terraphim-agent-aarch64-apple-darwin" --dir /tmp chmod +x /tmp/terraphim-agent-aarch64-apple-darwin mv /tmp/terraphim-agent-aarch64-apple-darwin ~/.cargo/bin/terraphim-agent
gh release download --repo terraphim/terraphim-ai
--pattern "terraphim-agent-aarch64-apple-darwin" --dir /tmp chmod +x /tmp/terraphim-agent-aarch64-apple-darwin mv /tmp/terraphim-agent-aarch64-apple-darwin ~/.cargo/bin/terraphim-agent
--pattern "terraphim-agent-aarch64-apple-darwin" --dir /tmp chmod +x /tmp/terraphim-agent-aarch64-apple-darwin mv /tmp/terraphim-agent-aarch64-apple-darwin ~/.cargo/bin/terraphim-agent
macOS x86_64 (Intel)
macOS x86_64(Intel)
gh release download --repo terraphim/terraphim-ai \
gh release download --repo terraphim/terraphim-ai \
--pattern "terraphim-agent-x86_64-apple-darwin" --dir /tmp
--pattern "terraphim-agent-x86_64-apple-darwin" --dir /tmp
Linux x86_64
Linux x86_64
gh release download --repo terraphim/terraphim-ai \
gh release download --repo terraphim/terraphim-ai \
--pattern "terraphim-agent-x86_64-unknown-linux-gnu" --dir /tmp
--pattern "terraphim-agent-x86_64-unknown-linux-gnu" --dir /tmp
Note: crates.io version (cargo install terraphim_agent) is outdated (v1.0.0)
注意:crates.io版本(cargo install terraphim_agent)已过时(v1.0.0)
and missing the guard command. Use GitHub releases for latest features.
且缺少guard命令。请使用GitHub Releases获取最新功能。
Test guard command
测试guard命令
echo "git checkout -- file.txt" | terraphim-agent guard --json
echo "git checkout -- file.txt" | terraphim-agent guard --json
Output: {"decision":"block","reason":"git checkout -- discards...","command":"..."}
输出:{"decision":"block","reason":"git checkout -- discards...","command":"..."}
echo "git checkout -b new-branch" | terraphim-agent guard --json
echo "git checkout -b new-branch" | terraphim-agent guard --json
Output: {"decision":"allow","command":"git checkout -b new-branch"}
输出:{"decision":"allow","command":"git checkout -b new-branch"}
undefinedundefinedInstallation
安装
Project-local installation:
bash
undefined项目级安装:
bash
undefinedCopy hook script
复制钩子脚本
cp .claude/hooks/git_safety_guard.sh /your/project/.claude/hooks/
cp .claude/hooks/git_safety_guard.sh /your/project/.claude/hooks/
Add to .claude/settings.local.json
添加到.claude/settings.local.json
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": ".claude/hooks/git_safety_guard.sh"
}]
}]
}
}
**Global installation (~/.claude/):**
```bash{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": ".claude/hooks/git_safety_guard.sh"
}]
}]
}
}
**全局安装(~/.claude/):**
```bashRun install script with --global flag
使用--global标志运行安装脚本
./scripts/install-terraphim-hooks.sh --global
undefined./scripts/install-terraphim-hooks.sh --global
undefinedCLI Usage
CLI使用方法
bash
undefinedbash
undefinedCheck a command (JSON output)
检查命令(JSON输出)
echo "git reset --hard" | terraphim-agent guard --json
echo "git reset --hard" | terraphim-agent guard --json
Check a command (human output - exits with code 1 if blocked)
检查命令(人类可读输出 - 若被拦截则返回退出码1)
echo "rm -rf /home/user" | terraphim-agent guard
echo "rm -rf /home/user" | terraphim-agent guard
Fail-open mode (always exit 0)
故障开放模式(始终返回退出码0)
echo "git checkout -- ." | terraphim-agent guard --fail-open
undefinedecho "git checkout -- ." | terraphim-agent guard --fail-open
undefinedFor AI Agents
面向AI代理
Detecting Guard Availability
检测防护是否可用
bash
undefinedbash
undefinedCheck if terraphim-agent is available
检查terraphim-agent是否可用
if command -v terraphim-agent >/dev/null 2>&1; then
echo "Guard available"
elif [ -x "./target/release/terraphim-agent" ]; then
AGENT="./target/release/terraphim-agent"
fi
undefinedif command -v terraphim-agent >/dev/null 2>&1; then
echo "Guard available"
elif [ -x "./target/release/terraphim-agent" ]; then
AGENT="./target/release/terraphim-agent"
fi
undefinedUsing Guard in Hooks
在钩子中使用防护
PreToolUse Hook Pattern:
bash
#!/bin/bashPreToolUse钩子模式:
bash
#!/bin/bashRead JSON input
读取JSON输入
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
Only process Bash commands
仅处理Bash命令
[ "$TOOL_NAME" != "Bash" ] && exit 0
[ "$TOOL_NAME" != "Bash" ] && exit 0
Check command
检查命令
RESULT=$(terraphim-agent guard --json <<< "$COMMAND")
RESULT=$(terraphim-agent guard --json <<< "$COMMAND")
If blocked, output deny decision
若被拦截,输出拒绝决策
if echo "$RESULT" | jq -e '.decision == "block"' >/dev/null; then
REASON=$(echo "$RESULT" | jq -r '.reason')
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "BLOCKED: $REASON"
}
}
EOF
fi
exit 0
undefinedif echo "$RESULT" | jq -e '.decision == "block"' >/dev/null; then
REASON=$(echo "$RESULT" | jq -r '.reason')
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "BLOCKED: $REASON"
}
}
EOF
fi
exit 0
undefinedGuard Response Format
防护响应格式
Blocked command:
json
{
"decision": "block",
"reason": "git checkout -- discards uncommitted changes permanently. Use 'git stash' first.",
"command": "git checkout -- file.txt",
"pattern": "git\\s+checkout\\s+--\\s+"
}Allowed command:
json
{
"decision": "allow",
"command": "git checkout -b new-branch"
}被拦截的命令:
json
{
"decision": "block",
"reason": "git checkout -- discards uncommitted changes permanently. Use 'git stash' first.",
"command": "git checkout -- file.txt",
"pattern": "git\\s+checkout\\s+--\\s+"
}允许的命令:
json
{
"decision": "allow",
"command": "git checkout -b new-branch"
}Error Handling
错误处理
The guard uses fail-open semantics:
- If terraphim-agent is not found: pass through unchanged
- If pattern matching fails: allow command
- Errors logged to stderr only in verbose mode
Enable verbose mode:
bash
export TERRAPHIM_VERBOSE=1防护采用故障开放语义:
- 若未找到terraphim-agent:命令直接通过
- 若模式匹配失败:允许命令执行
- 仅在 verbose 模式下将错误记录到stderr
启用verbose模式:
bash
export TERRAPHIM_VERBOSE=1What Happens When Blocked
被拦截时的行为
When Claude tries to run a blocked command, it receives feedback like:
BLOCKED by git_safety_guard
Reason: git checkout -- discards uncommitted changes permanently. Use 'git stash' first.
Command: git checkout -- file.txt
If this operation is truly needed, ask the user for explicit permission and have them run the command manually.The command never executes. Claude sees this feedback and should ask the user for help.
当Claude尝试运行被拦截的命令时,会收到如下反馈:
BLOCKED by git_safety_guard
Reason: git checkout -- discards uncommitted changes permanently. Use 'git stash' first.
Command: git checkout -- file.txt
If this operation is truly needed, ask the user for explicit permission and have them run the command manually.命令永远不会执行。Claude会看到此反馈并应向用户寻求帮助。
Testing
测试
bash
undefinedbash
undefinedManual test - should be blocked
手动测试 - 应被拦截
echo "git checkout -- test.txt" | terraphim-agent guard --json
echo "git checkout -- test.txt" | terraphim-agent guard --json
Manual test - should be allowed
手动测试 - 应被允许
echo "git checkout -b feature" | terraphim-agent guard --json
echo "git checkout -b feature" | terraphim-agent guard --json
Run unit tests
运行单元测试
cargo test -p terraphim_agent guard_patterns
cargo test -p terraphim_agent guard_patterns
Test hook script
测试钩子脚本
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' |
.claude/hooks/git_safety_guard.sh
.claude/hooks/git_safety_guard.sh
undefinedecho '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' |
.claude/hooks/git_safety_guard.sh
.claude/hooks/git_safety_guard.sh
undefinedTroubleshooting
故障排除
| Issue | Solution |
|---|---|
| Hook not triggering | Check |
| Command not blocked | Verify pattern matches with |
| Agent not found | Build with |
| Permission denied | Run |
| jq not found | Install jq: |
| 问题 | 解决方案 |
|---|---|
| 钩子未触发 | 检查 |
| 命令未被拦截 | 使用 |
| 未找到Agent | 使用 |
| 权限被拒绝 | 运行 |
| 未找到jq | 安装jq: |
The Incident That Prompted This
开发背景
On December 17, 2025, an AI agent ran on multiple files containing hours of uncommitted work from another agent. This destroyed the work instantly and silently. The files were recovered from a dangling Git object via , but it was a close call.
git checkout --git fsck --lost-foundInstructions alone don't prevent accidents. Mechanical enforcement does.
2025年12月17日,某AI代理在多个包含其他代理数小时未提交工作内容的文件上执行了命令,导致工作内容瞬间且无声地被销毁。最终通过从悬空Git对象中恢复了文件,但过程十分惊险。
git checkout --git fsck --lost-found仅靠指令无法防止意外,机械性强制防护才是关键。
Related Skills
相关技能
- - Knowledge graph-based text replacement
terraphim-hooks - - For building custom guards
implementation - - For validating guard behavior
testing - - For CI/CD integration with hooks
devops
- - 基于知识图谱的文本替换
terraphim-hooks - - 用于构建自定义防护
implementation - - 用于验证防护行为
testing - - 用于与CI/CD集成的钩子
devops