DACIP DACIP

AI reviewers have opinions.
DACIP has proof.

A PR gate that's 100% deterministic. It reads both sides of your pull request from source and tells you the exact frontend call site your backend change leaves stranded, down to the file and line. Then it hands you a repro that keeps failing until you fix it.

There's no LLM in the pipeline and no spec to keep in sync. Feed it the same two commits today or six months from now and you get the exact same verdict, whether it runs in CI or in review.

Free for public repos + one private repo · installs in one click · first verdict in ~1 min.

dacip / contract-gate · failedpassing · PR #482 · getredash/redash

⛔ 1 breaking change introduced by this PR

Removes GET /api/queries/recent, and 1 call site still targets it:

client/app/services/query.js:387 → 404 in production
Prove it yourself. Fails on this branch, passes once you fix it:
pytest .dacip/runs/gate/repro_2e70be3.py -x -q

✅ Contract restored, repro now passes

GET /api/queries/recent resolves again · client/app/services/query.js:387 matched.

pytest … 1 passed in 0.31s
Same comment flips to resolved on the next push. No new bot spam.
verdict recomputed, identical every run.
123 routes · 93/94 calls matched · 18 dynamic, listed and never guessed
Real output from a validation run on getredash/redash, with a synthetic breaking commit.
9
major OSS repos tested cold, including sentry, zulip, and posthog
0
false positives, because we hand-verified every asserted defect
3
real bugs found in famous repos the first time we ran it
100%
of asserted findings ship with a repro you can run
<2m
from push to verdict, and 36 seconds cold on the largest repo

The one class of bug that survives green CI.

Agents rarely write bad syntax. What they break are contracts. A route gets renamed, the old call sites keep calling the old path, the unit tests still pass, and CI stays green. Then production starts returning 404s, and every check you had said the PR was fine.

the agent's PR, everything green
- def get_recent_queries():        # renamed
+ def get_query_history():
# tests  ✓ 1,204 passed
# lint   ✓ clean
# type   ✓ 0 errors
# frontend still calls GET /api/queries/recent
  ↳ 404 · nobody caught it

Every claim comes with the command that proves it.

An LLM reviewer tells you something might break. DACIP gives your reviewer a test that fails because it's broken, and goes green the moment you fix it. Nobody argues with a red test.

terminal, on the PR branch
$ pytest .dacip/runs/gate/repro_2e70be3.py -x -q
FAILED repro_2e70be3::test_contract, DACIP: no backend route, GET /api/queries/recent answered 404
# restore the route (or authorize the removal in your plan) …
$ pytest .dacip/runs/gate/repro_2e70be3.py -x -q
1 passed in 0.31s
# on the next push the PR comment flips to ✅ resolved, same comment, no bot spam
Fails before. The defect is real, not plausible.
Passes after. The fix is proven, not asserted.
Deterministic. Run it again in six months and you get the same answer.

Built for the failure mode agents actually have.

We picked one class of bug and cover it properly, instead of covering every class halfway.

01

Blast radius per change

Compares the contract graph across your PR's two commits and reports what actually changed: routes removed, methods swapped, auth dropped, required fields added. Each one comes with every affected caller at file:line.

BREAKING_ROUTE_REMOVED → mention-autocomplete.tsx:46
02

Source is the spec

It reads Flask, Flask-RESTX, Django and DRF (nested routers and re_path included), FastAPI (routers and include_router prefixes), Express, and Next.js handlers, then matches them against your real fetch and axios calls. No OpenAPI needed, so a stale spec can't mislead it.

03

Runnable repro per finding

A generated pytest file that only fails when the defect is real. Auth walls skip instead of failing, and every assumption is spelled out. Once it reproduces, verify promotes the finding from high to proven.

04

Pre-write agent guardrail

Inside Claude Code, a resident gate checks each edit's contract impact before it touches disk. It denies unauthorized breaks in under 500ms and names the callers left stranded. You can always override it.

deny: removes GET /api/users/mentionable, 1 caller…
05

Native to GitHub

A single PR comment that gets edited in place instead of piling up, a contract-gate check run, and SARIF into code scanning. On a clean PR it stays quiet.

06

Honest coverage, always

Dynamic paths, unresolved prefixes, frameworks it doesn't support yet: all counted and labelled in every verdict. When DACIP can't see something, it tells you instead of padding the report with guesses.

One engine. Two ways to run it.

Standalone, it's the deterministic gate on every pull request. Paired with Claude Code, it becomes the fact layer and enforcement loop your agent runs inside.

On its own: the PR gate

Push a PR; DACIP derives both sides from source and proves what broke.

base ref
origin/main
head ref
PR branch
DACIP engine
deterministic · no LLM · no tokens
1 · extract facts
routes · calls · auth · fields
2 · diff contract graph
what this PR breaks / fixes
3 · evidence gate
assert only what's proven
PR comment
break + file:line + repro
check run
blocks merge on break
SARIF
→ code scanning
same refs in → byte-identical verdict out · clone wiped when the job ends

With Claude Code: the verified loop

The agent reasons; DACIP supplies facts and enforces them.

Claude Code
reasons · writes
verified facts over MCP · ~90% fewer tokens
plan validated · invented endpoint rejected
each edit · breaking edit denied <500ms
fix accepted · repro flips fail → pass
DACIP
knows · verifies · enforces
the agent proposes · DACIP verifies · you approve

Put your coding agent on deterministic rails.

Hallucination and token burn come from the same place: the agent guessing about your codebase. DACIP takes the guessing out of it. It hands the agent verified facts and refuses the edits those facts rule out.

CAN'T HALLUCINATE

It stops inventing your API.

If a plan references an endpoint or symbol that doesn't exist, it's rejected before the first edit. The facts come over MCP as indexed routes and symbols, so the agent works from what's actually there.

plan → rejected: symbol
  calc_totals not found in index
CAN'T DRIFT

It can't break a contract.

A resident guardrail checks every edit against the contract graph before the write lands. A breaking edit gets denied in about 470ms with the stranded callers named. Either you authorize it in the plan, or you don't break it.

edit → denied in 474ms
  orphans mention-autocomplete.tsx:46
SPENDS LESS

~90% fewer tokens.

Indexed facts replace crawling the repo. The agent asks DACIP for a route or symbol rather than reading half the tree to find it, which means a lot less context and a lot less spend.

crawl repo ~42k tok
dacip_context → ~3k tok

Latency measured on a 500-file pilot (p50 476ms, p95 566ms, breaking-edit deny 474ms). The guardrail covers the file-edit tools (Edit, Write, MultiEdit). If the daemon isn't running it fails open and says so out loud, so uncertainty never blocks you, and a human override always beats the gate.

They review. DACIP proves.

LLM reviewers are useful, so keep yours. DACIP is a different instrument: a deterministic gate for the one class of bug that slips through green CI.

DACIP CodeRabbit Greptile Cursor BugBot Copilot Review
Engine Deterministic, no LLM LLM LLM + graph 8-pass voting LLM
Same input → same output Always, byte-identical No No Majority vote No
Cross-boundary contract breaks Core: file:line blast radius
Runnable proof per finding Every asserted finding
False-positive discipline 0 across 9 audited repos noisy on small PRs 11 FPs in benchmark surface-level
Blocks agent edits pre-write Yes: in-session guardrail post-hoc fix
Your code + LLMs Never leaves the runner Sent to LLM Indexed + LLM Sent to LLM Sent to LLM
Review breadth One bug class, covered exhaustively: contracts, imports, routes, schedules. Zero overlap with your reviewer. Broad Broad Broad Broad
Pricing $15/active contributor · free tier $24–30/seat $30/seat + usage $40/seat + Cursor bundled $19+

Competitor rows are compiled from vendor pages and third-party comparisons (Jan 2026), and corrections are welcome. The last two rows are where the field beats us, and that's on purpose. DACIP covers one class of failure thoroughly rather than every class lightly, and it works alongside whichever reviewer you already run.

Nine famous codebases. Zero wolf-cries. Three real bugs.

We ran DACIP cold on nine large open-source repos we'd never seen, and hand-audited every asserted defect against source.

Repository Routes Asserted Hand-audit verdict
getsentry/sentry15100 FP largest, 36s cold
zulip/zulip44500 FP
posthog/posthog8500 FP weak coverage declared, not guessed
Flagsmith/flagsmith54900 FP
netbox-community/netbox23500 FP
mathesar-foundation/mathesar2400 FP unsupported frontend: says so, loudly
getredash/redash1231real bug verified below
apache/superset3071real bug verified below
HumanSignal/label-studio1851real bug verified below
getredash/redashissue #7769 ↗

GET api/dashboards/recent: the client ships a service method for it, but no backend route serves it. There are zero hits across the whole server tree, so the first caller gets a 404.

A TYPE_CHECKING import references a path that stopped existing after a refactor. Every type-check of that file has been broken since.

“I can verify the fix is correct … CI's green now. LGTM”

— Superset maintainer, verifying the fix before merging it into apache:master the same day it was filed
HumanSignal/label-studioissue #9815 ↗

io_storages/filesystem.py imports .base, which doesn't exist. It's a dead module that crashes on first import. Pure debt.

The full methodology, the per-repo write-ups, and the 19 extractor gap classes we fixed along the way ship with the beta. We disclosed all three bugs upstream before publishing this, and the receipts are linked above. A Superset maintainer verified our fix and merged it the same day.

What DACIP will not do.

It won't guess.

Anything static analysis can't resolve gets counted and labelled in the verdict rather than quietly filled in. That habit is why the false-positive count is zero.

It won't opine on style, naming, or architecture.

Bounded checks with provable answers. Run it under your LLM reviewer; they don't overlap.

It won't feed your code to a model.

No LLM anywhere in the pipeline. Clones are wiped when the job ends; we persist finding fingerprints, never source.

It won't spam.

Clean PR → silent green check. One comment per PR, edited in place, flipped to "resolved" when you fix it.

Cheaper than the reviewers it out-proves.

A deterministic engine has no per-token inference bill underneath it, and the pricing passes that saving straight through.

Free

$0
  • All public repos
  • 1 private repo
  • PR gate, comment, check run
  • SARIF → code scanning
Most teams

Team

$15 / active contributor / month
  • Unlimited private repos
  • Org-wide baselines & triage
  • Finding history across merges
  • Repro verification in CI
  • Claude Code guardrail + fix loop

Enterprise

Let's talk
  • Self-hosted / on-prem CLI
  • SSO
  • Support SLA

An active contributor is anyone whose pull requests DACIP gates in a given month. We count them automatically from PR authors, so nothing is self-reported, and bots don't count. Repos are unlimited because repos aren't the unit of value. People are.

Merge with proof.

Private beta opens with the GitHub App. If your stack is Django/Flask + React/Next and your team ships with agents, you're exactly who this was built for.

One email when the beta opens, and nothing else. No analytics on this site. Privacy.