Artifacts
The network carries exactly two kinds of artifact: patches and claims. Everything else on the ledger — seals, reveals, rounds, verdicts, settlements — is a claim, a reference to one, or a protocol record the system produces. This document specifies what each artifact carries, how it is bounded, and how it is signed. The schema is a build artifact; this names what it must contain.
The two artifact types
| Artifact | What it is | Checked by |
|---|---|---|
| Patch | A unified diff against a stated revision | Tier 1: applies, typechecks, corresponds |
| Claim | A short structured record: code path, version range, trace, stated assumptions, impact statement | Tier 1: path exists, trace verified, schema and caps |
That is the complete wire format, at every round and in every direction. No reproducers, test cases, proof-of-concept programs, fuzzing corpora, scripts, or binaries, not as a finding and not as a supporting attachment. A counter-refutation escalates with a patch or a trace, never a program. This is what keeps the no-execution rule true under pressure.
Rejected: accepting reproducers without running them. The network would still store and distribute attacker-authored programs, still tempt a future operator to "just run it in a sandbox to check", and still hand every agent a payload delivery channel. Refusing the artifact type is the only version of the rule that survives.
The claim record
| Field | Content | Bound | Scored? |
|---|---|---|---|
| Target | Package, ecosystem, and the version range or revisions claimed affected | — | Reach is measured from it |
| Code path | The exact path named, entry point to sink, in the project's source at the stated versions | — | Must exist |
| Trace | The call-graph and data-flow path reaching the sink; see Traces | Bounded node count | Yes; severity is computed from it |
| Stated assumptions | Structural: root class, the auth checks crossed, sink class, each assumed edge with its named callee | Part of the trace | Yes; they are the refutation targets |
| Impact statement | What an attacker gains | ~500 characters | No. Documentation for the humans who carry the finding upstream |
| Rationale | Why the claimant believes the path is real | ~500 characters | No |
| Attestation | Found by the submitting identity: a non-scoring flag shown on the record, so that laundered prior art is a false statement rather than a silence | Boolean | No |
| Kind and reference | Which contribution this is, and which finding it attaches to | — | — |
No free-text field ever reaches a component that could be steered by it: severity is computed from the trace, price from the assessor's ordinal and computed inputs, and the adjudicator reads source, patches, traces, and transcripts.
Per kind: a finding adds a patch, and its trace must start where the attacker starts. A refutation names its target and the assumption or trace property it attacks. A validation states what it moves: a version boundary, an environment, a precondition, or a trace extension. A corroboration is an independent claim of its own, with a seal reference if sealed before the finding. A simplification is a patch tied to the same finding. A notice carries no claim at all: the finding reference, a channel, and a delivered content hash. The network writes it when it delivers; an operator may write one only for a project the network cannot reach, and then it is a URL, checked by fetching it.
Patches
A unified diff against a stated revision, checked as described under tier 1; the check that carries the most weight is correspondence.
A patch may not modify build configuration. The typecheck runs against a dependency cache fetched from the unpatched revision with the network off, so a patch that touches go.mod, go.sum, build tags, or their equivalents in another ecosystem fails tier 1 by construction; stating it as a rule is cleaner than leaving it as a side effect, and it closes the door on a patch that introduces a dependency or reaches the network.
A patch that is only correct as a unit may be submitted as a small, capped number of ordered parts, each under the cap. Correspondence and typechecking run on the composed result applied in order, so the unit survives and volume stays bounded by parts times cap.
Traces
An ordered path of call-graph and data-flow edges from an entry point to a sink, with a bounded node count: a reachability path, not a call-graph dump. It carries the properties severity is computed from.
| Edge | Meaning | What tier 1 verifies |
|---|---|---|
| Resolved | The callee is statically determined | The edge exists in the call graph and the stated data flow holds |
| Assumed | The claimant names the callee across a dynamic call, reflection, or FFI | Only that the named target exists and is signature-compatible |
A trace with assumed edges is still E2, with its assumptions stated as structure. Three rules follow, each an instance of unverifiable defaults low: assumed edges are priced, each is a refutation target by name, and a finding that relies on one vests only at E3.
Rejected: assumptions stated in prose. Not checkable and not attackable by name.
Seals
A commitment hash of a conclusion — the claim record the sealer would post — together with a stake. Opaque until revealed: no scope, no target. The commitment is SHA-256(canonical claim || nonce) with a 32-byte random nonce revealed with the claim: hiding by the nonce, binding by the hash. Everything else about seals is in corroboration.md.
Signatures and sequencing
- Every artifact is signed by the identity that produced it and broadcast with attribution. The suite is RFC 8785 canonical JSON restricted to integers, SHA-256 for every hash, and Ed25519 for every key and signature. An author signs the kind, its own key, the payload hash, and the versions it built under; the sequencer then assigns the sequence number and the previous hash and signs the entry hash, which is what chains the ledger. The author's signature cannot cover the previous hash, because the author does not know it until the entry is sequenced.
- Every artifact is sequenced on the append-only ledger. Ledger order settles races, decides whether a seal is prior, and is the only timestamp the protocol trusts.
- Every tier verdict is signed with a transcript naming the tier's version and exact inputs. Tier-1 results are signed by the separate signer; adjudicator verdicts by an adjudicator identity, with the reasoning trace and inputs seen.
- Nothing is erased. A reversed result, a retired version, or a superseded patch stays on the ledger with its history.
Size caps
| Artifact | Cap | Rationale |
|---|---|---|
| Patch | ~64 KB / ~1,000 changed lines, measured in tokens | A fix that needs more is a refactor and cannot be reviewed as a unit |
| Patch parts | A small fixed count | Lets a unit-correct fix survive the cap with volume still bounded |
| Claim record | ~4 KB total | A structured record, not an essay |
| Free-text field | ~500 characters each | Summaries; free text is the injection surface, so it stays character-capped |
| Trace | Bounded node count | A reachability path, not a call-graph dump |
All values are provisional. The patch cap is measured on the same canonical token stream the tier-2 metric uses, so it is largely language-neutral and one normalisation serves both. Numbers come from the token-size distribution of historical CVE fixes, set at a high percentile, starting tight. Raising a cap later is a security change and is versioned as one.
The caps do more than bound storage:
- They shrink the injection surface reaching the assessor and adjudicator.
- They keep adjudication reproducible and cheap by bounding context.
- They stop artifact-stuffing as a strategy.
- They force precision, since a claim that cannot be stated in 4 KB against a named code path is usually not specific enough to score.
Anything that needs more room belongs in the dispute record as successive bounded assertions, each staked.
Rejected: caps in bytes or lines (language-dependent; a second normalisation); exceptions for large fixes (a fix over the cap cannot be reviewed as a unit; ordered parts preserve the unit without lifting the bound).
Contribution kinds
Every contribution is a signed assertion attached to a finding. What is scored is the artifact, not the description of it.
| Kind | Scored output | Checked by | Pays by |
|---|---|---|---|
| Finding | A code-path claim and the patch that closes it, together | Tier 1 | Minted award, split into a finding portion and a patch portion |
| Corroboration | An independent conclusion, sealed and stake-backed; a prior seal if it precedes the finding | Tier 1 and the seal | Minted convergence award |
| Validation | A claim extending the finding's reach or precision | Tier 1 | Minted, scaled by what it moves |
| Simplification | A patch superseding the accepted one: simpler, or correct where it was not | Tier 1 and the metric | Transfer of a share of the superseded patch portion |
| Refutation | A negative claim against the finding, the patch, or the severity | Tier 1 where decidable, else the adjudicator | Transfer of the claimant's posted stake; the award is reversed |
| Notice | Not a contribution. The network delivers notice itself and records it; an operator posts one only where the network has no channel | Tier 1, by fetching it | Nothing. A record, not an assertion |
A finding includes its patch. There is no standalone fix contribution, because an unpatched claim is not a finding. Producing a patch that applies, typechecks, and corresponds is real work, and the work that makes a finding useful downstream; it removes the coordination problem of orphaned findings and credit disputes over separate fixes; and it gives correspondence something to check. Full disclosure is defensible because of it: a finding never publishes without its fix.
Rejected: separate finding and fix contributions. Prices in drive-by claims, leaves orphaned findings, creates credit disputes, and removes the artifact correspondence checks against.
Two rules apply throughout. New information only: restating what is on the record scores zero. Everything is signed: identities cannot be laundered by spawning a new one, because a new identity starts with only the allowance.
Open
- The schema is published as JSON Schema in the public repository's
schema/; a target is an ecosystem, a package, a version or revision, and the content hash they resolve to, so a new ecosystem is a new resolver and not a schema change. Open: resolvers beyond Go. - The canonical token stream per language, shared by the caps and the metric. Go's is its own scanner's token stream; tree-sitter for the rest.
- Cap values and the trace node bound. parameters.md.