Catches false claims from AI coding agents. Verifies that actions were actually performed - not just claimed.
npx truthguard install && npx truthguard initOr via Homebrew: brew tap spyrae/truthguard && brew install truthguard
AI coding agents systematically claim things they didn't do:
- "All tests pass!" - tests were never run (claude-code#1501)
- "I updated the file" - file content is identical
- "Done, committing" - with failing tests, using
--no-verify git push --force- without asking
These aren't malicious. They're hallucinations and shortcuts. But unverified claims break production.
TruthGuard hooks into the agent's tool call pipeline and verifies results in real-time:
Agent decides to run a command
|
[PreToolUse] -- block dangerous commands, run tests before commit
|
Command executes
|
[PostToolUse] -- verify exit code, check file checksums, remind to verify
| Hook | Type | What it catches |
|---|---|---|
| Dangerous Command Blocker | PreToolUse | --no-verify, --force push, rm -rf /, reset --hard |
| Pre-Commit Test Runner | PreToolUse | Auto-detects project, runs tests before every git commit |
| File Checksum Recorder | PreToolUse | Saves SHA256 before file edit (for phantom edit detection) |
| Exit Code Verifier | PostToolUse | Command failed but agent might claim success |
| Phantom Edit Detector | PostToolUse | Agent claims edit, but file checksum unchanged |
| Commit Verification Reminder | PostToolUse | Forces agent to verify fix works before claiming "done" |
Pre-commit hook auto-detects: Flutter / Node.js (npm test) / Python (pytest) / Rust (cargo test) / Go (go test) / Makefile (make test)
npx truthguard install # Install scripts to ~/.truthguard
cd your-project
npx truthguard init # Add hooks to .claude/settings.jsonRestart Claude Code. Done.
brew tap spyrae/truthguard
brew install truthguard
truthguard-install # Set up ~/.truthguardThen add hooks to your project manually (see Option C).
1. Clone:
git clone https://github.com/spyrae/truthguard.git ~/.truthguard2. Add to your project's .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "bash ~/.truthguard/scripts/block-dangerous.sh", "timeout": 5 },
{ "type": "command", "command": "bash ~/.truthguard/scripts/pre-commit-tests.sh", "timeout": 120 }
]
},
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "bash ~/.truthguard/scripts/pre-file-change.sh", "timeout": 5 }
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "bash ~/.truthguard/scripts/check-exit-code.sh", "timeout": 10 },
{ "type": "command", "command": "bash ~/.truthguard/scripts/post-commit-remind.sh", "timeout": 5 }
]
},
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "bash ~/.truthguard/scripts/check-file-change.sh", "timeout": 5 }
]
}
]
}
}3. Restart Claude Code. Hooks activate on session start.
gemini extensions install https://github.com/spyrae/truthguardHooks load automatically via the extension system.
When TruthGuard catches something:
π TruthGuard: Blocked git push --force. Use --force-with-lease for safer force push.
π TruthGuard: Test failures detected (exit code 1). Agent must fix before continuing.
β οΈ TruthGuard: File 'utils.dart' was not actually modified. Checksum unchanged.
β οΈ TruthGuard: Commit successful. Verify the fix works before claiming done.
Dogfooding on a production Flutter project (2 days):
| Event | Count | What happened |
|---|---|---|
| Pre-commit test blocks | 5 | Agent tried to commit with failing tests - blocked every time |
| Dangerous command blocks | 3 | git push --force and git commit --no-verify - blocked |
| Verification reminders | Active | Agent now acknowledges verification after each commit |
Zero false positives. Every block was a real issue.
Create .truthguard.yml in your project root:
# Override auto-detected test command
test_command: "npm run test:unit"
# Block commit if no tests found (default: true = skip)
skip_on_no_tests: false| Variable | Default | Description |
|---|---|---|
TRUTHGUARD_LOG |
~/.truthguard/session.log |
Session log location |
TRUTHGUARD_CHECKSUMS |
~/.truthguard/checksums/ |
Checksum storage directory |
/verify- Run tests + type checks + linting with auto-detection/truthguard-status- Show session statistics
jq- JSON processing (most systems have it;brew install jq/apt install jq)bash4+shasumorsha256sum
truthguard/
βββ bin/
β βββ truthguard.js # CLI: npx truthguard init/install/status
βββ scripts/
β βββ block-dangerous.sh # PreToolUse: block risky git commands
β βββ pre-commit-tests.sh # PreToolUse: run tests before commit
β βββ pre-file-change.sh # PreToolUse: record file checksums
β βββ check-exit-code.sh # PostToolUse: verify exit codes
β βββ check-file-change.sh # PostToolUse: detect phantom edits
β βββ post-commit-remind.sh # PostToolUse: verification reminder
β βββ run-tests.sh # Helper: auto-detect and run tests
βββ hooks/
β βββ hooks.json # Claude Code hook configuration
β βββ gemini.json # Gemini CLI hook configuration
βββ skills/
β βββ verify/SKILL.md # /verify slash command
β βββ status/SKILL.md # /truthguard-status slash command
βββ homebrew/
β βββ truthguard.rb # Homebrew formula
βββ .claude-plugin/
β βββ plugin.json # Claude Code plugin manifest
βββ gemini-extension.json # Gemini CLI extension manifest
βββ GEMINI.md # Context injected into Gemini sessions
βββ .truthguard.yml.example # Example configuration
βββ package.json # npm package config
βββ LICENSE # BUSL-1.1 (converts to MIT 2030-03-08)
βββ README.md
| Claude Code | Gemini CLI | Script |
|---|---|---|
| PreToolUse -> Bash | BeforeTool -> run_shell_command | block-dangerous.sh, pre-commit-tests.sh |
| PreToolUse -> Write|Edit | BeforeTool -> write_file|replace | pre-file-change.sh |
| PostToolUse -> Bash | AfterTool -> run_shell_command | check-exit-code.sh, post-commit-remind.sh |
| PostToolUse -> Write|Edit | AfterTool -> write_file|replace | check-file-change.sh |
Scripts are agent-agnostic: read JSON from stdin, output JSON to stdout. Hook configs handle the mapping.
Business Source License 1.1 - free for all use except building competing AI verification products. Converts to MIT on 2030-03-08.
Roman Belov - GitHub
