Deterministic quality enforcement for Ralph. Unlike AGENTS.md guidance (advisory), hooks guarantee actions happen every time.
| Approach | Enforcement | Use Case |
|---|---|---|
| AGENTS.md | Advisory | Coding style, conventions |
| Hooks | Deterministic | Security, safety, quality gates |
Hooks catch mistakes that would otherwise require human review.
What it enforces:
- Blocks tracked file deletions unless the path is under
TRASH/ - Blocks committing secrets (
.env*, keys/certs, etc.) - Blocks very large diffs (>500 lines) unless explicitly allowed
- If
RALPH_HUMANS_WRITE_TESTS=1, blocks edits to test files
Environment variables:
RALPH_HOOKS_BYPASS=1- Skip all checks (emergency override)RALPH_ALLOW_LARGE_DIFF=1- Allow large file changesRALPH_MAX_CHANGED_LINES=N- Change the large diff threshold (default: 500)RALPH_HUMANS_WRITE_TESTS=1- Block test file modifications
What it enforces:
- If
prd.jsonexists, blocks pushing from a branch that doesn't matchprd.json.branchName
Environment variables:
RALPH_HOOKS_BYPASS=1- Skip check
Replacement for destructive deletes. Enforces the "NEVER use rm" rule from prompt.md.
./hooks/safe-rm path/to/file-or-dirBehavior:
- Creates
TRASH/directory if it doesn't exist - Moves files with timestamp prefix:
TRASH/20240115-143022-filename - Skips missing paths with warning
Environment variables:
RALPH_TRASH_DIR=custom-trash- Use a different trash directory
Runs formatters on edited files. Invoke from editor plugins or agent wrappers.
./hooks/post-edit.example src/component.tsxSupported formats: JS/TS (prettier), Python (black/ruff), Go (gofmt), Rust (rustfmt), JSON/MD (prettier), Shell (shfmt)
Environment variables:
RALPH_FORMAT_JS,RALPH_FORMAT_TS, etc. - Override formatter commands
Pre-flight check before editing files. Returns exit 1 if any file is protected.
./hooks/guardrails.example .env config/secrets.json
# ❌ BLOCKED: .env (protected by guardrails)Default protected patterns:
.env,.env.*- Environment files*.pem,*.key,*.p12,*.pfx- Certificates and keys*id_rsa*,*id_ed25519*- SSH keys*credentials*,*secrets*- Credential files
Environment variables:
RALPH_PROTECTED_PATTERNS="*.lock terraform/*"- Add protected patternsRALPH_ALLOWED_PATTERNS="TRASH/* temp/*"- Override protection for specific pathsRALPH_HOOKS_BYPASS=1- Skip all guardrails
Install git hooks into the current repo:
./hooks/install.shThis creates symlinks in .git/hooks/ pointing to the hooks in this directory.
To use example hooks, copy and customize:
cp hooks/post-edit.example hooks/post-edit
cp hooks/guardrails.example hooks/guardrails
chmod +x hooks/post-edit hooks/guardrails# Before edit_file
./hooks/guardrails "$FILE" || exit 1
# After edit_file
./hooks/post-edit "$FILE"# .github/workflows/pr.yml
- name: Check guardrails
run: |
CHANGED=$(git diff --name-only origin/main)
./hooks/guardrails.example $CHANGEDConfigure your editor to run post-edit on save for automatic formatting.
To add a new hook:
- Create the script in
hooks/ - Make it executable:
chmod +x hooks/my-hook - For git hooks, add to
install.sh - Document in this README
Follow the pattern of existing hooks:
- Use
set -euo pipefail - Support
RALPH_HOOKS_BYPASS=1for emergency override - Print clear error messages with ❌ prefix
- Exit 0 on success, 1 on failure