Skip to content

CTO tools wiring + iOS attention -> Primary - #987

Merged
arul28 merged 2 commits into
mainfrom
ade/cto-tools-wiring-ios-attention-4e9f0c40
Jul 31, 2026
Merged

CTO tools wiring + iOS attention -> Primary#987
arul28 merged 2 commits into
mainfrom
ade/cto-tools-wiring-ios-attention-4e9f0c40

Conversation

@arul28

@arul28 arul28 commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Follow-up to #986. Three fixes, all rooted in one fact: the CTO session is pinned to the project's primary lane. It does not have a lane of its own — earlier phrasing that said "the CTO's own lane" was misleading and is corrected throughout the docs.

1. The operator tools actually execute now

createCtoOperatorTools was only ever reached by previewSessionToolNames and the prompt manifest, so the CTO was told it had a tool surface it could not call. createCtoRuntimeToolMap (gated on identityKey === "cto") now feeds all five provider transports:

Provider Transport
claude ade-cto SDK MCP server injected into opts.mcpServers
codex ade_cto namespace inside the single refreshCodexDynamicTools
cursor / droid / opencode second HTTP MCP lease on managed.ctoHttpMcpServer

Two invariants worth knowing:

  • The Claude server is injected without the orchestration lead's allowManagedMcpServersOnly lockdown. The CTO is a daily-driver chat; that lockdown would strip the user's own MCP servers.
  • Codex clears its dynamic-tool map on every refresh, so both tool sets must register in one refresher or they clobber each other. Separate namespaces keep names from colliding.

buildCtoOperatorToolDeps is shared by the preview and runtime paths so the advertised surface and the callable surface cannot drift apart again. Both leases are closed on teardown.

2. Mutating git tools no longer default their lane

resolveLaneId defaulted to the CTO's session lane — the primary lane. So gitCommit/gitPush/gitPull with laneId omitted meant write to the primary worktree, and gitUndoLastHeadChange/gitRedoLastHeadChange meant git reset --hard on it.

Split into resolveReadLaneId (7 read-only tools keep the default — inspecting primary is normal supervision) and requireMutationLaneId (11 mutating tools must name a lane). Enforced in code rather than trusting the model to have read the manifest rule, and the zod schemas now mark laneId required so the generated manifest stops implying a safe default.

3. Attention reaches iOS

The dot was desktop-only because the phone talks to the CTO over sync commands — a third transport, separate from IPC and the action domain. New cto.getAttention delegates to the same canonical getCtoAttention().

Registered in MOBILE_SYNC_OPTIONAL_REMOTE_COMMAND_ACTIONS, not the required list: requiring it would flip every already-shipped brain into limited mode. iOS gates on supportsRemoteAction and simply never lights the dot against an older brain.

Verification

  • Typecheck clean (desktop + ade-cli), lint 0 errors, swiftc -parse clean on all three changed Swift files
  • New tests: 13 for the mutating-lane guard (parameterized over every mutating tool, asserting nothing touched git), 2 proving CTO tools are registered on a live Claude session and absent on an ordinary chat, 2 for the sync command incl. "never creates a session or lane"
  • 1474/1476 desktop + 479/479 ade-cli sync. The 2 failures (passes discovered local Claude plugins, resubscribes chat listeners after reconnect) reproduce on a clean stashed tree — both pre-existing and environment-dependent

Known limitation

Registering ~80 CTO tools as always-load MCP tools adds their schemas to context on top of the prompt manifest that documents them, and CTO sessions run with ENABLE_TOOL_SEARCH=0. Not measured here; worth a look if CTO context pressure shows up.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added CTO attention status syncing between desktop and mobile.
    • iOS now shows an alert badge when CTO input is required, with accessibility support.
    • Added a remote command to retrieve CTO waiting status.
    • CTO tools are available in supported live sessions.
  • Bug Fixes
    • Mutating Git actions now require an explicit lane, while read-only checks retain safe defaults.

…reach iOS

Three follow-ups to #986, all rooted in the same fact: the CTO session is
pinned to the project's PRIMARY lane. It does not have a lane of its own.

Operator tools now execute. createCtoOperatorTools was only ever reached by
previewSessionToolNames and the prompt manifest, so the CTO was told it had a
tool surface it could not call. createCtoRuntimeToolMap now feeds all five
provider transports: an `ade-cto` SDK MCP server for Claude (deliberately
without the orchestration lead's allowManagedMcpServersOnly lockdown, which
would strip the user's own MCP servers from a daily-driver chat), the `ade_cto`
namespace inside Codex's single dynamic-tool refresher, and a second HTTP MCP
lease for Cursor/Droid/OpenCode. buildCtoOperatorToolDeps is shared by the
preview and runtime paths so the advertised and callable surfaces cannot drift.

Mutating git tools no longer default their lane. resolveLaneId defaulted to the
CTO's session lane, so an omitted laneId on gitCommit/gitPush/gitPull — or on
gitUndo/gitRedo, which run `git reset --hard` — meant writing to the primary
worktree, the exact thing lanes exist to prevent. Reads keep the default;
mutations must name a lane. Enforced in code rather than trusting the model to
have read the manifest rule.

Attention reaches iOS. The dot was desktop-only because the phone talks to the
CTO over sync commands, a third transport. cto.getAttention delegates to the
same canonical getCtoAttention() and is registered as an OPTIONAL mobile
capability — requiring it would flip every shipped brain to limited mode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 31, 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 Jul 31, 2026 11:08pm

@coderabbitai

coderabbitai Bot commented Jul 31, 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: 55 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: f89420fe-39a9-405c-81af-c6cc04d8b3d5

📥 Commits

Reviewing files that changed from the base of the PR and between ae6802e and 33a2648.

⛔ Files ignored due to path filters (4)
  • docs/features/agents/tool-registration.md is excluded by !docs/**
  • docs/features/chat/tool-system.md is excluded by !docs/**
  • docs/features/cto/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/ios-companion.md is excluded by !docs/**
📒 Files selected for processing (9)
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/headlessLinearServices.test.ts
  • apps/ade-cli/src/headlessLinearServices.ts
  • apps/desktop/src/main/services/ai/tools/ctoOperatorTools.test.ts
  • apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/ios/ADE/App/ContentView.swift
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADETests/ADETests.swift
📝 Walkthrough

Walkthrough

The change makes CTO Git mutations lane-explicit, adds separate CTO MCP runtime wiring, and introduces the cto.getAttention sync command. iOS tracks CTO attention with debounced refreshes and displays an accessibility-aware tab badge.

Changes

CTO workflows

Layer / File(s) Summary
Lane-safe Git operations
apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts, apps/desktop/src/main/services/ai/tools/ctoOperatorTools.test.ts
Git read operations use the default CTO lane. Git mutations require an explicit laneId. Tests cover rejection, explicit execution, and read defaults.
CTO MCP runtime wiring
apps/desktop/src/main/services/chat/agentChatService.ts, apps/desktop/src/main/services/chat/agentChatService.test.ts
CTO tools now have separate runtime maps, MCP leases, server configuration, Codex namespace handling, and lifecycle teardown.
CTO attention synchronization
apps/desktop/src/shared/types/sync.ts, apps/desktop/src/shared/syncMobileCompatibility.ts, apps/ade-cli/src/services/sync/*, apps/desktop/src/main/services/sync/*, apps/ios/ADE/Models/RemoteModels.swift, apps/ios/ADE/Services/SyncService.swift, apps/ios/ADE/App/ContentView.swift
The optional cto.getAttention command returns CTO waiting state. iOS refreshes this state on workspace changes, preserves failures, clears it for older hosts, and displays a tab badge.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • arul28/ADE#702: Overlaps in CTO tools, chat service wiring, and remote commands.
  • arul28/ADE#726: Shares the mobile sync compatibility and iOS sync command paths.
  • arul28/ADE#580: Shares MCP configuration and session setup changes.

Suggested labels: desktop, ios, docs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the two main changes: CTO tool wiring and iOS attention support.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/cto-tools-wiring-ios-attention-4e9f0c40

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: 2

🧹 Nitpick comments (2)
apps/desktop/src/main/services/chat/agentChatService.ts (2)

15561-15565: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename closeOrchestrationHttpMcpServer to match the new behavior.

The function now closes the orchestration lease and the CTO lease. The current name states only the orchestration lease. A future teardown path can read the name and assume the CTO lease is still open.

♻️ Proposed rename
-  /** Closes both leases. Every teardown path must drop the CTO one too. */
-  const closeOrchestrationHttpMcpServer = (managed: ManagedChatSession): void => {
+  /** Closes both leases. Every teardown path must drop the CTO one too. */
+  const closeSessionHttpMcpServers = (managed: ManagedChatSession): void => {
     closeHttpMcpServer(managed, "orchestration");
     closeHttpMcpServer(managed, "cto");
   };

Update every call site if you apply the rename.

🤖 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/desktop/src/main/services/chat/agentChatService.ts` around lines 15561 -
15565, Rename closeOrchestrationHttpMcpServer to reflect that it closes both
orchestration and CTO leases, and update every reference and call site to use
the new name consistently.

8304-8315: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Drop the as cast so the deps object stays type-checked.

The declared return type is Parameters<typeof createCtoOperatorTools>[0], so the & { previewSessionToolNames } part of the cast is erased at the call boundary and adds nothing. The as cast also suppresses type errors inside the returned object literal, including the defaultModelId and defaultReasoningEffort fields this change introduced. If previewSessionToolNames is part of the real dependency contract, declare it in the return type instead of casting.

♻️ Proposed refactor
-  }): Parameters<typeof createCtoOperatorTools>[0] => {
+  }): Parameters<typeof createCtoOperatorTools>[0] & {
+    previewSessionToolNames: typeof previewSessionToolNames;
+  } => {
         previewSessionToolNames,
-    } as Parameters<typeof createCtoOperatorTools>[0] & {
-      previewSessionToolNames: typeof previewSessionToolNames;
-    };
+    };
   };

Also applies to: 8354-8357

🤖 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/desktop/src/main/services/chat/agentChatService.ts` around lines 8304 -
8315, Remove the `as` cast from the object returned by
`buildCtoOperatorToolDeps` so it is checked against `Parameters<typeof
createCtoOperatorTools>[0]`. If `previewSessionToolNames` is required by the
actual dependency contract, add it to that contract’s type instead of asserting
it, while preserving validation of `defaultModelId` and
`defaultReasoningEffort`.
🤖 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/ai/tools/ctoOperatorTools.ts`:
- Around line 1446-1455: Update the input schemas for gitUndoLastHeadChange,
gitRedoLastHeadChange, gitRebaseContinue, gitRebaseAbort, and gitMergeAbort to
require a trimmed laneId string instead of an optional one. Keep
requireMutationLaneId() in each execute path as the runtime guard.

In `@apps/ios/ADE/Services/SyncService.swift`:
- Around line 18896-18930: Update refreshActiveSessionsAndSnapshot so
refreshCtoAttentionIfNeeded() runs before the early return taken when the roster
signature is unchanged, ensuring CTO attention refreshes without roster changes.
Add a regression test covering a CTO attention transition while the roster
signature remains unchanged.

---

Nitpick comments:
In `@apps/desktop/src/main/services/chat/agentChatService.ts`:
- Around line 15561-15565: Rename closeOrchestrationHttpMcpServer to reflect
that it closes both orchestration and CTO leases, and update every reference and
call site to use the new name consistently.
- Around line 8304-8315: Remove the `as` cast from the object returned by
`buildCtoOperatorToolDeps` so it is checked against `Parameters<typeof
createCtoOperatorTools>[0]`. If `previewSessionToolNames` is required by the
actual dependency contract, add it to that contract’s type instead of asserting
it, while preserving validation of `defaultModelId` and
`defaultReasoningEffort`.
🪄 Autofix (Beta)

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: 7df43984-561a-4578-99f3-f93b2fc8663f

📥 Commits

Reviewing files that changed from the base of the PR and between aa72548 and ae6802e.

⛔ Files ignored due to path filters (8)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/agents/tool-registration.md is excluded by !docs/**
  • docs/features/chat/agent-routing.md is excluded by !docs/**
  • docs/features/chat/tool-system.md is excluded by !docs/**
  • docs/features/cto/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/ios-companion.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/remote-commands.md is excluded by !docs/**
📒 Files selected for processing (12)
  • apps/ade-cli/src/services/sync/syncHostService.test.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/desktop/src/main/services/ai/tools/ctoOperatorTools.test.ts
  • apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/sync/syncRemoteCommandService.test.ts
  • apps/desktop/src/shared/syncMobileCompatibility.ts
  • apps/desktop/src/shared/types/sync.ts
  • apps/ios/ADE/App/ContentView.swift
  • apps/ios/ADE/Models/RemoteModels.swift
  • apps/ios/ADE/Services/SyncService.swift

Comment thread apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts Outdated
Comment thread apps/ios/ADE/Services/SyncService.swift Outdated
…ease layer

Findings from /quality and /test on this lane.

The iOS attention probe could not fire for the case it exists for.
refreshCtoAttentionIfNeeded() sat below a guard keyed on the roster signature,
and the CTO is excluded from that roster by design — so a turn where only the
CTO changed left the signature identical and the probe never ran. Once lit by
an unrelated change, nothing cleared it either. Hoisted above the guard, and
the previously-dead `force` parameter now drives the first probe after a
(re)connect, when the host's command descriptors finally arrive.

Four operator tools were still dead. steerChat, cancelSteer, listSubagents and
approveToolUse were wired to `undefined`, so they were advertised in the prompt
manifest and registered on every transport but could only answer "not
available" — the exact defect this lane set out to remove, fixed for ~75 tools
and left for these. They are now required deps, so a future caller cannot ship
them unwired. handoffChat is deleted rather than wired: it targeted "a
different agent identity", a subsystem that no longer exists.

The headless agentChatService stub was missing three of them, which would have
thrown a raw TypeError through `ade actions run chat.*` and the matching sync
commands. Same bug class this lane already hit once with getCtoAttention.

Structural: the HttpMcpToolSet union spent itself on four string-switch helpers
and a duplicated session field. Replaced with a descriptor table and a single
keyed lease record, which also collapsed the three transport call sites and the
codex namespace fallback. closeOrchestrationHttpMcpServer closed both leases
despite its name; it is closeHttpMcpServers now.

Also: five mutating git tools still advertised laneId as optional while
throwing at runtime, and two error messages named tools that do not exist;
createTerminal relied on an invisible pty clamp instead of passing dimensions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@arul28

arul28 commented Jul 31, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@arul28
arul28 merged commit 774980f into main Jul 31, 2026
3 checks passed
@arul28
arul28 deleted the ade/cto-tools-wiring-ios-attention-4e9f0c40 branch July 31, 2026 23:22
arul28 added a commit that referenced this pull request Aug 1, 2026
…e false-clear, and residue from #986/#987 -> Primary (#1005)

* Refs ADE-136: ship: checkpoint ADE-136 CTO follow-ups

* Refs ADE-136: ship: iteration 1 — address #3696709345

* Refs ADE-136: ship: iteration 2 — address #3696743285
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