A consistency check for your repository

Your repository
disagrees
with itself.

The README says one thing. The config says another. Invariant finds conflicting claims and brings the evidence.

Create a contradiction Explore a real scan →
Runs locallyEvidence includedNo AI service required
Claim comparison / 01acme-gateway
README.md :13

API listens on

8080The documented port
compose.yml :6

API exposes

8080The configured port
Same system. Same port.
These claims agree.

Both sources describe the API on port 8080. Change one claim to see what Invariant finds.

Follow the evidence
README.md:13
8080
The API listens on port 8080.
documentation · active · 85% extraction confidence
compose.yml:6
8080
- "8080:8080"
config · active · 98% extraction confidence
01 / Extract claims

Recognize port assertions in a README and a Compose service.

Interactive replay of real engine results. The 3000 state is the original fixture; 8080 is an agreeing variant. No repository is uploaded.

One system. Many sources.READMEArchitectureADRsCodeConfigManifestsCI

01 / From text to something comparable

It compares claims.
Not just strings.

Different files describe the same system in different languages. Invariant extracts supported assertions and gives them a common shape.

ArtifactREADME.md:13
“The API listens on port 8080.”
Normalized claim
subject
api
predicate
listens_on_port
value
8080
source
README.md:13
Comparison

Same subject.
Same predicate.
Compatible scope.

8080 ≠ 3000

Conflict candidate → evidence

Focused extractors, explicit rules, and confidence scores. Runtime ranges are compared for compatibility; source authority informs classification. The result is an inspectable candidate, not an automatic code change.

02 / A repository, inspected

Small mismatches.
Real consequences.

One deliberately inconsistent gateway. 10 files, 30 extracted claims, 9 conflicting pairs. Five stories worth investigating.

documentation drift

The setup guide sends you to the wrong port.

compose.yml:6
3000
- "3000:3000"
config · active · 98% extraction confidence
README.md:13
8080
The API listens on port 8080.
documentation · active · 85% extraction confidence

Actual output from the included demo/acme-gateway fixture. A finding is a prompt to investigate, not a verdict on which source is right.

03 / The shape of disagreement

See the relationship.
Then read the source.

The Conflict Graph connects claim nodes through their disagreements. Select a relationship to move from the pattern to the exact files and lines behind it.

Real Invariant Conflict Graph: five connected pairs, including API ports 3000 and 8080, OAuth2 and API keys, and PostgreSQL and SQLite.
FIG. 01 / Actual report · acme-gatewayOpen the interactive graph →

04 / Evidence, all the way down

No finding
without a source.

A contradiction is only useful if you can explain it. Inspect both assertions, their source lines, extraction confidence, and authority.

Decide which claim is authoritative, record different scopes, or mark the difference intentional. Export your resolutions to carry them into the next scan.

Inspect the real evidence →
Actual evidence inspector showing Compose port 3000 beside README port 8080, with source lines and extraction confidence.
FIG. 02 / The original lines, side by side
A note on time

When Git history is available, Invariant adds each source file’s latest commit and change date. That gives a provenance clue—not the exact moment a contradiction began.

05 / Context changes the answer

Different doesn’t
always mean wrong.

Environment and decision lifecycle matter. Invariant keeps these distinctions in its claim model, so an old decision can remain useful history.

01 / Scope

Development9090

Production9091

✓ Scoped difference · different environments

Telemetry ports from docs/operations.md. Unknown scope is kept as an ambiguity, not confidently resolved.

02 / Lifecycle

ADR-001 · SupersededRedis

ADR-002 · AcceptedValkey

↳ Historical relationship · preserved, not flagged

The accepted cache decision supersedes the old one. Toggle its status to replay the actual comparison.

06 / Take a closer look

Follow a claim.
Find its other story.

Start with the real report. Select a conflict, trace its evidence, and record a resolution in your browser.

Explore the working demo Download the scan JSON ↓
Run locally / Node 22+
# From a checkout of the private incubator repository
cd cli/invariant
npm ci
npm run build
node dist/cli.js scan /path/to/repository --out invariant-report
# Open invariant-report/index.html in your browser

The source currently lives in a private JP5 Labs repository. These commands require an authorized checkout; there is no public npm release.

Local, deterministic analysis. No API key. No model call. Export browser decisions to .invariant/resolutions.json for the next scan.