PoQ Report spec
This is the field-by-field reference for the PoQ Report payload — the canonical JSON that every PoQ Report is a render of. For the conceptual overview (what a report is, how to read it, and how to verify one), see the PoQ Report guide.
Every PoQ Report is one canonical JSON payload (schema poq.attestation/v1), signed once. The readable formats — text, HTML — are deterministic renders of that payload, so this reference is also the source of truth for every value shown on a report page.
The payload is a single object. Its top-level keys map one-to-one onto the report's sections:
| Key | Type | Required | Report section |
|---|---|---|---|
schema | string (const) | yes | Header |
report_id | string | yes | Header |
issuer | string | yes | Header |
issued_at | timestamp | yes | Header |
scope | object | yes | Scope |
result | object | yes | Result |
scorecard | array | yes | Scorecard |
distribution | object | yes | Distribution |
poq_record | object | yes | PoQ Record excerpt |
quorum_routing | object | yes | Quorum routing |
configuration | object | yes | Configuration |
pool | object | yes | Pool & provenance |
stake | object | no | Pool & provenance (Collateral mode only) |
custody | object | yes | Chain of custody |
attestation | object | yes | Attestation |
assertion | string | yes | What this asserts |
The payload is strict: additionalProperties is false at every level, so any key not listed here is rejected. Every required field must be present.
Value types
Several fields reuse the same primitive types. They are defined once here and referenced throughout.
| Type | JSON | Format | Example |
|---|---|---|---|
| score | integer | 0–100. A quality or consensus score. | 82 |
| weight | string | "advisory" or a non-negative decimal ("0", "1", "2.5", "0.5"). A rubric weight. | "1.5" |
| wei | string | A non-negative decimal integer, in wei. Used only in Collateral mode. | "1000000000000000000" |
| hash | string | sha256: followed by 64 lowercase hex characters. | "sha256:9f2b…c1" |
| timestamp | string | RFC 3339 UTC, second precision, Z suffix: YYYY-MM-DDThh:mm:ssZ. | "2026-07-21T14:03:00Z" |
| bands | object | Map of score-band label → count. Band labels are 0-9, NN-NN (e.g. 40-49), or 90-100. | { "40-49": 3, "90-100": 12 } |
No floats in the signed bytes. Every numeric value is carried either as a bounded integer (scores, counts) or as a string (weights, wei). The signed payload contains no floating-point numbers, so the canonical bytes are deterministic.
Identity
The four top-level scalars that identify the report. They render in the report header.
| Field | Type | Required | Description |
|---|---|---|---|
schema | string (const) | yes | Always "poq.attestation/v1". Pins the payload to this schema version. |
report_id | string | yes | Stable report identifier, pattern PR-YYYY-NNNN-<ALNUM>-NNNN (e.g. PR-2026-0042-AB12-0007). |
issuer | string | yes | The issuing deployment / organization. Non-empty. |
issued_at | timestamp | yes | When the report was issued. |
scope
Which project the report covers and how much of it was reviewed. Renders as the Scope section.
| Field | Type | Required | Description |
|---|---|---|---|
project | string | yes | Project name. Non-empty. |
datapoints_covered | integer | yes | Number of datapoints the report certifies (≥ 1). |
reviewed | integer | yes | Number of datapoints reviewed (≥ 1). At M1 this equals datapoints_covered — there is no sampling. |
manifest_hash | hash | yes | Hash of the covered-datapoint manifest. |
result
The headline result. Renders as the Result section.
| Field | Type | Required | Description |
|---|---|---|---|
quality_rating | score | yes | The overall Quality Rating (0–100). |
consensus_strength | score | yes | The overall Consensus Strength (0–100). |
label | object | no | The headline label, when the rubric produces one. |
label object:
| Field | Type | Required | Description |
|---|---|---|---|
value | string | yes | The label text (e.g. the winning category). Non-empty. |
source | string | yes | Where the label came from (e.g. the rubric dimension that produced it). Non-empty. |
scorecard
Per-dimension quality and consensus, with rubric weights. A non-empty array; renders as the Scorecard section. Each element:
| Field | Type | Required | Description |
|---|---|---|---|
dimension | string | yes | Rubric dimension name (no whitespace). |
weight | weight | yes | The dimension's weight — "advisory" or a non-negative decimal. |
quality_rating | score | yes | Quality Rating for this dimension. |
consensus_strength | score | yes | Consensus Strength for this dimension. |
distribution
How scores were spread across datapoints. Renders as the Distribution section (histograms).
| Field | Type | Required | Description |
|---|---|---|---|
quality_rating | bands | yes | Distribution of per-datapoint Quality Ratings, as a band → count map. |
consensus_strength | bands | yes | Distribution of per-datapoint Consensus Strengths, as a band → count map. |
Each bands map has at least one entry; band labels are 0-9, a two-digit range like 40-49, or 90-100, and each count is ≥ 1.
poq_record
A commitment to the full per-datapoint PoQ Record, plus an optional one-datapoint excerpt signed inline. Renders as the PoQ Record excerpt section.
| Field | Type | Required | Description |
|---|---|---|---|
results_hash | hash | yes | Hash committing to the complete per-datapoint results record. |
excerpt | object | no | One datapoint's full detail, carried inline and signed with the payload. |
excerpt object:
| Field | Type | Required | Description |
|---|---|---|---|
schema | string (const) | yes | Always "poq.record/v1". |
shown | integer | yes | Which datapoint index is shown (≥ 1). |
datapoint | object | yes | The excerpted datapoint (see below). |
excerpt.datapoint object:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Datapoint identifier. Non-empty. |
canonical_hash | hash | yes | Hash of the datapoint's canonical content. |
quality_rating | score | yes | This datapoint's Quality Rating. |
consensus_strength | score | yes | This datapoint's Consensus Strength. |
settled_round | integer | yes | The round in which this datapoint settled (≥ 1). |
escalated | boolean | yes | Whether the datapoint was escalated beyond its first round. |
quorum | array | yes | The rounds and votes that decided it (see below). Non-empty. |
dimensions | array | yes | Per-dimension detail for this datapoint (see below). Non-empty. |
excerpt.datapoint.quorum[] — one entry per round:
| Field | Type | Required | Description |
|---|---|---|---|
round | integer | yes | Round number (≥ 1). |
votes | array | yes | The votes cast this round (see below). Non-empty. |
excerpt.datapoint.quorum[].votes[] — one entry per validator:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Validator identifier (pseudonymous). Non-empty. |
type | enum | yes | "human" or "agentic". |
model | string | no | Model identifier, for agentic validators. |
credential | string | no | Credential held, for human validators. |
weight | string | yes | The vote's consensus weight — a non-negative decimal. Unlike a rubric weight, "advisory" is not accepted here. |
excerpt.datapoint.dimensions[] — per-dimension breakdown:
| Field | Type | Required | Description |
|---|---|---|---|
dimension | string | yes | Rubric dimension name. Non-empty. |
quality | score | yes | Quality score for this dimension on this datapoint. |
strength | score | yes | Consensus strength for this dimension on this datapoint. |
weight | weight | yes | The dimension's weight. |
quorum_routing
How validators were assigned across rounds, and where datapoints settled. Renders as the Quorum routing section.
| Field | Type | Required | Description |
|---|---|---|---|
rounds | array | yes | The routing rounds (see below). Non-empty. |
execution | object | yes | Where datapoints settled (see below). |
quorum_routing.rounds[]:
| Field | Type | Required | Description |
|---|---|---|---|
round | integer | yes | Round number (≥ 1). |
quorum | integer | no | Quorum size targeted this round (≥ 1). |
escalation_target | score | no | The consensus-strength threshold below which a datapoint escalates. |
slots | array | yes | The validator slots offered this round (see below). Non-empty. |
quorum_routing.rounds[].slots[] — a validator slot. Each slot is either a human slot or an agentic slot (enforced by the schema's oneOf):
| Field | Type | Required | Description |
|---|---|---|---|
type | enum | yes | "human" or "agentic". |
count | integer | yes | Number of validators in this slot (≥ 1). |
vote_weight | string | yes | Per-vote weight — a non-negative decimal. |
credential | string | human slot | Required credential. Human slots only. |
instructions_hash | hash | human slot | Hash of the instructions shown. Human slots only. |
model | string | agentic slot | Model identifier (no whitespace). Agentic slots only. |
prompt_hash | hash | agentic slot | Hash of the agent prompt. Agentic slots only. |
A human slot must carry credential + instructions_hash and must not carry model/prompt_hash; an agentic slot is the mirror image. Mixing the two is rejected.
quorum_routing.execution:
| Field | Type | Required | Description |
|---|---|---|---|
settled_round_1 | integer | yes | How many datapoints settled in round 1 (≥ 0). |
escalated | integer | yes | How many datapoints escalated past round 1 (≥ 0). |
configuration
The rubric and the locked config. Renders as the Configuration section.
| Field | Type | Required | Description |
|---|---|---|---|
rubric | string | yes | Rubric identifier (no whitespace). |
config_hash | hash | yes | Hash of the locked poq.toml configuration. |
pool
Validator pool size, churn, participation, and independence. Renders as the Pool & provenance section.
| Field | Type | Required | Description |
|---|---|---|---|
size | integer | yes | Final pool size — every validator class eligible for the work, including agentic (≥ 0). |
size_at_start | integer | yes | Pool size when the review window opened (≥ 0). |
added | integer | yes | Validators added during the window (≥ 0). |
removed | integer | yes | Validators removed during the window (≥ 0). |
participated_human | integer | yes | Human validators who cast at least one vote (≥ 0). |
participated_agentic | integer | yes | Agentic (AI) validators who cast at least one vote (≥ 0). |
credentials | string | yes | Summary of the credentials represented in the pool. Non-empty. |
blind_review | boolean | yes | Whether reviews were blind (validators could not see each other's inputs). |
coi_declared | integer | no | Conflict-of-interest declarations collected (≥ 0). Present iff COI declarations were collected; 0 means collected, none declared. |
stake
Collateral mode only. Present only for events that put stake at risk; omitted otherwise. Renders under Pool & provenance.
| Field | Type | Required | Description |
|---|---|---|---|
stake_at_risk_wei | wei | yes | Total stake at risk, in wei. |
slashed_wei | wei | yes | Stake slashed, in wei. |
rewards_wei | wei | yes | Rewards paid, in wei. |
custody
The chain-of-custody timestamps. Renders as the Chain of custody section. All five are required timestamps.
| Field | Type | Required | Description |
|---|---|---|---|
config_locked | timestamp | yes | When the poq.toml config was locked. |
manifest_confirmed | timestamp | yes | When the datapoint manifest was confirmed. |
review_opened | timestamp | yes | When the review window opened. |
review_closed | timestamp | yes | When the review window closed. |
issued | timestamp | yes | When the report was issued. |
attestation
The cryptographic roots and signing key. Renders as the Attestation section.
| Field | Type | Required | Description |
|---|---|---|---|
root | hash | yes | The attestation root committing to the report. |
score_root | hash | yes | The root committing to the per-datapoint scores. |
signing_key_id | string | yes | Key id (kid) of the signing key (no whitespace). |
registry | string | no | Validator/revocation registry reference. Absent until the registry exists (M4). |
assertion
| Field | Type | Required | Description |
|---|---|---|---|
assertion | string | yes | The fixed plain-language statement of what the report certifies. A constant of the schema version; renders as the What this asserts section. |
The signed payload
The object above is signed exactly once and delivered in whichever format you request. The signature and canonicalization are fixed properties of poq.attestation/v1:
| Property | Detail |
|---|---|
| Signature | A single Ed25519 signature, delivered as a compact JWS. |
| Canonicalization | The payload is canonicalized with JCS (RFC 8785) before signing — deterministic bytes. |
| Numerics | All non-integer numeric values are carried as strings; there are no floats in the signed bytes. |
| Key id | The JWS header carries a kid matching attestation.signing_key_id. |
Any change to a covered value — in the JSON, the readable text, or the HTML — breaks verification.
Formats
The one signed payload is delivered in any of four formats:
| Format | Extension | What you get | Best for |
|---|---|---|---|
| Text | .txt | A readable render followed by the fenced signature | The default — human-readable, verifiable |
| HTML | .html | The designed, styled report page | Sharing / reading in a browser or PDF |
| JSON | .json | The canonical signed payload (this schema) | Machine consumption |
| JWS | .jws | The bare compact signature | Verifying against your own payload copy |
Envelopes
The two readable formats declare an envelope version so a verifier knows how to interpret the carrier before applying any grammar:
| Envelope | Carrier |
|---|---|
poq.envelope/text-v1 | The two-layer text artefact: a readable render followed by the fenced compact JWS. |
poq.envelope/html-v1 | The designed HTML page, which embeds the text artefact and tags every payload-derived value with data-poq. |
In the text artefact the JWS sits between -----BEGIN POQ SIGNED PAYLOAD----- / -----END POQ SIGNED PAYLOAD----- fences. In the HTML the same text artefact is embedded in a <script type="application/poq-attestation+text"> element. For how to verify either offline, see Verifying a report.
See also
| Page | Description |
|---|---|
| PoQ Report | The conceptual guide: what a report is, how to get one, how to verify it |
| poq.toml spec | Field reference for the project spec that produces the report |
| How consensus works | The mechanics behind the Quality Rating and Consensus Strength |