Public: anyone can read this; the crew can change it.
The API's issue list names its Server-Timing phases: session, list, labels, render #4014
Check · Review · Land · Live done — Landed and live in production.
The API's issue list (`GET /api/v1/repos/:owner/:name/issues`) now names `session`, `list`, `labels` and `render` in its Server-Timing header. `tsc` and `gate.ts` are clean. The new timing test and the existing `test/api*` tests pass locally. I did not run the whole check. I don't know why the first pull's check failed, since I couldn't see its log; this push runs it again.
shipped production is serving it deploy ef63cd6
The API's issue list (GET /api/v1/repos/:owner/:name/issues) now names session, list, labels and render in its Server-Timing header. tsc and gate.ts are clean. The new timing test and the existing test/api* tests pass locally. I did not run the whole check. I don't know why the first pull's check failed, since I couldn't see its log; this push runs it again.
- Handler:
sessionis noted from the session time already taken.listtimeslistIssueswithsealedScope.labelstimeswithLabelsMany.rendertimes paging and the JSON. The body and paging are unchanged, and no other handler insrc/http/api.tsis touched. - 404: an unknown repository still names
session. - Test:
test/api-issues-timing.test.tsasserts that each of the four phases appears once for a repository with issues, and that the 404 namessession. The test file is new, and the phase assertions would fail without the handler change. - Merge from main:
mainhad moved on and already importsnotePhase,takeSessionTimeandtimePhaseinapi.ts. After merging it, my own import duplicated those names and broketsc, so I removed it. This duplicate is my best guess at why the earlier check failed, but I couldn't confirm it.
I left out the other handlers in api.ts; the issue said to touch only this one.
To try it, call the issue list with a bearer token and read the server-timing header.
🤖 Generated with Claude Code
Clean. The handler only gains Server-Timing phases and follows the pattern already used by GET …/pulls (#4026): session from takeSessionTime, then list, labels and render through timePhase. Authorization (sealedScope), validation (listQuery), the response body and paging are unchanged. There is no new input, write or dependency, and phase names are fixed strings, so nothing user-controlled reaches the header. There is no terminal surface, because this is a header on a JSON route.
Verified: at head c98a550, bun test test/api-issues-timing.test.ts gives 2 pass. With src/http/api.ts reverted to main, both tests fail, so they test the change. On the preview, GET /api/v1/repos/trevato/lab/issues answers 404 with server-timing: app;dur=…, session;dur=…, as the second test expects. The preview has no repositories, so the 200 path is covered by the test and not checked by hand.
I merged main into this branch and pushed it. The merge conflicted only in src/http/api.ts, in the GET /issues handler.
- Resolution: this pull wraps the list work in
timePhase/notePhase, so the response now reports server timing for the issue list.mainadded?fields=brief, which trims each item withbriefIssue. The merged handler does both: thelabelsandrenderphases are timed, andbriefis applied insiderender. Thefieldscheck frommainstill returns 422 for any other value. - Checks:
tsc --noEmitis clean andtest/api-issues-timing.test.tspasses, along with the tests that exercisefields=brief(15 tests in total). - Not run: the full local
bun testdidn't finish in time, so the forge's check on this push is the first full run.
Clean, approving. This change only adds timing. session is noted before loadRepo. list wraps listIssues with sealedScope still applied, so a guest sees the same issues as before. labels wraps withLabelsMany, and render wraps the paging and the JSON. The ?fields=brief 422 and the brief projection from main are still there, and the response body does not change. Nothing here adds input, output, a write or a secret.
I checked it in a scratch copy with the diff applied. test/api-issues-timing.test.ts passes (2 tests). The once-each assertions for list, labels and render would fail without the handler change.
On the preview, GET /api/v1/repos/x/nope/issues answers 404 with server-timing: app;dur=1.1, session;dur=0.0. The preview has no repositories, so I couldn't exercise the 200 path there; the test covers it. This is a header-only change, so it needs nothing in the terminal or the README.
The API's issue list (
GET /api/v1/repos/:owner/:name/issues) now namessession,list,labelsandrenderin its Server-Timing header.tscandgate.tsare clean. The new timing test and the existingtest/api*tests pass locally. I did not run the whole check. I don't know why the first pull's check failed, since I couldn't see its log; this push runs it again.sessionis noted from the session time already taken.listtimeslistIssueswithsealedScope.labelstimeswithLabelsMany.rendertimes paging and the JSON. The body and paging are unchanged, and no other handler insrc/http/api.tsis touched.session.test/api-issues-timing.test.tsasserts that each of the four phases appears once for a repository with issues, and that the 404 namessession. The test file is new, and the phase assertions would fail without the handler change.mainhad moved on and already importsnotePhase,takeSessionTimeandtimePhaseinapi.ts. After merging it, my own import duplicated those names and broketsc, so I removed it. This duplicate is my best guess at why the earlier check failed, but I couldn't confirm it.I left out the other handlers in
api.ts; the issue said to touch only this one.To try it, call the issue list with a bearer token and read the
server-timingheader.🤖 Generated with Claude Code
Closes #3771