Introduction
matcha is an engineering philosophy for AI coding agents. It makes agents think before they code — checking purpose, reusing existing code, auditing the stack, and reviewing before shipping.
How It Works
matcha operates at 4 layers:
| Layer | What It Does | When It Runs |
|---|---|---|
| Planning Gate | Blocks code until Intent Discovery plan exists | Before any implementation |
| Safety Shield | Blocks dangerous commands (rm -rf, git push --force) | On every command |
| Post-Write Scan | Checks files for cleanup issues (13+ languages) | After every file write |
| Review Gate | 9-category review with risk-based routing | Before shipping |
Who Is It For?
Solo Developers
Use AI agents but want guardrails to prevent bad code from shipping.
Teams
Enforce consistent engineering standards across all AI-assisted code.
Security-Conscious
Automated security checks before code reaches production.
Legacy Codebases
Incremental refactoring with safety protocols for large projects.
Key Features
Purpose-First Thinking
Intent Discovery (problem, goals, success criteria, What → Why → How) forces agents to understand WHY before writing code. No more blind implementation.
Deterministic Enforcement
Hook-based safety checks run in Node.js, not LLM. Zero dependency on AI for critical checks.
Risk-Based Review
4-tier review routing (L0-L3). Quick tasks skip, critical code gets expert-level scrutiny.
Universal Compatibility
Works with Claude, Cursor, Copilot, OpenCode, Windsurf, Kiro, and any MCP client.
Adaptive Modes
Auto-detects what the agent is doing. Explore, implement, refactor, debug — zero friction.
13+ Languages
Pattern registry for JS, TS, Go, Python, Rust, Java, C#, C/C++, Ruby, Swift, PHP, Kotlin, Dart.
What's Inside
| Component | Count | Description |
|---|---|---|
| Modules | 6 | Core, project, modes, risk, engineering, legacy |
| Commands | 7 | why, review, audit, intensity, status, debt, markers |
| Agents | 6 | planner, finder, auditor, reviewer, cleaner, debugger |
| Hooks | 4 | shield, post-write, stop, metrics |
| MCP Tools | 4 | shield_check, post_write_scan, stop_tips, plan_validate |
| Languages | 13+ | JS, TS, Go, Python, Rust, Java, C#, C/C++, Ruby, Swift, PHP, Kotlin, Dart |
| Trigger Packs | 6 | web-saas, ml-pipeline, infra-iac, mobile, embedded, cli-tool |
Example: Before vs After matcha
| Without matcha | With matcha |
|---|---|
| Agent writes code immediately | Agent plans first (Intent Discovery) |
| Duplicates existing functions | Searches codebase, reuses existing |
| Ships without review | 9-category review gate |
| No security checks | Automated security scanning |
| Same process for all tasks | Adaptive modes (explore/implement/debug) |
| Breaks legacy code | Incremental batching with safety |
Quick Start
Up and running in 2 minutes.
Install matcha
One command. Works on macOS, Linux, and WSL.
npx @plumpslabs/matcha@latest initOr install globally:
npm install -g @plumpslabs/matcha && matcha initOr without npm (curl script):
curl -fsSL https://raw.githubusercontent.com/plumpslabs/matcha/main/install.sh | bashConfigure your provider
Matcha auto-detects your platform (Claude Code, OpenCode, Cursor, Windsurf, Kiro, and more) and installs the right files. No manual configuration needed.
Add project constraints (optional)
Copy the template and fill in your project-specific rules:
cp .agents/skills/matcha/modules/project.md ./MATCHA_PROJECT.md
# Edit with your framework, package manager, coding standardsVerify installation
Check that the rules files are installed:
ls AGENTS.md GEMINI.md hooks/matcha-shield.js
# All three must exist — matcha is now active for every agent.hooks/ and wired into .claude/settings.json for Claude Code.Installation
Multiple ways to install matcha depending on your setup.
Option A: npx — one command, nothing installed globally
npx @plumpslabs/matcha@latest initnpx downloads matcha temporarily, runs init into the current project, then discards it. No global install, no cleanup. Re-run any time to update.
During init, matcha asks which providers to configure (1 Claude · 2 OpenCode · 3 Cursor · 4 Windsurf · 5 Kiro · 6 Universal). Existing providers are auto-detected. For scripting: matcha init --platforms .opencode,.claude
Option B: Global install — matcha command works everywhere
npm install -g @plumpslabs/matcha
matcha init # install matcha rules into the current project
matcha status # verify + show platform detectionThe matcha CLI is available in every project. Run matcha init in each project you want to enable.
Option C: Project-local dev dependency — pinned per repo
npm install --save-dev @plumpslabs/matcha
npx matcha initScoped to one project via package.json. Best for teams — the matcha version is locked with the code.
Option D: One-liner — no npm required
curl -fsSL https://raw.githubusercontent.com/plumpslabs/matcha/main/install.sh | bashPure shell script, works on macOS / Linux / WSL. Installs the rules files only (no CLI).
Which one should I use?
| Situation | Command | Why |
|---|---|---|
| Most users — try it out | npx @plumpslabs/matcha@latest init | One command, zero cleanup |
| Use matcha in many projects | npm install -g @plumpslabs/matcha | matcha CLI available everywhere |
| Team repo, pinned version | npm install --save-dev @plumpslabs/matcha | Version locked in package.json |
| No Node.js / no npm | curl one-liner | Pure shell, no dependencies |
What Gets Installed
| Target | Contents | For |
|---|---|---|
AGENTS.md + CLAUDE.md + GEMINI.md + QWEN.md | Root context files (per-runtime: Claude Code, Antigravity/Gemini, Qwen Code, + universal AGENTS.md) | Every agent (Claude, Antigravity, Qwen, Gemini, Codex, Zed, ...) |
.github/copilot-instructions.md | Custom instructions | GitHub Copilot |
.claude/ | 6 agents, 7 commands, skill + modules, hooks + settings.json | Claude Code |
.opencode/ | 6 agents, 7 commands, skill + modules | OpenCode |
.cursor/rules/ | matcha.mdc rule | Cursor |
.windsurf/ | matcha.md rule + .windsurfrules | Windsurf |
.clinerules/ | matcha.md rule | Cline |
.roo/rules/ | matcha.md rule | Roo Code |
.kiro/ | 3 steering files, skill + modules | Kiro Code |
.qoder/rules/ | matcha.md rule | Qoder |
.trae/rules/ | matcha.md rule | Trae IDE |
.agents/ | 6 agents, 7 commands, skill + modules + rules/ | Universal / Antigravity (AGY) |
agents/ + rules/ + mcp_config.json | AGY plugin package structure (per official plugin layout) | Antigravity — agy plugin install |
hooks/ | Planning-gate, shield, post-write, stop, metrics, agy-hooks, instructions, MCP server | Every agent (server-side safety) |
Claude Code Setup
matcha works natively with Claude Code via plugin marketplace or manual setup.
Method 1: Plugin Marketplace
# Inside Claude Code
/install matchaMethod 2: npm install
Install matcha
npx @plumpslabs/matcha@latest initMethod 3: Curl script
Run install script
curl -fsSL https://raw.githubusercontent.com/plumpslabs/matcha/main/install.sh | bashHooks are auto-configured
The install script creates .claude/settings.json with hooks (merged, not overwritten).
Verify
ls AGENTS.md .claude/skills/matcha/SKILL.md
# Should show both files — Claude Code is configured ✅MCP Configuration (Optional)
Add matcha MCP tools for additional enforcement:
{
"mcpServers": {
"matcha": {
"command": "node",
"args": ["hooks/matcha-mcp-server.js"]
}
}
}Place in .mcp.json (per-project) or ~/.claude.json (global).
OpenCode Setup
matcha auto-detects OpenCode and configures agents + skills.
Install matcha
npx @plumpslabs/matcha@latest initAuto-detected
OpenCode reads .opencode/agents/*.md and .opencode/skills/matcha/SKILL.md automatically.
MCP Configuration
OpenCode's mcp schema requires command to be an array (executable + args together).
Per-project
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"matcha": {
"type": "local",
"command": ["node", "hooks/matcha-mcp-server.js"],
"enabled": true
}
}
}Place in opencode.json / opencode.jsonc in the project root.
Global (all projects) — no absolute path needed
npm install -g @plumpslabs/matcha
# Then in ~/.config/opencode/opencode.json:
{
"mcp": {
"matcha": {
"type": "local",
"command": ["matcha", "mcp"],
"enabled": true
}
}
}matcha mcp resolves via your global PATH — works from any project, nothing to update when you switch directories. (Fallback: absolute path ["node", "/path/to/matcha/hooks/matcha-mcp-server.js"] if the CLI isn't installed globally.)
"command": "node", "args": [...] — OpenCode rejects this with Expected "array". Property args is not allowed. Put everything inside command.Cursor Setup
matcha works with Cursor via AGENTS.md (native) and optional MCP.
Install matcha
npx @plumpslabs/matcha@latest initAGENTS.md auto-detected
Cursor reads AGENTS.md in project root automatically.
MCP Configuration (Optional)
{
"mcpServers": {
"matcha": {
"command": "node",
"args": ["hooks/matcha-mcp-server.js"]
}
}
}Place in .cursor/mcp.json (per-project) or ~/.cursor/mcp.json (global).
Windsurf Setup
matcha works with Windsurf via .windsurfrules.
Install matcha
npx @plumpslabs/matcha@latest init.windsurfrules auto-generated
Windsurf reads .windsurfrules in project root automatically.
MCP Configuration
{
"mcpServers": {
"matcha": {
"command": "node",
"args": ["hooks/matcha-mcp-server.js"]
}
}
}Place in ~/.codeium/windsurf/mcp_config.json (global only).
agy (Antigravity) Setup
matcha works with agy (Antigravity CLI) via plugin install.
Method 1: Plugin Install
agy plugin install https://github.com/plumpslabs/matchaMethod 2: npm install
Install matcha
npx @plumpslabs/matcha@latest initMethod 3: Curl script
Run install script
curl -fsSL https://raw.githubusercontent.com/plumpslabs/matcha/main/install.sh | bashAuto-detected
agy reads GEMINI.md and .agents/ automatically.
What Gets Installed
The repo ships an AGY-compatible plugin manifest (plugin.json) plus root agents/ and mcp_config.json so agy plugin install picks up everything:
skills/— 1 skill (matcha) → usable via/matchacommands/— 7 commands → converted to skills (matcha:review,matcha:why, ...)agents/— 6 agents: 4 selectable in the/agentspanel (planner, finder, auditor, reviewer) + 2 subagent-only (debugger, cleaner)mcp_config.json— matcha MCP server auto-registeredGEMINI.md+AGENTS.md— rules files (read automatically)
Using matcha agents
AGY discovers the 6 matcha agents from .agents/agents/ (project) and the plugin's agents/ dir. Verify with:
agy agent # list discovered agents (4 primary shown)
agy --agent matcha-planner "plan feature X" # one-shot, no TUI| Action | How |
|---|---|
| Pick an agent inside the TUI | Type /agents → arrow to the agent → Enter → Esc |
| Start a session with an agent | agy --agent <name> <prompt> (per-session only — AGY has no persistent default-agent setting) |
| List agents | agy agent |
Shift+Tab only cycles built-in execution modes (plan, auto-edit). Custom agents are selected via the /agents panel or --agent flag — this is normal AGY behavior, not a bug. debugger and cleaner are subagent-only (mainAgent: false) so they don't appear in agy agent; they run via invoke_subagent from a main agent./matcha slash command is the core skill; command skills are invoked via matcha:review-style names. Hooks use Claude Code's format, so they are not registered by AGY's plugin scanner.Kiro Setup
matcha works with Kiro via steering files in .kiro/steering/.
Install matcha
npx @plumpslabs/matcha@latest initSteering files created
.kiro/steering/matcha.md, dev-mode.md, review-mode.md
MCP Server Setup
matcha exposes 4 tools via MCP (Model Context Protocol) for any compatible client.
Available Tools
| Tool | Description |
|---|---|
matcha_shield_check | Check a command for dangerous patterns |
matcha_post_write_scan | Scan a file for cleanup issues (13+ languages) |
matcha_stop_tips | Get end-of-task suggestions from git diff |
matcha_plan_validate | Validate an Intent Discovery plan |
What Is This For?
MCP (Model Context Protocol) lets any AI agent call matcha's checks as tools — deterministic enforcement that doesn't depend on the agent reading rules. It's optional: the rules files (AGENTS.md, skills, commands) work without it. MCP adds a second, programmatic layer for agents that support tool calls (Claude, Cursor, Windsurf, AGY, OpenCode, ...).
Start the Server
Locally (project hooks dir):
node hooks/matcha-mcp-server.js
# Runs via stdio JSON-RPCOr via the globally installed CLI (works from any project):
npm install -g @plumpslabs/matcha
matcha mcpClient Configuration
Each client has a different config format:
| Client | Config file | Format |
|---|---|---|
| Claude Code | .mcp.json (project) / ~/.claude.json (global) | "mcpServers": { "matcha": { "command": "matcha", "args": ["mcp"] } } |
| OpenCode | opencode.json (project) / ~/.config/opencode/opencode.json (global) | "mcp": { "matcha": { "type": "local", "command": ["matcha", "mcp"], "enabled": true } } |
| Cursor | .cursor/mcp.json (project) / ~/.cursor/mcp.json (global) | "mcpServers": { "matcha": { "command": "matcha", "args": ["mcp"] } } |
| Windsurf | ~/.codeium/windsurf/mcp_config.json (global only) | "mcpServers": { "matcha": { "command": "matcha", "args": ["mcp"] } } |
| AGY / Antigravity | mcp_config.json (auto via plugin) or ~/.gemini/config/mcp_config.json | "mcpServers": { "matcha": { "command": "matcha", "args": ["mcp"] } } |
| Cline / Roo | ~/.cline/mcp.json / .roo/mcp.json | "mcpServers": { "matcha": { "command": "matcha", "args": ["mcp"] } } |
Global config tip: use "command": "matcha", "args": ["mcp"] (global CLI) — no absolute path, works after switching projects. Absolute path to hooks/matcha-mcp-server.js is only needed if the CLI isn't installed globally.
.mcp.json) — safer, easier to remove, can be committed to repo. Use the global CLI form if you want it everywhere.Philosophy
Simple. Efficient. Deliberate. Never twice.
The 6-Checkpoint Filter
Every implementation passes through 6 checkpoints:
| # | Checkpoint | Purpose |
|---|---|---|
| 1 | Purpose + Reuse | Intent Discovery + search for existing code |
| 2 | Stack Audit | Check for service overlap |
| 3 | Implementation | Write code with principles |
| 4 | Cleanup | Remove temp files, debug code |
| 5 | Verify | Run tests, typecheck, lint |
| 6 | Review Gate | Risk-based review (L0-L3) |
Core Principles
- No hardcoded values — use env vars:
APPNAME_VAR_NAME - One function = one responsibility — pure functions first
- Prefer stdlib — 3 use cases minimum before abstracting
- Fail fast — validate inputs at boundaries
- Idempotent — operations safe to retry
- No empty catches — explicit error paths
Context-Aware Modes
matcha auto-detects what the agent is doing and adjusts behavior.
| Mode | Trigger | Planning Gate | Review Gate |
|---|---|---|---|
| Explore | Reading, greping | Skip | Skip |
| Implement | Writing new code | Enforce | Enforce |
| Refactor | Changing existing code | Enforce + legacy | Enforce |
| Debug | Error, investigating | Skip | Skip |
| Review | Finished implementing | Skip | Is the review |
Modes are detected automatically from tool input. No manual switching needed.
Risk-Based Review
Not all code needs the same review. Route by risk.
Risk Tiers
| Tier | Risk | Review Level |
|---|---|---|
| L0 | Disposable | Output check only |
| L1 | Low | Lint + typecheck |
| L2 | Product Logic | Full 9-category review |
| L3 | High Risk | Expert review + threat model |
Trigger Packs
matcha does NOT hardcode what "high risk" means. Detection uses domain-specific trigger packs:
web-saas
Auth, payments, secrets, DB schema
ml-pipeline
Data leakage, PII, model deploy
infra-iac
Destructive applies, IAM, prod paths
mobile
Keychain, permissions, IAP
embedded
Memory, interrupts, watchdog
cli-tool
rm -rf, sudo, eval
See hooks/matcha-trigger-packs.json for all packs and custom template.
L2 Full Review Categories
| Severity | Category | Checks |
|---|---|---|
| 🔴 Must Fix | Correctness | Logic, edge cases, race conditions, dead code |
| 🔴 Must Fix | Performance | O(n²+), N+1, unbatched I/O, unbounded operations, re-render loops, memory leaks |
| 🔴 Must Fix | Security | Injection, secrets, authN/authZ + IDOR, fail-closed |
| 🟡 Should Fix | Architecture | God objects, circular deps, over-engineering |
| 🟡 Should Fix | Errors, Logging & Validation | Empty catches, generic messages, secrets/PII in logs, missing boundary validation |
| 🟡 Should Fix | Resilience & Data | Timeouts, retry + backoff, circuit breaker, transactions, migrations with rollback |
| 🟡 Should Fix | Quality | Duplication, magic numbers, deep nesting |
| 🟢 Nice to Have | Testing | Coverage, edge cases |
| 🟢 Nice to Have | Maintainability | WHY comments, env vars |
Planning Gate
Blocks code modifications until an Intent Discovery plan exists.
Smart Auto-Skip
Planning gate is automatically skipped for:
- Read-only commands (
git status,grep,ls) - Test commands (
npm test,vitest) - Lint/format commands (
eslint,prettier) - Documentation files (
.md,.txt) - Test files (
.test.js,.spec.ts)
Plan Format
<matcha_gate>
<what>Describe what you are building/fixing — with file refs</what>
<why>Why is this necessary? — with evidence</why>
<how>Simplest implementation path — numbered steps</how>
</matcha_gate>Validation Rules
<what>must reference specific files<why>must include evidence (metrics, errors)<how>must list 2+ concrete steps- Each section must be 15+ characters
Proportionality & Trivial Fast-Pass
Match ceremony to risk. The gates exist to protect — not to slow you down. Over-analysis is not rigor; it is waste.
| Task Size | Definition | Gate Required |
|---|---|---|
| Trivial | ≤5 LOC, 1 file, no logic change (typo, rename, copy, config value, docs) | Fast-pass — no full gate |
| Small | 1–3 files, contained change | Short plan + lint review |
| Large | Cross-cutting / production risk (auth, payments, DB, schema) | Full gate + risk-based review |
Trivial Plan Marker
For trivial tasks, write a minimal plan carrying the <!-- trivial --> marker (or type: plan-trivial in frontmatter) plus a **Problem:** line — the hook accepts it without the full What/Why/How gate. Without the marker, the hook still requires Problem + Goals + Success Criteria.
<!-- trivial -->
# 🍵 Intent Discovery
- **Problem:** Rename `foo` to `bar` in src/x.jsWhat Skips the Gate Automatically (Smart Auto-Skip)
- Commands: read-only (
git status,grep,ls), tests (npm test,vitest), lint/format (eslint,prettier), package managers - Files: docs (
.md), tests (.test.js), config & low-risk data (.yaml,.jsonc,.css,.html,.env*,.lock,tsconfig,Dockerfile), matcha session files (current.md) - Never skipped: dependency manifests (
package.json,pyproject.toml,Cargo.toml,go.mod,Gemfile), component source (.vue,.svelte), production code — these change logic or the dependency tree
Exit Conditions Beat STOP
Before stopping to ask the user, ask: is this actually blocking, or can I proceed on a recorded assumption? Prefer proceeding with a visible assumption over blocking on trivia. Record assumptions in the plan's Assumptions field so they survive context compaction.
Project Constraints
matcha supports project-specific rules that agents must follow.
Setup
cp .agents/skills/matcha/modules/project.md ./MATCHA_PROJECT.mdTemplate Sections
- Stack: Framework, language, package manager
- Conventions: Naming, imports, error handling
- Architecture: Layers, patterns, anti-patterns
- Testing: Framework, coverage requirements
- Security: Auth, secrets, validation rules
MATCHA_PROJECT.md from project root when present.Session Memory
Filesystem is durable memory; the context window is volatile. matcha persists gate artifacts so a compacted or fresh session resumes in under 500 tokens.
| File | Write | Read |
|---|---|---|
.agents/plan/current.md | Planning gate → overwrite (living plan) | Start of every task |
.agents/reports/<agent>-<YYYY-MM>.md | Review / Audit output → append | Resuming or auditing history |
.agents/plan/decisions.log | matcha decision <type> <reason> | matcha markers / /matcha:debt |
Rules
- Lazy-load only — never auto-inject memory files into context; read on demand. Zero token bloat.
- Living over archive —
current.mdoverwrites, never appends. Reports append monthly; keep latest 5 per agent, delete older. - Format — YAML frontmatter (
title,date,type,agent,status,tags): grep-able, git-friendly, industry standard (same as ADRs & memory banks). - Enforced permissions — planner/finder/reviewer/auditor are provider-enforced read-only (edit denied for all source code; writable paths only:
.agents/plan/current.mdfor planner + reviewer,.agents/reports/**for planner/reviewer/auditor). Bash permissions: planner/finder get a lean read-only allowlist (git history,rg/findsearch,wc -l,head/tail) and block everything else (*: deny) — file contents are read via thereadtool, not bashcat/sed. Auditor gets a read-only allowlist (git history, package managers, test runners, filters) with*: denyfallback — build commands are not allowlisted (they writedist/; blocked so subagents never stall on approval prompts — the orchestrating agent runs builds). Reviewer keeps full bash because its L0/L1 gates must run builds and tests. Web fetching stays denied for all (opencodewebfetchis scalar-only); advisory lookups go through the orchestrating agent. debugger/cleaner may modify code. - Gate artifacts only — persist plan/review/audit (they gate shipping). Skip finder/cleaner/debugger — cheaper to re-run than to archive.
Lifecycle (anti-stale)
current.md always holds exactly one active task:
- Start — read it. Intent matches the current request? Continue and update in place. Mismatch → overwrite (never follow a stale plan).
- During (step-by-step) — implement strictly in order from the Plan list: after each completed step check it off (
[x]) and update the**▶ Current:**line (Step N/M, K done). Overwrite / check-off in place, never append. The plan always reflects the real position — a compacted or fresh session resumes exactly where you left off. Deviation → update the plan first. - Done (task ships = review PASS) — the reviewer finalizes the handoff: append plan content to
reports/planner-<YYYY-MM>.md, write the verdict toreports/reviewer-<YYYY-MM>.md, then resetcurrent.mdto the empty template (status: active, TBD). Only a PASS resets — BLOCK / PASS_WITH_FIXES keeps the plan for fix iteration.
Portable across providers — .agents/plan/ + .agents/reports/ are plain files in the project, readable by any provider (OpenCode, AGY, Claude, Cursor, …). Switch provider mid-task? The new session injects AGENTS.md → reads current.md → resumes. The filesystem is the memory; the provider is just the host.
Workflow Guide (The 4-Phase Lifecycle)
How to actually use matcha day-to-day: which agent or command to call, when, and in what order — from a blank task to a reviewed, shippable change.
End-to-End Flow Diagram
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Phase 1: PLAN │ → │ Phase 2: SEARCH │ → │ Phase 3: CODE │ → │ Phase 4: SHIP │
│ @matcha-planner│ │ @matcha-finder │ │ Main agent │ │ /matcha:review │
│ (/matcha:why) │ │ (Reuse Check) │ │ (verify + debug)│ │ @matcha-cleaner │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
Implementasi dilakukan oleh main agent (bukan sub-agent) — mengikuti plan di .agents/plan/current.md step-by-step. @matcha-debugger hanya dipanggil jika terjadi error, dan @matcha-finder bisa dipanggil ulang saat menemukan kode yang bisa di-reuse.
Phase 1: Plan & Intent
/matcha:why or @matcha-planner. In enforce mode the planning gate runs automatically — the agent must state What / Why / How with empirical evidence before touching any file. No blind implementation.
Phase 2: Search & Reuse
@matcha-finder: "Check if there's existing code for X." Search codebase for exact or partial matches (`file:line`). Mandate reuse over rewrite — never duplicate what already exists.
Phase 3: Implement & Verify
Implement directly according to the plan in .agents/plan/current.md — check off steps ([x]) and update the **▶ Current:** line as you go. Follow the Engineering Directives (Type-Safe, Boundary Guard, Pure Core, Security, Resource & Memory Awareness). Verify runs automatically after each change (tests + typecheck + lint). If an error occurs, invoke @matcha-debugger for systematic 1-hypothesis-at-a-time investigation with log evidence — debugger is for failures, not the default implementer.
Phase 4: Review & Ship (Blocking Gate)
/matcha:review & @matcha-cleaner. Run full risk-based review (L0-L3). Nothing ships without PASS. Run @matcha-cleaner to remove debug logs and mark intentional shortcuts with // matcha: [reason] — deliberate-choice comments (skip/workaround/intentional hardcode) get the marker at write time, not as a separate cleanup pass.
Verify (automatic)
Tests + typecheck + lint run automatically (framework auto-detected). Red tests → stop and fix, never continue.
Review gate — before "done"
/matcha:review or @matcha-reviewer. Risk-based routing: L0 output check → L1 lint/typecheck → L2 full review (9 categories) → L3 expert + threat model. Verdict: BLOCK / PASS_WITH_FIXES / PASS / EXPERT_REQUIRED. If blocked, use @matcha-debugger to find the root cause.
Cleanup & debt
@matcha-cleaner removes temp/debug/unused code. /matcha:debt and /matcha:markers surface decision markers (// matcha: ...) and open items.
Report
/matcha:status shows the session dashboard: components, intensity, changes, test results.
When to Call What
| Phase | Automatic? | Command | Agent | Example |
|---|---|---|---|---|
| Setup | No | /matcha:intensity | — | Set enforce / observe / audit |
| Plan | Gate auto-runs | /matcha:why | @matcha-planner | "Plan this feature with Intent Discovery" |
| Reuse | No | — | @matcha-finder | "Is there existing code for X?" |
| Audit | Optional | /matcha:audit | @matcha-auditor | Health check before legacy refactor |
| Implement | Rules enforced | — | — | "matcha pause" if a better path appears |
| Verify | Yes | — | — | Tests + typecheck + lint |
| Review | No — must run | /matcha:review | @matcha-reviewer | Gate before "done" |
| Debug (if blocked) | No | — | @matcha-debugger | "Find the root cause of the N+1 query" |
| Cleanup | No | /matcha:debt /matcha:markers | @matcha-cleaner | Remove temp/debug/unused |
| Report | No | /matcha:status | — | Session dashboard |
Mode by Situation
| Mode | When | Behavior |
|---|---|---|
| observe | Exploring, prototyping, learning a new codebase | Tips only — no blocking |
| enforce | Normal implementation work (default) | Planning gate + shield active |
| audit | Critical paths: auth, payments, DB, legacy refactors, pre-release | Enforce + mandatory cleanup |
enforce. Drop to observe when exploring. Raise to audit when the stakes are high. Always end with /matcha:review.Commands Reference
7 slash commands for matcha workflows.
| Command | Purpose | Usage |
|---|---|---|
/matcha:why | Intent Discovery check | Before any implementation |
/matcha:review | Risk-based review gate | After implementation |
/matcha:audit | Stack audit | Check for overlaps |
/matcha:intensity | Set enforcement level | /matcha observe|enforce|audit |
/matcha:status | Session dashboard | Check current state |
/matcha:debt | Technical debt report | Find // matcha: markers |
/matcha:markers | Marker scan | Group by severity |
Note: /matcha:status now surfaces session metrics (planning-gate blocks, shield blocks, reviews run, issues caught, FP rate) when .agents/matcha-metrics.json exists — so matcha can measure its own overhead.
CLI Reference
Run matcha <command> after installing via npm (or node bin/matcha.js <command> from the repo). All commands resolve state at the workspace root (monorepo-aware).
| Command | Purpose |
|---|---|
matcha init | Interactive provider picker → runs install.sh for the selected platforms |
matcha status | Installation health: detected platforms, AGENTS.md, shield, intensity + metrics snapshot |
matcha metrics | Impact & overhead telemetry: tasks, reviews, issues caught, FP rate, planning/shield blocks (from .agents/matcha-metrics.json) |
matcha markers | Scan // matcha: decision markers grouped by severity |
matcha verify | Check installed rule copies across providers (anti-stale) |
matcha state | Inspect session state (intensity, plan, metrics paths) |
matcha decision | Log a technical decision to .agents/plan/decisions.log |
matcha mcp | Launch the matcha MCP server (stdio) |
matcha -v / --version | Print version only |
matcha help | Show usage |
Agents Reference
6 specialized agents for matcha workflows.
Read-only agents (planner/finder/reviewer/auditor) have provider-enforced edit: deny (OpenCode) / disallowedTools: Write, Edit (Claude Code) — they can never modify source code. Only plan/report paths are writable. debugger/cleaner may modify code.
| Agent | Read Tools | Edit (write) Access | Bash | Purpose |
|---|---|---|---|---|
@matcha-planner | Read, Grep, Glob, List | .agents/plan/current.md + .agents/reports/** only | Denied | Engineering planning: Intent Discovery → context → reuse → decision → roadmap |
@matcha-finder | Read, Grep, Glob, List | Denied | Denied | Hunt existing code before writing new |
@matcha-auditor | Read, Grep, Glob, List | .agents/reports/** only | Allowed | Stack audit for overlaps and risks |
@matcha-reviewer | Read, Grep, Glob, List | .agents/reports/** only | Allowed | Code review with risk-based routing (runs lint/tests) |
@matcha-cleaner | Read, Grep, Glob, List | Allowed (after confirmation) | Allowed | Remove temp/debug/unused code |
@matcha-debugger | Read, Grep, Glob, List | Allowed (minimal fix) | Allowed | Systematic debugging workflow |
Provider note: enforced in OpenCode (permission:) and Claude Code (disallowedTools:). Other providers (agy, Cursor, Windsurf) read the same agents as prompts — enforcement there is prompt-level + safety hooks.
Hooks Reference
4 lifecycle hooks for deterministic enforcement.
| Hook | Event | Purpose |
|---|---|---|
matcha-shield.js | PreToolUse | Blocks dangerous commands + mode detection |
matcha-post-write.js | PostToolUse | Scans files for cleanup issues (13+ languages) |
matcha-stop.js | Stop | End-of-task suggestions from git diff |
matcha-metrics.js | Shared | Session metrics tracking |
Override
MATCHA_SHIELD_OFF=true # Disable all shield checksModules Reference
6 focused modules loaded on-demand.
| Module | When to Load | Content |
|---|---|---|
core.md | Always | 6-checkpoint filter, intensity, planning gate |
project.md | Always | Project-specific constraints (MATCHA_PROJECT.md template) |
modes.md | Always | Context-aware mode switching |
risk.md | During review | Risk-based review routing (L0-L3) |
engineering.md | Implement + review | Universal engineering bar: errors, logging, validation, API contracts, state, concurrency |
legacy.md | Legacy codebases | Incremental batching, impact analysis |
Benchmark & Evidence
Matcha ships its own benchmark tooling (benchmark/) and publishes results — so the claim "rules improve output without bloating it" is measured, not asserted.
Where it earns its cost: multi-file refactors, cross-layer bug hunting, security/auth/production-critical changes, and teams that need standards enforced rather than suggested.
Where it's overkill: trivial single-file edits (typo, rename, one-line feature) — Proportionality routes those through the ≤30-line fast path; drop to
/matcha:intensity observe (tips only, no blocking) while exploring or prototyping.
Complex-Task Benchmarks (v3) — where a thinking-first agent earns its cost
First run (free model, n=1–2/cell, 2026-08-08): the arena matcha was built for — and the arms split hard.
| Task | ❌ No rules | 💬 Terse | 🍵 Matcha |
|---|---|---|---|
refactor-users-service — completed | 0/2 ❌ (+3 LOC, refactor not done) | 0/2 ❌ (+3 LOC, refactor not done) | ✅ 1/1 (+15 LOC, service layer extracted, tests green) |
refactor-users-service — defect density | n/a (no-op) | n/a (no-op) | 6.7 (1 finding / 15 LOC) |
fix-auth-security — passed | ✅ 1/1 (+8 LOC) | ✅ 2/2 (+4 LOC) | ✅ 1/1 (+16 LOC, density 0) |
Honest reading: without rules the agent fails the multi-file refactor — it adds a few lines and stops; matcha is the only arm that extracts the service layer without breaking behavior. The table shows completed cells: matcha's second refactor cell and several security cells hit the free-model queue timeout (the same security task passed at 240s in an isolated dry-run), so its 1/1 is not cherry-picking. On the small security bug every arm that finished fixed it — no measurable edge for matcha there. Defect density only counts completed work: a 3-line no-op has no density to measure.
Quality metric: defect density — anti-pattern findings (empty catches, magic numbers, hardcoded secrets) per 100 LOC added by the agent, scanned via hooks/patterns.json. This is the value side of the ledger: baseline writes few, sloppy lines; matcha writes more, cleaner lines. Re-run: node benchmark/live-bench.js --task refactor-users-service --arm matcha --n 5 --timeout 480.
Small-Task Benchmarks (18 runs) — the cost of thinking first
Real feature implementation on the express-api fixture (3 features × 3 arms × 2 iterations). This is matcha's worst case: trivial single-file tasks. Process cost (tokens, steps, wall time) is measured from real provider events, not estimated. Lower is better for every chart except Correctness.
Median per arm · data as of 2026-08-07 (re-run: node benchmark/live-bench.js --all --n 5, then update docs/benchmark.json + this chart) · details in docs/BENCHMARK.md. Cost is the invoice for the quality shown above — not a defect.
| Metric (median) | ❌ No rules | 💬 Terse | 🍵 Matcha | Verdict |
|---|---|---|---|---|
| Correctness (fail→pass) | 1.0 | 1.0 | 1.0 | Tie — rules don't hurt or help on small tasks |
| ExpectedPass (target suite) | 5/6 | 5/6 | 5/6 | Tie — sharper metric, still no correctness edge |
| LOC added | 13.5 | 6.5 | 17 | Matcha writes more — structure over brevity (anti-overbuild fix cut +136% → +26%) |
| Tokens (real) | 395K | 347K | 643K | Matcha +63% — the price of planning + verification (see below; variance high — BENCHMARK.md) |
| Wall time | 58s | 34s | 78s | Matcha +34% — same invoice on trivial tasks (was +70% pre-fix) |
| Compliance (changed files) | 100 | 100 | 100 | Tie — all arms clean |
Why matcha costs more — the mechanism: the extra tokens and time are mostly process steps, not code bloat. Matcha adds ~4 LLM turns per task (steps 8.5 → 12.5), which typically go to the planning gate (write a plan with evidence before touching files), verification (run the test suite), and the review pass. Each extra turn re-reads context — that's the ~49K cacheRead/step we measured. On small tasks those turns buy nothing visible — hence "overkill by design". On complex tasks they are exactly what turns a 0/2 failure into a completed, verified refactor.
Honest takeaway: cost (tokens/time) is context, not the verdict. Matcha spends more because it thinks before it implements — that buys precision, structure, and prevention. The quality side is why the cost is worth paying: defect density (anti-pattern findings per 100 LOC added, scanned on agent-written files only), correctness, and safe complex refactors. On small/trivial tasks matcha is overkill by design — Proportionality routes them through the ≤30-line fast path and the trivial plan; use /matcha:intensity observe for trivia.
So is matcha "slow and expensive"? Read the cost table as an invoice for verification, not a waste report: the same kind of process turns — planning and verification — that cost +63% on trivial tasks are the ones that completed a refactor every other arm abandoned. And the premium is capped by design — trivial edits skip the gate entirely (≤30-line fast path) and observe mode removes it altogether. You only pay the premium where you choose to — and it buys what no-rules arms never produce: a completed, verified result on the work that actually matters.
Assumption (estimated, not measured): one redo — detect the bug, reopen the session, re-understand the code, re-implement, re-test — costs ≈1.5× the original run, mostly because re-understanding re-reads the codebase all over again (the same standing-context cost we measured at ~49K/step). On the small-task numbers that's ≈590K tokens per redo — larger than matcha's entire +248K premium. One redo and no-matcha has already spent more tokens than matcha's whole run (≈985K vs 643K) — plus the developer hours in between, which tokens don't capture. Two redos, and it ships with debt on top. Matcha's premium is paid once, up front; the no-matcha cost is paid later, repeatedly, with interest.
Real Multi-Turn Feature Benchmark (agy, 3 features)
| Feature | LOC | Tests | Passed | Compliance |
|---|---|---|---|---|
| Activity Tracking | 111 | 12 | ✅ 12 | A |
| Pagination | 67 | 10 | ✅ 10 | A |
| Rate Limiting | 75 | 8 | ✅ 8 | A |
| Total | 270 | 30 | ✅ 30/30 | Excellent |
Matcha-driven feature builds on agy (Gemini 3.5 Flash): 3 real features, all tests green, top compliance grade. The same-prompt with/without comparison lives in docs/BENCHMARK.md — matcha produced named status codes, explicit errors, and a per-user data structure at ~16% more LOC.
Legacy / internal runs. Agentic A/B (Claude Code, 20 tasks × 3 arms): all arms tied at 13/20 correct — matcha wrote 260 LOC vs 347 no-rules via reuse/no-duplication, but this benchmark doesn't differentiate. Standing-context A/B (20 cells, core-only vs full): −6.3% tokens median, within run-to-run noise — the slim is correct-by-architecture (~1.5K tok/step) but standing context is dominated by AGENTS.md + hooks + system prompt, not skill modules. Full write-ups in docs/BENCHMARK.md.
Which feature to use when
| Feature | Use it when… |
|---|---|
@matcha-planner / plan gate | Starting any non-trivial feature — Intent Discovery (What → Why → How) before any code |
@matcha-finder | Before writing new code — hunt existing helpers first; never duplicate what exists |
@matcha-auditor / /matcha:audit | Stack overlap, dependency risk, security & PII exposure — read-only, report-only |
@matcha-reviewer / /matcha:review | Before commit — L0–L3 risk-tiered review, catches what the agent missed |
/matcha:intensity | Scale enforcement per task: enforce (default) / observe (exploring) / audit (high stakes) |
Rough rule: bigger than a one-file edit, or production-critical → matcha earns its keep. Everything else → fast path + observe keeps it out of the way.
Run It Yourself
Every published number is re-runnable — the harness ships in benchmark/:
node benchmark/live-bench.js --all --n 5 # full A/B: 6 tasks × 3 arms (headless opencode, tokens+time)
node benchmark/live-bench.js --task refactor-users-service --arm matcha --n 5 --timeout 480 # complex-task run
node benchmark/matcha-bench.js ./src # compliance scan of your code
node benchmark/agentic-runner.js --simulate # deterministic smoke test, no Claude neededComplex tasks run 200s+ per cell on free models — pass --timeout 480 for refactor/security tasks. Full methodology in docs/BENCHMARK.md.
Architecture
Layered by design. Each layer does one thing.
matcha