Where it fits
Receipts record what happened. Envelopes record what was authorized. Neither records a claim that either one reflects harm — that claim, when it exists, has historically lived unsigned, in a support ticket or a chat log. An abuse report is the accusation complement to both: it doesn't replace a receipt or an envelope, it points at one, by hash, as the basis for a claim that it reflects harm.
Receipts say what an agent did. Envelopes say what an agent may do. A report says someone claims one of those was harmful, and grounds that claim in the other two. Together they give a system four tenses of accountable evidence — capability, decision, history, and accusation — each independently verifiable, none requiring trust in the party that produced it, and none silently overreaching into what it cannot prove.
The eleven fields
A report is a JSON object with exactly these eleven members. A document with any additional
member, any missing member, an accused_role or category outside the
closed set, or a malformed evidence_refs is not a report and MUST fail verification.
| Field | Type | Requirement |
|---|---|---|
| protocol | string, "abuse-report/0.1" | REQUIRED |
| reporter_id | string, non-empty | REQUIRED |
| accused_id | string, non-empty | REQUIRED |
| accused_role | string, one of agent | principal | REQUIRED |
| category | string, closed vocabulary or other | REQUIRED |
| evidence_refs | array, non-empty, of {type, hash} | REQUIRED |
| narrative | string, non-empty | REQUIRED |
| prev_hash | string (64-char lowercase hex SHA-256) or null | REQUIRED; null only for a reporter's first report |
| issued_at | string, RFC 3339 timestamp | REQUIRED; supplied by the issuer, validated by parsing |
| sig | string (128-char hex Ed25519 signature) | REQUIRED |
| pubkey | string (64-char hex, raw 32-byte Ed25519 public key) | REQUIRED |
The category vocabulary
A closed, versioned set: unauthorized_scope_expansion, deceptive_output,
resource_abuse, collusive_behavior — an agent accused of abusing a
principal — and injection_attempt, capability_extraction,
harassment — a principal accused of abusing an agent — plus other, where
narrative carries the substantive claim. A new category is a minor protocol revision
(e.g. abuse-report/0.2); an implementation that accepts an unrecognized
category under an unchanged protocol value is nonconforming.
Evidence references
Each element of evidence_refs is exactly {type, hash} — a pointer, never
a bundled payload. type is receipt or envelope;
hash is computed the same way the cited artifact's own reference implementation
computes it. A report may cite more than one artifact — real abuse is often a pattern across
several receipts, not one isolated event — but the reporter MUST be a party to every
cited item, not just one; otherwise an unrelated citation could be smuggled in alongside a
legitimate one.
Canonicalization & signature
The signing input is the JSON serialization of the report with the sig member
removed, using: keys sorted lexicographically at every level; the compact separators
"," and ":" (no insignificant whitespace); UTF-8 encoding.
sig is the Ed25519 signature (RFC 8032) over those canonical bytes, hex-encoded;
pubkey is the raw 32-byte Ed25519 public key, hex-encoded. Identical inputs produce
byte-identical reports, and hostile input never raises out of the verifiers.
report {
protocol "abuse-report/0.1"
reporter_id the filer's identity
accused_id the accused party's identity
accused_role agent | principal
category closed vocabulary, or "other"
evidence_refs [ { type: receipt|envelope, hash } , ... ] (non-empty)
narrative the filer's account (required)
prev_hash SHA-256 of this reporter's prior report, or null
issued_at RFC 3339, caller-supplied
sig Ed25519 over the canonical body, sig removed
pubkey the reporter's raw Ed25519 public key
}
Report hash and the chain
The report hash is the lowercase-hex SHA-256 of the full report — including sig —
under the same key ordering and separators. A successor report's prev_hash must equal
the report hash of the same reporter's immediately preceding report. A reporter's chain is
reconstructed the same way an agent's envelope chain is: rejecting a gap (a deleted interior
report), a fork (two reports claiming the same predecessor), a foreign-chain splice (a
prev_hash reaching into another reporter's chain), and duplicates or zero/multiple
genesis reports.
Two-tier verification
A report's signature and structure can always be checked, with no external lookups. Whether its citation is real — whether the hash resolves to something, and whether the reporter was really a party to it — can only be checked by someone who holds the cited artifact. Conflating the two would mean either rejecting reports nobody happens to be able to fully audit yet, or silently trusting citations that were never actually confirmed. Both are wrong, so the check is split:
Always available
Format, canonical signature, and chain integrity across whatever set of a reporter's reports the verifier holds. No access to the cited evidence required.
Requires holding the artifact
Recomputes the artifact's hash, checks its declared type, and confirms the reporter is a real party to it. Returns confirmed, hash_mismatch, type_mismatch, or not_party.
A citation nobody has checked this way at all — the verifier simply doesn't hold the artifact — is unconfirmed, a distinct, honest state. Treating "not checked" as either "passed" or "failed" is a misuse of the primitive, not a property it provides.
What it does not do
Signs the accusation, not the verdict
A report is an accusation, not a finding. No report, however well-formed and evidence-confirmed, determines guilt or innocence.
No automatic score consequence
A confirmed report does not by itself change any reputation score. A future integration is a named direction, not built here.
Deployment policy, not this primitive
Who collects, stores, or distributes reports is outside this specification, the same boundary drawn around who runs a reputation auditor.
Out of scope. Whether an action actually happened, and whether it was authorized, are both outside this primitive — those are agency receipts' and agent envelope's questions. An abuse report only ever claims: someone accused this, grounded in that.