fix(workflows): preserve stage duration across durable resume - #1751
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
Persist pause-adjusted active-stage timing at repeated checkpoints and rebase resumed stage clocks from the durable baseline. Cover file and DBOS hydration, process-boundary completion, pause accounting, and replay idempotency. Assistant-model: GPT-5.6 Sol
Apply the durable timing baseline only once per live stage and cover concurrent tracked calls across process-boundary resume and replay. Co-Authored-By: GPT-5.6 Sol <noreply@openai.com>
Assistant-model: GPT-5.6 Sol
54f766c to
2d6ed61
Compare
|
Verified PR #1751 after rebasing onto the current The focused command passed twice with the same count. Base: Audit notes: added repeated two-boundary resume coverage with pauses in each resumed segment and task-baseline propagation. Completed output remains authoritative. Shared-file overlap was checked against #1750 (retain usage checkpoint/rollup metadata), #1748 (retain centralized resume eligibility), and #1758 (retain timing fields in completed snapshot reconstruction). Deterministic clock/backend tests are stronger than a tmux timing capture here, so no tmux proof was used. |
Summary
Preserve a durable LM stage's pause-adjusted elapsed duration across a mid-stage
/workflow resume. Active session checkpoints now refresh timing even when the session file is unchanged, and a resumed process rebases the live timer from the persisted baseline so user-visible and lifecycle durations cover both process segments.Changes
startedAtand accumulateddurationMson every changed active-stage session checkpoint.Acceptance criteria coverage
sessionFile, while identical timing snapshots deduplicate.Validation
AGENT=1 bun test test/unit/*durable*.test.ts test/unit/store.test.ts test/unit/node-card.test.ts test/unit/run-detail-render.test.ts test/unit/status-list-render.test.ts test/unit/executor-lifecycle-persistence-1.test.ts test/unit/executor-lifecycle-persistence-2.test.ts— 252 passedbun run test:unit— passed in commit and pre-push hooksbun run typecheck— passedbun run lint— passedbun run check:file-length— passedgit diff --check— passedFixes #1713
Verified proof
Verified from the rebased PR worktree against the current base; no tmux proof was used because controllable-clock and fresh-backend process-boundary tests provide deterministic timing evidence.
28388b7b6e8a5466d9d36c719ee999ac0fa13d262d6ed612ec9c588b66413f73def11e50a56d2373bun run typecheck: passedbun run lint: passedbun run check:file-length: passed (2,062 tracked files checked)git diff --check: passedOverlap audit confirmed that later integration must retain both sides of the shared contracts: #1750's stage usage checkpoint/rollup metadata, #1748's resumability eligibility predicate, and #1758's completed-run snapshot reconstruction alongside this PR's
startedAt/durationMssession shape and timing-aware checkpoint identity. Added regression coverage for two successive process-boundary resumes with per-segment pauses, resumed task baseline propagation, and completed-output replay authority.Greptile Summary
This PR preserves durable workflow stage timing across mid-session resumes. The main changes are:
startedAtand pause-adjusteddurationMs.Confidence Score: 5/5
Safe to merge with minimal risk.
The changes are focused on durable timing metadata and resume timer rebasing. Tests cover repeated checkpoints, pause accounting, file-backed resumes, DBOS hydration, tasks, and completed replay. No verified functional or security issues were found.
No files require special attention.
What T-Rex did
Important Files Changed
Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Live as Active workflow process participant Backend as Durable backend participant Fresh as Resumed workflow process participant Replay as Later replay Live->>Backend: recordStageSessionCheckpoint(sessionFile, startedAt, durationMs) Live->>Backend: refresh checkpoint with latest pause-adjusted duration Fresh->>Backend: getStageSession(replayKey) Backend-->>Fresh: sessionFile + accumulated durationMs Fresh->>Fresh: rebasedStageStartedAt(durationMs, Date.now()) Fresh->>Backend: completed stage checkpoint with cumulative duration Replay->>Backend: stageCheckpointWithOutput(replayKey) Backend-->>Replay: cached output + latest metadata Replay-->>Replay: return durable output without live stage side effects%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant Live as Active workflow process participant Backend as Durable backend participant Fresh as Resumed workflow process participant Replay as Later replay Live->>Backend: recordStageSessionCheckpoint(sessionFile, startedAt, durationMs) Live->>Backend: refresh checkpoint with latest pause-adjusted duration Fresh->>Backend: getStageSession(replayKey) Backend-->>Fresh: sessionFile + accumulated durationMs Fresh->>Fresh: rebasedStageStartedAt(durationMs, Date.now()) Fresh->>Backend: completed stage checkpoint with cumulative duration Replay->>Backend: stageCheckpointWithOutput(replayKey) Backend-->>Replay: cached output + latest metadata Replay-->>Replay: return durable output without live stage side effectsComments Outside Diff (1)
packages/workflows/src/durable/stage-primitive.ts, line 318-319 (link)metadataValuetakes the first checkpoint withdurationMs, but active session checkpoints are now written repeatedly before completion andlistCheckpoints()returns them in ascendingcompletedAtorder. For schema-backed stages whose output checkpoint lacks timing, replay hydration merges the earliest active duration instead of the finalstage-metaor latest session duration, so graph/status replay can show stale elapsed time after a durable resume.Artifacts
Repro: focused Bun test harness for stale replay hydration metadata
Repro: failing Bun test output showing hydrated durationMs 111 versus expected 333
Prompt To Fix With AI
Reviews (4): Last reviewed commit: "Merge origin/main into fix/1713-preserve..." | Re-trigger Greptile