A calibrated, provenance-first framework for detecting AI-generated media.
Project description
Bonafide
A calibrated, provenance-first framework for detecting AI-generated media — honest about what it knows, and about what it doesn't.
In an age of deepfakes and synthetic everything, the question "was this made by a human or by AI?" matters more each day. The existing detectors answer it with confident binaries that are wrong often enough — and in biased enough ways — that their own customers are turning them off.
Bonafide takes a different bet. It treats detection as evidence aggregation under uncertainty: it fuses hard provenance (C2PA / Content Credentials), watermarks (SynthID), and an ensemble of ML detectors into one calibrated probability with a confidence interval and a readable evidence report — and it abstains when the evidence doesn't support a confident call. Evidence, never an accusation.
- The moat: a Bayesian evidence-fusion + calibration engine that combines cryptographic proof and noisy ML scores into one honest, auditable verdict.
- The architecture: ports-and-adapters, so any detector for any medium plugs in — text and images first, audio and video as drop-in adapters later, with zero core changes.
- The wedge: the only detector you can actually trust — plus a regulatory tailwind (EU AI Act Article 50, effective 2 Aug 2026).
See DESIGN.md for the full technical design.
Status: M2a — a real, trust-verified C2PA / Content Credentials signal for images (M1),
plus a real calibration + conformal-abstention core with an evaluation harness and
bonafide fit / bonafide eval (M2a). The neural text ensemble lands in M2b, so text still uses a
placeholder heuristic and mostly returns abstain. See ROADMAP.md for the plan and
PROGRESS.md for what's shipped.
Run it
Prerequisites: Python ≥ 3.11 and uv (check: python --version, uv --version).
uv venv # create .venv
uv pip install -e ".[dev,provenance]" # install (core is pure-Python; ML is an extra)
# CLI — analyze an image's Content Credentials, or some text
uv run bonafide detect ./photo.jpg
uv run bonafide detect --text "The quick brown fox jumps over the lazy dog near the bridge."
uv run bonafide detect ./photo.jpg --json
# API — starts on http://localhost:8000 (interactive docs at /docs)
uv run uvicorn bonafide.service.app:app --reload
A C2PA-signed image gives a real, explained verdict:
Bonafide verdict: 100% AI-generated (CI 99-100%) | decision: AI
modality: image | engine: bonafide/0.0.1+fuse-logodds-v0 | coverage: 95%
Evidence:
[+] c2pa.manifest conclusive llr +6.00 x0.95 -> +5.70 (basis=digitalSourceType:
trainedAlgorithmicMedia, validation_state=Trusted, signer=Adobe Inc., ...)
Conflicts: none
Everything else still answers honestly: an unsigned image, a self-signed "a camera took this" spoof, and ordinary text all return abstain, because Bonafide refuses to guess. The text ensemble and real calibration arrive in M2.
Commands
| Command | What it does |
|---|---|
uv run bonafide detect <src> |
Run a detection and print the evidence report |
uv run bonafide fit <corpus.jsonl> -o cal.json |
Fit a calibration + abstention artifact from labeled data |
uv run bonafide eval <corpus.jsonl> -c cal.json |
Evaluate calibration + decisions (ECE, FPR, coverage) |
uv run bonafide detect <src> -c cal.json |
Detect using a fitted calibration artifact |
uv run uvicorn bonafide.service.app:app --reload |
Run the HTTP API |
uv run pytest |
Run the tests |
uv run ruff check . && uv run mypy src tests |
Lint + typecheck |
uv build |
Build the wheel/sdist |
Optional extras (installed per milestone)
| Extra | Adds | Milestone |
|---|---|---|
.[provenance] |
C2PA / Content Credentials verification (c2pa-python) |
M1 |
.[calibrate] |
isotonic calibration + conformal abstention | M2 |
.[text] |
zero-shot text detectors + SynthID-Text (torch, transformers) |
M2 |
.[image] |
image forensic detectors | M3 |
.[explain] |
Claude-rendered evidence reports | M4 |
.[all] |
everything above | — |
Project docs
| Doc | What's in it |
|---|---|
| DESIGN.md | The full design and rationale — the single source of truth. |
| ROADMAP.md | The milestone checklist (the plan + what's done). |
| PROGRESS.md | Build log: what shipped each milestone and why. |
| docs/adr/ | Architecture Decision Records. |
Tech stack
Python 3.11+ · Pydantic v2 · FastAPI + Uvicorn · Typer CLI · uv + hatchling. ML/provenance
(c2pa-python, transformers, torch, scikit-learn, conformal) load as optional extras.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
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 bonafide-0.0.1.tar.gz.
File metadata
- Download URL: bonafide-0.0.1.tar.gz
- Upload date:
- Size: 282.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b339cbeca7107906d40a1ad4d0cf19608995f230c865bb328fbd975a191facfe
|
|
| MD5 |
70263c35113bf9cbdeb3aae379a63f09
|
|
| BLAKE2b-256 |
209d5063167b9fba2a62ac39bf4dca09d7c6a571b960e7ade4615fd3cf17f28b
|
Provenance
The following attestation bundles were made for bonafide-0.0.1.tar.gz:
Publisher:
publish.yml on satchmakua/bonafide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bonafide-0.0.1.tar.gz -
Subject digest:
b339cbeca7107906d40a1ad4d0cf19608995f230c865bb328fbd975a191facfe - Sigstore transparency entry: 2232770093
- Sigstore integration time:
-
Permalink:
satchmakua/bonafide@74fc6a6fefff38301e585fabe36aad4df517b643 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/satchmakua
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@74fc6a6fefff38301e585fabe36aad4df517b643 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file bonafide-0.0.1-py3-none-any.whl.
File metadata
- Download URL: bonafide-0.0.1-py3-none-any.whl
- Upload date:
- Size: 84.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fef7004017427417e4f90e64c052598b94af6814ca0dbdb6fb9c0223832d06e
|
|
| MD5 |
e2c7667ca6c9e11f3df226bdf4a22bf2
|
|
| BLAKE2b-256 |
9ce374efda4d39e2dc432a0d0a805323623120ce294087d1f8984f2f797c513e
|
Provenance
The following attestation bundles were made for bonafide-0.0.1-py3-none-any.whl:
Publisher:
publish.yml on satchmakua/bonafide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bonafide-0.0.1-py3-none-any.whl -
Subject digest:
6fef7004017427417e4f90e64c052598b94af6814ca0dbdb6fb9c0223832d06e - Sigstore transparency entry: 2232770785
- Sigstore integration time:
-
Permalink:
satchmakua/bonafide@74fc6a6fefff38301e585fabe36aad4df517b643 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/satchmakua
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@74fc6a6fefff38301e585fabe36aad4df517b643 -
Trigger Event:
workflow_dispatch
-
Statement type: