Repository navigation
feat(check): add data-layout-allow-caption-zone waiver - #2853
Conversation
Opt intentional lower-third copy out of caption_zone_collision. Co-authored-by: Cursor <[email protected]>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
james-russo-rames-d-jusso
left a comment
There was a problem hiding this comment.
Reviewed at 37c5ea8.
Small, sharp addition — data-layout-allow-caption-zone slots cleanly next to the existing three waivers and both defense layers (browser candidate filter + pipeline captionFinding skip) are wired up. Tests cover own-element (pipeline) + ancestor (browser) placement. No blockers.
Three lens-level concerns / nits on the inline comments below, plus one question:
Question — presence semantics. .closest("[data-layout-allow-caption-zone]") and "data-layout-allow-caption-zone" in candidate.dataAttributes both treat data-layout-allow-caption-zone="false" as still-suppressing. Consistent with the other three data-layout-allow-* waivers, so probably intended — flagging only in case you'd prefer explicit falsy values to un-suppress.
What I didn't verify:
- Any downstream layout skill / template file that lists the four current waivers by name would need this new entry appended too. Grepped the CLI repo — only the two doc files above reference these attrs. If the parent HeyGen mono has any consumer of this skill's attribute vocabulary, worth a follow-up sweep.
— Review by Rames D Jusso
| cx <= zone.x1 * canvas.width && | ||
| cy >= zone.y0 * canvas.height && | ||
| cy <= zone.y1 * canvas.height; | ||
| if ("data-layout-allow-caption-zone" in candidate.dataAttributes) return null; |
There was a problem hiding this comment.
🟡 Concern — pipeline guard is redundant in prod, and asymmetric with the browser filter.
Under real runtime, all geometry candidates arrive from __hyperframesGeometryCandidates in the browser, which already excludes elements matching element.closest("[data-layout-allow-caption-zone]") from the text-candidate stream (browser.js:1402). By the time a candidate reaches captionFinding, a real-DOM waiver has already been stripped, so this guard is a no-op in prod — the only path that exercises it is the direct-mock test at check.test.ts:451 (which passes dataAttributes bypassing the browser filter entirely).
Also note the asymmetry: the browser filter uses .closest() (element OR any ancestor), while this check inspects only the candidate's own dataAttributes. That's fine while the browser is the sole candidate producer, but if a future non-DOM candidate source (fixture loader, cached-golden replay, batched cross-frame path) ever feeds the pipeline, ancestor-scoped waivers won't propagate through here.
Suggestion: a one-line comment above this guard noting it's defense-in-depth for test mocks / non-browser candidate sources would help the next reader understand why both layers exist. No code change required.
— Rames D Jusso
| if ( | ||
| includeText && | ||
| hasOwnTextCandidate(element, true) && | ||
| !element.closest("[data-layout-allow-caption-zone]") |
There was a problem hiding this comment.
🟡 Nit — inline .closest() diverges from the helper convention used by sibling waivers.
The three sibling waivers all sit behind small named predicates:
data-layout-ignore→ line ~101 (isElementIgnored-shape helper)data-layout-allow-overflow→ line 105data-layout-allow-overlap→ line 544data-layout-allow-occlusion→ line 867
The new attribute inlines !element.closest("[data-layout-allow-caption-zone]") at the call site. One usage is fine as-is, so this is a soft nit — but if you're anticipating more usages (e.g. gating other geometry findings on the same waiver, or adding a symmetric browser-side hasOwnMediaCaptionZone branch later), a isCaptionZoneExempt(element) helper next to the other three keeps the pattern uniform and makes future additions cheap.
— Rames D Jusso
| - In a multi-scene `group_wN.html` (continue runs), every scene-local element stays in the DOM during the other scenes' time windows; the layout-box union almost always overflows the canvas during morph seams. Mark the root and every scene-local primary/supporting element with this attribute **at construction**, not after `check` flags it. | ||
| - **Blast radius — it silences more than the overflow audit.** The attribute is inherited down the subtree (the perception probe walks ancestors), so it also suppresses the rendered-perception checks `text-clipping`, `content-cramped-container`, and `foreground-over-panel` for every descendant. Putting it on a persistent panel that also hosts real foreground content disables collision checks on that content for the panel's whole lifetime. Prefer the narrowest opt-out: scope it to the smallest decorative wrapper, or use per-element `data-layout-bleed="true"` for one intentional primary-text crop. The two canvas/edge checks `primary-offscreen` and `foreground-over-panel` deliberately run **even under** allow-overflow, so it cannot hide a wordmark sliced by the frame or text bleeding onto a panel edge. | ||
| - `data-layout-ignore` — exclude this element from layout audits entirely. | ||
| - `data-layout-allow-caption-zone` — opt out of `--caption-zone` / `caption_zone_collision` for intentional lower-third copy (element or ancestor). |
There was a problem hiding this comment.
🟡 Concern — one-liner is missing the blast-radius framing that the other waivers have.
Compare against the data-layout-allow-overflow entry a few lines up (line 58) which walks through inheritance semantics + what's silenced vs what deliberately still fires. The new attribute:
- Inherits down the subtree via
element.closest("[data-layout-allow-caption-zone]"), so placing it on a wrapper<div>silences caption-zone checks for every descendant. - Silences only
caption_zone_collision— the other layout audits (data-layout-*overflow / overlap / occlusion / clipping / bleed / etc.) all still run on marked elements.
Both of those are the intended contract, but a user reading this line wouldn't know either. A two-clause sentence would fix it — e.g. "…for intentional lower-third copy (applies to the element and every descendant via closest; does not suppress overflow, overlap, or occlusion checks — pair with those attributes if you need to silence multiple audits)."
— Rames D Jusso
miguel-heygen
left a comment
There was a problem hiding this comment.
Reviewed at exact head 37c5ea84a76e87a06064800aae8451bab80bd577.
The runtime implementation is narrow and correct: the browser guard removes only caption-zone text candidates, media/frame candidates still flow, and the pipeline backstop returns only from captionFinding, leaving overlap, occlusion, overflow, and contrast untouched. Direct, ancestor, unmarked, and mocked-candidate paths are meaningful; the two focused suites pass 127/127. Typecheck, oxlint, formatting, and manifest validation also pass locally, and exact-head CI is fully green.
One important agent-contract gap remains:
skills/hyperframes-cli/references/lint-validate-inspect.md:55-69 is the mandatory reference for agents running hyperframes check, but it still lists only the existing overflow/overlap/occlusion/ignore escape hatches and documents --caption-zone without the new waiver. A validation/diagnosis request routes directly to /hyperframes-cli; that agent is not required to load the updated hyperframes-core/references/data-attributes.md, so it cannot discover data-layout-allow-caption-zone and may move intentional lower-thirds instead of applying the sanctioned waiver.
Please add the new escape hatch to that CLI reference, including element/ancestor inheritance and narrowest-wrapper blast-radius guidance, then regenerate skills-manifest.json so the hyperframes-cli hash advances as well. The current manifest is mechanically in sync; the missing source reference is the issue.
No other blockers found.
Co-authored-by: Cursor <[email protected]>
|
Addressed the three inline notes:
|
Co-authored-by: Cursor <[email protected]>
|
Added |
miguel-heygen
left a comment
There was a problem hiding this comment.
Re-reviewed at exact head b57eec30954093c76a32477ec0c474aad1ccfcc5.
The original blocker is closed: the mandatory /hyperframes-cli check reference now documents the waiver, ancestor inheritance, narrowest-wrapper guidance, and single-audit blast radius; both hyperframes-cli and hyperframes-core manifest hashes advance and the manifest validates. The helper extraction and pipeline-backstop comment also resolve the earlier nits.
Runtime and tests remain clean. The focused browser + pipeline suites pass 127/127; CLI typecheck, oxlint, oxfmt, manifest validation, and exact-head CI are green.
One fresh P2 docs-contract issue surfaced in the R2 pass:
docs/packages/cli.mdx:615 adds data-layout-allow-caption-zone inside the deprecated inspect section, but the waiver belongs to the opt-in check --caption-zone gate documented at lines 548-551. inspect has no --caption-zone flag, so a reader following the new sentence from that section cannot exercise the feature it describes, while the active check section never tells them the waiver exists.
Please move the new caption-zone sentence into the check section immediately after the --caption-zone flag/table guidance (or duplicate it there and make the deprecated section explicitly point to check). State the same element/ancestor and caption-only blast-radius contract used in the CLI skill. The existing overflow/overlap/occlusion sentences can remain under inspect; only the new caption-zone guidance is misplaced.
No runtime blockers found.
Co-authored-by: Cursor <[email protected]>
|
Moved New head: |
miguel-heygen
left a comment
There was a problem hiding this comment.
Re-reviewed at exact head f3f33aab5964c84e38a0b11a35739f230e8bb679.
The R2 docs blocker is closed. The active check section now owns the waiver contract immediately beside --caption-zone: element-or-ancestor inheritance via closest, suppression limited to caption_zone_collision, explicit non-suppression of overflow/overlap/occlusion/contrast, and narrowest-wrapper guidance. The deprecated inspect section now points readers back to check instead of presenting the feature as an inspect capability.
The delta from the prior reviewed head is docs-only. The runtime/browser/pipeline implementation and focused 127-test evidence remain unchanged. On this exact head, the schema mirror is in sync, mint validate passes, and mint broken-links reports no broken links. Fresh CI is still running, so merge remains correctly gated by the required checks.
No blockers remain. Approved.
* feat(check): add data-layout-allow-caption-zone waiver Opt intentional lower-third copy out of caption_zone_collision. Co-authored-by: Cursor <[email protected]> * fix(check): address caption-zone waiver review nits Co-authored-by: Cursor <[email protected]> * docs(skills): document caption-zone waiver on CLI agent path Co-authored-by: Cursor <[email protected]> * docs(cli): document caption-zone waiver under check, not inspect Co-authored-by: Cursor <[email protected]> --------- Co-authored-by: Cursor <[email protected]>
Summary
data-layout-allow-caption-zoneso intentional lower-third text can opt out of--caption-zone/caption_zone_collision(element or ancestor viaclosest).captionFinding(for mocked candidates).Test plan
bun run test -- src/commands/check.test.ts -t 'allow-caption|caption band|caption zone'bun run test -- src/commands/layout-audit.browser.test.ts -t 'allow-caption|caption layers'hyperframes check --caption-zone=...on a fixture with/without the attrMade with Cursor