Challenges and liability
Contest a finding with one mechanical evidence class, then follow an upheld verdict through seller liability to settlement.
On this page
When a sold finding proves defective, the seller's collateral pays for it, whether a buyer who paid or a venue auditing at random brings the challenge.
Each filing presents one mechanical evidence class to an evaluator bound to a pinned verifier profile. The evaluator signs one of three verdicts, and only upheld opens seller liability. Claims, an appeal window, and confirmed external effects stand between that verdict and any money moving.
Three verdicts carry three different consequences
A buyer challenging a repair gets a signed verdict on the evidence. A proven defect, a failed challenge, and an evidence check that cannot run each end differently.
One evidence class, three verdicts
A buyer files with a dispute fee, a dispute lock, and purchase standing; a venue audit files under the pinned audit authority with no fee or bond. Each filing presents one evidence class: digest-mismatch, evidence-invalid, or replay-contradiction. Upheld places a reversible HoldBond and blocks new purchases through a signed appeal window; rejected makes the buyer's dispute bond eligible for forfeiture; indeterminate carries no hold and no sanction. Challenges and liability.
chio.finding.v1 finding, from admission to retraction; challenge and retraction run only when a finding is disputed. The bid figures are the basic_discount vector in USD minor units; fee arithmetic, audit sampling, and the hosted profile are left out.The cognition marketupheld. The only verdict that may enter penalty processing. It carries a checked penalty calculation, places a reversibleHoldBond, and blocks new purchases through a signed appeal window. The ordinary verdict path refuses it withupheld verdicts require the atomic exposure fence.rejected. The challenge failed on its merits. This is the only state against which a dispute bond may be forfeited.indeterminate. The evaluation could not establish its inputs, an infrastructure or authority failure rather than an answer. It lands inindeterminate_retryableorindeterminate_closed, creates no hold, sanction, liability transition, audit reward, or forfeiture, and returns the challenger's bond.
FindingChallengeVerdict is class-independent: the class-specific facet that produced it is nested under the evidence branch of the signed outcome and must match the class tag. An upheld verdict means the presented mechanical class was established against the challenged finding under the pinned verifier profile. The digest_mismatch facet carries a transform profile of exactly identity and a zero realized spend, so a generic mismatch or an operator-policy transform denial never sanctions the seller.
Each filing names one authorization branch and one evidence class
chio finding challenge builds and signs the filing against a venue control plane. Filing needs a running venue control plane, an admitted listing, and a funded dispute lock; replace FINDING_ID with the admitted finding's identifier and YOUR_VENUE_HOST with your venue's control-plane host.
chio finding challenge \
--finding FINDING_ID \
--class replay-contradiction \
--evidence ./challenge-evidence.json \
--challenger-key ./challenger.seed \
--control-url "https://YOUR_VENUE_HOST"A buyer_submission posts the challenger key, which must equal the envelope signer, a settled dispute fee, a live exclusive dispute lock, class-specific standing, and at least one affected delivery. A venue_audit posts the audit-epoch, selection, and authorization digests under the venue's pinned audit authority, and has no member for a challenger, lock, fee, forfeiture, or reward. So --challenger-key is required for a buyer submission and refused for a venue audit.
Standing must agree with the evidence class. A denied reveal creates no purchase record, so its standing is the signed failed-delivery terminal and pairs only with digest_mismatch; a settled sale's standing is its purchase record and pairs with evidence_invalid or replay_contradiction. The closed guarantee and evidence compatibility matrix is checked against the fetched finding before anything is signed, so only an applicable class reaches the evaluator.
An upheld verdict closes against the collateral the evaluator signed
An upheld verdict takes a separate entrypoint that holds one transaction over the verdict and the seller's exposure.
penalty = min(live_allocated_collateral, computed_exposure)
computed_exposure = base + encumbrances
computed_exposure > signed listing requirement rejects, never clampsThe store re-reads the authoritative outstanding exposure for the seller's allocation, requires it to equal the evaluator-signed calculation, and raises the listing sales block in the same transaction. If a purchase reservation raced the evaluator's own read, the mismatch rolls back both the block and the verdict with allocation exposure changed before the upheld verdict; the challenge stays evaluating, and a retry can sign the refreshed calculation. Once the transaction commits, no reservation can change the exposure behind the terminal outcome.
The penalty amount follows from checked arithmetic over the signed figures, outside the evaluator's discretion. The upheld verdict then opens a liability head: one row per defect on one backed listing, carrying the finding, the listing, the seller allocation, and the vault it is charged against. A second corroborating challenge joins that head instead of opening a second slashable liability.
Read more in Pricing a finding, where the exposure cap is sized.
A liability head settles only after claims, appeal, and confirmed effects
The head's moves are a closed table enforced by a store trigger, and the row is permanent.
An upheld verdict opens one head and freezes the purchase cutoff
One head covers one defect on one backed listing, and a second corroborating challenge joins it. The transaction that records the upheld challenge freezes the purchase cutoff at the listing's high-water mark and raises the sales block; the claim deadline freezes with it. Liability states.
liability_heads_lifecycle trigger admits, with the condition each edge waits on. Governance case selection, effect intents, and the challenge states before the upheld verdict are left out.- Upheld. The compare-and-set that records the upheld challenge freezes the purchase cutoff at the listing's high-water mark and commits in one transaction with the sales block. The claim deadline freezes with the cutoff and is never rewritten.
- Claims. The next edge freezes the seller-signed appeal window from a verified nonzero duration and the digest of its terms envelope. The claim snapshot seals once, at exactly the frozen cutoff, and is refused before the claim deadline passes.
- Appeal. A successful appeal closes the head without settlement: nothing was impaired, the seller is exonerated, and the listing's sales block lifts in the same transaction unless another live liability still holds it.
- Settle. Finalizing holds only while the named sanction is still the exact live case. The head settles only with exactly one settlement-required seller impairment, one anchored root intent, and one retraction, all confirmed; a quarantined head cannot settle.
Every edge is a compare-and-set in which the caller names the only legal source state, so no caller skips a state by naming a later one, and every edge is idempotent once the head sits at its target, which makes the process resumable after a crash. A retraction dispatches only after exactly one confirmed, reconciled seller impairment; a verdict alone moves no funds.
Every external effect passes a durable fence before dispatch
An effect intent records the semantic key of an external effect and a canonical commitment digest to what it does, before anything is dispatched for it. The store records transitions, exclusive locks, and durable records; calling services check signatures, adjudicate evidence, and authorize penalties.
- Kinds.
seller_impair,root_intent, andretractioncarry the settlement;challenge_bondandfeeappear when the operator collected a buyer dispute bond or filing fee. Each kind is keyed by its own domain-separated preimage. - States. An intent moves through
pending,dispatched,confirmed,failed, andquarantined. A failed intent may be dispatched again;confirmedandquarantinedare terminal. - Replays. An identical retry reconciles to the same row and reports that it replayed, so a resumed worker never fences an effect twice, while a different commitment under a durable key rejects. Store writes report
InsertedorExistingSame.
Quarantine is the fail-closed terminal for an effect whose transaction matched its intent but whose post-dispatch chain observation no longer matches the signed snapshot. A quarantined head keeps its state and keeps purchases blocked until a reobservation validates against the retained reconciliation evidence. A commit whose outcome cannot be observed surfaces as outcome-unknown and poisons the serving owner instead of reporting a result.
Challenge records, states, and refusals
Search for venue_audit, indeterminate_retryable, quarantined, or claim window.
Authorization branches
FindingChallengeAuthorization is a closed union with deny_unknown_fields, so a member belonging to the other branch is rejected at parse time. The store keeps the same discipline in SQL: a challenger is present exactly when the branch is a buyer submission, written as an equality between the two facts.
| Branch | Must post | Cannot carry |
|---|---|---|
buyer_ | The challenger key, equal to the envelope signer; a settled dispute-fee terminal payable to the admission- dispute lock; class-specific standing; at least one affected delivery. | Any audit member. The audit epoch, selection, and authorization digests have no encoding on this branch. |
venue_audit | The signed audit-epoch envelope digest, the selection digest, and the authorization digest, signed by the venue's pinned audit authority. | A challenger, a lock, a fee, a forfeiture, or a reward. A venue audit cannot acquire a bond disposition, and a buyer cannot borrow the audit authorization. |
Standing names the same digest the evidence branch binds: failed_delivery standing pairs only with digest_mismatch, and finalized_purchase only with evidence_invalid or replay_contradiction. The bond class is closed at one member. A lock held under the publication or listing class rejects at parse time, and the store pins bond_class to dispute as a column constraint, so a caller cannot present a listing bond as a challenge bond.
Filing input
The command takes the finding id, the mechanical class, and an evidence document. It fetches the venue's stored artifact verbatim, re-derives it through the strict ingress, and binds its exact digest into the challenge. The evidence document is strict canonical I-JSON: the file bytes must be exactly their own canonical serialization, every field is required, and every key at every depth is in canonical order.
The document carries only the operator-supplied half; the fetched artifact supplies schema, challenge_id, finding_id, and finding_artifact_sha256. --dry-run emits the canonical challenge, the signed envelope when one was produced, and their digests without transmitting anything. Without a venue control plane the command refuses with finding surfaces require --control-url pointing at the venue control plane.
Evidence classes and compatibility
Each branch of FindingChallengeEvidence carries exactly the references its class needs. The compatibility matrix is closed and normative, and it is checked before evaluation.
| Class | What the filing must show | Admitted against |
|---|---|---|
digest_mismatch | The signed failed-delivery envelope digest, plus the deny receipt and deny checkpoint references. | Any guarantee and evidence class, because its standing is the signed failed-delivery terminal. |
evidence_ | The contested receipt subset, non-empty, bounded, and free of duplicate receipt ids; the challenged checkpoint reference; the finalized purchase-record envelope digest. | An observed or verified evidence class. An asserted finding is refused. |
replay_ | An ordered, size-bounded reproduction set of {receipt_ref, checkpoint_ref, observation_ tuples sharing one replay_run_id; the strict canonical recipe preimage; the purchase-record envelope digest. Every observation commits the recipe preimage digest and the named verifier profile. | A deterministic_ guarantee class with a verified evidence class. Every other pairing is refused. |
The carried preimages are strict-parsed and cross-bound to the profile the challenge names, so a reproduction set belonging to another recipe or profile cannot ride along. Loose identifiers, a single checkpoint standing in for unrelated receipts, non-canonical preimages, and digest mismatches all reject before evaluation.
Challenge states
A challenge row moves through a closed set of states, three live and three terminal. A SQL trigger enumerates every admissible pair and aborts an update outside it with invalid finding challenge lifecycle, a second trigger makes a terminal row immutable, and a third refuses deletes.
| Current state | Permitted next states |
|---|---|
submitted |
|
evaluating |
|
upheld | Terminal: no outgoing transition. |
rejected | Terminal: no outgoing transition. |
indeterminate_ |
|
indeterminate_ | Terminal: no outgoing transition. |
begin_evaluation is the only way into evaluating. A submitted challenge starts its first evaluation. A retryable one starts its retry only inside its signed window; past that deadline the store closes it indeterminate, so a lapsed window never produces a verdict. A challenge already evaluating is left alone, and any other state is refused with challenge cannot enter evaluation from state naming the state.
A verdict is a compare-and-set against state = 'evaluating'. Every verdict transition retains the exact signed outcome envelope in the same transaction, under a digest that is a dedup key: the same digest bound to different bytes or a different challenge is refused. The two edges out of submitted that skip evaluation close a buyer filing whose bond was recovered only after its signed expiry, or an unstarted filing whose fee was returned because the paired bond never reached confirmed funding. Once an adjudication has started, only its signed outcome may close it. Source: finding challenge store lifecycle triggers.
Indeterminate outcomes and retry
The retry bound is a constant: a challenge is entitled to exactly one further evaluation inside its signed window. The store grants the retry only when the verdict carries a deadline still in the future and the retry is unspent; every other indeterminate result, and the next indeterminate verdict, closes the challenge. A larger bound would let an unavailable dependency hold a bond indefinitely.
The evaluator derives the absolute deadline from the challenge-bound seller terms, caps it at the terms expiry and at the buyer's signed dispute-lock expiry when one is present, and includes it before deriving the outcome id and signing. It must be strictly later than the evaluation time, and a terminal verdict, an exhausted retry, or a closed policy window omits it. A late retry closes at begin_evaluation, a trigger advances the retry counter by at most one per update, and a schema constraint ties a retry deadline to a granted retry.
Dispute bond
A buyer submission stakes collateral on its filing; a venue audit posts no bond and is refused by the bond-lock operation. A reservation records the lock identity before external funding is dispatched, permanent and idempotent for the same challenge and terms; reusing the lock id or challenge id with different terms rejects before value can move. The confirmed lock is exclusive per challenge, pinned to the dispute class, and owned by the challenger the challenge names.
Funding and return are keyed under separate domain-separated preimages, chio.finding.dispute-bond-funding.v1 and chio.finding.dispute-bond-return.v1, so confirming the debit can never satisfy the credit fence. Both keys bind the challenge and the lock together, so one funded lock cannot be claimed by another filing.
Bond return and forfeiture
A lock is disposed exactly once, from locked only, and only after its challenge closes; an attempt before then is refused with a dispute bond is disposed only once its challenge closes.
| Disposition | Available when | Also required |
|---|---|---|
returned | The challenge reached any terminal state, including upheld and indeterminate. | An independently confirmed return intent under the return domain, matching the lock's commitment digest; otherwise dispute bond has no independently confirmed return intent. |
forfeited | The challenge is rejected. Any other state is refused with a dispute bond cannot be forfeited against a challenge in state naming the state. | Nothing further. |
The store refuses a forfeiture that is not against a rejected challenge and a return without a confirmed return intent, and within those bounds records what the calling service requests. The signed evaluator outcome, checked against the pinned evaluator authority, is what makes forfeiture available.
Liability state transitions
| Current state | Permitted next states |
|---|---|
open |
|
upheld_ |
|
pending_appeal |
|
finalizing |
|
reversed_ | Terminal: no outgoing transition. |
settled | Terminal: no outgoing transition. |
Each edge is a compare-and-set whose named source state must be the only legal source of the requested edge, and each edge is idempotent once the head sits at the target.
Purchase cutoff and sales block
The store shares one connection and one serving-owner fence with the purchase store, so no slot opens between the upheld compare-and-set and the sales block, and the frozen cutoff is exactly the listing's high-water mark. A cutoff below that mark is refused, because buyers who paid before the block would sit above the claim line. A replay derives its own deadline from its own clock and that value is ignored, so a retry cannot shorten the window it resumes. Only an upheld challenge on this liability's own finding and listing may carry it.
Appeal deadline and claim snapshot
The caller supplies an already verified signed appeal duration, which must be nonzero, and the digest of the terms envelope that carried it; the store derives the absolute deadline from the trusted transition clock. A replay presents the same duration and envelope digest and never recomputes the deadline from a later clock.
The claim snapshot is written once, only while the head is in upheld_pending_claims or pending_appeal, and seals exactly the cutoff the upheld transaction froze. A seal before the frozen claim deadline is refused with claim window has not closed for this liability, because an immutable early snapshot would permanently drop every claim the window still had time to admit.
Governance case selection
Sanction and appeal cases are the two governance case kinds that target a liability, and the index records supersession in the same transaction that records the case. Resolving the case head means finding the single live case no other case supersedes. Two live cases on one defect fail closed: the store names no head, and the error names both cases, has two live governance cases ... no case head can be resolved. The finalizing edge holds only while the named sanction is still the exact live case and shares one transaction with appeal recording, so neither ordering strands a successful appeal behind a finalizing head.
Successful appeal
The reversal reaches the sale path in the same immediate transaction: the sales block lifts alongside the compare-and-set, so no restart observes a cleared head on a barred listing. It is the one transition that lifts a block, the mirror of the upheld transaction. One listing carries one block however many heads reached it, so only the last holder's exoneration releases it.
Effect intent kinds
| Kind | Operation | Confirmation or dispatch rule |
|---|---|---|
seller_impair | The impairment of the seller's allocation. | A settlement- |
root_intent | Publication of the enforcement root. | Bind the anchor proof before dispatch. Confirmation must match the exact bound root and evidence hash. |
retraction | Propagation of finding status. | Dispatch requires exactly one confirmed, reconciled seller impairment and a liability that is not quarantined. |
challenge_bond | The dispute bond's funding and return legs. | Present only when the operator collected a buyer dispute bond. |
fee | The filing fee's collection and return legs. | Present only when the operator collected the filing fee. |
Entering dispatched counts one attempt, and a trigger holds the attempt counter to advancing by at most one. A quarantined intent is never dispatched again.
Quarantine and reobservation
Confirming the intent and publishing it without the quarantine would open a window in which another finalizer could settle the liability from stale state, so the confirmation and the quarantine commit in the same write transaction. A quarantined head refuses settlement with a quarantined liability cannot settle. Clearing it validates the current observation against the exact reconciliation evidence retained with the confirmed impairment and clears the flag in the same write transaction; a mismatched reobservation leaves the liability quarantined.
Settlement requirements
The final edge and its gate share one immediate transaction. The head must carry exactly one settlement-required seller impairment, exactly one root intent with an anchor binding, and exactly one retraction; anything else is refused with liability does not carry the required finalization effect set. A required effect in any state other than confirmed is refused with liability still has unconfirmed required effects. Only then does the head settle and clear its pending publication.
Idempotent writes and recovery
Store APIs returning FindingChallengeWriteOutcome use a natural key and report Inserted when they applied the change and ExistingSame when the durable row already carried it. Write identity is the semantic content of the request; the trusted times a caller supplies are outside it, so a retry from a later clock replays. A replay carrying conflicting parameters rejects. Writes run under an immediate transaction behind the serving-owner fence.
Signed artifacts and verification
Each artifact is an envelope of {body, signerKey, signature}, and each registered schema requires all three members and rejects unknown members in the body. The profile, the challenge, the outcome, and the enforcement verify against an externally pinned authority key; the envelope's own embedded key is never sufficient for a value-moving decision. Envelope digests referenced by other artifacts cover the canonical JSON of the complete envelope.
| Registry id | Title | Role in the dispute |
|---|---|---|
chio. | Chio Finding Challenge- | The trust profile a challenge names and the evaluator runs under. |
chio. | Chio Finding Challenge (signed envelope) | The filing: one authorization branch, one evidence class, one affected- |
chio. | Chio Finding Challenge Outcome (signed envelope) | The evaluator- |
chio. | Chio Finding Liability | The money-bearing head one defect opens on one backed listing. |
chio. | Chio Finding Claim Allocation | The deterministic split of the slashed collateral across harmed purchases. |
chio. | Chio Finding Challenge Enforcement (signed envelope) | The finalization authority's instruction to impair one seller allocation. |
The outcome id derives from a domain-separated preimage over the whole canonical body with only the id member emptied, and the envelope signature lives outside the body, so penalty processing binds its reference id to the outcome id and its digest to the signed envelope digest as two independent facts. The durable outcome-envelope digest pins the evaluator policy at adjudication: later liability and appeal processing checks the exact pinned envelope under that adjudication-time key and a fresh signed status reading covering the evaluation time, so rotating the current evaluator key leaves an authentic recorded outcome valid.
Errors and recovery
Store refusal messages or their exact prefixes, with the entry that defines the gate and the state retained after refusal.
| Message | Cause | Next check |
|---|---|---|
challenge cannot enter evaluation from state | The current challenge state cannot begin an evaluation. | |
allocation exposure changed before the upheld verdict | Outstanding exposure changed after the evaluator signed its calculation. | |
dispute bond has no independently confirmed return intent | The matching return intent is unconfirmed. | |
claim window has not closed for this liability | The caller tried to seal claims before the frozen deadline. | |
a quarantined liability cannot settle | Reconciliation has not cleared the liability's quarantine. | |
liability does not carry the required finalization effect set | The required seller impairment, root intent, or retraction is missing or duplicated. | |
liability still has unconfirmed required effects | At least one required effect is unconfirmed. |
Normative sources
The lane follows the registered v1 finding schemas and the SQLite challenge store.
spec/schemas/chio-finding/v1/defines the closed signed schemas.crates/platform/chio-store-sqlite/src/finding_challenge_store.sqldefines the allowed state transitions and immutable rows.crates/platform/chio-store-sqlite/src/finding_challenge_store.rsimplements the transaction, bond, appeal, and effect checks.crates/economy/chio-finding/src/challenge.rsandcrates/trust/chio-finding-challenge/src/evaluate.rsdefine the filing and the evaluator.