Open specs

Open formats, cross-checked in CI.

Seven signed formats with published specs and committed known-answer vectors. If the Python, WebCrypto and node implementations ever disagree, the build goes red — which is the only reason to believe any of them.

loss-event/v2

One authorization decision, signed by the enforcement point — and countersigned by a human when one approved it.

agent-record/v1

A self-attested record an agent signs about what it did. Says witness: self, because that is what it is.

mcp-audit/v1

One MCP tool call: which tool, which arguments hash, which session.

agent-signin/v1

An assertion an agent presents to a relying party that never talks to us.

agent-payment/v1

Proof a named human approved this cart, at this price, from this merchant.

agent-descriptor/v1

The .well-known document: who operates this agent and who to contact.

compliance-pack/v1

An evidence bundle that states what it does NOT cover, in the pack.

One canonicalisation, everywhere

# sorted keys, no whitespace, floats REFUSED —
# a float does not serialize portably, so a record
# containing one would verify in Python and fail in JS.
canonical = json.dumps(body, sort_keys=True, separators=(",", ":"))
digest    = sha256(canonical.encode())
signature = ed25519_sign(private_key, digest)

That last line is why every amount in these formats is a decimal string rather than a number. It is not a style choice — it is the reason the same record verifies in three languages.