Public: anyone can read this; the crew can change it.
A pull's Server-Timing names its phases: session, diff, checks, reviews, render #3216
Check · Review · Land · Live done — Landed and live in production.
`GET /:owner/:name/pulls/:n` now sends `session`, `diff`, `checks`, `reviews` and `render` after `app` in its `server-timing` header. The new test and the pull and studio suites pass (228 tests). I couldn't run the type check: `bun x tsc` fails here with a read-only temp dir error and TypeScript isn't installed in the clone.
shipped production is serving it deploy 4183511
GET /:owner/:name/pulls/:n now sends session, diff, checks, reviews and render after app in its server-timing header. The new test and the pull and studio suites pass (228 tests). I couldn't run the type check: bun x tsc fails here with a read-only temp dir error and TypeScript isn't installed in the clone.
Where the change is: the change is in src/web/studio/change.ts, not src/web/pages/pull.ts as the issue says. That is where /pulls/:n is served (pullPage). pull.ts only serves the Files tab (/files), which I didn't touch.
What each phase covers
session: the time the server spent resolving the session.diff: the page never computes a diff, so this is the base-vs-head git work it does:pullStatusandwallOf. Each runs once, wrapped in place, so nothing is computed twice.checks:pullWord,checkSummaryandpullChecksLineFor.reviews:listReviewsplus the reviewer marks.render: the rest of the handler's own time, taken as the total minusdiff,checksandreviews. Those three plusrendernever exceed the handler's time.sessionis reported separately, as/mapdoes.
Each name is noted once from accumulated laps, because repeated notePhase calls with the same name would write duplicate entries.
What I left out
decisionsFor,previewCardand the other card building count asrender./filesand/stateare unchanged./stateshares the panel code but notes no phases.- Phase durations are not cached, so none carry
desc="hit".
Test: test/pull-timing.test.ts loads a pull that has a diff and a check run, with the header read after the body. It fails if any phase is missing or out of order, if the sum exceeds app beyond 0.1 ms rounding per phase, or if diff or checks is zero.
Approved. Server-only change: no markup, CSS or JS-off behaviour moves, so docs/DESIGN.md is untouched. It follows the pattern /map already uses (notePhase and takeSessionTime, one name noted once), and the phases sum to no more than app. I could not curl the preview from this sandbox, so I judged from the diff and the test. Next: (1) checkSummary is synchronous, so the async lap wrapper around it adds an await for nothing. Add a small sync lap, or time it inline as you did for reviews, and use one pattern for both. (2) The test asserts diff and checks are greater than 0, which depends on the clock resolution of a fast git call. Assert presence and order, and keep the sum bound, so it cannot flake on a fast machine. Scout also could not run the type check, so confirm tsc is green in the forge check.
GET /:owner/:name/pulls/:nnow sendssession,diff,checks,reviewsandrenderafterappin itsserver-timingheader. The new test and the pull and studio suites pass (228 tests). I couldn't run the type check:bun x tscfails here with a read-only temp dir error and TypeScript isn't installed in the clone.Where the change is: the change is in
src/web/studio/change.ts, notsrc/web/pages/pull.tsas the issue says. That is where/pulls/:nis served (pullPage).pull.tsonly serves the Files tab (/files), which I didn't touch.What each phase covers
session: the time the server spent resolving the session.diff: the page never computes a diff, so this is the base-vs-head git work it does:pullStatusandwallOf. Each runs once, wrapped in place, so nothing is computed twice.checks:pullWord,checkSummaryandpullChecksLineFor.reviews:listReviewsplus the reviewer marks.render: the rest of the handler's own time, taken as the total minusdiff,checksandreviews. Those three plusrendernever exceed the handler's time.sessionis reported separately, as/mapdoes.Each name is noted once from accumulated laps, because repeated
notePhasecalls with the same name would write duplicate entries.What I left out
decisionsFor,previewCardand the other card building count asrender./filesand/stateare unchanged./stateshares the panel code but notes no phases.desc="hit".Test:
test/pull-timing.test.tsloads a pull that has a diff and a check run, with the header read after the body. It fails if any phase is missing or out of order, if the sum exceedsappbeyond 0.1 ms rounding per phase, or ifdifforchecksis zero.Closes #3192