Signed, hash-addressed decision records for AI agents, with reasons you can re-run
claude mcp add warrant -- python -m warrant-verify{
"mcpServers": {
"warrant": {
"command": "python",
"args": ["-m", "warrant-verify"]
}
}
}Resumen de MCP Servers
# Warrant
**When a machine says something was allowed, can you check why — without trusting the machine that allowed it?**
A green CI run, a signed audit log, an agent's own JSON summary: each is a claim
about work, made by the party that did the work, covering exactly what that party
decided it should cover. Warrant is a decision record built the other way round. It
says **what** was decided, **under** which policy — pinned by hash, so "the policy"
is a specific sequence of bytes rather than a name — **because** of which reasons,
on **which** evidence, signed by the actor and addressed by its own hash. A reason
can be an executable check, which means the argument is not something you read. It
is something you re-run, on your own machine, and get the same verdict for.
Concretely: when an agent accepts, rejects, or proposes something, it writes a small JSON record, linked to the decisions that came before it.
```json
{
"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": "policy clause 1: coverage drops 87.0 -> 84.2" }
],
"evidence": [ "9dc0c3…" ],
"actor": { "id": "agent-b@vendor2" },
"prior": [ "00f79f…" ],
"ts": 1751677200
}
```
The record's hash is its identity. Change one byte of the decision, the policy reference, or the reasons — the hash changes, and every later record that cited it stops resolving. Nothing can be quietly edited after the fact.
## Why not just logs?
A trace tells you what an agent did. A warrant proves **why it was allowed to** — and the proof survives the agent. Logs are mutable, vendor-shaped prose. Warrants are:
- **Immutable** — identity is the hash of the content.
- **Signed** — you know which actor decided.
- **Anchored** — `under` pins the exact bytes of the policy that was in force, not "the policy" in someone's memory.
- **Re-checkable** — a reason can be an executable check. Anyone can re-run it and get the same verdict.
- **Linked** — `prior` makes decisions a chain: propose → reject (with reasons) → revise → accept. `warrant why <hash>` walks the whole chain.
A rejection is a first-class record, not an absence. This is the part that matters as agents get autonomy: the "no, because" survives, gets cited by hash, and stops the same argument from being re-had from scratch.
## Ten minutes
```bash
pipx install warrant-verify # or: pip install warrant-verify
```
Installs four commands: the `warrant` verifier, the `warrant-mcp` sealing proxy,
the `warrant-mcp-server` MCP server, and the `warrant-anchor` Merkle batcher.
`ski@v1` reasons re-run **offline** — the Σ-GLYPH Book I check engine ships
inside the package, so no separate clone is needed. (From a checkout:
`git clone … && pip install .`.)
The latest release **on PyPI is 0.7.1** (2026-07-31, tag `v0.7.1`), which is what
that line installs today; six versions are published. **This checkout is 0.8.0
and is not released** — so `warrant-mcp-server`, which 0.8.0 adds, is not
installable from PyPI until that release is cut. `CHANGELOG.md` is written
through 0.6.0. That each release installs and runs has been checked in a clean
venv by the maintainer — it is not a claim that anyone else has installed it.
```bash
warrant init # .warrants/ store in your repo
warrant keygen --out me.key # Ed25519; prints your pubkey
printf 'demo diff\n' > diff.patch # the thing being decided about
POL=$(warrant policy add examples/policy.txt) # pin the rules in force -> hash
P=$(warrant propose --subject diff.patch --under $POL \
--reason "utility fns needed" --actor me@host --key me.key)
R=$(warrant reject $P --check examples/check.sh --verdict fail \
--reason "clause 1: coverage drop" --actor me@host --key me.key)
A=$(warrant accept $R --check examples/check.sh --verdict pass \
--actor me@host --key me.key)
warrant why $A # decision -> reasons -> checks -> policy, verified
warrant verify # every hash, signature, and link in the store
```
The store is plain files, content-addressed, git-friendly. No server, no vendor, no account.
## Machine-readable output (`--json`)
> **Requires `warrant-verify` 0.5.0 or newer.** `0.4.0` (2026-07-16) predates
> this boundary, so against that release the commands below give
> `error: unrecognized arguments: --store-mode --json`. That gap — the README
> documenting a surface no published artifact had — is now a release gate:
> `tools/check_release_surface.py` runs in CI against the checkout and in the
> publish workflow against the built wheel, so a release that cannot do what this
> file promises fails to publish.
For CI, MCP, or an agent framework, add `--json` to `verify` and get exactly one
`warrant.verify-report@v0` object (one physical line) on stdout — no human text to
parse. Add `--store-mode` so a path that is not an initialized store fails closed
(`ok:false`) instead of being silently treated as an empty verification — this is
what makes `.ok` a safe store-verification predicate. The Python CLI takes the
store via the global `--store`; the Go CLI takes it as a positional argument. An
Evidence Pack's store is its `.warrants/` directory:
```sh
warrant --store ./evidence-pack/.warrants verify --store-mode --json | jq -e '.ok'
warrant-go verify --store-mode --json ./evidence-pack/.warrants | jq -e '.ok' # Go: positional store
```
```json
{"report":"warrant.verify-report@v0","grade":"base","ok":true,
"records":3,"errors":0,"warnings":1,
"findings":[{"level":"WARN","subject":"<WarrantID>","message":"..."}]}
```
`ok == (errors == 0)`; the counts and exit status are identical to text mode. Under
`--store-mode` a missing/uninitialized store fails closed (`ok:false`, one `ERR`
with subject `store`) in both implementations, so Python and Go agree on the
**normative** fields — `report`, `grade`, `ok`, `records`, `errors`, `warnings`,
and the set of `(level, subject)` findings; branch on those. A finding's `message`
is human-oriented prose and **may differ between the two implementations** (do not
branch on it). Without `--store-mode`, the Go CLI keeps a legacy flat-directory
mode for loose example files — pass `--store-mode`. The report is **not** a
Warrant: it is unsigned and carries no settlement authority.
Two guarantees a consumer may rely on (surfaced by the first consumer outside this
repository — the sibling `oaip` ledger, which is the same author's, not an outside
adopter):
- **Counts bind the findings.** `errors` equals the number of `ERR` findings and
`warnings` equals the number of `WARN` findings — always, in both
implementations. `findings` carries every `ERR`/`WARN` event (never `INFO`), so a
consumer may cross-check `errors`/`warnings` against the finding levels and reject
a report where they disagree.
- **`warrant.verify-report@v0` is a CLOSED schema.** Exactly the seven top-level
keys above, and exactly `{level, subject, message}` per finding — no more. Any
future additive field ships under a **new tag** (`@v1`), never inside `@v0`, so a
strict consumer that rejects an unknown top-level or finding key stays correct
across Warrant versions. Gate on the exact `report` tag you understand.
**The contract is specified in [`SPEC.md` §11](SPEC.md#11-verification-report--warrantverify-reportv0), not here.** This section is the
tour; §11 is what a producer commits to by printing the tag and what a consumer
may rely on when it reads it, with `schemas/verify-report-v0.schema.json`
alongside. Until 2026-07-30 §11 did not exist and this README was the only
statement of a contract a CI system branches on — a machine boundary specified
in a marketing document.
## Try it on a real case
Verify what an AI agent decided — the Air Canada chatbot case, as the record the
airline never had. **No clone, no build, no account.** Download the pack, check
it, and re-run the reason yourself:
```bash
pipx install warrant-verify
curl -LO https://github.com/s0fractal/warrant/releases/latest/download/air-canada-pack.zip
unzip air-canada-pack.zip
warrant --store air-canada-pack/.warrants verify # every hash, signature, link
warrant --store air-canada-pack/.warrants why 9084cd23f205cdd6e013deb6c6e2a84e4a5f4f469fb8f77ba443dfed44716f5a
warrant --store air-canada-pack/.warrants check b423b6a82c3451bfbd75563b39e6391093a64db57941d9247a61a6c620bd997f
```
That last line is the part nothing else does: it **re-executes the reason** on
your machine — a content-addressed, budget-bounded Σ-GLYPH term — and prints
`pass result=65cd957fee7e… atp_spent=17`. The same bytes give the same verdict
for anyone, forever. You are not trusting a log; you are recomputing the argument.
The walkthrough is in **[`demos/air-canada/`](demos/air-canada/)**; the packs are
built by `tools/build_release_packs.sh`, which refuses to ship a pack containing
anything key-shaped and verifies each zip the way a stranger will — unzipped, in
an empty directory, with no repo on the path — before it is attached to a
release. Packs ship from **0.5.0 onward**; the release process is in
[`PUBLISHING.md`](PUBLISHING.md). The portable bundle format is specified in
**[`EVIDENCE-PACK.md`](EVIDENCE-PACK.md)**.
## Use it as a CI gate
```yaml
- uses: s0fractal/warrant@v0.6.0 # or @master to track HEAD
with:
store: ./evidence-pack # a pack, or a .warrants store
version: '0.6.0' # pin the verifier for a reproducible gate
```
Pin **0.6.0 or newer**. 0.6.0 is the domain-separation flag day (below): a
0.5.0 verifier does not accept a `warrant-sig-v1` signature, so pinning an
older version against a store signed today fails every signature — the
reverse of the 0.4.0/`--json` gap, and just as invisible until it fires.
Installs theLo que la gente pregunta sobre warrant
¿Qué es s0fractal/warrant?
+
s0fractal/warrant es mcp servers para el ecosistema de Claude AI. Signed, hash-addressed decision records for AI agents, with reasons you can re-run Tiene 4 estrellas en GitHub y se actualizó por última vez today.
¿Cómo se instala warrant?
+
Puedes instalar warrant clonando el repositorio (https://github.com/s0fractal/warrant) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar s0fractal/warrant?
+
s0fractal/warrant aún no ha sido auditado por nuestro agente de seguridad. Revisa el repositorio original en GitHub antes de usarlo en producción.
¿Quién mantiene s0fractal/warrant?
+
s0fractal/warrant es mantenido por s0fractal. La última actividad registrada en GitHub es de today, con 5 issues abiertos.
¿Hay alternativas a warrant?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega warrant en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/s0fractal-warrant)<a href="https://claudewave.com/repo/s0fractal-warrant"><img src="https://claudewave.com/api/badge/s0fractal-warrant" alt="Featured on ClaudeWave: s0fractal/warrant" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!