use std::collections::BTreeMap;
use std::fmt;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub const REGISTRY_SCHEMA_VERSION: &str = "1.1.0";
pub const READABLE_REGISTRY_SCHEMA_VERSIONS: &[&str] = &["1.0.0", "1.1.0"];
pub const RULES_VERSION: &str = "1.1.0";
pub const READABLE_RULES_VERSIONS: &[&str] = &["1.0.0", "1.1.0"];
#[derive(Debug, Error, PartialEq, Eq)]
pub enum RegistryError {
#[error("{vocabulary}: unknown token {token:?} (accepted: {accepted})")]
UnknownToken {
vocabulary: &'static str,
token: String,
accepted: String,
},
#[error(
"entry id {id:?} is not `<YYYY-MM-DD>-<slug>` with a lowercase alphanumeric slug: {reason}"
)]
EntryId {
id: String,
reason: &'static str,
},
#[error("digest {value:?} is not 64 lowercase hexadecimal characters")]
Digest {
value: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum EntryKind {
Conformance,
Bench,
}
impl EntryKind {
pub const ALL: &[EntryKind] = &[EntryKind::Conformance, EntryKind::Bench];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
EntryKind::Conformance => "conformance",
EntryKind::Bench => "bench",
}
}
pub fn parse(token: &str) -> Result<Self, RegistryError> {
parse_token("registry entry kind", token, Self::ALL, EntryKind::as_str)
}
}
impl fmt::Display for EntryKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Tier {
Reproduced,
Console,
SelfReported,
}
impl Tier {
pub const ALL: &[Tier] = &[Tier::Reproduced, Tier::Console, Tier::SelfReported];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Tier::Reproduced => "reproduced",
Tier::Console => "console",
Tier::SelfReported => "self-reported",
}
}
pub fn parse(token: &str) -> Result<Self, RegistryError> {
parse_token("registry tier", token, Self::ALL, Tier::as_str)
}
}
impl fmt::Display for Tier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Relationship {
Vendor,
Integrator,
Independent,
Maintainer,
}
impl Relationship {
pub const ALL: &[Relationship] = &[
Relationship::Vendor,
Relationship::Integrator,
Relationship::Independent,
Relationship::Maintainer,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Relationship::Vendor => "vendor",
Relationship::Integrator => "integrator",
Relationship::Independent => "independent",
Relationship::Maintainer => "maintainer",
}
}
pub fn parse(token: &str) -> Result<Self, RegistryError> {
parse_token(
"submitter relationship",
token,
Self::ALL,
Relationship::as_str,
)
}
}
impl fmt::Display for Relationship {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum DeploymentKind {
ReproducibleTopology,
ContainerImage,
HostedEndpoint,
LocalBuild,
}
impl DeploymentKind {
pub const ALL: &[DeploymentKind] = &[
DeploymentKind::ReproducibleTopology,
DeploymentKind::ContainerImage,
DeploymentKind::HostedEndpoint,
DeploymentKind::LocalBuild,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
DeploymentKind::ReproducibleTopology => "reproducible-topology",
DeploymentKind::ContainerImage => "container-image",
DeploymentKind::HostedEndpoint => "hosted-endpoint",
DeploymentKind::LocalBuild => "local-build",
}
}
pub fn parse(token: &str) -> Result<Self, RegistryError> {
parse_token("deployment kind", token, Self::ALL, DeploymentKind::as_str)
}
}
impl fmt::Display for DeploymentKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ArtifactRole {
Results,
Verdicts,
Transcript,
BenchResult,
RecordManifest,
Signature,
Report,
Ixit,
Statement,
}
impl ArtifactRole {
pub const ALL: &[ArtifactRole] = &[
ArtifactRole::Results,
ArtifactRole::Verdicts,
ArtifactRole::Transcript,
ArtifactRole::BenchResult,
ArtifactRole::RecordManifest,
ArtifactRole::Signature,
ArtifactRole::Report,
ArtifactRole::Ixit,
ArtifactRole::Statement,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
ArtifactRole::Results => "results",
ArtifactRole::Verdicts => "verdicts",
ArtifactRole::Transcript => "transcript",
ArtifactRole::BenchResult => "bench-result",
ArtifactRole::RecordManifest => "record-manifest",
ArtifactRole::Signature => "signature",
ArtifactRole::Report => "report",
ArtifactRole::Ixit => "ixit",
ArtifactRole::Statement => "statement",
}
}
#[must_use]
pub const fn required_for(kind: EntryKind) -> &'static [ArtifactRole] {
match kind {
EntryKind::Conformance => &[ArtifactRole::Results, ArtifactRole::Verdicts],
EntryKind::Bench => &[ArtifactRole::BenchResult],
}
}
pub fn parse(token: &str) -> Result<Self, RegistryError> {
parse_token("artifact role", token, Self::ALL, ArtifactRole::as_str)
}
}
impl fmt::Display for ArtifactRole {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum SignatureScheme {
OpenpgpDetached,
SigstoreBundle,
}
impl SignatureScheme {
pub const ALL: &[SignatureScheme] = &[
SignatureScheme::OpenpgpDetached,
SignatureScheme::SigstoreBundle,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
SignatureScheme::OpenpgpDetached => "openpgp-detached",
SignatureScheme::SigstoreBundle => "sigstore-bundle",
}
}
pub fn parse(token: &str) -> Result<Self, RegistryError> {
parse_token(
"signature scheme",
token,
Self::ALL,
SignatureScheme::as_str,
)
}
}
impl fmt::Display for SignatureScheme {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
fn parse_token<T: Copy>(
vocabulary: &'static str,
token: &str,
all: &'static [T],
render: fn(T) -> &'static str,
) -> Result<T, RegistryError> {
all.iter()
.copied()
.find(|candidate| render(*candidate) == token)
.ok_or_else(|| RegistryError::UnknownToken {
vocabulary,
token: token.to_owned(),
accepted: all
.iter()
.copied()
.map(render)
.collect::<Vec<_>>()
.join(", "),
})
}
const DATE_LEN: usize = "YYYY-MM-DD".len();
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
pub struct EntryId(String);
impl EntryId {
pub fn parse(id: &str) -> Result<Self, RegistryError> {
let refuse = |reason: &'static str| RegistryError::EntryId {
id: id.to_owned(),
reason,
};
let (date, slug) = id
.split_at_checked(DATE_LEN)
.ok_or_else(|| refuse("it is shorter than a calendar date"))?;
if !is_calendar_date(date) {
return Err(refuse("it does not open with a YYYY-MM-DD date"));
}
let slug = slug
.strip_prefix('-')
.ok_or_else(|| refuse("no `-` separates the date from the slug"))?;
if slug.is_empty() {
return Err(refuse("the slug is empty"));
}
if !slug
.chars()
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-')
{
return Err(refuse("the slug carries something other than [a-z0-9-]"));
}
if slug.starts_with('-') || slug.ends_with('-') {
return Err(refuse("the slug opens or closes on a `-`"));
}
Ok(Self(id.to_owned()))
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
#[must_use]
pub fn date(&self) -> &str {
self.0.get(..DATE_LEN).unwrap_or_default()
}
}
impl TryFrom<String> for EntryId {
type Error = RegistryError;
fn try_from(value: String) -> Result<Self, Self::Error> {
Self::parse(&value)
}
}
impl From<EntryId> for String {
fn from(value: EntryId) -> Self {
value.0
}
}
impl fmt::Display for EntryId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
fn is_calendar_date(text: &str) -> bool {
text.len() == DATE_LEN
&& text.chars().enumerate().all(|(position, c)| {
if position == 4 || position == 7 {
c == '-'
} else {
c.is_ascii_digit()
}
})
}
const DIGEST_LEN: usize = 64;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
pub struct Digest(String);
impl Digest {
pub fn parse(value: &str) -> Result<Self, RegistryError> {
if value.len() == DIGEST_LEN
&& value
.chars()
.all(|c| c.is_ascii_digit() || ('a'..='f').contains(&c))
{
Ok(Self(value.to_owned()))
} else {
Err(RegistryError::Digest {
value: value.to_owned(),
})
}
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl TryFrom<String> for Digest {
type Error = RegistryError;
fn try_from(value: String) -> Result<Self, Self::Error> {
Self::parse(&value)
}
}
impl From<Digest> for String {
fn from(value: Digest) -> Self {
value.0
}
}
impl fmt::Display for Digest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Submitter {
pub name: String,
pub contact: String,
pub relationship: Relationship,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Deployment {
pub kind: DeploymentKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub topology: Option<String>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub images: BTreeMap<String, String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub endpoint: Option<String>,
pub reproduction_authorized: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Subject {
pub system: String,
pub display_name: String,
pub version: String,
pub deployment: Deployment,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EnvironmentDisclosure {
pub os: String,
pub arch: String,
pub host_class: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cpu_model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cores: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory_bytes: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Disclosure {
pub instrument_version: String,
pub run_started_at: String,
pub environment: EnvironmentDisclosure,
pub sut_configuration: String,
pub conflict_of_interest: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum ResultBlock {
Conformance {
catalogue_revision: String,
statement: String,
},
Bench {
pack_id: String,
pack_version: String,
repetitions: u32,
posture_profile: String,
},
}
impl ResultBlock {
#[must_use]
pub const fn kind(&self) -> EntryKind {
match self {
ResultBlock::Conformance { .. } => EntryKind::Conformance,
ResultBlock::Bench { .. } => EntryKind::Bench,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ArtifactRef {
pub role: ArtifactRole,
pub path: String,
pub sha256: Digest,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "tier", rename_all = "kebab-case")]
pub enum Provenance {
Reproduced {
workflow_ref: String,
run_id: String,
run_attempt: u32,
predicate_type: String,
verify_command: String,
},
Console {
instrument_origin: String,
console_run_id: String,
workflow_ref: String,
run_id: String,
run_attempt: u32,
scheme: SignatureScheme,
signature: String,
signs: String,
identity: String,
verify_command: String,
},
SelfReported {
scheme: SignatureScheme,
signature: String,
signs: String,
identity: String,
verify_command: String,
},
}
impl Provenance {
#[must_use]
pub const fn tier(&self) -> Tier {
match self {
Provenance::Reproduced { .. } => Tier::Reproduced,
Provenance::Console { .. } => Tier::Console,
Provenance::SelfReported { .. } => Tier::SelfReported,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RegistryEntry {
pub registry_schema_version: String,
pub entry_id: EntryId,
pub rules_version: String,
pub submitter: Submitter,
pub subject: Subject,
pub disclosure: Disclosure,
pub result: ResultBlock,
pub artifacts: Vec<ArtifactRef>,
pub provenance: Provenance,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub supersedes: Vec<EntryId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub supersede_reason: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
}
impl RegistryEntry {
#[must_use]
pub const fn kind(&self) -> EntryKind {
self.result.kind()
}
#[must_use]
pub const fn tier(&self) -> Tier {
self.provenance.tier()
}
#[must_use]
pub fn expected_path(&self) -> String {
format!(
"registry/entries/{}/{}/{}.json",
self.kind(),
self.subject.system,
self.entry_id
)
}
#[must_use]
pub fn artifact(&self, role: ArtifactRole) -> Option<&ArtifactRef> {
let mut matching = self.artifacts.iter().filter(|a| a.role == role);
let first = matching.next()?;
matching.next().is_none().then_some(first)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EntryDefect {
SchemaVersion {
declared: String,
},
RulesVersion {
declared: String,
},
EmptyField {
field: &'static str,
},
Timestamp {
value: String,
},
DateMismatch {
id_date: String,
run_date: String,
},
MissingArtifact {
role: ArtifactRole,
kind: EntryKind,
},
DuplicateArtifact {
path: String,
},
UnsafeArtifactPath {
path: String,
},
MisplacedBenchRecord {
path: String,
},
MisplacedRecord {
path: String,
expected_prefix: String,
},
UnsignedArtifact {
path: String,
},
UndeclaredSignature {
path: String,
},
ForeignWorkflow {
workflow_ref: String,
},
UnreproducibleDeployment {
kind: DeploymentKind,
},
UndrivableDeployment {
kind: DeploymentKind,
},
MissingTopology,
SelfSupersede,
DuplicateSupersede {
id: EntryId,
},
UnexplainedSupersede,
}
fn version_set(versions: &[&str]) -> String {
versions.join(", ")
}
impl fmt::Display for EntryDefect {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EntryDefect::SchemaVersion { declared } => write!(
f,
"the entry declares registry format {declared:?}, and this release reads {}",
version_set(READABLE_REGISTRY_SCHEMA_VERSIONS)
),
EntryDefect::RulesVersion { declared } => write!(
f,
"the entry declares rules version {declared:?}, and this release accepts {}",
version_set(READABLE_RULES_VERSIONS)
),
EntryDefect::EmptyField { field } => {
write!(f, "{field} is empty, and the disclosure is mandatory")
}
EntryDefect::Timestamp { value } => write!(
f,
"run_started_at {value:?} is not an RFC 3339 timestamp in UTC"
),
EntryDefect::DateMismatch { id_date, run_date } => write!(
f,
"the entry id opens on {id_date} and the run started on {run_date}"
),
EntryDefect::MissingArtifact { role, kind } => write!(
f,
"a {kind} entry carries exactly one `{role}` artifact, and this one carries none \
or several"
),
EntryDefect::DuplicateArtifact { path } => {
write!(f, "{path} is declared as an artifact twice")
}
EntryDefect::UnsafeArtifactPath { path } => write!(
f,
"{path:?} is not a plain repository-relative path (no leading `/`, no `..`, no \
backslash)"
),
EntryDefect::MisplacedBenchRecord { path } => write!(
f,
"{path} is outside benchmarks/submissions/, which is the tree the benchmark board \
renders from"
),
EntryDefect::MisplacedRecord {
path,
expected_prefix,
} => write!(f, "{path} is outside {expected_prefix}"),
EntryDefect::UnsignedArtifact { path } => write!(
f,
"the signature covers {path}, which the entry does not carry as an artifact"
),
EntryDefect::UndeclaredSignature { path } => write!(
f,
"the signature {path} is not declared as a `signature` artifact, so nothing pins \
its bytes"
),
EntryDefect::ForeignWorkflow { workflow_ref } => write!(
f,
"the reproduced tier is issued by this repository's own workflow, and \
{workflow_ref:?} is not one"
),
EntryDefect::UnreproducibleDeployment { kind } => write!(
f,
"the reproduced tier requires a deployment this repository composes itself, and \
this entry declares {kind}"
),
EntryDefect::UndrivableDeployment { kind } => write!(
f,
"the console tier is a run the hosted instrument drove against an endpoint the \
submitter named, and this entry declares {kind}"
),
EntryDefect::MissingTopology => f.write_str(
"the deployment is a reproducible topology and names none, so no recipe stands \
behind it",
),
EntryDefect::SelfSupersede => f.write_str("the entry supersedes itself"),
EntryDefect::DuplicateSupersede { id } => {
write!(f, "{id} is superseded twice by one entry")
}
EntryDefect::UnexplainedSupersede => f.write_str(
"an entry that supersedes another states why, because the superseded one stays \
published",
),
}
}
}
const OWN_WORKFLOW_PREFIX: &str = "rubentalstra/Veredictum/.github/workflows/";
const BENCH_SUBMISSIONS: &str = "benchmarks/submissions/";
#[must_use]
pub fn entry_defects(entry: &RegistryEntry) -> Vec<EntryDefect> {
let mut defects = Vec::new();
if !READABLE_REGISTRY_SCHEMA_VERSIONS.contains(&entry.registry_schema_version.as_str()) {
defects.push(EntryDefect::SchemaVersion {
declared: entry.registry_schema_version.clone(),
});
}
if !READABLE_RULES_VERSIONS.contains(&entry.rules_version.as_str()) {
defects.push(EntryDefect::RulesVersion {
declared: entry.rules_version.clone(),
});
}
defects.extend(empty_field_defects(entry));
defects.extend(timestamp_defects(entry));
defects.extend(artifact_defects(entry));
defects.extend(provenance_defects(entry));
defects.extend(supersede_defects(entry));
defects
}
fn empty_field_defects(entry: &RegistryEntry) -> Vec<EntryDefect> {
let mandatory: [(&'static str, &str); 9] = [
("submitter.name", &entry.submitter.name),
("submitter.contact", &entry.submitter.contact),
("subject.system", &entry.subject.system),
("subject.display_name", &entry.subject.display_name),
("subject.version", &entry.subject.version),
(
"disclosure.instrument_version",
&entry.disclosure.instrument_version,
),
(
"disclosure.environment.host_class",
&entry.disclosure.environment.host_class,
),
(
"disclosure.sut_configuration",
&entry.disclosure.sut_configuration,
),
(
"disclosure.conflict_of_interest",
&entry.disclosure.conflict_of_interest,
),
];
mandatory
.into_iter()
.filter(|(_, value)| value.trim().is_empty())
.map(|(field, _)| EntryDefect::EmptyField { field })
.collect()
}
fn timestamp_defects(entry: &RegistryEntry) -> Vec<EntryDefect> {
let stamp = &entry.disclosure.run_started_at;
let Some((date, _)) = stamp.split_once('T') else {
return vec![EntryDefect::Timestamp {
value: stamp.clone(),
}];
};
if !stamp.ends_with('Z') || stamp.parse::<jiff::Timestamp>().is_err() {
return vec![EntryDefect::Timestamp {
value: stamp.clone(),
}];
}
if date == entry.entry_id.date() {
Vec::new()
} else {
vec![EntryDefect::DateMismatch {
id_date: entry.entry_id.date().to_owned(),
run_date: date.to_owned(),
}]
}
}
fn artifact_defects(entry: &RegistryEntry) -> Vec<EntryDefect> {
let kind = entry.kind();
let mut defects: Vec<EntryDefect> = ArtifactRole::required_for(kind)
.iter()
.copied()
.filter(|role| entry.artifact(*role).is_none())
.map(|role| EntryDefect::MissingArtifact { role, kind })
.collect();
let mut seen: Vec<&str> = Vec::new();
let record_prefix = format!(
"registry/records/{}/{}/",
entry.subject.system, entry.entry_id
);
for artifact in &entry.artifacts {
let path = artifact.path.as_str();
if seen.contains(&path) {
defects.push(EntryDefect::DuplicateArtifact {
path: path.to_owned(),
});
} else {
seen.push(path);
}
if !is_plain_relative_path(path) {
defects.push(EntryDefect::UnsafeArtifactPath {
path: path.to_owned(),
});
continue;
}
if artifact.role == ArtifactRole::BenchResult {
if !path.starts_with(BENCH_SUBMISSIONS) {
defects.push(EntryDefect::MisplacedBenchRecord {
path: path.to_owned(),
});
}
} else if !path.starts_with(&record_prefix) {
defects.push(EntryDefect::MisplacedRecord {
path: path.to_owned(),
expected_prefix: record_prefix.clone(),
});
}
}
defects
}
fn is_plain_relative_path(path: &str) -> bool {
!path.is_empty()
&& !path.starts_with('/')
&& !path.contains('\\')
&& !path.split('/').any(|segment| {
segment.is_empty() || segment == "." || segment == ".." || segment.starts_with(' ')
})
}
fn provenance_defects(entry: &RegistryEntry) -> Vec<EntryDefect> {
let mut defects = Vec::new();
match &entry.provenance {
Provenance::Reproduced { workflow_ref, .. } => {
if !workflow_ref.starts_with(OWN_WORKFLOW_PREFIX) {
defects.push(EntryDefect::ForeignWorkflow {
workflow_ref: workflow_ref.clone(),
});
}
if entry.subject.deployment.kind != DeploymentKind::ReproducibleTopology {
defects.push(EntryDefect::UnreproducibleDeployment {
kind: entry.subject.deployment.kind,
});
}
}
Provenance::Console {
instrument_origin,
console_run_id,
workflow_ref,
signature,
signs,
..
} => {
if instrument_origin.trim().is_empty() {
defects.push(EntryDefect::EmptyField {
field: "provenance.instrument_origin",
});
}
if console_run_id.trim().is_empty() {
defects.push(EntryDefect::EmptyField {
field: "provenance.console_run_id",
});
}
if !workflow_ref.starts_with(OWN_WORKFLOW_PREFIX) {
defects.push(EntryDefect::ForeignWorkflow {
workflow_ref: workflow_ref.clone(),
});
}
if entry.subject.deployment.kind != DeploymentKind::HostedEndpoint {
defects.push(EntryDefect::UndrivableDeployment {
kind: entry.subject.deployment.kind,
});
}
let kind = entry.kind();
for role in [
ArtifactRole::Transcript,
ArtifactRole::Ixit,
ArtifactRole::Statement,
] {
if entry.artifact(role).is_none() {
defects.push(EntryDefect::MissingArtifact { role, kind });
}
}
defects.extend(signature_defects(entry, signature, signs));
}
Provenance::SelfReported {
signature, signs, ..
} => defects.extend(signature_defects(entry, signature, signs)),
}
if entry.subject.deployment.kind == DeploymentKind::ReproducibleTopology
&& entry.subject.deployment.topology.is_none()
{
defects.push(EntryDefect::MissingTopology);
}
defects
}
fn signature_defects(entry: &RegistryEntry, signature: &str, signs: &str) -> Vec<EntryDefect> {
let mut defects = Vec::new();
if !entry
.artifacts
.iter()
.any(|artifact| artifact.path == signs)
{
defects.push(EntryDefect::UnsignedArtifact {
path: signs.to_owned(),
});
}
if !entry
.artifacts
.iter()
.any(|artifact| artifact.role == ArtifactRole::Signature && artifact.path == signature)
{
defects.push(EntryDefect::UndeclaredSignature {
path: signature.to_owned(),
});
}
defects
}
fn supersede_defects(entry: &RegistryEntry) -> Vec<EntryDefect> {
let mut defects = Vec::new();
let mut seen: Vec<&EntryId> = Vec::new();
for superseded in &entry.supersedes {
if *superseded == entry.entry_id {
defects.push(EntryDefect::SelfSupersede);
}
if seen.contains(&superseded) {
defects.push(EntryDefect::DuplicateSupersede {
id: superseded.clone(),
});
} else {
seen.push(superseded);
}
}
if !entry.supersedes.is_empty()
&& entry
.supersede_reason
.as_ref()
.is_none_or(|reason| reason.trim().is_empty())
{
defects.push(EntryDefect::UnexplainedSupersede);
}
defects
}
#[cfg(test)]
#[expect(
clippy::panic_in_result_fn,
reason = "the Book's Result-test shape: assertions panic, plumbing propagates with `?`"
)]
mod tests {
use super::*;
fn bench_entry() -> RegistryEntry {
RegistryEntry {
registry_schema_version: REGISTRY_SCHEMA_VERSION.to_owned(),
entry_id: EntryId(String::from("2026-01-02-example-cdr")),
rules_version: RULES_VERSION.to_owned(),
submitter: Submitter {
name: String::from("Example Health"),
contact: String::from("https://github.com/example"),
relationship: Relationship::Vendor,
},
subject: Subject {
system: String::from("example"),
display_name: String::from("Example CDR"),
version: String::from("1.2.3"),
deployment: Deployment {
kind: DeploymentKind::ContainerImage,
topology: None,
images: BTreeMap::new(),
endpoint: None,
reproduction_authorized: false,
},
},
disclosure: Disclosure {
instrument_version: String::from("0.1.1"),
run_started_at: String::from("2026-01-02T03:04:05Z"),
environment: EnvironmentDisclosure {
os: String::from("linux"),
arch: String::from("x86_64"),
host_class: String::from("bare metal, 8 cores"),
cpu_model: None,
cores: Some(8),
memory_bytes: None,
},
sut_configuration: String::from("basic auth, template validation, no audit"),
conflict_of_interest: String::from("the submitter builds the system"),
},
result: ResultBlock::Bench {
pack_id: String::from("community-vitals"),
pack_version: String::from("1.0.0"),
repetitions: 3,
posture_profile: String::from("minimal"),
},
artifacts: vec![
ArtifactRef {
role: ArtifactRole::BenchResult,
path: String::from("benchmarks/submissions/example/2026-01-02-aaaaaaaa.json"),
sha256: Digest("a".repeat(DIGEST_LEN)),
},
ArtifactRef {
role: ArtifactRole::Signature,
path: String::from(
"registry/records/example/2026-01-02-example-cdr/bench-result.json.asc",
),
sha256: Digest("b".repeat(DIGEST_LEN)),
},
],
provenance: Provenance::SelfReported {
scheme: SignatureScheme::OpenpgpDetached,
signature: String::from(
"registry/records/example/2026-01-02-example-cdr/bench-result.json.asc",
),
signs: String::from("benchmarks/submissions/example/2026-01-02-aaaaaaaa.json"),
identity: String::from("0123456789ABCDEF"),
verify_command: String::from("gpg --verify bench-result.json.asc"),
},
supersedes: Vec::new(),
supersede_reason: None,
notes: None,
}
}
fn console_entry() -> RegistryEntry {
const RECORD: &str = "registry/records/example/2026-01-02-example-cdr/";
let mut entry = bench_entry();
entry.subject.deployment.kind = DeploymentKind::HostedEndpoint;
entry.subject.deployment.endpoint = Some(String::from("https://cdr.example/openehr/v1"));
entry.result = ResultBlock::Conformance {
catalogue_revision: String::from("0.1.4"),
statement: String::from("party/example/statement.json"),
};
entry.artifacts = vec![
ArtifactRef {
role: ArtifactRole::Results,
path: format!("{RECORD}results.json"),
sha256: Digest("a".repeat(DIGEST_LEN)),
},
ArtifactRef {
role: ArtifactRole::Verdicts,
path: format!("{RECORD}verdicts.json"),
sha256: Digest("b".repeat(DIGEST_LEN)),
},
ArtifactRef {
role: ArtifactRole::Transcript,
path: format!("{RECORD}transcript.json"),
sha256: Digest("c".repeat(DIGEST_LEN)),
},
ArtifactRef {
role: ArtifactRole::Ixit,
path: format!("{RECORD}ixit.json"),
sha256: Digest("e".repeat(DIGEST_LEN)),
},
ArtifactRef {
role: ArtifactRole::Statement,
path: format!("{RECORD}statement.json"),
sha256: Digest("f".repeat(DIGEST_LEN)),
},
ArtifactRef {
role: ArtifactRole::Signature,
path: format!("{RECORD}verdicts.json.asc"),
sha256: Digest("d".repeat(DIGEST_LEN)),
},
];
entry.provenance = Provenance::Console {
instrument_origin: String::from("https://console.veredictum.eu"),
console_run_id: String::from("018f3b1e-6f0a-7c21-9a3d-6c2f5d4b8e77"),
workflow_ref: String::from(
"rubentalstra/Veredictum/.github/workflows/registry-console.yml@refs/heads/main",
),
run_id: String::from("33306498731"),
run_attempt: 1,
scheme: SignatureScheme::OpenpgpDetached,
signature: format!("{RECORD}verdicts.json.asc"),
signs: format!("{RECORD}verdicts.json"),
identity: String::from("0123456789ABCDEF"),
verify_command: String::from("veredictum verify-record --record ."),
};
entry
}
#[test]
fn the_publishable_fixture_carries_no_defect() {
assert_eq!(entry_defects(&bench_entry()), Vec::new());
}
#[test]
fn the_version_a_new_entry_declares_is_itself_readable() {
assert!(
READABLE_REGISTRY_SCHEMA_VERSIONS.contains(®ISTRY_SCHEMA_VERSION),
"{READABLE_REGISTRY_SCHEMA_VERSIONS:?} must carry {REGISTRY_SCHEMA_VERSION}"
);
assert!(
READABLE_RULES_VERSIONS.contains(&RULES_VERSION),
"{READABLE_RULES_VERSIONS:?} must carry {RULES_VERSION}"
);
let entry = bench_entry();
assert_eq!(entry.registry_schema_version, REGISTRY_SCHEMA_VERSION);
assert_eq!(entry.rules_version, RULES_VERSION);
assert_eq!(entry_defects(&entry), Vec::new());
}
#[test]
fn an_entry_at_an_earlier_readable_version_carries_no_version_defect() {
let mut entry = bench_entry();
entry.registry_schema_version = String::from("1.0.0");
entry.rules_version = String::from("1.0.0");
assert_eq!(entry_defects(&entry), Vec::new());
}
#[test]
fn an_entry_at_an_unreadable_format_version_is_refused() {
let mut entry = bench_entry();
entry.registry_schema_version = String::from("0.9.0");
let defects = entry_defects(&entry);
assert_eq!(
defects,
vec![EntryDefect::SchemaVersion {
declared: String::from("0.9.0")
}],
"an unreadable format version is the one defect, and rules_version is unaffected"
);
let rendered = defects
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join("; ");
for readable in READABLE_REGISTRY_SCHEMA_VERSIONS {
assert!(
rendered.contains(readable),
"{rendered:?} must name the accepted version {readable}"
);
}
}
#[test]
fn an_entry_at_an_unaccepted_rules_version_is_refused() {
let mut entry = bench_entry();
entry.rules_version = String::from("0.9.0");
let defects = entry_defects(&entry);
assert_eq!(
defects,
vec![EntryDefect::RulesVersion {
declared: String::from("0.9.0")
}],
"an unaccepted rules version is the one defect, and the format version is unaffected"
);
let rendered = defects
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join("; ");
for readable in READABLE_RULES_VERSIONS {
assert!(
rendered.contains(readable),
"{rendered:?} must name the accepted version {readable}"
);
}
}
#[test]
fn a_console_entry_missing_its_re_derivation_inputs_is_refused() {
let mut entry = console_entry();
entry
.artifacts
.retain(|artifact| artifact.role != ArtifactRole::Transcript);
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::MissingArtifact {
role: ArtifactRole::Transcript,
kind: EntryKind::Conformance
}),
"{defects:?}"
);
}
#[test]
fn a_completed_console_entry_carries_no_defect() {
assert_eq!(entry_defects(&console_entry()), Vec::new());
}
#[test]
fn a_console_entry_naming_a_foreign_workflow_is_refused() {
let mut entry = console_entry();
let foreign = String::from("example/ci/.github/workflows/sign.yml@refs/heads/main");
if let Provenance::Console { workflow_ref, .. } = &mut entry.provenance {
*workflow_ref = foreign.clone();
}
assert!(
entry_defects(&entry).contains(&EntryDefect::ForeignWorkflow {
workflow_ref: foreign
}),
"a foreign re-derivation workflow must be refused"
);
}
#[test]
fn a_console_entry_over_a_deployment_the_instrument_cannot_reach_is_refused() {
let mut entry = console_entry();
entry.subject.deployment.kind = DeploymentKind::LocalBuild;
assert!(
entry_defects(&entry).contains(&EntryDefect::UndrivableDeployment {
kind: DeploymentKind::LocalBuild
}),
"a console entry over a local build must be refused"
);
}
#[test]
fn a_console_entry_whose_signature_is_not_pinned_is_refused() {
let mut entry = console_entry();
entry
.artifacts
.retain(|artifact| artifact.role != ArtifactRole::Signature);
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::UndeclaredSignature {
path: String::from(
"registry/records/example/2026-01-02-example-cdr/verdicts.json.asc"
)
}),
"{defects:?}"
);
}
#[test]
fn a_console_entry_missing_its_instrument_facts_is_refused() {
let mut entry = console_entry();
if let Provenance::Console {
instrument_origin,
console_run_id,
..
} = &mut entry.provenance
{
instrument_origin.clear();
console_run_id.clear();
}
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::EmptyField {
field: "provenance.instrument_origin"
}) && defects.contains(&EntryDefect::EmptyField {
field: "provenance.console_run_id"
}),
"{defects:?}"
);
}
#[test]
fn an_entry_id_states_a_date_then_a_lowercase_slug() {
assert!(EntryId::parse("2026-01-02-example-cdr").is_ok());
assert!(EntryId::parse("2026-01-02").is_err());
assert!(EntryId::parse("2026-01-02-Example").is_err());
assert!(EntryId::parse("20260102-example").is_err());
assert!(EntryId::parse("2026-01-02-").is_err());
assert!(EntryId::parse("2026-01-02-a-").is_err());
}
#[test]
fn a_digest_is_sixty_four_lowercase_hex_characters() {
assert!(Digest::parse(&"a".repeat(DIGEST_LEN)).is_ok());
assert!(Digest::parse(&"A".repeat(DIGEST_LEN)).is_err());
assert!(Digest::parse(&"a".repeat(DIGEST_LEN - 1)).is_err());
assert!(Digest::parse(&"g".repeat(DIGEST_LEN)).is_err());
}
#[test]
fn every_closed_vocabulary_refuses_an_unknown_token() {
assert!(EntryKind::parse("perf").is_err());
assert!(Tier::parse("verified").is_err());
assert!(Relationship::parse("partner").is_err());
assert!(DeploymentKind::parse("kubernetes").is_err());
assert!(ArtifactRole::parse("summary").is_err());
assert!(SignatureScheme::parse("ssh").is_err());
}
#[test]
fn an_empty_disclosure_field_is_named() {
let mut entry = bench_entry();
entry.disclosure.conflict_of_interest = String::from(" ");
assert_eq!(
entry_defects(&entry),
vec![EntryDefect::EmptyField {
field: "disclosure.conflict_of_interest"
}]
);
}
#[test]
fn a_run_date_that_disagrees_with_the_id_is_refused() {
let mut entry = bench_entry();
entry.disclosure.run_started_at = String::from("2026-01-03T00:00:00Z");
assert_eq!(
entry_defects(&entry),
vec![EntryDefect::DateMismatch {
id_date: String::from("2026-01-02"),
run_date: String::from("2026-01-03"),
}]
);
}
#[test]
fn a_timestamp_outside_utc_is_refused() {
let mut entry = bench_entry();
entry.disclosure.run_started_at = String::from("2026-01-02T03:04:05+02:00");
assert_eq!(
entry_defects(&entry),
vec![EntryDefect::Timestamp {
value: String::from("2026-01-02T03:04:05+02:00")
}]
);
}
#[test]
fn a_conformance_entry_without_verdicts_is_refused() {
let mut entry = bench_entry();
entry.result = ResultBlock::Conformance {
catalogue_revision: String::from("4cee001c"),
statement: String::from("party/example/statement.json"),
};
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::MissingArtifact {
role: ArtifactRole::Verdicts,
kind: EntryKind::Conformance,
}),
"{defects:?}"
);
assert!(
defects.contains(&EntryDefect::MissingArtifact {
role: ArtifactRole::Results,
kind: EntryKind::Conformance,
}),
"{defects:?}"
);
}
#[test]
fn an_artifact_path_that_escapes_the_repository_is_refused() {
let mut entry = bench_entry();
if let Some(artifact) = entry.artifacts.first_mut() {
artifact.path = String::from("../../etc/passwd");
}
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::UnsafeArtifactPath {
path: String::from("../../etc/passwd")
}),
"{defects:?}"
);
}
#[test]
fn a_bench_record_outside_the_submissions_tree_is_refused() {
let mut entry = bench_entry();
let moved = String::from("registry/records/example/2026-01-02-example-cdr/bench.json");
if let Some(artifact) = entry.artifacts.first_mut() {
artifact.path = moved.clone();
}
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::MisplacedBenchRecord { path: moved }),
"{defects:?}"
);
}
#[test]
fn a_signature_over_something_the_entry_does_not_carry_is_refused() {
let mut entry = bench_entry();
entry.provenance = Provenance::SelfReported {
scheme: SignatureScheme::OpenpgpDetached,
signature: String::from(
"registry/records/example/2026-01-02-example-cdr/bench-result.json.asc",
),
signs: String::from("benchmarks/submissions/example/somebody-elses.json"),
identity: String::from("0123456789ABCDEF"),
verify_command: String::from("gpg --verify bench-result.json.asc"),
};
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::UnsignedArtifact {
path: String::from("benchmarks/submissions/example/somebody-elses.json")
}),
"{defects:?}"
);
}
#[test]
fn a_self_declared_reproduced_tier_is_refused() {
let mut entry = bench_entry();
entry.provenance = Provenance::Reproduced {
workflow_ref: String::from("example/ci/.github/workflows/bench.yml@refs/heads/main"),
run_id: String::from("1"),
run_attempt: 1,
predicate_type: String::from("https://slsa.dev/provenance/v1"),
verify_command: String::from("gh attestation verify"),
};
let defects = entry_defects(&entry);
assert!(
defects.contains(&EntryDefect::ForeignWorkflow {
workflow_ref: String::from(
"example/ci/.github/workflows/bench.yml@refs/heads/main"
)
}),
"{defects:?}"
);
assert!(
defects.contains(&EntryDefect::UnreproducibleDeployment {
kind: DeploymentKind::ContainerImage
}),
"{defects:?}"
);
}
#[test]
fn a_supersede_without_a_reason_is_refused() {
let mut entry = bench_entry();
entry.supersedes = vec![EntryId(String::from("2025-12-01-example-cdr"))];
assert_eq!(
entry_defects(&entry),
vec![EntryDefect::UnexplainedSupersede]
);
}
#[test]
fn an_entry_that_supersedes_itself_is_refused() {
let mut entry = bench_entry();
entry.supersedes = vec![entry.entry_id.clone()];
entry.supersede_reason = Some(String::from("a correction"));
assert_eq!(entry_defects(&entry), vec![EntryDefect::SelfSupersede]);
}
#[test]
fn an_entry_round_trips_through_its_own_serialization() -> Result<(), Box<dyn std::error::Error>>
{
let entry = bench_entry();
let rendered = serde_json::to_string(&entry)?;
let parsed: RegistryEntry = serde_json::from_str(&rendered)?;
assert_eq!(parsed, entry);
assert_eq!(parsed.kind(), EntryKind::Bench);
assert_eq!(parsed.tier(), Tier::SelfReported);
assert_eq!(
parsed.expected_path(),
"registry/entries/bench/example/2026-01-02-example-cdr.json"
);
Ok(())
}
}