Implementing it

Until today this site explained the format and left you to write it. That is a project: work out the required members from prose, get the digest rule right unaided, and find out whether you have finished by asking somebody. Two files make it an afternoon, and neither of them needs anything else of ours at runtime.

Writing a record

testimony_emit.py is one standard-library file with no dependencies, MIT licensed, meant to be copied into your repository rather than depended on.

from testimony_emit import Record

r = Record()
r.scope(acts=True, description="Support agent. Refunds to 500 EUR.")
e = r.evidence(kind="api", source="crm://customers/8842")
r.belief(subject="customer:8842", proposition="requested_refund",
         asserted_by={"id": "agent", "kind": "agent"}, evidence=[e])
d = r.decision(action_type="issue_refund", risk_class="high",
               risk_source="registry",
               proposed_by={"id": "agent", "kind": "agent"},
               verdict="permitted", executed=True)
r.approval(decision=d, approver={"id": "sam@example.com", "kind": "human"},
           identity_source="auth-session")
r.seal()
print(r.jsonl())

That reaches TR-4. It refuses at the point of the mistake rather than leaving you to find it from a validator after the run is over:

a refused action cannot also have executed
risk_source: 'model' is the proposing side of the same system
the approver is the proposer, 'agent'. An agent's own credential signing
  off its own action meets every other requirement and is worth nothing
'corp-sso' is not a known source. Use one of auth-session, api-key, jwt,
  ... or 'x-corp-sso' to declare your own

What it cannot check is what no emitter can. Whether the evidence you cite is what you say it is, whether the risk class really came from a registry, whether the name in an approval came from the session it claims. Those are attestations, the specification says so, and the validator reports them as attestations rather than counting them as proof.

Knowing when you are finished

The conformance corpus is 47 records and the verdict each one should get. The runner takes your command and compares.

python3 conformance/run.py --command "python3 my_validator.py --json {file}"

47 of 47 agree with the reference

run.py imports nothing of ours. Copy it into your repository and run it in your own CI, which is the only kind of conformance claim this project is willing to make about anybody.

What conformance means here, and what it does not

Your implementation reaches the same verdict as the reference on all 47 cases. It does not mean the same check names, the same wording, or the same number of checks. Those are this project's prose, and a corpus that compared them would be testing whether you had transliterated somebody else's file rather than implemented a specification. An independent implementation is the entire point, so the comparison is deliberately blind to everything except the answer.

It is also not a certificate. It is a statement about 47 cases, and the specification is larger than any 47 cases.

Two cases worth reading first

digest-of-nothing is sixty-four zeros where a digest should be. anchor-over-another-record carries a genuine, correctly signed RFC 3161 token issued over a different record.

Both reached TR-4 in this project's own reference validator until 5 September 2026, because it checked that an integrity entry carried a digest and never that the digest was the digest of the record. An implementation that accepts either has the same hole, which is why they are in the corpus rather than in a changelog.

If you already keep logs

You almost certainly have the timestamps and the actions. The four things a log usually lacks, in the order they cost you:

  1. Who approved, taken from authentication. Not that a human approved. Which one.
  2. What was refused. A log of executions is a receipt, and the interesting question afterwards is usually what the system was stopped from doing.
  3. Both sides of a disagreement. When two sources conflict and the system picks one, a log that keeps only the winner has hidden the decision that mattered.
  4. A digest somebody else can recompute. Which is the whole of the next page.

The honest state of this

There are two implementations and both are this author's, one in Python and one in TypeScript, written separately and compared against each other on every case. That is not an independent implementation in the sense that matters, and the Internet-Draft says so in its implementation status section rather than leaving you to notice.

If you build one, it is the most useful thing that could happen to this format, and you do not need to tell anybody or ask for anything. The licence is MIT for the tooling and CC BY 4.0 for the specification.

When you disagree with the reference

A case you fail is not necessarily your bug. If you have read the specification and reached a different answer, that disagreement is worth more than the corpus is: open an issue naming the case. The reference has been wrong before, the specification has been vaguer than it knew, and two of the checks exist because somebody said so.