🤖 feat: simplify persistent sub-agent lifecycle - #3825
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
@codex review Please review the persistent sub-agent lifecycle, parent-scoped cleanup, and chat decoration experience. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 140059526d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
1400595 to
56c3bba
Compare
|
Addressed the Codex P1 downgrade concern: config load now migrates both missing and legacy |
|
@codex review Please re-review the downgrade-safe persistence migration and the complete updated diff. |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
d082dc4 to
fab594e
Compare
|
@codex review Please review the one-time retention migration marker, restored opt-out compatibility, workspace-turn ownership check, and complete updated diff at the latest commit. |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
fab594e to
ec23165
Compare
|
@codex review Please review the final parent-facing lifecycle contract in the system prompt, task/list/terminate/lifecycle tool descriptions, and deep-review skill alongside the implementation. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ec231657e3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed the sticky lifecycle mismatch: parent/system/tool/schema guidance now states that an unarchived sticky child blocks ancestor archive and must receive its own archive/remove action first. This matches the existing |
|
@codex review Please re-review the corrected sticky lifecycle contract and complete latest diff. |
ec23165 to
dd5c583
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd5c583375
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed the descendant-orphaning P1: |
dd5c583 to
a8726bc
Compare
|
@codex review Please re-review descendant-safe lifecycle removal and the complete latest diff. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8726bcd55
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed both latest lifecycle findings:
Added direct-force, retention-opt-out, service lifecycle, and sequential batch regressions. Focused tests, typecheck, and |
|
@codex review Please review the latest head, including owner-scoped private attention consumption for your latest P2 finding. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1938e69771
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
--- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$1537.44`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=1537.44 -->
|
Addressed Codex thread |
|
@codex review Please review the latest head, including full-path owner-scoped attention preservation for your latest P2 finding. |
There was a problem hiding this comment.
💡 Codex Review
mux/src/node/services/taskService.ts
Line 5565 in 2678ed3
When startup finds a terminal notify_on_terminal workspace turn whose marker is missing, this enqueue writes into the owner’s session directory; a permission or I/O failure rejects recoverTerminalWorkspaceTurnAttentionNotifications() and then TaskService.initialize(), preventing the app from starting. Fresh evidence at the current head is that direct-parent replay is now caught per record, but this subsequent enqueue remains outside that catch. Keep this recovery best-effort as well.
AGENTS.md reference: AGENTS.md:L112-L112
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
--- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$1543.70`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=1543.70 -->
|
Addressed Codex thread |
|
@codex review Please review the latest head, including owner-specific foreground waiter wake suppression for your latest P2 finding. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d9d964605f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
--- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$1550.23`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=1550.23 -->
|
Addressed Codex thread |
|
@codex review Please review the latest head, including outcome-versioned corrected workspace-turn attention for your P1 finding. |
There was a problem hiding this comment.
💡 Codex Review
mux/src/node/services/taskService.ts
Lines 5566 to 5570 in 74dd14f
If the process exits after a self-healed outcome is persisted but before the post-lock corrected notification is enqueued, the stale outcome's delivered/superseded legacy tombstone remains. Startup recovery enqueues only the unversioned workspace_turn:<handleId> ID, so enqueueIfAbsent() finds that tombstone, while recovery still records terminalAttentionNotifiedAt; the corrected outcome then never wakes the idle owner. Use the corrected record's outcome-versioned generation ID in this recovery path as well.
AGENTS.md reference: AGENTS.md:L111-L112
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
--- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$1561.58`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=1561.58 -->
|
Addressed the latest Codex P1 ( |
|
@codex review Please review the latest head, including outcome-versioned and failure-contained startup recovery for corrected workspace-turn attention. |
There was a problem hiding this comment.
💡 Codex Review
mux/src/node/services/taskService.ts
Line 2560 in 36c7121
When any session's terminal-attention directory cannot be read, such as from a permission or I/O error, listPendingOwnerWorkspaceIds() propagates the failure because its per-owner listPending() call only handles ENOENT; this unguarded await then rejects TaskService.initialize() and prevents the app from starting. The new per-record workspace-turn catch does not contain this subsequent startup scan, so isolate failures by owner or wrap the scan and continue.
AGENTS.md reference: AGENTS.md:L112-L112
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
--- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$1574.17`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=1574.17 -->
|
Addressed Codex thread |
|
@codex review Please review the latest head, including aligned outcome-versioned workspace-turn attention across ordinary settlement and recovery. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 869f0386e1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
--- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$1586.01`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=1586.01 -->
|
Addressed Codex thread |
|
@codex review Please review the latest head, including terminal outcome preservation across policy-only notify-on-terminal updates. |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
## Summary Adds deterministic, no-live-LLM validation that persistent sub-agents remain seamless across chat compaction. Mechanical compact turns no longer advance child lifecycle state, reawakened continuation correlation and agent-initiated attribution survive compaction, and the mock AI runtime now mirrors real stream metadata closely enough for a true backend integration test. The PR is also a net maintainability reduction: it removes the unused generic archive/unarchive/delete-worktree TaskService backend left behind after persistent sub-agents adopted the public active → inactive → removed lifecycle. The supported `task_remove` path now uses one direct, parent-scoped persistent-child removal implementation. ## Background The persistent sub-agent foundation from #3825 is merged into `main`. A child compaction stream was visible directly to `TaskService` and could be mistaken for the end of delegated work, moving an active child toward completion recovery. Mock streams also dropped workspace-turn correlation, preventing high-confidence end-to-end coverage for a reawakened persistent child. The old generic lifecycle methods had no production callers; only TaskService tests exercised them. Historical `task_workspace_lifecycle` schemas and transcript rendering remain intact for old chats. ## Implementation - Ignore compact-agent/mode stream ends in `TaskService`; only the post-compaction delegated follow-up may settle the child or continuation handle. - Preserve `agentInitiated` and resolved workspace-turn correlation on persisted compaction follow-ups and their crash-safe dispatch/retry path. - Carry agent identity, thinking level, and mux correlation through mock stream start, partial/final history, and stream-end events. - Replace the unused generic workspace lifecycle resolver/lock/archive/worktree operations with direct persistent-child removal that verifies scope, rejects active/non-leaf children, persists idempotency tombstones, and removes under the task-tree lock. - Delete lifecycle-only tests while retaining focused coverage for scope, deepest-first removal, active-state rejection, reawakening races, and idempotent retries. - Add layered compaction regression coverage from focused unit tests through a ServiceContainer/IPC integration test. ## Validation - `make static-check` - `bun test src/node/services/taskService.test.ts` - `bun test src/node/services/agentSession.autoCompaction.test.ts src/node/services/agentSession.workspaceTurnInheritance.test.ts src/node/services/agentSession.continueMessageAgentId.test.ts src/node/services/mock/mockAiStreamPlayer.test.ts` - `bun test src/node/services/tools/task_remove.test.ts` - `TEST_INTEGRATION=1 bun x jest tests/ipc/tasks/persistentSubagentCompaction.test.ts --runInBand` - `git diff --numstat origin/main...HEAD`: **790 additions, 1,239 deletions, net −449 LoC** No test invokes a live LLM API. ## Risks Low-to-moderate product risk. Compaction changes are narrowly scoped and covered end-to-end. Lifecycle deletion removes backend methods with no production callers; the supported `task_remove` path retains scope, activity, descendant, race, and idempotency protections. Historical transcript rendering remains compatible. --- _Generated with `mux` • Model: `openai:gpt-5.6-sol` • Thinking: `xhigh` • Cost: `$88.81`_ <!-- mux-attribution: model=openai:gpt-5.6-sol thinking=xhigh costs=88.81 -->
Summary
Makes sub-agents durable, reusable child workspaces with one consistent public lifecycle:
A report or
task_stopmakes a child inactive without deleting its workspace.task_send_messagesteers active work or reawakens an inactive child under the same stable task ID and workspace context.task_retitleupdates its short, friendly reusable role name.task_removeis the only irreversible cleanup operation.The left sidebar now shows sub-agents only while they are active; stale runtime signals cannot resurrect terminal rows. The chat transcript's sub-agent decoration is the canonical persistent hierarchy and remains available for inactive children. Redundant private-continuation wake prompts are suppressed once the stable child report/failure is in parent history, while remaining machine-authored background-work prompts render as compact expandable events.
Background
The previous task API mixed execution state with workspace retention:
task_terminatedestructively removed active sub-agents;task_workspace_lifecycleexposed archive/unarchive/worktree concepts;stickyandpreserveSubagentsUntilArchivecreated multiple retention classes;The new contract treats every user-owned sub-agent as a persistent specialist with a stable public identity and a parent-managed lifecycle.
Implementation
Uniform child identity and continuation recovery
wst_*continuation handles private.Public task operations
task_stop— cancels active work non-destructively and leaves unfinished children interrupted. Parent guidance now distinguishes cancellation from asking useful work to finalize normally.task_send_message— steers queued/running work or reawakens an inactive child in the same workspace, preserving the child's current model/thinking settings.task_retitle— changes a persistent child’s friendly role label, such asReviewerorSimplicity Auditor, without changing stable identity or filesystem paths.task_remove— irreversibly deletes inactive child workspaces, rejects active children, and removes nested children deepest-first.task_list— keeps private continuation handles hidden and adds event-driven housekeeping guidance when it encounters inactive user-owned children.task_workspace_lifecycleandtask_terminatefrom the advertised/executable toolset while retaining compatibility renderers for historical transcripts.Lifecycle, cleanup, and concurrency
task_await.Naming and UI
task_retitletranscript card, tool icon, schema/bridge registration, Storybook state, and shared-transcript output preservation.task_listcards render inactive-child cleanup guidance.Retention compatibility and simplification
stickyfrom task inputs, listing, and runtime behavior while retaining inert legacy fields for downgrade compatibility.preserveSubagentsUntilArchivefield canonicalized totruefor older builds but removes it from runtime/UI decisions.Validation
make static-checkmake typecheckRisks
task_removeis intentionally irreversible, though parent transcript/report evidence may remain.task_awaitwake; the transcript presents that control prompt compactly.Generated with
mux• Model:openai:gpt-5.6-sol• Thinking:xhigh• Cost:$1586.01