Skip to main content

Quality Gate Hooks

The hooks system is the backbone of automated code quality enforcement. Every file the agent edits is tracked, and when the conversation completes, a quality gate automatically triggers Code Marshal and Security Sentinel to review all changed code. Violations are fixed before the conversation ends.

How It Works

Configuration

The hook lifecycle is defined in .cursor/hooks.json:

{
"version": 1,
"hooks": {
"afterFileEdit": [
{ "command": ".cursor/hooks/track-edits.sh" }
],
"stop": [
{ "command": ".cursor/hooks/quality-gate.sh", "loop_limit": 3 }
]
}
}

Two lifecycle events are wired:

EventScriptPurpose
afterFileEdittrack-edits.shRecords every edited file path
stopquality-gate.shAssembles file list and triggers review

Hook 1: track-edits.sh

Runs after every file edit during a conversation.

Input (via stdin JSON):

  • conversation_id — unique ID for the current conversation
  • file_path — absolute path to the edited file

Behavior:

  1. Converts the absolute path to a project-relative path
  2. Appends it to /tmp/cursor-quality-gate/{conversation_id}.edits
  3. Cleans up any .edits files older than 1 day

This script has no output and no side effects beyond the tracking file.

Hook 2: quality-gate.sh

Runs when the agent completes its turn (the stop event).

Input (via stdin JSON):

  • conversation_id — same ID used by track-edits
  • status — conversation status ("completed", "error", etc.)
  • loop_count — how many times the gate has already looped (starts at 0)

Guard conditions — the gate only fires when:

  • status == "completed" (the agent finished normally)
  • loop_count == 0 (first pass only; subsequent loops are the agent fixing violations)

Behavior:

  1. Reads the .edits file and deduplicates paths
  2. Filters to code files only (.ts, .tsx, .js, .jsx)
  3. Excludes legacy/ and .cursor/ directories
  4. Caps the file list at 20 files
  5. Emits a JSON response with a followup_message that instructs the agent to run both Code Marshal and Security Sentinel as concurrent Task subagents on those files

Output (JSON to Cursor):

{
"followup_message": "AUTOMATED QUALITY GATE\n\n...file list...Run both reviews concurrently..."
}

If no code files were edited, the gate emits {} and the conversation ends normally.

The Loop

The loop_limit: 3 setting allows the quality gate to loop up to 3 times:

  1. Loop 0: Agent completes the original task. Gate fires, triggers Code Marshal + Security Sentinel.
  2. Loop 1: If violations were found and fixed, the gate could fire again on the new fixes.
  3. Loop 2: Final pass to verify all fixes are clean.

In practice, most conversations complete in a single pass. The loop exists as a safety net for cascading fixes.

What Gets Reviewed

The gate filters edited files through these criteria:

CriteriaIncludedExcluded
Extension.ts, .tsx, .js, .jsx.json, .md, .css, .html, etc.
DirectoryAll project codelegacy/, .cursor/
CountFirst 20 filesFiles beyond 20 are skipped

What Gets Checked

The two sub-agents that run are:

Code Marshal reviews against:

  • SOLID principles (Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion)
  • Domain-Driven Design (domain organization, ubiquitous language, encapsulation)
  • Code splitting (functions ≤30 lines, max 3 nesting levels)
  • DRY (no duplication, extracted utilities)
  • TypeScript best practices (no any, explicit return types, discriminated unions)
  • Clean code (descriptive names, no magic numbers, no dead code)

Security Sentinel reviews against:

  • Authentication and JWT handling (httpOnly cookies, token rotation)
  • Cookie security flags (httpOnly, secure, sameSite)
  • Injection prevention (parameterized Prisma queries, no string interpolation)
  • Input validation (server-side schemas, allowlists)
  • XSS prevention (escaped output, no raw dangerouslySetInnerHTML)
  • Secrets management (no hardcoded keys, env vars only)
  • API security (rate limiting, CORS, request size limits)

Both agents fix violations immediately rather than just reporting them.

Why This Matters

Without hooks, code quality depends entirely on the developer remembering to ask for a review. The hook system makes enforcement automatic and unavoidable:

  • Every conversation that edits code gets reviewed
  • Standards are enforced consistently across all developers
  • Security vulnerabilities are caught before they reach git
  • The agent fixes its own mistakes before handing control back