From fb0bf09a22ed28cf0992d47851d7b8e33ea4ecc3 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 11 Aug 2026 22:52:12 -0700 Subject: [PATCH] test(perf): raise entity-card ratio ceiling 50x -> 100x (CI flake) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RATIO GUARD asserted entity p99 <= 50x max(getPage p50, 1ms). On a fast runner getPage p50 floors to 1ms and a normal entity p99 (~50ms) reads as ~52x, tripping the gate even though absolute p99 (52ms) is well under the 100ms budget — a p99 tail divided by a sub-ms median. At the 1ms floor, 50x also made the ratio STRICTER than the test's own 100ms absolute budget. Raise the ceiling to 100x: still far below the >=200x O(N)-regression signal the guard exists to catch, and consistent with (never stricter than) the absolute budget. --- test/entity-card-perf.slow.test.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/test/entity-card-perf.slow.test.ts b/test/entity-card-perf.slow.test.ts index 831317be1..928bf1647 100644 --- a/test/entity-card-perf.slow.test.ts +++ b/test/entity-card-perf.slow.test.ts @@ -12,12 +12,15 @@ * loosen in CI only with evidence of runner noise). The protocol DOC * promises this number; the bound is op-layer latency (transport * excluded, as documented). - * 2. RATIO GUARD (machine-independent) — entity p99 ≤ 50× max(getPage p50, + * 2. RATIO GUARD (machine-independent) — entity p99 ≤ 100× max(getPage p50, * 1ms) on the same corpus. Calibration: the card is ~7 indexed reads + - * a keyword search on the miss path, measured ~21× a 1ms-floored - * getPage at 20K pages — an O(N) scan regression lands at 200ms+ - * (≥200×), far past the ceiling even on a slow runner, while the - * 2.4× headroom absorbs planner noise. + * a keyword search on the miss path. It measures ~21× a getPage p50 of + * ~2.5ms, but on a fast runner getPage p50 floors to 1ms and normal + * entity p99 (~50ms) reads as ~50×. An O(N) scan regression lands at + * 200ms+ (≥200×), far past the ceiling even on a slow runner. The ceiling + * is 100× (not 50×) so the guard is never STRICTER than the 100ms absolute + * budget when getPage floors to 1ms — the earlier 50× tripped on fast + * runners (a p99 tail ÷ a sub-ms median) while p99 stayed well under budget. * * The 200K-page validation is a documented MANUAL recipe in * docs/protocol/MEMORY_VERBS_v1.md — not CI-gated (seed time would dominate). @@ -40,8 +43,12 @@ const MEASURED = 200; const TARGET_ENTITIES = 50; // pages the measured calls rotate over const P99_BUDGET_MS = 100 * (Number(process.env.GBRAIN_PERF_BUDGET_MULTIPLIER) || 1); -// entity p99 ≤ 50× max(getPage p50, 1ms) — see the calibration note above. -const RATIO_CEILING = 50; +// entity p99 ≤ 100× max(getPage p50, 1ms) — see the calibration note above. +// (100×, not 50×: at the 1ms getPage floor, 50× would cap p99 at 50ms — stricter +// than the 100ms absolute budget — and tripped on fast runners where a p99 tail +// is divided by a sub-ms getPage median. 100× stays far below the ≥200× O(N) +// regression signal.) +const RATIO_CEILING = 100; function percentile(sorted: number[], p: number): number { const idx = Math.min(sorted.length - 1, Math.ceil((p / 100) * sorted.length) - 1);