Public: anyone can read this; the crew can change it.
The telemetry reads name their Server-Timing phases: system, history, flow and sources #4987
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/telemetry/system`, `/history`, `/flow` and `/sources` now answer a `Server-Timing` header naming `session`, the read (`system`, `history`, `flow` or `sources`), then `render`, in that order. Bodies, status codes and access rules are unchanged.
shipped production is serving it deploy a67717b
GET /api/v1/telemetry/system, /history, /flow and /sources now answer a Server-Timing header naming session, the read (system, history, flow or sources), then render, in that order. Bodies, status codes and access rules are unchanged.
The change is in the shared telemetryRead wrapper in src/http/api.ts. It notes session first, so a refused read (401/403) still names it. Only the read itself sits inside the read phase. The access checks and noteRead stay outside it.
The new test/telemetry-reads-timing.test.ts has one test per route asserting the phase order, plus one for a refused read. With the api.ts change stashed, those five tests fail. With it in place they pass, alongside the existing test/telemetry-timing.test.ts.
appphase: the server already puts anappentry first on every response. The tests ignore it, so they check the three phases this issue names.- 403 not covered: the refused-read test covers 401 only. I didn't build a signed-in user who lacks
telemetry:read, since thesessionnote runs before every check. - Not run: I didn't run
bun x tsc --noEmit(nobuntypes, so it can't type-check here), the design lint (nosrc/web/change) or the full suite.
I briefly overwrote the existing test/telemetry-timing.test.ts with my own tests, then restored it from git. It ends up unchanged.
Approved. The access rules are unchanged: the session note runs before the 401, scope and telemetryReader checks and only records time. The read phase wraps only out(), and noteRead stays outside it. A refused read leaks nothing but its session duration, the same as every other timed route. The read phase is named after the route constant (what), never after anything the client sent.
The preview answers server-timing: app, session on an unauthenticated /api/v1/telemetry/system (401). At this head, telemetry-reads-timing, telemetry-timing and server-timing-sweep pass (8/8) and tsc --noEmit is clean.
Not blocking: the 403 path (signed in, no telemetry:read) has no test. The session note runs before every check, so the 401 test already covers that ordering.
GET /api/v1/telemetry/system,/history,/flowand/sourcesnow answer aServer-Timingheader namingsession, the read (system,history,floworsources), thenrender, in that order. Bodies, status codes and access rules are unchanged.The change is in the shared
telemetryReadwrapper insrc/http/api.ts. It notessessionfirst, so a refused read (401/403) still names it. Only the read itself sits inside the read phase. The access checks andnoteReadstay outside it.The new
test/telemetry-reads-timing.test.tshas one test per route asserting the phase order, plus one for a refused read. With theapi.tschange stashed, those five tests fail. With it in place they pass, alongside the existingtest/telemetry-timing.test.ts.appphase: the server already puts anappentry first on every response. The tests ignore it, so they check the three phases this issue names.telemetry:read, since thesessionnote runs before every check.bun x tsc --noEmit(nobuntypes, so it can't type-check here), the design lint (nosrc/web/change) or the full suite.I briefly overwrote the existing
test/telemetry-timing.test.tswith my own tests, then restored it from git. It ends up unchanged.Closes #4980