Skip to content

fix(rewind): fail loudly past a compacted boundary (#3598) + suffix-scan CanCode (#3438)#3672

Merged
esengine merged 2 commits into
main-v2from
fix/rewind-compaction-cancode
Jun 9, 2026
Merged

fix(rewind): fail loudly past a compacted boundary (#3598) + suffix-scan CanCode (#3438)#3672
esengine merged 2 commits into
main-v2from
fix/rewind-compaction-cancode

Conversation

@esengine

@esengine esengine commented Jun 9, 2026

Copy link
Copy Markdown
Owner

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.Messages without rewriting checkpoint boundaries, so once a turn has been compacted away its boundary exceeds len(Messages). Controller.Rewind tested boundary <= len(s.Messages) and, when that was false, skipped the truncation but still emitted a "rewound conversation to turn N" success notice. For RewindBoth the 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 point failure (surfaced as a Warn notice via the existing rewindFail path) 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 desktop CanCode flag only checked the turn's own Paths, disabling the code/both buttons for such turns. It now propagates backwards over the oldest-first checkpoint list so the UI matches backend capability.

Note: this addresses the CanCode sub-bug called out in #3438. The broader frontend turn-number divergence in #3438/#3640 (synthetic user messages from stream-recovery/retries/plan-approval shift the frontend turn counter relative to backend checkpoint turns) is a separate, larger fix that needs end-to-end desktop verification and is tracked separately.

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 asserts RewindBoth now returns a compacted-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 asserts CheckpointsForTab returns CanCode [true, true, false].
  • go test ./internal/control ./internal/checkpoint green; 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.)

reasonix 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
@esengine esengine requested a review from SivanCola as a code owner June 9, 2026 10:46
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) agent Core agent loop (internal/agent, internal/control) and removed v2 Go rewrite (1.x) — main-v2 branch, active development labels Jun 9, 2026
@esengine esengine merged commit 0f6492f into main-v2 Jun 9, 2026
10 checks passed
@esengine esengine deleted the fix/rewind-compaction-cancode branch June 9, 2026 10:58
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Core agent loop (internal/agent, internal/control) desktop Wails desktop app (desktop/**)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant