Pytest regression shield with predictive analytics — Louvain communities, Kaplan-Meier survival, adaptive Kalman over git history
Project description
forge
A pytest regression shield with predictive analytics — validated across 14 pre-registered scientific cycles on real Python bugs.
Single-file core. Stdlib-only runtime. Algorithms implemented from the papers, not wrapped from sklearn / scipy.
pip install forge-shield
forge --init && forge --baseline # 30 seconds to bootstrap
forge --predict # rank files by defect risk
Why forge?
Most defect prediction and test orchestration tools either:
- wrap sklearn / networkx in a black box, or
- make claims without empirical validation, or
- require complex setup before you see value.
forge does the opposite:
- Empirically validated on real bugs from BugsInPy — pre-registered hypotheses, public verdicts, a few losses honestly admitted
- Algorithms from the papers — Louvain, Kaplan-Meier, Newman Q, Ochiai, Halstead, McCabe, Wavelet, Kalman, DTW, ddmin, churn — full citations below
- Zero runtime deps beyond pytest (your test runner). No
.venvbloat, no transitive supply chain - One file —
forge.py, mypy--strictclean, 292 tests passing on Linux / macOS / Windows × Python 3.11 / 3.12 / 3.13
Headline finding
Across 3 independent pre-registered cycles on real Python bugs:
| Predictor | precision@10 (holdout) |
|---|---|
forge --predict (churn-only, Nagappan-Ball 2005) |
54 – 71 % |
forge --carmack (6-signal composite) |
28 – 45 % |
| random baseline | ~ 9 % |
The simple churn-only baseline beats the sophisticated multi-signal composite. Counter-intuitive, but empirically robust over 3 independent cycles. We document this honestly rather than ship marketing claims.
60-second tour
# Install + bootstrap in your repo
pip install forge-shield
cd your-python-project
forge --init # creates .forge/ + BUGS.md
forge --baseline # snapshots current test suite
# Now make changes. Then any of:
forge # detect regressions vs baseline
forge --predict # rank files by defect risk
forge --fast # run only tests impacted by recent changes
forge --mutate # how good are my tests? (AST-aware mutation)
forge --bisect TEST_NAME # find the commit that broke TEST_NAME
forge --flaky 5 # run tests 5× to detect unstable ones
forge --shield # orchestrated pipeline: predict → gen-tests → run impacted
Real forge --predict output (sample shape):
==================================================
DEFECT PREDICTION — 1245 files, last 8 weeks
==================================================
RANK RISK FILE
1 0.94 httpie/cli/argparser.py (churn 0.41, age 3w, 12 authors)
2 0.83 httpie/output/formatters/colors.py
3 0.71 httpie/cli/items.py
...
Install variants
| Command | What you get |
|---|---|
pip install forge-shield |
Core (stdlib + pytest only) |
pip install 'forge-shield[mutate]' |
+ --mutate (libcst AST-aware) |
pip install 'forge-shield[locate]' |
+ --locate (coverage.py) |
pip install 'forge-shield[fuzz]' |
+ --gen-props (Hypothesis) |
pip install 'forge-shield[all]' |
Everything |
Requirements: Python ≥ 3.11. Cross-platform: macOS / Linux / Windows (CI tested across 9 OS × Python combinations).
Sub-commands
Prediction & analysis
| Command | What it does |
|---|---|
forge --predict |
Recommended primary predictor. Rank files by churn-based defect risk (Nagappan-Ball 2005) |
forge --carmack |
Multi-signal risk score (research mode, 6 signals composite) |
forge --carmack --weeks-from <ISO_OR_SHA> |
Anchor history window to a date (BUG-014 fix) |
forge --modularity |
Newman-Girvan Q over the import graph |
forge --anomaly |
Flag commits with anomalous git activity |
forge --heatmap |
Per-file failure heatmap |
Test orchestration
| Command | What it does |
|---|---|
forge |
Run tests vs baseline (detect regressions) |
forge --baseline |
Snapshot the suite |
forge --fast / --fast-deep |
Run only impacted tests (1-hop / transitive, Bazel-style) |
forge --bisect TEST |
Bisect a failing test back to its commit |
forge --flaky [N] |
Re-run tests N times to find flaky ones |
forge --watch |
Auto re-run on file change |
forge --shield |
Orchestrate predict → gen-props → fast-deep |
Test quality & generation
| Command | What it does |
|---|---|
forge --mutate [--paths-to-mutate FILE] |
Mutation testing (libcst AST-aware) |
forge --mutate --incremental-mutate --since SHA |
Mutate only files changed since SHA |
forge --locate |
Ochiai SBFL fault localization (filters system libs by default) |
forge --gen-props PATH |
Generate Hypothesis property tests |
forge --minimize TEST INPUT |
Shrink failing inputs (ddmin, Zeller 2002) |
forge --snapshot "CMD" / --snapshot-check |
Capture command output as golden, diff later |
Project ops
| Command | What it does |
|---|---|
forge --init |
Scaffold .forge/ + BUGS.md |
forge --add "DESC" / --close BUG-ID |
Log bugs in BUGS.md |
forge --install-hook / --uninstall-hook |
Git pre-commit hook integration |
Run forge --help for the complete flag list. forge --version for installed version.
How forge compares to industry tools
From cycle 8 external benchmark:
| Job | forge | Industry tool | Result |
|---|---|---|---|
| Mutation testing (httpie/cli/argparser.py) | --mutate libcst, 70 mutants |
mutmut regex, 301 mutants |
forge: 100 % kill in 11 min vs mutmut 33 % in 16 min |
| Test impact selection on cold-start CI | --fast-deep (Bazel-style transitive) |
pytest --testmon (coverage-based) |
forge wins cold-start (no .testmondata to maintain) |
| Architecture quality metric | --modularity (Newman-Girvan Q) |
pydeps (graph extraction only) |
forge unique — pydeps has no Q metric |
See BENCHMARK.md for the 6 frictions admitted.
Scientific validation
forge has been tested through 14 pre-registered scientific cycles on real Python bugs from BugsInPy. Full methodology + verdicts public on forge-case-studies.
What "pre-registered" means
Before each cycle:
- Hypothesis written and committed to GitHub
- Eligibility criteria for the test panel locked
- Train / test seeds fixed (disjoint inter-cycles)
- Pass / fail thresholds set in stone
After the cycle: results published verbatim. No threshold shift, no cherry-pick, no post-hoc justification.
This is standard in clinical research and ML publication. Rare in OSS dev tools.
Production-validated capabilities
| Tool | Validation source |
|---|---|
forge --predict |
54 – 71 % precision@10 holdout (cycles 11, 13, 15) — recommended primary predictor |
forge --carmack |
Cycle 15 C1 verdict: Fisher exact p = 2.5e-9 (forge 47/105 vs random 9/105) |
forge --modularity |
Cycle 8 benchmark vs pydeps (unique Newman Q metric in OSS Python) |
forge --mutate |
Cycle 8 benchmark vs mutmut: 100 % kill rate in 11 min |
forge --gen-props, --minimize, --snapshot, --watch, --bisect, --flaky |
Cycle 20 v2: 30 real cases, 5 projects, 100 % pass |
10 auxiliary tools (--anomaly, --heatmap, --baseline/--diff, --init/--add/--close, --install-hook, --full-cycle, --incremental-mutate, --flaky-dtw) |
Cycle 21B: 50 real cases, 5 projects, 10 / 10 pass |
Cycles 11 → 24 summary
| Cycle | Hypothesis tested | Verdict |
|---|---|---|
| 11 – 15 | --carmack composite calibration |
1/3 OUI (cycle 15 Fisher p = 2.5e-9 robust) |
| 16 | Cold-start AST similarity signal | REJECTED (Jaccard uniform on Python) |
| 17 | --locate at scale |
REJECTED for user-facing (system files w/o filter) |
| 18 v2 | --shield on active HEAD |
OUI conditional (11 / 11 active, 0 / 9 dormant) |
| 19 v2 | Composite ablation (drop kalman + wavelet) | AMBIGUOUS (populations partially disjoint) |
| 20 v2 | Sanity at scale, 6 main tools | OUI 6 / 6 on 30 real cases |
| 21A | Fix BUG-014 + locate filter + shield warning | shipped v2.1.0 |
| 21B | Sanity 10 auxiliary tools | OUI 10 / 10 on 50 real cases |
| 22 | incremental-mutate retest + kalman analysis | kalman 56 % zeros; wavelet 7 × discriminant |
| 23 | NO DROP — single-signal performance per algo | 6 / 6 signals useful solo (≥ 2 × random) |
| 24 | Repondération + kalman extraction fix benchmark | NEUTRAL (∆ + 0.0 on panel_ref) → v2.1.0 kept |
Reproducibility
15+ FINAL_REPORTs publicly available with pre-registration committed before all runs. Seeds 42/43, 44/45, 48/49, 50/51, 52/53, 54/55, 56/57 — all disjoint inter-cycles. Anyone can git clone forge-case-studies && bash run_all.sh.
Algorithms (papers, not wrappers)
| Algorithm | Implementation | Reference |
|---|---|---|
| Louvain community detection | Greedy modularity gain, pure Python | Blondel et al. 2008 |
| Newman-Girvan modularity Q | (1/2m)·Σ[A_ij − k_i·k_j/2m]·δ |
Newman & Girvan 2004 |
| Kaplan-Meier survival | Right-censoring, ties handled events-first | Kaplan & Meier 1958 |
| Adaptive Kalman filter | Innovation-based variance re-estimation | Mehra 1970 |
| Haar wavelet | Avg / diff, padded to power of 2 | Mallat 1989 |
| DTW (Dynamic Time Warping) | O(n·m) DP matrix | Sakoe & Chiba 1978 |
| Ochiai SBFL | failed / sqrt(totalFailed × (passed + failed)) |
Abreu et al. 2007 |
| ddmin (delta debugging) | Unresolved-aware shrinking | Zeller & Hildebrandt 2002 |
| McCabe + Halstead complexity | Cyclomatic + effort + LOC + nesting | McCabe 1976, Halstead 1977, Menzies 2007 |
| Churn-based defect prediction | (added + deleted) / max(loc, MIN) |
Nagappan & Ball 2005 |
Validation tests pin known results: Karate Club graph Q ∈ [0.38, 0.45] (Zachary 1977), Kaplan-Meier hand-checked survival probabilities, two-cliques + bridge community split detection.
mypy --strict passes the entire codebase. 292 tests pass (cycle 24 state).
Honest limits
forge --carmackcomposite weights are heuristic, not calibrated against a labelled dataset. Cycle 24 attempted performance-based repondération — NEUTRAL benchmark onpanel_reference. Use as a ranking signal, not a probability.forge --predict(churn-only) outperformsforge --carmackon Python defect prediction at this scale (3 independent cycles confirm). Counter-intuitive but empirically robust.- Kalman filter on bugfix event series is theoretically sub-optimal for sparse count data (Kalman assumes continuous Gaussian noise). Hawkes process / Poisson regression would be canonical. Documented in v2.3+ roadmap.
- Coverage of forge's own CLI orchestration code is partial — math primitives are well tested, orchestration code less so. Cycles 20 v2 + 21B validate orchestration on real projects.
Roadmap
- v2.2+ : investigate Hawkes process / Poisson regression to replace Kalman for count data (cycle 23B finding)
- v2.2+ : empirical cross-validation calibration of composite weights (after cycle 24 NEUTRAL)
- v2.2+ : larger
panel_reference(N = 50+) to detect subtle signals masked by N = 20 variance
Links
- CHANGELOG.md — version history
- BUGS.md — open issue tracker
- BENCHMARK.md — cycle 8 vs industry tools
- forge-case-studies — 15+ FINAL_REPORTs with pre-registration
MIT License — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file forge_shield-2.1.2.tar.gz.
File metadata
- Download URL: forge_shield-2.1.2.tar.gz
- Upload date:
- Size: 141.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3dc0b124bb9d5e57c3f6ba5517ee52aa3d5adc596545d4fbca022f5d19581dac
|
|
| MD5 |
79ecccade21a587224efc3105100a742
|
|
| BLAKE2b-256 |
fe87021f45457488e7923bc19af29c83d9e3f66bec04feec6da4ebbcc1fdbe0c
|
File details
Details for the file forge_shield-2.1.2-py3-none-any.whl.
File metadata
- Download URL: forge_shield-2.1.2-py3-none-any.whl
- Upload date:
- Size: 79.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36d0d6602062e7e1e6a9d1c13ea16f69fcfcbac64e45fcebafc9b1fc41899cb8
|
|
| MD5 |
2f1d189a5c6f952f752bf45e30cd3c27
|
|
| BLAKE2b-256 |
41396bfaf051a435c04108da05b3c55de691c9f0ab0adfe4188ba7908474fd53
|