The complete source for the semantic session-contract gate described in the field note. When you tell a coding agent "don't stop until every test passes," this is the mechanism that holds it to that — a lifecycle hook that classifies the agent's own stop message and refuses an early hand-back.
Free to download. No email required. Start with the portable version — one dependency-free Node.js file.
Take the portable one if you just want it working. The others are for reading.
The core mechanism compressed into a single Node.js script that handles all three lifecycle events. Copy it to a path, register it in your Claude Code settings, done. Ships with a 22-case executable smoke-test harness so you can verify it before you trust it.
session-contract-minimal.mjs — SessionStart, UserPromptSubmit and Stop in one filesession-contract-smoke-test.mjs — 22-case harness, run it with nodeREADME.md — install, arm, disarm, kill switchThe wider implementation this was extracted from — a work-item ledger, a question gate, reasoned waivers, classified escalations, a managed hook installer and the full production unit suite. It integrates with FoundryOS operator infrastructure, so treat it as reference source rather than a drop-in package.
The full written appendix from the field note — installation notes, the design rationale behind the classifier, and the complete portable source and smoke-test source inline. Nothing omitted from either file. Read this if you want to understand the mechanism before you run it.
Requires Claude Code with lifecycle hooks, and Node.js 20 or later.
Unzip the portable package, keep both files in the same directory, and run the smoke test.
node session-contract-smoke-test.mjs # expected: 22/22 smoke tests passed.
Copy session-contract-minimal.mjs to a stable absolute path, then register that same path for all three lifecycle events in your Claude Code settings.
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "node \"/absolute/path/session-contract-minimal.mjs\""
}]
}],
"UserPromptSubmit": [{
"hooks": [{
"type": "command",
"command": "node \"/absolute/path/session-contract-minimal.mjs\""
}]
}],
"Stop": [{
"hooks": [{
"type": "command",
"command": "node \"/absolute/path/session-contract-minimal.mjs\""
}]
}]
}
}
Use an absolute path that exists in the environment where Claude Code actually runs.
No command, no flag. You arm it with the correction you would already have typed.
Don't stop until every migration test passes. # disarm explicitly: stop # emergency bypass: SESSION_CONTRACT=0
What it does and doesn't do. The gate records the condition you stated and uses it as session context — it does not independently prove that condition is met. It blocks contradictory or avoidable hand-offs and permits ordinary completion messages. Pair it with tests, acceptance criteria, an external verifier or a work ledger when the end state itself needs independent enforcement.
Published as the reference implementation accompanying FoundryOS Field Note 01. Use it, adapt it, ship it in your own setup. If it saves you a morning, tell me what broke — that's the useful feedback.
This gate is a byproduct. The day job is custom operational software — engineered around how your business actually works, shipped in 2–4 weeks.