Skip to content

fix(core): the bundle's contract check reads a timeline registered in a local script - #7248

Merged
miguel-heygen merged 2 commits into
mainfrom
fix/static-guard-external-scripts
Nov 5, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
fix/static-guard-external-scripts

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

What

Bundling a project (as check and the other commands do) no longer warns [StaticGuard] Invalid HyperFrame contract: Missing window.__timelines registration for a composition that registers its timeline in a local script (<script src="timeline.js">). hyperframes lint already accepted it; the bundle's contract check now reads the same files.

Why

A project registered its paused timeline from an external local script. The runtime found the timeline and lint passed, but every bundle printed the StaticGuard error, so the check output said the contract was broken when it was not.

The bundler's contract check (validateHyperframeHtmlContract) built its own lint options and passed only the linked stylesheets. lintProject passes the stylesheets and the local scripts, and the missing_timeline_registry rule looks for the registration in both the page and those scripts. The guard never got the scripts.

How

@hyperframes/lint exports linkedSources(projectDir, html, compSrcPath), which returns the linked stylesheets and local scripts a file's rules read. lintProject (root and compositions) and validateHyperframeHtmlContract all spread it, so the two cannot drift again. collectExternalStyles is no longer exported at all: the guard was its only outside caller, and linkedSources is now its only caller.

Test plan

  • Unit tests added/updated:
    • fails without the fix: htmlBundler.test.ts "reads a timeline registered by a local script, as hyperframes lint does": the root registers its timeline only in timeline.js, and bundling prints no [StaticGuard] warning. It fails with the guard given only the stylesheets.
    • htmlBundler.test.ts (215) passes three runs in a row; lint/src/project.test.ts (86) passes. tsc on core: no errors.
  • Manual testing performed: a project whose timeline is registered only in timeline.js. Released 0.9.15 check --json prints [StaticGuard] Invalid HyperFrame contract: Missing window.__timelines registration. twice; the CLI built from this branch prints no StaticGuard line, and the check passes (ok: true, no errors).
  • Documentation updated (if applicable): none needed; lint already documents this behaviour.
  • Comments follow CONTRIBUTING.md "Comments": no new comments.

Size

About 20 lines of source in three files and one test. One fix: the bundle's contract check reads what lint reads.

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 267 (base branch 267), smooth 107 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (8)

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head f38ccb2a

The fix is right, and the fails without the fix: test holds. With the old staticGuard.ts it fails and receives [StaticGuard] Invalid HyperFrame contract: Missing `window.__timelines` registration.. With this head it passes. htmlBundler.test.ts (215) and lint/src/project.test.ts (87) pass locally. One required check fails because of this diff (inline): CI › Fallow audit.

Scope / CI

Read all 4 files. The guard now passes the same externalScripts that lintProject passes, so error findings from rules that read local scripts also reach the guard's console.warn. That matches lint and only warns, so it does not block a bundle. Player perf failed in bun install (an ffmpeg-static download returned 504): infra, not this diff. Fallow's two code-duplication findings (project.ts:645/:714) are on lines this diff does not touch, so they are pre-existing code in a file it does touch. Windows render verification and regression were still running when I posted. No prior reviews.

compSrcPath?: string,
): Pick<HyperframeLinterOptions, "externalStyles" | "externalScripts"> {
return {
externalStyles: collectExternalStyles(projectDir, html, compSrcPath),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocker: CI › Fallow audit fails with fallow/unused-export on packages/lint/src/project.ts:143: Export 'collectExternalStyles' is never imported by other modules. This PR removed it from index.ts, and linkedSources here is now its only caller. Drop export from collectExternalStyles (line 143).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Fixed in f0c0d6f

@miguel-heygen
miguel-heygen force-pushed the fix/static-guard-external-scripts branch from f38ccb2 to f0c0d6f Compare November 5, 2026 14:49
@miguel-heygen

Copy link
Copy Markdown
Collaborator Author

Fixed at f0c0d6f: collectExternalStyles is no longer exported; linkedSources is its only caller. fallow audit --fail-on-issues against the merge base exits 0 (the one duplicate group it lists is in lines this PR does not touch). lint/src/project.test.ts 87/87.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — 1 resolved, 0 open, 0 new · f38ccb2a → f0c0d6fa

collectExternalStyles is no longer exported, and CI (Fallow audit included), Windows, regression and Comments pass on this head. The rest of the range-diff is the rebase onto main. preview-regression on this head was cancelled, not failed; it needs a rerun if the gate requires it.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 5, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 5, 2026
@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 5, 2026
Merged via the queue into main with commit 0b35598 Nov 5, 2026
143 of 145 checks passed
@miguel-heygen
miguel-heygen deleted the fix/static-guard-external-scripts branch November 5, 2026 16:15
SanHsien added a commit to SanHsien/hyperframes that referenced this pull request Nov 6, 2026
…view

Adopts heygen-com#7250 (SVG stroke drawing is not a dead stretch), heygen-com#7248
(contract check reads a timeline registered in a local script), heygen-com#7252
(comma-list selectors hidden by authored CSS), heygen-com#7238 (snapshot and
preview show a clip on the render frame), heygen-com#7237 (stalled cloud upload
retries) and heygen-com#7251 (per-scene SVG id namespacing), with prerequisite
heygen-com#6829. Defers heygen-com#7246 (needs the delivery limiter from heygen-com#6940) and heygen-com#7232
(needs the WebKit decode-first pipeline), with conditions in the
ledger. Watermark advances to b108f85.

Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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