fix: keep Claude idle after helper PreToolUse follows Stop

Merged
AU
23d ago
+198-0

Fixes #19781

Summary

Claude Code can run a background helper after the parent turn emits Stop. If that helper emits PreToolUse, cmux previously treated it as a new parent turn and persisted the session as Running. The hook now persists a settled-turn fence in ClaudeHookSessionRecord, preserves it across post-Stop notifications, and clears it atomically at the next accepted UserPromptSubmit before normal tool activity resumes.

Validation

  • Regression test was red before the original fix: run 38368340569 at f849aa559c4.
  • Focused hosted test passed with the original production fix: run 38370969121.
  • Current-head scoped checks passed: python3 scripts/verify-local.py (Swift syntax, localization defaults, test wiring, feature flags) and python3 scripts/lint-feature-flags.py.
  • Review-fix focused hosted suite: run 38511169194.

Changelog

  • Fixed: Keep Claude sessions settled when helper tool activity follows Stop, including after a notification.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes #19781 so a Claude session stays settled when a background helper emits PreToolUse after the parent turn has completed with Stop or StopFailure.

  • Acknowledges helper tool events without reopening the parent session as Running.
  • The settled-turn guard is persisted in the session record so it survives notifications, and is released by the next UserPromptSubmit.
  • Adds regression tests for helpers running after Stop, including pending background work and notification-driven events.

Summary by CodeRabbit

  • Bug Fixes
    • Prevented Claude tool activity after a completed turn from incorrectly marking a settled session as running. New user prompts still allow subsequent tool activity to update the session status.