Warrant

A decision record for AI agents. Signed, hash-addressed, with reasons you can re-run.

When an agent accepts, rejects, or proposes something, it writes a small JSON record: what was decided, under which policy, because of which reasons, on which evidence — signed by the actor, addressed by its own hash. v0.3 — DRAFT

{
  "decision": "reject",
  "subject":  { "hash": "d5cf37…", "note": "PR-42" },
  "under":    [ "cb3a0a…  (policy in force, by hash)" ],
  "because":  [
    { "kind": "check", "check": "05d234…", "runtime": "cmd@v1",
      "verdict": "fail", "transcript": "9dc0c3…" },
    { "kind": "prose", "text": "clause 1: coverage 87.0 -> 84.2" }
  ],
  "actor":    { "id": "agent-b@vendor2" },
  "prior":    [ "00f79f…" ]
}

The record's hash is its identity. Change a byte of the body and its WarrantID changes — a citation still names the original bytes, so it no longer resolves to the altered record. Given the ID, tampering is detectable by anyone holding it; it does not rest on trusting a server.

Why not just logs?

A trace tells you what an agent did. A warrant records why it was allowed to — and the record survives the agent. Logs are mutable and vendor-specific. Warrants are:

Don't trust this page — re-run it

The spec's design rule is that two independent implementations MUST agree on every WarrantID and every verification outcome. Both ship in the repo. Run them:

$ pip install cryptography            # the one dependency (Ed25519)

# Python reference — SPEC §8 vectors, byte-exact, then a live tamper-detection round-trip
$ python3 impl/warrant.py conformance examples
CONFORMANCE: ALL PASS (20/20)
$ python3 impl/warrant.py selftest
SELFTEST: ALL PASS

# independent Go implementation (stdlib-only, Go 1.22+) — the SAME vectors
$ (cd impl-go && go build -o warrant-go .) && ./impl-go/warrant-go conformance examples
CONFORMANCE: ALL PASS (20/20)

# the two implementations agree on every settlement outcome, not just integrity
$ python3 tests/settlement.py
SETTLEMENT: ALL AGREE

That agreement is a spec requirement; these suites are the evidence it currently holds — the 20 SPEC §8 conformance vectors plus the settlement and hostile cross-checks. Outputs are real, from an actual run. Python needs one package (cryptography, for Ed25519); the Go implementation is standard-library only. (The page itself is zero-dependency; the reference impl is not.)

Reasons you can actually re-run

A reason is not just prose. Reasons come in two kinds — prose and check — and a check runs under one of two runtimes: cmd@v1 (the check run as a command in an isolated container; you supply the runner) or ski@v1 — a portable, deterministic, budget-bounded check. An ski@v1 reason is a content-addressed SKI term evaluated per Σ-GLYPH Book I; the verdict is a hash comparison, and work and peak memory are bounded by an ATP budget. That bound is what makes re-running a stranger's reason tractable — it caps the cost, it does not vouch for the reason. The Go implementation re-runs ski@v1 natively; the Python one re-runs it only when pointed at a sigma_glyph module via SIGMA_GLYPH, and otherwise says so:

$ python3 impl/warrant.py conformance examples
# ...
OK   ski: runtime re-run SKIPPED (no sigma_glyph; set SIGMA_GLYPH)

$ ./impl-go/warrant-go conformance examples
# ...native evaluator:
OK   ski: re-run -> pass, H(S), 20 ATP

The intended bridge between the two projects, precisely: where a reason is ski@v1, Σ-GLYPH is the compute model and Warrant the decision layer that cites it — Warrant otherwise runs on its own. In the other direction, Σ-GLYPH adopts its releases as warrants (its whole governance chain is signed decision records), so the compute core is governed by the format that runs on it.

Held to its own standard

The format was adopted from GOV-001 rev 4 after an adversarial review gate by three model families (Codex, Gemini 3.1 Pro, DeepSeek v4 Pro). The open review directory holds 14 documents — critiques, gate records, and point-by-point maintainer responses — with input from five model families (Codex, DeepSeek, Gemini, Claude Opus 4.8, Qwen). The hostile-input suite exists because a reviewer found recursive prior traversal that raised RecursionError in Python on a cyclic chain — and the Go implementation had the equivalent defect. Both now traverse iteratively, cycle-safe:

$ python3 tests/hostile.py
HOSTILE: ALL PASS   # cycles, self-cycle, 3000-deep chains, malformed JSON, unverified ski — no crash; Python/Go agree

What it is not

  • Not an agent framework.
  • Not a blockchain, token, or consensus network.
  • Not observability or a log aggregator.
  • One file format and a handful of verbs, deliberately small.
  • Specified precisely enough to re-implement from the document, in any language.
  • No server, no vendor, no account — the store is plain, content-addressed files.

Scope, status & non-goals

DRAFT. The v0.1/v0.2 body schema is stable and vector-pinned; the v0.3 additions (settlement §7, multi-root stores §9, key state §5.1) are document-level rules still under review, and their verification outcomes may change before v0.3 freezes — WarrantIDs themselves will not.

What it does: records who decided what, under which pinned rules, and lets anyone check that a record's canonical bytes match a known WarrantID and that its signature verifies under locally configured key state. A valid signature proves which key signed — not that the key should be trusted; trust roots are your configuration, and genesis.json is advisory until you pin it.

What it does not: judge whether a decision was correct; enforce anything at runtime; guarantee that a store stays available or that an un-pinned record isn't substituted. Its cryptographic mechanisms are exactly SHA-256 content addressing and Ed25519 signatures — no confidentiality, trusted timestamping, availability, consensus, or global identity.