Skip to content

🤖 feat: simplify persistent sub-agent lifecycle - #3825

Merged
ammario merged 57 commits into
mainfrom
feat/persistent-subagent-experience
Aug 11, 2026
Merged

🤖 feat: simplify persistent sub-agent lifecycle#3825
ammario merged 57 commits into
mainfrom
feat/persistent-subagent-experience

Conversation

@ammar-agent

@ammar-agent ammar-agent commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Makes sub-agents durable, reusable child workspaces with one consistent public lifecycle:

active → inactive → removed

A report or task_stop makes a child inactive without deleting its workspace. task_send_message steers active work or reawakens an inactive child under the same stable task ID and workspace context. task_retitle updates its short, friendly reusable role name. task_remove is 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_terminate destructively removed active sub-agents;
  • task_workspace_lifecycle exposed archive/unarchive/worktree concepts;
  • sticky and preserveSubagentsUntilArchive created multiple retention classes;
  • completed children required a different operation to continue;
  • task-like workspace titles became stale when a persistent child received new assignments;
  • inactive children could accumulate without prompting the parent to retain or remove them deliberately;
  • stopping useful work merely to reconcile a turn marked the child interrupted rather than completed.

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

  • Keeps one stable public task ID equal to the child workspace ID.
  • Persists completed/stopped user-owned children until explicit removal.
  • Keeps internal wst_* continuation handles private.
  • Routes list/await/send operations through the stable child identity, including nested children whose direct parent owns the continuation record.
  • Validates canonical ISO timestamps while recovering the newest continuation after crashes.
  • Replays a stopped queued child's preserved initial brief when its first continuation starts.
  • Mirrors only the terminal settlement that actually wins concurrency races.

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 as Reviewer or Simplicity 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.
  • Removes task_workspace_lifecycle and task_terminate from the advertised/executable toolset while retaining compatibility renderers for historical transcripts.

Lifecycle, cleanup, and concurrency

  • Parents reconcile active descendants before finishing a turn.
  • After consuming a terminal report, parents decide whether to retain a reusable specialist or remove a one-shot/obsolete child.
  • Before completing a large task or PR, parents are guided to list reported/interrupted children and clean up stale ones deepest-first.
  • Compaction/restart recovery rediscovers inactive children without deleting them automatically.
  • Initial creation, reawakening, archive, and direct removal share a task-tree lifecycle lock so ancestors cannot disappear while child work starts.
  • Reawakened children count once toward parallel quotas rather than once as a child and again as a continuation.
  • Explicit stops supersede pending terminal wake-ups; intentional background work retains one-shot terminal attention.
  • Persistent-child reports/failures supersede the private continuation handle's duplicate wake, while ordinary workspace turns and continuations without a current report still direct the model through task_await.

Naming and UI

  • Parent/system/tool guidance requests short, friendly reusable role names instead of ordinary task-summary chat titles.
  • Adds a task_retitle transcript card, tool icon, schema/bridge registration, Storybook state, and shared-transcript output preservation.
  • task_list cards render inactive-child cleanup guidance.
  • Inactive/reported/interrupted child rows disappear from the left sidebar automatically, including terminal workflow members and selected inactive children; stale live store state cannot reintroduce a completed row.
  • Active, queued, and reawakened children remain visible.
  • Background-work control prompts use a compact, expandable machine-event component instead of a full user-message bubble; user-authored lookalikes remain ordinary escaped user messages.
  • The transcript sub-agent decoration remains the canonical nested hierarchy for persistent children and reports terminal continuation outcomes accurately.

Retention compatibility and simplification

  • Removes sticky from task inputs, listing, and runtime behavior while retaining inert legacy fields for downgrade compatibility.
  • Keeps the legacy preserveSubagentsUntilArchive field canonicalized to true for older builds but removes it from runtime/UI decisions.
  • Workflow-owned workers remain transient because their workflow journal owns durable output.
  • Centralizes active workspace-turn status checks, continuation lookup, and WorkspaceService lifecycle-lock dispatch, reducing duplicated lifecycle branching.

Validation

  • make static-check
  • make typecheck
  • Full TaskService and WorkspaceService suites
  • Task create/await/list/send/retitle/stop/remove suites
  • Tool schema, bridge, built-in agent policy, system-prompt, and transcript-sharing suites
  • Task tool UI/registry/story tests
  • MessageRenderer machine-wake tests and Storybook interaction suite
  • Project sidebar, sidebar grouping/filtering, AgentListItem, and sub-agent decoration suites
  • Focused simplification validation: 713 lifecycle tests passed
  • QuickJS runtime suite in a fresh process, plus 50 repeated coverage runs while classifying a CI-only callback-loss flake

Risks

  • Downgrades: older builds still interpret retained compatibility fields with previous archive-oriented behavior.
  • Internal executions: stable-child routing must remain synchronized with private continuation records.
  • Removal: task_remove is intentionally irreversible, though parent transcript/report evidence may remain.
  • Sidebar discoverability: inactive children intentionally leave the sidebar; users access them through the canonical transcript decoration.
  • Intentional wakes: ordinary workspace turns and continuations that do not deliver a current stable-child report still require a later task_await wake; the transcript presents that control prompt compactly.
  • CI isolation: QuickJS-heavy runtime tests run in fresh Bun processes because the monolithic coverage process can crash or lose asyncified runtime callbacks.

Generated with mux • Model: openai:gpt-5.6-sol • Thinking: xhigh • Cost: $1586.01

@mintlify

mintlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Mux 🟢 Ready View Preview Aug 9, 2026, 9:02 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the persistent sub-agent lifecycle, parent-scoped cleanup, and chat decoration experience.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/common/types/tasks.ts
@ammar-agent
ammar-agent force-pushed the feat/persistent-subagent-experience branch from 1400595 to 56c3bba Compare August 9, 2026 21:11
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed the Codex P1 downgrade concern: config load now migrates both missing and legacy preserveSubagentsUntilArchive: false values to persisted true through the serialized migration queue before task startup. Added coverage for both on-disk forms and re-ran make static-check.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please re-review the downgrade-safe persistence migration and the complete updated diff.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 56c3bbac19

ℹ️ 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".

@ammar-agent
ammar-agent force-pushed the feat/persistent-subagent-experience branch 2 times, most recently from d082dc4 to fab594e Compare August 9, 2026 21:43
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: fab594e5f3

ℹ️ 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".

@ammar-agent
ammar-agent force-pushed the feat/persistent-subagent-experience branch from fab594e to ec23165 Compare August 9, 2026 21:49
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/node/services/systemMessage.ts Outdated
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

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 preflightArchive/archive guard. Re-ran system-message, tool-definition, sticky lifecycle, and static checks.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please re-review the corrected sticky lifecycle contract and complete latest diff.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/node/services/taskService.ts
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed the descendant-orphaning P1: removeOwnedTaskWorkspace now refuses removal while any descendant sub-agent workspace remains, reports the blocking descendant IDs, and the parent/system/tool guidance directs nested removals deepest-first. Added a regression proving parent removal is blocked until child then parent are removed. Static checks and focused lifecycle tests pass.

@ammar-agent
ammar-agent force-pushed the feat/persistent-subagent-experience branch from dd5c583 to a8726bc Compare August 9, 2026 22:06
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please re-review descendant-safe lifecycle removal and the complete latest diff.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/common/types/tasks.ts
Comment thread src/node/services/tools/task_workspace_lifecycle.ts Outdated
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed both latest lifecycle findings:

  • direct WorkspaceService.remove(..., force: true) and retention opt-out paths now refuse removal whenever any descendant sub-agent workspace remains, so archived-workspace UI deletion cannot orphan the tree
  • task_workspace_lifecycle now executes targets sequentially in caller order, so a deepest-first nested remove batch deterministically removes child then parent

Added direct-force, retention-opt-out, service lifecycle, and sequential batch regressions. Focused tests, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including owner-scoped private attention consumption for your latest P2 finding.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/node/services/taskService.ts Outdated
---

_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 -->
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed Codex thread PRRT_kwDOPxxmWM6YHu6u in 2678ed3f06. The final task_await attention-consumption API now carries consumingWorkspaceId and returns without touching owner-scoped workspace-turn attention when consumer and continuation owner differ. The existing nested-owner regression now invokes both snapshot consumption and this later API, confirming the higher ancestor's pending wake survives the full await path. Task-await tests assert consumer identity propagation for immediate, waited, timeout-race, and error paths. Full TaskService, task_await, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including full-path owner-scoped attention preservation for your latest P2 finding.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

await this.enqueueTerminalAttention({

P1 Badge Contain terminal-notification recovery failures

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".

Comment thread src/node/services/taskService.ts Outdated
---

_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 -->
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed Codex thread PRRT_kwDOPxxmWM6YHzWz in d9d964605f. Workspace-turn settlement now suppresses the owner-scoped wake only when foregroundWaiterWorkspaceIds contains the continuation owner. A waiter in another workspace, including the persistent child's direct parent, receives its result without consuming the owner's wake. Added a production settlement regression with a root-owned nested continuation and direct-parent foreground waiter; after settlement, the root's workspace-turn attention remains pending or delivered rather than absent. Full TaskService, task_await, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including owner-specific foreground waiter wake suppression for your latest P2 finding.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/node/services/taskService.ts
---

_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 -->
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed Codex thread PRRT_kwDOPxxmWM6YH48f in 74dd14f46e. Corrected/resettled owner-scoped workspace-turn attention now uses the exact terminal outcome generation (handleId:status:updatedAt), while legacy IDs remain compatible for initial/older notifications. Stale and versioned IDs are deleted independently; consumption creates and delivers both tombstones under the settlement lock and is keyed to the exact returned status + updatedAt. A stale drain can therefore transition only its old ID and cannot swallow the corrected notification. Added a regression that completes the stale legacy drain after corrected replacement and verifies the corrected version remains persisted. Full TaskService, task_await, TerminalAttentionStore, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including outcome-versioned corrected workspace-turn attention for your P1 finding.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

await this.enqueueTerminalAttention({
ownerWorkspaceId: record.ownerWorkspaceId,
sourceKind: "workspace_turn",
terminalOutcome: terminalAttentionOutcome(record.status),
sourceId: record.handleId,

P1 Badge Recover corrected attention with the outcome version

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 -->
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed the latest Codex P1 (Recover corrected attention with the outcome version) in 36c712181f. Startup recovery now enqueues terminal workspace-turn attention with the exact handleId:status:updatedAt generation, so a delivered legacy tombstone cannot suppress a corrected self-healed outcome. The recovery marker is written only if the same terminal generation is still current. I also addressed the prior startup-containment observation from the earlier review: notification enqueue/marker work is isolated per record, so a read-only or corrupt owner session cannot reject TaskService.initialize() or block later records. Added regressions for both legacy-tombstone recovery and per-record I/O failure containment. Full TaskService, task_await, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including outcome-versioned and failure-contained startup recovery for corrected workspace-turn attention.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

await this.terminalAttentionStore.listPendingOwnerWorkspaceIds();

P1 Badge Contain unreadable attention directories during startup

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".

Comment thread src/node/services/taskService.ts Outdated
---

_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 -->
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed Codex thread PRRT_kwDOPxxmWM6YIbAY in 869f0386e1. All newly persisted workspace-turn terminal attention now uses the same exact handleId:status:updatedAt generation in ordinary settlement, corrected resettlement, late notify-on-terminal policy races, and startup recovery. Recovery remains backward-compatible: a legacy notification dedupes only when its outcome matches and its creation time is at/after the current terminal record; stale/different generations get a versioned notification. Added regressions proving ordinary settlement persists the versioned notification, matching legacy ordinary recovery does not double-wake, and corrected legacy recovery still bypasses the stale tombstone. Full TaskService, task_await, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including aligned outcome-versioned workspace-turn attention across ordinary settlement and recovery.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread src/node/services/taskService.ts
---

_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 -->
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed Codex thread PRRT_kwDOPxxmWM6YImA9 in d3c8246f7c. persistNotifyOnTerminalPolicy() now treats a policy-only write on an already-terminal handle as metadata, preserving updatedAt and therefore the terminal outcome generation/direct-parent delivery key. Active handles still update updatedAt normally. Added a regression that backgrounds a terminal handle, verifies its exact outcome timestamp is unchanged, and confirms attention is enqueued under that generation. Full TaskService, task_await, typecheck, and make static-check pass.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the latest head, including terminal outcome preservation across policy-only notify-on-terminal updates.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: d3c8246f7c

ℹ️ 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".

@ammario
ammario merged commit 88580ca into main Aug 11, 2026
21 of 22 checks passed
@ammario
ammario deleted the feat/persistent-subagent-experience branch August 11, 2026 15:18
ammario pushed a commit that referenced this pull request Aug 11, 2026
## 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 -->
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