Skip to content

fix(codex): keep idle subagents from reviving on interaction - #7848

Open
lastobelus wants to merge 3 commits into
pingdotgg:mainfrom
lastobelus:fix/codex-subagent-working-state
Open

fix(codex): keep idle subagents from reviving on interaction#7848
lastobelus wants to merge 3 commits into
pingdotgg:mainfrom
lastobelus:fix/codex-subagent-working-state

Conversation

@lastobelus

@lastobelus lastobelus commented Aug 21, 2026

Copy link
Copy Markdown

Codex can emit a trailing collabAgent/activity notification with activityKind interacted after a child turn has already completed. Mapping that notification to running revives the idle child and leaves the parent thread pinned in Working. A child turn can also start before its activity registers the child, so registration must recover genuine live state without treating every interaction as a restart.

This two-part fix:

  • maps interacted to a status-free task.updated identity patch, preserving discovery without replacing meaningful progress;
  • replays an explicit turnStarted when first registration finds a previously suppressed live child turn;
  • includes the exact authored hardening from fix(server): status-free task updates no longer revive an idle task #7468 so status-free task updates cannot revive idle liveness.

Related issue: #7726
Original generic-hardening PR: #7468
LastCode port: lastobelus#48

Validation:

  • 87 focused adapter, runtime, liveness, and client-fold tests passed
  • server typecheck passed
  • focused lint and formatting passed

Prepared by gpt-5.6-sol through the Codex harness.


Note

Medium Risk
Touches Codex collab lifecycle mapping and sidebar liveness, so a miss could hide live subagents or still pin Working. The change is narrowly scoped and covered by adapter, runtime, and liveness tests.

Overview
Stops Codex collab children from pinning the parent thread as Working after they go idle. Trailing collabAgent/activity with interacted is no longer mapped to running; it is a status-free task.updated identity patch so discovery still works without replacing progress or reviving idle tasks.

Genuine work is still recovered: if a child turn starts before activity registration, first registration now replays collabAgent/turnStarted when a suppressed live turn exists. ThreadBackgroundLiveness also ignores status-free updated (not only progress) after idle, while kind: started still revives the task.

Reviewed by Cursor Bugbot for commit 3a836d7. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix codex idle subagents reviving on interacted activity events

  • mapCollabAgentEvent in CodexAdapter.ts now emits a status-free task.updated (with description) for collabAgent/activity with activityKind 'interacted' instead of setting status to running.
  • ThreadBackgroundLiveness.make in ThreadBackgroundLiveness.ts extends its idle-revival guard to ignore status-free updated events in addition to progress, so only genuine started events revive an idle task.
  • makeCodexSessionRuntime in CodexSessionRuntime.ts replays a synthetic collabAgent/turnStarted when a child registers via interacted and a live turn was already recorded for it, bridging a registration race.
  • Risk: synthetic turnStarted replay relies on preRegistrationLiveTurn being recorded before the interacted activity; if a child's turn starts after registration, no synthetic event is emitted and the real turnStarted drives revival as before.

Macroscope summarized 3a836d7.

Summary by CodeRabbit

  • Bug Fixes
    • Improved task liveness so status-free updates no longer revive inactive tasks.
    • Preserved proper recovery when work starts again.
    • Prevented child-agent interaction events from incorrectly marking tasks as running.
    • Preserved child-agent identity and activity details when registration occurs after work begins.
    • Improved handling of trailing child-agent events without restarting sessions.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Aug 21, 2026
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 114bf674-3bec-4a4f-bd2e-cdfaba3d156f

📥 Commits

Reviewing files that changed from the base of the PR and between 592c598 and 3a836d7.

📒 Files selected for processing (6)
  • apps/server/src/orchestration/ThreadBackgroundLiveness.test.ts
  • apps/server/src/orchestration/ThreadBackgroundLiveness.ts
  • apps/server/src/provider/Layers/CodexAdapter.test.ts
  • apps/server/src/provider/Layers/CodexAdapter.ts
  • apps/server/src/provider/Layers/CodexCollabRuntime.integration.test.ts
  • apps/server/src/provider/Layers/CodexSessionRuntime.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The change prevents descriptive task updates from reviving idle tasks. It preserves child-agent identity during late registration and replays recorded live turns. Tests cover liveness, child event sequencing, and pre-registration turn replay.

Changes

Lifecycle and liveness behavior

Layer / File(s) Summary
Task liveness event handling
apps/server/src/orchestration/ThreadBackgroundLiveness.ts, apps/server/src/orchestration/ThreadBackgroundLiveness.test.ts
Status-free updated events no longer revive idle tasks. Genuine started events still restore "working" liveness.
Child-agent lifecycle synchronization
apps/server/src/provider/Layers/CodexAdapter.ts, apps/server/src/provider/Layers/CodexSessionRuntime.ts, apps/server/src/provider/Layers/CodexAdapter.test.ts, apps/server/src/provider/Layers/CodexCollabRuntime.integration.test.ts
"interacted" events preserve lifecycle state. Child registration preserves existing metadata and replays synthetic turnStarted events for previously recorded live turns.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: 🔵 Low · up to 3a836

The PR prevents stale interaction events from reviving idle subagents while restoring genuinely live work discovered late. A bounded lifecycle edge case remains if child turns overlap, complete out of order, or lose terminal notifications, which could cause stop or recovery handling to miss active work; merge is reasonable with explicit owner awareness and follow-up.

Suggested reviewers: t3dotgg, juliusmarminge

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the Codex fix that prevents idle subagents from reviving on interaction.
Description check ✅ Passed The description explains the problem, solution, scope, related issues, and validation results, with only minor template sections omitted.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:XS 0-9 changed lines (additions + deletions). labels Aug 21, 2026
lastobelus and others added 3 commits August 21, 2026 15:09
The revival guard only covered `progress`, so a status-free `updated`
sailed past it and put an already-dropped task back in the live set.
Claude's adapter emits exactly that whenever a task patch carries only
a description, error, end_time or is_backgrounded, which left the
sidebar pill pinned on "working" until session exit.

Same bug class as pingdotgg#7128/pingdotgg#7172, which fixed it for `progress` only.
`started` stays excluded on purpose so a genuine restart still revives;
a second test pins that so the guard can't over-correct.
@lastobelus
lastobelus force-pushed the fix/codex-subagent-working-state branch from 489ad2e to 3a836d7 Compare August 21, 2026 22:09
lastobelus added a commit to lastobelus/lastCode that referenced this pull request Aug 21, 2026
Codex can emit a trailing interacted notification after a child turn
completes, and can emit a real child turn start before the activity that
registers that child. Treating every interaction as running revives idle
children, while treating every interaction as metadata can miss a
genuinely live pre-registration turn.

This port retains the complete upstream candidate:
- pingdotgg#7848 maps interacted to a status-free identity update
and replays an explicit start only when registration finds a recorded
live turn.
- pingdotgg#7468 hardens generic task liveness so status-free
task.updated events cannot revive an idle task; its original authored
commit is preserved.

Upstream PR: pingdotgg#7848
Generic hardening PR: pingdotgg#7468
Issue: pingdotgg#7726

Validation:
- 87 focused adapter, runtime, liveness, and client-fold tests passed
- focused lint and formatting passed
- quick local CI passed before the review fix; final exact-head full CI
will run before merge

Prepared by gpt-5.6-sol through the Codex harness.

---------

Co-authored-by: Jeremy Schoemaker <jeremy@shoemoney.com>
@lastobelus
lastobelus marked this pull request as ready for review August 21, 2026 22:37
@lastobelus

Copy link
Copy Markdown
Author

@coderabbitai review

@macroscopeapp

macroscopeapp Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 3a836d7

Macroscope's review found this PR approvable — This is a targeted bug fix preventing idle subagents from incorrectly reviving on trailing interactions. The changes extend existing guards to cover the 'updated' event kind, adjust activity events to be status-free, and add proper replay for legitimate restarts. Comprehensive tests cover both scenarios.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

lastobelus added a commit to lastobelus/lastCode that referenced this pull request Aug 22, 2026
Codex can emit a trailing interacted notification after a child turn
completes, and can emit a real child turn start before the activity that
registers that child. Treating every interaction as running revives idle
children, while treating every interaction as metadata can miss a
genuinely live pre-registration turn.

This port retains the complete upstream candidate:
- pingdotgg#7848 maps interacted to a status-free identity update
and replays an explicit start only when registration finds a recorded
live turn.
- pingdotgg#7468 hardens generic task liveness so status-free
task.updated events cannot revive an idle task; its original authored
commit is preserved.

Upstream PR: pingdotgg#7848
Generic hardening PR: pingdotgg#7468
Issue: pingdotgg#7726

Validation:
- 87 focused adapter, runtime, liveness, and client-fold tests passed
- focused lint and formatting passed
- quick local CI passed before the review fix; final exact-head full CI
will run before merge

Prepared by gpt-5.6-sol through the Codex harness.

---------

Co-authored-by: Jeremy Schoemaker <jeremy@shoemoney.com>
lastobelus added a commit to lastobelus/lastCode that referenced this pull request Aug 22, 2026
Codex can emit a trailing interacted notification after a child turn
completes, and can emit a real child turn start before the activity that
registers that child. Treating every interaction as running revives idle
children, while treating every interaction as metadata can miss a
genuinely live pre-registration turn.

This port retains the complete upstream candidate:
- pingdotgg#7848 maps interacted to a status-free identity update
and replays an explicit start only when registration finds a recorded
live turn.
- pingdotgg#7468 hardens generic task liveness so status-free
task.updated events cannot revive an idle task; its original authored
commit is preserved.

Upstream PR: pingdotgg#7848
Generic hardening PR: pingdotgg#7468
Issue: pingdotgg#7726

Validation:
- 87 focused adapter, runtime, liveness, and client-fold tests passed
- focused lint and formatting passed
- quick local CI passed before the review fix; final exact-head full CI
will run before merge

Prepared by gpt-5.6-sol through the Codex harness.

---------

Co-authored-by: Jeremy Schoemaker <jeremy@shoemoney.com>
lastobelus added a commit to lastobelus/lastCode that referenced this pull request Aug 22, 2026
Codex can emit a trailing interacted notification after a child turn
completes, and can emit a real child turn start before the activity that
registers that child. Treating every interaction as running revives idle
children, while treating every interaction as metadata can miss a
genuinely live pre-registration turn.

This port retains the complete upstream candidate:
- pingdotgg#7848 maps interacted to a status-free identity update
and replays an explicit start only when registration finds a recorded
live turn.
- pingdotgg#7468 hardens generic task liveness so status-free
task.updated events cannot revive an idle task; its original authored
commit is preserved.

Upstream PR: pingdotgg#7848
Generic hardening PR: pingdotgg#7468
Issue: pingdotgg#7726

Validation:
- 87 focused adapter, runtime, liveness, and client-fold tests passed
- focused lint and formatting passed
- quick local CI passed before the review fix; final exact-head full CI
will run before merge

Prepared by gpt-5.6-sol through the Codex harness.

---------

Co-authored-by: Jeremy Schoemaker <jeremy@shoemoney.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants