7.1 KiB
Verdict rules
The skill's job is to decide whether a performance result is actionable, not merely to restate a dashboard row.
Evidence checklist
For every suspicious change, try to fill this table:
| Evidence | Question | Strong signal | Weak/noisy signal |
|---|---|---|---|
| Changed metric | Is the raw diff above threshold? | large diff, consistent direction | barely above threshold |
| Repeated PR runs | Does it recur over days/runs? | same query/metric/arch repeats | appears once/disappears/flips |
| Confidence | Does confidence keep or downgrade? | tier/reason supports raw change; named checks explain why | tier says noise/suspect; adaptive threshold or raw samples downgrade |
| Trend/history | Is selected run outside normal spread? | outside p95/recent band, stable history | inside recent p95, frequent spikes/change points |
| Related metrics | Do CPU/real/client/memory agree? | consistent metrics | contradictory metrics |
| Coverage/PR diff | Did PR touch executed code? | intersecting covered changed files | no overlap/unrelated files |
| Flamegraph | Does stack delta explain metric? | hotspot aligns with PR/query | absent/unrelated/mixed |
| Local run | Does controlled local pair reproduce? | repeatable, significant p-value | one-off or toolchain-biased |
Verdict labels
real regression
Use when most of the following hold:
- CI diff is above threshold.
- Same query/metric/arch repeats across PR runs or confidence supports it.
- History does not show the same random movement frequently.
- Related metrics are consistent.
- PR/coverage relation is plausible, or flamegraph points at changed behavior.
Do not require every item; explain missing evidence.
likely noise
Use when:
- changed row appears once and disappears in later PR runs;
- selected value sits inside normal trend/history spread;
- confidence downgrades raw evidence;
- related metrics contradict the headline;
- no plausible PR/test relation and no profile support.
Still show the data that proves this.
needs rerun
Use when:
- raw diff is large but confidence/history/repeated runs disagree;
- only one run exists;
- result is near threshold;
- setup or infrastructure may have distorted measurements;
- local and CI disagree.
Recommended action: rerun performance CI or run a focused local pair.
unstable test
Use when:
- trend/history shows frequent comparable spikes;
- same query flips slowdown/speedup across runs;
- dashboard marks unstable metrics;
- self-comparisons or repeated runs are noisy.
Do not use this label just because a result is inconvenient.
real improvement
Use when:
- speedup is above threshold;
- repeated runs/confidence/history support it;
- it is not simply a reversal of random instability.
local-only evidence
Use when local perf.py shows a meaningful result but CI/dashboard evidence is absent or not checked.
not enough evidence
Use when required identity is missing:
- unknown run;
- unknown query index;
- wrong metric/arch;
- unavailable history and no repeated/local evidence.
Repeated PR run rules
When checking a PR, list all performance.ci runs returned by:
curl -fsS "$BASE/runs?q=$PR" | jq .
Then compare the same test/query/metric/arch across runs.
Interpretation:
N/Nrepeated with similar diff: strong.1/Nonly: weak; likely rerun/noise unless diff is huge and profile explains it.- direction flips: unstable.
- only old run has it and latest run is clean: likely resolved/noise.
- latest run newly has it after earlier clean runs: investigate; could be new PR changes or master movement.
Master/history rules
Use dashboard trend/history instead of guessing.
Evidence for flakiness/noise:
- selected point lies in the recent normal band, e.g. below/near p95;
- comparable spikes appear without the PR;
- confidence adaptive threshold is larger than the raw effect;
changePointsshow a master change before/after the PR run;periodComparisonsshow frequent similar movements.
Evidence for new PR effect:
- selected point is outside recent p95 by a meaningful factor;
- no comparable historical spikes;
- repeated PR runs show same movement;
- PR touched covered relevant code.
Required history wording:
History center trend: 976 points over 2026-04-24 → 2026-06-15; all p05/p50/p95 = ..., recent 30 points over 22.7h p05/p50/p95 = ...; candidate is 3.06x p95.
Forbidden history wording:
min=..., median-ish=..., max=..., last=... .
Coverage/PR relation rules
Coverage answers: did this test execute code touched by the PR?
It does not answer: did the PR cause the slowdown?
Use coverage to phrase plausibility:
intersectingFiles > 0: plausible relation; inspect changed hunks.- touched-only files but no coverage overlap: relation less direct.
- covered-only files but PR did not touch them: maybe indirect behavior change.
- coverage unavailable: say unavailable; use PR diff and query text manually.
Flamegraph rules
Use flamegraph only for the matching:
- run id;
- test;
- query index;
- metric;
- arch;
- trace type.
Interpretation:
- CPU diff stack grows in candidate: compute hotspot candidate.
- Real grows but CPU does not: wait/I/O/lock/scheduler likely.
- Memory trace grows: allocation pressure likely.
Do not claim root cause if stack delta does not connect to query/PR changes.
Required flamegraph wording:
- include the UI query-page link first (
/runs/<runId>/tests/<test>/queries/<queryIndex>), because that opens the Flamegraphs card; - include raw API link only as supporting machine-readable evidence;
- list top sample deltas;
- say whether frames are absent.
Forbidden flamegraph wording:
flamegraph diff exists and contains relevant samples.
That is too vague to review.
Local perf.py rules
Meaningful local result requires:
- enough runs;
- p-value <= 0.05;
- diff above test threshold;
- repeat stability when result is important;
- identical datasets and comparable server settings.
Local-only result should be reported as local-only until checked against CI/history.
Report wording
Good:
The latest PR run shows
aggregation_in_order_2/4client_time/armat+23.2%, above a21.7%threshold. The same query appears in 3/4 PR runs, history does not show comparable spikes, and coverage intersectssrc/AggregateFunctions/...; verdict: real regression, medium confidence.
Bad:
This is a regression because the table says slower.
Bad:
Confidence:
M1:downgrade, M2:neutral, M3:downgrade.
Good:
Confidence tier is
noise: History Adaptive Threshold downgraded because observed 47.2% is below the 94.8% threshold from recent master noise; Raw Sample Evidence also downgraded.
Bad:
Cross-run behavior is unstable.
Good:
Cross-run chart oldest→newest: -15.3%, +19.8%, +6.6%, -10.7%, +15.3%, -15.6%, -3.1%, +22.5%; direction flips repeatedly, so verdict: unstable.
Good:
The latest rerun no longer reproduces the earlier
+24%row: the same test/query/metric/arch is now+1.2%, below threshold. The older row is superseded, so verdict: likely noise or resolved.
Bad:
Shows an old
+24%measurement table after a newer clean rerun with no explanation.