Public: anyone can read this; the crew can change it.
The flags page's Server-Timing names its phases: session, each read, render #3447
Check · Review · Land · Live done — Landed and live in production.
`GET /settings/flags` now answers with a Server-Timing header that names `session`, `registry`, `values`, `uses` and `render`, using `notePhase`/`timePhase` the way the milestones page does.
shipped production is serving it deploy bbd5a0b
GET /settings/flags now answers with a Server-Timing header that names session, registry, values, uses and render, using notePhase/timePhase the way the milestones page does.
- What each phase covers:
- registry is loading the flag registry.
- values is the sum of the live-value reads across all flags.
- uses is the sum of the 7-day and 30-day usage queries.
- render is the rest of the row and page building.
- Why the reads are summed: they happen inside the per-flag row loop, so each is added up and noted once after the page is built. The reads still run in the same order and throw the same errors.
- Nothing else changed: the body, status codes and caching are the same, and no other page is touched. A non-admin still gets the 403 or the sign-in page, now with
sessionin the header. - Test:
test/flags-timing.test.tssigns in as the admin, requests the page, and checks thatappand each of the five phases appears with adur=value. It fails on the old code. - Checks run:
bun testontest/flags-timing.test.tsandtest/flags-settings.test.tspasses (8 tests). I did not run the type check becausebun x tscandbun installboth failed in my sandbox with a read-only tempdir error, so the forge's check will be the first type check. - To try it: sign in as an admin and run
curl -sI -H "cookie: …" $URL/settings/flags | grep -i server-timing.
I didn't add a phase per flag, because phase names must be fixed lowercase tokens and the flag count changes.
🤖 Generated with Claude Code
Follows the milestones/boards pattern (session via takeSessionTime, timePhase for the registry, one summed note per interleaved read). Phase names are fixed tokens, the render phase is clamped at zero, and no body, status or security behaviour changes. The denied paths still carry session. The test signs in as admin and fails on the old code. No markup changed, so DESIGN.md is untouched. I could not exercise the admin-only page on the preview without a session.
Two things to do next: (1) the test header cites #3406 while the pull is #3447, so fix the reference; (2) the uses phase is two queries per flag, so if it dominates the header, batch the 7 and 30 day counts into one query in the registry rather than timing them harder.
GET /settings/flagsnow answers with a Server-Timing header that namessession,registry,values,usesandrender, usingnotePhase/timePhasethe way the milestones page does.-
registryis loading the flag registry. -valuesis the sum of the live-value reads across all flags. -usesis the sum of the 7-day and 30-day usage queries. -renderis the rest of the row and page building.sessionin the header.test/flags-timing.test.tssigns in as the admin, requests the page, and checks thatappand each of the five phases appears with adur=value. It fails on the old code.bun testontest/flags-timing.test.tsandtest/flags-settings.test.tspasses (8 tests). I did not run the type check becausebun x tscandbun installboth failed in my sandbox with a read-only tempdir error, so the forge's check will be the first type check.curl -sI -H "cookie: …" $URL/settings/flags | grep -i server-timing.I didn't add a phase per flag, because phase names must be fixed lowercase tokens and the flag count changes.
🤖 Generated with Claude Code
Closes #3406