─── │ ╦ ╦╔═╗╔═╗╔═╗╦
│ ╠═╣╠═╣╠═╝╠═╣║
│ ╩ ╩╩ ╩╩ ╩ ╩╩
guardrails for AI coding assistants
Deterministic guardrails for AI coding assistants. Hooks that enforce rules before execution — not probabilistic prompts that get ignored.
hapai v1.7+ combines shell-based enforcement hooks with a cloud-native analytics dashboard. It intercepts Claude Code, Cursor, and Copilot tool calls in real-time and blocks violations immediately. When combined with Cloud Storage + BigQuery + GitHub Pages, it provides real-time visibility into guard enforcement across your team.
event_id per event, flow-dispatcher guard, incremental sync with cursor, BigQuery MERGE on event_idcontext RECORD in BigQuery: git op, branch, file category, risk tier, enforcement method, and more — enables deep analyticsstats_comparison, project_health, denial_reasons, context_breakdown, hook_detail, tool_detail + dedup CTE on all queriesaudit_log() resolves hook via BASH_SOURCE[] walk (fixes _lib pollution in audit logs)load_audit_from_gcs updated for Gen2 CloudEvent format; separate hapai-bq-query HTTP function for dashboardAI coding tools frequently ignore markdown instructions and safety guidelines. They commit to protected branches, edit secrets files, run destructive commands, and add AI attribution despite explicit rules.
Why this happens: LLMs see markdown as suggestions, not requirements.
The solution: Deterministic enforcement via hooks running before the action, not after.
# Install (no sudo required)
curl -fsSL https://raw.githubusercontent.com/renatobardi/hapai/main/install.sh | bash
# Reload PATH
source ~/.profile
# Install globally (all projects)
hapai install --global
# Or per-project
cd your-project && hapai install --project
# Verify
hapai validate
| Guardrail | What it prevents | Config key |
|---|---|---|
| Branch Protection | Commits/pushes/gh api deletions on protected branches (main, master, etc.) |
branch_protection.protected |
| Branch Taxonomy | Enforces naming conventions (feat/, fix/, chore/, etc.) | branch_taxonomy.allowed_prefixes |
| Branch Rules | Validates description + origin branch | branch_rules.enabled |
| Commit Hygiene | Co-Authored-By, AI mentions, "Generated with Claude" | commit_hygiene.blocked_patterns |
| File Protection | Writes to .env, lockfiles, CI workflow files | file_protection.protected |
| Destructive Commands | rm -rf, git push --force, git reset --hard, DROP TABLE |
command_safety.blocked |
| Blast Radius | Large commits touching too many files or packages | blast_radius.max_files |
| Uncommitted Changes | AI overwriting your uncommitted work | uncommitted_changes.enabled |
| PR Review | Background code review on all PRs (with optional auto-fix) | pr_review.enabled |
| Git Workflow | Trunk-based or GitFlow enforcement | git_workflow.model |
All guardrails support fail_open:
fail_open: false — Block execution, show errorfail_open: true — Warn but allow (soft constraints)Automations run in the background after tool execution, enabling proactive code fixes and improvements.
When code review finds issues, automatically attempt to fix them before blocking the push.
How it works:
auto_fix.enabled: true, launch background fix agentfix_clean state)fix_failed state)Configuration:
guardrails:
pr_review:
auto_fix:
enabled: false # opt-in (requires pr_review.enabled=true)
model: "claude-sonnet-4-6" # model for applying fixes
max_fix_attempts: 2 # rounds of fix → re-review → fix
severities: # which issues to auto-fix
- critical
- high
- medium
- low
Disabled by default — double opt-in ensures this is explicit and project-aware.
Deploy a real-time analytics dashboard to GitHub Pages to monitor guardrail events across your team.
🚀 View Live Demo — Real-time dashboard showing guardrail enforcement across teams.
hook_detail/tool_detail queries)context RECORD in BigQuery~/.hapai/audit.jsonl (with event_id + context)
↓ hapai sync (incremental, cursor-based)
gs://hapai-audit-{name}/YYYY-MM/DD-offset-N.jsonl
↓ load_audit_from_gcs (Gen2 Cloud Function, Storage trigger)
hapai_dataset.events (BigQuery, MERGE dedup on event_id)
↓ hapai-bq-query (HTTP Cloud Function, Firebase auth)
Dashboard (Svelte 5, GitHub Pages)
Overview Tab — Real-time guardrail enforcement snapshot
┌─────────────────────────────────────────────────────┐
│ 📊 KPI Bar: Denials | Warnings | Allow Rate | Deny │
├─────────────────────────────────────────────────────┤
│ 📈 Timeline: Daily enforcement trends (7/14/30d) │
│ 🎯 Project Health: Per-project health scores │
│ 📋 Denial Reasons: Top reasons ranked by frequency │
└─────────────────────────────────────────────────────┘
Projects Tab — Per-project enforcement summary
Project Name Deny Rate Top Guard Events
──────────────────────────────────────────────────────────
my-app 12% branch-protection 234
api-service 8% file-protection 89
dashboard 5% commit-hygiene 42
Guardrails Tab — Guard documentation & stats
Guard Blocks Warns Last Event Drill-Down
────────────────────────────────────────────────────────────────
branch-protection 1,245 342 2 min ago [Details]
file-protection 523 91 15 min ago [Details]
commit-hygiene 187 445 1 hour ago [Details]
Events Tab — Full audit log with filtering
Timestamp Hook Tool Project Result Reason
──────────────────────────────────────────────────────────────────────
14:32:15 guard-branch Bash my-app DENY Protected branch
14:31:02 guard-files Write api-service DENY .env edit blocked
14:29:45 guard-blast-radius Bash dashboard WARN 7 files touched
[Load More...]
load_audit_from_gcs (Storage trigger) + hapai-bq-query (HTTP trigger)VITE_FIREBASE_API_KEY, VITE_FIREBASE_APP_ID, VITE_BQ_PROXY_URL)https://{owner}.github.io/{repo}/Live Demo: https://renatobardi.github.io/hapai (requires GitHub OAuth login)
See infra/gcp/SETUP.md for complete setup guide.
Sync audit logs to GCP for enterprise analytics and compliance.
Architecture:
~/.hapai/audit.jsonl (event_id + context per entry)
↓ hapai sync (incremental — cursor-based, delta only)
gs://hapai-audit-{name}/YYYY-MM/DD-offset-N.jsonl
↓ load_audit_from_gcs (Gen2 Cloud Function, Storage trigger)
hapai_dataset.events (BigQuery — MERGE dedup on event_id)
↓ hapai-bq-query (HTTP Cloud Function, Firebase auth)
Analytics Dashboard (Svelte 5, GitHub Pages)
Auto-sync — get data to GCS automatically:
| Method | When | How |
|---|---|---|
| Claude Code | Session end | gcp.auto_sync.enabled: true in hapai.yaml |
| Cursor · Windsurf · Devin · Trae · Copilot | After each commit | hapai install --git-hooks |
| CI (safety net) | Daily at 2h UTC | hapai-sync.yml — loads from GCS to BigQuery |
Local sync:
# Authenticate once
gcloud auth application-default login
# Sync audit log to GCS + BigQuery
hapai sync
What you get:
gcloud auth application-default login)hapai-sync.yml for any GCS data not yet in BigQuerySee infra/gcp/SETUP.md for setup instructions.
| Automation | What it does | Config key |
|---|---|---|
| Auto-Checkpoint | Granular git snapshots per file edited | automation.auto_checkpoint |
| Auto-Format | Runs prettier/ruff/black after writes | automation.auto_format |
| Auto-Lint | Runs ESLint/ruff/pylint, reports issues | automation.auto_lint |
| Squash on Stop | Consolidates checkpoints into clean commits | automation.auto_checkpoint.squash_on_stop |
hapai install --global # Global (~/.hapai)
hapai install --project # Per-project (./hapai/)
hapai install --git-hooks # Post-commit auto-sync (Cursor/Windsurf/Devin/Trae/Copilot)
hapai uninstall [--global] # Remove hooks
hapai uninstall --git-hooks # Remove post-commit hook
hapai validate # Verify installation
hapai status # Hook registration and active guardrails
hapai audit [N] # Show last N audit entries (default: 20)
hapai kill # Disable all hooks immediately
hapai revive # Re-enable hooks
hapai export --target cursor # Generate Cursor rules
hapai export --target copilot # Generate Copilot rules
hapai export --target claude # Generate CLAUDE.md rules
YAML-based with three-tier fallback:
./hapai.yaml (overrides all)~/.hapai/hapai.yamlhapai.defaults.yamlcp hapai.defaults.yaml hapai.yaml
# Edit hapai.yaml for your project
version: "1.0"
risk_tier: high
guardrails:
branch_protection:
enabled: true
protected: [main, develop]
fail_open: false
branch_taxonomy:
enabled: true
allowed_prefixes: [feat, fix, chore, docs, refactor]
require_description: true
fail_open: false
blast_radius:
enabled: true
max_files: 5
max_packages: 1
fail_open: false # Block large changes
pr_review:
enabled: true
model: "claude-haiku-4-5-20251001"
fail_open: false # Require review to pass
automation:
auto_format:
enabled: true
python: "ruff format {file}"
javascript: "prettier --write {file}"
Technology Stack:
Design Principles:
Directory Structure:
~/.hapai/
├── hooks/
│ ├── _lib.sh (config, JSON I/O, audit)
│ ├── pre-tool-use/ (11 guardrails)
│ ├── post-tool-use/ (automations)
│ └── stop/ (session cleanup)
├── audit.jsonl (immutable audit log)
└── state/ (cross-session counters)
project-root/
├── hapai.yaml (project config)
├── infra/gcp/
│ ├── dashboard/ (Svelte 5 frontend)
│ ├── functions/ (Cloud Function)
│ └── SETUP.md (deployment guide)
├── .github/workflows/
│ ├── hapai-sync.yml (OIDC Cloud Storage sync)
│ └── deploy-dashboard.yml (GitHub Pages)
bash tests/run-tests.sh
Pure bash assertions (no test framework). ~200 assertions covering:
For cloud logging (optional):
Q: Hooks aren't blocking. Why?
hapai status # Check registration
hapai audit # See what hooks decided
# Edit hapai.yaml: ensure fail_open: false
Q: How do I see hook execution?
hapai audit 50 | jq # Recent entries
tail -f ~/.hapai/audit.jsonl | jq # Live stream
Q: Can I disable a guardrail?
# In hapai.yaml
guardrails:
branch_protection:
enabled: false # Disable specific guard
Q: Custom guardrails?
Create ~/.hapai/hooks/pre-tool-use/my-guard.sh:
#!/bin/bash
source "$HAPAI_LIB"
# Your logic here
exit 0 # allow
# or exit 2 # deny
MIT — See LICENSE file.
Contributions welcome! Please see CONTRIBUTING.md for:
Quick checklist:
bash tests/run-tests.sh)set -euo pipefail, shellcheck)hapai.defaults.yaml