EXP-01---- traces committed---- incidents---- reproducibility---- bondedSolana mainnet
KORTX

EXP-01 / Bonded challenges

Incidents

A challenge here is not an opinion. To open one you lock a bond. Several bonded verifiers then re-run the inference independently, and each seals its answer behind a commitment before any of them is allowed to reveal it -- so no verifier can save itself the work by copying another one's answer. That seal has a limit, and it is set out below rather than left for you to find: it does not stop a verifier copying the output hash the provider already published, and what covers that gap is a trap rather than a proof. The reveals are weighed by the stake behind them, not counted by head, and once enough re-runs and enough stake are in, one of the two bonds pays. Short of that the challenge is void and both bonds go home.

Whether a re-run counts as reproducing the original is not always byte-for-byte equality. It is the reproduction rule the provider registered the model under, which is on the plate and was declared before the model served anything. Both of those -- the sealed re-run and the declared tolerance -- are set out below, because a challenge procedure that leaves either one out describes a system that would not work.

Network totals

Challenges recorded

0

Every incident account the indexer has read.

Open

0

Bond locked, still waiting on a rerun or a ruling.

Upheld

0

The rerun disagreed with the committed output.

Bond in open challenges

0KORTX

Challenger money currently at risk, not fees collected.

A committed track crossing the vessel with a second, orange track diverging from it after the rerun

What a challenge does

It rewinds the track and runs it again. The white line is what was committed. The orange one is what the rerun produced, and the point where they part is the whole finding.

Procedure

  1. 01

    Commit

    commit_trace

    The provider writes the input hash, the output hash, the model fingerprint and the sampling seed before anyone has asked a question about them.

  2. 02

    Bond a challenge

    open_incident

    Anyone may dispute a trace, but not for free. The challenger locks a bond -- plus an open fee when fees are on, returned only if the challenge is upheld -- and the account records both deadlines and the number of independent re-runs this plate has to gather before a verdict counts.

  3. 03

    Seal a re-run

    submit_reruncommit

    Each bonded verifier runs the input against the plate and posts only a commitment -- a hash of the answer, salted and bound to that verifier and that incident. Nothing readable is on chain yet.

  4. 04

    Reveal and judge

    submit_rerunreveal

    Once the commit window shuts, verifiers publish the output hash, the salt and the divergence they measured. The program recomputes the commitment, rejects any reveal that does not match it, and only then rules each re-run matched or not.

  5. 05

    Tally and settle

    resolve_incident

    The revealed verdicts are weighed by stake -- each counts for its verifier's bond at the moment it revealed -- and the side with more stake behind it decides. The money moves in one transaction: the losing side's bonds, the challenger's stake, the burn and the verifiers' reward all settle together.

Why sealed first

Reading an account is free. Running a model is not. If the first verifier posted its answer in the clear, the cheapest thing every other verifier could do is copy it -- and then a quorum of ten is worth exactly as much as a quorum of one, because nine of them re-ran nothing. The commitment takes that answer off the table. Salting it and binding the verifier key and the incident key into the pre-image is what stops a commitment being replayed by somebody else or against a different challenge. It does not take the provider's own published hash off the table -- that is a different problem with a different answer, and it is set out directly below this diagram.

Why a window between them

Reveals cannot begin until the commit window has closed. Without that gap a late verifier could read an early reveal, commit to the same answer and reveal it a moment later, which is the copying problem again with one extra step.

Stages 03 and 04

Both carry the instruction name submit_rerun. It takes a two-variant payload rather than being split into two instructions, so the commitment and the reveal write to the same record and the program can check one against the other without trusting the caller to pair them up.

What sealing does not stop

Decoy incidents / off chain

The commitment in stage 03 is worth exactly what it removes, and it does not remove everything. Read on its own it invites the conclusion that a re-run cannot be faked, and that conclusion is false. Three statements are true at once, and the first is only honest in the company of the other two.

What the seal stops

Verifiers copying each other.

No re-run is readable until the commit window has shut, so the second verifier cannot save itself the work by reading the first one's answer. The commitment is salted and the verifier key and the incident are bound into the pre-image, so a commitment cannot be lifted from one verifier and posted by another, or carried over from one challenge to the next. Within the set of verifiers, this holds.

What it does not stop

A verifier copying the provider.

The committed output hash is public on the Trace account from the moment the trace is written. A verifier that never loads the model can read that hash, salt it, commit to it and reveal it, and what it produces is a formally perfect commitment and a formally perfect reveal that the program will validate. There is no cryptographic fix for this. You cannot force somebody to perform a computation whose answer is already published, and nothing on this page is going to pretend otherwise.

What catches that instead

Decoy incidents.

A decoy is a challenge against a canary trace whose committed output hash has been deterministically corrupted, so the published answer is known to be wrong. A verifier that actually re-runs the model disagrees with it and reports a mismatch. A verifier that echoes the published hash reports a match, and that is not a difference of opinion -- it is direct evidence that no inference was performed. The corruption is keyed, so a verifier cannot recompute it and pick the decoys out of the chain data. What makes laziness expensive here is a trap it has to pay for, not a proof it cannot forge.

Where this runs

A decoy is opened with the ordinary open_incident instruction against an ordinary trace, and the chain has no idea it is one -- that is the point of it. The corruption, the scoring of reveals against the known-wrong answer and the accumulation of strikes all happen in the incident engine, off chain. The deployed program contains no decoy instruction and no laziness penalty.

What decoys do not cover

Only under an exact policy

The field a decoy corrupts is the output hash. Under TokenPrefix, LogitBand or Semantic the comparison reads a field the decoy never touched, so it comes back indeterminate and no strike is recorded. Emitting one there would punish honest verifiers, which is a worse failure than missing a lazy one.

Only while the canary pool rotates

Decoys work because they are indistinguishable from real challenges. With one canary plate, verifiers learn to recognise it and answer that one honestly, and the mechanism stops measuring anything. A large, rotating pool is a condition of the method, not a detail of its deployment.

One strike is not evidence

A single divergence can come from a bad build, a truncated download or a misconfigured backend. Strikes are accumulated over a sliding window and a penalty is only proposed once a threshold of them falls inside it. The window, the threshold and the share of bond at stake are engine parameters, and they are named here rather than numbered because this page does not read them.

It proposes; it does not execute

The detector returns a penalty proposal carrying the strikes that produced it, so the decision can be audited against the same evidence. Acting on it is a separate step. No instruction in the deployed program slashes a verifier for laziness, and nothing above should be read as saying the chain does this on its own.

What counts as a match

A re-run is not always required to reproduce the committed output byte for byte. Accelerator kernels reduce in non-deterministic order, so two runs of the same weights on the same prompt can differ in the last bits of a logit and then part company at the first near-tie token. Demanding bitwise equality of every provider would not catch cheats -- it would slash honest ones, and the honest ones are the only participants who would leave.

So a plate declares, at registration and before it has served anything, which rule it agrees to be judged under. That declaration is on the plate, it is public, and it cannot be changed for a trace after the fact.

Match policyJudged byDivergence allowedQuorum floor
BitwiseThe programNone

The raw output bytes hash identically or they do not. A plate on this policy cannot declare any tolerance at all.

Protocol floor, at least 3
CanonicalTextThe programNone

The output is normalised -- unicode NFC, trailing whitespace stripped -- and then hashed. The canonical form is what the trace committed to.

Protocol floor, at least 3
TokenPrefixVerifier quorumShare of the token stream allowed to diverge

Only a prefix of the stream has to match. How much of it may drift is the plate's declared tolerance.

3 re-runs
LogitBandVerifier quorumLogit gap on the top-1 token

The same token has to win at each step, and the margin it won by has to sit inside the declared band.

3 re-runs
SemanticVerifier quorumEmbedding distance from the committed output

The loosest policy on the instrument, and the one whose result depends most on who measured it.

3 re-runs

Where the divergence figure comes from

A verifier reports it as part of its reveal. On the two exact policies it is required to be zero and the chain decides the outcome from the hashes alone. On the three tolerant ones the chain cannot re-measure it, so it accepts the number the verifier gave and rules the re-run matched when it sits inside the plate's declared tolerance.

What that costs in trust

A tolerant verdict is a measurement the program took on trust. That is exactly why those three policies cannot settle on fewer than three independent re-runs: the floor is a substitute for a check the chain is not able to perform. A result on a tolerant plate is weaker evidence than a result on an exact one, and this page is not going to print them as if they were the same finding.

How the bonds settle

resolve_incident

A ruling is weighed across independent re-runs by the stake behind each one, not one verifier's finding and not a head count. Every step below happens inside a single call that anyone may crank -- there is no privileged resolver, and no moment where somebody reads the comparison and then decides what to do about it.

Reaching the verdict

  • Quorum is set when the challenge opens

    It is the higher of the protocol floor and the floor the plate declared for itself. A provider may demand more scrutiny than the network requires; it can never accept less.

  • Too few reveals, or too little stake, voids the challenge

    A verdict needs revealed re-runs at or above the quorum (at least 3) and total revealed stake at or above the stake threshold the incident opened with. Short of either, nobody is judged: the challenger's bond comes back, an open fee (if one was charged) is forfeited, and the provider is not slashed. A challenger is not punished for the verifier network failing to turn up, and where a stake threshold is set, a handful of thinly bonded wallets cannot carry a ruling on their own.

  • Stake decides, not head count

    Each revealed re-run counts for its verifier's bond, snapshotted at the moment it revealed. More mismatch stake than match stake upholds the challenge. Anything else rejects it, so a tie goes to the provider. Bonding more after revealing changes nothing.

  • Some re-run slots are reserved

    Of the seven re-run slots on an incident, a number set on the config account is reserved for curated verifiers; everyone else shares the rest, and the split is fixed when the challenge opens. Curated verifiers can take any slot. A swarm of new wallets cannot fill every slot before the curated set arrives.

  • Committing and never revealing is a loss

    Withholding a reveal is not neutral -- it is the cheap way to stall a verdict, so it costs the same as being wrong.

Moving the money

  • The losing verifiers pay

    Every re-run on the losing side forfeits a share of that verifier's bond into a minority pool. Being on the wrong side is not free, which is what makes the stake behind a vote mean something.

  • The pool depends on the ruling

    Upheld, it is the provider's slashed plate bond plus the minority pool. Rejected, it is the challenger's forfeited bond plus the minority pool. Void, it is the minority pool alone.

  • A share of the pool is burned

    Burned as in destroyed: the tokens leave the vault and the supply falls by that amount. The remainder that will not divide exactly among the winners is burned as well, so the vault matches what the accounts claim rather than accumulating dust nobody has a record of.

  • The rest pays the verifiers who did the work

    After the burn, and after the challenger's cut on an upheld ruling, what is left is split between the re-runs on the winning side in proportion to their stake: each receives the verifier cut times its weight, divided by the total winning stake. Splitting a bond across wallets earns nothing extra. A rejected or void challenge has no challenger cut, so their share goes to the verifiers too.

  • The open fee follows the ruling

    When fees are on, opening a challenge escrows an open fee on top of the bond. Upheld returns it with the bond. Rejected or void forfeits it into the fee split -- verifiers, the burn and the treasury, in the proportions on the config account. With fees off there is no open fee at all.

  • At most seven re-runs settle at once

    Every rerun record opened against a challenge has to be supplied to the ruling, in one transaction, so that no state exists where half the verifiers have been paid. The transaction size limit is what caps the number.

The proportions are deliberately absent. How much of a plate bond a slash takes, how much of the pool is burned, what the challenger's cut is, how many re-runs the protocol floor demands and how much revealed stake an incident needs are all fields on the program config account. This page does not read that account, so it names those parameters and does not put figures on them.

Challenges

Nothing recorded

No challenge has been opened against any committed trace.

An empty log is not a clean record. It can also mean nobody has paid to look.