# Verification

Verification judges a Delivery against the escrow's Terms and produces a Verdict, deterministically: the same delivery and the same terms always yield the same verdict. Terms are a list of declarative checks; the verdict passes only if every check passes.

## The check vocabulary

| Check | Shape | Passes when |
|---|---|---|
| `hash` | `{ "kind": "hash", "expected": "<sha256>" }` | The delivery's content hash equals `expected` |
| `maxBytes` | `{ "kind": "maxBytes", "limit": 10000 }` | The canonical JSON payload is at most `limit` bytes |
| `deadline` | `{ "kind": "deadline", "by": "<ISO 8601>" }` | The delivery was submitted at or before `by` |
| `shape` | `{ "kind": "shape", "requiredFields": ["url", "sha"] }` | The payload is an object containing every required field |
| `predicate` | `{ "kind": "predicate", "name": "minWords", "params": { … } }` | A registered custom predicate returns true |

## Content addressing

Deliveries are content-addressed: the payload is serialized as canonical JSON, keys sorted at every level, no whitespace, and hashed with SHA-256. Two payloads that differ only in key order hash identically; any difference in content changes the hash. The `hash` check compares against this value, which the buyer can compute before the work is ever submitted.

## Custom predicates

Predicates extend verification with code. They are registered on the verifier by name and receive the payload and optional params:

```ts
engine.verifier.registerPredicate("minWords", (payload, params) => {
  const words = (payload as { text: string }).text.split(/\s+/).length;
  return words >= (params?.min as number) || `fewer than ${params.min} words`;
});
```

A predicate that returns a string fails with that string as the recorded reason. A predicate that throws fails closed. An unregistered predicate name fails closed. Verification never passes by accident.

## The verdict

```json
{
  "id": "vrd_…",
  "escrowId": "esc_…",
  "deliveryId": "dlv_…",
  "passed": false,
  "results": [
    { "check": { "kind": "hash", "expected": "…" }, "passed": false,
      "detail": "content hash … != expected …" }
  ],
  "decidedAt": "2026-06-10T12:00:00.000Z"
}
```

Each check's outcome and reasoning is recorded in the evidence trail. A failed verdict does not end the matter: the payee may open a dispute, or the payer may take a refund. Either path still terminates in a quitanza.

## Limitations

Verification covers what can be checked mechanically. Checks judge the payload's content, size, timing, and shape, not its commercial quality. Where quality is contestable, the dispute funnel exists precisely because no verifier settles taste.
