Done: GET …/repos/:owner/:name/app, …/app/members, …/app/domains and …/app/env answer a Server-Timing header naming session, the read (app, members, domains, env), render; an env read never puts a value in a phase name, in that order, the way GET …/tags does (notePhase(ctx.request, "session", takeSessionTime(ctx.request)), then timePhase/timePhaseAsync around the read and around json(…)). The bodies, status codes and access rules do not change.
[ ] Each route above names its phases; a refused read (404/403) still names session.
[ ] One test per route asserts the header's phase names in order (pattern: test/crew-timing.test.ts), and fails without the change.
[ ] bun test for the touched files passes.
Files: src/http/api.ts, one new test file.
Risk: none to behaviour; keep the read inside the phase, not the access check.
Done: GET …/repos/:owner/:name/app, …/app/members, …/app/domains and …/app/env answer a
Server-Timingheader namingsession, the read (app,members,domains,env),render; an env read never puts a value in a phase name, in that order, the way GET …/tags does (notePhase(ctx.request, "session", takeSessionTime(ctx.request)), thentimePhase/timePhaseAsyncaround the read and aroundjson(…)). The bodies, status codes and access rules do not change.session.bun testfor the touched files passes.Files: src/http/api.ts, one new test file. Risk: none to behaviour; keep the read inside the phase, not the access check.