Skip to content

acpmux: restore older Claude chat history after restart - #28098

Merged
teamleaderleo merged 24 commits into
feat-cmux-nextfrom
lane/p0-history-fix
Oct 31, 2026
Merged

teamleaderleo merged 24 commits into
feat-cmux-nextfrom
lane/p0-history-fix

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Leo asked: “I can't fing scroll up past the current fing turn after restarting, and I still don't see the fing left side session scroll prompts thing. ... the scroll up thing was because it still took thirty fing seconds to load anything.”

After a restart, adopted Claude chats now expose the transcript cursor recorded in acpmux and page older turns once the seeded session log is exhausted. Native transcript pages use bounded cursors, fold whole turns above the visible history, preserve the scroll anchor, and stop cleanly on older daemons or unsupported peers. This carries the implementation from draft #27982 into an owned lane because its owner is dead.

Before: the pane stopped at the newest log-seeded page, so older turns were unavailable after restart.
After: the pane reads older transcript pages on demand and shows every prior turn while keeping the reader's place.

Before/after synthetic Linux captures (same restarted adopted chat, newest answer visible):

No capture: the native Swift change only allows the history RPC and its parameters through the relay; it changes no native rendering. The web transcript behavior is captured below on revision 39aad15 in the Linux harness.

Before After
Before After

I viewed the after image above: the transcript is readable, aligned, and leaves the composer unobstructed. The independent reviewer also opened it and accepted the layout alongside ChatGPT/Claude. This is the synthetic capture from revision 39aad15, not a new capture of the latest integration.

Performance

Same synthetic Linux Playwright harness and build, one sample per mode: 700 transcript turns, 200 seeded turns, 500,000 raw log records. Each sample starts a fresh browser after restarting its fixture daemon. Before omits waitLogs; after sends waitLogs:false.

metric before after delta harness
Navigation to newest answer in DOM 1,806.9 ms 256.5 ms −1,550.4 ms (−85.8%) restore fixture, run 41066566417

A repeated run of the same harness (five samples per mode) measured a median of about 1.87 s before and 0.27 s after (about 85% faster): head run 41068764032. At the merge base, both modes took 1,827–1,991 ms: base run 41068759544.

This isolates the attach wait on the same build. It measures DOM detection after navigation and daemon readiness, not pixel paint or full restart wall time. Both samples had no page errors; the captures use synthetic content.

Validation at 750f0eb: web passed all 10 history/scroll/queue/config regressions, typecheck, and lint; fast gates passed. The daemon library run passed 2,382 tests with zero failures and five ignored. Independent Codex integration review passed at this exact head, including both parent diffs and visual inspection of the accepted after image. Fleet Swift results are being checked against base per failing test.

Cursor marks use file identity, observed length, and a bounded boundary hash. Validation and paging share one open descriptor. Exact persisted unmarked seeds have an upgrade path; arbitrary unissued unmarked offsets are rejected. The sampled boundary does not fingerprint arbitrary rewrites elsewhere in the file. Restored held prompts publish a queue change to already attached clients. Native reply pages reduce their turn count to fit the RPC budget; an indivisible oversized turn uses explicit omission markers for payloads that cannot fit, while retaining the continuation cursor. No repeating timer was added; older-history reads stop at cursor zero and the existing selection-generation/epoch checks discard stale responses.

Agent session: agent session

teamleaderleo and others added 3 commits October 30, 2026 07:02
…script

#27740 seeded an adopted or watched Claude Code chat with its transcript's newest page and a
native_history cursor nothing read. _acpmux/native_history reads the page before a cursor
(adopt_replay_page.rs, same caps) and returns its turns as the records adopting logs, numbered
below 1, with the next cursor. The pane pages them in once the log's own history is held, and an
older daemon or host just stops the paging.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-062eab5f69c0c07fd08e
…r that serves none is never asked

Review (codex gpt-6-astra): a Web client could read the transcript, an older peer's refusal
read as an error to retry, and a paged native turn offered a Fork acpmux cannot do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-062eab5f69c0c07fd08e
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 86cbd1d: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr28098 -f ref=lane/p0-history-fix -f platform=macos -f backend_mode=local

Gallery before/after for 86cbd1d: 16 states rendered, 0 images differ, 2521 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 41131652641 -R manaflow-ai/cmux -n gallery-advisory-28098-86cbd1d80d04a0be5a5fe4136ef2b94abc370efd (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.live-chat-watch/choice-alone Apple System Colors Light unchanged 0% own direct.ts
agent-pane.live-chat-watch/choice-alone Apple System Colors unchanged 0% own direct.ts
agent-pane.live-chat-watch/view-only Apple System Colors Light unchanged 0% own direct.ts
agent-pane.live-chat-watch/view-only Apple System Colors unchanged 0% own direct.ts
agent-pane.auth-health/signed-in Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/signed-in Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/signed-out Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/signed-out Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/expired Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/expired Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/unknown Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.auth-health/unknown Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.chat-width/standard Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.chat-width/standard Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.chat-width/wide Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.chat-width/wide Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.chat-width/wide-blocks Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.chat-width/wide-blocks Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-edge/short-edge Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-edge/short-edge Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-edge/wide-edge Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-edge/wide-edge Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-edge/no-edge Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-edge/no-edge Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-floats/scrolled-to-end Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-floats/scrolled-to-end Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-floats/composer-grown Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.composer-floats/composer-grown Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.continuation-spacing/shipped Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.continuation-spacing/shipped Apple System Colors unchanged 0% imports direct.ts (1 hops)
agent-pane.continuation-spacing/two-thirds Apple System Colors Light unchanged 0% imports direct.ts (1 hops)
agent-pane.continuation-spacing/two-thirds Apple System Colors unchanged 0% imports direct.ts (1 hops)

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

Passes: CI passes on 86cbd1d80d.

CI passes on 86cbd1d80d (run 41131653624 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

web and size checks: green

Shipped in:

@github-actions github-actions Bot added the risk:high Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@blacksmith-sh

blacksmith-sh Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
main.DeveloperIdAppTests.test_download_prints_the_active_profile_only/
test_download_prints_the_active_profile_only
View Logs
stubs: /System/Library/Frameworks/Security.framework/Versions/A/Security has no stub/
Security has no stub
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_CFRetain']/
CoreFoundation, missing 1: ['_CFRetain']
View Logs
stubs: CoreFoundation.tbd: install-name /System/Library/Frameworks/
CoreFoundation.framework/Versions/A/CoreFoundation, missing 1: ['_log2']/
CoreFoundation, missing 1: ['_log2']
View Logs
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)/
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)
View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol high fast, independent): BLOCK at d3c1460 (raw first pass; its P1 is refuted below, so treat the net as not yet confirmed SHIP)

Sol reviewed the diff only (no checkout). Its findings:

  1. [P1, claimed] hub/adoption.rs:521-529: adoption never appends the native_history cursor record, so canLoadOlder stays false.
    Checked against the head tree: refuted. The record is written by code this PR does not touch: hub/adoption.rs:~500-506 (replay_adopted appends native_history with before when the seeded page has older turns) and hub/watch.rs:174 (watched chats). The PR's own native_history_tests.rs seeds through replay_adopted and reads that record back. The re-run that was given this context could not finish: the review router answered 503 "no space left on device" (/var/lib/subrouter), so there is no second Sol pass yet.
  2. [P2 by Sol, I would call P3] hub/native_history.rs:152-171: the daemon accepts any positive before below MAX_BEFORE, not only a cursor it issued. The cursor is a byte offset into the session's own transcript, which the caller can already read through the session, so the effect is a client asking for an odd page (overlap or a gap in its own view). Native seqs are derived from the cursor, so a repeated page merges. Optional hardening: reject a before at or above the seeded cursor.

Not found by Sol: races, lost or duplicated pages, waitLogs:false never loading logs, older-peer handling, or remote-guard gaps. It had no checkout, so none of that was run.

Fast-gates (run 41029289350, dispatched on feat-cmux-next with pr=28098): see the lane message for its conclusion.

…tory-fix

# Conflicts:
#	webviews/src/agent-session/acpmux/direct.ts
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex gpt-6-astra; independent delta): SHIP at 57408a5

The hand-resolved base integration preserves native-history behavior, base turn identifiers, and the queue/config restoration fixes. No actionable findings.

…tory-fix

# Conflicts:
#	cmux-tui/crates/acpmux/src/server/requests.rs
@cursor

cursor Bot commented Oct 30, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex): SHIP at 750f0eb

No actionable defects found in either parent diff or the affected integration. Both feature flags survive; fast attach, queue/config restoration, bounded native-history paging, and negative-sequence guards remain intact.

Visual verdict: Yes—Leo would accept the shown layout next to ChatGPT/Claude. Opened and inspected after-visible.png: readable transcript, consistent alignment, and unobstructed composer. This is the accepted synthetic screenshot from revision 39aad153, visual-only evidence—not a fresh capture.

Read-only source review and scoped git diff --check completed. No tests run; unrelated base changes excluded.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): SHIP at 713f2d3 (delta 750f0eb..713f2d3, a clean merge of feat-cmux-next ac6b39b)

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex gpt-6-astra; independent delta): SHIP at 86cbd1d

No correctness findings in 713f2d3..86cbd1d. Guarded accesses preserve response-size accounting and omission selection; marker semantics, event identity/order, cursor continuation fields, and mutable borrow lifetimes remain intact. git diff --check passes. No tests run by the reviewer.

This branch was previously deployed

3 inactive deployments
artifacts — 86cbd1d8 Deployed Oct 30, 2026 by teamleaderleo via add the Windows daemon to the tree #85162
ci-routing-agent — 86cbd1d8 Deployed Oct 30, 2026 by github-actions[bot] via cmux-next macOS placement #51218
sentry-dsyms — 86cbd1d8 Deployed Oct 30, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #85162
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:high Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant