Skip to content

CTO revamp: one persistent-memory agent thread (desktop + iOS)#702

Merged
arul28 merged 8 commits into
mainfrom
ade/big-task-incoming-start-skill-a0ef4fe0
Jul 5, 2026
Merged

CTO revamp: one persistent-memory agent thread (desktop + iOS)#702
arul28 merged 8 commits into
mainfrom
ade/big-task-incoming-start-skill-a0ef4fe0

Conversation

@arul28

@arul28 arul28 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

What this does

Rebuilds the CTO tab around a single long-living agent thread with a smart, provider-agnostic memory system, and removes the legacy workers/hiring and Linear-workflow subsystems entirely.

Smart memory (files as truth, under .ade/cto/)

  • MEMORY.md — curated durable facts, always injected (injection capped; disk never truncated), editable in Settings, written by the CTO via new saveMemory/searchMemory/readMemory operator tools.
  • thread-state.md — rolling thread summary, flushed deterministically before compaction and before any model/provider switch (async LLM upgrade never blocks).
  • Daily journal — one line per completed turn (HH:MM — intent → outcome), no LLM.
  • Memory-rich reconstruction injected on session start, after compaction, and after model switches.

Model switching never breaks the thread

  • Same ADE session across providers; flush-before-teardown; identity modelPreferences and the live session stay in sync both directions; foreign-lane CTO sessions rebind instead of silently orphaning the transcript; dead ChatModelSwitchPolicy plumbing removed.

Legacy removed completely (code, tests, docs)

  • Worker/hiring subsystem, Linear workflow engine (dispatch/sync/ingress/intake/routing/closeout/outbound/flow-policy/templates), pipeline builder, Team/Workflows tabs, ~45 IPC channels, 17 sync commands, dead ade cto/ade flow/ade linear workflows|sync|ingress CLI + TUI surfaces.
  • Kept: Linear read/credential/OAuth plumbing used by PRs, lane cards, chat attachments, ade linear issue bridge.

UI

  • Desktop: no tabs — slim identity header (name, personality chip, live model switcher, gear), full-bleed thread, settings sheet (personality + work style, model, editable memory, prompt preview), single-card onboarding.
  • iOS: brain tab icon (matches desktop), inline single-thread tab, one-card setup, trimmed settings with a Memory section via new cto.getMemory sync command.

Validation

  • Desktop + ade-cli typecheck clean; cto suite 84 tests, agentChat 460, ade-cli 1450+, TUI 812; iOS xcodebuild BUILD SUCCEEDED; /quality dual-review (0 Blocker/High) and /test consolidation both run.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added persistent CTO memory capabilities so you can save, search, and read remembered context across sessions.
    • Enhanced CTO session continuity to retain durable memory and model preferences on reconnect.
  • Bug Fixes
    • Improved session identity handling so CTO sessions consistently reuse the correct pinned lane and state.
  • Behavior Changes
    • Updated Linear CLI/TUI surfaces to show only the currently supported commands and help text (with broader Linear workflows removed from the interface).

Greptile Summary

This PR rebuilds the CTO experience around one persistent agent thread with durable memory. The main changes are:

  • Adds .ade/cto/ memory files for durable facts, thread state, and daily turn logs.
  • Wires CTO memory into agent tools, model-switch continuity, desktop settings, and iOS settings.
  • Removes the legacy worker, hiring, Linear workflow, sync, ingress, routing, pipeline, Team, and Workflows surfaces.
  • Simplifies CLI/TUI and Linear commands to the remaining issue bridge and read/update flows.

Confidence Score: 4/5

Mostly safe to merge after fixing the bound-runtime memory bridge bug.

The core memory service and chat lifecycle wiring are coherent, and the earlier memory eviction/search issues are addressed. Confidence is limited by one contained bug where desktop memory saves and searches send the wrong payload shape through runtime bindings.

apps/desktop/src/preload/preload.ts

T-Rex T-Rex Logs

What T-Rex did

  • The focused Vitest repro against the real getAdeActionDomainServices memory registry path was executed and reproduced the failure: updateMemory threw 'updateMemory requires a string `memory` field.' and searchMemory ran with {"args":{"query":"needle","limit":7}} while the registry returned an empty `query` and used the default limit 20.
  • A repro artifact for the wrapped CTO memory payload tests and a verbose Vitest output log were captured to document inputs and results.
  • The CTO UI focused Vitest run completed with exit code 0.
  • The Playwright/Vite capture attempt for the CTO UI started but failed due to server kill/connection errors and exited with code 1.
  • A follow-up settings harness attempt timed out before DOMContentLoaded.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
apps/desktop/src/preload/preload.ts Routes CTO memory APIs through project runtime bindings, but update/search wrap arguments incorrectly and break bound-runtime memory save/search.
apps/desktop/src/main/services/cto/ctoMemoryService.ts Adds CTO memory file management, search, snapshot, and injection helpers.
apps/desktop/src/main/services/chat/agentChatService.ts Wires CTO thread-state flushing, daily turn journaling, and model preference persistence into identity chat lifecycle paths.
apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts Adds CTO operator tools for save, search, and read memory backed by the new memory service.
apps/ade-cli/src/services/sync/syncRemoteCommandService.ts Adds iOS/remote sync command support for ensuring the CTO session, reading CTO state, and fetching memory snapshots.
apps/ios/ADE/Views/Cto/CtoSettingsScreen.swift Updates iOS CTO settings to show identity, Linear status, and read-only memory/thread state via sync.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
  participant User
  participant Desktop as Desktop CTO UI
  participant Preload as preload.cto bridge
  participant Runtime as Project runtime actions
  participant Memory as ctoMemoryService
  participant Chat as CTO agent thread
  participant iOS as iOS Sync client

  User->>Desktop: Edit/read CTO settings
  Desktop->>Preload: getMemory/updateMemory/searchMemory
  Preload->>Runtime: cto_memory action when bound
  Runtime->>Memory: getSnapshot/writeMemory/searchMemory
  Memory-->>Runtime: snapshot/search rows
  Runtime-->>Preload: result
  Preload-->>Desktop: memory state

  Chat->>Memory: writeThreadState before compaction/model switch
  Chat->>Memory: appendTurnJournal after completed turn
  iOS->>Runtime: cto.getMemory
  Runtime->>Memory: getSnapshot
  Memory-->>iOS: CtoMemory snapshot
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
  participant User
  participant Desktop as Desktop CTO UI
  participant Preload as preload.cto bridge
  participant Runtime as Project runtime actions
  participant Memory as ctoMemoryService
  participant Chat as CTO agent thread
  participant iOS as iOS Sync client

  User->>Desktop: Edit/read CTO settings
  Desktop->>Preload: getMemory/updateMemory/searchMemory
  Preload->>Runtime: cto_memory action when bound
  Runtime->>Memory: getSnapshot/writeMemory/searchMemory
  Memory-->>Runtime: snapshot/search rows
  Runtime-->>Preload: result
  Preload-->>Desktop: memory state

  Chat->>Memory: writeThreadState before compaction/model switch
  Chat->>Memory: appendTurnJournal after completed turn
  iOS->>Runtime: cto.getMemory
  Runtime->>Memory: getSnapshot
  Memory-->>iOS: CtoMemory snapshot
Loading

Comments Outside Diff (1)

  1. apps/desktop/src/main/services/chat/agentChatService.ts, line 7643-7670 (link)

    P1 Memory never injected
    ctoMemoryService.buildMemoryContextSections() is not used when rebuilding pendingReconstructionContext, so facts saved through saveMemory or Settings are persisted but not included after session start, compaction, or provider reset. The only CTO-specific context added here is identity, state reconstruction, continuity summary, and transcript tail; durable MEMORY.md is omitted unless the model explicitly calls readMemory.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/chat/agentChatService.ts
    Line: 7643-7670
    
    Comment:
    **Memory never injected**
    `ctoMemoryService.buildMemoryContextSections()` is not used when rebuilding `pendingReconstructionContext`, so facts saved through `saveMemory` or Settings are persisted but not included after session start, compaction, or provider reset. The only CTO-specific context added here is identity, state reconstruction, continuity summary, and transcript tail; durable `MEMORY.md` is omitted unless the model explicitly calls `readMemory`.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/desktop/src/preload/preload.ts:8221-8227
**Memory payload wrapped**
`callProjectRuntimeActionOr` sends its request fields as the `run_ade_action` payload, so passing `{ args }` invokes `cto_memory.updateMemory` with `{ args: { memory } }` instead of `{ memory }`. The registry rejects saves with `updateMemory requires a string memory field`, and `searchMemory` searches an empty query for bound runtimes. Pass the memory/search fields directly in `args`.

Reviews (6): Last reviewed commit: "ship: search archive ahead of transient ..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

arul28 and others added 3 commits July 4, 2026 23:13
… workers/workflows removed

Desktop + iOS CTO tab redesigned around a single long-living agent thread:

- Smart memory (files-as-truth under .ade/cto/): curated MEMORY.md (always
  injected, cap-truncated only in injection), rolling thread-state.md flushed
  deterministically before compaction and model switches (async LLM upgrade),
  turn-end daily-log journal, saveMemory/searchMemory/readMemory operator
  tools, memory-rich reconstruction injection on start/compaction/switch.
- Model switching never breaks the thread: same ADE session across providers,
  flush-before-teardown, identity modelPreferences synced both ways, foreign-
  lane CTO sessions rebind instead of orphaning; dead model-switch policy
  removed.
- Legacy removed completely (incl. tests/docs): worker/hiring subsystem,
  Linear workflow engine (dispatch/sync/ingress/intake/routing/closeout/
  outbound/flow-policy/templates), pipeline builder, Team/Workflows surfaces,
  ~45 dead IPC channels + 17 sync commands, dead `ade flow`/`ade cto` CLI.
  Kept Linear read/credential plumbing used by PRs, lane cards, chat
  attachments, and `ade linear`.
- New desktop UI: no tabs — slim identity header + full-bleed thread +
  settings sheet (personality, work style, live model switch, editable
  memory panel, prompt preview); single-card onboarding.
- iOS parity: brain tab icon matching desktop, inline single-thread tab,
  one-card setup (personality + work style), trimmed settings with memory
  section via new cto.getMemory sync command.
- Docs rewritten: cto/README, linear-integration canonicalized, all worker/
  workflow cross-references, public Mintlify pages + nav.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…iOS work-style parity

- ctoMemoryService owns the turn-journal line format (appendTurnJournal) using
  shared clipText; removed the test-only _localHourMinute export and the
  duplicate clip helper in agentChatService; trimmed unused service exports.
- iOS CtoSetup: verbosity segmented order matches desktop (concise/adaptive/
  detailed); preset descriptions mirror shared CTO_PERSONALITY_PRESETS verbatim.
- Removed stale recentSubordinateActivity field from adeRpcServer test mock.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ocs parity drift

- Consolidated cto/ suite: linearTokenRefresh tests folded into linearAuth
  (helper-of-parent), linearLiveStatusService tests folded into
  linearLaneCardService (Linear PR-reflection contract); 6 → 4 test files,
  all 84 cases green.
- Added appendTurnJournal contract test (format, caps, blank-turn no-op).
- TUI: removed dead /linear workflows|run|route|sync|ingress slash groups that
  pointed at deleted daemon tools; usage strings updated; tests replaced.
- CLI: help text no longer advertises removed `ade cto` / linear workflow
  subcommands; stale routing comment fixed.
- Docs: restored Source file map to linear-integration README; fixed 3 stale
  ARCHITECTURE.md tree comments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 5, 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 5, 2026 5:58am

@arul28 arul28 changed the title Big Task Incoming Start Skill CTO revamp: one persistent-memory agent thread (desktop + iOS) Jul 5, 2026
@arul28

arul28 commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds durable CTO memory storage and threads it through CTO state, tools, chat, IPC, and runtime wiring. Removes worker-agent and Linear workflow/dispatcher/sync/ingress services, plus related CLI, RPC, and test surface updates.

Changes

CTO Memory + Worker/Linear Pipeline Removal

Layer / File(s) Summary
CtoMemoryService implementation and tests
apps/desktop/src/main/services/cto/ctoMemoryService.ts, apps/desktop/src/main/services/cto/ctoMemoryService.test.ts
New file-backed service persists facts, thread state, daily logs, search, snapshot, and context sections under CTO storage paths, with a dedicated test suite.
CtoStateService memory integration and subordinate-activity removal
apps/desktop/src/main/services/cto/ctoStateService.ts, apps/desktop/src/main/services/cto/ctoState.test.ts, apps/desktop/src/main/services/cto/ctoPromptContent.ts
Adds optional memory injection to reconstruction and prompt preview, and removes subordinate-activity tracking, persistence, and test coverage.
CtoOperatorTools memory tools and surface trimming
apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts, apps/desktop/src/main/services/ai/tools/ctoOperatorTools.test.ts
Adds save/search/read memory tools and removes worker, Linear workflow/routing, and budget-related tools and tests.
agentChatService CTO continuity, journaling, and identity pinning
apps/desktop/src/main/services/chat/agentChatService.ts, apps/desktop/src/main/services/chat/agentChatService.test.ts, apps/desktop/src/main/services/chat/identitySessionPolicy.ts, apps/desktop/src/main/services/chat/identitySessionPolicy.test.ts
Wires CTO memory into chat runtime, adds continuity/journal persistence, reuses and rebinds CTO sessions across lanes, and narrows identity pinning to "cto".
adeActions registry domain catalog and ensureCtoSession
apps/desktop/src/main/services/adeActions/registry.ts, apps/desktop/src/main/services/adeActions/registry.test.ts
Updates action domains and allowlists to add CTO memory/session support and remove worker_agent plus Linear routing/dispatch/sync/ingress domains.
IPC registration for CTO memory endpoints
apps/desktop/src/main/services/ipc/registerIpc.ts
Adds CTO memory IPC endpoints and AppContext.ctoMemoryService, and removes older worker/Linear IPC wiring.
Desktop and CLI runtime bootstrap wiring
apps/desktop/src/main/main.ts, apps/ade-cli/src/bootstrap.ts, apps/desktop/src/main/services/projects/adeProjectService.ts, apps/desktop/src/main/services/lanes/laneService.ts
Constructs and wires CTO memory into runtime services, removes worker service initialization and Linear pipeline lifecycle, and updates project/lane cleanup dependencies.
ade-cli sync services and remote CTO memory command
apps/ade-cli/src/services/sync/*
Drops worker/flow-policy/Linear sync dependencies, adds CTO memory, and exposes cto.getMemory through sync remote commands.
adeRpcServer tool catalog and tests
apps/ade-cli/src/adeRpcServer.ts, apps/ade-cli/src/adeRpcServer.test.ts
Adds CTO memory tool specs and read-only classification, removes Linear workflow/sync/flow-policy/routing tools, and updates runtime mocks and action lists.
ade-cli CLI/TUI and headless service pruning
apps/ade-cli/src/cli.ts, apps/ade-cli/src/tuiClient/*, apps/ade-cli/src/headlessLinearServices.ts, apps/ade-cli/src/cli.test.ts, apps/ade-cli/src/tuiClient/__tests__/commands.test.ts, apps/ade-cli/src/headlessLinearServices.test.ts
Prunes CTO/Linear workflow, route, sync, and ingress help/commands and headless service wiring, and updates matching tests.
Automation worker-heartbeat removal and Linear live-status/token-refresh tests
apps/desktop/src/main/services/automations/automationService.ts, apps/desktop/src/main/services/cto/linearAuth.test.ts, apps/desktop/src/main/services/cto/linearLaneCardService.test.ts
Removes worker heartbeat status syncing from automations and adds Linear token-refresh and live-status coverage.
Estimated code review effort: 5 (Critical) ~120 minutes

Possibly related PRs

  • arul28/ADE#80: Both touch the agentChatService chat-event pipeline and its handling of turn output.
  • arul28/ADE#88: Both modify ctoOperatorTools dependency wiring and tool surface.
  • arul28/ADE#179: Both change CTO identity pinning and lane/session behavior.
  • arul28/ADE#274: Both affect the ADE RPC Linear issue/tool surface.
  • arul28/ADE#276: Both update CLI command dispatch and help text.
  • arul28/ADE#395: Both alter the headless Linear credential/service wiring.

Suggested labels: desktop

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: a CTO revamp centered on a persistent-memory agent thread across desktop and iOS.
✨ 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/big-task-incoming-start-skill-a0ef4fe0

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts (1)

1620-1638: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Pass ctoStateService into the ADE RPC tool bridge

createCtoOperatorTools already accepts ctoStateService, and getRecentEvents uses it for cto_session entries, but apps/ade-cli/src/adeRpcServer.ts:2355-2367 only passes ctoMemoryService. Add ctoStateService: runtime.ctoStateService.

🤖 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/ai/tools/ctoOperatorTools.ts` around lines
1620 - 1638, `getRecentEvents` in `createCtoOperatorTools` already reads from
`deps.ctoStateService`, but the ADE RPC bridge is only wiring
`ctoMemoryService`, so `cto_session` events are missing. Update the
`createCtoOperatorTools` call in the ADE RPC server to pass `ctoStateService`
from runtime alongside the existing deps, matching the `deps.ctoStateService`
usage in the session log collection block.

Source: Coding guidelines

🧹 Nitpick comments (2)
apps/ade-cli/src/adeRpcServer.ts (1)

2690-2692: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Stale name: CTO_LINEAR_SYNC_TOOL_SPECS no longer holds sync tools.

Per the line-range change details, the sync/queue/ingress/flow-policy/routing tools were removed from this array, and it now appears to hold issue-query tools like getLinearIssuePickerData/searchLinearIssues/getLinearIssueComments (per the test file's expectations). The _SYNC_ name is now misleading for future readers.

♻️ Suggested rename
-const CTO_LINEAR_SYNC_TOOL_SPECS = [...]
+const CTO_LINEAR_ISSUE_TOOL_SPECS = [...]

(and update the reference at this call site accordingly)

🤖 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/ade-cli/src/adeRpcServer.ts` around lines 2690 - 2692,
`CTO_LINEAR_SYNC_TOOL_SPECS` is now a misleading name because it no longer
contains sync/queue/ingress/flow-policy/routing tools and instead groups Linear
issue-query tools like `getLinearIssuePickerData`, `searchLinearIssues`, and
`getLinearIssueComments`. Rename the constant to something that reflects its
current contents, and update the `allVisibleTools` assembly in `adeRpcServer` to
use the new symbol so the CTO tool list remains clear and accurate.
apps/desktop/src/main/services/chat/agentChatService.test.ts (1)

4239-4293: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Ensure db.close() runs even if assertions fail.

Both new tests open a real on-disk KV db (with migrations) via createCtoServices() and only call db.close() as the final line. If an expect(...) earlier in the test throws, the db handle is never closed, leaking the sqlite connection/file for the rest of the run. Wrap the body in try { ... } finally { db.close(); }, or move the close into an afterEach keyed off a per-test db reference.

♻️ Suggested cleanup pattern
     it("persists a CTO model switch back into identity model preferences (D3)", async () => {
       const { db, ctoStateService, ctoMemoryService } = await createCtoServices();
-      const { service } = createService({ ctoStateService, ctoMemoryService });
-
-      const session = await service.ensureIdentitySession({
-        identityKey: "cto",
-        laneId: "lane-1",
-      });
-
-      await service.updateSession({
-        sessionId: session.id,
-        modelId: "opencode/openai/gpt-5.2",
-      });
-
-      const prefs = ctoStateService.getIdentity().modelPreferences;
-      expect(prefs.modelId).toBe("opencode/openai/gpt-5.2");
-      expect(prefs.provider).toBe("opencode");
-
-      db.close();
+      try {
+        const { service } = createService({ ctoStateService, ctoMemoryService });
+        const session = await service.ensureIdentitySession({
+          identityKey: "cto",
+          laneId: "lane-1",
+        });
+        await service.updateSession({
+          sessionId: session.id,
+          modelId: "opencode/openai/gpt-5.2",
+        });
+        const prefs = ctoStateService.getIdentity().modelPreferences;
+        expect(prefs.modelId).toBe("opencode/openai/gpt-5.2");
+        expect(prefs.provider).toBe("opencode");
+      } finally {
+        db.close();
+      }
     });
🤖 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.test.ts` around lines
4239 - 4293, The two CTO memory tests leak the real KV db handle if an assertion
fails because `db.close()` is only called at the end of each `it` block. Update
both tests in `agentChatService.test.ts` to ensure cleanup always runs by
wrapping the test body in `try/finally` with `db.close()` in the `finally`, or
by moving the cleanup into an `afterEach` tied to the `createCtoServices()` db
reference. Keep the existing assertions around `createCtoServices`,
`ensureIdentitySession`, `updateSession`, and `buildReconstructionContext`, but
make the db teardown unconditional.
🤖 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/ade-cli/src/bootstrap.ts`:
- Around line 1190-1192: The headless ADE bootstrap is not forwarding Linear
credentials into the sync runtime, so CTO Linear status checks can miss stored
tokens. Update the headless service wiring in bootstrap.ts where the sync
runtime is assembled to pass headlessLinearServices.linearCredentialService
alongside getLinearIssueTracker, matching the
createSyncService/createSyncRemoteCommandService path. Verify the CTO Linear
status flow (cto.getLinearConnectionStatus and quick view) uses the same
credential source in both headless mode and the desktop socket-backed ADE RPC
path.

In `@apps/ade-cli/src/cli.ts`:
- Around line 9766-9769: Update the fallback error message in buildLinearPlan so
it matches the वास्तविक supported linear subcommands. In the CliUsageError
thrown for unknown subcommands, remove the unsupported `projects` entry and add
the implemented commands currently missing from the list, especially
`picker-data`/`picker` and `search-issues`/`search`. Keep the message aligned
with the actual branches in buildLinearPlan so users are only advertised
commands handled by the `sub` switch logic.

In `@apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts`:
- Around line 1993-2000: The `saveMemory` flow in `ctoOperatorTools.ts`
currently writes any fact through `deps.ctoMemoryService.appendMemoryFact`,
which can leak credentials into `MEMORY.md`. Add a secret-detection guard in the
`execute` path before calling `appendMemoryFact`, and reject/return an error
when the input looks like credentials or other secrets. Keep the check close to
the `saveMemory` tool implementation so plaintext memory writes are blocked
unless the fact is clearly non-sensitive.
- Around line 2034-2040: The readMemory tool is omitting daily log data even
though ctoMemoryService.getSnapshot() returns it. Update the readMemory response
to include dailyLog and dailyLogDate alongside memory, threadState, and
updatedAt so the tool can read the recent daily memory stream. Use the
getSnapshot() call in ctoOperatorTools to locate the return shape and preserve
the existing fields while adding the missing ones.

In `@apps/desktop/src/main/services/cto/ctoMemoryService.ts`:
- Around line 98-199: Add a secret-detection guard before any CTO memory write
in ctoMemoryService so sensitive content is not persisted to `.ade/cto/*.md`.
Update the write paths used by writeMemory, appendMemoryFact, writeThreadState,
appendDailyEntry, and appendTurnJournal to reject or reroute content containing
API keys, tokens, passwords, or private keys, using the existing encrypted
secret store instead of plaintext files. Keep the check close to the file-write
boundary so all callers are covered consistently.
- Around line 150-157: The trimming logic in ctoMemoryService’s saveMemory flow
only removes older entries while facts.length > 1, so a single oversized fact
can still exceed MEMORY_FILE_MAX_BYTES. Update the render/write path to handle
the one-fact case explicitly: if the newest fact alone is too large, either clip
that fact’s content or reject it before calling writeTextAtomic. Keep the
existing byte-cap loop, but add the single-fact fallback around render(facts) so
MEMORY.md always stays within the limit.

In `@apps/desktop/src/main/services/cto/ctoStateService.ts`:
- Around line 131-132: Add an explicit no-secrets rule to the persistent-memory
guidance in ctoStateService so the instructions for
saveMemory/searchMemory/readMemory clearly forbid storing API keys, tokens,
passwords, private keys, or other credentials in plaintext project files. Update
the guidance text near the existing durable-facts bullets to state that secrets
must not be saved to `.ade/cto/` and should use the encrypted store instead,
keeping the wording concise and consistent with the surrounding ctoStateService
memory policy.

---

Outside diff comments:
In `@apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts`:
- Around line 1620-1638: `getRecentEvents` in `createCtoOperatorTools` already
reads from `deps.ctoStateService`, but the ADE RPC bridge is only wiring
`ctoMemoryService`, so `cto_session` events are missing. Update the
`createCtoOperatorTools` call in the ADE RPC server to pass `ctoStateService`
from runtime alongside the existing deps, matching the `deps.ctoStateService`
usage in the session log collection block.

---

Nitpick comments:
In `@apps/ade-cli/src/adeRpcServer.ts`:
- Around line 2690-2692: `CTO_LINEAR_SYNC_TOOL_SPECS` is now a misleading name
because it no longer contains sync/queue/ingress/flow-policy/routing tools and
instead groups Linear issue-query tools like `getLinearIssuePickerData`,
`searchLinearIssues`, and `getLinearIssueComments`. Rename the constant to
something that reflects its current contents, and update the `allVisibleTools`
assembly in `adeRpcServer` to use the new symbol so the CTO tool list remains
clear and accurate.

In `@apps/desktop/src/main/services/chat/agentChatService.test.ts`:
- Around line 4239-4293: The two CTO memory tests leak the real KV db handle if
an assertion fails because `db.close()` is only called at the end of each `it`
block. Update both tests in `agentChatService.test.ts` to ensure cleanup always
runs by wrapping the test body in `try/finally` with `db.close()` in the
`finally`, or by moving the cleanup into an `afterEach` tied to the
`createCtoServices()` db reference. Keep the existing assertions around
`createCtoServices`, `ensureIdentitySession`, `updateSession`, and
`buildReconstructionContext`, but make the db teardown unconditional.
🪄 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

Run ID: 5d4d447c-c2f8-4d24-ab83-acdb232b5390

📥 Commits

Reviewing files that changed from the base of the PR and between 5a6b823 and 5ceeabb.

⛔ Files ignored due to path filters (33)
  • apps/ios/ADE.xcodeproj/project.pbxproj is excluded by !**/*.xcodeproj/project.pbxproj
  • docs.json is excluded by !docs.json
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/PRD.md is excluded by !docs/**
  • docs/README.md is excluded by !docs/**
  • docs/features/agents/README.md is excluded by !docs/**
  • docs/features/agents/identity-and-personas.md is excluded by !docs/**
  • docs/features/agents/tool-registration.md is excluded by !docs/**
  • docs/features/automations/README.md is excluded by !docs/**
  • docs/features/automations/guardrails.md is excluded by !docs/**
  • docs/features/automations/triggers-and-actions.md is excluded by !docs/**
  • docs/features/chat/README.md is excluded by !docs/**
  • docs/features/chat/agent-routing.md is excluded by !docs/**
  • docs/features/chat/composer-and-ui.md is excluded by !docs/**
  • docs/features/chat/tool-system.md is excluded by !docs/**
  • docs/features/computer-use/README.md is excluded by !docs/**
  • docs/features/computer-use/artifact-broker.md is excluded by !docs/**
  • docs/features/cto/README.md is excluded by !docs/**
  • docs/features/cto/linear-integration.md is excluded by !docs/**
  • docs/features/cto/onboarding.md is excluded by !docs/**
  • docs/features/cto/pipeline-builder.md is excluded by !docs/**
  • docs/features/cto/workers.md is excluded by !docs/**
  • docs/features/history/README.md is excluded by !docs/**
  • docs/features/history/recording-and-export.md is excluded by !docs/**
  • docs/features/linear-integration/README.md is excluded by !docs/**
  • docs/features/linear-integration/dispatch-and-sync.md is excluded by !docs/**
  • docs/features/linear-integration/workflow-presets.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/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/**
  • key-concepts.mdx is excluded by !*.mdx
  • welcome.mdx is excluded by !*.mdx
📒 Files selected for processing (137)
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/headlessLinearServices.test.ts
  • apps/ade-cli/src/headlessLinearServices.ts
  • apps/ade-cli/src/services/sync/syncHostService.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/ade-cli/src/services/sync/syncService.ts
  • apps/ade-cli/src/tuiClient/__tests__/commands.test.ts
  • apps/ade-cli/src/tuiClient/commands.ts
  • apps/ade-cli/src/tuiClient/linearCommands.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/adeActions/registry.test.ts
  • apps/desktop/src/main/services/adeActions/registry.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/automations/automationService.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/chat/identitySessionPolicy.test.ts
  • apps/desktop/src/main/services/chat/identitySessionPolicy.ts
  • apps/desktop/src/main/services/cto/ctoMemoryService.test.ts
  • apps/desktop/src/main/services/cto/ctoMemoryService.ts
  • apps/desktop/src/main/services/cto/ctoPromptContent.ts
  • apps/desktop/src/main/services/cto/ctoState.test.ts
  • apps/desktop/src/main/services/cto/ctoStateService.ts
  • apps/desktop/src/main/services/cto/ctoWorkerLifecycle.test.ts
  • apps/desktop/src/main/services/cto/flowPolicyService.ts
  • apps/desktop/src/main/services/cto/linearAuth.test.ts
  • apps/desktop/src/main/services/cto/linearCloseoutService.ts
  • apps/desktop/src/main/services/cto/linearDispatcherRunStore.ts
  • apps/desktop/src/main/services/cto/linearDispatcherService.ts
  • apps/desktop/src/main/services/cto/linearIngressService.ts
  • apps/desktop/src/main/services/cto/linearIntake.test.ts
  • apps/desktop/src/main/services/cto/linearIntakeService.ts
  • apps/desktop/src/main/services/cto/linearLaneCardService.test.ts
  • apps/desktop/src/main/services/cto/linearLiveStatusService.test.ts
  • apps/desktop/src/main/services/cto/linearOutboundService.ts
  • apps/desktop/src/main/services/cto/linearRoutingService.ts
  • apps/desktop/src/main/services/cto/linearSync.test.ts
  • apps/desktop/src/main/services/cto/linearSyncService.ts
  • apps/desktop/src/main/services/cto/linearTemplateService.ts
  • apps/desktop/src/main/services/cto/linearTokenRefresh.test.ts
  • apps/desktop/src/main/services/cto/linearWorkflowFileService.ts
  • apps/desktop/src/main/services/cto/workerAdapterRuntimeService.ts
  • apps/desktop/src/main/services/cto/workerAgentService.ts
  • apps/desktop/src/main/services/cto/workerBudgetService.ts
  • apps/desktop/src/main/services/cto/workerHeartbeatService.ts
  • apps/desktop/src/main/services/cto/workerRevisionService.ts
  • apps/desktop/src/main/services/cto/workerTaskSessionService.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/lanes/laneService.ts
  • apps/desktop/src/main/services/projects/adeProjectService.ts
  • apps/desktop/src/main/services/sync/syncRemoteCommandService.test.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.test.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/app/AppShell.tsx
  • apps/desktop/src/renderer/components/app/TabNav.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/cto/AgentSidebar.tsx
  • apps/desktop/src/renderer/components/cto/CtoMemoryPanel.tsx
  • apps/desktop/src/renderer/components/cto/CtoOnboardingCard.tsx
  • apps/desktop/src/renderer/components/cto/CtoPage.tsx
  • apps/desktop/src/renderer/components/cto/CtoSettingsPanel.tsx
  • apps/desktop/src/renderer/components/cto/IdentityEditor.tsx
  • apps/desktop/src/renderer/components/cto/LinearSyncPanel.tsx
  • apps/desktop/src/renderer/components/cto/OnboardingBanner.tsx
  • apps/desktop/src/renderer/components/cto/OnboardingWizard.tsx
  • apps/desktop/src/renderer/components/cto/Segmented.tsx
  • apps/desktop/src/renderer/components/cto/TeamPanel.tsx
  • apps/desktop/src/renderer/components/cto/WorkerActivityFeed.tsx
  • apps/desktop/src/renderer/components/cto/WorkerCreationWizard.tsx
  • apps/desktop/src/renderer/components/cto/ctoUi.test.tsx
  • apps/desktop/src/renderer/components/cto/personalityTheme.ts
  • apps/desktop/src/renderer/components/cto/pipeline/CloseoutCard.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/OperationsSidebar.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/PipelineCanvas.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/PipelineVisualization.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/StageCard.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/StageConfigPanel.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/StageConnector.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/TriggerCard.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/WorkflowListSidebar.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/AdvancedConfig.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/CloseoutConfig.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/ExecutionConfig.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/PlanConfig.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/TriggerConfig.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/pipeline.test.ts
  • apps/desktop/src/renderer/components/cto/pipeline/pipelineHelpers.ts
  • apps/desktop/src/renderer/components/cto/pipeline/pipelineLabels.ts
  • apps/desktop/src/renderer/components/cto/pipeline/shared/VisualSelector.tsx
  • apps/desktop/src/renderer/components/cto/shared/AgentStatusBadge.tsx
  • apps/desktop/src/renderer/components/cto/shared/ConnectionStatusDot.tsx
  • apps/desktop/src/renderer/components/cto/shared/designTokens.ts
  • apps/desktop/src/renderer/components/cto/useCtoModelOptions.ts
  • apps/desktop/src/renderer/components/history/eventTaxonomy.ts
  • apps/desktop/src/renderer/components/history/historyActivitySources.test.ts
  • apps/desktop/src/renderer/components/history/historyActivitySources.ts
  • apps/desktop/src/shared/chatModelSwitching.test.ts
  • apps/desktop/src/shared/chatModelSwitching.ts
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/linearWorkflowPresets.test.ts
  • apps/desktop/src/shared/linearWorkflowPresets.ts
  • apps/desktop/src/shared/types/agents.ts
  • apps/desktop/src/shared/types/chat.ts
  • apps/desktop/src/shared/types/cto.ts
  • apps/desktop/src/shared/types/index.ts
  • apps/desktop/src/shared/types/linearSync.ts
  • apps/desktop/src/shared/types/sync.ts
  • apps/desktop/src/shared/workerRuntimeNoise.ts
  • apps/ios/ADE/App/ContentView.swift
  • apps/ios/ADE/Models/RemoteModels.swift
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADE/Views/Cto/CtoIdentityEditor.swift
  • apps/ios/ADE/Views/Cto/CtoRootScreen.swift
  • apps/ios/ADE/Views/Cto/CtoSessionDestinationView.swift
  • apps/ios/ADE/Views/Cto/CtoSettingsScreen.swift
  • apps/ios/ADE/Views/Cto/CtoSetup.swift
  • apps/ios/ADE/Views/Cto/CtoSharedHelpers.swift
  • apps/ios/ADE/Views/Cto/CtoTabShell.swift
  • apps/ios/ADE/Views/Cto/CtoTeamScreen.swift
  • apps/ios/ADE/Views/Cto/CtoWorkerDetailScreen.swift
  • apps/ios/ADE/Views/Cto/CtoWorkflowsScreen.swift
  • apps/ios/ADETests/ADETests.swift
  • chat/capabilities.mdx
  • cto/overview.mdx
  • cto/setup.mdx
  • cto/workers.mdx
  • integrations/linear.mdx
  • tools/automations.mdx
  • tools/history.mdx
💤 Files with no reviewable changes (29)
  • apps/desktop/src/main/services/cto/linearLiveStatusService.test.ts
  • apps/desktop/src/main/services/cto/flowPolicyService.ts
  • apps/desktop/src/main/services/cto/linearTokenRefresh.test.ts
  • apps/desktop/src/main/services/cto/linearDispatcherService.ts
  • apps/desktop/src/main/services/cto/linearRoutingService.ts
  • apps/desktop/src/main/services/cto/linearOutboundService.ts
  • apps/desktop/src/main/services/cto/linearIntakeService.ts
  • apps/desktop/src/main/services/cto/workerRevisionService.ts
  • apps/desktop/src/main/services/cto/linearIngressService.ts
  • apps/desktop/src/main/services/cto/linearWorkflowFileService.ts
  • apps/desktop/src/main/services/cto/linearSyncService.ts
  • apps/desktop/src/main/services/cto/workerAgentService.ts
  • apps/desktop/src/main/services/cto/linearIntake.test.ts
  • apps/desktop/src/main/services/cto/workerTaskSessionService.ts
  • apps/desktop/src/main/services/cto/linearDispatcherRunStore.ts
  • apps/desktop/src/main/services/cto/workerAdapterRuntimeService.ts
  • apps/desktop/src/main/services/cto/linearTemplateService.ts
  • apps/desktop/src/main/services/cto/ctoWorkerLifecycle.test.ts
  • apps/desktop/src/main/services/cto/workerBudgetService.ts
  • apps/desktop/src/main/services/cto/ctoPromptContent.ts
  • apps/desktop/src/main/services/cto/workerHeartbeatService.ts
  • apps/desktop/src/main/services/lanes/laneService.ts
  • apps/desktop/src/main/services/cto/linearCloseoutService.ts
  • apps/desktop/src/main/services/projects/adeProjectService.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/headlessLinearServices.test.ts
  • apps/desktop/src/main/services/automations/automationService.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/ade-cli/src/headlessLinearServices.ts

Comment thread apps/ade-cli/src/bootstrap.ts
Comment thread apps/ade-cli/src/cli.ts
Comment on lines +1993 to +2000
inputSchema: z.object({
fact: z.string().trim().min(1).describe("A single durable fact to remember."),
}),
execute: async ({ fact }) => {
if (!deps.ctoMemoryService) return { success: false, error: "Memory service is not available." };
try {
const result = deps.ctoMemoryService.appendMemoryFact(fact);
return { success: true, saved: result.saved, fact: result.fact, file: "MEMORY.md" };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reject secrets before writing to plaintext memory.

saveMemory persists arbitrary facts into MEMORY.md; add a guard so credentials are not stored outside the encrypted secret store.

Suggested patch
     execute: async ({ fact }) => {
       if (!deps.ctoMemoryService) return { success: false, error: "Memory service is not available." };
       try {
+        if (/\b(api[_ -]?key|access[_ -]?token|password|secret|private key|credential)\b/i.test(fact)) {
+          return {
+            success: false,
+            error: "Do not store secrets in persistent memory; use ADE's encrypted secret storage instead.",
+          };
+        }
         const result = deps.ctoMemoryService.appendMemoryFact(fact);
         return { success: true, saved: result.saved, fact: result.fact, file: "MEMORY.md" };

As per coding guidelines, "**: Do not store secrets in plaintext project files when an encrypted store already exists".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
inputSchema: z.object({
fact: z.string().trim().min(1).describe("A single durable fact to remember."),
}),
execute: async ({ fact }) => {
if (!deps.ctoMemoryService) return { success: false, error: "Memory service is not available." };
try {
const result = deps.ctoMemoryService.appendMemoryFact(fact);
return { success: true, saved: result.saved, fact: result.fact, file: "MEMORY.md" };
inputSchema: z.object({
fact: z.string().trim().min(1).describe("A single durable fact to remember."),
}),
execute: async ({ fact }) => {
if (!deps.ctoMemoryService) return { success: false, error: "Memory service is not available." };
try {
if (/\b(api[_ -]?key|access[_ -]?token|password|secret|private key|credential)\b/i.test(fact)) {
return {
success: false,
error: "Do not store secrets in persistent memory; use ADE's encrypted secret storage instead.",
};
}
const result = deps.ctoMemoryService.appendMemoryFact(fact);
return { success: true, saved: result.saved, fact: result.fact, file: "MEMORY.md" };
🤖 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/ai/tools/ctoOperatorTools.ts` around lines
1993 - 2000, The `saveMemory` flow in `ctoOperatorTools.ts` currently writes any
fact through `deps.ctoMemoryService.appendMemoryFact`, which can leak
credentials into `MEMORY.md`. Add a secret-detection guard in the `execute` path
before calling `appendMemoryFact`, and reject/return an error when the input
looks like credentials or other secrets. Keep the check close to the
`saveMemory` tool implementation so plaintext memory writes are blocked unless
the fact is clearly non-sensitive.

Source: Coding guidelines

Comment thread apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts
Comment thread apps/desktop/src/main/services/cto/ctoMemoryService.ts
Comment thread apps/desktop/src/main/services/cto/ctoMemoryService.ts Outdated
Comment thread apps/desktop/src/main/services/cto/ctoStateService.ts
- Merge origin/main (conflict in ios-companion.md resolved: main's newer
  Work/PRs rows + this branch's CTO row).
- Secret hygiene for CTO memory: redactSecrets applied at every
  ctoMemoryService write path (writeMemory/appendMemoryFact/writeThreadState/
  appendDailyEntry, covering appendTurnJournal); single facts clipped to 2000
  chars so one oversized saveMemory cannot evict the whole file; memory
  guidance prompt now forbids storing secrets; regression test added.
- readMemory tool returns dailyLog/dailyLogDate alongside memory/thread state.
- Headless sync runtime forwards linearCredentialService so
  cto.getLinearConnectionStatus reports stored credentials on remote hosts.
- `ade linear` unknown-subcommand error lists the real supported subcommands.
- Fix duplicate type import from the test consolidation.

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

arul28 commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: 3e16fdaefe

ℹ️ 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 on lines +8217 to +8221
getMemory: async (): Promise<CtoMemorySnapshot> =>
ipcRenderer.invoke(IPC.ctoGetMemory, {}),
updateMemory: async (args: CtoUpdateMemoryArgs): Promise<CtoMemorySnapshot> =>
ipcRenderer.invoke(IPC.ctoUpdateMemory, args),
searchMemory: async (args: CtoSearchMemoryArgs): Promise<CtoSearchMemoryResult> =>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route CTO memory calls through the project runtime

When the renderer is bound to a socket-backed local/remote project runtime, these direct ipcRenderer.invoke calls bypass the same callProjectRuntimeActionOr path used by adjacent CTO state methods. In that context the Memory settings panel will read/write the Electron host AppContext instead of the bound project, or fail with “CTO memory service is not available,” so project-specific memory cannot be viewed or edited from remote/runtime-backed desktops.

Useful? React with 👍 / 👎.

Comment on lines +842 to +843
var isOnboardingComplete: Bool {
onboardingState?.isComplete ?? false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat dismissed CTO onboarding as unblocked on iOS

If a user clicks the desktop “Set up later” path, the stored onboarding state has dismissedAt but no completedAt or identity step; desktop explicitly treats that as non-blocking, but this iOS helper returns false and CtoRootScreen gates the whole tab on it. Those users are forced back into setup on iOS and cannot open the CTO chat/settings until they complete setup, even though they already dismissed onboarding on desktop.

Useful? React with 👍 / 👎.

Comment thread apps/desktop/src/preload/preload.ts Outdated
…smissed setup

- New cto_memory action domain (getSnapshot/updateMemory/searchMemory) in the
  shared adeActions registry; preload memory methods now use
  callProjectRuntimeActionOr like the rest of the CTO surface, so
  runtime-backed and remote-bound desktops read/write the bound project's
  memory instead of the Electron host context (Codex P2 + Greptile P1).
- iOS: dismissed-but-not-completed setup no longer blocks the CTO tab
  (isOnboardingBlocking mirrors desktop's needsOnboarding gate); added a
  "Set up later" skip to the setup card for desktop parity; regression test.

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

arul28 commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: e167068e70

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

"setAgentStatus",
"triggerWakeup",
],
cto_memory: ["getSnapshot", "searchMemory", "updateMemory"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Gate CTO memory writes behind the CTO role

When a non-CTO ADE action caller invokes run_ade_action for cto_memory.updateMemory, this allowlist exposes the mutating method, but ADE_ACTION_CTO_ONLY above does not include cto_memory, so the role guard in the RPC action path never runs. That lets any agent/external caller with ADE action access overwrite the persistent .ade/cto/MEMORY.md, which is injected into the CTO across sessions and model switches; the mutating memory method should be marked CTO-only before it is exposed.

Useful? React with 👍 / 👎.

Comment on lines +26442 to +26443
if (managed.session.identityKey === "cto" && modelChanged) {
persistCtoModelPreference(managed, descriptor.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist reasoning-only CTO model changes

When the CTO Settings reasoning picker changes only the reasoning tier for the current model, updateSession receives the same modelId, so modelChanged is false even though the session's reasoningEffort is updated earlier in this branch. This new persistence hook is therefore skipped, leaving ctoStateService's modelPreferences.reasoningEffort stale; future new/reconciled CTO sessions can fall back to the old effort despite the user changing it in Settings.

Useful? React with 👍 / 👎.

Comment thread apps/desktop/src/main/services/cto/ctoMemoryService.ts Outdated
…soning-only changes

- cto_memory.updateMemory added to ADE_ACTION_CTO_ONLY so non-CTO ADE-action
  callers cannot overwrite the CTO's injected durable memory (Codex P1).
- MEMORY.md byte-cap eviction no longer destroys facts: oldest facts move to
  append-only .ade/cto/memory-archive.md, remain searchable via searchMemory,
  and saveMemory reports the eviction to the model (Greptile P1).
- Reasoning-only CTO tier changes now persist into identity modelPreferences
  (both the same-model and reasoning-only updateSession branches) so ensured
  sessions do not resurrect a stale effort (Codex P2).

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

arul28 commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@cursor

cursor Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@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: 1

🤖 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/adeActions/registry.ts`:
- Around line 1202-1204: The updateMemory handler currently converts an omitted
memory payload into an empty string and writes it directly, which can overwrite
MEMORY.md with blank content. Update the updateMemory logic in registry.ts so it
rejects missing or empty args?.memory instead of defaulting to "", or route the
write through the archive-preserving path used by ctoMemoryService to avoid
losing evicted facts. Refer to updateMemory and
ctoMemoryService.writeMemory/getSnapshot when making the change.
🪄 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

Run ID: e5e30e16-0207-4de2-a780-d3aef4cd3a49

📥 Commits

Reviewing files that changed from the base of the PR and between 5ceeabb and ff17699.

⛔ Files ignored due to path filters (4)
  • apps/ios/ADE.xcodeproj/project.pbxproj is excluded by !**/*.xcodeproj/project.pbxproj
  • 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 (18)
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/services/sync/syncHostService.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/cto/ctoMemoryService.test.ts
  • apps/desktop/src/main/services/cto/ctoMemoryService.ts
  • apps/desktop/src/main/services/cto/ctoStateService.ts
  • apps/desktop/src/main/services/cto/linearLaneCardService.test.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/shared/types/cto.ts
  • apps/desktop/src/shared/types/sync.ts
  • apps/ios/ADE/Models/RemoteModels.swift
  • apps/ios/ADE/Services/SyncService.swift
  • apps/ios/ADE/Views/Cto/CtoRootScreen.swift
  • apps/ios/ADE/Views/Cto/CtoSetup.swift
  • apps/ios/ADETests/ADETests.swift
💤 Files with no reviewable changes (1)
  • apps/desktop/src/main/services/cto/linearLaneCardService.test.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/ade-cli/src/services/sync/syncHostService.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/main/services/cto/ctoMemoryService.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/desktop/src/main/services/ai/tools/ctoOperatorTools.ts
  • apps/desktop/src/main/services/cto/ctoStateService.ts

Comment thread apps/desktop/src/main/services/adeActions/registry.ts

@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: ff17699083

ℹ️ 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 on lines +25019 to +25023
await updateSession({
sessionId: managed.session.id,
modelId: desiredModelId,
reasoningEffort: managed.session.reasoningEffort ?? null,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply stored reasoning when reconciling CTO model

When the CTO model preferences are changed while a persistent CTO session already exists but is not the live renderer session (for example after a reload or from the iOS/settings path), this reconciliation path is what applies the saved preference on the next ensureSession. It passes the old managed.session.reasoningEffort into updateSession, and the whole block only runs when the model id differs, so reasoning-only preference changes are ignored and model+reasoning changes can start the new model with the stale tier.

Useful? React with 👍 / 👎.

Comment thread apps/desktop/src/main/services/cto/ctoMemoryService.ts Outdated
…ct, reconcile reasoning

- searchMemory scans durable facts first (MEMORY.md → thread-state → archive)
  before daily journal lines, so archived facts can't be starved out of the
  result budget by high-volume journals (Greptile P1).
- updateMemory (IPC + action domain) requires an explicit string; a missing
  field can no longer blank MEMORY.md, and a deliberate clearing rewrite
  archives the replaced content (shared archiveMemoryContent helper, also
  used by the eviction path) (CodeRabbit Major).
- ensureIdentitySession reconciliation honors identity reasoningEffort too:
  reasoning-only preference changes move the ensured session instead of
  resurrecting the stale tier (Codex P2).

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

arul28 commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: 2709b58351

ℹ️ 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 on lines +294 to +295
if (rows.length < limit) scan("thread-state.md", null, readThreadState());
if (rows.length < limit) scan("memory-archive.md", null, readFileOrEmpty(memoryArchivePath));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Prioritize archived facts before thread-state matches

When MEMORY.md has evicted durable facts into memory-archive.md, a broad query can still lose those facts because thread-state.md is scanned before the archive and the scan stops once the default limit is filled. In a session whose thread summary has 20 matching lines, searchMemory() returns no archived durable facts even though the eviction path tells callers they remain searchable; scan the archive before transient thread/daily state or reserve budget for it.

Useful? React with 👍 / 👎.

Durable facts (current + archived) take the search budget before the rolling
thread summary and daily journals, closing the last lookup-starvation edge
case (Codex P2).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment on lines +8221 to +8227
updateMemory: async (args: CtoUpdateMemoryArgs): Promise<CtoMemorySnapshot> =>
callProjectRuntimeActionOr("cto_memory", "updateMemory", { args }, () =>
ipcRenderer.invoke(IPC.ctoUpdateMemory, args),
),
ensureAgentSession: async (
args: CtoEnsureAgentSessionArgs,
): Promise<AgentChatSession> =>
callProjectRuntimeActionOr(
"chat",
"ensureAgentIdentitySession",
{ args },
() => ipcRenderer.invoke(IPC.ctoEnsureAgentSession, args),
),
getBudgetSnapshot: async (
args: CtoGetBudgetSnapshotArgs = {},
): Promise<AgentBudgetSnapshot> =>
callProjectRuntimeActionOr(
"worker_agent",
"getBudgetSnapshot",
{ args },
() => ipcRenderer.invoke(IPC.ctoGetBudgetSnapshot, args),
),
triggerAgentWakeup: async (
args: CtoTriggerAgentWakeupArgs,
): Promise<CtoTriggerAgentWakeupResult> =>
callProjectRuntimeActionOr(
"worker_agent",
"triggerWakeup",
{ args },
() => ipcRenderer.invoke(IPC.ctoTriggerAgentWakeup, args),
),
listAgentRuns: async (
args: CtoListAgentRunsArgs = {},
): Promise<WorkerAgentRun[]> =>
callProjectRuntimeActionOr(
"worker_agent",
"listAgentRuns",
{ args },
() => ipcRenderer.invoke(IPC.ctoListAgentRuns, args),
),
listAgentSessionLogs: async (
args: CtoListAgentSessionLogsArgs,
): Promise<AgentSessionLogEntry[]> =>
callProjectRuntimeActionOr(
"worker_agent",
"listSessionLogs",
{ argsList: [args.agentId, args.limit ?? 40] },
() => ipcRenderer.invoke(IPC.ctoListAgentSessionLogs, args),
searchMemory: async (args: CtoSearchMemoryArgs): Promise<CtoSearchMemoryResult> =>
callProjectRuntimeActionOr("cto_memory", "searchMemory", { args }, () =>
ipcRenderer.invoke(IPC.ctoSearchMemory, args),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Memory payload wrapped
callProjectRuntimeActionOr sends its request fields as the run_ade_action payload, so passing { args } invokes cto_memory.updateMemory with { args: { memory } } instead of { memory }. The registry rejects saves with updateMemory requires a string memory field, and searchMemory searches an empty query for bound runtimes. Pass the memory/search fields directly in args.

Artifacts

Repro: focused Vitest test for wrapped CTO memory payloads

  • Contains supporting evidence from the run (text/typescript; charset=utf-8).

Repro: verbose Vitest output showing wrapped payloads, rejected update, and empty-query search

  • Keeps the command output available without making the summary code-heavy.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/preload/preload.ts
Line: 8221-8227

Comment:
**Memory payload wrapped**
`callProjectRuntimeActionOr` sends its request fields as the `run_ade_action` payload, so passing `{ args }` invokes `cto_memory.updateMemory` with `{ args: { memory } }` instead of `{ memory }`. The registry rejects saves with `updateMemory requires a string memory field`, and `searchMemory` searches an empty query for bound runtimes. Pass the memory/search fields directly in `args`.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

False positive — the payload is not wrapped in the real pipeline. callProjectRuntimeActionOr({ args }) puts the fields on request.args; the runtime bridge forwards the request untouched (runtimeBridge.ts localRuntimeCallAction), the connection pools send arguments: { domain, action, args: request.args } (localRuntimeConnectionPool.ts:995), and run_ade_action unwraps with safeObject(toolArgs.args) and invokes the domain method with that object directly (adeRpcServer.ts:3203-3206). So cto_memory.updateMemory receives { memory }, not { args: { memory } } — the same envelope project_secret.set and ai.getStatus have used in production. The repro harness appears to have invoked the domain method with the whole request envelope rather than going through the dispatcher.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You're right, and I've verified the pipeline you described. The { args } wrapping in callProjectRuntimeActionOr is the established convention across the entire codebase — the third parameter becomes the full run_ade_action request body, and adeRpcServer.ts unwraps it at safeObject(toolArgs.args) before dispatching to the domain method. The T-Rex repro called the domain registry method directly rather than going through the run_ade_action dispatcher, so it saw { args: { memory } } instead of the correctly-unwrapped { memory }. That's a test harness artifact, not a real bug.

Withdrawing this comment. Sorry for the noise.

@arul28 arul28 merged commit 30af03f into main Jul 5, 2026
29 checks passed
@arul28 arul28 deleted the ade/big-task-incoming-start-skill-a0ef4fe0 branch July 5, 2026 06:15
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