You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Step cache doesn't survive a killed worker process (disk-backed persistence + resume) #244
When a for_each job (e.g. tool-musical-trailer's 12-entry shot step) is killed partway through, rerun_job restarts from the first entry (shot@s01) rather than resuming after the last completed member.
Suggested fix: commit each for_each member's step-cache entry as soon as that member completes, rather than only at job completion. This is what would make a mid-run failure (OOM kill, manual cancel, crash) cheap to recover from instead of re-paying the full cost of every already-finished member.
triage: escalate — the premise is off, and the real fix is an engine change. step_cache.put already runs per step, immediately after each step saves (dw/workflow.py ~L1319), and a for_each member is an ordinary step after expansion — so completed members are committed as they finish. What is lost is the cache itself: dw/step_cache.py is in-memory in the worker process, so a SIGKILL (or a cancel that terminates the worker) takes every entry with it, and the rerun starts from shot@s01. Also the cache is disabled entirely when the workflow sets no seed. Resuming a killed job means either a disk-backed step cache or rebuilding hits from the previous run's manifest + files on rerun — a new engine concept (partial-run resume) that needs sign-off on semantics (what counts as a valid hit after a crash, cache invalidation, interaction with new_seed). (triage by implementer agent, model opus via provider anthropic)
The "cache never gets populated for a randomly-seeded run at all" part is split out as Step cache disabled wholesale for randomly-seeded runs, even within a single run #251 (a plain internal fix — the cache gate was wrongly keyed on whether the user supplied a seed rather than whether one was resolved; safe to fix immediately, no design needed).
a persistence format for cache entries (versioned, atomic writes so a kill mid-write can't leave a corrupt/half-written entry)
rehydrating a full Result (not just file paths) from disk for any downstream step whose result is still needed after restart — per media type (image/video/audio/text), since a fresh process has nothing in memory
lifecycle: where entries live relative to a job's run directory, and how/when they're cleaned up
interaction with new_seed reruns and the existing file-existence/generation invalidation checks in step_cache.py, which should carry over largely as-is
Staying parked at owner:don / status:needs-approval pending a written proposal on the above.
More evidence from Don's dw findings ledger (DW-15, tool-musical-trailer): the same kill, logged independently. Triage against develop f11ac2a found nothing new beyond this issue's existing analysis. (claude-opus-5-5 via anthropic, filing session)
Linking the design: resume.md scopes this issue's fix as a feature: rehydrate the existing step cache from run-directory manifests, rather than building a second cache. A run is resumable only if it's reproducible, so the seed changes are a prerequisite. todo.md ranks it Tier 3: meaningful for expensive multi-step runs, but a correctness-sensitive engine change.
Labeled feature and priority:3 as part of migrating docs/proposals/ to issues (harnest roadmap R11). It stays parked with Don. Starting it means handing it to the feature lead rather than to the implementer.
claude-opus-5-5 via anthropic, interactive session with Don.
Activity
dkackman commentedon Sep 19, 2026
triage: escalate — the premise is off, and the real fix is an engine change.
step_cache.putalready runs per step, immediately after each step saves (dw/workflow.py ~L1319), and afor_eachmember is an ordinary step after expansion — so completed members are committed as they finish. What is lost is the cache itself:dw/step_cache.pyis in-memory in the worker process, so a SIGKILL (or a cancel that terminates the worker) takes every entry with it, and the rerun starts fromshot@s01. Also the cache is disabled entirely when the workflow sets noseed. Resuming a killed job means either a disk-backed step cache or rebuilding hits from the previous run's manifest + files on rerun — a new engine concept (partial-run resume) that needs sign-off on semantics (what counts as a valid hit after a crash, cache invalidation, interaction withnew_seed). (triage by implementer agent, model opus via provider anthropic)dkackman commentedon Sep 19, 2026
Split per discussion with Don:
Result(not just file paths) from disk for any downstream step whose result is still needed after restart — per media type (image/video/audio/text), since a fresh process has nothing in memorynew_seedreruns and the existing file-existence/generation invalidation checks instep_cache.py, which should carry over largely as-isStaying parked at
owner:don/status:needs-approvalpending a written proposal on the above.[-]A killed for_each job doesn't commit completed members' step cache[/-][+]Step cache doesn't survive a killed worker process (disk-backed persistence + resume)[/+]dkackman commentedon Sep 22, 2026
More evidence from Don's dw findings ledger (DW-15,
tool-musical-trailer): the same kill, logged independently. Triage against develop f11ac2a found nothing new beyond this issue's existing analysis. (claude-opus-5-5 via anthropic, filing session)dkackman commentedon Sep 23, 2026
Linking the design: resume.md scopes this issue's fix as a feature: rehydrate the existing step cache from run-directory manifests, rather than building a second cache. A run is resumable only if it's reproducible, so the seed changes are a prerequisite.
todo.mdranks it Tier 3: meaningful for expensive multi-step runs, but a correctness-sensitive engine change.Labeled
featureandpriority:3as part of migratingdocs/proposals/to issues (harnest roadmap R11). It stays parked with Don. Starting it means handing it to the feature lead rather than to the implementer.claude-opus-5-5 via anthropic, interactive session with Don.
docs(proposals): retire the two shipped proposals