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
idea: step cache across workflow identities (renamed and inline copies hit) #912
Proposal split out of #866 plan v3 (stage 0, #905). Don asked for it as an idea: #866
claude-opus-5-5 / anthropic, lead
Idea
Keep a card's step cache across a workflow identity switch, keyed by the output identity alone, so a renamed copy or an inline copy of a stored workflow can hit it.
Why
#905 keys the plan fingerprint and step cache only by what can change the output. That pays off only for the same stored workflow edited in place. The cache belongs to one worker (one card), and dw/worker.py_prepare_workflow clears it when that worker's workflow identity changes. Jobs are routed to a card by identity, so a copy under another name, or the inline JSON an agent gets from get_workflow, never sees the original's cached steps.
Scope to decide
This is memory retention and routing, not a key audit:
how much a card keeps across identities, and how it's evicted;
whether routing prefers the card that holds a matching output identity;
a cache hit replays files to their recorded paths (subfolder, file_base_name stay in the step-cache key). Serving a hit to a new destination means copying the files there.
Related: the validate probe ignores identity (bug filed alongside this).
claude-opus-5-5 / anthropic, lead. Checked against develop @ 0dce4cb (#905 and #911 landed).
Verdict: don't build. Instead, add one paragraph of docs saying a copy starts cold
The idea assumes a renamed or inline copy would hit if the card kept its cache. The code check found two places where it still wouldn't. Separately, the demand check found no real run that would have hit.
Value: none found in Don's use.
Don's real driving in h3-quality and known-issues runs inline workflows. Each variant gets its own id: H3Ladder_P1_base30_fbc05, H3Ladder_P2_base12_fbc05, KnownIssuesRestorePointHD_tag, and so on.
The step cache keys entries on (definition id, step_name) (dw/step_cache.py:44-48, :627), not on the identity tuple. A copy with a new id misses whether or not the card keeps its cache.
Those variants also differ in the one expensive step: steps, cache config and attention backend change on every H3 rung. There was nothing upstream for a hit to skip.
Re-running the same stored workflow with changed arguments hits.
Re-running the same inline JSON under the same id hits, because the identity is ("inline", id) (dw/worker_protocol.py:242-249).
rerun_job hits.
That covers the edit-and-retry loop. What it misses is running one stored workflow by name and its inline copy back and forth on the same card. Nothing in the job history does that.
Build cost: about $10-16 over 3 stages.
(1) Retain the cache across a switch, with eviction.
(2) Copy files on a hit to a new destination.
(3) Prefer the warm card in routing.
Each touches worker, routing and probe code at the reach of recent server fixes, so $3-6 a session.
Inertia: high for what it buys.
Correctness seams.
A hit republishes files from the other workflow's output folder: the folder is <output_dir>/<identity>/<run>/ (dw/runs.py:296), and the step cache compares only the output_dir root.
Republishing those paths mis-attributes outputs in the gallery, in job_for_file and on delete.
Avoiding that needs a copy on every cross-identity hit: disk use, plus one more write path through validate_output_path.
Memory.
_cleanup_all clears the step cache on a switch because a cached Result can hold GPU tensors tied to components released at the same moment (dw/worker.py:703-705).
One paragraph of docs (recommended). Add it beside the existing step-cache scope paragraph at docs/WORKFLOW_GUIDE.md:2636-2644, which already explains the workspace scope. It would say:
the cache is per card and per workflow identity: a stored name, or an inline id;
to reuse cached upstream steps, rerun the same workflow (same name, or the same inline id) with changed arguments;
a renamed copy, a new inline id, or switching between a stored workflow and its inline copy starts cold.
It goes to the implementer, docs only: an estimated $1-2, verified over MCP by get_guide("workflows", section=...) returning the text.
a field-report showing an agent switching between a stored workflow and its inline copy (same id), where the upstream steps are costly;
or a multi-step template whose expensive first stage is commonly shared across differently-named workflows. Then it would be worth keying on output identity and copying files.
If Don overrides to build: the shape it would take
So the override is a one-reply decision, this is the design I'd write up as v2.
Problem. A cached step is lost when a card switches to a different workflow identity that would produce the same step.
run stored A with seed s, then its inline copy (same id) with the same arguments on the same card: cached_steps > 0 in validate, reused: true steps in get_job, and output files under the copy's own run folder, not A's;
deleting A's run doesn't break the copy's files;
a different-id copy reports cached_steps: 0.
B: route to the card that holds the entry.
choose_slot prefers it after rerun affinity and before same-identity affinity, and the probe routes the same way.
Server deploy. About $4.
Acceptance:
with two cards, the copy goes to the card that ran A, and get_job.device matches;
when that card is busy, the copy goes to an idle card and reports cold.
Review of plan v1 — approved: don't build, file the docs fix (Q1 yes, Q2 no)
Checked against origin/develop @ 9dfb9e6. The code claims hold:
the step cache is keyed on (workflow_id, step_name) (dw/step_cache.py, StepCache.get);
an inline job's identity is ("inline", id) (dw/worker_protocol.py, workflow_identity);
an identity switch runs _cleanup_all, which calls step_cache.clear() (dw/worker.py);
test_entries_are_scoped_to_the_workflow_id is the guard against one workflow republishing another's paths;
choose_slot prefers rerun card, then warm identity, then an idle card.
Q1: yes, file the docs paragraph, with two amendments:
Name the commoner cold path. Running any other workflow on the card in between empties the cache: A → B → A runs the second A cold. That's far likelier in real use than switching between a stored workflow and its inline copy. On a multi-card server, warm-identity routing mostly avoids it unless that card is busy. On a single card it happens every time.
Be exact about "changed arguments". Only arguments that reach later steps leave the earlier steps cached. Changing an argument the expensive first step reads re-runs it. Add a line saying validate_workflow's plan.cached_steps is the way to check before running.
Q2: no. Moot under "don't build", and dropping id from the key would remove the guard test.
Reopen criteria: add a third trigger. A field report showing an agent alternating two different workflows on one card (A → B → A), where the upstream steps are costly. That would argue for keeping the cache across a switch even without cross-identity hits.
Lead: file the docs fix to owner:implementer with the amendments above, then close #912wontfix.
Per Don's review: no stages are filed. The docs paragraph (Q1 yes) went to the implementer as #914, with both amendments:
it names the common cold path: A → B → A on one card;
it says exactly which argument changes keep earlier steps cached, and to check with validate_workflow's plan.cached_steps.
Q2: no, so the (id, step) key and test_entries_are_scoped_to_the_workflow_id stay.
This reopens if any one of these turns up:
a field-report of an agent switching between a stored workflow and its inline copy (same id), where the upstream steps are costly;
a multi-step template whose expensive first stage is commonly shared across differently named workflows;
a field-report of an agent alternating two different workflows on one card (A → B → A) where the upstream steps are costly. That would argue for keeping the cache across a switch even without cross-identity hits.
Activity
dkackman commentedon Oct 15, 2026
Plan v1: step cache across workflow identities
claude-opus-5-5 / anthropic, lead. Checked against
develop@ 0dce4cb (#905 and #911 landed).Verdict: don't build. Instead, add one paragraph of docs saying a copy starts cold
The idea assumes a renamed or inline copy would hit if the card kept its cache. The code check found two places where it still wouldn't. Separately, the demand check found no real run that would have hit.
Value: none found in Don's use.
h3-qualityandknown-issuesruns inline workflows. Each variant gets its ownid:H3Ladder_P1_base30_fbc05,H3Ladder_P2_base12_fbc05,KnownIssuesRestorePointHD_tag, and so on.(definition id, step_name)(dw/step_cache.py:44-48,:627), not on the identity tuple. A copy with a newidmisses whether or not the card keeps its cache.field-reportissue asks for this, and no same-class bug does either. The only cross-identity runs in the job list are the tester's bug: validate's cached_steps probe ignores the card's warm workflow identity #911 verification, inregression-complete.What already hits today.
idhits, because the identity is("inline", id)(dw/worker_protocol.py:242-249).rerun_jobhits.Build cost: about $10-16 over 3 stages.
Inertia: high for what it buys.
<output_dir>/<identity>/<run>/(dw/runs.py:296), and the step cache compares only theoutput_dirroot.job_for_fileand on delete.validate_output_path._cleanup_allclears the step cache on a switch because a cachedResultcan hold GPU tensors tied to components released at the same moment (dw/worker.py:703-705).choose_slot(dw/server/pool.py:119-135) by output identity, which has to agree with the probe. bug: validate's cached_steps probe ignores the card's warm workflow identity #911 just fixed the case where those two disagreed.tests/test_worker_execute.py:94-173,:690(bug: validate's cached_steps probe ignores the card's warm workflow identity #911);tests/test_worker_pool.py:704-883;tests/test_step_cache.py:399, which is what currently stops one workflow republishing another's paths.docs/WORKER_GUIDE.md:21,31-36anddocs/ARCHITECTURE.md:69.Reversibility. Good. There's no MCP, REST or syntax surface, so it could be taken out without a
breaking-change. That's the one point in its favour.Cheaper alternatives:
Do nothing.
validate_workflowalready reportsplan.cached_steps: 0for a copy, now that bug: validate's cached_steps probe ignores the card's warm workflow identity #911 has landed. An agent that checks before quoting sees the cold run coming. Gives up nothing measured.One paragraph of docs (recommended). Add it beside the existing step-cache scope paragraph at
docs/WORKFLOW_GUIDE.md:2636-2644, which already explains the workspace scope. It would say:id;id) with changed arguments;id, or switching between a stored workflow and its inline copy starts cold.It goes to the implementer, docs only: an estimated $1-2, verified over MCP by
get_guide("workflows", section=...)returning the text.Overlap.
What would reopen it:
field-reportshowing an agent switching between a stored workflow and its inline copy (sameid), where the upstream steps are costly;If Don overrides to build: the shape it would take
So the override is a one-reply decision, this is the design I'd write up as v2.
ids, unless Q2 says otherwise.Stages:
Results tosaved_files-only entries instead of clearing them, so no GPU tensors outlive their components.(id, step), plus the output identity from #866 stage 0: key the plan fingerprint and step cache only by what changes the output #905.validate_output_path. It doesn't republish them.id) with the same arguments on the same card:cached_steps> 0 in validate,reused: truesteps inget_job, and output files under the copy's own run folder, not A's;idcopy reportscached_steps: 0.choose_slotprefers it after rerun affinity and before same-identity affinity, and the probe routes the same way.get_job.devicematches;Questions
owner:implementer.wontfixwith nothing filed.idhit too?idfrom the step-cache key, which reopens the guard attests/test_step_cache.py:399.Reply in comments and hand back with
owner:lead. Approve by addingstatus:plan-approvedyourself. No agent may set it.dkackman commentedon Oct 15, 2026
Review of plan v1 — approved: don't build, file the docs fix (Q1 yes, Q2 no)
Checked against
origin/develop@ 9dfb9e6. The code claims hold:(workflow_id, step_name)(dw/step_cache.py,StepCache.get);("inline", id)(dw/worker_protocol.py,workflow_identity);_cleanup_all, which callsstep_cache.clear()(dw/worker.py);test_entries_are_scoped_to_the_workflow_idis the guard against one workflow republishing another's paths;choose_slotprefers rerun card, then warm identity, then an idle card.Q1: yes, file the docs paragraph, with two amendments:
validate_workflow'splan.cached_stepsis the way to check before running.Q2: no. Moot under "don't build", and dropping
idfrom the key would remove the guard test.Reopen criteria: add a third trigger. A field report showing an agent alternating two different workflows on one card (A → B → A), where the upstream steps are costly. That would argue for keeping the cache across a switch even without cross-identity hits.
Lead: file the docs fix to
owner:implementerwith the amendments above, then close #912wontfix.dkackman commentedon Oct 15, 2026
Disposition: don't build (plan v1, approved)
claude-opus-5-5 / anthropic, lead
Per Don's review: no stages are filed. The docs paragraph (Q1 yes) went to the implementer as #914, with both amendments:
validate_workflow'splan.cached_steps.Q2: no, so the
(id, step)key andtest_entries_are_scoped_to_the_workflow_idstay.This reopens if any one of these turns up:
field-reportof an agent switching between a stored workflow and its inline copy (sameid), where the upstream steps are costly;field-reportof an agent alternating two different workflows on one card (A → B → A) where the upstream steps are costly. That would argue for keeping the cache across a switch even without cross-identity hits.Closing
wontfix.