Skip to content

fix: persist the autopilot milestone map so a paused run survives a reload (#4140) - #4246

Merged
atomantic merged 1 commit into
mainfrom
claim/issue-4140
Aug 15, 2026
Merged

fix: persist the autopilot milestone map so a paused run survives a reload (#4140)#4246
atomantic merged 1 commit into
mainfrom
claim/issue-4140

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

The Autonomous-mode card's milestone map was drawn from two halves that lived only on the in-memory run record — the projected plan on the run's retained start frame, and the progress snapshot folded onto the record by noteProgress. Both are served only while the run is alive (activeRunStart / activeRunProgress return null once the run finishes, and the panel's mount effect bails on !active), so the map answered "where is it now" perfectly while the panel stayed open and answered nothing the morning after: a run that paused overnight came back as a resume banner with no map beside it.

  • persistMarker (server/services/pipeline/seriesAutopilot/session.js) now stamps { plan, progress } onto the marker alongside status / currentStep / resumeOptions. Stamped on every marker write that has a projected plan, not only the pause/complete/error terminals: the marker is wholesale-replaced per write, so a terminals-only stamp would leave the map missing for the one interruption that skips a terminal write entirely — a hard restart, whose running marker the boot recovery demotes to paused by spreading whatever it already held.
  • sanitizeAutopilot (server/services/pipeline/series.js) bounds both halves so the shape survives a peer round-trip: plan rows are capped and each drops to {kind, count, note, estActions}; the progress snapshot keeps currentStep / currentStepComplete and bounded completed / skipped / verified maps. A zero tally and a verification blob carrying none of the numbers the map reads are dropped rather than persisted.
  • AutopilotPanel falls back to series.autopilot.plan / .progress only when no run is active and there is no live plan — a run in flight and a dry-run preview both keep the fresher in-memory copy. The new autopilotMarkerTerminal(status) in client/src/lib/autopilotMilestones.js translates a persisted status into the terminal frame type the fold reads, so the step a paused run stopped on redraws as blocked instead of still running.
  • No SCHEMA_VERSIONS bump. The map keeps the existing autopilot-marker posture documented in sanitizeAutopilot — transient, regenerated-every-run status, not durable creative content — so a behind peer that drops it just shows the pre-Persist autopilot milestone map so a paused run survives reload #4140 bare banner until the next run re-stamps it. The added payload is a couple of KB on a series record that is already tens.

Also rolled in: the three keyed autopilot marker maps (per-dimension discarded findings, per-step progress counts, per-gate verifications) now share one sanitizeAutopilotKeyedMap bounder instead of each re-rolling the cap/trim/drop-empty loop.

Test plan

  • cd server && NODE_ENV=test npx vitest run services/pipeline lib/schemaVersions — 2093 passed / 13 skipped, including:
    • new sanitizeAutopilot milestone map (#4140) cases: plan rows kept, kind-less rows dropped, absurd counts defaulted, peer-written plan capped, progress snapshot kept with the stopped-on step, both gate verification shapes, empty/malformed inputs.
    • new seriesAutopilot integration cases: a paused run's marker carries the plan and the progress (with currentStep: 'editorialReview'), and a restart-interrupted run keeps both across recoverStuckAutopilots().
  • cd client && npx vitest run src/lib/autopilotMilestones.test.js src/components/pipeline/AutopilotPanel.test.jsx src/lib/index.test.js — 84 passed, including new cases for autopilotMarkerTerminal, the panel redrawing the map from the marker with no active run, and a live run winning over a stale marker.
  • cd client && npm run lint — clean.

Closes #4140

…eload (#4140)

The Autonomous-mode card drew its map from two halves that lived only on the
in-memory run record — the projected plan on the retained `start` frame and the
progress snapshot folded onto it. Both are served only while the run is alive, so
a run that paused overnight came back as a resume banner with no map beside it.

persistMarker now stamps both onto the persisted marker (on every write that has
a plan, not only the terminals — a hard restart never reaches a terminal write,
and the boot recovery demotes its `running` marker by spreading it), sanitizeAutopilot
bounds them so the shape survives a peer round-trip, and the panel falls back to
the marker when no run is active. No schema-version bump: the marker keeps its
existing transient posture, so a behind peer that drops the map just shows the
pre-#4140 bare banner until the next run re-stamps it.
@atomantic
atomantic merged commit f85fd6d into main Aug 15, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-4140 branch August 15, 2026 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persist autopilot milestone map so a paused run survives reload

1 participant