Skip to content

fix: sticky idle state prevents stale working status - #149

Merged
aterrylu merged 1 commit into
mainfrom
terry/hook-recap-bug
Apr 15, 2026
Merged

fix: sticky idle state prevents stale working status#149
aterrylu merged 1 commit into
mainfrom
terry/hook-recap-bug

Conversation

@aterrylu

Copy link
Copy Markdown
Owner

Summary

  • Agent sessions were showing as "working/spinning" in the dashboard even after finishing work
  • Root cause: the deriveStatus() state machine had no protection against late-arriving hook events overriding the idle state
  • Additionally, known CC bugs (#26770, #29881) mean Stop hooks sometimes don't fire, compounding the issue
  • The "recap" feature (CC v2.1.108) was investigated but is unrelated — it's a session-resume summary, not end-of-turn output

Changes

  • Sticky idle/stopped statesidle and stopped can only be exited by UserPromptSubmit, SessionStart, SessionEnd, PermissionRequest, Notification, or PreToolUse. Late PostToolUse, SubagentStop, etc. are logged and dropped
  • Debug logging — dropped events now log with session ID prefix for diagnostics
  • Dashboard default fix — changed ?? "working" fallback to ?? "unknown" in Sidebar and TabBar so agents with no hook state don't show as spinning
  • Notification guard fixNotification added to idle exit events so permission_prompt notifications can break through the sticky guard
  • 11 new tests — comprehensive coverage for sticky idle behavior, sticky stopped, and transition edge cases

CC Bug References

  • #26770 — Stop hooks via settings.json command type sometimes never fire
  • #29881 — Stop hook only fires on session termination, not per-turn
  • #40655 — Race: Stop hook fires before transcript JSONL flush

Test plan

  • All 30 hook tests pass (16 existing + 11 new sticky + 3 notification)
  • Biome lint/format clean
  • Manual verification: spawn agent in dashboard, give it a task, verify status transitions correctly to idle after completion
  • Verify permission prompts still show as "needs input" when agent is idle

🤖 Generated with Claude Code

The agent status state machine could get stuck showing "working" when
late-arriving hook events (PostToolUse, SubagentStop, etc.) overrode
the idle status set by the Stop event. This was exacerbated by known
CC bugs where Stop hooks don't always fire (#26770, #29881).

Changes:
- Make idle and stopped "sticky" states — only UserPromptSubmit,
  SessionStart, SessionEnd, PermissionRequest, Notification, and
  PreToolUse can transition out of them
- Log dropped events for debugging sticky guard behavior
- Fix dashboard default status fallback from "working" to "unknown"
  (agents with no hook state showed as spinning)
- Add Notification to idle exit events so permission_prompt
  notifications can break through the sticky guard
- Add comprehensive tests for sticky idle behavior (11 new tests)
- Export clearAgentState helper for test cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aterrylu
aterrylu marked this pull request as ready for review April 15, 2026 06:01

@nox-0x nox-0x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid fix. Sticky idle/stopped guard is clean and well-tested (11 new cases). The UI fallback change from "working" to "unknown" is the right call — no hook state != actively working. LGTM.

@aterrylu
aterrylu merged commit 3d27fa4 into main Apr 15, 2026
1 check passed
@aterrylu
aterrylu deleted the terry/hook-recap-bug branch April 15, 2026 06:13
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.

2 participants