Banh-Mi-Guard Bánh Mì Logo

Banh-Mi-Guard

The Sandwich Pattern Regression Guard for AI-Assisted Development

⭐ Star on GitHub

Dual-Gate Impact Analysis & Regression Guard for AI-Assisted Development.
A safety harness around AI coding agents (Claude Code, Cursor, Windsurf, Aider, omp): scope and diff checks, static rules and project invariants at no token cost, then an LLM review, before a change is accepted.

1. Overview & Vision

Coding agents are fast, but they can be careless: they accidentally delete keyboard shortcuts, drop responsive CSS classes, leak API tokens, or make out-of-scope modifications across untouched files.

guard enforces a deterministic Sandwich Pattern around every task:

Before code is touched (Pre-Task): guard records the declared scope and a baseline snapshot, detects the repository domain, extracts existing baseline contracts, and locks the project invariants.

After code is written (Post-Task): guard measures the exact diff blast radius and scans its static rulebook, on request (guard post --full) Alibaba Open Code Review (OCR) reviews the changes with your LLM (with --full, a high or critical finding, OCR not running or a review OCR did not complete blocks approval; lower findings are reported, and an OCR status of skipped is reported without blocking. A plain guard post reports OCR as "not run", which never blocks), the project build/test command runs, the invariant checks verify the locked rules, and your configured LLM issues the final authoritative verdict (APPROVED or REVISE).

2. Three-Pillar Architecture

               [User Task / Issue Prompt]
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. PRE-TASK PHASE: `guard pre "<prompt>"`                   │
│ • Scope declaration & repository domain detection           │
│ • Contract hints (keyword scan of up to 5 scoped files)     │
│ • Lock Invariant Rules (Must NOT be broken)                 │
│ ➔ Emits: "### 🔍 PRE-TASK IMPACT NOTE"                      │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼ (AI Coding Agent / Developer modifies code)
                           │
┌─────────────────────────────────────────────────────────────┐
│ 2. POST-TASK PHASE: `guard post`                            │
│ • Diff Inspector (0-cost): Diff audit & blast radius check  │
│ • Static rules: secrets, injection, XSS, infra, UX          │
│ • Alibaba OCR (LLM, --full): Reviews the task's changes     │
│ • Project Health Check: Automated compile & test execution  │
│ • Invariant checks (0-cost): guard.invariants.json rules    │
│ ➔ Compiles: "### 🧪 POST-TASK VERIFICATION"                 │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. FINAL REVIEW: YOUR CONFIGURED LLM                        │
│ (Claude / GPT / DeepSeek / Ollama / OpenAI-compatible)      │
│ • Reviews the report, verified evidence & batched diff      │
│ • Technical Audit (architecture, memory, nulls, scope)      │
│ • Cross-Platform UX/UI & Ergonomics Assessment              │
│ • Verdict: [APPROVED] or [REVISE] with Actionable Remediation│
└─────────────────────────────────────────────────────────────┘

3. 2D Quality Matrix: Platform Domains × Quality Pillars

Guard looks at a change across 5 Platform Domains (frontend, backend, fullstack, infra, mobile) and 7 Cross-Cutting Quality Pillars. In each cell, a rule ID is a deterministic check on the diff, run on every guard post at no token cost; what follows the ·, or a cell without an ID, is what the LLM review is asked to look at (concerns like resource leaks, null dereferences, blocking async calls, dead code, and over-engineering are checked by the LLM review in every language). Most rules read the lines a change adds and skip docs, tests, comments and lines over 2,000 characters (the LLM review still sees them); for those line rules, a line marked guard-allow <RULE>: <reason> in a comment stays in the report as a LOW note. quality-pillars.md lists every rule.

Platform Domain 🛡️ Security 🧠 Memory Safety ⚡ Performance 🧱 Integrity & Schema ♿ UX & Ergonomics 🧹 Code Hygiene 🛋️ Simplicity (KISS/YAGNI)
Frontend (React, Vue, Svelte) SEC-001 SEC-003 SEC-005 SEC-006 SEC-007 SEC-008 secrets, HTML sinks, eval, TLS off, open CORS, tokens in localStorage · CSP listeners without removers, intervals never cleared · detached DOM blocking calls · re-renders deep property access without checks · UI states UX-001 UX-002 hidden focus ring, images without alt · keyboard, modals, mobile view DEAD-001 DEAD-REF · commented code LAZY-001 · over-engineering, reinvented helpers
Backend (Python, Go, Node, Rust, Java, Kotlin, C#, PHP, Ruby) SEC-001 SEC-002 SEC-003 SEC-004 SEC-005 SEC-006 SEC-007 secrets, SQL, raw HTML sinks, deserialization, shell/eval, TLS off, open CORS · auth, RBAC unclosed streams and connections, unclosed resources blocking calls in async code · N+1 queries, async blocking build and tests, project invariants · schema compatibility, atomic writes, null dereference error codes and status DEAD-001 DEAD-REF · commented code, unused imports and private functions LAZY-001 · over-engineering, reinvented helpers
Fullstack (both in one repository) every frontend and backend rule, on its own files as frontend and backend as frontend and backend the API contract between both halves: project invariants · the LLM review as frontend and backend DEAD-REF a removed key still used by the other half LAZY-001 · over-engineering, reinvented helpers
Infra / DevOps (Docker, Kubernetes, Compose) SEC-001 INFRA-001 INFRA-003 SEC-006 secrets, privileged or host access, root user, TLS off · open ports resource limits, quotas image size, startup time INFRA-002 unpinned or :latest images · rollout safety liveness and readiness probes DEAD-001 orphan files · stale scripts minimal manifests and base images
Mobile (Android, iOS, Flutter, React Native) SEC-001 SEC-002 SEC-004 SEC-005 SEC-006 SEC-008 MOB-001 MOB-002 secrets, SQL, deserialization, shell/eval, TLS off, tokens in storage, debuggable Android builds, cleartext traffic, backups, iOS ATS off, shared Documents folder · permissions intervals never cleared · retained controllers, bitmaps frame rate, battery offline sync safe areas, notch DEAD-001 unused assets · commented code LAZY-001 · native UI primitives, no heavy SDKs

Focused Deep-Dives (--focus)

By default, all quality pillars are audited at 100% rigor. When investigating specific defects, use the --focus flag to direct the LLM gate's analytical scrutiny:

# Scrutinize KISS, YAGNI, over-engineering & dependency bloat:
guard review --focus simplicity

# Scrutinize dead code, zombie blocks & orphan files:
guard review --focus dead-code
# Ask the LLM review to look at memory handling (listeners, unclosed handles):
guard review --focus memory

# Scrutinize security vulnerabilities (SQLi, XSS, secrets):
guard review --focus security

# Scrutinize performance (blocking I/O, heavy operations):
guard review --focus performance

# Scrutinize ergonomics and responsive UX:
guard review --focus ux

4. Installation Guide (Cross-Platform)

Works natively on Windows, Linux, and macOS:

# Recommended: Install globally from PyPI via pipx (Linux/macOS)
pipx install banh-mi-guard

# Or with standard pip (Windows / Linux / macOS)
pip install banh-mi-guard

# Or the newest main branch straight from GitHub (can be ahead of the last release)
pip install git+https://github.com/okrath/banh-mi-guard.git

# Install globally (hooks + agent directives), no model download needed:
guard install

# Verify installation health
guard doctor

5. LLM Setup Wizard & Auto-Sync

Run the interactive step-by-step wizard to configure your preferred LLM provider. The settings are written into the Alibaba OCR CLI as its custom provider guard, so the optional OCR review that guard post --full adds uses the same LLM:

guard config llm

Test your connection with an instant sub-second verification ping:

guard config test

Choose who writes commit messages for approved work: auto lets the agent write them, ask makes it ask you for each one. guard doctor always shows the choice as "Commit messages" (guard install lists it only while it is still unset), and an approved post report ends with a Commit line that tells the agent what to do.

guard config commit auto

6. Install: Global or Workspace

Two ways to install, neither needs a per-repository step:

# Global (whole machine): Git hooks for every repository + guard directives in the global
# instruction file of each installed agent (Claude Code, Codex, Gemini CLI, opencode)
guard install

# Workspace (one folder only): directives in that folder's CLAUDE.md / AGENT.md
# + Git hooks in its repository or every repository below it
guard install --workspace path/to/workspace

# Remove what install added
guard uninstall [--workspace path/to/workspace]

The agent reads the directives and runs guard pre before editing; the first guard run inside a repository sets it up, and the Git hook checks every commit. Agents without a global instruction file (Cursor, omp) get the directives through a workspace install.

🧾 No diff in your repository: inside a repository guard writes only in .git and the Git-excluded .guard/ folder (local invariants, sessions, reports). Repository files (agent docs, hooks kept in the tree such as .husky/, guard.invariants.json) are only read; guard doctor tells you what to change. Where guard is asked to write agent docs, it appends a marked block and keeps your content (.guard.bak backup).

🔒 State isolation & signed approvals: approvals are cryptographically signed with HMAC-SHA256 ($GUARD_HOME/approval.key). Automated agent edit tools are blocked on .guard/, and unsigned approvals are refused on commit. See Architecture: Security Model.

After an upgrade, guard update self refreshes what guard installed and prints a setup check; guard doctor shows the same check at any time.

7. CLI Command Reference

Command Description Common Flags
guard install Install globally (hooks + agent directives) or for one folder --workspace <dir>
guard pre "<prompt>" Run Pre-Task Guard: scope, baseline, contracts & locked invariants --scope <path>, --allow-dirty, --force
guard post Run Post-Task Guard: diff audit, rules, build, invariants, LLM final gate --focus <area>, --hook, --full, --reviewers, --validate, --test-checklist, --threat-frame, --max-llm-calls
guard run "<prompt>" -- <cmd> Execute Sandwich Pattern: pre ➔ command ➔ post --scope, --allow-dirty, --force
guard invariants init / check / prune Create local invariants file / evaluate rules / prune unchecked learned rules --shared
guard reset Close the current session (archived to .guard/history/) —
guard finding <id> Record a deferral or a rejection of a review finding; the next review sees the reason --defer "<why>", --reject "<evidence>"
guard untracked [path] Decide whether an untracked path is tracked by guard or always ignored --include, --ignore
guard accept Your decision on a task that used its review rounds: approve as reviewed, or allow three more rounds interactive terminal only
guard setup Interactive setup for missing config: LLM, Alibaba OCR, commit mode, agent hooks —
guard review Perform on-demand LLM Code Review on current git diff --focus <area>
guard config llm Launch interactive LLM configuration wizard (an API, or your own claude / codex / omp CLI) --local
guard agent add / list / test / fix / remove Put guard on an agent's own hooks (Claude Code, Codex, Cursor, Grok Build, Gemini CLI, Antigravity, ZCode, omp, pi, opencode, or any other agent guard can set up) test --report, fix --note
guard config test Send instant token-free ping test to configured LLM —
guard config sync Write the LLM settings into Alibaba OCR (custom provider guard) —
guard config commit Choose who writes commit messages: the agent (auto) or you (ask) auto | ask
guard config review Show the effective review options and where each comes from, or set one (interactive terminal only); the extra review stages are opt-in <option> <value>
guard hook refresh Refresh what guard installed earlier to the current version —
guard update Safely upgrade Alibaba OCR respecting 3-day quarantine --check, --force, self
guard doctor Check system environment health and supply-chain security --no-updates, -q <days> (also shows the setup check)

8. Supply-Chain Security & Quarantine Policy

To protect development environments against zero-day npm supply-chain backdoors, Guard enforces a 3-Day Quarantine Cooling Period on Alibaba OCR releases:

# Check update status safely without installing:
guard update --check

# Safely upgrade (automatically halts if release is under quarantine):
guard update

# Bypass quarantine hold explicitly if verified:
guard update --force