Skip to content

fix(cli): count font axes as motion in the sweep fingerprint - #3107

Open
miguel-heygen wants to merge 1 commit into
mainfrom
fix/sweep-fingerprint-font-axis
Open

fix(cli): count font axes as motion in the sweep fingerprint#3107
miguel-heygen wants to merge 1 commit into
mainfrom
fix/sweep-fingerprint-font-axis

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

Fold the computed font-variation-settings into the layout audit's per-element sweep fingerprint.

Why

The fingerprint is rect plus opacity, with an 8x8 pixel hash for <canvas> and <video>. A composition whose only change across the timeline is a font axis touches none of those, so all six samples hash identically and check reports sweep_static on a timeline that is visibly animating.

Duplexed variable fonts make this unavoidable rather than unlikely. Recursive holds a single advance width across its entire weight axis by design, so even the element rect stays fixed while the letterforms change underneath it.

This is the third instance of the same failure class in this function. The canvas-repaint and opacity-reveal cases already have regression tests sitting right where these two go, which is itself the argument that the fingerprint is the correct place to fix it rather than the compositions.

How

font-variation-settings reads "normal" on every element that does not use it, so no existing composition's fingerprint changes.

Test plan

  • Unit tests added/updated
  • Manual testing performed
  • Documentation updated (if applicable)

packages/cli full suite: 175 files passed, 1 skipped, 2489 tests passed, 2 skipped, 0 failed. oxfmt --check and oxlint clean on both files.

Two regression tests, both mutation-checked rather than trusted green:

Sabotage Failing test
Drop the axis string from the fingerprint changes the sweep fingerprint when only font-variation-settings moves
Add Math.random() to the axis read keeps the sweep fingerprint identical when nothing moves, font axes included

Exactly one test failed in each case (1 failed, 82 passed). The second is the load-bearing one: without it a fingerprint that varied on its own would make sweep_static unfireable and every green layout verdict meaningless, and the suite would still be green.

Worth knowing

A fresh worktree needs bun run build before vitest, or 68 files fail to collect on Cannot find package '@hyperframes/parsers/ff-binaries'. That is missing workspace build output, not a real failure, and it looks alarming.

feat/primitive-weight-wave depends on this landing first. Demonstrated on the same composition: the CLI without this fix reports sweep_static and check fails; with it, layout reports 0 issues across 9 samples and check passes.

The layout audit fingerprints each element by rect and opacity, plus an
8x8 pixel hash for canvas and video. A composition whose only change over
the timeline is font-variation-settings touches none of those, so all six
samples hash identically and the audit reports sweep_static on a timeline
that is visibly animating.

Duplexed variable fonts make it unavoidable rather than unlikely. Recursive
holds one advance width across its whole weight axis by design, so even the
element rect stays fixed while the letterforms change.

Fold the computed font-variation-settings into the per-element fingerprint.
It reads normal on every element that does not use the property, so no
existing composition's fingerprint changes.

This is the third instance of this failure class in the same function,
after the canvas-repaint and opacity-reveal cases whose regression tests
already sit alongside these. Two more join them: a scene where only the
axes move must change the fingerprint, and a scene where nothing moves
must hash identically twice. The second is the load-bearing one, since a
fingerprint that varies on its own would make sweep_static unfireable and
every green layout verdict meaningless.
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