Hanfani Guard
A deterministic AI governance layer for your Git workflow.
Hanfani Guard is an open-source CLI that enforces your coding, Git, and project policies automatically — so you stop repeating the same operational instructions to every AI coding assistant.
Instead of telling Cursor, Claude Code, Codex, Copilot, Gemini CLI, or Windsurf the same things over and over:
- "Don't add
Co-authored-by." - "Use Conventional Commits."
- "Don't add a commit body."
- "Keep comments minimal."
- "Add tests."
- "Don't break existing features."
…you configure these rules once and let Hanfani Guard enforce them on every commit and push. It is not another AI coding agent — it is the deterministic guardrail that sits between AI-generated code and your repository.
Why
AI assistants generate code brilliantly, but they still need the same operational reminders in every project and every session. Hanfani Guard removes that friction by acting as a policy engine that runs locally, produces predictable results, and works regardless of which assistant wrote the code.
- Deterministic first — every rule produces predictable, repeatable results.
- AI-agnostic — works with any assistant (or none at all).
- Language-agnostic — operates on Git and config, not on a specific language.
- Local-first — no cloud service required; you own your configuration.
- Extensible — every policy can be independently enabled, disabled, or tuned.
Install
# one-off
npx @hanfani/guard init
# or globally
npm install -g @hanfani/guard
hanfani init
Requires Node.js >= 20.
Quick start
# 1. Create hanfani.config.ts and install Git hooks
hanfani init
# 2. Validate your working tree at any time
hanfani check
# 3. Commit with automatic policy enforcement + message sanitizing
git add .
hanfani commit -m "feat(api): add rate limiting"
# 4. Audit the whole repository
hanfani review
# 5. Verify your installation and hooks
hanfani doctor
Once hooks are installed, every commit is governed automatically — even
git commit made by your AI assistant. Disallowed commit bodies, Co-authored-by
trailers, and AI tool signatures are stripped deterministically; debug
statements, secrets, and policy violations block the commit.
Commands
| Command | Description |
|---|---|
hanfani init |
Create hanfani.config.ts and install Git hooks. |
hanfani check |
Run every configured policy against your changes. |
hanfani commit |
Sanitize the message, validate all policies, then commit. |
hanfani review |
Full repository audit with recommendations. |
hanfani doctor |
Verify installation, hooks, and configuration integrity. |
hanfani policies |
List all built-in policies. |
hanfani uninstall |
Remove Hanfani-managed Git hooks (leaves your config untouched). |
Useful flags: --json (machine-readable output), --quiet (only show failures),
-C, --cwd <dir> (run in another directory), --dry-run (for commit).
Configuration
hanfani init creates a typed hanfani.config.ts:
import { defineConfig } from "@hanfani/guard/config";
export default defineConfig({
commits: {
conventional: true, // enforce Conventional Commits
body: false, // strip / block commit bodies
coAuthors: false, // strip / block Co-authored-by trailers
},
comments: {
style: "minimal", // "off" | "minimal" | "strict"
},
testing: {
required: false, // require tests alongside source changes
changedFilesOnly: true,
},
github: {
requireCI: false, // require a GitHub Actions workflow
},
code: {
todos: "warn", // "off" | "warn" | "error"
debugStatements: "error", // console.log, debugger, print(), …
duplication: "warn", // copy-pasted blocks; "off" | "warn" | "error"
duplicationMinLines: 6, // minimum significant lines per duplicated block
syntax: "error", // unparseable JS/TS/JSX; "off" | "warn" | "error"
},
security: {
secrets: "error", // scan changed files for hardcoded credentials
patterns: [], // custom regex patterns for secrets
},
regression: {
enabled: false, // warn on risky changes (e.g. deleted source)
},
hooks: {
preCommit: true,
commitMsg: true,
prePush: false,
},
});
Every rule is configurable. Config files can also be .js, .mjs, .cjs, or
.json. Unknown, namespaced keys are preserved so future policy plugins can
read their own options.
To disable a specific policy without changing its category settings:
export default defineConfig({
disable: ["code/todos"],
});
Suppressing a single line
Add hanfani-allow in a comment on any line to acknowledge an intentional
match (e.g. a real console.log you want to keep):
console.log("intentional"); // hanfani-allow
Built-in policies
| ID | Stage(s) | What it enforces |
|---|---|---|
commits/conventional |
commit-msg | Conventional Commit subject format. |
commits/no-body |
commit-msg | Blocks commit bodies when disabled. |
commits/no-co-authors |
commit-msg | Blocks Co-authored-by: and AI signatures. |
code/todos |
pre-commit, check, review | TODO / FIXME / XXX / HACK / BUG markers. |
code/debug-statements |
pre-commit, check, review | Leftover debug statements (multi-language). |
code/duplication |
pre-commit, check, review | Copy-pasted code blocks within/across files. |
code/syntax |
pre-commit, check, review, push | Unparseable JS/TS/JSX (parse errors). |
comments/style |
pre-commit, check, review | Redundant, narrating comments and comment density. |
security/secrets |
pre-commit, check, review, push | Hardcoded credentials (AWS, GitHub, OpenAI, etc.). |
testing/required |
pre-commit, check, push, review | Tests accompany source changes. |
github/require-ci |
check, push, review | A GitHub Actions workflow exists. |
docs/require-readme |
check, review | A README exists at the repo root. |
regression/guard |
pre-commit, check, push, review | Warns on risky changes (deleted source, API). |
Git integration
hanfani init installs managed hooks (pre-commit, commit-msg, and
optionally pre-push). The hooks are marked with a header so Hanfani can update
or remove them safely, and they never overwrite an existing non-Hanfani hook
unless you pass --force. Each hook resolves hanfani from a global install,
a local node_modules/.bin, or npx — in that order.
Bypass in an emergency with git commit --no-verify (not recommended).
1. Expanded Secret Scanning
The security/secrets policy now detects 35+ provider-specific patterns:
- Cloud: AWS, Azure, Google Cloud, Firebase
- Source: GitHub (standard + fine-grained PAT), GitLab, npm, PyPI
- SaaS: OpenAI, Anthropic, Slack, Discord, Telegram, Twilio, Stripe, SendGrid, Shopify, Postman, Datadog
- Credentials in URLs and bearer tokens
- Entropy fallback: catches bespoke/rotated credentials via Shannon entropy analysis
Example:
const apiKey = "gT7xQ2vLpZ9kW4mB8nR1cE6sD3aF5hJ0"; // hanfani-allow — example: flagged as high-entropy secret
const token = process.env.API_KEY; // ← Allowed (env reference)
2. Code Duplication Detection
The code/duplication policy flags copy-pasted blocks within and across files:
- Normalizes source (strips whitespace, comments, imports)
- Hashes sliding windows of 6+ significant lines
- Reports duplicates with origin location
- Precise: ignores boilerplate and trivial lines
Example:
$ hanfani check
✗ Code / component duplication
→ Duplicated block of 6+ lines — matches src/cart.ts:10. (src/checkout.ts:1)
Configure with:
code: {
duplication: "warn", // "off" | "warn" | "error"
duplicationMinLines: 6, // minimum lines per block
}
3. Syntax / Parse Validation
The code/syntax policy catches parse errors before they land:
- Uses TypeScript compiler API for accurate parsing
- Supports
.ts,.tsx,.js,.jsx,.mjs,.cjs - Ignores non-script files (Python, Go, etc.)
- Prevents "Parsing ecmascript source code failed" at runtime
Example:
$ hanfani check
✗ Syntax / parse validation
→ Parse error: ':' expected. (src/api.ts:15)
hint: The file does not parse. Fix the syntax before committing.
Programmatic API
Hanfani Guard also ships a typed library so you can embed the engine or author custom policies:
import { Engine, buildContext, loadConfig, builtinPolicies } from "@hanfani/guard";
const { config } = await loadConfig(process.cwd());
const ctx = await buildContext({ stage: "check", cwd: process.cwd(), config });
const run = await new Engine(builtinPolicies).run(ctx);
console.log(run.summary);
Roadmap
The architecture is plugin-oriented to support, over time: AI policy plugins, team/organization policy sharing, security rule packs, CI/CD and IDE integrations, GitHub/GitLab/Bitbucket apps, multi-language analyzers, and AI-assisted regression detection — without changing the deterministic core.
Distribution beyond npm (Homebrew, Winget, apt, Chocolatey, Docker, standalone binaries) is planned; the engine is intentionally platform-agnostic.
Development
npm install
npm run build # bundle with tsup (ESM + type declarations)
npm run typecheck # tsc --noEmit
npm test # vitest
See CONTRIBUTING.md for how to add a policy and open a PR, and CHANGELOG.md for release history.