mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-05 00:56:23 +00:00
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 `<source>` 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.
This commit is contained in:
@@ -12,7 +12,10 @@
|
||||
// document order. Transitions are NOT written here — the transitions injector
|
||||
// mutates this file afterward (data-start/duration/track-index + GSAP).
|
||||
//
|
||||
// Track lanes (same-track time-overlap is illegal — lint timeline_track_too_dense):
|
||||
// Track lanes. Same-track time-overlap is this workflow's own assembly convention,
|
||||
// not a framework rule: the render never reads data-track-index, and no lint rule
|
||||
// checks overlap (timeline_track_too_dense counts elements per lane for readability).
|
||||
// The convention exists because the frame injector below ping-pongs 0/1 for overlaps:
|
||||
// 1 frame sub-comp clips (sequential; the injector 0/1-ping-pongs for overlaps)
|
||||
// 2 captions sub-comp clip (full-duration overlay, on top of frames)
|
||||
// 10 per-frame voice <audio>
|
||||
@@ -216,7 +219,7 @@ function guardFrame(html, label) {
|
||||
for (let i = 1; i < list.length; i++) {
|
||||
if (list[i].start < list[i - 1].end - EPS) {
|
||||
errors.push(
|
||||
`${label}: clips on track ${track} overlap (one ends at ${r3(list[i - 1].end)}s, the next starts at ${r3(list[i].start)}s) — same-track time-overlap causes a render conflict. Put them on distinct data-track-index lanes or fix their windows.`,
|
||||
`${label}: clips on track ${track} overlap (one ends at ${r3(list[i - 1].end)}s, the next starts at ${r3(list[i].start)}s). This workflow's injector assumes one clip per lane at a time. The render itself tolerates the overlap; put them on distinct data-track-index lanes or fix their windows.`,
|
||||
);
|
||||
break; // one report per track is enough
|
||||
}
|
||||
|
||||
@@ -326,7 +326,8 @@ function runVerify(argv) {
|
||||
a.start < b.start + b.duration - EPS && b.start < a.start + a.duration - EPS;
|
||||
const fail = [];
|
||||
|
||||
// (4) global no same-track overlap (the lint invariant).
|
||||
// (4) global no same-track overlap. This is this workflow's own lane convention,
|
||||
// not a lint rule: nothing in the framework rejects same-track overlap.
|
||||
const all = [...clips.values()];
|
||||
for (let i = 0; i < all.length; i++)
|
||||
for (let j = i + 1; j < all.length; j++) {
|
||||
|
||||
Reference in New Issue
Block a user