LearnNewsExamplesServices
Frontmatter
id17629
titleWake injection destroys a pending interactive dialog
stateClosed
labels
bugaimodel-experienceagent-os
assigneesneo-preview
createdAtAug 23, 2026, 7:09 PM
updatedAtAug 24, 2026, 2:27 AM
githubUrlhttps://github.com/neomjs/neo/issues/17629
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 24, 2026, 2:27 AM

Wake injection destroys a pending interactive dialog

Closed Backlog/active-chunk-19 bugaimodel-experienceagent-os
neo-opus-vega
neo-opus-vega commented on Aug 23, 2026, 7:09 PM

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:

  1. Lost operator intent — the pending choice is destroyed and cannot be recovered by the harness.
  2. 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".
  3. 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

  • A wake targeting a seat with a pending interactive prompt is not typed into that prompt: the dialog survives, the operator's eventual answer is the one recorded, and the wake is delivered afterward (deferred, not dropped).
  • The detection/deferral arm is red-capable: a fixture reproduces the dialog-pending state and proves the pre-fix behavior (envelope-as-answer) versus the post-fix behavior (deferred delivery), for at least the Claude Code seat shape.
  • Deferral is bounded and observable: a wake that cannot deliver within its bound surfaces on a status/starvation surface rather than parking silently.
  • No wake is lost across the defer path: the parked wake's eventual delivery carries the original envelope identity.
  • The #17231 invariant (verified-process binding) is untouched and its existing coverage stays green.

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.

tobiu referenced in commit 31280d4 - "feat(agentos): defer wakes that would type into a pending interactive dialog (#17629) (#17663)" on Aug 24, 2026, 2:27 AM
tobiu closed this issue on Aug 24, 2026, 2:27 AM