Skip to content
Warrantv0.1

Write your first policy

Three bands, one floor, and a reason code that overrides all of them.

A policy is bands read from the top score down, plus reason codes that win regardless — and it must have a band at minScore: 0 or it will be rejected.

{
  "bands": [
    { "minScore": 1, "outcome": "release", "label": "clean pass" },
    { "minScore": 0.8, "outcome": "partial_release", "releasedBps": 5000 },
    { "minScore": 0, "outcome": "escalate", "label": "anything else" }
  ],
  "alwaysRefund": ["source_not_found"]
}

Start from the default

Every organisation without its own policy gets this, and it is the strictest sensible rule:

{
  "bands": [
    { "minScore": 1, "outcome": "release", "label": "clean pass" },
    { "minScore": 0, "outcome": "escalate", "label": "anything else" }
  ]
}

Only a clean pass pays. Everything else waits for a person. If you are unsure what you want, this is the right thing to be unsure with — it never pays for something nobody checked.

Add a middle band when the queue gets loud

The default sends every imperfect result to a human. Once you can see which imperfections are routine, give them an outcome:

{
  "bands": [
    { "minScore": 1, "outcome": "release", "label": "clean pass" },
    { "minScore": 0.8, "outcome": "partial_release", "releasedBps": 5000, "label": "mostly there" },
    { "minScore": 0, "outcome": "escalate", "label": "anything else" }
  ]
}

Bands sort by minScore descending and the first one the score reaches wins. A score of 0.9 hits the middle band and pays half.

The floor band is mandatory

Leave out minScore: 0 and the policy is rejected at write time with policy_no_floor_band. A low score would otherwise match nothing, and a policy that can decline to decide would leave funds held indefinitely.

Reason codes beat the score

{
  "alwaysRefund": ["source_not_found"],
  "alwaysEscalate": ["source_unreachable"]
}

alwaysRefund is checked first, then alwaysEscalate, then the bands.

The ordering matters. "The source did not exist" is not a quality judgement, and a band should not be allowed to pay 50% on it because two of four clauses happened to pass. A reason code says what went wrong; a score says how much went right.

source_unreachable is the usual candidate for alwaysEscalate: the check could not be completed, so both paying and refusing would be deciding on evidence that does not exist.

Two scales in one object

FieldScale
minScoreFraction, 0 to 1
releasedBpsBasis points, 0 to 10000

0.8 and 5000 in the same band are not a typo. minScore is compared against the engine's score, which is a fraction; releasedBps is a share of an amount. The field names are the only thing telling them apart.

releasedBps must be strictly between 0 and 10000 — zero is a refund and 10000 is a release, so neither needs a partial band.

Cap the size

{ "maxAmount": "50000000" }

50.00 USDC, as an integer string of the smallest unit, ^[0-9]+$. A warrant above it is refused at open.

"50000000"   50.00 USDC
50000000     rejected — a JSON number
"50.00"      rejected — not the smallest unit

Versions, not edits

A policy is never edited in place. New rules create a new version, and a warrant pins the version it ran under, with the rules_hash recorded on the trace. A settlement from March can be re-read against exactly the rules that produced it.

Policies are written in the console — there is no POST /v1/policies. See the API reference.