2026-07-17 — XP-144 query-budget bench harness
What shipped
Section titled “What shipped”- A
test:benchlane (packages/service/src/__bench__/) the Stage-2 standards review runs as its query-perf gate. Against an ephemeral podman PG seeded with ~100k lesson sessions + 200k settlements, it asserts two deterministic things — never wall-time: (1) SQL-statement roundtrip budgets per endpoint (counted via a Drizzle logger callback), (2) EXPLAIN structural asserts (noSeq Scanon the large indexed tables) fromEXPLAIN (FORMAT JSON). - Baseline budgets captured post XP-135…143:
dashboard.summary4,sessions.list7,sessions.unresolvedAging8, the threefinance.list*Settlements1 each. - New rule
.claude/rules/query-perf-budget.md(paths:packages/service/**).
Key decisions
Section titled “Key decisions”- Bench runs on the SAME
createDBfactory the app uses (fidelity over isolation): added an additive optionalloggerparam tocreateDB(CreateDBOptions), default preserved, so no app call site changes. Bench injects aCountingLogger. - Budgets asserted with
toBeLessThanOrEqual— a ratchet cap, so a future improvement never reds the gate; tightening is a manual reviewer step, not a failing green run. - EXPLAIN targets only the ~100k tables where an index is unambiguously correct;
small dimension tables and the settlement LIST
created_atsort deliberately not asserted (a hash join seq-scanning a tiny table is the correct plan) — the settlement EXPLAIN targets the keyset cursor PK lookup instead.
Gotchas / lessons
Section titled “Gotchas / lessons”- Determinism is a construction property: every seeded value is a pure fn of the
generate_seriesindex (norandom(), no run-clock in the sesi grain). Unresolved sesi pinned to an early-July-2026 band that stays both ≤now−graceand inside the 2026/2027 academic year forever, so the aging resolver count does not drift month-to-month. pickStatementmatches captured SQL by substring and THROWS (loud) on a shape change rather than silently skipping — a hot-query rewrite is forced to revisit its EXPLAIN target.- Seed is ~48s wall (300k-row INSERTs + ANALYZE + EXPLAINs). Fine for a manually-invoked Stage-2 lane; not on any hot path.
Reference changes
Section titled “Reference changes”- New locked rule
.claude/rules/query-perf-budget.md— the wall-time-free query-budget gate convention (reference set re-ingests on next build).