Skip to content

fix(lint): consolidate lint and audit correctness#2413

Open
miguel-heygen wants to merge 12 commits into
mainfrom
consolidate/lint-audit-correctness
Open

fix(lint): consolidate lint and audit correctness#2413
miguel-heygen wants to merge 12 commits into
mainfrom
consolidate/lint-audit-correctness

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

What

Consolidates the remaining lint and audit correctness fixes into one modern replacement for #2381, #2319, #2074, and #1897.

  • reports duplicate live data-composition-id values, including entity-equivalent values, while ignoring inert templates
  • prevents CSS comments inside <style> from creating phantom root tags
  • audits only directly painted text for caption visibility, overflow, overlap, invisibility, and occlusion
  • preserves the 5% text-occlusion floor
  • resolves GSAP targets lexically and distinguishes real proxy instances without treating descriptive proxy labels as identity
  • preserves browser-first duplicate attribute semantics

Why

The original PRs address one lint/audit contract from different angles. Keeping them separate leaves overlapping implementations, partial fixes, and inconsistent regression coverage. This replacement preserves every unique valuable behavior while removing false positives and false negatives found during adversarial review.

How

The implementation uses structural HTML parsing and canonical decoded composition IDs, direct text-node ranges instead of aggregate descendant geometry, and lexical GSAP binding/provenance data to identify stable proxy targets. Helper-local proxy declarations receive per-expansion identity; shared outer proxies retain one identity across helper calls.

Test plan

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

Validation completed:

  • parsers: 820 passed, 5 skipped, 3 todo
  • lint: 374 passed
  • CLI: 1,749 passed, 2 skipped
  • parsers/lint/CLI typechecks
  • parser production build
  • formatting and git diff --check
  • fallow changed-file audit
  • independent adversarial review

…ot tags

extractOpenTags scans raw source text with a flat regex that has no
concept of <style>/<script> block boundaries, so a CSS comment like
`/* <g> wrapper */` inside a <style> block reads as a real open tag.
findRootTag consumes that flat tag list and only skips tags literally
named script/style/meta/link/title, so the phantom <g> tag (not in
that skip list) wins the "first non-ignored body tag" search and gets
returned as the composition root instead of the real one that follows.

This manufactured root_missing_composition_id and root_missing_dimensions
(the phantom tag has neither) plus head_leaked_text (the leaked-text
scan slices up to the phantom tag's position, landing inside the
<style> block before its real closing tag, so the raw CSS text reads
as leaked markup) on an otherwise valid sub-composition — reported
with an exact bisected repro: a <template>-wrapped SVG sub-composition
whose <style> block comments reference an inner <g> element.

Fix: compute <style>/<script> content spans up front (reusing the
existing extractBlocks + STYLE_BLOCK_PATTERN/SCRIPT_BLOCK_PATTERN) and
skip any TAG_PATTERN match that falls inside one, before it ever
reaches findRootTag or any other extractOpenTags consumer. Same shape
as the prior fix for a leading <svg> defs block being mistaken for the
root (8ee4b7d) — this closes a sibling gap in the same function.

Test: new regression case with a <style> block containing a `/* <g> */`
comment ahead of an <svg data-composition-id> root, asserting none of
the three findings fire. Full lint package suite (318 tests) passes.
Declaring data-composition-id on more than one element (commonly the <meta>
tag from the quickstart template AND the root <div> added to satisfy
root_missing_composition_id) is a silent collision: `compositions --json`
returns two entries for the same id (one duration:0) and inspect/snapshot
crash with "Cannot read properties of undefined (reading totalDuration)".
Lint passed clean through all of it.

New rule `duplicate_composition_id`: group elements by data-composition-id
value and error on any value shared by 2+ elements, naming the id and calling
out the meta-vs-root collision in the fixHint. 3 tests: dup fires, single id
passes, two distinct ids don't collide. (Implemented via Codex; verified
independently: 111 lint tests pass, oxfmt/oxlint clean.)
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