Root-cause analysis¶
Point rca at run history (many runs, ideally with commit + outcome). For each
failure signature it assigns a root cause, a flaky-vs-real verdict, and a
risk score. An all-flaky failure set grades WARN so flakiness doesn't
block your gate:
$ assaylab rca history.csv
verdict: FAIL — 4 failing execution(s) across 2 signature(s) (1 real, 1 flaky); 4/8 passed.
[error] failure_signature cause=null_deref (conf 1.0) flaky=False (p=0.0) risk=0.7
NullPointerException across 1 test (3 runs): NullPointerException: card was null at 0x1a
why: matched 'null_deref' on 'NullPointer'; consistent failures — looks real
[warning] flaky_suspect cause=timeout (conf 0.85) flaky=True (p=0.95) risk=0.5333
Failure across 1 test (1 run): timeout waiting for lock after 5000ms
why: matched 'timeout' on 'timeout'; same commit produced both pass and fail
How it decides¶
- Root cause — a transparent, always-on categorizer maps the signature to a
cause (
null_deref,timeout,dependency,config,resource,concurrency,network,assertion, …) with a confidence and the evidence that fired. It's the interpretable floor the learned model is measured against. - Flaky-vs-real — the strongest signal is a single commit that shows both a pass and a failure (order-agnostic flakiness), backed by flip-rate across runs. Real failures are consistent at a given commit.
- Risk & forecast — recency-weighted failure rate blended with instability;
forecastestimates the chance the test fails on its next run.
Rank the riskiest tests¶
$ assaylab risk history.csv --top 5
risk forecast fail% flip% test
0.700 1.000 100.0% 0.0% svc.Broken::test_charge
0.533 0.000 33.3% 100.0% svc.Flappy::test_race
0.000 0.000 0.0% 0.0% svc.Stable::test_ok
The learned model¶
assaylab ships a self-contained logistic-regression classifier for flaky
prediction — pure Python (no scikit-learn in the base wheel), trained by batch
gradient descent, and persisted as JSON, never pickle (loading a model can't
execute code — a real supply-chain footgun avoided):
$ assaylab train labeled.csv -o flaky-model.json # rows of features + a 'flaky' 0/1 label
trained on 80 rows -> flaky-model.json (3 features)
$ assaylab rca history.csv --model flaky-model.json # use the learned model
For heavier models, train externally and export coefficients into the same JSON shape; prediction stays dependency-free and inert to load.