Skip to content

fix(cli): sweep_static geometry fingerprint now covers SVG stroke/dash motion - #3914

Open
miga-heygen wants to merge 1 commit into
mainfrom
fix/sweep-static-svg-dash
Open

fix(cli): sweep_static geometry fingerprint now covers SVG stroke/dash motion#3914
miga-heygen wants to merge 1 commit into
mainfrom
fix/sweep-static-svg-dash

Conversation

@miga-heygen

Copy link
Copy Markdown
Contributor

Summary

hyperframes check's seek-audit fires a sweep_static finding ("Timeline did not advance under seek; every green verdict on this run is unreliable") whenever a per-sample geometry "fingerprint" is byte-identical across the whole run. That fingerprint already patches two known blind spots for motion that moves no bounding box and no opacity: a pixel hash for canvas/video/img, and a folded-in font-variation-settings string for variable-font-axis animation. An SVG stroke-dasharray/stroke-dashoffset "draw the line in" entrance (the standard technique for animating a connector/diagram line) shares the exact same blind spot — the path's bounding box comes from its static d geometry, not from how much of the stroke is currently dashed-visible — so a genuinely, visibly animating composition using it could get flagged as a frozen timeline.

The first version of this fix folded the two dash properties directly into the fingerprint's existing per-element loop. That loop only runs over elements that already pass a separate visibility gate requiring a non-degenerate bounding box (width/height > 0.5px) — and a perfectly straight (horizontal or vertical) connector line's real bounding box has near-zero width or height regardless of its stroke width, so that first version never actually covered the most common real shape for this exact animation pattern. Caught and fixed before merging (see test plan).

The shipped fix instead walks stroke-capable SVG shapes (path, circle, ellipse, rect, line, polyline, polygon) in a separate pass, gated only on paint-visibility (display/visibility/opacity — reusing an existing helper), not on bounding-box size, and folds each shape's parsed, rounded stroke-dasharray/stroke-dashoffset into the fingerprint.

Test plan

  • Two new tests mirror the existing font-variation-settings test pair exactly: one confirms the fingerprint changes across three dash-offset values, one confirms it stays identical when nothing moves (the "other direction" safety check — a fingerprint that varies on its own would make sweep_static unfireable and every green verdict meaningless). Both use a deliberately degenerate (zero-height) mocked bounding box for the connector, to prove the new independent pass — not the pre-existing per-element loop — is what's under test.
  • Could not execute layout-audit.browser.test.ts in this sandbox (this file has no build step and is injected into a real page via window.eval; its happy-dom test environment fails to collect for an unrelated, pre-existing reason). Verified instead via a real-Chromium (Puppeteer) harness driving the actual script against a real SVG path: confirmed the exact degenerate-bbox scenario (a straight connector line) produced an unchanging fingerprint before this fix and a correctly-varying one after, both for the initial design and again after the redesign.
  • bunx tsc --noEmit, oxlint, oxfmt --check clean on both touched files.
  • An adversarial review pass caught that the first design's fix was effectively inert for straight connector lines (the most common real case) before this ever reached CI; the shipped design was verified against that same failure mode directly.

Deliberately out of scope: other "moves nothing else" SVG reveal patterns (fill-opacity, stroke-opacity, gradient stop-opacity) aren't covered — this closes the specific stroke/dash gap the report described, not every conceivable adjacent one.

…h motion

check's seek-audit fingerprint already folds font-variation-settings into
each element's per-element segment and a pixel hash for canvas/video/img,
to catch motion channels that move no bbox and no opacity. An SVG
stroke-dasharray/stroke-dashoffset "draw the line in" entrance shares that
exact blind spot, so a genuinely animating composition using it could get
flagged as a frozen timeline.

A dedicated pass now walks stroke-capable SVG shapes independently of the
per-element loop, gated on paint-visibility rather than bounding-box size —
a perfectly straight connector line's raw path geometry has near-zero
width or height regardless of stroke-width, so it fails the per-element
loop's bbox gate and would otherwise never be reached.

Co-Authored-By: Miguel Angel <miguel.sierra@heygen.com>
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