Skip to content

Native chat: rewind works at any chat length - #30394

Merged
brennanb2025 merged 5 commits into
mainfrom
brennanb2025/chat-rewind-length
Oct 19, 2026
Merged

brennanb2025 merged 5 commits into
mainfrom
brennanb2025/chat-rewind-length

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 10 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​271 $\color{#cf222e}{\Huge{\mathbf{−}}}$​808 $\color{#cf222e}{\Huge{\mathbf{−}}}$​537
Prod 15 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​338 $\color{#cf222e}{\Huge{\mathbf{−}}}$​712 $\color{#cf222e}{\Huge{\mathbf{−}}}$​374

ELI5

In a long chat, "Rewind to here" said "This conversation is too long to go back in. Nothing was changed." Long chats are exactly where people want to go back. Rewind no longer refuses a chat because its saved history exceeds those limits.

What Changed

Before: to rewind, Orca copied every message it would keep into a saved record, and for Codex it also re-read Codex's entire history twice (before and after the revert) and translated it all back into chat rows. Each of those copies had a size cap: about 10,000 rows or 2 MB for the saved copy, and 1,024 turns-plus-items or 2 MB for the Codex read. A chat past any cap was refused. With large tool outputs, about 130 tool calls were enough.

After: rewind removes the selected turn and later turns without those history-size refusals.

Rejected messages, including messages stopped before delivery, are omitted after rewind just as before. Preserving earlier submission status during rewind is tracked separately and is outside this length-limit change.

Why

The common pattern for going back in a chat keeps the app's own message store authoritative. It marks or deletes only the undone part by reference, and stores only ids for a rewind in progress. This adopts that authority and the small in-progress record. The existing completion write still takes work proportional to the kept history, as described below.

Differences, each intended:

  • Orca still writes the kept rows into a new chat version instead of only marking the removed ones. Older paired desktops detect a finished rewind only by the chat version changing, and mixed client and server versions are normal. This is a local database write, with no size refusal.
  • Recovery reads Codex to decide whether a revert happened. Without that read, a retry after a crash can revert a second time.
  • Kept subagent rows follow the main turn they belong to, including rows received late. Previously, ordinary child-thread rows absent from the provider's returned history could disappear. Keeping the already visible rows with their parent turn is intended.
  • Rewind no longer adds older turns that the chat never showed (for example a chat imported with only its newest part). It shows what you saw, minus the part you went back over.

Alternative rejected: raise or remove the caps but keep the copy and the full re-read. The saved record would grow without bound, since it is rewritten whole on every step. A long Codex chat would also re-read and re-translate its whole history twice per rewind.

Linked Issue

Tracked in the native-chat audit (data limits D-K4, provider limits #7). No GitHub issue.

Visual Proof

Real Orca build of this branch on a Mac (M4Air), driven through the app with a real, signed-in Codex. The chat's Codex history was 3.3 MB before the rewind, past the old 2 MB limit. All six flows passed; "This conversation is too long to go back in" never appeared.

  1. Long chat before the rewind (the first red notice is a test-machine model setup error, then the run continued on GPT-6.1-Sol):
    01-long-chat.jpg
  2. After "Rewind to here" on "Remember the code word BANANA": that turn and everything after it are gone, and the message is back in the composer:
    02-rewound.jpg
  3. Codex no longer remembers the undone turn (asked for the code word, it answers NONE):
    03-memory.jpg
  4. After restarting Orca the chat is still rewound:
    04-restart.jpg
  5. A short chat still rewinds:
    05-short.jpg
  6. A rewind after /clear keeps everything above the "Context cleared" divider:
    06-clear.jpg

Not shown: the same chat on a build of main. The 3.3 MB is the size of Codex's saved history file; the automated tests are what pin the old refusal and its removal.

Testing

  • New: a chat whose kept part is past 2 MB rewinds end to end. A 5,000-turn Codex chat rewinds reading only the turns it undoes. Recovery decides from the newest turn. A subagent's rows follow the main turn they arrived in.
  • Added from review: a message stopped before it reached the agent is dropped by a rewind (as on main), instead of reappearing as a sent message.
  • Kept: the existing tests for /clear, at-rest, live-send, the raw Stop note, turn openers, goals, newer row kinds, turn-duration ownership (Native chat: one settlement transaction for everything an ended run left (4/5, rebuild of #26867) #28111) and replay. They now run against the journal-derived rows.
  • Automated tests added/updated
  • Manual QA: real Electron build on macOS (M4Air) with a signed-in Codex; long chat rewind, memory check, restart, short chat, after /clear. All passed.

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • SSH / paired servers / phone: no wire change. The rewind record lives only on the host. The "too long" message stays in the client, because older servers still send it.
  • Saved data: the record's old retained field becomes optional and is no longer written. A rewind left half-done by an older build can recover from the chat history when the provider outcome can be established; an uncertain outcome remains unresolved.
  • Platforms: no platform-specific code.

Author: @BrennanKB5

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (CI will cover)

Rewind copied the kept part of the chat into its saved record and, for
Codex, re-read and re-translated the whole provider history before and
after the revert. Both were bounded (10,000 rows / 2 MB host, 1,024
entries / 2 MB Codex), so long chats were refused with "too long to go
back in".

The record now names the cut; the kept rows are derived from the
journal, which keeps the old epoch until the rewind completes. Codex
reads only the turns it undoes and trusts thread/revert; recovery
proves an applied revert from the newest turn alone and never
truncates otherwise.
@brennanb2025
brennanb2025 marked this pull request as ready for review October 18, 2026 19:02
@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

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

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 990a6bbd-2181-4eda-996f-d23e914a7053
📥 Commits

Reviewing files that changed from the base of the PR and between d378f49 and 4dd8212.

📒 Files selected for processing: 25
  • config/scripts/vitest-sqlite-runtime-files.mjs
  • src/main/codex/codex-structured-rewind.test.ts
  • src/main/codex/codex-structured-rewind.ts
  • src/main/native-chat/agent-session-journal/journal-item-provenance.spec.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-adapter.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-attach-orchestration.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-clear-rewind.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-provider-started.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind-at-rest.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind-live-send.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind-provenance.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind-replay.test-fixture.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind-stop-note.test-fixture.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-rewind.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-send-preparation.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-cut.test.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-cut.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-journal-body.test.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-journal-body.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-recovery.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-retained-host-rows.test.ts
  • src/main/native-chat/agent-session-wire/structured-rewind-retained-host-rows.ts
  • src/main/runtime/agent-session-rewind-completion.ts
  • src/shared/agent-session-rewind.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Long chats could refuse “Rewind to here” because Orca copied retained messages into a size-limited saved record and read Codex’s history through another size-limited path. This change removes those history-size refusals: rewind keeps Orca’s saved messages before the selected turn, finds the Codex turn a page at a time, and updates the conversation after Codex confirms the rewind.

The full review loop completed two rounds on 4dd82125cc7b01cd9c00fe643dd455d5c19a668f, with zero open findings and zero new findings in round two. The final readiness review found no additional proven high- or medium-priority defects.

Fixed findings:

  • C1 — P2: A message rejected or stopped before delivery could reappear as a sent message after rewind. Rewind now omits those messages, preserving the existing behavior. The regression test failed before the fix and passed afterward.
  • C2 — P2: The new SQLite test ran in an incompatible test runtime. It is now assigned to Node and was verified there.
  • C3 — P3: A test fixture’s type assertion failed the changed-code quality check. The fixture now declares its parameter types directly.

The three-model architecture panel unanimously ruled KEEP after reviewing the expanded implementation budget. It retained the common pattern of treating the app’s saved conversation as authoritative and keeping only the rewind boundary in the in-progress record. Two deliberate differences remain intended: completion still rewrites the kept messages into a new chat version so older paired clients recognize completion, and recovery checks Codex’s state rather than repeating a destructive rewind. Keeping subagent messages with their retained parent turn is also an intended behavior change.

Deferred items, with their recorded labels:

  • D1 — concern, deferred: If an imported conversation lacks the preceding Codex turn, recovery may be unable to prove whether rewind happened. It deliberately leaves the outcome unresolved. The bounded trace established no new failure.
  • D2 — concern, deferred: Recovery treats a changed chat version as evidence that this rewind already completed. That relies on rewind being the only operation that replaces an existing conversation’s version. The bounded caller trace found no competing replacement; this remains an assumption to preserve, not a reproduced defect.
  • D3 — evidence gap, deferred: Older saved rewind records and older paired clients were checked in source, but no real historical-build upgrade or mixed-version client execution was performed.

Verification: 49 targeted tests passed, plus 23 explicit Node-runtime checks. The full PR workflow, run 39160047711, is successful on the exact reviewed head, including its aggregate gate, static analysis, tests, packaging and cross-version compatibility checks. The head and checks were verified again for this closing comment.

The lane owner completed real Electron QA on the M4Air under ticket 398 after the loop’s earlier QA attempt was blocked by driver capacity. Grok drove a real signed-in Codex with a 3.3 MB saved history. All six reported flows passed: long-chat setup, rewind, continuation without the undone context, persistence after restart, short-chat rewind, and rewind after /clear. The length-refusal message did not appear. This closing step accepts that completed QA and does not claim a new run. The history file’s size alone does not measure the old capped payload; automated tests establish the old refusal and its removal. No matching main-build screenshot run, historical-build upgrade, actual mixed-client execution, or crash/network fault-injection run is claimed.

For Brennan’s review

The branch screenshots below are the existing QA evidence from the PR body. Matching main screenshots were not captured.

  1. Long chat before rewind. The first red notice is a test-machine model setup error; the run then continued on GPT-6.1-Sol.

Long chat before rewind

  1. After rewinding “Remember the code word BANANA”: that turn and later turns are removed, and its text returns to the composer.

Long chat after rewind

  1. Continuation: Codex answers NONE when asked for the undone code word.

Continuation without undone context

  1. The rewind persists after restarting Orca.

Rewound chat after restart

  1. Short chats still rewind.

Short chat rewind

  1. Rewind after /clear preserves messages above the divider.

Rewind after clear

Two places worth human attention:

@brennanb2025
brennanb2025 merged commit 9a662c3 into main Oct 19, 2026
34 checks passed
@brennanb2025
brennanb2025 deleted the brennanb2025/chat-rewind-length branch October 19, 2026 04:38
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