Repository navigation
feat(cli): tell authors in check why motion blur is off - #5992
vanceingalls wants to merge 1 commit into
Conversation
d306aaa to
201da6a
Compare
b2fce35 to
0b3f708
Compare
201da6a to
b036dee
Compare
0b3f708 to
d5e218c
Compare
miguel-heygen
left a comment
There was a problem hiding this comment.
Reviewed exact head d5e218c7565b433df887c803fa4ad5de20c44b09 relative to b036deef790b8897bd6c805b94ff861182baec2a.
Audited probe-before-grid and suspend-to-plain-DOM order, severity/fixHint mapping, requested-root selection and console echo deduplication. Local authored mapping/page tests19/19 pass, including the GPU hint now requiring a separate/flattened render rather than an in-document subcomposition. Own delta has no additional demonstrated blocker; #5971's omitted animated hidden face remains invisible to this consumer.
Independent revision-bound review of the nine-PR composition. Earlier approvals/requests covered older heads. Current saved head/review/inline/check snapshot has no fresh duplicate finding and no failing/pending latest check. Stacked broad-suite skips are not executed tests.
Audited: CLI probe before grid audits, suspend to plain DOM, severity and fixHint mapping, requested-root choice and console warning deduplication.
Limits: Composed local focused run:196 authored core tests pass; separate WAAPI/CLI44 pass. Synthetic geometry/canvas controls, not fresh browser pixel/performance proof. No app/model/provider call, source fix, merge or release.
— Magi / desktop-review
Verdict: APPROVE
Reasoning: No additional blocker in this own delta. The later #5971 defect must be repaired before landing the complete stack.
Blur that turns itself off is silent in the output, so an author who asked for data-motion-blur="on" cannot tell. Have hyperframes check read the runtime's decision through probe() and the reason codes from the previous change. check reports motion_blur_off as a warning with a fix hint for a root that asked for blur and got none (an iframe in the root gets its own hint), motion_blur_no_movers when nothing moves enough to blur, and motion_blur_unverified when the check browser has no html-in-canvas to decide with. The console echo of the same message is dropped so a finding is not shown twice. check asks the runtime which root wants blur instead of reading attributes itself, so data-root="true" is honoured, and after probing it suspends blur painting for the rest of the session: its audits read plain DOM, which removes the roughly 10x slowdown of auditing a wrapped composition. It never sets the page's off switch, which would change the probe's answer. Tests drive a finding from the page to the check output, with its fix and without its echo. Folded review fixes: R9 (check hint), R12, R13 (check half), T6. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
b036dee to
7693556
Compare
d5e218c to
1964007
Compare
miguel-heygen
left a comment
There was a problem hiding this comment.
Reviewed exact head 1964007049ed40416b05ff4e83412915b26398f3 against its actual parent 7693556e8860654d3b40dd99d238445b58996aee and the previously reviewed tree.
The restack changes only the inherited detector/test files relative to its previously reviewed tree; its CLI probe/suspend/finding implementation is unchanged. The repaired candidate scan therefore reaches the existing check consumer without a new consumer delta.
Independent verification: own-head and composed-tip synthetic computed-style controls 4/4 pass; predecessor witness remains red (inline positive passes). Exact-source authored detector suites run locally:31 own-head +47 tip tests pass, including WAAPI containment, named/multiple animations and cached-candidate retention. The computed animation-name seam is explicit because jsdom does not expand animation shorthand. These are deterministic detector controls, not fresh Chrome pixel/performance proof.
Current exact-head check snapshot has no failed or pending check. Read completed regression gate logs and executed #5991 preflight lint/format output; stacked broad-suite skips and aggregate gate success do not prove execution of the new pixel/unit suites. Author Chrome152 experiments, 26ms scan cost and package-budget margin remain attributed.
Known sampling limit remains: a short WAAPI-only face absent at every scan cannot enter the cached set. This bounded sampling residual differs from the repaired omission of ordinary animation-derived candidates; no universal detection guarantee is claimed. No new source blocker found in this successor composition. No browser/app/model call, merge or release.
— Magi / desktop-review
Verdict: APPROVE
Reasoning: The earlier animated-face candidate blocker is repaired and retained through the restacked composition; no additional blocking change was found.

What
Tells authors in
hyperframes checkwhy motion blur is off.checkreads the runtime'sprobe()for a page whose root asked for blur and reportsmotion_blur_off(warning, with a fix hint per reason code; theiframe-in-roothint now names<iframe>,<object>,<embed>and custom elements, which are all re-initialised when blur wraps the root, and a rootmix-blend-modehas its own: move it to a child element, or drop motion blur),motion_blur_no_movers(info, when nothing moves fast enough to blur) andmotion_blur_unverified(info, when the check browser has no html-in-canvas to decide with).data-root="true"is honoured and the first composition's attribute is not mistaken for the runtime's choice. The finding is anchored (selector, data attributes, bounding box) on that same root,data-root="true"first and else the first composition, not on the first[data-composition-id]in the document.suspend()for the rest of its session. Its audits read plain DOM, so they no longer pay the roughly 10x slowdown of auditing a wrapped composition. It never sets the page's off switch, which would change the probe's answer.[motion-blur] off: …) is dropped when a finding says it, so a finding is not shown twice; an unrelated console warning, and an error that only starts like the echo, are kept.Why
Part 9 of 9 in the capture motion blur stack: #5875 → #5967 → #5968 → #5969 → #5970 → #5971 → #5990 → #5991 → #5992. It builds on #5991, which gives the runtime the reason codes,
probe()andsuspend()this reads.The stack delivers opt-in capture motion blur for compositions, in Studio preview and in renders, drawn with Chrome's html-in-canvas. Blur turns itself off in several cases, and without this an author who asked for
data-motion-blur="on"cannot tell from the check output.Notes
data-motion-bluris not supported: the attribute has to be in the HTML for the render-mode hint, andcheckreports only what the runtime decided.overflow:hidden; a 2D flip throughscaleX = 0blending as rotation; sub-pixelleftsteps in whole px; a fast child inside a parent that moved earlier not blurred; SVG elements not scanned; shadow DOM not scanned for backface; blurred preview updating at half rate; video preview about 2–3% darker; worker-count output differences; the scan leaving about one level of noise) are unchanged by this PR.Testing
checkMotionBlur.test.ts: each finding, its severity and fix hint (the widened iframe hint,root-blend-mode, and the accelerated-canvas hint, which now says the scan covers sub-compositions too and offers rendering that effect separately or flattening it out of the page, or droppingdata-motion-bluron the composition), and the console-echo filter;checkMotionBlur.page.test.ts: the probe serialised into the page, which root it asks about, thesuspend()right after the probe (and a runtime withoutsuspend), the mover count, and a page that never opted in.checkBrowser.test.ts: a blur finding reaches the check output with its fix and its anchor, the anchor is thedata-root="true"composition when a sub-composition comes first in the document, once when a second Chrome shares the sampling, the runtime's duplicate console line is dropped while unrelated warnings and look-alike errors stay, and nothing is added for a page that never opted in.check.test.tsstill passes.bun run buildandtsc --noEmitin cli pass; comment ratchet against feat(core,engine): report why blur is off, and what each render session did #5991's branch passes; every package is within its size budget.🤖 Generated with Claude Code