git-safety-guard

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Git 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:
  • terraphim-agent guard
    - CLI command for pattern checking
  • 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命令,并阻止可能永久销毁未提交工作内容或重要文件的危险操作。该防护使用正则表达式模式匹配结合白名单来区分命令的安全变体和危险变体。
核心功能:
  • terraphim-agent guard
    - 用于模式检查的CLI命令
  • 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 -> Allow
Claude 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 PatternReason
git checkout -- <files>
Discards uncommitted changes permanently
git restore <files>
Discards uncommitted changes (except --staged)
git reset --hard
Destroys all uncommitted changes
git reset --merge
Can lose uncommitted changes
git clean -f
Removes untracked files permanently
git push --force
Destroys remote history
git push -f
Same as --force
git branch -D
Force-deletes branch without merge check
rm -rf
(non-temp paths)
Recursive file deletion
git stash drop
Permanently deletes stashed changes
git stash clear
Deletes ALL stashed changes
git commit --no-verify
Bypasses pre-commit and commit-msg hooks
git commit -n
Same as --no-verify
git push --no-verify
Bypasses pre-push hooks
命令模式原因
git checkout -- <files>
永久丢弃未提交的更改
git restore <files>
丢弃未提交的更改(
--staged
除外)
git reset --hard
销毁所有未提交的更改
git reset --merge
可能丢失未提交的更改
git clean -f
永久移除未跟踪的文件
git push --force
销毁远程仓库历史
git push -f
--force
功能相同
git branch -D
强制删除分支,不进行合并检查
rm -rf
(非临时路径)
递归删除文件
git stash drop
永久删除暂存的更改
git stash clear
删除所有暂存的更改
git commit --no-verify
绕过pre-commit和commit-msg钩子
git commit -n
--no-verify
功能相同
git push --no-verify
绕过pre-push钩子

Commands Explicitly Allowed

明确允许的命令

Command PatternWhy Safe
git checkout -b <branch>
Creates new branch, doesn't modify files
git checkout --orphan
Creates orphan branch
git restore --staged
Only unstages files, doesn't discard changes
git clean -n
/
--dry-run
Preview only, no actual deletion
git push --force-with-lease
Safer force push with remote check
rm -rf /tmp/...
Temp directories are designed for ephemeral data
rm -rf /var/tmp/...
System temp directory
rm -rf $TMPDIR/...
User's temp directory
命令模式安全原因
git checkout -b <branch>
创建新分支,不修改文件
git checkout --orphan
创建孤立分支
git restore --staged
仅取消暂存文件,不丢弃更改
git clean -n
/
--dry-run
仅预览,不实际删除
git push --force-with-lease
更安全的强制推送,包含远程仓库检查
rm -rf /tmp/...
临时目录用于存储临时数据
rm -rf /var/tmp/...
系统临时目录
rm -rf $TMPDIR/...
用户临时目录

For Humans

面向人类用户

Quick Start

快速开始

bash
undefined
bash
undefined

Install 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
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

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"}

undefined
undefined

Installation

安装

Project-local installation:
bash
undefined
项目级安装:
bash
undefined

Copy 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/):**
```bash

Run install script with --global flag

使用--global标志运行安装脚本

./scripts/install-terraphim-hooks.sh --global
undefined
./scripts/install-terraphim-hooks.sh --global
undefined

CLI Usage

CLI使用方法

bash
undefined
bash
undefined

Check 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
undefined
echo "git checkout -- ." | terraphim-agent guard --fail-open
undefined

For AI Agents

面向AI代理

Detecting Guard Availability

检测防护是否可用

bash
undefined
bash
undefined

Check 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
undefined
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
undefined

Using Guard in Hooks

在钩子中使用防护

PreToolUse Hook Pattern:
bash
#!/bin/bash
PreToolUse钩子模式:
bash
#!/bin/bash

Read 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
undefined
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
undefined

Guard 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=1

What 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
undefined
bash
undefined

Manual 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
undefined
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' |
.claude/hooks/git_safety_guard.sh
undefined

Troubleshooting

故障排除

IssueSolution
Hook not triggeringCheck
.claude/settings.local.json
configuration
Command not blockedVerify pattern matches with
terraphim-agent guard --json
Agent not foundBuild with
cargo build -p terraphim_agent --release
Permission deniedRun
chmod +x .claude/hooks/git_safety_guard.sh
jq not foundInstall jq:
brew install jq
or
apt install jq
问题解决方案
钩子未触发检查
.claude/settings.local.json
配置
命令未被拦截使用
terraphim-agent guard --json
验证模式是否匹配
未找到Agent使用
cargo build -p terraphim_agent --release
构建
权限被拒绝运行
chmod +x .claude/hooks/git_safety_guard.sh
未找到jq安装jq:
brew install jq
apt install jq

The Incident That Prompted This

开发背景

On December 17, 2025, an AI agent ran
git checkout --
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
git fsck --lost-found
, but it was a close call.
Instructions alone don't prevent accidents. Mechanical enforcement does.
2025年12月17日,某AI代理在多个包含其他代理数小时未提交工作内容的文件上执行了
git checkout --
命令,导致工作内容瞬间且无声地被销毁。最终通过
git fsck --lost-found
从悬空Git对象中恢复了文件,但过程十分惊险。
仅靠指令无法防止意外,机械性强制防护才是关键。

Related Skills

相关技能

  • terraphim-hooks
    - Knowledge graph-based text replacement
  • implementation
    - For building custom guards
  • testing
    - For validating guard behavior
  • devops
    - For CI/CD integration with hooks
  • terraphim-hooks
    - 基于知识图谱的文本替换
  • implementation
    - 用于构建自定义防护
  • testing
    - 用于验证防护行为
  • devops
    - 用于与CI/CD集成的钩子