Repository navigation
Inherited cost estimate quoted unchanged when frame count differs: 7x under-quote on multi-shot Ref2VA #821
Description
Field report
validate_workflow quoted 7.8 min (basis: inherited, from templates/minimax/reference-to-video) for two multi-shot Ref2VA render jobs. Each actually took ~56 min per card, about 7× more. The plan reported differs: ['frame count'], but the minutes went out unchanged. Each job had 3-4 shots and 768-899 rendered frames, against the template's single 124-frame clip. An earlier run showed the same gap at about 2×.
Cause
inherited_observed(dw/server/deps.py:174) prices an inline workflow from the observed runs of the catalog template with the same pipeline identity.inherited_differences(dw/vram_inheritance.py:78) detects the frame-count difference, but it only goes into a warning (dw/server/routes/jobs.py:930).minutesis never adjusted.- Shot count is not counted.
template_identityaccepts any number of steps that share one identity, so 3-4 H3 steps are priced as one template run. - Frame count is not scaled. Driver values only carry over when the inline workflow uses the template's own variable names.
Scaling by frames would have been close: 899/124 ≈ 7.2 and 768/124 ≈ 6.2, against an actual 56/7.8 ≈ 7.2. Each shot is a separate generation, so cost grows roughly in line with total rendered frames. plan_cuts already returns render_frames "for quoting the cost".
Proposed fix
When an inherited estimate's differs includes frame count, or the workflow runs the identity in more than one step, do one of these:
- scale
minutesby (total rendered frames across steps / template frames) and mark itbasis: derived, in line with Assess: acknowledged_cost gate should bind to a budget/fingerprint, not just a boolean #85; or - withhold the figure (
basis: unknown), in line with Cost estimate: derived basis scales by entry count, not frames, and skips the #593 field-shift check #796, which already withholds observed history when an entry's frame count moves.
Never quote the template's figure unchanged. Model loading is a fixed cost that doesn't grow with frames, so scaling the whole number linearly over-quotes slightly. That is the safe direction to be wrong in.
Acceptance
- A multi-step inline H3 workflow totalling ~900 frames, priced against a 124-frame template, does not quote the template's minutes as they stand.
- A test pins both the multi-step case and the single-step longer-
num_framescase.
Activity
dkackman commentedon Oct 11, 2026
triage: work — not fixed on develop @ 84fdf78 (#796's 8f23dea gates observed history only; the inherited basis still quotes template minutes unchanged). Fix scales or withholds it in the estimate path (
dw/server/deps.py/dw/vram_inheritance.py/routes/jobs.py), no new surface. (triage by claude-opus-5-5 via anthropic)fix(plan): #821 - withhold the inherited estimate when the inline wor…
dkackman commentedon Oct 11, 2026
Fixed in bf65c85 on develop, deployed to lem (12:33, healthy). Model: claude-sonnet-5-5 via anthropic.
Chose the withhold option.
inherited_observed(dw/server/deps.py) now skips a template candidate when (a) the inline workflow has a different number of pipeline steps than the template (multi-shot), or (b) after applying the matched bucket's driver values, the inline frame count still differs from the template's (literal/renamednum_frames). With no candidate left the estimate comes backbasis: unknown, not the template's minutes. A workflow that shares the template's driver variable (e.g.num_framesargument) still gets its exact bucket's figure, unchanged behavior.Not done: scaling by total rendered frames (
basis: derived) — only withholding. Tests in tests/test_inherited_cost.py: 3-step inline vs 1-step template, literal 899 frames vs 124-frame template (both → no inherited figure), and shared-driver bucket still priced.To verify: validate_workflow on an inline multi-shot H3 Ref2VA workflow (3-4 shots, ~900 frames) should not show 7.8 min / basis inherited.
dkackman commentedon Oct 11, 2026
Architecture review queued by the loop driver: this hand-off changed
dw/ordw_mcp/ondevelop(84fdf7859f..bf65c85410: dw/server/deps.py). The reviewer checks it againstdocs/ARCHITECTURE.mdbefore the tester verifies.dkackman commentedon Oct 11, 2026
Architecture review: pass (reviewer, claude-opus-5-5 via anthropic).
Read:
git diff 84fdf785..bf65c854 -- dw/ dw_mcp/(onlydw/server/deps.py:_pipeline_steps,_scales_past_template, the skip ininherited_observed) againstdocs/ARCHITECTURE.mdand stage-c-guardrails item 3.vram_inheritance.inherited_differencesand doesn't re-derive it._pipeline_stepsuses the same "step with apipelinedict" predicate astemplate_identity, but both modules belong to the same row, so no rule moved.tests/test_inherited_cost.pycases. That's worth a line at the next consolidation.deps.pyand in_scales_past_template's docstring. NoCLAUDE.mdchange.No
arch-approvedwaiver was needed. The issue is back to the tester for verification.dkackman commentedon Oct 11, 2026
Verified on lem (develop @ 264c9a1) by the tester, claude-opus-5-5 via anthropic.
All calls were
validate_workflowwith an inline H3 Ref2VA workflow that has the same pipeline identity astemplates/minimax/reference-to-video(124 frames, 960x544, 9 steps, observed 7.75 min over 33 runs):num_framesvariable = 124minutes: 7.8,basis: inherited,inherited_from: templates/minimax/reference-to-video,differs: [quantization]num_framesvariable = 294minutes: null,basis: unknownnum_frames: 294minutes: null,basis: unknownminutes: null,basis: unknownThe control proves that the inline identity still inherits, so the
unknownresults come from the new skip and not from an identity mismatch. The template's minutes are no longer quoted unchanged for a multi-step workflow or a different frame count, which meets the acceptance. As the hand-off says, the fix withholds the figure rather than scaling it (basis: derived). The issue offered either option.