Skip to content

fix(telemetry): honor CLI opt-out in Studio and render CI - #4500

Merged
jrusso1020 merged 2 commits into
mainfrom
codex/first-party-telemetry-audit
Sep 25, 2026
Merged

jrusso1020 merged 2 commits into
mainfrom
codex/first-party-telemetry-audit

Conversation

@jrusso1020

@jrusso1020 jrusso1020 commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

A CLI launched with telemetry disabled currently withholds its anonymous identity, but Studio has a separate browser telemetry policy and can still send events. Pass a page-scoped disabled flag before Studio initializes and honor it in the shared browser policy, covering both telemetry transports and canary eligibility. Enabled CLI sessions and standalone Studio keep their existing behavior; no browser preference is persisted.

Also pass the explicit HYPERFRAMES_NO_TELEMETRY=1 opt-out into the first-party regression and fast-video Docker jobs. A workflow-level environment does not cross docker run. The public render image keeps its existing defaults.

Validation: 109 focused CLI opt-out/identity, Studio policy, and Studio client tests pass against built core outputs. The transport test attempts the same render event in both modes: disabled sends nothing, enabled sends once. Full pre-commit checks pass, including oxlint, oxfmt, core/Studio/scripts typechecks, fallow, file-size/artifact checks and commitlint. Core was built to generate the runtime artifacts required by these checks; no generated artifact is committed.

This requires a normal package release and downstream CLI pin updates to protect deployments still serving older Studio bundles. No publication or deployment is included. Ready for review; keep unmerged pending explicit merge authorization.

Before

Browser regression harness using the base Studio policy and the real client transport. A CLI opt-out does not set a browser flag; attempting one render_complete event produces one intercepted PostHog batch. The harness intercepts fetch locally; no test analytics are transmitted. This is behavioral evidence, not a screenshot of a visible Studio layout change.

Before: one intercepted telemetry batch despite CLI opt-out

After

Same browser harness and event attempt, with this PR's policy and injected CLI disabled flag. Zero PostHog batches. Captures use Chrome, the actual bundled Studio client/policy, and a fresh browser profile for each state.

After: zero intercepted telemetry batches

@jrusso1020
jrusso1020 marked this pull request as ready for review September 25, 2026 21:10

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed this exact SHA, current diff/tests and actual Studio bootstrap and telemetry consumers.

telemetryIdentity.ts:133 transmits the existing CLI policy independently of trusted-host identity. The served Studio shell injects it before the bundle; both browser transports use the shared policy at policy.ts:105. Missing/false preserves existing OSS defaults and other opt-out controls; this does not persist a browser preference. Docker CI forwarding crosses the process boundary explicitly.

Independent exact-head validation: 114 focused tests passed across CLI identity/policy, Studio policy/client and legacy transport, including disabled transport plus enabled control. No new built-browser network E2E or production render was run by this review. Broader CI still has pending jobs, with no failed checks at posting.

Verdict: APPROVE
Reasoning: The injected flag reaches both browser telemetry transports before initialization without changing ordinary OSS defaults. No code blocker found. Older internal pins still need a release/update; review only, no merge/release/deploy performed.

— Magi

@jrusso1020
jrusso1020 added this pull request to the merge queue Sep 25, 2026
Merged via the queue into main with commit edb3747 Sep 25, 2026
124 of 125 checks passed
@jrusso1020
jrusso1020 deleted the codex/first-party-telemetry-audit branch September 25, 2026 23:57
felipecaldas added a commit to felipecaldas/hyperframes that referenced this pull request Sep 29, 2026
The branch was on v0.8.50 and 513 commits behind upstream/main; this takes it to
v0.8.89. The fork's main mirror was already identical to upstream/main (1bede47)
with the v0.8.89 tag on origin. Merged, not rebased, per the fork rules.

30 conflicts. Resolved one by one, not by taking a side wholesale:

Upstream deleted what the patch touched (accepted the deletion):

* packages/studio/src/components/storyboard/** and useStoryboard /
  useProjectSignaturePoll. Upstream heygen-com#4140 removed the Storyboard view and its
  Storyboard/Preview switch. TAB-703 had added Send-to-Agent buttons and
  format-aware tile aspect ratios there. The compositor emits its own
  STORYBOARD.md and imports nothing from this view, and the agent bridge itself
  (AgentDrawer / Tabario AI) does not depend on it, so the patch goes with the
  view. Our orphaned storyboardAspectRatio.ts and StoryboardFrameTile.test.tsx
  went too. The "storyboard-*" AgentRequestKinds are now unused but harmless.

Upstream took the fix (dropped ours, patch surface shrinks):

* engine wavChunks.ts / audioFxRender.ts / audioVolumeEnvelope.ts: upstream
  landed its own shared RIFF walk and WAVE_FORMAT_EXTENSIBLE resolution. Both
  sides added wavChunks.ts, and git's add/add merge left two wavFormatTag
  declarations that only the build caught. Took upstream's implementation. Our
  extra extensible-WAV tests stay and pass against it, bar one case:
  "invalid precision" (validBitsPerSample 33 in a 32-bit container) is now
  accepted and decoded as ordinary 32-bit float. Dropped that case; the files
  come from FFmpeg, so it guards malformed input, not render correctness.
* useTimelinePlayer.ts: upstream now reloads into a shadow iframe and never hides
  the live one, so TAB-1062's armRevealFallback has nothing left to unhide.
  Removed it and its tests; the file is now identical to upstream.
* useDomEditTextCommits.ts: upstream inlined the same three helpers we had
  extracted into domEditCommitHelpers.ts (byte-identical) and moved style
  commits into domStyleCommit. Deleted our helper module. What remains of our
  patch is the caption word-span re-plan in capture (+34/-2 vs upstream).
* studio-server subComposition.ts: upstream moved isFullHtmlDocument into
  @hyperframes/core/compiler/html-document, a superset of ours (it also skips
  leading comments). Used theirs; kept our vendoredGsap import.

Both sides kept:

* studio-server createStudioApi / index / types / routes/preview and
  cli studioServer.ts: our agent runtime + write lock, vendored GSAP and Google
  Font proxy routes, alongside upstream's project history routes and
  project-dir-missing middleware. Import unions only.
* .fallowrc.jsonc: our TAB-1148 exemptions plus upstream's reworded comment.
* useSdkSession.ts: our agent refresh subscription plus upstream's
  whenPreviewBooted.
* useAppHotkeys.ts: the caption-editing gate (isTypingKeyEvent, 20eb534)
  auto-merged into handleAppKeyDown; only the import conflicted.
* LintModal.tsx: kept our LintFindingRow, applied upstream's Tailwind v4 rename
  (flex-shrink-0 -> shrink-0), the only change upstream made to those rows.
* StudioFeedbackCard.tsx: kept the removal of the external "Talk to us"
  interview link.
* StudioHeader.tsx: rebuilt from upstream's new design-system header (undo/redo
  moved to the timeline toolbar in heygen-com#4196, storyboard toggle gone) and re-added
  "Go to Tabario" and "Tabario AI" on the new Button. The return-to-Tabario
  fetch moved into a local useReturnToTabario hook so the header's complexity
  does not grow.
* bun.lock: upstream's, then bun install. It differs from upstream only by our
  vendored gsap dep and workspace version strings upstream left at 0.8.62.

Fixed at the seams (upstream changes our code had not caught up with):

* studioServer.ts measureLayout: getThumbnailBrowser gained an isShuttingDown
  argument; our Tabario AI layout probe now passes () => shuttingDown.
* studioServer.test.ts: CheckReport gained a required hdr section; the engine
  mock now spreads importOriginal, because compositions.ts imports
  resolveReferencedStart from the engine.
* propertyPanelFlatCaptionSection.tsx: upstream's new hex ratchet flagged our two
  "#ffffff" caption defaults. They are composition data, not Studio chrome, so
  they are hoisted into one DEFAULT_CAPTION_COLOR (the same shape as upstream's
  InlineTextToolbar DEFAULT_COLOR) and the baseline gains exactly that file at 1.
* useAskAgentModal.test.tsx (new upstream): the fork sends the prompt to the
  agent bridge, not the clipboard. Mocked the bridge; every assertion kept.
* telemetry/client.test.ts (new upstream, heygen-com#4500): the opt-out half is upstream's
  as-is; the "enabled control sends" half asserts not-sent, because Studio
  telemetry is off in the fork (TAB-697).

Verified:

* bun install --frozen-lockfile clean; bun run build exit 0.
* tsc --noEmit clean for core, engine, producer, player, lint, studio,
  studio-server, cli, sdk. bun run lint clean. oxfmt clean on changed files.
* Tests per package, 4 workers each: core 3645, engine 2021, lint 746,
  studio-server 1099, cli 3951, player 512, sdk 554, producer 851,
  studio 6076. All pass, including the fork egress guards
  (forkEgressGuard.test.ts, policy.forkEgress.test.ts).
* No new third-party host in studio / studio-server / runtime / player source.
* Tabario symbols confirmed in the built artifacts, not just the source:
  isTypingKeyEvent, TABARIO_STUDIO_HOSTED, "Tabario AI", "Go to Tabario",
  buildCaptionWordSpans, /api/tabario/session/exit, AgentRuntime,
  registerVendorRoutes, registerGoogleFontProxyRoutes.

Upstream is not frame-stable. Renders may differ from v0.8.50: this range
carries engine colour, HDR, frame-selection and audio-timing fixes. The
compositor pin bump and deploy are out of scope for TAB-1216.

Pre-commit: every gate ran; none was skipped and --no-verify was not used.
largefiles ran with HF_MAX_NONLFS_KB=2300, the gate's documented per-commit
override, because upstream committed two catalog assets as plain blobs (not LFS):
docs/public/catalog/items/blue-sweater-intro-video/assets/joe-sai-avatar.png
(1954 KB) and .../sfx/integrated-melodic-tech-mix.wav (2251 KB). They are
upstream's objects byte-for-byte. Moving them into LFS here would diverge from
upstream and conflict on every later sync.

fallow passed, auditing 3258 changed files (the merge itself); its 32 complexity
findings are informational and none of them is in code this merge authored.
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.

2 participants