Build Log · July 17, 2026
Gate Enforcement Architecture
Set out to build a Deploy Gate transcript layer; found and fixed a real fail-open bug in the mechanical gate system already policing every session
- OS
- Gates
- Security
- real bugs found in the existing gate system (fail-open on relative hook paths, self-referential tree-hash)
- 2
- real vulnerability found + fixed in new code (marker-ordering spoof)
- 1
- fixture/integration tests written, all passing
- 27
- historical confirmed-bypass instances found in bounded audit
- 4
- Crucible/Council rounds, each finding a real problem with the prior design
- 3
real bugs found in the existing gate system (fail-open on relative hook paths, self-referential tree-hash)
real vulnerability found + fixed in new code (marker-ordering spoof)
fixture/integration tests written, all passing
historical confirmed-bypass instances found in bounded audit
Crucible/Council rounds, each finding a real problem with the prior design
Timeline
Start
Charge: correct gate docs, extend hook architecture with judgment-gate ledger
Crucible round 1
Council rejects the pending-ledger design outright
Unproven detection precision would relocate, not fix, the marker-trust problem
Design pivot 1
Notes-keyword 'substantive validator' built, then caught as theater before shipping
Checked Claude's own prose, not a real fact
Investigation
Empirically verified PostToolUse does not fire on failing Bash commands
2 controlled tests with a temporary debug hook
Crucible round 2-3
Transcript-capture design proposed, found to have a context-binding hole, fixed with tree-hashing, re-approved
Build
Deploy Gate transcript layer built, tested, live-demonstrated
Real discovery
5 Whys traced a live test failure to MODULE_NOT_FOUND fail-open in the PRE-EXISTING gate-check.mjs
Relative hook paths break when Bash cd's into a subdirectory
Hardening
Zeb's review named 6 concrete gaps; all fixed, tested, and proven live
CLAUDE_PROJECT_DIR, fail-closed, SHA-256 tree-hash w/ untracked coverage, shell-free wrapper, nested-dir integration test, spoofing test
Audit
Bounded historical blast-radius audit found 4 real historical confirmed bypasses
1 prior session, low-severity content, corrected in that session's own JSON
Done
3-tier model documented, coverage table generated from config, Crucible interactivity rule hardened
What shipped
Deploy Gate transcript layer — a PostToolUse hook (gate-transcript-capture.mjs) captures real command exit codes for products/forge's `npm run gate:typecheck`, independent of anything Claude writes in a marker's notes field
Tree-hash binding (computeScopedTreeHash in marker.mjs) — SHA-256 over unstaged + staged + untracked file contents, so a transcript captured before a later edit is correctly treated as stale
Fail-closed boundary in gate-check.mjs — any unexpected crash now exits 2 (blocking) instead of silently letting the gated action through; proven with real injected-failure tests, not just review
Fixed 2 real bugs in the PRE-EXISTING gate system: relative hook command paths in settings.json (fail-open on subdirectory cwd, now uses ${CLAUDE_PROJECT_DIR}), and markerPath()/transcriptPath() resolving against process.cwd() instead of repo root
Fixed 1 real vulnerability found by writing an adversarial test: a spoofed echo could win over a real command's own marker in stdout if printed first — fixed by using the last match, not the first
27 fixture/integration tests across 3 test files (marker-transcript, fail-closed, real-hook-invocation) — a test harness that did not exist before this session
Generated gate-coverage table script (npm run gate:coverage) reading directly from gates.config.mjs — replaces the informal '13 gates' hand-count
3-tier enforcement model documented in triggers.md and gates.md — present-state-first, both historical bugs named with evidence
Bounded historical blast-radius audit — 225 fail-open events classified, 4 real historical confirmed bypasses found and corrected in the originating session's own JSON
Hardened ignition.md §1.6 Crucible interactivity rule after two live lapses this session (batching without Zeb's turn, presenting summary instead of raw output)
“The session's biggest success is not the transcript hook. It is that your pressure transformed a plausible mechanism into one that discovered a defect in the system already policing it.”