Foreshock

Concepts

Verdicts, bands, and pools

Three verdicts, ordinal bands that are not scores, and why funds are routed into separate pools rather than one collection address.

Updated
2026-08-24

Three verdicts

POST /v1/decide/deposit returns exactly one of three values in verdict.

VerdictMeaning
CREDITThe deposit may be credited.
HOLDThe deposit must not be credited yet.
REJECTThe deposit must not be credited.

There is no fourth value, and no path returns CREDIT when any input was degraded, stale, unavailable, or over budget. Every degraded path resolves to HOLD.

A verdict only ever arrives in a 200 response. There is no verdict in a 4xx and no verdict in a 5xx.

Bands are not scores

Two ordinal bands appear in the API.

  • severity on an exposure match: R0 (lowest) through R2.
  • risk_level on a decision: R0 (lowest) through R4.

They are bands, not scores. Foreshock publishes no numeric risk score on any endpoint in any mode, and there is no debug or verbose mode that reveals one, because no internal score is ever placed in an outbound response body.

Third-party vendor scores are a separate matter. When a vendor produces one, it is returned in VendorResult.score exactly as the vendor produced it, on the vendor’s own scale, alongside vendor, verdict, categories, list_version, and a raw_ref to the snapshot. Scores from different vendors are on different scales and are not comparable. Foreshock does not convert between them: converting would manufacture precision that does not exist and would break the audit trail back to the vendor’s original judgement.

When vendors disagree, vendor_disagreement is true and both results are still there. The disagreement is reported, never reconciled into a single answer.

Reasons classify, they do not derive

reasons is an array of DecisionReason, each carrying a code, an optional severity band, an optional vendor, and an optional raw_ref. A reason states what class of finding applied. It does not state how the finding was made, and it never contains an enforcement target address or a score.

Reason codes split into two families: risk classifications, and degradations. Every degradation code yields HOLD with HTTP 200. The full enumeration is in the generated reference.

New codes may be introduced in a minor version. Treat an unrecognised code as at least as serious as the accompanying risk_level.

Pools

pool tells you where the funds should go: clean, tagged, or quarantine.

Keeping pools separate is what prevents differently classified funds from being swept into one collection address. A quarantine verdict that lands in the same hot wallet as everything else has achieved nothing — the classification survives only as long as the segregation does. QUARANTINE_ROUTE appears in required_actions when this matters.

Required actions and the deadline

required_actions lists the operational steps your workflow must complete before the deposit can leave HOLD — collecting source of funds, first-line or escalated review, routing to quarantine, notifying a compliance officer, opening a case, or re-deciding after a degradation clears.

sla_deadline is when those actions are due under the service levels you configured, or null when no deadline applies. It is your deadline, not ours.