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

The page knows your name and says nothing about who may cache it #48

open not picked up yet opened this
opened this

Every response in this app stands on the floor in src/http.ts, and the floor has no cache directive in it. GET / is rendered per person — it carries who.name, the sign-out link, the notice cookie's toast, and with #6 a guest session — and production answers it with no cache-control and no vary at all. Nothing in front of us caches HTML today; that is a default, not a rule, and the rule is the thing this app keeps.

Checked on production (df130d5): GET / returns content-security-policy, x-content-type-options, referrer-policy, permissions-policy and strict-transport-security, and no cache header of any kind.

Done looks like

  • [ ] The floor gains a cache directive: html(), json(), text() and empty() in src/http.ts carry one by default, so a door cannot forget it by existing.
  • [ ] The directive is chosen and the choice is written in the pull: private, no-store is the strongest and costs Chrome's back-forward cache; private, no-cache keeps bfcache and still stops a shared cache serving one person's page to the next. Either is acceptable; picking one without saying why is not.
  • [ ] A genuinely public, identity-free response can opt out through the same one argument the callers already pass headers through — and the only one that does today says so in a comment.
  • [ ] Identity-varying responses carry vary: cookie, x-forge-identity as well, so a cache that honours vary but not private still keys on the right thing.
  • [ ] Unchanged and asserted rather than assumed: staticFile/bytes keep public, max-age=31536000, immutable when linked by content (asset) and stay short-lived without ?v; eventStream keeps no-store.
  • [ ] A test in the shape of the existing floor test walks every route in routes.ts and fails if a response carries no cache directive — the streaming and image doors included, and HEAD answering as GET.
  • [ ] AGENTS.md's security floor gains the one clause, so the next twelve doors inherit it.

Files src/http.ts, src/server.test.ts, AGENTS.md.

Risks no-store on / disables bfcache, which for a game page that reopens a socket on every restore is a real cost — hence the choice above. Do not put a directive on /card.png and /icon-180.png that stops a chat client caching them; they are public by design and have no identity in them.

Fits Vesper's brief: it is the floor, and the floor is one file.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs