fix(cli,studio,core): close five R5 telemetry and canary findings

- A long-lived preview cached its telemetry posture in two places
  (readConfig and shouldTrack). Running `telemetry disable` in another
  terminal left it resolving canaries and injecting the CLI id for hours.
  Both caches are now dropped together at a request boundary.
- Studio minted and shipped a telemetry id for every render regardless of
  the browser profile's opt-out, and the server emitted the outcome under
  CLI policy, which cannot see localStorage or DNT. The browser now sends
  an explicit telemetryOptOut, distinct from an old client's omission.
- Any non-empty HYPERFRAMES_PREVIEW_HOST disabled the DNS-rebinding guard,
  so even a loopback bind accepted a hostile Host. The guard now holds for
  loopback binds and, on a LAN bind, admits only names this machine
  answers on.
- sunsetAfter had no reader of the current date. A scheduled workflow runs
  scripts/check-canary-sunset.ts weekly, so a failure lands on the
  rollout's owner rather than on an unrelated PR author.
- The install-state seed memo outlived `rm -rf ~/.hyperframes`,
  resurrecting a cleared cohort. Removed; it only saved a read on a
  readConfig cache miss.

Docs updated for the Host rule and the 100% exclusion carve-out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-08-01 17:21:41 -07:00
co-authored by Claude Opus 5
parent 3f69a2c635
commit 6f0df2640b
16 changed files with 504 additions and 47 deletions
+6 -3
View File
@@ -313,9 +313,12 @@ describe("registry", () => {
// Deliberately NOT `overdueCanaries()` with the ambient date. That assertion
// reads wall-clock time, so it turns the entire @hyperframes/core suite red
// on a calendar date for every unrelated PR — a broken build nobody caused
// and whose fix is unrelated to the change under test. The registry's own
// freshness is enforced by the pinned dates below plus the sunset REPORT,
// which is advisory rather than a gate.
// and whose fix is unrelated to the change under test.
//
// Enforcement against the CURRENT date is real, it just is not here: the
// scheduled `Canary sunset` workflow runs `scripts/check-canary-sunset.ts`
// weekly and fails on the rollout's owner rather than on a passing author.
// These two tests cover the pinned-date and boundary logic it depends on.
it("every canary carries a parseable sunset date in the future at authoring time", () => {
const authored = new Date("2026-07-31T00:00:00Z");
for (const c of CANARIES) {