Version line
v2 — Go rewrite (1.x), main-v2 (active development)
Exact version
desktop v1.19.6 (Windows 10/11)
What happened?
After a session that was recovered from a stale runtime (rewrite conflict), the Edit message button is disabled for every turn of that session, even when the agent is fully idle. Hovering over any user message shows the tooltip/reason "Conversation boundary is unavailable", and EditPrompt never activates.
The UI gating is: editDisabled = rewindDisabled || !checkpoint?.canConversation (desktop/frontend/src/components/Transcript.tsx), and the backend computes CanConversation = ctrl.CheckpointHasBoundary(m.Turn) (desktop/app.go). CheckpointHasBoundary returns false when the recorded boundary index is greater than the current session log length (internal/control/checkpoint.go, boundary(turn) + boundary <= Session().Len() check).
Steps to reproduce
- Have a long-running session that crashes / goes stale so it gets recovered.
- Open the recovered session (its meta name is "Recovered unsaved changes from stale runtime",
recovery_reason: "rewrite conflict").
- Send a message, wait for the turn to finish.
- Hover your own message → Edit is disabled with "Conversation boundary is unavailable".
Root cause (observed in session files)
In the recovered session the checkpoint boundaries (.ckpt/turn-*.json) still point at message indices of the old log, while the log has been rebuilt:
jsonl.meta: recovery_reason: "rewrite conflict", recovery_depth: 3, fork_message_index: 397, revision: 129, turns: 17
event-index.json: message_count: 101
- checkpoint boundaries recorded as:
397, 403, 405, 79, 81, 83, 89, 97, 107, 60, 146, 166, 182, 206, 210, 212, 214, 216, 220, 94, 107, 109, 118, 53, 69, 111 — non-monotonic and mostly larger than the current log length (101)
events.jsonl shows repeated replace events (rev 125→129) — the log was rewritten wholesale; boundaries are not remapped to the new indices.
Because boundary > Session().Len(), CheckpointHasBoundary is false for every turn, so conversation rewind/edit is permanently unavailable in the recovered session.
Expected behavior
- Either remap checkpoint boundaries to the rebuilt log after recovery, or drop them explicitly so the UI reports a clear reason instead of silently disabling Edit for the whole session.
- Ideally, editing the latest user message should still work without a checkpoint boundary (truncate to the last user message) — it is the most common edit use-case.
Additional context
Related: #4042 (different aspect — rollback of code/conversation failing in general, closed). This report focuses on the recovery path: a recovered session should not lose the ability to edit messages forever.
Version line
v2 — Go rewrite (1.x), main-v2 (active development)
Exact version
desktop v1.19.6 (Windows 10/11)
What happened?
After a session that was recovered from a stale runtime (rewrite conflict), the Edit message button is disabled for every turn of that session, even when the agent is fully idle. Hovering over any user message shows the tooltip/reason "Conversation boundary is unavailable", and
EditPromptnever activates.The UI gating is:
editDisabled = rewindDisabled || !checkpoint?.canConversation(desktop/frontend/src/components/Transcript.tsx), and the backend computesCanConversation = ctrl.CheckpointHasBoundary(m.Turn)(desktop/app.go).CheckpointHasBoundaryreturns false when the recorded boundary index is greater than the current session log length (internal/control/checkpoint.go,boundary(turn)+boundary <= Session().Len()check).Steps to reproduce
recovery_reason: "rewrite conflict").Root cause (observed in session files)
In the recovered session the checkpoint boundaries (
.ckpt/turn-*.json) still point at message indices of the old log, while the log has been rebuilt:jsonl.meta:recovery_reason: "rewrite conflict",recovery_depth: 3,fork_message_index: 397,revision: 129,turns: 17event-index.json:message_count: 101397, 403, 405, 79, 81, 83, 89, 97, 107, 60, 146, 166, 182, 206, 210, 212, 214, 216, 220, 94, 107, 109, 118, 53, 69, 111— non-monotonic and mostly larger than the current log length (101)events.jsonlshows repeatedreplaceevents (rev 125→129) — the log was rewritten wholesale; boundaries are not remapped to the new indices.Because
boundary > Session().Len(),CheckpointHasBoundaryis false for every turn, so conversation rewind/edit is permanently unavailable in the recovered session.Expected behavior
Additional context
Related: #4042 (different aspect — rollback of code/conversation failing in general, closed). This report focuses on the recovery path: a recovered session should not lose the ability to edit messages forever.