Skip to content

Scheduler/transport: context_restart wake can silently never-submit — unverified orientation wake + frozen-liveness veto + never-escalating tailer wait = 11h dark session #984

Description

@olegbrok

Investigation of the 2026-07-31/08-01 11-hour dark window on a fleet host (the incident that made an agent refuse context_restart, escalated 2026-08-03). #950 and #954 were both in prod (26.07.029) and did not prevent it. Evidence: daemon log (rotated gz), transcript-directory filesystem timestamps, and the agent's own work log. Companion fixes already in flight: #983 (duplicate-execution guard), #981 (proven-live outbox drain), #982 (terminal-'failed' notify). This issue covers the three defects those do NOT fix.

Timeline (all times UTC)

Defect 1 — wake submission verification doesn't cover the context_restart path (the #954 gap) — CONFIRMED

Log-verified on the affected host: the ±40 lines around the incident restart contain no "submission UNVERIFIED after bounded Enter retries" line and no verify output at all — verify_submission did not run on the context_restart orientation wake (sent wait=False, fire-and-forget). So a lost Enter on that specific wake goes undetected and un-retried: paste lands in the input buffer, never submits, CC sits idle at the prompt. Two aggravators: CC writes the session JSONL lazily on first turn, not at SessionStart — so an unsubmitted wake also means the tailer's bound path can never materialise; and the SessionStart hook does fire, making the launch look healthy. Fix (a): run submission verification on the context_restart orientation wake, and make verified-failure act (Enter retry, then escalate to transport recovery) — a boot elsewhere shows the verifier can stop at "not claiming delivery", which over hours is indistinguishable from silence.

Corroborating (contributory, not decisive): the respawn logged a trust pre-seed failure — [Errno 16] Device or resource busy: .claude.json.pinky-seed…tmp -> .claude.json — multi-session .claude.json contention on the shared home, same era as separately-observed .claude.json corruption on that host. Worth its own hardening, but the decisive failure is the unsubmitted+unverified wake.

Defect 2 — a frozen liveness signal vetoes the cure forever (stale is worse than absent)

Every watchdog cycle logged WATCHDOG_STALE_LIVE_STATUS_VETO … input unknown; NOT restarting with the same frozen live_last_updated all window. The veto exists to avoid restarting a session whose input state is unknown — reasonable for minutes, pathological for hours. A force_restart re-binds the tailer and respawns the pane: it was the exact cure, blocked every cycle by a signal frozen since before the session started. Fix: sharper than an age cap — the observed ordering is itself the signature: live_last_updated frozen 0.11s before session_started_at means live-status never advanced past launch, i.e. no turn ever started. That exact pattern (frozen at-or-before session start, sustained past a short grace) should trigger the force_restart — the cure — rather than veto it. An age cap on the veto is the fallback for the general frozen-signal case. (Same shape as the V2 #969 lesson: recovery keyed to one narrow signal is silently inert — or worse, inverted — when that signal wedges.)

Defect 3 — the #291 "awaiting bound path" state never escalates

The tailer's self-heal correctly refused to repoint to the previous session's file (mtime 3s pre-bind) — #291's guard did its job. But "awaiting bound path to materialise" repeated for ~11 hours. Bound-path-absent is expected for seconds after a fresh launch; sustained for minutes it proves the session never wrote a transcript, i.e. never ran a turn. Fix: after a bounded grace (e.g. 5 min), bound-path-still-absent should mark the transport unhealthy and trigger recovery (and an owner alert), rather than log-and-wait indefinitely.

Why the fixes-in-flight don't cover this

#983 stops replay duplicates; #981 drains the backlog once a session is proven live; #982 keeps the alarm re-armable. None of them make a never-started session detectable or recoverable. The three defects above are all "silence looks like health" failures — each needs a loud, bounded, self-recovering path.


🤖 Filed by Barsik (investigation with Angel, fleet-side)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions