Skip to content

Stop silent human demotion of subagent chats - #1082

Merged
arul28 merged 2 commits into
mainfrom
ade-138-subagent-takeover-ux-explicit-ownership-popup-demote-promote-stop-silent-peer-demotion
Aug 12, 2026
Merged

Stop silent human demotion of subagent chats#1082
arul28 merged 2 commits into
mainfrom
ade-138-subagent-takeover-ux-explicit-ownership-popup-demote-promote-stop-silent-peer-demotion

Conversation

@arul28

@arul28 arul28 commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Fixes ADE-138

Summary

  • Subagent chats keep reporting to their parent after a human messages them. Takeover is explicit: composer banner, session menu, ade chat demote/promote, TUI /session demote|promote, and iOS parity.
  • Demoting to peer posts a quiet parent note. The next subagent wake names how many human messages landed in that turn.
  • Parent re-dispatch into a peer child auto-promotes it back to a subagent without a takeover note.

Test plan

  • Spawn a subagent, send a human message in the child, confirm the parent still wakes.
  • Confirm the composer banner: Take over demotes to peer; Keep reporting hides the banner once.
  • Demote/promote from the Work session menu, CLI, and TUI.
  • Confirm a later parent dispatch into a demoted peer auto-promotes it.

Linked Linear issues

ADE   Open in ADE  ·  ade-138-subagent-takeover-ux-explicit-ownership-popup-demote-promote-stop-silent-peer-demotion branch  ·  PR #1082

Summary by CodeRabbit

  • New Features
    • Added controls to switch eligible chat sessions between subagent and peer modes.
    • Added takeover prompts with options to take over or keep reporting to the parent.
    • Added desktop and iOS context-menu actions for promoting and demoting sessions.
    • Added CLI commands: demote, promote, and keep-reporting, plus corresponding TUI commands.
  • Bug Fixes
    • Improved parent status reporting for messages sent during subagent turns.
    • Clarified mission ownership so ordinary messages are not treated as directives.

@linear-code

linear-code Bot commented Aug 12, 2026

Copy link
Copy Markdown

ADE-138

@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Aug 12, 2026 7:17pm

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@arul28, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 10 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d1755bce-70c1-49ea-b818-548de47614da

📥 Commits

Reviewing files that changed from the base of the PR and between 4c7b98b and aff9aa2.

⛔ Files ignored due to path filters (1)
  • docs/features/chat/README.md is excluded by !docs/**
📒 Files selected for processing (20)
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/services/sync/syncHostService.test.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/chat/spawnMissionOwnership.test.ts
  • apps/desktop/src/main/services/chat/spawnMissionOwnership.ts
  • apps/desktop/src/main/services/sync/syncRemoteCommandService.test.ts
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/shared/syncMobileCompatibility.ts
  • apps/desktop/src/shared/types/sync.ts
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADE/Views/Work/WorkChatSessionView.swift
  • apps/ios/ADE/Views/Work/WorkModels.swift
  • apps/ios/ADE/Views/Work/WorkRootComponents.swift
  • apps/ios/ADE/Views/Work/WorkRootScreen.swift
  • apps/ios/ADE/Views/Work/WorkSessionDestinationView+Actions.swift
  • apps/ios/ADE/Views/Work/WorkSessionDestinationView.swift
  • apps/ios/ADETests/ADETests.swift
📝 Walkthrough

Walkthrough

Changes

Subagent takeover lifecycle

Layer / File(s) Summary
Spawn metadata and action contracts
apps/desktop/src/shared/types/chat.ts, apps/desktop/src/main/services/adeActions/registry.ts, apps/ios/ADE/Models/RemoteModels.swift, apps/ios/ADE/Services/SyncService.swift
Chat types, action contracts, RPC scoping, and iOS models now carry spawn kind and takeover-prompt state.
Chat service role transitions and reporting
apps/desktop/src/main/services/chat/*
The service persists role changes, validates parent relationships, manages takeover notices, and reports human child messages according to spawn kind.
Desktop takeover and session controls
apps/desktop/src/renderer/components/chat/*, apps/desktop/src/renderer/components/terminals/*
Desktop chat panes render takeover prompts and notices. Session menus invoke demotion and promotion actions.
CLI and TUI lifecycle commands
apps/ade-cli/README.md, apps/ade-cli/src/*
CLI and TUI clients expose demote, promote, and keep-reporting commands.
iOS takeover and role controls
apps/ios/ADE/Views/Work/*
iOS views display takeover actions and expose role transitions through session menus and session updates.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

  • arul28/ADE#820 — Provides the spawn-kind and orchestration infrastructure extended by this PR.
  • arul28/ADE#861 — Also changes spawn-kind, lineage handling, and related CLI/TUI session metadata.
  • arul28/ADE#676 — Implements authorization logic related to the chat-action scoping extended here.

Suggested labels: desktop, ios, docs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preventing implicit demotion of subagent chats after human messages.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade-138-subagent-takeover-ux-explicit-ownership-popup-demote-promote-stop-silent-peer-demotion

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.

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/main/services/chat/agentChatService.ts`:
- Around line 29741-29752: Move the readTranscriptEnvelopes(child) and
mergeEnvelopeStreams call inside the parentShouldWake branch, so transcript
history is loaded only for subagent completions before
countHumanChildMessagesForTurn runs. Preserve the existing zero-count behavior
for peers and avoid any synchronous transcript read on the peer completion path.

In `@apps/ios/ADE/Views/Work/WorkSessionDestinationView.swift`:
- Around line 1583-1585: Gate role-transition callbacks and menu actions on
paired-host spawnKind update support. In
apps/ios/ADE/Views/Work/WorkSessionDestinationView.swift:1583-1585, pass each
callback only when supported; in
apps/ios/ADE/Views/Work/WorkRootComponents.swift:570-573, add the availability
input to WorkSessionListRow, and at 678-688 require it before enabling either
action. In apps/ios/ADE/Views/Work/WorkRootScreen.swift:1208-1209, derive and
pass it from the matching SyncService capability. Add regression test
testRoleTransitionActionsAreHiddenWhenSpawnKindUpdateIsUnsupported.

In `@apps/ios/ADE/Views/Work/WorkSessionDestinationView`+Actions.swift:
- Around line 419-424: Update the action handling around the existing
chat-summary update logic to build the modified summary from composerChatSummary
when chatSummary is nil, applying updated.spawnKind and
updated.subagentTakeoverPromptShownAt. Persist the result to chatSummary,
lastKnownChatSummary, and syncService.chatSummaryCache so fallback-rendered
state is updated; preserve the current path when chatSummary is present. Add
regression test
testTakeoverAndKeepReportingUpdateFallbackSummaryWhenChatSummaryIsNil.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: c9d7f85f-baca-436a-887d-d6657531ed58

📥 Commits

Reviewing files that changed from the base of the PR and between 0a81366 and 4c7b98b.

⛔ Files ignored due to path filters (3)
  • docs/features/agents/README.md is excluded by !docs/**
  • docs/features/chat/README.md is excluded by !docs/**
  • docs/logging.md is excluded by !docs/**
📒 Files selected for processing (29)
  • apps/ade-cli/README.md
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/tuiClient/__tests__/sessionLifecycle.test.tsx
  • apps/ade-cli/src/tuiClient/adeApi.ts
  • apps/ade-cli/src/tuiClient/app.tsx
  • apps/ade-cli/src/tuiClient/commands.ts
  • apps/ade-cli/src/tuiClient/sessionLifecycle.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/chat/spawnMissionOwnership.test.ts
  • apps/desktop/src/main/services/chat/spawnMissionOwnership.ts
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/chat/ChatSubagentTakeoverBanner.tsx
  • apps/desktop/src/renderer/components/terminals/SessionContextMenu.test.tsx
  • apps/desktop/src/renderer/components/terminals/SessionContextMenu.tsx
  • apps/desktop/src/renderer/components/terminals/sessionLifecycleActions.ts
  • apps/desktop/src/shared/types/chat.ts
  • apps/ios/ADE/Models/RemoteModels.swift
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADE/Views/Work/WorkChatSessionView.swift
  • apps/ios/ADE/Views/Work/WorkRootComponents.swift
  • apps/ios/ADE/Views/Work/WorkRootScreen+Actions.swift
  • apps/ios/ADE/Views/Work/WorkRootScreen.swift
  • apps/ios/ADE/Views/Work/WorkSessionDestinationView+Actions.swift
  • apps/ios/ADE/Views/Work/WorkSessionDestinationView.swift

Comment thread apps/desktop/src/main/services/chat/agentChatService.ts
Comment thread apps/ios/ADE/Views/Work/WorkSessionDestinationView.swift Outdated
Comment on lines +419 to +424
if var summary = chatSummary {
summary.spawnKind = updated.spawnKind
summary.subagentTakeoverPromptShownAt = updated.subagentTakeoverPromptShownAt
chatSummary = summary
syncService.cacheChatSummary(summary)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply the returned state when chatSummary is nil.

composerChatSummary can render the banner from lastKnownChatSummary or syncService.chatSummaryCache. If chatSummary is nil, both actions discard updated. The cached state can then remain .subagent with no prompt timestamp after a successful action.

Build the update from composerChatSummary. Update chatSummary, lastKnownChatSummary, and syncService.chatSummaryCache.

Add regression test testTakeoverAndKeepReportingUpdateFallbackSummaryWhenChatSummaryIsNil.

Also applies to: 440-445

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ios/ADE/Views/Work/WorkSessionDestinationView`+Actions.swift around
lines 419 - 424, Update the action handling around the existing chat-summary
update logic to build the modified summary from composerChatSummary when
chatSummary is nil, applying updated.spawnKind and
updated.subagentTakeoverPromptShownAt. Persist the result to chatSummary,
lastKnownChatSummary, and syncService.chatSummaryCache so fallback-rendered
state is updated; preserve the current path when chatSummary is present. Add
regression test
testTakeoverAndKeepReportingUpdateFallbackSummaryWhenChatSummaryIsNil.

arul28 and others added 2 commits August 12, 2026 15:00
Human messages no longer steal the parent report channel. Takeover is an explicit demote-to-peer action with a composer banner, session menu, CLI, TUI, and iOS parity.

Co-authored-by: Cursor <cursoragent@cursor.com>
…picker.

Phone Take over was gated on chat.setSpawnKind, which the host never advertised, and chat.updateSession dropped spawnKind. Also restore selectReasoningEffort after the takeover insert ate its header.

Co-authored-by: Cursor <cursoragent@cursor.com>
@arul28
arul28 force-pushed the ade-138-subagent-takeover-ux-explicit-ownership-popup-demote-promote-stop-silent-peer-demotion branch from 4c7b98b to aff9aa2 Compare August 12, 2026 19:17
@arul28
arul28 merged commit 775c00e into main Aug 12, 2026
36 checks passed
@arul28
arul28 deleted the ade-138-subagent-takeover-ux-explicit-ownership-popup-demote-promote-stop-silent-peer-demotion branch August 12, 2026 19:30
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.

1 participant