Verifiers
The eight clause kinds the engine can evaluate.
A verifier is a list of clauses, and a clause is one checkable assertion about the deliverable — the engine evaluates all of them and reports each one separately.
{
"clauses": [
{ "kind": "http.status", "equals": 200 },
{ "kind": "json.schema", "schema": "invoice.v2" },
{ "kind": "data.freshness", "maxAgeSeconds": 60 }
]
}The eight kinds
These are the entire registry. A clause with any other kind is rejected at
the API boundary, so there is no way to open a warrant against a check the
engine cannot run.
kind | Fields | Passes when |
|---|---|---|
http.status | equals | The response status equals it exactly. |
json.schema | schema | The body validates against that named schema. |
json.jsonpath | path, equals? | The path resolves; if equals is given, it matches. |
file.sha256 | digest | The bytes hash to that digest. |
data.freshness | maxAgeSeconds | The payload is no older than that. |
uptime.window | windowSeconds, minRatio | Coming soon. Reads a supplied uptimeRatio; returns no_uptime_data otherwise. |
chain.event | topic | Coming soon. Reads supplied emittedTopics; returns no_event_log otherwise. |
llm.judge | rubric, minScore | Coming soon. Reads a supplied judgeScore; returns no_judgement otherwise. |
Three of these do not gather their own evidence yet
uptime.window, chain.event and llm.judge are real clause kinds and the
engine evaluates them, but each one reads a value handed to it alongside the
deliverable — uptimeRatio, emittedTopics, judgeScore — rather than probing
uptime, reading a chain log, or running a model.
Nothing in Warrant collects those today, so on a live warrant they fail closed
with no_uptime_data, no_event_log or no_judgement unless something upstream
supplies the value. If that something is the payee, the clause is the payee's
own word, which is the one thing a verifier exists to avoid. Build specs on the
other five until these are finished.
Every clause is reported, not just the first failure
The engine evaluates the whole list and returns a per-clause result with a reason code. A spec with three clauses where the second fails returns three details, not one — you learn that the status was fine and the schema matched and the data was stale, which is the difference between a useful escalation and a shrug.
score is the share of clauses that passed. The policy
decides what to do with it: a partial pass is exactly the grey band that
partially_released and escalated exist for.
When the source cannot be reached
Every clause fails with evidence_unreachable. A timeout, a refused connection
and a DNS failure are deliberately the same answer, because the useful question
is not which one it was — it is that no evidence exists, and a warrant never
settles in the payee's favour on an absence.
llm.judge is in the registry and is the weakest link
It is a real clause kind and the engine evaluates it, but a model's opinion is
not a proof in the way a hash or a status code is. Treat it as a filter that
routes borderline work to a person, not as an oracle that releases money on its
own. Pair it with a minScore you would defend in an argument.
Trying one without spending anything
The verifier bench takes a pasted payload and a spec and runs the real engine
against it: POST /bench/run, no key, nothing held, nothing spent. It is the
fastest way to find out what a spec actually does before a warrant depends on
it.