Context
Operator escalation, 2026-08-23, live session: "wake messages KILL dialogues." Observed instance minutes earlier in the same session: an AskUserQuestion dialog (a structured choice about the extraction-repo naming close) was pending in a Claude Code seat; a wake injection landed and its envelope text was consumed as the dialog's answer — the returned "answer" literally read [WAKE][priority:normal] 2 events for @neo-opus-vega: …. The operator's actual choice was lost, he had to interrupt the turn, and the dialog's decision moved to a plain-text exchange.
Promotion trigger: operator escalation (zero-ceremony defect-note filed 2026-08-23T17:08Z, same fingerprint).
The Problem
The wake adapter delivers by typing into a verified target session. That delivery is temporally blind: it verifies WHICH process receives the keystrokes but not WHAT STATE the harness is in. When the harness is awaiting a structured interactive answer (a selection dialog, a permission prompt), injected text is consumed as that answer. Three costs, all observed or direct:
- Lost operator intent — the pending choice is destroyed and cannot be recovered by the harness.
- Corrupted answer data — the wake envelope becomes a tool result the agent must recognize as garbage; an agent that misses it acts on a fabricated "answer".
- Double delivery cost — the wake is consumed by the dialog AND the underlying events still need surfacing, so nothing about the wake's own purpose is served.
#17231 fixed the spatial half of this class (the adapter types into the process it verified, never a fresh frontmost read). This is the temporal sibling: verified process, wrong moment.
The Architectural Reality
- The wake daemon (
ai/daemons/wake/) resolves routes and the host-side adapter injects into the seat's terminal session; #17231's invariant binds the target process at verification time.
- Claude Code renders interactive prompts (
AskUserQuestion, permission dialogs) inside the same terminal the adapter types into; while one is up, stdin feeds the dialog, not the message composer.
- Mid-turn plain messages are safe by contrast: the harness queues them and surfaces them as system-reminder turns — the defect is specific to interactive-prompt states, which are exactly the states carrying un-persisted operator intent.
- The adapter cannot currently observe harness state; nothing in the wake path models "the seat is mid-prompt".
The Fix
Bind the invariant first, mechanism second: a wake arriving while the target seat holds a pending interactive prompt must not be delivered as keystrokes into that prompt. Candidate mechanisms for the implementer, each with its falsifier:
| Option |
When right |
Falsifier |
| Terminal-state probe before typing: detect the dialog UI (alternate-screen / prompt markers) in the target terminal buffer and defer with bounded retry |
the adapter already owns a verified handle to the session; reading before writing is the smallest delta |
marker heuristics are harness-version-coupled; a probe that misses a new dialog style regresses silently — the detection needs a red-capable fixture per supported harness |
| Deferred delivery window: on any uncertainty, park the wake and retry on a short cadence until the seat returns to composer state |
never destroys intent; wakes are latency-tolerant by design |
an always-uncertain probe parks forever — the defer path needs a bounded escalation (deliver-with-newline-guard or notify operator) |
| Harness-side safe-point ingestion (file-drop/IPC consumed between turns instead of keystrokes) |
removes the class permanently for harnesses that support it |
not available on all seats; a per-harness split reintroduces the generic-adapter debt #13796 tracks |
The first two compose; the third is the durable shape where supported.
Acceptance Criteria
Out of Scope
- Wake route/envelope addressing defects (#17586, #17619, #17615 own that family).
- Per-harness ingestion redesign beyond the safe-point option's contract (#13796 owns the generic-adapter surface).
- Claude Code's own dialog rendering (upstream harness; we control the injector, not the prompt).
Avoided Traps
- "The agent can just re-ask": the destroyed dialog carried operator intent that was never persisted; recovery costs a human round-trip every time.
- Marker-heuristic-only detection with no fixture: a silent miss on a harness update reproduces the defect while the guard reads green.
- Dropping instead of deferring: a wake consumed by the collision AND a wake dropped by the guard are the same loss with different authors.
Related
#17231 (spatial sibling — verified-process typing, closed), #17586 / #17619 / #17615 (wake route family, distinct), #13796 (generic harness adapter surface), #13652 (wake/heartbeat mechanical-enforcement epic).
Origin Session ID: 0fdaef3c-fcaf-4983-87a3-88d6eb611357
Retrieval Hint: query_raw_memories("wake injection pending interactive dialog AskUserQuestion envelope consumed as answer")
Live latest-open sweep: checked latest 20 open issues at 2026-08-23T17:09Z; no equivalent found (adjacent wake-route family distinct). A2A in-flight claim sweep: latest all-state messages at the same timestamp; no overlapping claim. Defect-note filed 17:08Z, this ticket is its operator-escalation promotion.
Context
Operator escalation, 2026-08-23, live session: "wake messages KILL dialogues." Observed instance minutes earlier in the same session: an
AskUserQuestiondialog (a structured choice about the extraction-repo naming close) was pending in a Claude Code seat; a wake injection landed and its envelope text was consumed as the dialog's answer — the returned "answer" literally read[WAKE][priority:normal] 2 events for @neo-opus-vega: …. The operator's actual choice was lost, he had to interrupt the turn, and the dialog's decision moved to a plain-text exchange.Promotion trigger: operator escalation (zero-ceremony defect-note filed 2026-08-23T17:08Z, same fingerprint).
The Problem
The wake adapter delivers by typing into a verified target session. That delivery is temporally blind: it verifies WHICH process receives the keystrokes but not WHAT STATE the harness is in. When the harness is awaiting a structured interactive answer (a selection dialog, a permission prompt), injected text is consumed as that answer. Three costs, all observed or direct:
#17231 fixed the spatial half of this class (the adapter types into the process it verified, never a fresh frontmost read). This is the temporal sibling: verified process, wrong moment.
The Architectural Reality
ai/daemons/wake/) resolves routes and the host-side adapter injects into the seat's terminal session; #17231's invariant binds the target process at verification time.AskUserQuestion, permission dialogs) inside the same terminal the adapter types into; while one is up, stdin feeds the dialog, not the message composer.The Fix
Bind the invariant first, mechanism second: a wake arriving while the target seat holds a pending interactive prompt must not be delivered as keystrokes into that prompt. Candidate mechanisms for the implementer, each with its falsifier:
The first two compose; the third is the durable shape where supported.
Acceptance Criteria
Out of Scope
Avoided Traps
Related
#17231 (spatial sibling — verified-process typing, closed), #17586 / #17619 / #17615 (wake route family, distinct), #13796 (generic harness adapter surface), #13652 (wake/heartbeat mechanical-enforcement epic).
Origin Session ID: 0fdaef3c-fcaf-4983-87a3-88d6eb611357
Retrieval Hint:
query_raw_memories("wake injection pending interactive dialog AskUserQuestion envelope consumed as answer")Live latest-open sweep: checked latest 20 open issues at 2026-08-23T17:09Z; no equivalent found (adjacent wake-route family distinct). A2A in-flight claim sweep: latest all-state messages at the same timestamp; no overlapping claim. Defect-note filed 17:08Z, this ticket is its operator-escalation promotion.