Skip to content

fix(session): delete reverted messages boundary-last and tie-break ids by raw order - #52588

Open
austinborn wants to merge 3 commits into
anomalyco:devfrom
austinborn:revert-order-tiebreak
Open

austinborn wants to merge 3 commits into
anomalyco:devfrom
austinborn:revert-order-tiebreak

Conversation

@austinborn

Copy link
Copy Markdown

Issue for this PR

Closes #42816 (items 1 and 2). Supersedes #42819, which was auto-closed as stale. The completion-gate fallback from the same issue is handled separately in #48472.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Revert cleanup. SessionRevert.cleanup deleted the revert boundary message first, and each removal is its own write. If cleanup was interrupted after that, the next cleanup couldn't find the boundary (findIndex → -1), deleted nothing, and clearRevert() dropped the marker. The rest of the reverted messages then stayed in the transcript. Messages and parts are now deleted newest-first, so the boundary goes last and an interrupted cleanup can still be finished by the next one.

Tie-break collation. Storage pages with ORDER BY time_created, id (SQLite BINARY). The TUI (compareMessage, listSessions) and the share page tie-broke on localeCompare, which can order ids from the same millisecond the other way (e.g. msg_A… vs msg_a…) and returns 0 for canonically equivalent distinct ids. In the TUI this also disagreed with its own search(), which uses <. All three now compare by code unit.

How did you verify your code works?

  • New tests in packages/opencode/test/session/revert-compact.test.ts: boundary-last removal order (messages and parts), and a cleanup that resumes after a partial delete.
  • New packages/tui/test/context/sync.test.ts: case-differing ids sort in storage order whatever the input order, and canonically equivalent distinct ids never compare equal.
  • The new revert-order test and both TUI tests fail without the fix and pass with it.
  • bun test for the session revert/message-v2/pagination suites (100 pass) and the TUI context tests; bun typecheck across the repo (pre-push hook).

Screenshots / recordings

N/A, no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

🤖 Generated with Claude Code

Actual Operator and others added 3 commits October 1, 2026 23:02
- Update .actual/rules/cross-cutting-message-ingestion-synchronization-layers-e283.md (claude)
- Update .actual/rules/cross-cutting-session-history-compaction-routines-reve-df90.md (claude)
- Update .actual/rules/cross-cutting-session-message-timelines-transcript-exp-f4fc.md (claude)
- Update AGENTS.md (agents)
- Update docs/adr/e2838170-cdcd-4036-ae98-5e997b53d7cd-standardize-chronological-ordering-for-session-message-ingestion-and-timelines-message-ingestion-synchronization-layers-not-assume.md (docs)
- Update docs/adr/df903f58-c272-4a3f-b640-a93922945540-standardize-chronological-ordering-for-session-message-ingestion-and-timelines-session-history-compaction-routines-revert-boundary.md (docs)
- Update docs/adr/f4fcb389-bd12-4d7e-8adc-0d32c57f98c4-standardize-chronological-ordering-for-session-message-ingestion-and-timelines-session-message-timelines-transcript-exports-sync.md (docs)
…s by raw order

Revert cleanup removed the boundary message first, so an interrupted cleanup
left no marker and the next cleanup cleared the revert while resurrecting the
remaining reverted messages. Delete messages and parts newest-first so the
boundary is removed last and an interrupted cleanup stays resumable.

The TUI and share page tie-broke same-millisecond messages with localeCompare,
which disagrees with storage's SQLite BINARY collation (and with the TUI's own
binary search) and can treat distinct ids as equal. Compare ids by code unit.

Refs anomalyco#42816

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

This branch has not been deployed

No deployments
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.

[BUG] Two ordering-correctness gaps remain after the ID-rollover fix

1 participant