Skip to content

fix(engine): scale static-frame verification budget with the job - #6901

Merged
miguel-heygen merged 4 commits into
mainfrom
fix/static-verify-adaptive-budget
Oct 31, 2026
Merged

miguel-heygen merged 4 commits into
mainfrom
fix/static-verify-adaptive-budget

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

What

Static-frame verification stopped after a fixed 15 s, so on long or 4K jobs most static ranges went unverified and were captured frame by frame (refs #6881).

The budget is now max(15 s, 1.5 x planned screenshots x the first shot's seek+capture time), capped at 300 s. Short jobs keep the 15 s floor and behave as before. Exhaustion still fails closed (outcome time_budget, normal capture continues), and a mismatch still disables dedup.

Why this shape

The plan already bounds the work (about 3 screenshots per 24 frames saved), so the budget follows that cost at the measured speed. If later shots run well past the first one's pace, it still gives up. The reporter measured nothing gained past 600 s, so the ceiling is 300 s.

Tests

  • New: a 40-range job with 1 s shots verifies all 40 (fails on main at 15 s); shots that keep slowing down still end in time_budget.
  • Updated: the 8,400-frame test with 8 s shots now stops at the 300 s ceiling (38 shots) instead of 2 shots.
  • Engine density test file: 13/13, three runs. Confirmed the two changed tests fail on the old code.

fails without the fix: frameCapture-staticDedupVerifyDensity.test.ts › "scales the wall budget with planned work instead of stopping at 15 s"

Before / after

600 s, 1920x1080, 30 fps transparent overlay (120 caption holds), PNG sequence, 2 workers pinned to the same 4 cores, one run per arm, same machine:

wall ranges verified frames reused
main 718 s 26 of 240 (stopped at 15 s) 3380 of 9000 per worker
this PR 171 s 240 of 240 (77 s) about 8200 of 9000 per worker

All 18000 output frames are byte-identical between the two (md5 of every frame, same digest). Box load was around 10 during both runs, so treat the ratio as indicative.

Size

Under 100 changed source lines.

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy did not run: 0 of 15 shards reported results; see the shard jobs.

Nothing was compared with the base branch.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes at 11216b5d.

1. The body has no fails without the fix: line. This is a fix PR. The Tests section says the new 40-range test "fails on main at 15 s" and that the two changed tests fail on the old code, but the gate needs a fails without the fix: line that names the test. For example: fails without the fix: frameCapture-staticDedupVerifyDensity.test.ts › "scales the wall budget with planned work instead of stopping at 15 s".

2. The comment on the constants now says the opposite of what the code does. frameCapture.ts ~3651–3657 still reads "Bound wall time … so a long composition cannot spend minutes proving an optimization before the real render starts", directly above STATIC_VERIFY_MAX_MS = 15_000. With this PR, a long composition can spend up to 5 minutes before the render starts, and that is the point of the change. Rewrite the comment to say why:

  • 15 s is now the floor.
  • The budget follows planned shots × the first shot's time.
  • 300 s is the ceiling (the reporter saw no gain past 600 s).
  • Exhaustion still fails closed.

Not blocking:

  • firstShotMs times only capture(), but spent also counts seekToFrame and the comparisons. If seeking is slow, the budget runs out early. That fails closed, so it is safe, but it is worth a word in the comment, or time the seek too.
  • If the first screenshot is unusually slow (cold page), it can set the budget near 300 s for the whole job. That is bounded by the ceiling, so it is fine as long as the trade-off is intentional.
  • The body still owes a before/after render time from a long composition. Please add it before merge, as promised.

The logic looks right otherwise: floor and ceiling via max/min, the hard count cap still checked, the 8,400-frame test reaching 38 shots matches the 300 s ceiling at 8 s per shot, and the slowing-shots test proves it still fails closed.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving c372b2a6. Both blockers from my last review are fixed:

  • The body now has a fails without the fix: line naming "scales the wall budget with planned work instead of stopping at 15 s".
  • The comment above the constants now describes the scaled budget correctly: 15 s floor, 1.5 × planned shots × the first shot's seek+capture time, 300 s ceiling, failing closed for the runs not yet verified. It matches the loop, where a budget exit keeps the completed runs.

Also checked:

  • shotStart now comes before seekToFrame, so the first-shot estimate includes the seek, as I suggested.
  • CI run 41246015236 is green (39 success, 13 skipped).

Still open, not blocking: the before/after render time from a long composition that the body promises.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 31, 2026
@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit f3cdf2b Oct 31, 2026
136 of 137 checks passed
@miguel-heygen
miguel-heygen deleted the fix/static-verify-adaptive-budget branch October 31, 2026 23:14
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.

1 participant