From 2a57746592a6d60d39fdc0a3cc5ff0c554b146f6 Mon Sep 17 00:00:00 2001 From: hermanngeorge15 Date: Tue, 20 Oct 2026 22:33:45 +0200 Subject: [PATCH 1/2] ci: raise the PERF-01 budget 200 -> 400ms for the 79-pattern library (#188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 200ms budget was set in 20c88d1 (2026-08-21) against 48 patterns. v0.2.0 ships 79 — 65% more per-file matching work — and the budget was never revisited. The job was being cancelled at 30 minutes before it ever reached this step, so the stale budget stayed invisible until the 30 -> 60 ceiling change exposed it. The gate was nondeterministic, not wrong. Four Dependabot PRs opened 2026-10-16 that change no Rust at all split two-pass/two-fail on this step (#193 #195 pass, #194 #196 fail), and main itself has been red since 2026-10-10. Measured 213ms on a hosted runner and 172ms best-of-5 locally, with runs spanning 172-375ms. 400ms keeps the gate load-bearing: the regression it defends against is pattern compilation moving back inside the per-file loop, which cost 806ms at 48 patterns and would be roughly 1.3s at 79. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f6af41..4f1068d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,8 +197,26 @@ jobs: if [ "$elapsed" -lt "$best" ]; then best=$elapsed; fi done - echo "500-file scan: ${best}ms (budget 200ms)" - if [ "$best" -ge 200 ]; then - echo "::error::PERF-01 regression: 500 files took ${best}ms, budget is 200ms (issue #29)." + # Budget raised 200 -> 400ms on 2026-10-20. The 200ms figure was set in + # 20c88d1 (2026-08-21) against a 48-pattern library; v0.2.0 ships 79, a + # 65% increase in per-file matching work, and the budget was never + # revisited. It went unnoticed because the job was being cancelled at + # 30 minutes before ever reaching this step — raising that ceiling to 60 + # exposed a gate that had already been failing. + # + # Measured: 213ms on a hosted runner (#188), and 172ms best-of-5 locally + # on arm64 with individual runs spanning 172-375ms. At 200ms the gate was + # nondeterministic rather than wrong: four Dependabot PRs on 2026-10-16 + # that changed no Rust at all split two-pass/two-fail (#193 #195 vs + # #194 #196), and `main` itself was red from 2026-10-10. + # + # 400ms keeps the gate load-bearing. The regression it exists to catch is + # pattern compilation moving back inside the per-file loop, which cost + # 806ms at 48 patterns and would be ~1.3s at 79 — still several times over + # this budget. Re-derive this number whenever the pattern count moves + # materially; a budget that tracks no measurement is how this one rotted. + echo "500-file scan: ${best}ms (budget 400ms)" + if [ "$best" -ge 400 ]; then + echo "::error::PERF-01 regression: 500 files took ${best}ms, budget is 400ms (issue #29)." exit 1 fi From a498a11bddbf2d4a5a3ab8fb8a494eb1fd5acab7 Mon Sep 17 00:00:00 2001 From: hermanngeorge15 Date: Wed, 21 Oct 2026 09:12:59 +0200 Subject: [PATCH 2/2] ci: rename the perf gate step to match the budget it enforces The step was still called "500 files under 200ms" while checking against 400ms, which is the same documentation drift this gate already suffered from. The required status check is the job name, not the step name, so renaming is safe. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f1068d..c31714c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,7 +166,7 @@ jobs: # the build. Measured at ~5ms of scan time locally and well under 100ms # end-to-end on a hosted runner; the regressed build this defends against # was 806ms on hardware faster than CI. - - name: Performance gate — 500 files under 200ms + - name: Performance gate — 500 files under 400ms run: | set -euo pipefail corpus="$(mktemp -d)"