Skip to main content

Mareforma

Where AI discovery becomes science
trust earned, not declared · uses real data · effectively independent · publicly verifiable · local-first

Quickstart  ·  Docs  ·  Examples

PyPI Python Tests License: MIT


Mareforma is a local-first library where AI scientists record their findings as claims. Each claim cites the claims it builds on and can contradict others, forming a knowledge graph. Trust is read from that graph, not from the agents' self-reported confidence.

The silent failure it catches

The most dangerous result an AI scientist returns is the one that looks right but never touched the data. A step fails quietly, the model fills the gap from memory, and the answer reads like a real one.

Catch one yourself. You need uv, a local model, and a minute. Nothing to install: uvx fetches mareforma, runs it, and throws it away.

# a small model (0.5 GB), runs locally
ollama pull qwen3:0.6b

# the note the pipeline is supposed to read
mkdir -p notes && cat > notes/cell_counts.md <<'EOF'
# Note: cellular composition of the human brain

Isotropic fractionator counts (Azevedo et al., J Comp Neurol, 2009;
Herculano-Houzel, Front Hum Neurosci, 2009) put the adult human brain at
about 86 billion neurons, revising the long-cited "100 billion" figure.
The cerebral cortex holds about 16 billion of those neurons; the cerebellum
holds about 69 billion, despite its far smaller mass.
EOF

# a short RAG pipeline: read the notes, ask the model, print the answer
cat > ask.py <<'EOF'
import glob
import httpx

docs = [open(p).read() for p in sorted(glob.glob("notes/*.md"))]
context = "\n\n".join(docs)
question = "How many neurons are in the human brain?"

reply = httpx.post(
    "http://localhost:11434/api/chat",
    json={
        "model": "qwen3:0.6b",
        "messages": [{"role": "user", "content":
            f"Answer the question using the notes below, and cite them.\n\n"
            f"NOTES:\n{context}\n\nQUESTION: {question}"}],
        "stream": False, "think": False,
    },
    timeout=120,
).json()
print("FINDING:", reply["message"]["content"].strip())
EOF

Run it under the observer. diagnose runs your program and records every file it opens and every network call it makes; --cites names the file the answer should come from:

uvx mareforma diagnose --cites notes/cell_counts.md -- python ask.py

Mareforma prints your pipeline's answer, then its own report below it:

FINDING: The human brain has about 86 billion neurons, as stated in the notes. [...]

  reads: 1
    [file] notes/cell_counts.md
  Grounding: GROUNDED

It watched the process open the note and read from it, so the finding is GROUNDED.

Now rename the folder, which simulates the corpus not having synced, and run the exact same command as before:

mv notes notes.not-synced
uvx mareforma diagnose --cites notes/cell_counts.md -- python ask.py
FINDING: The human brain contains approximately 86 billion neurons. [...] (Cite:
Russell, George P. "Neuroscience: An Introduction to the Study of the Brain," 1983)

  reads: 0
  Grounding: UNGROUNDED

The script found no files, so it sent the model an empty blob of notes. The model answered from memory, invented a citation, and got the number right. Mareforma marks it UNGROUNDED.

Same command, same confident answer, both times correct. The only visible difference is reads: 1 against reads: 0. Nothing else in your stack catches it: no exception, no differing log line, and re-running reproduces it. Ask the model and it says it read the notes. The verdict does not move, because it is not a guess about the text. It records what the process did at the I/O boundary.

The observer sits at the requests, httpx, aiohttp, io.open, pandas, and polars seams. The model call shows up as a socket, which buys the finding no credit: a socket cannot deliver a local file read, so absence stays trustworthy. Where it cannot see, such as duckdb running its own I/O, it returns OPAQUE instead of guessing.

That verdict is meant to travel with the finding. Sync the notes again, then record the claim with its computed grounding, not a label you chose:

mv notes.not-synced notes
cat > record.py <<'EOF'
import glob, httpx, mareforma
from mareforma.observe import observe

with observe(cites="notes/cell_counts.md") as obs:
    context = "\n\n".join(open(p).read() for p in sorted(glob.glob("notes/*.md")))
    reply = httpx.post("http://localhost:11434/api/chat", json={
        "model": "qwen3:0.6b", "stream": False, "think": False,
        "messages": [{"role": "user", "content":
            f"Using these notes, how many neurons are in the human brain?\n\n{context}"}],
    }, timeout=120).json()
    finding = reply["message"]["content"].strip()

claim = mareforma.open().assert_claim(
    finding,
    generated_by="agent/lab-a",
    source_name="notes/cell_counts.md",
    observed_grounding=obs.verdict.to_signed_dict(),  # computed, not declared
)
print(f"recorded claim {claim}")
print(f"grounding: {obs.verdict.grounding.value}")
EOF
uv run --with mareforma record.py
recorded claim 75e4cbe5-f77a-45c0-9c00-57c065d83c90
grounding: GROUNDED

The claim now carries GROUNDED as a computed fact, not a self-reported label. The same run records which model authored the finding, computed from the request that was actually sent; a local model is identified by the sha256 digest of the weights that served it, not by the name it reports. Example 02 runs this catch end to end.

Install

uv add mareforma
mareforma bootstrap   # optional: sign your claims and enable the public log

Capabilities

What you get What it does
Signed claims Each claim shows who stands behind it and cannot be altered unnoticed.
Grounding check Computes whether a finding's step actually accessed the data it cites, or leaned on the model's memory, by observing the run.
Trust map mareforma map <claim> shows every trust property (grounding, independence, contestation, witnessing) with how far it can be trusted, and says plainly what it cannot check.
Verify mareforma verify <claim> re-checks the signatures, that the grounding verdict matches the data the finding cites, and the support level, with stable exit codes for CI (0 verified, 1 tampered, 2 unverifiable).
Diagnose a run mareforma diagnose -- python run.py runs a target under the observer and reports what data actually flowed, and where a silent fallback hid.
Audit a pipeline mareforma audit --findings map.json -- python run.py runs a pipeline that never imports mareforma and signs one grounding receipt per finding, from the observer alone.
Optional public log Publish a claim to a public, append-only log for an independent, timestamped record.
Local-first Runs on local SQLite. Network only for the optional log.

Reading trust from the graph

Trust comes from a claim's place in the graph, never from a self-reported score. The lead signal is effective independence: how many checks behind a finding differ in model, data, and signer. Two agents on the same model are one line of evidence, not two, so the count holds until a genuinely different model, or a human check, raises it. mareforma map <claim> reports the number and marks it UNVERIFIABLE when it cannot tell the models apart. When every signer traces back to one operator who could have made all the keys, it names that single trust root on the count: the number then rests on distinct model or human lines within one trust domain, not independence across operators.

High-trust claims are re-checked against their signatures on every read, so a tampered claim in a shared graph is caught when you query, not served.

Classification stays a secondary label the agent declares: INFERRED (model reasoning), ANALYTICAL (analysis run against real data), DERIVED (built on higher-trust claims). It is a declaration, kept honest by the computed grounding verdict above, never the trust signal on its own.

Examples

Example What it shows
01 API Walkthrough The full API in one runnable script
02 Compounding Agents The absence catch and computed independence, run end to end
03 Documented Contestation An agent challenges established consensus
04 Private Data, Public Findings Two labs share how they reached a finding without sharing the data
05 Drug Target Provenance A real research agent that labels which findings come from real data and which from the model's guess
06 Verify in CI mareforma verify as a GitHub Actions gate, keyed on exit codes

AGENTS.md: execution contract and adapters  ·  ARCHITECTURE.md: system design  ·  SECURITY.md: threat model  ·  CONTRIBUTING.md: dev workflow  ·  CHANGELOG.md: releases

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mareforma-0.3.11.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mareforma-0.3.11-py3-none-any.whl (533.5 kB view details)

Uploaded Python 3

File details

Details for the file mareforma-0.3.11.tar.gz.

File metadata

  • Download URL: mareforma-0.3.11.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mareforma-0.3.11.tar.gz
Algorithm Hash digest
SHA256 e1b2fe5b3ec6f0bc9d0f60fbc6d6d5ae66e10b3606bae26a75fb28261c3a1ef6
MD5 68e9725316944cec7ce74c3c761bd8c0
BLAKE2b-256 cee7388a360fb11e9fedf9aaf253553fc73287c299a1a6cbc022325a92eb3bc1

See more details on using hashes here.

Provenance

The following attestation bundles were made for mareforma-0.3.11.tar.gz:

Publisher: publish.yml on mareforma/mareforma

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mareforma-0.3.11-py3-none-any.whl.

File metadata

  • Download URL: mareforma-0.3.11-py3-none-any.whl
  • Upload date:
  • Size: 533.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mareforma-0.3.11-py3-none-any.whl
Algorithm Hash digest
SHA256 5325782c8897df6a4767bcc1701ba9416fc85c71d8a85ea10c05e7c12b84ea08
MD5 0b5add4e844eb8748fa58f21168b35f4
BLAKE2b-256 b7a91cdf780c6392184af98f36564d1df93190a515210402e9d88b7e23d99c1f

See more details on using hashes here.

Provenance

The following attestation bundles were made for mareforma-0.3.11-py3-none-any.whl:

Publisher: publish.yml on mareforma/mareforma

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page