Your tests passed. Your PR was approved. Your change still broke production.
Tests confirm existing behavior. Code review confirms intent. Neither validates what your change actually does.
GauntletCI detects Behavioral Change Risk in pull request diffs: logic shifts, missing validations, and hidden regressions that compile cleanly, pass every test, and survive code review.
GauntletCI is a diff-first Behavioral Change Risk detector for .NET that analyzes what changed, not your full codebase.
- Sub-second analysis - No compilation, no network
- 100% Local - No code leaves your machine
- Deterministic - Same diff, same findings, every time
- High-signal - Designed to surface 2–3 findings per run
Modern pipelines answer different questions:
| Layer | Question |
|---|---|
| Static analysis | Is this code well-formed? |
| Security scanning | Does this code contain vulnerabilities? |
| Tests | Does this code match expected behavior? |
| Code review | Does this change match intended behavior? |
None ask: is the behavioral impact of this change verified?
GauntletCI is that layer. It doesn't replace the others—it closes the gap none of them cover.
→ Full Architecture Guide | Technical FAQ
public async Task<Order> CreateOrderAsync(CreateOrderRequest request)
{
- if (request is null) throw new ArgumentNullException(nameof(request));
var order = new Order(request.CustomerId, request.Items);
return await _repo.SaveAsync(order);
}- 1 line removed
- Tests passed
- PR approved ("cleaned up redundant null check")
Callers relying on the early ArgumentNullException now receive a NullReferenceException deeper in the call stack. The change shipped.
GauntletCI flagged it before the commit was created:
[High] GCI0003: Guard clause removed at line 3. ArgumentNullException no
longer thrown on null input. Callers relying on this contract will see
NullReferenceException deeper in the call stack.
This is Behavioral Change Risk: a change that compiles, passes tests, and passes review, but alters runtime behavior in a way none of those checks can see.
The GauntletCI-Demo repo shows GauntletCI's approach with 36 scenarios across 3 tiers:
- Tier 1: 6 core rule scenarios
- Tier 2: 12 single-rule scenarios
- Tier 3: 18 behavioral regression scenarios
Each compiles cleanly, passes all tests, and would pass traditional SAST gates—but introduces behavioral risk only visible in diff-level analysis.
dotnet tool install -g GauntletCI
# Run before committing
gauntletci analyze --stagedFive minutes from install to first finding. No configuration required.
GauntletCI ships with 50+ deterministic rules organized across 8 production risk tiers:
- Tier 1: Structural & Scope Integrity
- Tier 2: Behavioral & Correctness Risk (control flow, method signatures)
- Tier 3: Security & Compliance (secrets, SQL injection, PII logging)
- Tier 4: Resource & Concurrency (async deadlocks, disposables, shared state)
- Tier 5: Observability & Failure (swallowed exceptions, removed logging)
- Tier 6: Evidence & Test Completeness
- Tier 7: Architecture & Structural Contracts
- Tier 8: Dependency & Integration Safety
Learn from real incidents how GauntletCI detects behavioral changes:
- GCI0029 - PII Logging Leak - 18 months of plaintext passwords, $2.1M GDPR settlement
- GCI0050 - SQL Column Truncation - Silent data loss during schema migrations
- GCI0048 - Insecure Random - Predictable tokens enable account takeover
- GCI0054 - Async Void Abuse - Stack Overflow outages from unhandled exceptions
- GCI0016 - Concurrency Safety - Race conditions cause data corruption
- GCI0022 - Duplicate Charge - 147 duplicate charges, $23K in refunds (missing idempotency)
See how GauntletCI detects risky patterns in real, open-source projects:
- AngleSharp - Enum Removal - Breaking change in public API
- Dapper - Null Forgiving - Nullable reference type handling
- EF Core - LINQ Loop - Query optimization pitfall
Start in advisory mode first:
name: GauntletCI
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
risk-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: EricCogen/GauntletCI@main
with:
fail-on-findings: "false"
inline-comments: "true"Once signal quality is tuned, change fail-on-findings to "true" to block risky merges.
Introducing GauntletCI into an existing codebase with legacy issues?
gauntletci baseline create
gauntletci analyze --stagedOnly new risks are shown. Legacy findings are suppressed until you address them.
A GauntletCI finding signals that behavioral impact is unverified—not that code is definitely broken.
- Confirm whether the behavior actually changed
- Check whether tests or validation cover the changed path
- Add validation, update tests, or document why the change is intentional
- Suppress only when the risk is understood and accepted
- Not a linter
- Not a static analysis replacement
- Not a test runner
- Not a formatter
- Not a general code quality tool
GauntletCI has one job: detect unverified Behavioral Change Risk in the diff.
No Behavioral Change Risk signals were identified. This doesn't guarantee correctness—it means no high-confidence risks were found by the current rule set.
- All analysis runs locally
- No code leaves your machine
- Auto-redaction prevents sensitive data in output
- Telemetry is opt-in
Troubleshooting Guide - Common problems and solutions
Advanced Tuning - Rule sensitivity, performance optimization
- Documentation Hub - Full documentation index
- CLI Reference - Complete command-line usage
- Contributing Guide - How to contribute
- Features & Benefits - Complete feature matrix
- Behavioral Change Risk Research - Academic foundations
- Security Policy - Vulnerability reporting
- Support - Getting help
- Release Notes - Current version
Questions? Ideas? Found a false positive?
- Twitter: @GauntletCI_BCRV - announcements and updates
- GitHub Issues: Report bugs or request features
- GitHub Discussions: Ask questions and share ideas
Elastic License 2.0
