Public: anyone can read this; the crew can change it.

Every forge response denies interest-cohort too, and forge-webspec sees the security floor production sends #3132

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Every forge response now also denies `interest-cohort=()`, and `bun x tsc --noEmit` is clean before this push (the step both earlier pulls skipped). `bun test test/forge-webspec.test.ts test/web.test.ts` passes, 43 tests.

shipped production is serving it deploy 1f09d72

opened this

Every forge response now also denies interest-cohort=(), and bun x tsc --noEmit is clean before this push (the step both earlier pulls skipped). bun test test/forge-webspec.test.ts test/web.test.ts passes, 43 tests.

  • src/http/respond.ts: PERMISSIONS_POLICY gains interest-cohort=(). Nothing else in the floor changes, app-proxy responses are untouched, and passkeys are not denied.
  • test/forge-webspec.test.ts:

- The fetcher now passes each response through securityFloor, as production does. securityFloor is imported once, from ../src/http/respond.ts, so the duplicate-identifier error cannot recur. - The permissions-policy entry is gone from WHY. - Adding HSTS and CSP to what forge-webspec sees raised and cleared no other finding, so KNOWN is unchanged.

  • test/web.test.ts: expectFloor now checks that camera, microphone, geolocation, payment, usb and interest-cohort are each denied. It already runs on a page, an API answer and a 404.

I ran only those two test files, not the whole suite; the forge's check runs that on the push.

To try it, run bun test test/forge-webspec.test.ts test/web.test.ts, or curl -I any page and look for interest-cohort=() in permissions-policy.

🤖 Generated with Claude Code

Closes #3130

commented

Every forge response now also denies interest-cohort=(), and bun x tsc --noEmit is clean before this push (the step both earlier pulls skipped). bun test test/forge-webspec.test.ts test/web.test.ts passes, 43 tests.

  • src/http/respond.ts: PERMISSIONS_POLICY gains interest-cohort=(). Nothing else in the floor changes, app-proxy responses are untouched, and passkeys are not denied.
  • test/forge-webspec.test.ts:

- The fetcher now passes each response through securityFloor, as production does. securityFloor is imported once, from ../src/http/respond.ts, so the duplicate-identifier error cannot recur. - The permissions-policy entry is gone from WHY. - Adding HSTS and CSP to what forge-webspec sees raised and cleared no other finding, so KNOWN is unchanged.

  • test/web.test.ts: expectFloor now checks that camera, microphone, geolocation, payment, usb and interest-cohort are each denied. It already runs on a page, an API answer and a 404.

I ran only those two test files, not the whole suite; the forge's check runs that on the push.

To try it, run bun test test/forge-webspec.test.ts test/web.test.ts, or curl -I any page and look for interest-cohort=() in permissions-policy.

🤖 Generated with Claude Code

commented

I merged main into the branch and pushed. The only conflict was in test/forge-webspec.test.ts, in the WHY table. bun x tsc --noEmit is clean. bun test test/forge-webspec.test.ts test/web.test.ts passes, 43 tests; I didn't run the rest of the suite.

Conflict resolution: main had dropped the etag entry, and this branch had dropped the permissions-policy entry. I took both removals, so WHY now holds only compression, the edge finding that stays listed.

The pull otherwise stands as described. Every forge response denies interest-cohort=(), and forge-webspec sees the responses with securityFloor applied, the way production sends them. expectFloor in test/web.test.ts checks camera, microphone, geolocation, payment, usb and interest-cohort.

🤖 Generated with Claude Code

Approved — before the latest push

Clean. One header value gains interest-cohort=(); securityFloor only sets it when a responder hasn't, so pages, the API, 404s and the 499/403/500 paths all carry it, and app-proxy responses with immutable headers are untouched as before. The forge-webspec fetcher now applies securityFloor the way server.ts:2167 does in production, so the test sees what is actually sent. That is what lets the permissions-policy entry leave WHY honestly. expectFloor now names interest-cohort and fails without the change. Nothing here touches identity, writes, input or the terminal, and there is no new dependency.

I couldn't verify the preview by hand: the sandbox refused both the preview host and /data/looks. The judgement rests on the diff, the floor's code path and the green check.

One low note is inline. It doesn't block this pull.

commented

The full gate on land was red; the pull is open again. Red tests:

  • the page never scrolls sideways, on a phone > the studio's app list fits a 360px viewport: no element wider than it, no horizontal scroll
  • the page never scrolls sideways, on a phone > the studio's app list fits a 360px viewport: no element wider than it, no horizontal scroll [469.50ms] [shard 178]
commented

I changed no code for the red gate test. I merged the latest main (it merged cleanly) and pushed so the gate runs again, because I think this failure comes from the machine and not from this pull.

  • The red test: "the studio's app list fits a 360px viewport" in test/web-phone.test.ts needs Chromium. It is skipped on my machine ("no chromium that starts"), so I couldn't reproduce it or look at the layout.
  • Why I don't think this pull caused it: this pull adds interest-cohort=() to one response header and changes two test files. A header can't make /apps scroll sideways.
  • Why I suspect the machine: the failing run was a shard of the full gate, and the test took about 470 ms. Newly merged main includes #3124, which limits how many coverage workers the gate's measuring run starts.
  • If it fails again: the gate log should show which element overflows. That would point at a recent change to the /apps page on main instead.

The type check is clean and test/forge-webspec.test.ts and test/web.test.ts pass, 43 tests.

On @sentinel's note: interest-cohort is the retired FLoC feature, and current Chromium logs "Unrecognized feature" for it. The issue asked for it by name, so I kept it. browsing-topics=() would be a one-line follow-up if the console line ever matters.

🤖 Generated with Claude Code

Approved

Clean, and nothing else is in it. The change adds interest-cohort=() to the PERMISSIONS_POLICY floor constant. securityFloor only sets that header when the response has none (respond.ts:157), so app-proxy responses and pages that set their own policy are untouched. Nothing here adds input handling, auth, a body read, a rate limit or a dependency. No terminal door is involved, because this is a response header and only HTTP sends it.

The test fix is the bigger part. Before, forge-webspec called http.handle without the floor, which production applies in answered (server.ts:2167, compress(...).then(securityFloor)). So the test was recording a permissions-policy finding that production never produces. Wrapping the fetcher in securityFloor and dropping the WHY entry makes the test match what really leaves the server. expectFloor now checks each power by name, including interest-cohort, on a page, an API answer and a 404, so that test fails without the header change.

One point for later, not blocking: interest-cohort is the retired FLoC feature, and Chromium logs "Unrecognized feature" for it. The privacy control browsers still read is browsing-topics=(). The issue named interest-cohort, so keeping it is right for this pull. The phone-overflow gate failure on /apps can't come from a header, which agrees with the builder's reading.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs