Epistemic infrastructure for AI scientists
Project description
Mareforma
Verify your AI agents' findings the way you'd verify a paper.
Mareforma is the local store where research agents write their claims. Signed, cross-referenced, and promoted when independent agents converge. Trust comes from evidence, not the agent's confidence score.
Why
AI agents now run real research problems with no infrastructure for knowing which findings to trust. Tracing tools record what the agent did. They do not record what it means, whether it converges with independent evidence, or how far a conclusion sits from its raw data. A silent pipeline failure, a prior-knowledge fallback, and a real result look identical.
What it does
import mareforma
with mareforma.open() as graph:
# Query established prior claims. query_for_llm wraps text in
# <untrusted_data>...</untrusted_data> tags so a downstream LLM
# consumes it as data, not instructions.
prior = graph.query_for_llm("topic X", min_support="REPLICATED")
claim_id = graph.assert_claim(
"Cell type A exhibits property X under condition Y (n=842, p<0.001)",
classification="ANALYTICAL",
generated_by="agent/model-a/lab_a",
supports=[c["claim_id"] for c in prior],
)
# Walk the full lineage of any claim: upstream + downstream + signatures
# + contradictions + verdicts in one deterministic dict.
lineage = graph.query_provenance(claim_id, depth=4)
graph LR
P(["ESTABLISHED upstream<br/>(prior literature)"]) --> A["ANALYTICAL · lab_a"]
P --> B["ANALYTICAL · lab_b"]
A --> R(["REPLICATED ✓"])
B --> R
R -->|"graph.validate()"| E(["ESTABLISHED ✓"])
style P fill:#713f12,stroke:#f59e0b,color:#fde68a
style A fill:#1e3a5f,stroke:#3b82f6,color:#93c5fd
style B fill:#1e3a5f,stroke:#3b82f6,color:#93c5fd
style R fill:#14532d,stroke:#22c55e,color:#86efac
style E fill:#713f12,stroke:#f59e0b,color:#fde68a
REPLICATED fires when two enrolled keys sign claims with different generated_by strings, all citing the same ESTABLISHED upstream in supports[]. Three conditions, all required. On a fresh graph, bootstrap an ESTABLISHED anchor with seed=True (enrolled validator only). See Example 03 for the seed-then-converge pattern.
Trust ladder. Derived from graph topology, never self-reported.
| Level | Meaning |
|---|---|
PRELIMINARY |
One agent asserted it. Cryptographic provenance, no convergence signal yet. |
REPLICATED |
≥2 enrolled keys signed claims sharing an ESTABLISHED upstream with different generated_by strings. |
ESTABLISHED |
An enrolled human-typed key signed a validation envelope binding evidence_seen=[...] review citations. |
Classification. Declared by the agent, records what kind of work produced it: INFERRED (LLM reasoning), ANALYTICAL (deterministic analysis against source data), DERIVED (built on ESTABLISHED or REPLICATED claims). Trust level and classification are independent axes. Query both: graph.query(text, min_support="REPLICATED", classification="ANALYTICAL").
Findings: earned, not declared. The trust ladder above is read from provenance. The trust layer (mareforma.trust) goes one step further. It turns a claim into a content-addressed Proposition bound to a pre-registered Prediction, computes the direction of evidence with compute_bearing instead of letting the agent declare it, and derives a count-based Status (PRELIMINARY to CORROBORATED) from independent datasets. A finding rides a signed claim, so it is additive. See Findings and Example 02.
Core surface
graph.assert_claim(text, classification, supports=[...])
graph.query(text, min_support="REPLICATED")
graph.query_provenance(claim_id, depth=4)
graph.validate(claim_id, evidence_seen=[...])
# Trust layer: a computed bearing and a derived status
graph.assert_finding(proposition, prediction, estimate, data_id="...")
graph.proposition_status(proposition) # derived Status + independence counts
mareforma bootstrap # generate Ed25519 signing key
mareforma --help # all subcommands
mareforma ingest paper.md # paper-abstract claim drafts (v0.3.3)
Full API and CLI reference: docs.mareforma.com. Opt-in components (DSSE signing, Sigstore-Rekor transparency, RFC 6962 inclusion proofs, DOI HEAD-checks against Crossref/DataCite, grounding sensors): see AGENTS.md. Storage is local SQLite, WAL mode, ACID. Network calls only for the opt-ins above.
Silent pipeline failures become visible
An AI agent runs a multi-step analysis: query a public dataset, regress a gene's expression against a phenotype, return the top hit. The data lookup silently returns null because of a stale identifier. The agent's LLM reasoning fills the gap with prior knowledge and returns a plausible-sounding answer. The output looks identical to a data-driven result.
finding_text = run_pipeline(target_gene, phenotype)
graph.assert_claim(
finding_text,
# The one line that breaks the symmetry: classification depends on
# whether real data flowed through. Mareforma doesn't compute
# this. The agent's wrapper inspects the pipeline state and tells
# the truth at assertion time.
classification="ANALYTICAL" if generated_code_ran else "INFERRED",
generated_by="agent/gpt-4o/lab_a",
source_name="depmap_24q2" if data_actually_loaded else None,
)
A downstream consumer querying min_support="REPLICATED", classification="ANALYTICAL" excludes the silent-fallback rows. The hallucinated finding stays in the graph (auditable, signed) but is NOT in the trustworthy result set. The wrapper that picks ANALYTICAL vs INFERRED is doing the work. Mareforma makes that work visible and tamper-evident.
Example 05: Drug Target Provenance wraps the omics AI agent MEDEA and shows the classification gate catching a real silent failure in its identifier lookup.
Findings contradict
prior = graph.query("Treatment X", min_support="ESTABLISHED")
graph.assert_claim(
"Treatment X shows no effect (n=1240, p=0.21): larger and more diverse cohort",
classification="ANALYTICAL",
contradicts=[c["claim_id"] for c in prior],
)
Both claims coexist. A human reviewer sees the tension in the graph. graph.refutation_status(claim_id) surfaces whether a claim is clean, contested, contradicted, or retracted.
Get started
uv add mareforma
mareforma bootstrap # optional: enable signing and transparency
Without bootstrap, claims store unsigned. With it, every claim carries a tamper-evident signature and can submit to a Sigstore-Rekor transparency log.
Optional: adapters for ClawInstitute, ToolUniverse, Gemini for Science, and a mareforma.hooks recorder for Claude Code tool calls. See AGENTS.md → Adapter framework.
Examples
| Example | What it shows | |
|---|---|---|
| 01 | API Walkthrough | Full API reference |
| 02 | Compounding Agents | Findings accumulate across agent runs |
| 03 | Documented Contestation | Agent challenges established consensus |
| 04 | Private Data, Public Findings | Two labs share provenance without sharing data |
| 05 | Drug Target Provenance | Real AI research agent with honest evidence labels |
AGENTS.md: execution contract, signing setup, adapter framework.
ARCHITECTURE.md: system design, trust ladder topology, honest scope.
SECURITY.md: threat model and disclosure channel.
CONTRIBUTING.md: dev workflow.
CHANGELOG.md: release notes.
Full documentation: https://docs.mareforma.com
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 mareforma-0.3.4.tar.gz.
File metadata
- Download URL: mareforma-0.3.4.tar.gz
- Upload date:
- Size: 418.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
43554c6a3c9124fd03a8183a3a802093ffc6aaf4001aa686853e90f97572b51e
|
|
| MD5 |
4016df70e100d48a36fde3bd7c0998f0
|
|
| BLAKE2b-256 |
fbf702b11b773ed7b813b265c4efdab3aaea8a913e4191587950881e95d6ee0a
|
Provenance
The following attestation bundles were made for mareforma-0.3.4.tar.gz:
Publisher:
publish.yml on mareforma/mareforma
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mareforma-0.3.4.tar.gz -
Subject digest:
43554c6a3c9124fd03a8183a3a802093ffc6aaf4001aa686853e90f97572b51e - Sigstore transparency entry: 1792303242
- Sigstore integration time:
-
Permalink:
mareforma/mareforma@6325d570118bac87590abb574f03c25b6faf7fd7 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/mareforma
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6325d570118bac87590abb574f03c25b6faf7fd7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mareforma-0.3.4-py3-none-any.whl.
File metadata
- Download URL: mareforma-0.3.4-py3-none-any.whl
- Upload date:
- Size: 300.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad0caf765cf02530c27adbbf01a6a29db3d120efd77fd91b66a567d49b21ff37
|
|
| MD5 |
92abb9eaca5d03b4b2c2c6d6d7dbc668
|
|
| BLAKE2b-256 |
e87d9d496de559c5428aaa78605f982c901072b8f7cd35f6c7a3a19646bafd6c
|
Provenance
The following attestation bundles were made for mareforma-0.3.4-py3-none-any.whl:
Publisher:
publish.yml on mareforma/mareforma
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mareforma-0.3.4-py3-none-any.whl -
Subject digest:
ad0caf765cf02530c27adbbf01a6a29db3d120efd77fd91b66a567d49b21ff37 - Sigstore transparency entry: 1792303376
- Sigstore integration time:
-
Permalink:
mareforma/mareforma@6325d570118bac87590abb574f03c25b6faf7fd7 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/mareforma
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6325d570118bac87590abb574f03c25b6faf7fd7 -
Trigger Event:
release
-
Statement type: