diff --git a/gitnexus/bench/emit-persistence/baselines.json b/gitnexus/bench/emit-persistence/baselines.json index 0bb4250c3..93806b252 100644 --- a/gitnexus/bench/emit-persistence/baselines.json +++ b/gitnexus/bench/emit-persistence/baselines.json @@ -1,5 +1,6 @@ { "fingerprint": "1b9dd0b783899b47067c36511d241860f291ac736e57682b0ece14148e3958ff", "scaling_budget": 1.8, - "_note": "fingerprint = sha256 over per-file digests (filename + sha256(file bytes)), entry list sorted — binds each emitted line to its file so a row routed to the WRONG pair file changes the hash, AND catches within-file row reordering (file bytes hashed as-written). Byte-identity gate for #2203 U2/U3. NOTE: a future change that legitimately reorders emit (without changing the node/edge SET) will trip --check; regenerate then. scaling_budget bounds (t_large/t_small)/(LARGE/SMALL): observed ~0.95-1.05 (linear); 1.8 tolerates disk-I/O timing noise on CI while still catching an O(n^2) re-regression (~4x). Regenerate via `node --import tsx bench/emit-persistence/measure.mjs`." + "max_ms_large": 1000, + "_note": "fingerprint = sha256 over per-file digests (filename + sha256(file bytes)), entry list sorted — binds each emitted line to its file so a row routed to the WRONG pair file changes the hash, AND catches within-file row reordering (file bytes hashed as-written). Byte-identity gate for #2203 U2/U3. NOTE: a future change that legitimately reorders emit (without changing the node/edge SET) will trip --check; regenerate then. scaling_budget bounds (t_large/t_small)/(LARGE/SMALL): observed ~0.95-1.05 (linear); 1.8 tolerates disk-I/O timing noise on CI while still catching an O(n^2) re-regression (~4x). max_ms_large=1000ms is a coarse absolute backstop (observed ~200ms) that catches a gross uniform slowdown the ratio gate misses; generous so CI host noise won't flake it. Regenerate via `node --import tsx bench/emit-persistence/measure.mjs`." } diff --git a/gitnexus/bench/emit-persistence/measure.mjs b/gitnexus/bench/emit-persistence/measure.mjs index 49fbe278c..f7623bc34 100644 --- a/gitnexus/bench/emit-persistence/measure.mjs +++ b/gitnexus/bench/emit-persistence/measure.mjs @@ -198,6 +198,15 @@ if (!CHECK) { `(${SMALL}->${LARGE} entities, ms ${result.elapsed_ms_small}->${result.elapsed_ms_large})`, ); } + // Absolute backstop: the scaling ratio alone passes a uniform Nx slowdown (it + // only compares large/small). A generous, host-noise-tolerant ceiling catches + // a gross absolute regression. Opt-in (only enforced when max_ms_large is set). + if (base.max_ms_large !== undefined && result.elapsed_ms_large >= base.max_ms_large) { + failures.push( + `absolute wall-time regression: elapsed_ms_large ${result.elapsed_ms_large}ms >= budget ` + + `${base.max_ms_large}ms (coarse backstop, not a tight SLA)`, + ); + } process.stdout.write(JSON.stringify(result) + '\n'); if (failures.length > 0) { for (const f of failures) process.stderr.write(`[emit-persistence --check] FAIL: ${f}\n`);