# Artifact — the enforcement that binds the Stop event

These are excerpts from the two live Stop-hook gates. They are lightly abridged for length
(marked `[…]`); no logic is altered. Full sources at the cited paths.

---

## 1. Ordinary-session gate — `system/_operator/scripts/check-session-stop-contract.mjs`

The header states the catch, the mechanism, and the block signal:

```
// check-session-stop-contract.mjs — FoundryOS Stop hook. The ordinary-session anti-stop.
//
// THE CATCH IT PREVENTS (witnessed 2026-07-26, seven real sessions)
//   Session <redacted> ended a turn with: "225 owner-write cells remain across ~120 files.
//   Continuing down the density list." — then stopped, at 49 turns, with the work explicitly
//   unfinished and continuation explicitly announced. No question was asked, so the AskUserQuestion
//   gate could never have fired. […]
//
// THE MECHANISM
//   Blocks turn-end (exit 2) when THIS session holds an armed contract that is not satisfied. Two
//   predicates […]:
//     P1  open items > 0                                   -> BLOCK
//     P2  the turn-ending message is classified (R1/R2) and there is no unconsumed escalation
//                                                          -> BLOCK
//   P1 carries the structural load. P2 […] R1 rule keys on a CONTRADICTION (the message says
//   "continuing", the act is stopping), not on interrogative grammar […].
```

The exit codes and the block path (the harness reads exit `2` as "refuse turn-end"):

```
const EXIT_ALLOW = 0;
const EXIT_BLOCK = 2;
[…]
export function runStopGate(payload, env = process.env, deps = {}) {
  if (gateDisabled(env)) return { exitCode: EXIT_ALLOW, […] };        // kill switch
  if (deps.chassisOwns) return { exitCode: EXIT_ALLOW, […] };         // stand down for chassis
  […]
  // block path:
  return { exitCode: EXIT_BLOCK, stdout: '', stderr: blockedMessage(contract, decision, classified, effectiveStreak) };
}
```

Failure posture is split by error class *on purpose* — a user-level install must not turn a defect
in this one file into a machine-wide lockout across unrelated work:

```
// FAILURE POSTURE IS SPLIT […]
//   malformed contract -> fail-CLOSED · no contract -> release · infra failure -> fail-OPEN […]
```

---

## 2. Chassis audit-loop gate — `system/_operator/scripts/check-audit-loop-terminal.mjs`

Same lifecycle event, different release predicate: the owned chassis run must reach a **terminal
run-state**, not merely emit a terminal-looking audit verdict.

```
// check-audit-loop-terminal.mjs — the structural anti-stop for the auto pre-exec/post-exec audit loop.
//
// WHY THIS EXISTS (the catch it prevents)
//   […] the operator CAN simply stop on a CONTINUE verdict (turn length, "diminishing returns",
//   fatigue). Witnessed 2026-06-12: the operator stopped the […] pre-exec loop at round 3
//   (CONTINUE) and called it a "checkpoint" — an UNAUTHORIZED stop. CONTINUE is not a stop condition.
//
// THE MECHANISM
//   the hook reads its stdin session_id and blocks (exit 2) iff […] THIS session owns a non-terminal
//   chassis run […]. The release predicate is RUN-STATE terminality {closed, elevated} […] NOT the
//   audit verdict […].
```

The block signal is stated inline, which is the load-bearing platform contract for the whole claim:

```
// Exit 2 is the Stop-hook BLOCK signal (Claude Code feeds stderr back + refuses turn-end).
process.exit(exitCode);
```

The rendered denial tells the driver plainly not to stop:

```
'check-audit-loop-terminal: BLOCKED — YOUR chassis run is NOT terminal.\n' +
[…]
'  - status=closed   ("<plan> is closed out and ready to merge"), OR\n' +
'  - status=elevated (a kernel-minted elevation to surface to Dan).\n' +
reinvoke   // "Re-invoke YOUR chassis run and keep driving. Do NOT stop here."
```

---

## 3. Where they are registered as `Stop` hooks

`system/_operator/scripts/install-session-contract-hooks.mjs` writes the ordinary-session gate into
the root `.claude/settings.json` under the `Stop` event (managed-rule set, marker
`FOUNDRYOS_SESSION_CONTRACT_v1`):

```
Stop: [{ hooks: [{ type: 'command', command: s('check-session-stop-contract.mjs') }] }],
```

The chassis gate is registered under `Stop` by the two-signal-surfacing installer. Both
registrations are audited to stay installed by Caliber criteria **C221** (session gate) and **C168**
(chassis gate) — a gate that is not installed is itself a Caliber finding.
