fix(tui): recover plan state when resuming a session - #65
Merged
Conversation
handleSessionDetail swapped the transcript but kept the previous session's plan knowledge and never seeded a refetch: the replayed transcript bypasses the WS plan trigger, and the adopt's session event carries the already-swapped id, so the switch-delta reset never fired. The strip then stayed empty — or showed stale steps — until the next live plan call. Reset the plan surface and fetch the resumed session's snapshot in the resume batch itself (RED-first: TestPlanSurface_SessionResumeResetsAnd- Refetches). Validated against a live odek serve (v1.39.0): the plan survives session_switch from a fresh connection and a full serve restart.
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.
Root cause
Restoring a session (
/sessions→handleSessionDetail) swapped the transcript but left the planning surface untouched — and neither live path covered a resume:replayTranscriptrebuilds turns outsidehandleEvent, so the persistedplantool calls never set the WS trigger that schedules a fetch.sessionevent carries the already-swapped session id (handleSessionDetailsetsm.sessionIDfirst), soprevSession == ev.SessionID— the switch-delta guard that armsplanResetPendingnever fires (a live switch between two different sessions does).case sessionDetailMsgreturns the handler's own batch, without theplanFollowuptail.Net:
planInitstayedfalse(or held the previous session's stale snapshot), soplanStripLabel()rendered nothing after restore — not even during the next busy run — until the agent happened to call theplantool again. Cross-session version crosstalk was also possible via the monotonicplanVerguard.Fix
handleSessionDetailnow resets the plan surface and seeds the fetch in the resume batch itself:The endpoint is session-id-scoped REST, so the immediate fetch cannot race the WS switch.
Test (RED-first)
TestPlanSurface_SessionResumeResetsAndRefetchespins the full loop: stale knowledge dropped → fetch seeded → old plan must not leak into the strip → resumed session's snapshot rendersplan 1/4while busy. Failed before the fix (init=true ver=7), passes after.End-to-end validation against a live odek serve (v1.39.0)
A throwaway client harness (bodek's own
internal/client) drove a realodek serve:found=true ver=2, 3 steps,probe-ain_progresssession_switch→/plan/planSessionDetailtranscriptConclusion: odek recovers the plan on session load on both the same-process and restart paths — the missing indicator was purely the client-side gap fixed here.
Checklist
go fmtclean ·go vetclean · fullgo test -race -count=1 ./...green (7/7 packages)