New Capability: Build Verification Gate
Date: March 15, 2026 Origin: Corrective Action — recurring pattern of running 7-minute full website builds for SSR-only changes, flagged by Chris as a persistent failure across many sessions Impact: Structural enforcement prevents unnecessary builds; saves 5-7 minutes per SSR-only code change Resolves:
Leadership/reports/2026-03-15-corrective-unnecessary-full-builds.md
What Was Built
A PreToolUse hook on Bash that intercepts full website build commands and surfaces a decision gate before execution. When V (or any agent) attempts to run pnpm build or npm run build targeting apps/website/, the hook fires and presents the SSR vs static decision matrix. The operator sees the gate, determines whether the change affects static content, and either proceeds with the full build or switches to tsc --noEmit (~15 seconds).
This is the second structural enforcement hook in the system. The first — the Dewey Decimal lookup hook — fires on Edit|Write and surfaces codebase classification context. Both follow the same principle: behavioral rules fail when they depend on the operator remembering to follow them. Structural gates force the decision point into the workflow itself.
The hook is one component of a four-layer prevention system built to resolve the corrective action:
- Hook (structural gate): Intercepts build commands, surfaces decision matrix
- Infrastructure Trigger:
vf-self-correction.mdentry catches the behavior pattern - Anti-Rationalization: Counters "better safe than sorry — run the full build"
- Critical Lesson + Build Notes:
MEMORY.mdnow distinguishes SSR type-check from full static build
Infrastructure Changes
| Change | Before | After |
|---|---|---|
| PreToolUse hooks | 1 hook (Dewey on Edit|Write) | 2 hooks (+ Build Gate on Bash) |
vf-self-correction.md Infrastructure Triggers |
7 triggers | 8 triggers (+ full build for SSR) |
vf-self-correction.md Verification Rationalizations |
5 entries | 6 entries (+ "better safe than sorry") |
MEMORY.md Build Notes |
"Website build: ~5-6 minutes" (neutral) | Explicit SSR/static distinction with tsc --noEmit alternative |
MEMORY.md Critical Lessons |
No build verification rule | Full build prevention rule with CAR reference |
Implementation
| File | Purpose |
|---|---|
.claude/hooks/build-check.sh |
PreToolUse hook — intercepts website build commands, surfaces decision gate |
/mnt/d/.claude/settings.local.json |
Hook registration — Bash matcher added to PreToolUse array |
skills/enforcement/vf-self-correction.md |
Infrastructure Trigger + anti-rationalization entry |
memory/MEMORY.md |
Critical Lesson + rewritten Build Notes |
agents/instruction-optimizer/data/incident-log.json |
Incident logged for pattern analysis |
Leadership/reports/2026-03-15-corrective-unnecessary-full-builds.md |
Corrective Action Report (root cause analysis) |
Usage
The hook is automatic. No invocation needed. It fires whenever a Bash command matches a website build pattern.
What triggers it
# All of these trigger the gate:
cd apps/website && npx pnpm build
cd apps/website && npm run build
npx pnpm build # bare build (could be in website dir)
What stays silent
# These do NOT trigger the gate:
cd apps/portal && npx pnpm build # portal builds are unaffected
cd apps/website && npx tsc --noEmit # type check — correct SSR approach
git status # non-build commands
node scripts/hubspot/api.js # unrelated bash
The decision it presents
===========================================================
BUILD VERIFICATION GATE
===========================================================
STOP. Do ANY changed files affect static content?
YES (full build needed):
- getStaticPaths changes
- Sanity data queries
- Build config (astro.config.mjs)
- New static routes
NO (type check only — 15s instead of 7min):
- SSR pages (prerender = false)
- Command Center / admin pages
- API routes
- Component-only changes
SSR pages are built by Vercel on-demand.
They are NOT in the static build output.
For SSR-only changes, use instead:
cd apps/website && npx tsc --noEmit
Decision matrix: skills/build-verification/SKILL.md
===========================================================
The SSR verification path
# For Command Center, admin, or any prerender=false page changes:
cd /mnt/d/Projects/value-first-operations/apps/website && npx tsc --noEmit
# ~15 seconds. Catches type errors. Then commit and push.
Leader Applications
V (Operations)
Primary beneficiary. V builds Command Center pages, agent visualizations, and admin interfaces — all SSR. The gate prevents V from defaulting to full builds on every commit. The 4-tier decision matrix (skills/build-verification/SKILL.md) becomes structurally enforced rather than optional reference material.
This also establishes a pattern: when a behavioral rule fails repeatedly, escalate to a structural hook. The Dewey hook proved this works for file classification. The build gate proves it works for operational decisions.
Sage (Customer)
No direct application. Sage does not execute website builds.
Pax (Finance)
No direct application. Pax does not execute website builds.
Dependencies
| Dependency | Status | Notes |
|---|---|---|
| Node.js (for JSON parsing in hook) | Confirmed | Used to extract command from tool input |
/mnt/d/.claude/settings.local.json hook registration |
Confirmed | PreToolUse Bash matcher configured |
skills/build-verification/SKILL.md |
Confirmed | Referenced in hook output as decision matrix source |
| Unix line endings on hook script | Confirmed | Fixed CRLF from Write tool; sed -i 's/\r$//' applied |
Verification
# Should fire the gate:
echo '{"tool_input":{"command":"cd apps/website && npx pnpm build"}}' | \
/mnt/d/Projects/value-first-operations/.claude/hooks/build-check.sh
# Should stay silent:
echo '{"tool_input":{"command":"git status"}}' | \
/mnt/d/Projects/value-first-operations/.claude/hooks/build-check.sh
echo '{"tool_input":{"command":"cd apps/portal && npx pnpm build"}}' | \
/mnt/d/Projects/value-first-operations/.claude/hooks/build-check.sh
Both tests pass. Hook fires on website builds, stays silent on everything else.
Design Principle
Documentation alone does not change behavior. The build-verification skill existed since its creation and explicitly documented "Don't: Run full build for every change" as an anti-pattern. It was never consulted. Enforcement triggers in vf-self-correction.md reduce the failure rate but still depend on the operator reading and internalizing them at session start.
Structural hooks eliminate the dependency on memory. The Dewey hook doesn't ask V to remember to check the codebase index — it surfaces the classification automatically on every edit. The build gate doesn't ask V to remember the 4-tier decision matrix — it surfaces the decision automatically on every build attempt.
Rule: If a behavioral correction fails twice, escalate to a structural hook.