onetrace
onetrace is an SDK for emitting and verifying stage receipts: a signed, chained record of what a pipeline actually did at each step, checkable independently of the code that produced it. onetrace does not check whether a pipeline's output is true — it checks what was recorded, and whether an independent verifier can confirm that record is internally consistent and unbroken. Truth is a claim about the world; onetrace only ever speaks to what was recorded and what a verifier could confirm about it.
Install and quickstart
pip install onetrace
onetrace-verify (the reference verifier, standard library only) comes along automatically —
it is a declared dependency, not an extra step.
Save this as demo.py. It emits a two-stage run with no network, no model, and no file beyond
itself:
#!/usr/bin/env python3
"""onetrace quickstart demo: two stages, no network, no model, deterministic."""
import json
import sys
from pathlib import Path
from onetrace.emit import Instrument, Recorder
QUESTION = "What does the warranty cover?"
CORPUS = [
{"id": "p1", "text": "The warranty covers manufacturing defects for twelve months."},
{"id": "p2", "text": "Shipping delays are handled by the logistics partner, not the warranty."},
{"id": "p3", "text": "Batteries are covered by a separate six-month warranty."},
]
def main(out_dir: str, run_id: str) -> None:
out = Path(out_dir)
out.mkdir(parents=True, exist_ok=True)
corpus_path = out / "corpus.json"
corpus_path.write_text(json.dumps(CORPUS), encoding="utf-8")
rec = Recorder(out_dir, run_id=run_id, declared_stages=["retrieve", "answer"],
manifest=Path(__file__), policy="fail-closed",
anchor_reason="quickstart demo; epoch anchoring is not implemented")
retrieve_cfg = {"tokenizer": "lower-split", "top_k": "1"}
@rec.stage("retrieve", Instrument("word-overlap", "retriever", "1.0.0", retrieve_cfg))
def retrieve(ctx):
corpus = json.loads(
ctx.read_external(corpus_path, "application/json", name="corpus",
trust_class="operator-authored").decode("utf-8"))
qwords = set(QUESTION.lower().split())
scored = [(p["id"], p["text"], len(qwords & set(p["text"].lower().split())))
for p in corpus]
scored.sort(key=lambda s: (-s[2], s[0]))
best_id, best_text, _ = scored[0]
for k, v in retrieve_cfg.items():
ctx.constant(k, v)
ctx.assertion("candidate_count", str(len(corpus)))
return ctx.write_json("retrieved.json", {"id": best_id, "text": best_text})
answer_cfg = {"method": "extractive"}
@rec.stage("answer", Instrument("extractive", "answerer", "1.0.0", answer_cfg))
def answer(ctx, retrieved_artifact):
retrieved = ctx.read_json(retrieved_artifact)
for k, v in answer_cfg.items():
ctx.constant(k, v)
ctx.assertion("source", retrieved["id"])
return ctx.write_json("answer.json", {"answer": retrieved["text"], "cited": retrieved["id"]})
retrieved = retrieve()
answer(retrieved)
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2])
Emit two runs of it:
python demo.py run_a run-a
python demo.py run_b run-b
Verify one with the reference verifier:
cd run_a && onetrace-verify .
[PASS ] receipts/01-retrieve.json: bytes are canonical
...
[PASS ] manifest: chain head matches the last receipt
52 pass, 0 fail, 2 not-run -> PASS
The 2 not-run rows are originality — this run is unanchored (no epoch anchoring configured),
so the verifier checks that the record is internally consistent, not that it is first-published.
Compare the two runs:
onetrace diff run_a run_b --out diff_report
baseline run_a run-a (run)
candidate run_b run-b (run)
diff: identical
stage baseline candidate verdict
--------------------------------------------------------------------
retrieve 51bd312473c4 51bd312473c4 same
answer 35a281ec6835 35a281ec6835 same
first difference none
comparisons performed 2; stages identical before the first difference 2
onetrace localize takes the same two runs (or just one, to find the first unclean stage in it
alone) and finds the first point of divergence:
onetrace localize run_a run_b --out localize_report
baseline run_a run-a (run)
candidate run_b run-b (run)
localize: identical
stage baseline candidate verdict
--------------------------------------------------------------------
retrieve 51bd312473c4 51bd312473c4 same
answer 35a281ec6835 35a281ec6835 same
first difference none
comparisons performed 2; stages identical before the first difference 2
onetrace reproduce re-executes a recorded stage and compares its output against what the
receipt claims — it needs the original pipeline code available to re-run, so it isn't part of
this quickstart.
This transcript was run word for word in a fresh virtual environment (pip install onetrace
from a locally-built wheel, no editable install, no repository checkout) before being written
here.
Five verdicts
Every stage in a comparison gets exactly one of five verdicts, and nothing else:
- same — the stage's output digest matches on both sides.
- FIRST DIFFERENCE — the first stage, in order, whose output digest does not match.
- downstream — after the first difference, still different; the divergence propagated.
- reconverged — after diverging, a later stage's output matches again (different work, same result — this happens in practice and is reported honestly, not hidden).
- COULD NOT CHECK — the stage can't be evaluated (an unimplemented format version, a declared boundary, a file that can't be read). This is not a pass, and it is not silently folded into "same."
A verdict is always about a stage's output. A difference in the instrument, its
configuration, or the declared constants never changes a verdict by itself — it appears as an
annotation alongside the ladder, naming exactly what differs, so a same result never hides that
something about how the output was produced changed even though the bytes didn't.
diff and localize each also report one overall result word for the whole comparison
(identical, diverged, not comparable, refused, or could not check, with exit codes
0/1/2/3/4 respectively — localize on a single run instead reports clean or located, exit
0 or 1); reproduce reports each stage as REPRODUCED, DIVERGED, or COULD NOT CHECK.
Links and the trust model
- Documentation — the format in plain words, the five verdicts, the three verbs, one page per adapter, and what onetrace does not claim.
- The stage-receipt format (Internet-Draft)
- The reference verifier
- The rejection vectors — records a conforming verifier must refuse, and why
The verifier does not trust the SDK that emitted a record. Every record this SDK produces is checked the same way a record from any other emitter would be — the verifier reads bytes, not intentions, and it owes nothing to the code that wrote them.
Stability
The current record format is stage-receipt/0.2 (format major version 0), specified by an
Internet-Draft that has not yet reached RFC status. Anything in the format — required members,
canonical-form rules, the rejection vectors — may still change before major version 1. Format
major version is carried in every record: a manifest declaring one the reference verifier does
not implement is refused outright, by name, rather than silently accepted (verify a manifest with
an unrecognized format and it prints [REFUSED] manifest: format -- ... and exits non-zero); a
verb comparing individual stages reports the stage's own verdict as COULD NOT CHECK for the
same reason. Neither ever guesses.
License, security, and reporting a problem
Licensed under Apache-2.0.
This is pre-release software (see the classifiers in pyproject.toml). See SECURITY.md
for what's in scope and how to report a vulnerability; for anything else, open an issue against
this repository.
Release files for onetrace 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| onetrace-0.1.0.tar.gz | 4.8 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| onetrace-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.9 MB
Release files / onetrace-0.1.0.tar.gz
| Download URL | onetrace-0.1.0.tar.gz |
|---|---|
| Size | 4.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
51344b75b779ddeb138b6e2e60f547f341b5c550a4864ec632863f41878121d5
|
|
BLAKE2b-256 checksum How to use checksums |
2cd8e21418c5e0075d052e795ce34b47cb8ab3e8c59189c7741a42b32a8f2f5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / onetrace-0.1.0-py3-none-any.whl
| Download URL | onetrace-0.1.0-py3-none-any.whl |
|---|---|
| Size | 86.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f5b6b1a9baa809956071f64aa5288edbc1c5a14e80fe66f68f94aa7eb369ae7
|
|
BLAKE2b-256 checksum How to use checksums |
9efa1774aad9a962c2f9ee0550448eba7d0b36c50e296472f96808ac6fac0507
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|