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

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

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

opened this

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 the full suite; the forge runs that on push.

  • Budget: EXPLORE_READ_BUDGET (50 ms) is registered in src/perf/budgets.ts.
  • New test: test/explore-budget.test.ts seeds 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.

  • Header rename: the phase was already there but called rank. I renamed it to read in src/web/studio/explore.ts and in the assertion in test/explore-timing.test.ts; that assertion was out of step with the issue, not wrong about behaviour. Anyone reading the old rank phase name will no longer find it.
  • Not done:

- 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.ts also tests that, including a repository flipping from private to public. - /api/v1/explore and 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 /explore and read the read;dur= entry in the Server-Timing header, or run bun test test/explore-budget.test.ts.

Closes #10946

Changes requested — before the latest push

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.

commented

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 BUDGETS in src/perf/budgets.ts, with the pattern /explore#read and a 50 ms p95. It no longer reuses /explore, so the 800 ms route budget is unchanged. EXPLORE_READ_BUDGET is now just budgetFor("/explore#read"), and the test reads the entry from BUDGETS and asserts it is there.
  • The #read pattern: it names a phase of the route, not a route, so budgetFor finds it when asked by that name but no router pattern matches it. I did not check whether perf/watch picks 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.
commented

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: BUDGETS has an entry for the read, /explore#read, at p95 under 50 ms. test/explore-budget.test.ts seeds 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.ts now reports the phase as read instead of rank.
  • Stall test fix: test/mcp-system-stalls.test.ts was order-dependent, and it fails the same way on main when run after mcp-write-scope in one process. A stall is blamed on any request that overlaps its window before it is blamed on a job. An earlier file's /mcp call 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 with mcp-write-scope, twice in a row, and tsc --noEmit is clean.

What I did not fix

  • mcp-write-scope: "each write is refused for a read-only token" passes alone and together with mcp-system-stalls and explore-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.

commented

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.ts registers /explore#read at p95 under 50 ms.
  • Test: test/explore-budget.test.ts seeds 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 in test/explore-timing.test.ts.

Check failures and fixes

  • mcp-write-scope: this was the last failure, and it fails on current main too, not because of this pull. The new flow drift-update on main only writes with action: "update" plus kind: "drift", repo and pull. The test's generic arguments made it a read, so its plansOnly assertion failed. The test now calls flow with a real write through a small WRITE_ARGS map. I merged main into 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 /mcp call 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-stalls and explore-budget pass together (7 pass, 0 fail), and tsc --noEmit is 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.

commented

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, not main'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's WRITE_ARGS lookup, not main's hard-coded flow branch. Its flow entry carries the same arguments (kind: "drift", action: "update", repo: "alice/game", pull: 1), so main's drift-update call is covered and nothing was lost.
Approved

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.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs