fix: a fresh session checkout takes the head its payload came from, and a deploy keeps the base it pinned

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-09-15 20:27:31 +02:00
co-authored by Claude Opus 5
parent de5769fb56
commit 9abd8fa7aa
3 changed files with 15 additions and 5 deletions
@@ -646,9 +646,11 @@ function createRuntime(session: Session): SessionRuntime {
await initFlow(flow, store, stateStore, workspace)
// A draft keeps the base it forked from, unknown included (it then falls
// back to the timestamps); only a fresh checkout takes the head, which is
// also what keeps it from always diffing. See loadScript.
if (deployedVersionId != null && store.val && !serverDraft)
store.val.version_id = deployedVersionId
// also what keeps it from always diffing. See loadScript. The head comes
// from the response that supplied the payload, so a deploy landing between
// the two requests cannot label this checkout as forked from the older one.
const head = (result as SavedFlow).version_id ?? deployedVersionId
if (head != null && store.val && !serverDraft) store.val.version_id = head
slot.loadedPath = path
slot.loadedWorkspace = workspace
} catch (err) {
@@ -500,7 +500,11 @@
// itself; the prompt's own pair is what the loader knows, and this deploy
// consumed the draft it described, so the route holds no base until it loads
// again (the deploy guard covers that window).
draftBaseVersion = undefined
// Keep the base the editor just pinned when this deploy is the head: the
// prompt has no draft to describe either way, and the drawer needs it to
// keep offering Take latest. A raced deploy leaves it unknown, since the
// pair would then differ and open the prompt on a draft that is gone.
draftBaseVersion = version != null && version === head ? String(version) : undefined
draftSavedAt = undefined
if (head != null) {
// Named by whoever deployed the head, not by the page load's author.
@@ -661,7 +661,11 @@
// deploy consumed the draft it described, so the route holds no base until it
// loads again (the deploy guard covers that window).
parentVersion = version
draftBaseVersion = undefined
// Keep the base the editor just pinned when this deploy is the head: the
// prompt has no draft to describe either way, and the drawer needs it to
// keep offering Take latest. A raced deploy leaves it unknown, since the
// pair would then differ and open the prompt on a draft that is gone.
draftBaseVersion = version != null && version === head ? String(version) : undefined
draftSavedAt = undefined
if (head != null) {
// Named by whoever deployed the head, not by the page load's author.