From b2fc18b2df60fd9049cb694c97c45104ee5b4e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Mon, 24 Aug 2026 18:04:39 -0400 Subject: [PATCH] fix(skills,lint): correct composition-contract claims the code contradicts (#3468) The runtime absorbed a series of authoring mistakes over time and `runtime/init.ts` says so in its own comments, but the skills kept teaching the old rules. Four of them actively cost an agent a failing run: add `crossorigin` (lint rejects it unconditionally), never build a timeline inside `async` (lint calls that the documented contract), never `gsap.set` later-scene clips (two fixHints instruct exactly that), and 12 copyable media snippets with no `id`, which render silent. Corrected in every place each claim appeared, including `hyperframes-animation`, three workflow scripts, the scaffolded project instructions, the CLI `docs` command, and the public docs site: `data-track-index` is a Studio display lane the render never reads, `class="clip"` is a layout convention rather than a visibility requirement, timed elements may nest, the visibility window is half-open, sub-composition host dimensions are backfilled, and the root-fill rule applies only to the layered-composite path. Behaviour changes, each backed by a render rather than by reading code: - `timeline_registry_missing_init` deleted. The runtime creates the registry before any inline script; a composition without the guard line renders and animates correctly. - `video_nested_in_timed_element` kept, message corrected. A rendered repro shows the nested-with-local-start case really does break, so the rule guards a real defect, but nothing is "FROZEN": the extractor ignores the wrapper's offset while visibility uses it, so the clip shows wrong frames and then vanishes. - `mediaRenderIds` now stamps media whose source is a `` child, closing a duplicate-id gap the old `[src]`-only selector left open. - Stale messages fixed on `subcomposition_root_styled_by_class` and `deprecated_data_layer`. `coreSkillContent.test.ts` pinned the literal sentence that made root `data-start` look required, so it is narrowed to structure plus the regression it genuinely catches. Not covered, and flagged in the PR: the media global-vs-local start heuristic in `runtime/init.ts` is the root cause behind the nested-video defect. Removing it changes the meaning of existing compositions and needs its own deprecation. --- docs/concepts/data-attributes.mdx | 17 ++++---- docs/reference/html-schema.mdx | 9 ++-- .../cli/src/commands/coreSkillContent.test.ts | 12 ++++-- packages/cli/src/docs/data-attributes.md | 6 +-- packages/cli/src/templates/_shared/AGENTS.md | 4 +- packages/cli/src/templates/_shared/CLAUDE.md | 4 +- .../core/src/compiler/mediaRenderIds.test.ts | 30 ++++++++++++- packages/core/src/compiler/mediaRenderIds.ts | 25 ++++++++++- packages/lint/src/rules/composition.ts | 20 +++++---- packages/lint/src/rules/core.test.ts | 27 ++++++++---- packages/lint/src/rules/core.ts | 26 ++++++----- packages/lint/src/rules/media.ts | 4 +- skills-manifest.json | 10 ++--- .../scripts/assemble-index.mjs | 7 ++- .../scripts/transitions.mjs | 3 +- skills/hyperframes-animation/adapters/gsap.md | 6 +-- .../transitions/TRANSITION-REGISTRY.md | 3 +- skills/hyperframes-core/SKILL.md | 32 ++++++++------ .../references/composition-patterns.md | 4 +- .../references/creator-editing-recipes.md | 34 +++++++++++++-- .../references/data-attributes.md | 37 +++++++++------- .../references/determinism-rules.md | 11 +++-- .../references/full-screen-motion.md | 16 ++++++- .../references/minimal-composition.md | 14 +++--- .../references/sub-compositions.md | 6 ++- .../references/tracks-and-clips.md | 43 ++++++++++--------- .../references/variables-and-media.md | 6 ++- skills/pr-to-video/scripts/assemble-index.mjs | 7 ++- skills/pr-to-video/scripts/transitions.mjs | 3 +- .../scripts/assemble-index.mjs | 9 ++-- .../scripts/transitions.mjs | 3 +- 31 files changed, 288 insertions(+), 150 deletions(-) diff --git a/docs/concepts/data-attributes.mdx b/docs/concepts/data-attributes.mdx index a71e3d452..7ee156218 100644 --- a/docs/concepts/data-attributes.mdx +++ b/docs/concepts/data-attributes.mdx @@ -17,19 +17,20 @@ a start, a duration, and a track: | ------------------ | ------------------------------------------------ | | `data-start` | When the element enters the composition timeline | | `data-duration` | How long its timeline slot lasts | -| `data-track-index` | Which timeline lane owns that slot | +| `data-track-index` | Which Studio lane displays it (optional; the render ignores it) | -Add `class="clip"` to timed DOM and image elements so the runtime can control -their visibility. Video visibility is managed by the media runtime; audio has -no visual lifecycle. +Add `class="clip"` to timed DOM and image elements. The runtime keys visibility +off `data-start` rather than the class, but the shared `.clip` rule is what gives +a scene its full-frame box. Video visibility is managed by the media runtime; +audio has no visual lifecycle. ## Tracks are not layers -Tracks prevent time ranges from colliding. They do not decide which element is -in front. Use CSS `z-index` for paint order. +Tracks are the rows Studio draws. They do not decide which element is in front, +and they do not schedule anything. Use CSS `z-index` for paint order. -Two clips on one track cannot overlap. Put an intentional overlap, such as a -crossfade, on separate tracks: +Two clips on one track may overlap; the render composites both. Separate tracks +keep an intentional overlap, such as a crossfade, readable in Studio: ```html