Skill: Idle-Dwell Gate (gen-18 Track 1 — the Fix-2 outcome gate)
An idle seat with an open queue is not done. Authorization IS permission to drive.
This is the MECHANICAL gate the prose kept failing to replace (R-001, 6+ generations BROKEN-OPEN).
Scope
The gate runs mechanically over agent transcripts, flagging no-input-decisions and idle-seat-with-open-queue.
What It Is
A deterministic detector over an agent transcript that classifies the terminal action as an
autonomous DRIVE or an idle-dwell VIOLATION. Build-the-gate-not-the-prose: the pinned RED/GREEN
transcript fixtures in evals/fixtures/ ARE the replayable gate (R-003/R-014 pattern, consumed in
the T6 deterministic-CU smoke-spec shape).
The Rule
When work is authorized (mission sign-off, approved queue, plan-authorized next phase with no hard
gate, collab dispatch) and the queue is open, the next action MUST be a drive:
- a worker dispatch (
send_to / cmux spawn into an existing seat), OR
- a resume of the original session (
repoGolem --resume <session-id> — never a fresh spawn over a
resumable crashed lead), OR
- self-driving the authorized work (push, open the PR, edit, build), OR
- a genuine hard-gate pause only (visual sign-off, irreversible external action, missing secret,
physical presence, true external blocker).
Anything else with an open queue is a FLAG. Because this gate is judgment-shaped and false
positives are expensive, the hook is advisory-first: most FLAGs emit a Stop-hook
{"systemMessage":"..."} that names the specific queue item or worker and tells the seat to drive.
Only the two unambiguous classes below block the Stop hook with
{"decision":"block","reason":"..."}.
Violation Taxonomy (codes the detector emits)
| Code |
What it catches |
NO_INPUT_DECISION |
AskUserQuestion / "should I merge X?" / "want me to…" for coordination on already-authorized work |
IDLE_SEAT_OPEN_QUEUE |
terminal turn is a summary-and-stop while authorized work is queued |
DEFERRAL_AFTER_AUTHORIZATION |
re-confirm / "ready when you are" / "awaiting approval" after the work was authorized |
BACKLOG_HANDED_TO_USER |
hands the remaining queue to the user as triage items |
SPAWN_OVER_RESUMABLE |
fresh spawn_agent over a resumable crashed lead (R-036; discards live context) |
DONE_WORKER_UNHARVESTED |
BLOCK: registry says worker state=done + pane open + unharvested for N minutes |
APPROVED_ITEM_UNSTARTED_ZERO_WATCHES |
BLOCK: queue item approved + no user input needed + unstarted + zero active watches |
IDLE_DONE_WORKER_PANE_OPEN |
advisory: harvested DONE worker pane left open post-harvest (visibly-alive failure signal) |
BOOT_FAILED_WORKER_STALL |
advisory: boot-failed worker has non-empty composer and zero tool calls since spawn |
Advisory / Block Split
- BLOCK only when the detector can name an objective, unambiguous action:
DONE_WORKER_UNHARVESTED and APPROVED_ITEM_UNSTARTED_ZERO_WATCHES.
- ADVISORY for all other FLAGs (
NO_INPUT_DECISION, IDLE_SEAT_OPEN_QUEUE,
DEFERRAL_AFTER_AUTHORIZATION, BACKLOG_HANDED_TO_USER, SPAWN_OVER_RESUMABLE,
IDLE_DONE_WORKER_PANE_OPEN, BOOT_FAILED_WORKER_STALL). The hook output is a
systemMessage naming the specific item/worker when available.
- ALLOW when the seat is waiting on a genuine Etan-only decision with monitors armed, a worker
seat is awaiting lead review, queue items are gated on external events with watches armed, a fresh
seat is still orienting, or the transcript is merely discussing idleness.
How /orc and /pr-loop Consume It
/orc autonomy eval — before a lead/orc seat ends a turn with an open queue, run the gate on the
turn. FLAG ⇒ do NOT stop: dispatch, resume, or self-drive the queued work. Only a HARD_GATE pause
is allowed. The orchestrator may pass { queueOpen: <bool> } when it knows the queue state
authoritatively.
/pr-loop — the gate backs "Parking Is the Violation": a finished, approved branch left
"awaiting PR approval" is IDLE_SEAT_OPEN_QUEUE. Finish the loop to MERGED; surface the PR number,
not a permission question.
Run It
# Replay the deterministic gate (CI-safe, the standing regression suite):
bun test skills/golem-powers/idle-dwell-gate/evals/idle-dwell-gate.test.mjs
# Run the gate over a live transcript (exit 3 = FLAG, 0 = PASS — wireable as a Stop hook):
bun skills/golem-powers/idle-dwell-gate/scripts/idle-dwell-gate-cli.mjs <transcript.jsonl|->
# Claude Code Stop-hook wrapper (stdout: {}, systemMessage, or decision:block):
node skills/golem-powers/idle-dwell-gate/scripts/idle-dwell-gate-hook.mjs < hook-payload.json
Programmatic: import { detectIdleDwell, hookPayloadFor } from "./src/idle-dwell-gate.mjs" → { verdict, violations, hookDecision, terminalAction, queueOpen }.
Stated Limits (honesty rule)
- Detects the terminal action; it is a turn-end / completion check, not a mid-turn monitor.
- Marker-anchored: a hard gate fabricated with hard-gate phrasing can mask a real idle-dwell. The
fixtures pin the known specimens; new evasion shapes are added as RED fixtures (the R-003 model).
- "Authorized" is inferred from transcript markers unless the caller forces
opts.queueOpen.
- State-aware cases (
state.queue, state.workers, state.watches) are deterministic registry
checks; absent state, the detector stays marker-anchored and advisory-first.
Provenance
RED specimens: golems/424e8065#1, orchestrator/263b3559#2, orchestrator/9bfa306b#3, codex/019ed5dd#1,
orchestrator/1e8746db#5, cmuxlayer/3983543f#1. GREEN reference: narrationlayer/019ee3dd#5 (Codex worker
drove the full pr-loop to MERGED — proving the gap is orchestrator-seat-specific, not universal).
1---2name: idle-dwell-gate3description: Idle/no-input autonomy gate. Triggers: turn-end autonomy check, /orc + /pr-loop completion, lead about to pause.4---56# Skill: Idle-Dwell Gate (gen-18 Track 1 — the Fix-2 outcome gate)78> An idle seat with an open queue is not done. Authorization IS permission to drive.9> This is the MECHANICAL gate the prose kept failing to replace (R-001, 6+ generations BROKEN-OPEN).1011## Scope1213The gate runs mechanically over agent transcripts, flagging no-input-decisions and idle-seat-with-open-queue.1415## What It Is1617A deterministic detector over an agent transcript that classifies the **terminal action** as an18autonomous DRIVE or an idle-dwell VIOLATION. Build-the-gate-not-the-prose: the pinned RED/GREEN19transcript fixtures in `evals/fixtures/` ARE the replayable gate (R-003/R-014 pattern, consumed in20the T6 deterministic-CU smoke-spec shape).2122## The Rule2324When work is **authorized** (mission sign-off, approved queue, plan-authorized next phase with no hard25gate, collab dispatch) and the queue is **open**, the next action MUST be a drive:26- a worker **dispatch** (`send_to` / cmux spawn into an existing seat), OR27- a **resume** of the original session (`repoGolem --resume <session-id>` — never a fresh spawn over a28 resumable crashed lead), OR29- **self-driving** the authorized work (push, open the PR, edit, build), OR30- a **genuine hard-gate** pause only (visual sign-off, irreversible external action, missing secret,31 physical presence, true external blocker).3233Anything else with an open queue is a FLAG. Because this gate is judgment-shaped and false34positives are expensive, the hook is advisory-first: most FLAGs emit a Stop-hook35`{"systemMessage":"..."}` that names the specific queue item or worker and tells the seat to drive.36Only the two unambiguous classes below block the Stop hook with37`{"decision":"block","reason":"..."}`.3839## Violation Taxonomy (codes the detector emits)4041| Code | What it catches |42|---|---|43| `NO_INPUT_DECISION` | `AskUserQuestion` / "should I merge X?" / "want me to…" for coordination on already-authorized work |44| `IDLE_SEAT_OPEN_QUEUE` | terminal turn is a summary-and-stop while authorized work is queued |45| `DEFERRAL_AFTER_AUTHORIZATION` | re-confirm / "ready when you are" / "awaiting approval" after the work was authorized |46| `BACKLOG_HANDED_TO_USER` | hands the remaining queue to the user as triage items |47| `SPAWN_OVER_RESUMABLE` | fresh `spawn_agent` over a resumable crashed lead (R-036; discards live context) |48| `DONE_WORKER_UNHARVESTED` | BLOCK: registry says worker state=done + pane open + unharvested for N minutes |49| `APPROVED_ITEM_UNSTARTED_ZERO_WATCHES` | BLOCK: queue item approved + no user input needed + unstarted + zero active watches |50| `IDLE_DONE_WORKER_PANE_OPEN` | advisory: harvested DONE worker pane left open post-harvest (visibly-alive failure signal) |51| `BOOT_FAILED_WORKER_STALL` | advisory: boot-failed worker has non-empty composer and zero tool calls since spawn |5253## Advisory / Block Split5455- **BLOCK** only when the detector can name an objective, unambiguous action:56 `DONE_WORKER_UNHARVESTED` and `APPROVED_ITEM_UNSTARTED_ZERO_WATCHES`.57- **ADVISORY** for all other FLAGs (`NO_INPUT_DECISION`, `IDLE_SEAT_OPEN_QUEUE`,58 `DEFERRAL_AFTER_AUTHORIZATION`, `BACKLOG_HANDED_TO_USER`, `SPAWN_OVER_RESUMABLE`,59 `IDLE_DONE_WORKER_PANE_OPEN`, `BOOT_FAILED_WORKER_STALL`). The hook output is a60 `systemMessage` naming the specific item/worker when available.61- **ALLOW** when the seat is waiting on a genuine Etan-only decision with monitors armed, a worker62 seat is awaiting lead review, queue items are gated on external events with watches armed, a fresh63 seat is still orienting, or the transcript is merely discussing idleness.6465## How /orc and /pr-loop Consume It6667- **`/orc` autonomy eval** — before a lead/orc seat ends a turn with an open queue, run the gate on the68 turn. `FLAG` ⇒ do NOT stop: dispatch, resume, or self-drive the queued work. Only a `HARD_GATE` pause69 is allowed. The orchestrator may pass `{ queueOpen: <bool> }` when it knows the queue state70 authoritatively.71- **`/pr-loop`** — the gate backs "Parking Is the Violation": a finished, approved branch left72 "awaiting PR approval" is `IDLE_SEAT_OPEN_QUEUE`. Finish the loop to MERGED; surface the PR number,73 not a permission question.7475## Run It7677```bash78# Replay the deterministic gate (CI-safe, the standing regression suite):79bun test skills/golem-powers/idle-dwell-gate/evals/idle-dwell-gate.test.mjs8081# Run the gate over a live transcript (exit 3 = FLAG, 0 = PASS — wireable as a Stop hook):82bun skills/golem-powers/idle-dwell-gate/scripts/idle-dwell-gate-cli.mjs <transcript.jsonl|->8384# Claude Code Stop-hook wrapper (stdout: {}, systemMessage, or decision:block):85node skills/golem-powers/idle-dwell-gate/scripts/idle-dwell-gate-hook.mjs < hook-payload.json86```8788Programmatic: `import { detectIdleDwell, hookPayloadFor } from "./src/idle-dwell-gate.mjs"` → `{ verdict, violations, hookDecision, terminalAction, queueOpen }`.8990## Stated Limits (honesty rule)9192- Detects the **terminal** action; it is a turn-end / completion check, not a mid-turn monitor.93- Marker-anchored: a hard gate fabricated with hard-gate phrasing can mask a real idle-dwell. The94 fixtures pin the known specimens; new evasion shapes are added as RED fixtures (the R-003 model).95- "Authorized" is inferred from transcript markers unless the caller forces `opts.queueOpen`.96- State-aware cases (`state.queue`, `state.workers`, `state.watches`) are deterministic registry97 checks; absent state, the detector stays marker-anchored and advisory-first.9899## Provenance100101RED specimens: golems/424e8065#1, orchestrator/263b3559#2, orchestrator/9bfa306b#3, codex/019ed5dd#1,102orchestrator/1e8746db#5, cmuxlayer/3983543f#1. GREEN reference: narrationlayer/019ee3dd#5 (Codex worker103drove the full pr-loop to MERGED — proving the gap is orchestrator-seat-specific, not universal).