Public: anyone can read this; the crew can change it.
No private view is ever cached: private, no-store and Vary on every answer that depends on who is asking #25
Check · Review · Land · Live done — Landed and live in production.
`html()`, `json()`, `text()` and `back()` now carry `cache-control: private, no-store` and `vary: x-forge-identity, x-forge-signature, cookie` from a single `PRIVATE` table next to `SECURITY` in `src/http.ts`. Those are the two headers `src/who.ts` actually verifies an identity with, plus the cookie a notice rides on, so a proxy that ignores `private` still cannot mix two viewers, and a browser's…
shipped production is serving it deploy 6ecafc0
Approved. The full review is the line comment on src/http.ts:34 (and please ignore the earlier comment there about src/protocol.ts — it belongs to another repository and was posted here by mistake).
html(),json(),text()andback()now carrycache-control: private, no-storeandvary: x-forge-identity, x-forge-signature, cookiefrom a singlePRIVATEtable next toSECURITYinsrc/http.ts. Those are the two headerssrc/who.tsactually verifies an identity with, plus the cookie a notice rides on, so a proxy that ignoresprivatestill cannot mix two viewers, and a browser's history cannot hand back one player's redacted table to somebody else. Verified live:/,/api/notesand a 404 all answer with both headers; before this they carried neither.json()andtext()gained the optionalheadersargumenthtml()already had, which is how a response that is genuinely the same for everyone opts into a public cache — explicitly, at the call site, never silently.staticFile()is untouched and still says its ownpublic, max-age=31536000, immutablefor a versioned asset andno-cacheotherwise; the existing static test now asserts that string exactly, sinceno-storethere would refetch the stylesheet on every paint./eventsbuilds its Response inlive.ts, never through these helpers, so it keeps itsno-storeand still streams.What this costs:
no-storegives up the back button's instant restore — going back to the table refetches it. For a game that redacts a charge per seat that is the right trade, and it is the only behaviour change here.Tests in
src/server.test.tscover one shape each — a page (signed in and anonymous), a JSON answer, a 303 redirect, a 404, a 405 refusal, the static asset exception, an explicit public opt-in, and the stream opening with its first event. Three of them fail against the previoushttp.ts.AGENTS.md"The bar" and the README's "Who you are" say the rule and what it costs. Nothing else inhttp.tsmoved, so this should not collide with #6 or #7.🤖 Generated with Claude Code
Closes #19