use serde::{Deserialize, Serialize};
use serde_json::{json, Map, Value};
use sha2::{Digest, Sha256};
use std::path::Path;
use std::str::FromStr;
use super::drain::{
AdmissionCap, BandContext, BandInput, BandStatus, ComparatorStatus, DerivedBand, SampleRow,
StreamMode, StreamWitness, SCHEMA_VERSION,
};
use super::join::{BandRatios, JoinKey};
use super::protocol::ProtocolParams;
use super::samples::SamplesFile;
use super::witness::BatchInvarianceWitness;
pub const SPEC_ID: &str = "PP-LLAMA-001 v3.0";
pub const CLOCK_SOURCE_SYSTEM_REALTIME: &str = "std::time::SystemTime (CLOCK_REALTIME)";
pub const SERVER_ONLY_FIELDS: &str = "§4.4.9 scheduler block (max_in_flight, admission_rejected, \
preempted_recompute, preempted_swap, kv_blocks_total, kv_blocks_peak_used, \
kv_bytes_reserved, kv_bytes_used, gpu_layers_requested, gpu_layers_resolved, \
gpu_layers_total, backend_loaded[], autofit_applied[]) — every one is reported by the \
SERVER. PP-13: max_in_flight is reported by the server, not inferred by the harness; PP-2: \
gpu_layers_resolved is read from the loader and never inferred. A client-side estimate \
would read exactly like a measurement, so none is emitted.";
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
pub struct RunId(String);
impl RunId {
#[must_use]
pub fn derive(started_utc: &str, host: &str, client_sha256: &str, pid: u32) -> Self {
let mut hasher = Sha256::new();
hasher.update(started_utc.as_bytes());
hasher.update(host.as_bytes());
hasher.update(client_sha256.as_bytes());
hasher.update(pid.to_string().as_bytes());
let digest = format!("{:x}", hasher.finalize());
Self(digest[..32].to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl TryFrom<String> for RunId {
type Error = String;
fn try_from(value: String) -> Result<Self, Self::Error> {
if value.len() == 32
&& value
.bytes()
.all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
{
Ok(Self(value))
} else {
Err(format!(
"run_id {value:?} is not 32 lowercase hex characters — PP-3 keys the baseline on \
it, so a malformed one would make every ratio unjoinable"
))
}
}
}
impl From<RunId> for String {
fn from(id: RunId) -> Self {
id.0
}
}
#[cfg(not(target_arch = "wasm32"))]
#[must_use]
pub fn now_utc_millis() -> String {
chrono::Utc::now()
.format("%Y-%m-%dT%H:%M:%S%.3fZ")
.to_string()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ComputeClass {
Cpu,
Cuda,
Metal,
Wgpu,
Unknown,
}
impl ComputeClass {
#[must_use]
pub fn wire_token(self) -> &'static str {
match self {
Self::Cpu => "cpu",
Self::Cuda => "cuda",
Self::Metal => "metal",
Self::Wgpu => "wgpu",
Self::Unknown => "unknown",
}
}
}
impl FromStr for ComputeClass {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
[
Self::Cpu,
Self::Cuda,
Self::Metal,
Self::Wgpu,
Self::Unknown,
]
.into_iter()
.find(|c| c.wire_token() == s)
.ok_or_else(|| {
format!(
"compute_class {s:?}: expected one of cpu, cuda, metal, wgpu, unknown (PP-2 \
requires the path TAKEN, not the hardware present)"
)
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SubjectIdentity {
pub path: String,
pub sha256: String,
pub commit: String,
pub feature_set: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ClientIdentity {
pub path: String,
pub sha256: String,
pub commit: String,
pub pid: u32,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ComparatorIdentity {
pub commit: String,
pub cmake: String,
pub sha256: String,
pub pin_expiry: String,
pub props: Value,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ModelIdentity {
pub path: String,
pub sha256: String,
pub bytes: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Provenance {
pub binary_path: String,
pub binary_sha256: String,
pub resolution: String,
pub compute_class: ComputeClass,
pub host: String,
pub accelerator: String,
pub model: String,
pub quantization: String,
pub feature_set: Vec<String>,
pub started_utc: String,
pub clock_source: String,
pub subject: SubjectIdentity,
pub client: ClientIdentity,
pub comparator: Option<ComparatorIdentity>,
pub server_config: Option<Value>,
pub model_file: Option<ModelIdentity>,
}
impl Provenance {
pub fn validate(&self) -> Result<(), String> {
for (name, value) in self.required_strings() {
if value.trim().is_empty() {
return Err(format!(
"provenance.{name}: empty — this field has no default; a receipt that does \
not say {name} is an anonymous number, not evidence"
));
}
}
for (name, digest) in self.digests() {
if !is_sha256(digest) {
return Err(format!(
"provenance.{name}: {digest:?} is not 64 lowercase hex characters"
));
}
}
validate_rfc3339_utc_millis("provenance.started_utc", &self.started_utc)?;
if let Some(c) = &self.comparator {
validate_rfc3339_utc_millis("provenance.comparator.pin_expiry", &c.pin_expiry)?;
}
self.validate_feature_set()
}
#[must_use]
pub fn comparator_is_stale(&self) -> bool {
self.comparator
.as_ref()
.is_some_and(|c| c.pin_expiry < self.started_utc)
}
fn required_strings(&self) -> Vec<(&'static str, &str)> {
let mut out = vec![
("binary_path", self.binary_path.as_str()),
("binary_sha256", self.binary_sha256.as_str()),
("resolution", self.resolution.as_str()),
("host", self.host.as_str()),
("accelerator", self.accelerator.as_str()),
("model", self.model.as_str()),
("quantization", self.quantization.as_str()),
("started_utc", self.started_utc.as_str()),
("clock_source", self.clock_source.as_str()),
("subject.path", self.subject.path.as_str()),
("subject.commit", self.subject.commit.as_str()),
("client.path", self.client.path.as_str()),
("client.commit", self.client.commit.as_str()),
];
if let Some(c) = &self.comparator {
out.push(("comparator.commit", c.commit.as_str()));
out.push(("comparator.cmake", c.cmake.as_str()));
out.push(("comparator.pin_expiry", c.pin_expiry.as_str()));
}
if let Some(m) = &self.model_file {
out.push(("model_file.path", m.path.as_str()));
}
out
}
fn digests(&self) -> Vec<(&'static str, &str)> {
let mut out = vec![
("binary_sha256", self.binary_sha256.as_str()),
("subject.sha256", self.subject.sha256.as_str()),
("client.sha256", self.client.sha256.as_str()),
];
if let Some(c) = &self.comparator {
out.push(("comparator.sha256", c.sha256.as_str()));
}
if let Some(m) = &self.model_file {
out.push(("model_file.sha256", m.sha256.as_str()));
}
out
}
fn validate_feature_set(&self) -> Result<(), String> {
let needs_feature = matches!(self.compute_class, ComputeClass::Cuda | ComputeClass::Wgpu);
let token = self.compute_class.wire_token();
if needs_feature && !self.subject.feature_set.iter().any(|f| f == token) {
return Err(format!(
"provenance.compute_class={token} but subject.feature_set={:?} does not contain \
it — a build without the feature cannot take that path (PP-2)",
self.subject.feature_set
));
}
Ok(())
}
}
fn validate_rfc3339_utc_millis(field: &str, value: &str) -> Result<(), String> {
const SHAPE: &str = "YYYY-MM-DDTHH:MM:SS.mmmZ";
let bytes = value.as_bytes();
let ok = bytes.len() == 24
&& bytes.iter().enumerate().all(|(i, b)| match i {
4 | 7 => *b == b'-',
10 => *b == b'T',
13 | 16 => *b == b':',
19 => *b == b'.',
23 => *b == b'Z',
_ => b.is_ascii_digit(),
});
if !ok {
return Err(format!(
"{field}: {value:?} is not {SHAPE} — PP-30 needs a canonical UTC instant, because \
PP-20 compares a pin expiry against it as a string and any other spelling sorts \
wrongly"
));
}
Ok(())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TokenCountingMethod {
ServerUsage,
ClientTokenizer,
}
impl TokenCountingMethod {
#[must_use]
pub fn wire_token(self) -> &'static str {
match self {
Self::ServerUsage => "server_usage",
Self::ClientTokenizer => "client_tokenizer",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "method", rename_all = "snake_case", deny_unknown_fields)]
pub enum TokenizationBlock {
ServerUsage {
counts_special_tokens: bool,
counts_prompt_echo: bool,
},
ClientTokenizer {
tokenizer_sha256: String,
counts_special_tokens: bool,
counts_prompt_echo: bool,
},
}
impl TokenizationBlock {
#[must_use]
pub fn method(&self) -> TokenCountingMethod {
match self {
Self::ServerUsage { .. } => TokenCountingMethod::ServerUsage,
Self::ClientTokenizer { .. } => TokenCountingMethod::ClientTokenizer,
}
}
pub fn validate(&self) -> Result<(), String> {
match self {
Self::ServerUsage { .. } => Ok(()),
Self::ClientTokenizer {
tokenizer_sha256, ..
} if is_sha256(tokenizer_sha256) => Ok(()),
Self::ClientTokenizer {
tokenizer_sha256, ..
} => Err(format!(
"tokenization.tokenizer_sha256: {tokenizer_sha256:?} is not 64 lowercase hex \
characters — §4.4.6 requires it when method = client_tokenizer"
)),
}
}
pub fn require_counter(&self, has_client_counter: bool) -> Result<(), String> {
match (self.method(), has_client_counter) {
(TokenCountingMethod::ClientTokenizer, false) => Err(
"tokenization.method = client_tokenizer but no client TokenCounter was supplied"
.to_string(),
),
(TokenCountingMethod::ServerUsage, true) => Err(
"tokenization.method = server_usage but a client TokenCounter was supplied; \
declare client_tokenizer or drop the counter"
.to_string(),
),
_ => Ok(()),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct KvBlock {
bytes_used: u64,
bytes_reserved: u64,
admission_rejected: Option<u64>,
preempted_swap: Option<u64>,
}
impl KvBlock {
#[must_use]
pub fn from_server_report(
bytes_used: u64,
bytes_reserved: u64,
admission_rejected: Option<u64>,
preempted_swap: Option<u64>,
) -> Self {
Self {
bytes_used,
bytes_reserved,
admission_rejected,
preempted_swap,
}
}
#[must_use]
pub fn uncounted_fields(&self) -> Vec<&'static str> {
let mut out = Vec::new();
if self.admission_rejected.is_none() {
out.push("kv.admission_rejected");
}
if self.preempted_swap.is_none() {
out.push("kv.preempted_swap");
}
out
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SlotsAdmitted {
pub apr: Option<u32>,
pub llama: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Ladder {
pub declared: Vec<u32>,
pub derived: Vec<u32>,
pub slots_admitted: SlotsAdmitted,
}
impl Ladder {
#[must_use]
pub fn derive(declared: &[u32], slots_admitted: SlotsAdmitted) -> Self {
let cap = match (slots_admitted.apr, slots_admitted.llama) {
(Some(a), Some(l)) => Some(a.min(l)),
(Some(a), None) => Some(a),
(None, Some(l)) => Some(l),
(None, None) => None,
};
let derived = declared
.iter()
.copied()
.filter(|c| cap.admits(*c))
.collect();
Self {
declared: declared.to_vec(),
derived,
slots_admitted,
}
}
#[must_use]
pub fn is_underived(&self) -> bool {
self.slots_admitted.apr.is_none() && self.slots_admitted.llama.is_none()
}
}
trait CapExt {
fn admits(self, c: u32) -> bool;
}
impl CapExt for Option<u32> {
fn admits(self, c: u32) -> bool {
match self {
None => true,
Some(cap) => cap >= c,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Roofline {
pub bandwidth_bytes_per_sec: f64,
pub model_bytes: u64,
}
impl Roofline {
#[must_use]
pub fn tok_per_sec(self) -> Option<f64> {
if self.model_bytes == 0 || self.bandwidth_bytes_per_sec <= 0.0 {
return None;
}
Some(self.bandwidth_bytes_per_sec / self.model_bytes as f64)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Workload {
W1,
W2,
}
impl Workload {
#[must_use]
pub fn wire_token(self) -> &'static str {
match self {
Self::W1 => "W1",
Self::W2 => "W2",
}
}
}
impl FromStr for Workload {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
[Self::W1, Self::W2]
.into_iter()
.find(|w| w.wire_token() == s)
.ok_or_else(|| format!("workload {s:?}: expected W1 or W2 (§5.1)"))
}
}
pub fn sha256_file(path: &Path) -> std::io::Result<String> {
let mut file = std::fs::File::open(path)?;
let mut hasher = Sha256::new();
std::io::copy(&mut file, &mut hasher)?;
Ok(format!("{:x}", hasher.finalize()))
}
#[derive(Debug, Clone, PartialEq)]
pub struct ReceiptInput {
pub schema_version: u32,
pub run_id: RunId,
pub provenance: Provenance,
pub tokenization: TokenizationBlock,
pub workload: Workload,
pub protocol: ProtocolParams,
pub commit: String,
pub ladder: Ladder,
pub bands: Vec<BandInput>,
pub kv: Option<KvBlock>,
pub roofline: Option<Roofline>,
}
impl ReceiptInput {
#[must_use]
pub fn new(
run_id: RunId,
provenance: Provenance,
tokenization: TokenizationBlock,
workload: Workload,
protocol: ProtocolParams,
commit: impl Into<String>,
ladder: Ladder,
bands: Vec<BandInput>,
) -> Self {
Self {
schema_version: SCHEMA_VERSION,
run_id,
provenance,
tokenization,
workload,
protocol,
commit: commit.into(),
ladder,
bands,
kv: None,
roofline: None,
}
}
#[must_use]
pub fn band_context(&self) -> BandContext {
BandContext {
schema_version: self.schema_version,
replicates: self.protocol.replicates,
interleaved: self.protocol.interleaved,
comparator_stale: self.provenance.comparator_is_stale(),
..BandContext::default()
}
}
#[must_use]
pub fn join_key(&self, band: &BandInput) -> JoinKey {
JoinKey::of(self, band)
}
pub fn render(&self) -> Result<Value, String> {
self.provenance.validate()?;
self.tokenization.validate()?;
self.check_ladder_is_derived()?;
if self.bands.is_empty() {
return Err(
"receipt has no bands — a measurement over zero bands is a vacuous pass"
.to_string(),
);
}
let ctx = self.band_context();
let stale = ctx.comparator_stale;
let mut bands = Vec::with_capacity(self.bands.len());
for input in &self.bands {
self.check_ladder(input)?;
let mut derived = input.derive_in(&ctx)?.with_join_key(self.join_key(input));
if stale {
let expiry = self
.provenance
.comparator
.as_ref()
.map_or("", |c| c.pin_expiry.as_str());
derived = derived.marked_comparator_stale(expiry, &self.provenance.started_utc);
}
bands.push(derived);
}
self.check_roofline(&bands)?;
let samples = samples_ms(&bands);
validate_samples(&samples)?;
Ok(self.assemble(&bands, samples))
}
pub fn render_string(&self) -> Result<String, String> {
let value = self.render()?;
serde_json::to_string_pretty(&value).map_err(|e| format!("serialising receipt: {e}"))
}
fn check_ladder_is_derived(&self) -> Result<(), String> {
let recomputed = Ladder::derive(&self.ladder.declared, self.ladder.slots_admitted);
if recomputed.derived == self.ladder.derived {
return Ok(());
}
Err(format!(
"PP-24: ladder.derived is {:?} but declared {:?} with slots_admitted apr={:?} \
llama={:?} derives {:?} — `derived` is `{{c ∈ declared : c ≤ min(slots_admitted)}}`, \
not a field a producer may state. A supplied ladder that disagrees with its own \
inputs excuses exactly the bands PP-24 exists to exclude.",
self.ladder.derived,
self.ladder.declared,
self.ladder.slots_admitted.apr,
self.ladder.slots_admitted.llama,
recomputed.derived
))
}
fn check_ladder(&self, band: &BandInput) -> Result<(), String> {
if self.ladder.derived.contains(&band.concurrency) {
return Ok(());
}
match &band.comparator {
ComparatorStatus::NotApplicable { .. } => Ok(()),
ComparatorStatus::Unmeasured {
admission_capped: Some(_),
..
} => Ok(()),
_ => Err(format!(
"PP-24: band c={} is not in the derived ladder {:?} (slots_admitted apr={:?} \
llama={:?}) and carries neither an admission cap nor a decision — a band above \
what the servers admitted measured a queue, not a server",
band.concurrency,
self.ladder.derived,
self.ladder.slots_admitted.apr,
self.ladder.slots_admitted.llama
)),
}
}
fn check_roofline(&self, bands: &[DerivedBand]) -> Result<(), String> {
let Some(ceiling) = self.roofline.and_then(Roofline::tok_per_sec) else {
return Ok(());
};
for b in bands.iter().filter(|b| b.concurrency == 1) {
if let Some(dec) = b.decode_tok_per_sec {
if dec > ceiling {
return Err(format!(
"PP-23: decode_tok_per_sec={dec:.1} at c=1 exceeds the memory-bandwidth \
ceiling {ceiling:.1} tok/s — decoding a token reads the whole model \
once, so this is not a fast run, it is a wrong measurement"
));
}
}
}
Ok(())
}
fn assemble(&self, bands: &[DerivedBand], samples: Vec<f64>) -> Value {
let mut map = Map::new();
map.insert("spec".into(), json!(SPEC_ID));
map.insert("schema_version".into(), json!(self.schema_version));
map.insert("run_id".into(), json!(self.run_id.as_str()));
map.insert("commit".into(), json!(self.commit));
map.insert("workload".into(), json!(self.workload.wire_token()));
map.insert("protocol".into(), to_value(&self.protocol));
map.insert("client_model".into(), json!("closed_loop"));
map.insert("provenance".into(), to_value(&self.provenance));
map.insert("tokenization".into(), to_value(&self.tokenization));
insert_counts(&mut map, bands);
map.insert(
"short_of_n_predict".into(),
json!(sum(bands, |b| b.short_of_n_predict)),
);
map.insert("drain_ms".into(), json!(receipt_drain_ms(bands)));
map.insert("n".into(), json!(samples.len()));
map.insert("samples_ms".into(), json!(samples));
map.insert("ladder".into(), to_value(&self.ladder));
let roofline = self.roofline.and_then(Roofline::tok_per_sec);
let render_ctx = RenderContexts {
subject: RenderContext {
agg1: band_metric(bands, 1, |b| b.aggregate_tok_per_sec),
dec1: band_metric(bands, 1, |b| b.decode_tok_per_sec),
roofline,
},
comparator: RenderContext {
agg1: baseline_metric(bands, 1, |b| b.aggregate_tok_per_sec),
dec1: baseline_metric(bands, 1, |b| b.decode_tok_per_sec),
roofline,
},
};
map.insert(
"bands".into(),
Value::Array(
bands
.iter()
.map(|b| band_json(b, &render_ctx.subject, Some(&render_ctx)))
.collect(),
),
);
if let Some(kv) = self.kv {
map.insert("kv".into(), to_value(&kv));
}
map.insert("unproduced_fields".into(), json!(self.unproduced(bands)));
Value::Object(map)
}
fn unproduced(&self, bands: &[DerivedBand]) -> Vec<String> {
let mut out = vec![SERVER_ONLY_FIELDS.to_string()];
match &self.kv {
None => out.push(
"Arm D `kv` block (bytes_used, bytes_reserved, admission_rejected, \
preempted_swap) — server-reported. Absent here, so this receipt is legal at \
merge phase and correctly FAILS at release phase rather than carrying invented \
memory figures."
.to_string(),
),
Some(kv) => {
let uncounted = kv.uncounted_fields();
if !uncounted.is_empty() {
out.push(format!(
"Arm D {uncounted:?} — the server reported the KV byte figures but not \
these counters: the mechanism they would count does not exist on this \
build. They are null rather than 0, because \"not counted\" and \
\"counted none\" are different facts and Arm D reads one of them as \
evidence."
));
}
}
}
if self.roofline.is_none() {
out.push(
"PP-23 roofline_tok_per_sec — no `[V]` memory bandwidth is committed for this \
host, so the ceiling is null on every band. A vendor GB/s figure is not a \
measurement (PP-12)."
.to_string(),
);
}
if self.ladder.is_underived() {
out.push(format!(
"PP-24 ladder.slots_admitted — neither lane reported a slot count, so \
ladder.derived is the declared set {:?} on no evidence. The band ceiling is \
server-reported (PP-13) and this run did not observe one.",
self.ladder.declared
));
}
if self.provenance.server_config.is_none() {
out.push(
"PP-2 provenance.server_config — `GET /v1/effective-config` was not stored, so \
resolved max_batch, GpuProfile, scheduler identity and the memory fields are \
absent. Every one of them is server-reported; none is inferred here."
.to_string(),
);
}
out.extend(bands.iter().flat_map(|b| b.unproduced.clone()));
out
}
}
struct RenderContext {
agg1: Option<f64>,
dec1: Option<f64>,
roofline: Option<f64>,
}
struct RenderContexts {
subject: RenderContext,
comparator: RenderContext,
}
fn band_metric(
bands: &[DerivedBand],
concurrency: u32,
f: impl Fn(&DerivedBand) -> Option<f64>,
) -> Option<f64> {
bands
.iter()
.find(|b| b.concurrency == concurrency)
.and_then(f)
}
fn baseline_metric(
bands: &[DerivedBand],
concurrency: u32,
f: impl Fn(&DerivedBand) -> Option<f64>,
) -> Option<f64> {
match &bands
.iter()
.find(|b| b.concurrency == concurrency)?
.comparator
{
ComparatorStatus::Measured(join) => f(join.baseline()),
ComparatorStatus::NotApplicable { .. } | ComparatorStatus::Unmeasured { .. } => None,
}
}
fn receipt_drain_ms(bands: &[DerivedBand]) -> f64 {
bands.iter().map(|b| b.drain_ms).fold(0.0_f64, f64::max)
}
fn insert_counts(map: &mut Map<String, Value>, bands: &[DerivedBand]) {
map.insert("requested".into(), json!(sum(bands, |b| b.requested)));
map.insert("completed".into(), json!(sum(bands, |b| b.completed)));
map.insert("timeouts".into(), json!(sum(bands, |b| b.timeouts)));
map.insert("truncated".into(), json!(sum(bands, |b| b.truncated)));
map.insert("errors".into(), json!(sum(bands, |b| b.errors)));
}
fn sum(bands: &[DerivedBand], f: impl Fn(&DerivedBand) -> usize) -> usize {
bands.iter().map(f).sum()
}
fn samples_ms(bands: &[DerivedBand]) -> Vec<f64> {
bands.iter().flat_map(|b| b.latencies_ms.clone()).collect()
}
fn validate_samples(samples: &[f64]) -> Result<(), String> {
if samples.is_empty() {
return Err(
"samples_ms would be empty — no band completed a single request, and a \
receipt with no retained samples permanently forecloses the bootstrap (PP-7)"
.to_string(),
);
}
let first = samples[0];
if samples.len() > 1 && samples.iter().all(|s| (s - first).abs() < f64::EPSILON) {
return Err(format!(
"samples_ms: all {} samples identical ({first}) — a real timing distribution is not \
constant; this is the fabricated-measurement shape (F12)",
samples.len()
));
}
Ok(())
}
fn to_value<T: Serialize>(value: &T) -> Value {
serde_json::to_value(value).unwrap_or(Value::Null)
}
fn band_json(b: &DerivedBand, ctx: &RenderContext, comparator: Option<&RenderContexts>) -> Value {
let mut map = Map::new();
map.insert("concurrency".into(), json!(b.concurrency));
map.insert("replicate".into(), json!(b.replicate));
map.insert("status".into(), json!(b.status.wire_token()));
if let Some(agg) = b.aggregate_tok_per_sec {
map.insert("aggregate_tok_per_sec".into(), json!(agg));
}
map.insert("tokens_total".into(), json!(b.tokens_total));
map.insert("span_ms".into(), json!(b.span_ms));
map.insert("window_ms".into(), json!(b.window_ms));
map.insert("drain_ms".into(), json!(b.drain_ms));
map.insert("requested".into(), json!(b.requested));
map.insert("completed".into(), json!(b.completed));
map.insert("timeouts".into(), json!(b.timeouts));
map.insert("truncated".into(), json!(b.truncated));
map.insert("errors".into(), json!(b.errors));
map.insert("short_of_n_predict".into(), json!(b.short_of_n_predict));
map.insert("suspect".into(), json!(b.suspect));
map.insert(
"stream_mode".into(),
b.stream_mode.map_or(Value::Null, |m| to_value(&m)),
);
map.insert(
"stream_witness".into(),
b.stream_witness.map_or(Value::Null, |w| to_value(&w)),
);
map.insert(
"witness".into(),
b.witness.as_ref().map_or(Value::Null, to_value),
);
map.insert("scaling_efficiency".into(), scaling_efficiency(b, ctx));
map.insert("overhead_share".into(), overhead_share(b, ctx));
map.insert(
"roofline_tok_per_sec".into(),
ctx.roofline.map_or(Value::Null, |r| json!(r)),
);
map.insert(
"samples_file".into(),
b.samples_file.as_ref().map_or(Value::Null, to_value),
);
map.insert("samples".into(), to_value(&b.samples));
map.insert(
"join_key".into(),
b.join_key.as_ref().map_or(Value::Null, to_value),
);
if let Some(run_id) = &b.run_id {
map.insert("run_id".into(), json!(run_id.as_str()));
}
insert_optional_latency(&mut map, b);
if let Some(contexts) = comparator {
insert_comparator(&mut map, &b.comparator, contexts);
}
Value::Object(map)
}
fn insert_optional_latency(map: &mut Map<String, Value>, b: &DerivedBand) {
for (key, value) in [
("decode_tok_per_sec", b.decode_tok_per_sec),
("ttft_p50_ms", b.ttft_p50_ms),
("ttft_p95_ms", b.ttft_p95_ms),
("itl_p50_ms", b.itl_p50_ms),
("itl_p95_ms", b.itl_p95_ms),
] {
if let Some(v) = value {
map.insert(key.into(), json!(v));
}
}
if let Some(prefill) = b.prefill_tok_per_sec {
map.insert("prefill_tok_per_sec".into(), json!(prefill));
map.insert("prefill_source".into(), json!("server"));
}
}
fn scaling_efficiency(b: &DerivedBand, ctx: &RenderContext) -> Value {
if b.concurrency <= 1 {
return Value::Null;
}
match (b.aggregate_tok_per_sec, ctx.agg1) {
(Some(agg), Some(agg1)) if agg1 > 0.0 => {
json!(agg / (f64::from(b.concurrency) * agg1))
}
_ => Value::Null,
}
}
fn overhead_share(b: &DerivedBand, ctx: &RenderContext) -> Value {
if b.concurrency != 1 {
return Value::Null;
}
match (ctx.agg1, ctx.dec1) {
(Some(agg1), Some(dec1)) if dec1 > 0.0 => json!(agg1 / dec1),
_ => Value::Null,
}
}
fn insert_comparator(
map: &mut Map<String, Value>,
status: &ComparatorStatus,
ctx: &RenderContexts,
) {
map.insert("comparator_status".into(), json!(status.wire_token()));
match status {
ComparatorStatus::NotApplicable {
decided_by,
reason,
budget,
} => {
map.insert("comparator_decided_by".into(), json!(decided_by));
map.insert("comparator_reason".into(), json!(reason));
if let Some(b) = budget {
map.insert("comparator_budget".into(), json!(b));
}
map.insert("baseline".into(), Value::Null);
map.insert("ratios".into(), Value::Null);
}
ComparatorStatus::Unmeasured {
owner,
reason,
admission_capped,
} => {
map.insert("comparator_owner".into(), json!(owner));
map.insert("comparator_reason".into(), json!(reason));
if let Some(cap) = admission_capped {
map.insert("comparator_admission_capped".into(), to_value(cap));
}
map.insert("baseline".into(), Value::Null);
map.insert("ratios".into(), Value::Null);
}
ComparatorStatus::Measured(join) => {
map.insert(
"baseline".into(),
band_json(join.baseline(), &ctx.comparator, None),
);
map.insert("ratios".into(), to_value(join.ratios()));
}
}
}
fn is_sha256(value: &str) -> bool {
value.len() == 64
&& value
.bytes()
.all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Receipt {
pub spec: String,
pub schema_version: u32,
pub run_id: RunId,
pub commit: String,
pub workload: Workload,
pub protocol: ProtocolParams,
pub client_model: String,
pub provenance: Provenance,
pub tokenization: TokenizationBlock,
pub requested: usize,
pub completed: usize,
pub timeouts: usize,
pub truncated: usize,
pub errors: usize,
pub short_of_n_predict: usize,
pub drain_ms: f64,
pub n: usize,
pub samples_ms: Vec<f64>,
pub ladder: Ladder,
pub bands: Vec<ReceiptBand>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub kv: Option<KvBlock>,
pub unproduced_fields: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub signature: Option<serde_json::Value>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[allow(clippy::struct_excessive_bools)]
pub struct ReceiptBand {
pub concurrency: u32,
pub replicate: u32,
pub status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub aggregate_tok_per_sec: Option<f64>,
pub tokens_total: u64,
pub span_ms: f64,
pub window_ms: f64,
pub drain_ms: f64,
pub requested: usize,
pub completed: usize,
pub timeouts: usize,
pub truncated: usize,
pub errors: usize,
pub short_of_n_predict: usize,
pub suspect: Vec<String>,
pub stream_mode: Option<StreamMode>,
pub stream_witness: Option<StreamWitness>,
pub witness: Option<BatchInvarianceWitness>,
pub scaling_efficiency: Option<f64>,
pub overhead_share: Option<f64>,
pub roofline_tok_per_sec: Option<f64>,
pub samples_file: Option<SamplesFile>,
pub samples: Vec<SampleRow>,
pub join_key: Option<JoinKey>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub run_id: Option<RunId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub decode_tok_per_sec: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ttft_p50_ms: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ttft_p95_ms: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub itl_p50_ms: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub itl_p95_ms: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub prefill_tok_per_sec: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub prefill_source: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comparator_status: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comparator_owner: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comparator_decided_by: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comparator_reason: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comparator_budget: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub comparator_admission_capped: Option<AdmissionCap>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub baseline: Option<Box<ReceiptBand>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ratios: Option<BandRatios>,
}
impl Receipt {
pub fn parse(text: &str) -> Result<Self, String> {
serde_json::from_str(text).map_err(|e| format!("parsing receipt: {e}"))
}
pub fn validate(&self) -> Result<(), String> {
if self.spec != SPEC_ID {
return Err(format!(
"receipt.spec is {:?}, expected {SPEC_ID:?}",
self.spec
));
}
if self.schema_version != SCHEMA_VERSION {
return Err(format!(
"receipt.schema_version is {}, expected {SCHEMA_VERSION} — a receipt at another \
version is historical and is never a baseline (PP-4)",
self.schema_version
));
}
self.provenance.validate()?;
self.tokenization.validate()?;
if self.bands.is_empty() {
return Err(
"receipt has no bands — a measurement over zero bands is a vacuous \
pass"
.to_string(),
);
}
self.check_run_id()?;
for band in &self.bands {
band.validate()?;
}
Ok(())
}
fn check_run_id(&self) -> Result<(), String> {
let recomputed = RunId::derive(
&self.provenance.started_utc,
&self.provenance.host,
&self.provenance.client.sha256,
self.provenance.client.pid,
);
if recomputed == self.run_id {
return Ok(());
}
Err(format!(
"PP-3: run_id is {} but sha256(started_utc ‖ host ‖ client.sha256 ‖ client.pid)[..32] over this receipt's own provenance is {} — the id is DERIVED, and one that its own contents do not reproduce identifies nothing",
self.run_id.as_str(),
recomputed.as_str()
))
}
}
impl ReceiptBand {
pub fn validate(&self) -> Result<(), String> {
let known = BandStatus::vocabulary()
.iter()
.any(|s| s.wire_token() == self.status);
if !known {
return Err(format!(
"band c={}: status {:?} is outside the §7.4 vocabulary {:?}",
self.concurrency,
self.status,
BandStatus::vocabulary()
.iter()
.map(|s| s.wire_token())
.collect::<Vec<_>>()
));
}
if self.ratios.is_some() && self.baseline.is_none() {
return Err(format!(
"PP-3 band c={}: `ratios` without a `baseline` — a ratio is representable only \
against a baseline object that itself passes every receipt rule and shares the \
run_id",
self.concurrency
));
}
if let Some(baseline) = &self.baseline {
if baseline.baseline.is_some() || baseline.ratios.is_some() {
return Err(format!(
"PP-3 band c={}: the baseline carries its own baseline/ratios — a baseline is \
one comparator lane, not a chain of them",
self.concurrency
));
}
baseline.validate()?;
}
Ok(())
}
}
#[cfg(test)]
mod producer_tests {
use super::*;
use std::io::Write;
#[test]
fn compute_class_roundtrip_is_the_only_spelling() {
for c in [
ComputeClass::Cpu,
ComputeClass::Cuda,
ComputeClass::Metal,
ComputeClass::Wgpu,
ComputeClass::Unknown,
] {
assert_eq!(
ComputeClass::from_str(c.wire_token()).expect("wire token must parse"),
c
);
}
}
#[test]
fn the_wire_tokens_are_bench_receipt_pys_compute_classes() {
let tokens: Vec<&str> = ["cpu", "cuda", "metal", "wgpu", "unknown"].into();
for t in &tokens {
assert!(ComputeClass::from_str(t).is_ok(), "{t} must parse");
}
assert!(ComputeClass::from_str("tpu").is_err());
assert!(ComputeClass::from_str("gpu").is_err());
assert!(
ComputeClass::from_str("CUDA").is_err(),
"case is load-bearing"
);
}
#[test]
fn workload_roundtrips_and_refuses_anything_else() {
for w in [Workload::W1, Workload::W2] {
assert_eq!(Workload::from_str(w.wire_token()).expect("parses"), w);
}
assert!(Workload::from_str("W3").is_err());
assert!(Workload::from_str("w1").is_err());
}
#[test]
fn sha256_file_produces_a_digest_provenance_accepts() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("payload.bin");
let mut f = std::fs::File::create(&path).expect("create");
f.write_all(b"abc").expect("write");
drop(f);
let digest = sha256_file(&path).expect("hashes");
assert_eq!(
digest,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
);
assert_eq!(digest.len(), 64);
assert!(is_sha256(&digest), "must satisfy the receipt's own check");
}
#[test]
fn sha256_file_reports_a_missing_file_rather_than_a_digest() {
assert!(sha256_file(Path::new("/nonexistent/perf-025")).is_err());
}
#[test]
fn the_run_id_is_derived_from_the_receipts_own_contents() {
let a = RunId::derive("2026-09-02T10:11:12.345Z", "lambda", &"c".repeat(64), 4242);
let b = RunId::derive("2026-09-02T10:11:12.345Z", "lambda", &"c".repeat(64), 4242);
assert_eq!(a, b, "the same four facts give the same id");
assert_eq!(a.as_str().len(), 32);
assert!(a
.as_str()
.bytes()
.all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase()));
for changed in [
RunId::derive("2026-09-02T10:11:12.346Z", "lambda", &"c".repeat(64), 4242),
RunId::derive("2026-09-02T10:11:12.345Z", "gx10", &"c".repeat(64), 4242),
RunId::derive("2026-09-02T10:11:12.345Z", "lambda", &"d".repeat(64), 4242),
RunId::derive("2026-09-02T10:11:12.345Z", "lambda", &"c".repeat(64), 4243),
] {
assert_ne!(a, changed, "every input must move the id");
}
}
#[test]
fn a_malformed_run_id_is_refused() {
assert!(RunId::try_from("abc".to_string()).is_err());
assert!(RunId::try_from("A".repeat(32)).is_err(), "case matters");
assert!(RunId::try_from("z".repeat(32)).is_err(), "hex only");
assert!(RunId::try_from("a".repeat(33)).is_err());
assert!(RunId::try_from("a".repeat(32)).is_ok());
}
#[test]
fn started_utc_must_be_rfc3339_utc() {
assert!(validate_rfc3339_utc_millis("t", "2026-09-02T10:11:12.345Z").is_ok());
for bad in [
"",
"2026-09-02",
"2026-09-02T10:11:12Z",
"2026-09-02T10:11:12.345+00:00",
"2026-09-02t10:11:12.345Z",
"2026-09-02T10:11:12.3456Z",
"not-a-time-at-all-....Z",
] {
assert!(
validate_rfc3339_utc_millis("t", bad).is_err(),
"{bad:?} must be refused"
);
}
}
#[test]
fn canonical_timestamps_sort_chronologically() {
let mut times = vec![
"2026-12-01T00:00:00.000Z".to_string(),
"2026-09-02T10:11:12.345Z".to_string(),
"2026-09-02T10:11:12.344Z".to_string(),
"2025-01-01T00:00:00.000Z".to_string(),
];
times.sort();
assert_eq!(
times,
vec![
"2025-01-01T00:00:00.000Z",
"2026-09-02T10:11:12.344Z",
"2026-09-02T10:11:12.345Z",
"2026-12-01T00:00:00.000Z",
]
);
}
#[test]
fn ladder_derives_from_the_minimum_admission() {
let declared = [1_u32, 4, 8, 16];
let l = Ladder::derive(
&declared,
SlotsAdmitted {
apr: Some(11),
llama: Some(16),
},
);
assert_eq!(l.derived, vec![1, 4, 8], "c=16 exceeds the subject's 11");
assert!(!l.is_underived());
let other_way = Ladder::derive(
&declared,
SlotsAdmitted {
apr: Some(16),
llama: Some(4),
},
);
assert_eq!(other_way.derived, vec![1, 4], "the comparator caps too");
let one_lane = Ladder::derive(
&declared,
SlotsAdmitted {
apr: Some(8),
llama: None,
},
);
assert_eq!(one_lane.derived, vec![1, 4, 8]);
let blind = Ladder::derive(
&declared,
SlotsAdmitted {
apr: None,
llama: None,
},
);
assert_eq!(
blind.derived,
vec![1, 4, 8, 16],
"no evidence does not narrow the ladder"
);
assert!(blind.is_underived(), "…but it is named as unevidenced");
}
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn now_utc_millis_is_the_shape_the_validator_accepts() {
let now = now_utc_millis();
validate_rfc3339_utc_millis("now", &now)
.unwrap_or_else(|e| panic!("{now:?} must satisfy the receipt's own check: {e}"));
assert!(now.ends_with('Z'));
assert_eq!(now.len(), 24);
}
#[test]
fn the_roofline_is_bandwidth_over_model_bytes() {
let r = Roofline {
bandwidth_bytes_per_sec: 1_008_000_000_000.0,
model_bytes: 4_683_073_440,
};
let ceiling = r.tok_per_sec().expect("a sized model has a ceiling");
assert!((ceiling - 215.2).abs() < 0.1, "{ceiling}");
assert!(Roofline {
bandwidth_bytes_per_sec: 1.0,
model_bytes: 0
}
.tok_per_sec()
.is_none());
assert!(Roofline {
bandwidth_bytes_per_sec: 0.0,
model_bytes: 10
}
.tok_per_sec()
.is_none());
}
}