# RUNBOOK.md — Layer 08

Every alarm the system can raise, mapped to one exact response — written down before the alarm
fires, so 3 a.m. is a lookup, not a decision. The heartbeat emits each alarm as a line starting
`ALARM:<name>`; keep this table in sync with the code (Checkpoint 08 greps for drift).

| Alarm | Severity | What it means | Response |
|-------|----------|---------------|----------|
| `ALARM:halt` | high | Daily spend hit the cap (Layer 06). | Expected. Read `spend.jsonl` for a runaway task; raise `CAP_USD` only with a reason. |
| `ALARM:gate-fail-loop` | high | A task failed `check-constitution.sh` 3× running. | Auto-opens a PR; agent stops retrying it. Read the diff — usually a flaky test or a real bug. |
| `ALARM:trust-drop` | medium | A task type fell below 95% and lost autonomy (Layer 04). | Working as designed. Inspect the recent failures before re-earning; don't just bump the threshold. |
| `ALARM:goal-regressed` | medium | A standing goal that was true is now false (Layer 05). | Issue is already filed. Prioritize — a regression is a promise the system made and broke. |
| `ALARM:reroute` | medium | Fable returned a safety refusal; loop fell back to Opus 4.8. | Expected under the strict filter. Log it; if a whole task type reroutes, rewrite its prompt to read plainly benign. |
| `ALARM:held` | low | Fable judged a task unsafe to run unattended and skipped it. | Read the one-line reason. Usually correct; if consistently over-cautious, clarify the constitution. |
| `ALARM:model-missing` | high | A model id in `models.json` stopped resolving. | Point that tier at the next model down. One-line edit — the id lives in exactly one place. |

## Escalation

- **high** → page a human now; the loop has stopped or is spending.
- **medium** → an issue is filed; handle in the next working block.
- **low** → informational; review in the daily digest.

## Adding an alarm

Emit `ALARM:<name>` from the code, add a row here in the same commit. Checkpoint 08:

```
grep -oE 'ALARM:[a-z-]+' ops/*.py ops/*.sh | sort -u | sed 's/.*ALARM://' \
  | while read a; do grep -q "$a" ops/RUNBOOK.md || echo "UNDOCUMENTED: $a"; done
```
