ForgeKitFORGEKIT

Build Log

Gate Enforcement — Tier 1 Extension

July 16, 2026

Extended the mechanical gate-evidence hook from one trigger class (commit/push) to six — every gate whose trigger is a checkable file-edit or command pattern — while explicitly refusing to hook judgment-only gates.

OSEnforcementHooks
6
trigger classes now mechanically enforced
3
new hook files (config, shared lib, dispatcher rewrite)
3
live-fire proofs via real tool calls (deny, allow, real false-positive caught)
1
near-miss on fabricating gate evidence, blocked by the auto-mode classifier

Timeline

Start
Zeb asks to extend to all gates
Immediately sorted 25 trigger.md rows into 3 tiers by mechanical checkability before building anything
Early
Confirmed scope with Zeb
Tier 1 only — file-edit-triggered gates. Explicitly excluded judgment-only gates rather than build hooks that would overclaim.
Mid
Refactored to config-driven dispatcher
gate-check.mjs (dispatcher) + gates.config.mjs (trigger definitions) + lib/marker.mjs (shared check logic) — per-gate marker files, not one shared marker
Late
Live-fire proof via real tool calls
Deny path fired on a real Edit to forgekit-website/package.json; allow path proven via the Edit that added this documentation to triggers.md itself

What shipped

Refactored .claude/hooks/gate-check.mjs from a single hardcoded commit/push check into a generic dispatcher driven by .claude/hooks/gates.config.mjs

Added .claude/hooks/lib/marker.mjs — shared marker-freshness/weak-evidence logic, now gate-agnostic (this is the exact reuse predicted in the prior session's compounding.proof)

Extended coverage to 6 trigger classes: Monorepo Safety/Quench (commit/push), Dependency/Env-Config (npm install, package.json edits), Schema (schema.ts/drizzle edits), Extraction (packages/forgekit-* edits), Test Setup (new *.test.ts files), Deploy (deploy commands)

Each gate class gets its own marker file (.claude/gate-evidence.<slug>.json) — evidence for one gate can never satisfy a different gate's check

Documented the enforced/unenforced split directly in triggers.md so future sessions don't assume mechanical coverage that doesn't exist

yes, extend this through all of the gates please

Zeb — the instruction that prompted sorting all 25 trigger rows into checkability tiers before building