∵ causari · part of the Crovia family · v0.4.0

AI-written code has no author. It has causes. Causari records them.

How many lines from AI-tagged commits are still alive in your repository? One command, any git repo, no setup. A count, not a grade.

install · audit
curl -fsSL https://causari.dev/install.sh | sh
re audit                    # the repository you are in
re audit vercel/next.js     # any public repository

Apache 2.0 · one Rust binary, ~5 MB · Linux, macOS, Windows · no telemetry, no account, no cloud · no third-party requests on this page

01 · measure · re audit

Everyone argues about how much code AI writes. Nobody can check the numbers.

re audit reads plain git history — Co-Authored-By trailers, bot authors, agent markers — and asks git blame how many lines from those commits are still at HEAD. No model, no estimate, no survey. The same bytes require the same commit, method, blame flags and refs/notes/ai. A repository that has moved does not match.

--json gives the exact bytes behind any published row; --summary writes the same count as Markdown for CI.

$ re audit
∵ causari · AI code survival
───────────────────────────────────────────
  216 commits analyzed (git metadata only)

AI-tagged (metadata matched):   14 commits, 6267 introduced,
                      5185 survived (82.7%)
Probable AI-assisted: none detected
By agent (metadata matched only)
  cursor        6267 lines,  5185 survived (82.7%)

Baseline (untagged lines of the same repository)
  untagged      202 commits, 95759 introduced (79.5%)
  0-30 d        AI-tagged 85.6% · untagged 82.7%
  age-matched   +2.9 points (1 window, 75% of AI lines)

A measurement, not a grade · causari.dev/method

What it cannot see

Inline completions (Copilot, Cursor Tab, Windsurf, …) leave no git trace. Commits without a trailer are UNKNOWN and excluded from the headline. UNKNOWN is not a finding that a human wrote them. One bulk commit can dominate a line-weighted ratio, so method v2 also reports a capped ratio and the median per commit; repositories under five AI-tagged commits are measured but not aggregated. Method v3 puts the repository's own untagged lines next to the AI-tagged ones inside matched age windows, and names the oldest line still at HEAD. Method v4 keeps that baseline and stops counting a git-ai note that does not name a tool. Published reports through the 0.3.0 release stay on v3. The survival percentage is persistence of the tagged cohort. It is not quality, productivity, total AI usage, authorship, security, correctness, or a causal effect. All of it is written down at causari.dev/method, with how to reproduce or contest a number.

re audit --json   # "coverage": what was counted, what was not

02 · record · re init

Git remembers what changed. The ledger records what the runtime declared.

The same binary can record each agent edit — prompt, model, files read and written — into a local ledger in .causari/, gitignored. re why names the ledger event associated with a line. That is what the recorder stored. It is not a proof of who wrote the line, and a miss is not a finding that a human did.

re init                     # .causari/, added to .gitignore
re hook claude-code         # every prompt and edit, exactly
re hook cursor              # same, from Cursor's hooks.json

$ re why src/auth.ts:42

src/auth.ts:42  ⊢  introduced by event 2d070eb8cf
  agent:     claude-code
  tool:      Write
  evidence:  declared (agent lifecycle hook)
  prompt:    "Add a health-check endpoint returning
              build sha and uptime"
  reads:     spec/health.md, package.json
  writes:    src/auth.ts

What each agent gives you today

Derived from the code and kept current; if a cell is wrong, open an issue. The two evidence classes, declared and correlated, are defined on the method page.

AgentPrompt + file, exactModel, tokens, costHow
Claude Codeyes, via lifecycle hooksnot yetre hook claude-code
Aiderheuristic join, measuredyesOPENAI_API_BASE → re proxy + re watch
Codex CLI, Agents SDKnot yetyesOPENAI_BASE_URL → re proxy
Cursoryes, via native hooksmodel yes; tokens, cost nore hook cursor
Windsurf, Copilotwhat the agent self-reportsnore mcp
Cline / Roo, scripts, curlheuristic joinyesbase URL → re proxy + re watch

03 · prove · re audit --seal

A measurement nobody can check is an opinion.

re audit --seal signs the exact audit JSON, bound to the commit and the method version, with the repository's Ed25519 issuer key: a Crovia Seal (crovia.seal.v1). re seal verify audit.seal.json checks it with the file alone — no server, no account, no trust in us — and the same check runs in a browser at causari.dev/verify without a network request.

$ re audit --seal
… the audit as usual, then:
✓ seal cs_2026_6X3TIUCUGIMGLH7ZQNXOMRREJ4
  written  audit.seal.json
  issuer   urn:crovia:seal-issuer:causari:c4b3b0a67b24
  commit   5990442f31c267cdbaee9039a54e0cbf6a81ef57
  method   v4 · sequence 0

$ re seal verify audit.seal.json
✓ signature valid — cs_2026_6X3TIUCUGIMGLH7ZQNXOMRREJ4
  crovia.seal.v1, audit seal · method v4
  commit   5990442f31c267cdbaee9039a54e0cbf6a81ef57
  audit    216 commits · AI-tagged (metadata matched): 14 commits,
           6267 introduced, 5185 survived

$ # someone edits a number…
✗ invalid: audit JSON does not match
  subject.output_hash: the numbers were altered

What it proves, and what it does not

A valid audit seal proves that this issuer key signed this exact audit JSON for this commit, produced with this method version, and that the numbers were not altered since. It does not prove the numbers are true: anyone reruns re audit on the commit and compares the bytes. It does not say who controls the key: the seal names it, you decide whether to trust it. This page says "signed" only where something is signed today.

re seal verify audit.seal.json   # needs the file and nothing else

04 · report · weekly

One numbered report a week, on open-source repositories.

The Survival Report counts, for each measured repository, the lines introduced by AI-tagged commits and the lines git blame still attributes to them at HEAD. Alphabetical and unranked, with intervals over the sample, a DOI per report, and opt-out by pull request; every row links to the audit bytes behind it.

$ re audit openai/codex --json   # the bytes behind a row
{
  "method": "v4",
  "total_commits": …,
  "verified": { "commits": …, "introduced": …,
                "surviving": …, "survival_rate": …,
                "capped_survival_rate": …,
                "median_survival": …,
                "largest_commit_share": … },
  "baseline": { "untagged": { … }, "by_age": [ … ],
                "age_matched": { "tagged_rate": …, "untagged_rate": …, "gap": … },
                "oldest_surviving": { "date": …, "commits_before": … } },
  "coverage": { "method": "v4", "shallow": false,
                "blame_flags": ["-w", "-M", "-C"] },
  "repository": { "head": "40 hex", "origin": "https://github.com/openai/codex" }
}
$ diff <(re audit openai/codex --json) repos/openai__codex.json

install

One binary. Verified download.

installer · sh / PowerShell
curl -fsSL https://causari.dev/install.sh | sh
# Windows (PowerShell)
iwr -useb https://causari.dev/install.ps1 | iex
Homebrew · macOS, Linux
brew install croviatrust/tap/causari
Scoop · Windows
scoop bucket add causari \
  https://github.com/croviatrust/scoop-bucket
scoop install causari
cargo · npm · pip
cargo install causari --locked
# no install: the launchers fetch the verified binary
npx causari audit
pipx run causari audit

One program under two names, causari and re. The installers check the archive's SHA-256 against the release's SHA256SUMS.txt; every archive carries a signed SLSA provenance attestation. re mcp serves Claude Code, Cursor, Windsurf and Cline over local stdio (README). Everything stays in .causari/ next to your code. Apache 2.0, no paid tier.

in CI · croviatrust/causari@v1

On every pull request.

The Action downloads the prebuilt Linux binary, runs re audit --summary, writes the count to the job summary and keeps one sticky comment per PR. No traffic lights, no verdict: a count with its coverage statement. A live example.

on: pull_request
permissions: { contents: read, pull-requests: write }
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }   # shallow clones are refused
      - uses: croviatrust/causari@v1