fix(rewind): fail loudly past a compacted boundary (#3598) + suffix-scan CanCode (#3438)#3672
Merged
Merged
Conversation
added 2 commits
June 9, 2026 03:46
A turn's conversation-rewind boundary is the message-log index at turn start. Compaction shrinks the log without rewriting boundaries, so for a turn compacted away the boundary now exceeds len(Messages). Rewind tested `boundary <= len` and, when false, skipped the truncation but still emitted a "rewound conversation" success — code restored, conversation silently not. Return a clear failure instead, and only report success when the log was actually truncated. Closes #3598
…iles RestoreCode(turn) reverts every file touched in that turn or any later one, so a turn that changed no files of its own can still rewind code when a later turn did. CanCode only checked the turn's own paths, disabling the code/both rewind buttons for such turns. Propagate CanCode backwards over the oldest-first checkpoint list so the UI matches the backend's capability. Refs #3438
SuMuxi66
pushed a commit
to SuMuxi66/DeepSeek-Reasonix
that referenced
this pull request
Jun 10, 2026
…suffix-scan CanCode (esengine#3438) (esengine#3672) * fix(control): fail conversation rewind loudly past a compacted boundary A turn's conversation-rewind boundary is the message-log index at turn start. Compaction shrinks the log without rewriting boundaries, so for a turn compacted away the boundary now exceeds len(Messages). Rewind tested `boundary <= len` and, when false, skipped the truncation but still emitted a "rewound conversation" success — code restored, conversation silently not. Return a clear failure instead, and only report success when the log was actually truncated. Closes esengine#3598 * fix(desktop): mark a turn code-rewindable when a later turn changed files RestoreCode(turn) reverts every file touched in that turn or any later one, so a turn that changed no files of its own can still rewind code when a later turn did. CanCode only checked the turn's own paths, disabling the code/both rewind buttons for such turns. Propagate CanCode backwards over the oldest-first checkpoint list so the UI matches the backend's capability. Refs esengine#3438 --------- Co-authored-by: reasonix <reasonix@deepseek.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two rewind-correctness fixes from issue triage.
1. Conversation rewind silently no-ops after compaction (#3598)
A turn's conversation-rewind boundary is the message-log index recorded at turn start. Compaction shrinks
Session.Messageswithout rewriting checkpoint boundaries, so once a turn has been compacted away its boundary exceedslen(Messages).Controller.Rewindtestedboundary <= len(s.Messages)and, when that was false, skipped the truncation but still emitted a "rewound conversation to turn N" success notice. ForRewindBoththe code was rolled back while the conversation silently was not — the data-loss in #3598 ("code rolled back but conversation is not").Now it returns a clear
conversation rewind unavailable … the conversation was compacted past this pointfailure (surfaced as a Warn notice via the existingrewindFailpath) and only reports success when the log was actually truncated.2. CanCode ignores later turns' file changes (#3438)
RestoreCode(turn)reverts every file touched in that turn or any later one, so a turn that changed no files of its own can still rewind code when a later turn did. The desktopCanCodeflag only checked the turn's ownPaths, disabling the code/both buttons for such turns. It now propagates backwards over the oldest-first checkpoint list so the UI matches backend capability.Test plan (end-to-end)
internal/control/rewind_e2e_test.go— drives two real turns through a real agent + controller + checkpoint store, simulates compaction by shrinking the log below the recorded boundary, and assertsRewindBothnow returns acompacted-past failure, emits no false success notice, and leaves the log intact; companion test asserts a live boundary still truncates + reports success.desktop/checkpoints_cancode_test.go— seeds a real checkpoint store (turn 0 no files, turn 1 with a file, turn 2 no files) and assertsCheckpointsForTabreturns CanCode[true, true, false].go test ./internal/control ./internal/checkpointgreen;go vet+ gofmt clean on changed files. (Two pre-existing desktop failures on Windows —TestMediaTokenHandlerEscapedFilename,TestAddSkillPathRestoresConventionRootWithoutCustomPath— reproduce without this change and are platform/env-specific.)