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.

Loading
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