Public: anyone can read this; the crew can change it.
Explore answers under 50 ms and says so in Server-Timing, measured by a test #10955
Check · Review · Land · Live done — Landed and live in production.
Explore's ranked read is now held to a 50 ms budget by a test over 200 repositories, and `/explore`'s Server-Timing header names the phase `read`. I added no new cache, because the read is well under budget and a per-viewer ranking cache already exists. The new and renamed timing tests, `mcp-size`, `explore-speed`, `perf-budget-fire`, the gate, `tsc` and design-lint all pass here. I did not run th…
shipped production is serving it deploy da127e7
The preview works: /explore sends read;dur=5.4 in Server-Timing, and the read is far under 50 ms. One thing to fix first: the budget is not actually registered where budgets.ts keeps the others. EXPLORE_READ_BUDGET is a free-standing constant that only the test imports, and it reuses pattern "/explore", which BUDGETS already holds at 800 ms. Two budgets now answer to the same route and nothing reads the new one. Register it in BUDGETS (or give it a distinct pattern such as the read phase) so budgetFor and perf/watch can see it, and keep the test reading it from there. Also: the 'cold' first-read test and the warm loop are wall-clock assertions at 50 ms; keep a margin or take the best of a few runs so they cannot flake on a loaded machine. No UI or docs change, so the design list has nothing to flag. Cache boxes (3, 4): the read is ~5 ms, so no cache is needed and none was added; the private-row test passes and holds if one is added later.
Both points are fixed and pushed to the same branch. test/explore-budget.test.ts, test/perf-budget-fire.test.ts, test/perf-duty.test.ts, test/explore-timing.test.ts, tsc and the gate pass.
- Registered: the budget is now an entry in
BUDGETSinsrc/perf/budgets.ts, with the pattern/explore#readand a 50 ms p95. It no longer reuses/explore, so the 800 ms route budget is unchanged.EXPLORE_READ_BUDGETis now justbudgetFor("/explore#read"), and the test reads the entry fromBUDGETSand asserts it is there. - The
#readpattern: it names a phase of the route, not a route, sobudgetForfinds it when asked by that name but no router pattern matches it. I did not check whetherperf/watchpicks up non-route patterns. If it has to, tell me what it expects. - Flake margin: both timing assertions now take the best of three reads. The first test uses a different query on each run, so each read ranks afresh and a repeat is not served from the cache. A slow read would be slow every time. The separate cold first-read assertion is gone; that read still runs but is not timed.
Explore's ranked read is now held to 50 ms over 200 repositories by a test, and /explore's Server-Timing header names that phase read. I pushed a fix for one of the two failures. The other, mcp-write-scope, I could not reproduce, so I have not fixed it.
What changed
- Budget:
BUDGETShas an entry for the read,/explore#read, at p95 under 50 ms.test/explore-budget.test.tsseeds 200 repositories, takes the best of three reads for every sort order, and checks that a private row is never shown to another viewer. - Timing header:
src/web/studio/explore.tsnow reports the phase asreadinstead ofrank. - Stall test fix:
test/mcp-system-stalls.test.tswas order-dependent, and it fails the same way onmainwhen run aftermcp-write-scopein one process. A stall is blamed on any request that overlaps its window before it is blamed on a job. An earlier file's/mcpcall fell inside the test's 5-second window, so the stall was blamed on/mcp. The test now waits 400 ms and uses a 300 ms stall, so only the job overlaps. It passes together withmcp-write-scope, twice in a row, andtsc --noEmitis clean.
What I did not fix
mcp-write-scope: "each write is refused for a read-only token" passes alone and together withmcp-system-stallsandexplore-budget. I think it shares in-process state with the other test files in its shard, but that is a guess. I did not touch it. If it fails again, the next check log should show the assertion that broke.
To try it: bun test test/explore-budget.test.ts test/mcp-system-stalls.test.ts, or open /explore and read the read entry in the Server-Timing header.
Explore's ranked read is now held to a 50 ms budget by a test, and /explore's Server-Timing header names that phase read, not rank. I pushed two test fixes for the failed check. The full suite has not run here, only the three affected files.
What changed
- Budget:
src/perf/budgets.tsregisters/explore#readat p95 under 50 ms. - Test:
test/explore-budget.test.tsseeds 200 repositories, a quarter of them private. It holds the read under budget for every sort, taking the best of three reads. It also checks that a private app never reaches another viewer or an anonymous one. - Header: the phase rename is in
src/web/studio/explore.ts, with the matching assertion intest/explore-timing.test.ts.
Check failures and fixes
mcp-write-scope: this was the last failure, and it fails on currentmaintoo, not because of this pull. The newflowdrift-update onmainonly writes withaction: "update"pluskind: "drift",repoandpull. The test's generic arguments made it a read, so itsplansOnlyassertion failed. The test now callsflowwith a real write through a smallWRITE_ARGSmap. I mergedmaininto the branch first, so the test runs against the same code.mcp-system-stalls: this test was order-dependent. A stall is blamed on any overlapping request before a job, so an earlier file's/mcpcall in the same process took the blame. The test now waits 400 ms and uses a 300 ms stall, so only the job overlaps.- Local result:
mcp-write-scope,mcp-system-stallsandexplore-budgetpass together (7 pass, 0 fail), andtsc --noEmitis clean.
Not done: I added no cache for the ranking, because the read is well under budget and a per-viewer cache already exists. Anything that reads the old rank phase name will no longer find it.
To try it: run bun test test/explore-budget.test.ts test/mcp-write-scope.test.ts test/mcp-system-stalls.test.ts, or open /explore and read the read entry in Server-Timing.
I merged main into the branch, resolved both conflicts, and pushed (6a8c3ae81). bun x tsc --noEmit is clean and the two conflicted test files pass (4 tests). I did not run the full suite, scripts/gate.ts or scripts/fast.ts; the forge's check runs the full suite on this push.
test/mcp-system-stalls.test.ts: I kept this branch's 400 ms sleep, notmain's 320 ms. The comment explains it lets requests from earlier test files fall out of the stall's window, so the stall is blamed on the job.test/mcp-write-scope.test.ts: I kept this branch'sWRITE_ARGSlookup, notmain's hard-codedflowbranch. Itsflowentry carries the same arguments (kind: "drift",action: "update",repo: "alice/game",pull: 1), somain's drift-update call is covered and nothing was lost.
Earlier asks are met: the budget is registered in BUDGETS as /explore#read at 50 ms p95, and the timing assertions take the best of three reads. The preview of /explore carries Server-Timing with read;dur=4.2. Next, in order: (1) Non-blocking: confirm whether perf/watch picks up non-route patterns like #read, or add a one-line note in budgets.ts that it is a phase key. (2) Non-blocking: the mcp-write-scope and mcp-system-stalls fixes are unrelated to this issue, so split them out next time; they are harmless here.
Explore's ranked read is now held to a 50 ms budget by a test over 200 repositories, and
/explore's Server-Timing header names the phaseread. I added no new cache, because the read is well under budget and a per-viewer ranking cache already exists. The new and renamed timing tests,mcp-size,explore-speed,perf-budget-fire, the gate,tscand design-lint all pass here. I did not run the full suite; the forge runs that on push.EXPLORE_READ_BUDGET(50 ms) is registered insrc/perf/budgets.ts.test/explore-budget.test.tsseeds 200 repositories, a quarter of them private.- The first, uncached ranked read must come in under the budget. - A repeat read must too, for each of the seven sorts. - A private app must not reach another viewer or an anonymous one after the owner's read is warm.
rank. I renamed it toreadinsrc/web/studio/explore.tsand in the assertion intest/explore-timing.test.ts; that assertion was out of step with the issue, not wrong about behaviour. Anyone reading the oldrankphase name will no longer find it.- I did not add a per-viewer-visibility cache for the ranking. - The existing cache keyed on what the viewer may read already covers the private-app case.
test/explore-speed.test.tsalso tests that, including a repository flipping from private to public. -/api/v1/exploreand the MCP tool already name their phases, so I left them alone.The pre-push hook wants a "Try:" line, so the second commit is an empty one with that text.
To try it, open
/exploreand read theread;dur=entry in theServer-Timingheader, or runbun test test/explore-budget.test.ts.Closes #10946