Skip to content

fix(activity): close stuck flags from JSONL replay at bootstrap_complete - #53

Merged
Juliusolsson05 merged 1 commit into
mainfrom
fix/dispatch-stale-running
May 7, 2026
Merged

Juliusolsson05 merged 1 commit into
mainfrom
fix/dispatch-stale-running

Conversation

@Juliusolsson05

Copy link
Copy Markdown
Owner

Summary

Root cause for panes reporting sessionStatus="running" after restart despite no live activity (sometimes for days):

  • Codex: rollout-sourced turn_started opens semantic.currentTurn during replay, but the matching turn_completed / turn_stopped never fires, so isSemanticTurnRunning stays true → sessionStatus = 'running' permanently.
  • Claude: queue-op replay sets awaitingAssistant = true on enqueue but never clears it on remove. Live ops clear via clearOptimisticAwaiting; replay does not.

Reconcile both at the bootstrap_complete callback (after the 150ms JSONL-quiet window, i.e. replay is done). Only acts when there is no live signal (processActive false, streamPhase idle).

Verified against this user's debug bundles: today's app run has 22 sessions with unmatched turn_started events — 21 from Codex rollout, 1 from Claude proxy.

Verification

  • npm run build:app
  • Forensic confirmation via ~/.config/cc-shell/feed-debug logs

🤖 Generated with Claude Code

Diagnosed via debug bundles that 11 panes reported sessionStatus="running" after
restart despite having no live signal (processActive=false, streamPhase=idle,
activityStatus=null). Two distinct shapes:

  - Claude: queue-op replay (enqueue → ... → remove pairs from old turns) sets
    awaitingAssistant=true on enqueue but never clears it when the queue empties
    via remove. Live operation gets a turn_completed semantic event that clears
    via clearOptimisticAwaiting; replay does not, so the flag stays true.

  - Codex: rollout-sourced turn_started opens semantic.currentTurn but the
    matching turn_completed/turn_stopped never fires during replay, so
    isSemanticTurnRunning stays true and deriveSessionStatus returns 'running'.

Reconcile both at the bootstrap_complete callback (after the 150ms quiet
window, i.e. when replay has finished). Only acts when there's no live signal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant