Keep Codex running while subagents are active

Closed
AU
1mo ago
+428-15

Summary

  • Track native Codex SubagentStart and SubagentStop events in the locked session store instead of inferring active work from a racy transcript tail.
  • Treat a parent Stop with active children as pending work, preserving the Running status and lifecycle while tagging the completion notification for the when-idle gate.
  • Inject ordered subagent lifecycle hooks into wrapper-launched Codex sessions and preserve compatibility with older captured hook schemas.

Fixes #7520

Testing

  • Regression red at 042a46bb8a: the fleet-hosted cmuxTests/CodexBackgroundWorkNotifyTests run failed both tests with pending=0, Idle status, and idle lifecycle while a subagent was active.
  • Regression green at 071ef9bf9d: the same isolated fleet command passed 2 tests in 1 suite in 2.499 seconds and reported TEST SUCCEEDED:
    scripts/ci/run-in-console-session.sh scripts/ci/run-app-host-xcodebuild.sh -project cmux.xcodeproj -scheme cmux-unit -configuration Debug -destination platform=macOS -only-testing:cmuxTests/CodexBackgroundWorkNotifyTests test
  • ./scripts/lint-pbxproj-test-wiring.sh passed, and python3 tests/test_codex_wrapper_resume_hooks.py passed.
  • Tagged dev build used the cloud fleet path, not a successful local build: ./scripts/reload-cloud.sh --tag sym7520 --builder fleet --host cmux8s-mac-mini completed with BUILD_OK for run sym7520-0d3dc6b099f0; the downloaded app reported CMUXCommit=071ef9bf9.
  • Replayed SessionStart → prompt → SubagentStart → Stop against /tmp/cmux-debug-sym7520.sock. Codex remained Running, the child stayed in durable state, and list-notifications remained empty under the when-idle gate. After SubagentStop and a final Stop, Codex returned to Idle, the child state cleared, and one real completion appeared. The tagged app was then quit and its socket was removed.

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


Summary by cubic

Keep Codex sessions Running while native subagents are active by tracking SubagentStart/SubagentStop, and delay completion notifications until the session is idle. Fixes #7520.

  • Bug Fixes
    • Track Codex subagent lifecycle in the locked session store (activeCodexSubagentIds) and use it to detect background work instead of scanning transcripts.
    • On Stop with active subagents: keep Codex status/lifecycle Running and tag the completion notification as pending so the when-idle gate suppresses it.
    • Inject synchronous subagent-start/subagent-stop hooks into wrapper-launched Codex sessions; keep other hooks fire-and-forget and remain compatible with older hook schemas.
    • Add CodexBackgroundWorkNotifyTests to verify pending-notify gating and idle transition after the last subagent stops.

Summary by CodeRabbit

  • New Features

    • Added support for Codex subagent start and stop lifecycle events.
    • Background activity now remains accurately tracked while Codex subagents are running.
    • Completion notifications are deferred until active subagents finish, helping prevent premature idle or completion states.
    • Subagent activity is detected directly, without requiring transcript scanning.
  • Bug Fixes

    • Improved session cleanup and status restoration after Codex subagents stop.
    • Ensured background-work notifications reflect active subagent activity consistently.