open-standards/wai/wai-rs/src/codecs/registry.rs
Transaction Science 454d3865a7
Some checks failed
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
wai-quantum studio and desktop / does this change touch it (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI conformance / does this change touch it (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
wai: shared lists name their tables instead of enumerating every record
Every slice extended the same sentences: SPEC's and REGISTRY's record bullet,
registry.rs's wire-identifier comment, the workflow's verifier comment, the
live-conformance exclusion reason and the live-conformance README's provenance
sentence. Each PR then conflicted with every other in prose that a merge has to
rewrite by hand. Each now points at the table that lists the entries (REGISTRY's
table, kind record; live-conformance/README.md's table, which gains a generator
column), so a new slice adds a row and edits no sentence.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 19:14:21 -04:00

1924 lines
99 KiB
Rust

//! The registry as one table: every string SPEC §5 registers, with its kind, its
//! registration status, its media class, the section of SPEC that registers it,
//! the edition it carries and the date it was registered — and the named
//! identifiers and unregistered labels that look like capability strings but are
//! not capabilities.
//!
//! This module is unconditional (no feature gate), so every build of the crate
//! sees the same registry, and `wai registry export` writes the same files from
//! every build. The export ([`export_files`]) is the machine-readable registry:
//! `wai/registry/capabilities.json`, its JSON Schema, the generated vocabulary
//! `wai/vocab/v2.*`, and the generated table in `wai/REGISTRY.md`. A library test
//! holds each committed file byte-equal to what this module renders, so a change
//! here that is not exported fails, and so does a hand edit of an exported file.
//!
//! The policy the table implements is stated in `wai/REGISTRY.md`.
use super::*;
/// Whether a registered string's payload format is pinned (SPEC §5, *Candidate
/// capabilities*).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum RegistrationStatus {
/// Registered with a pinned payload format (or, for a record or derivation, a
/// pinned definition): encoders may emit it and sinks may dispatch it.
Registered,
/// Registered, but no revision has pinned its payload format. An encoder MUST
/// NOT emit it, and a sink MUST treat it as unsupported (SPEC §5).
Candidate,
}
impl RegistrationStatus {
/// Every status, in declaration order. (A function, not an associated
/// constant, so the C header generator does not export it.)
pub const fn all() -> [Self; 2] {
[Self::Registered, Self::Candidate]
}
/// The label the export and `wai capabilities` use.
pub fn label(self) -> &'static str {
match self {
Self::Registered => "registered",
Self::Candidate => "candidate",
}
}
}
/// What a registered string names (SPEC §5, *Kinds of registered string*).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Kind {
/// A payload capability: the envelope's `capability` (or `fallback`, or a
/// `WAI2` rendition) names the codec its payload is decoded with.
Payload,
/// A companion-only capability ([`is_companion_only`]): its payload is applied
/// with a base rendition, never on its own.
Companion,
/// A refinement-only capability ([`is_refinement_only`]): its payload is applied,
/// in a declared order, to the output of the stage below it, bound to that
/// output's producer by content hash, never on its own
/// (`extensions/staged-delivery.md`).
Refinement,
/// A derivation operation of ISO/IEC 23001-16 (`wai.derive.*`): it acts on
/// samples another capability decoded and names no payload format.
Derivation,
/// A signed record a WAI tool emits and verifies (a receipt kind). It names
/// no payload format and is never an envelope's capability.
Record,
}
impl Kind {
/// Every kind, in declaration order.
pub const fn all() -> [Self; 5] {
[Self::Payload, Self::Companion, Self::Refinement, Self::Derivation, Self::Record]
}
/// The label the export uses.
pub fn label(self) -> &'static str {
match self {
Self::Payload => "payload",
Self::Companion => "companion",
Self::Refinement => "refinement",
Self::Derivation => "derivation",
Self::Record => "record",
}
}
}
/// The media class of a payload or companion capability: the value `wai wrap`
/// writes in a manifest's `media` field (SPEC §3: informational; the capability
/// is authoritative).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Media {
Image,
Audio,
Video,
Text,
/// Meshes, point clouds and Gaussian splats.
Volumetric,
Haptic,
/// Metadata applied with another payload (the HDR dynamic-metadata descriptors).
Metadata,
/// Worlds, feeds and avatars: content that consumes input.
Interactive,
/// A payload in none of the classes above.
Binary,
}
impl Media {
/// Every media class, in declaration order.
pub const fn all() -> [Self; 9] {
[
Self::Image, Self::Audio, Self::Video, Self::Text, Self::Volumetric,
Self::Haptic, Self::Metadata, Self::Interactive, Self::Binary,
]
}
/// The manifest value.
pub fn label(self) -> &'static str {
match self {
Self::Image => "image",
Self::Audio => "audio",
Self::Video => "video",
Self::Text => "text",
Self::Volumetric => "volumetric",
Self::Haptic => "haptic",
Self::Metadata => "metadata",
Self::Interactive => "interactive",
Self::Binary => "binary",
}
}
}
impl LicenseClass {
/// Every class, in declaration order.
pub const fn all() -> [Self; 4] {
[Self::RoyaltyFree, Self::PatentPool, Self::Proprietary, Self::NonCommercial]
}
/// The label SPEC §5 gives the class, which `wai capabilities` prints and the
/// codec glossary and the registry export record.
pub fn label(self) -> &'static str {
match self {
Self::RoyaltyFree => "royalty-free",
Self::PatentPool => "patent-pool",
Self::Proprietary => "proprietary",
Self::NonCommercial => "non-commercial",
}
}
}
impl FidelityTier {
/// Every tier, in declaration order.
pub const fn all() -> [Self; 3] {
[Self::Lossless, Self::Lossy, Self::Perceptual]
}
/// The label the export uses.
pub fn label(self) -> &'static str {
match self {
Self::Lossless => "lossless",
Self::Lossy => "lossy",
Self::Perceptual => "perceptual",
}
}
}
impl ReplicateClass {
/// Every class, in declaration order.
pub const fn all() -> [Self; 8] {
[
Self::StandardDefined, Self::StandardTolerance, Self::StandardUnclassified,
Self::NeuralIntegerExact, Self::NeuralEntropyExact, Self::GenerativeDeterministic,
Self::NeuralFloat, Self::Behavioral,
]
}
}
/// The role labels `wai capabilities` prints and the export records for a
/// payload, companion or refinement capability.
pub const ROLE_LABELS: [&str; 4] = ["standalone", "companion", "enhancement", "refinement"];
/// How dispatch treats a payload, companion or refinement capability's payload:
/// standalone media, a companion applied with a base rendition, an enhancement layer
/// bound to exactly one base encode (SPEC §5, §7.1), or a refinement applied to the
/// output of the stage below it (SPEC §5, *Refinement capabilities*). `None` for any
/// other string.
pub fn capability_role(cap: &str) -> Option<&'static str> {
if !is_known_capability(cap) {
None
} else if is_refinement_only(cap) {
Some("refinement")
} else if is_enhancement_layer(cap) {
Some("enhancement")
} else if is_companion_only(cap) {
Some("companion")
} else {
Some("standalone")
}
}
/// The registered capabilities whose payload format no revision has pinned
/// (SPEC §5, *Candidate capabilities*).
const CANDIDATES: &[&str] = &[CAP_TENSOR_NNC, CAP_SPLAT_SOG];
// ---- Records -----------------------------------------------------------------
/// The record kinds SPEC §5 registers. The quantum strings are copies of
/// `wai_quantum::quantum_ops::CAP_QUANTUM_{CALIBRATION,JOB}`; a test under the
/// `quantum_ops` feature holds them equal.
pub const CAP_ASSET_PROVENANCE: &str = "wai.asset.provenance";
pub const CAP_QUANTUM_CALIBRATION: &str = "wai.quantum.calibration";
pub const CAP_QUANTUM_JOB: &str = "wai.quantum.job";
pub const CAP_VIDEO_MANIFEST: &str = "wai.video.manifest";
pub const CAP_VIDEO_SSAI: &str = "wai.video.ssai";
pub const CAP_VIDEO_KEYS: &str = "wai.video.keys";
pub const CAP_VIDEO_PACKAGE: &str = "wai.video.package";
pub const CAP_VIDEO_CHANNEL: &str = "wai.video.channel";
pub const CAP_LIVE_EVENTS: &str = "wai.live.events";
pub const CAP_LIVE_ROOM: &str = "wai.live.room";
pub const CAP_CAPTURE_TAKE: &str = "wai.capture.take";
pub const CAP_LIVE_COMPOSE: &str = "wai.live.compose";
pub const CAP_LIVE_RECORDING: &str = "wai.live.recording";
pub const CAP_LIVE_METERING: &str = "wai.live.metering";
pub const CAP_LIVE_STEERING: &str = "wai.live.steering";
pub const CAP_TEXT_TIMED: &str = "wai.text.timed";
pub const CAP_LIVE_MODERATION: &str = "wai.live.moderation";
pub const CAP_LIVE_E2EE: &str = "wai.live.e2ee";
pub const CAP_LIVE_WATERMARK: &str = "wai.live.watermark";
pub const CAP_LIVE_ADS: &str = "wai.live.ads";
pub const CAP_LIVE_PROVENANCE: &str = "wai.live.provenance";
pub const CAP_EDGE_DERIVATION: &str = "wai.edge.derivation";
pub const CAP_MEDIA_SYNTHESIS: &str = "wai.media.synthesis";
pub const CAP_AI_USAGE: &str = "wai.ai.usage";
pub const CAP_MEDIA_CONTRIBUTION: &str = "wai.media.contribution";
pub const CAP_DELIVERY_SETTLEMENT: &str = "wai.delivery.settlement";
/// One row per string SPEC §5 registers that is a payload, companion or record:
/// `(string, SPEC section, edition, registered)`.
///
/// - The section is the heading of SPEC §5 under which the string is registered.
/// - `edition` is the designation of the edition the registration names, or
/// `None`: then the string carries the edition of its named standard current on
/// the date it was registered, and no later edition or amendment (SPEC §8,
/// *Editions*).
/// - `registered` is the date of the first commit of this repository that
/// registers the string. The specification entered this repository on
/// 2026-06-12; a string registered before then carries that date.
const ROWS: &[(&str, &str, Option<&str>, &str)] = &[
(CAP_IMAGE_PNG, S_FLOOR, None, "2026-06-12"),
(CAP_AUDIO_FLAC, S_FLOOR, None, "2026-06-12"),
(CAP_TEXT_ZSTD, S_FLOOR, None, "2026-06-12"),
(CAP_IMAGE_JXL, S_RECOMMENDED, None, "2026-06-12"),
(CAP_IMAGE_AVIF, S_RECOMMENDED, None, "2026-06-12"),
(CAP_IMAGE_JPEG, S_RECOMMENDED, None, "2026-06-12"),
(CAP_AUDIO_OPUS, S_RECOMMENDED, None, "2026-06-12"),
(CAP_VIDEO_AV1, S_RECOMMENDED, None, "2026-06-12"),
(CAP_VIDEO_AV1_LOSSLESS, S_RECOMMENDED, None, "2026-06-12"),
(CAP_TEXT_XZ, S_RECOMMENDED, None, "2026-06-12"),
(CAP_NEURAL_ENCODEC32, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_DAC, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_MIMI, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_WAVTOKENIZER, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_SNAC, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_BMSHJ2018, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_MBT2018_MEAN, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_INT_SYNTH, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_INT_HYPER, S_NEURAL, None, "2026-06-24"),
(CAP_NEURAL_INT_MLICPP, S_NEURAL, None, "2026-09-30"),
(CAP_IMAGE_JPEGAI, S_NEURAL, Some("ISO/IEC 6048-1:2025"), "2026-06-13"),
(CAP_GENERATE_SPECTRAL, S_NEURAL, None, "2026-06-25"),
(CAP_NEURAL_ELIC, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_MLICPP, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_MLICV2, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_CMIC, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_GLC, S_NEURAL, None, "2026-06-12"),
(CAP_SEMANTIC_CLIP, S_NEURAL, None, "2026-06-13"),
(CAP_SEMANTIC_PERCO2, S_NEURAL, None, "2026-06-13"),
(CAP_NEURAL_VIDEO_BMSHJ2018, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_DCVC_RT, S_NEURAL, None, "2026-06-12"),
(CAP_NEURAL_DCVC_FM, S_NEURAL, None, "2026-06-13"),
(CAP_VIDEO_INT_MOTION, S_NEURAL, None, "2026-06-27"),
(CAP_VIDEO_INT_HYPER, S_NEURAL, None, "2026-06-27"),
(CAP_VIDEO_MANIFEST, S_NEURAL, None, "2026-09-03"),
(CAP_VIDEO_SSAI, S_NEURAL, None, "2026-09-03"),
(CAP_VIDEO_KEYS, S_NEURAL, None, "2026-09-03"),
(CAP_VIDEO_PACKAGE, S_NEURAL, None, "2026-09-03"),
(CAP_VIDEO_CHANNEL, S_NEURAL, None, "2026-09-03"),
(CAP_PRIOR_NNC, S_PRIOR, Some("ISO/IEC 15938-17:2024"), "2026-09-28"),
(CAP_PRIOR_SET, S_PRIOR, None, "2026-09-30"),
(CAP_TENSOR_NNC, S_PRIOR, None, "2026-09-28"),
(CAP_EDGE_DERIVATION, S_PRIOR, None, "2026-10-21"),
(CAP_WORLD_SCENE, S_INTERACTIVE, None, "2026-06-13"),
(CAP_WORLD_REPLAY, S_INTERACTIVE, None, "2026-06-13"),
(CAP_WORLD_LIVE, S_INTERACTIVE, None, "2026-06-13"),
(CAP_WORLD_MODEL, S_INTERACTIVE, None, "2026-06-27"),
(CAP_MESH_GLB, S_INTERACTIVE, None, "2026-06-13"),
(CAP_SPLAT_SPZ, S_INTERACTIVE, None, "2026-06-13"),
(CAP_AUDIO_SCENE, S_INTERACTIVE, None, "2026-06-13"),
(CAP_AUDIO_SCORE, S_INTERACTIVE, None, "2026-06-14"),
(CAP_AUDIO_INT_CODEC, S_INTERACTIVE, None, "2026-06-27"),
(CAP_HAPTIC_SIGNAL, S_INTERACTIVE, None, "2026-06-13"),
(CAP_FEED_STATE, S_INTERACTIVE, None, "2026-06-13"),
(CAP_AVATAR_POSE, S_INTERACTIVE, None, "2026-06-13"),
(CAP_SPLAT_4D, S_INTERACTIVE, None, "2026-06-13"),
(CAP_SPLAT_INT_CODEC, S_INTERACTIVE, None, "2026-06-28"),
(CAP_FILM_LINEAR, S_INTERACTIVE, None, "2026-06-16"),
(CAP_FILM_REEL, S_INTERACTIVE, None, "2026-06-17"),
(CAP_TERNARY_TT, S_INTERACTIVE, None, "2026-07-30"),
(CAP_QUANTUM_CIRCUIT, S_INTERACTIVE, None, "2026-07-25"),
(CAP_QUANTUM_CIRCUIT2, S_INTERACTIVE, None, "2026-10-09"),
(CAP_ASSET_PROVENANCE, S_INTERACTIVE, None, "2026-06-13"),
(CAP_QUANTUM_CALIBRATION, S_INTERACTIVE, None, "2026-08-01"),
(CAP_QUANTUM_JOB, S_INTERACTIVE, None, "2026-08-01"),
(CAP_LIVE_EVENTS, S_INTERACTIVE, None, "2026-10-16"),
(CAP_LIVE_ROOM, S_INTERACTIVE, None, "2026-10-16"),
(CAP_CAPTURE_TAKE, S_INTERACTIVE, None, "2026-10-17"),
(CAP_LIVE_COMPOSE, S_INTERACTIVE, None, "2026-10-17"),
(CAP_LIVE_RECORDING, S_INTERACTIVE, None, "2026-10-17"),
(CAP_LIVE_METERING, S_INTERACTIVE, None, "2026-10-18"),
(CAP_LIVE_STEERING, S_INTERACTIVE, None, "2026-10-18"),
(CAP_TEXT_TIMED, S_INTERACTIVE, None, "2026-10-17"),
(CAP_LIVE_MODERATION, S_INTERACTIVE, None, "2026-10-19"),
(CAP_LIVE_E2EE, S_INTERACTIVE, None, "2026-10-19"),
(CAP_LIVE_WATERMARK, S_INTERACTIVE, None, "2026-10-20"),
(CAP_LIVE_ADS, S_INTERACTIVE, None, "2026-10-20"),
(CAP_LIVE_PROVENANCE, S_INTERACTIVE, None, "2026-10-21"),
(CAP_MEDIA_SYNTHESIS, S_INTERACTIVE, None, "2026-10-21"),
(CAP_AI_USAGE, S_INTERACTIVE, None, "2026-10-21"),
(CAP_MEDIA_CONTRIBUTION, S_INTERACTIVE, None, "2026-10-21"),
(CAP_DELIVERY_SETTLEMENT, S_INTERACTIVE, None, "2026-10-21"),
(CAP_AUDIO_IAMF, S_IMMERSIVE, None, "2026-06-17"),
(CAP_AUDIO_AC4, S_IMMERSIVE, None, "2026-06-17"),
(CAP_AUDIO_IVAS, S_IMMERSIVE, None, "2026-06-17"),
(CAP_IMAGE_JP2, S_IMMERSIVE, None, "2026-06-17"),
(CAP_VIDEO_J2K, S_IMMERSIVE, None, "2026-06-17"),
(CAP_MESH_DRACO, S_IMMERSIVE, None, "2026-06-17"),
(CAP_PC_GPCC, S_IMMERSIVE, None, "2026-06-17"),
(CAP_PC_VPCC, S_IMMERSIVE, None, "2026-06-17"),
(CAP_SPLAT_SOG, S_IMMERSIVE, None, "2026-06-17"),
(CAP_HAPTIC_MIHS, S_IMMERSIVE, Some("ISO/IEC 23090-31:2025"), "2026-06-17"),
(CAP_META_HDR10PLUS, S_IMMERSIVE, None, "2026-06-17"),
(CAP_META_DOVI, S_IMMERSIVE, None, "2026-06-17"),
(CAP_VIDEO_AV2, S_BROADCAST, Some("AV2 Bitstream & Decoding Process Specification v1.0.0 (2026-05-28)"), "2026-09-28"),
(CAP_VIDEO_VVC, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_HEVC, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_AVC, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_VP9, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_EVC, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_EVC_BASELINE, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_AVS3, S_BROADCAST, Some("T/AI 109.2-2021"), "2026-09-28"),
(CAP_VIDEO_LCEVC, S_BROADCAST, None, "2026-09-28"),
(CAP_AUDIO_MPEGH, S_BROADCAST, None, "2026-09-28"),
(CAP_AUDIO_AVS3, S_BROADCAST, Some("T/AI 109.3-2023"), "2026-09-28"),
(CAP_AUDIO_AAC, S_BROADCAST, None, "2026-09-28"),
(CAP_VIDEO_VP8, S_BROADCAST, None, "2026-10-18"),
(CAP_AUDIO_OPUS_PACKET, S_BROADCAST, None, "2026-10-18"),
(CAP_IMAGE_INT_REFINE, S_REFINEMENT, None, "2026-10-01"),
(CAP_VIDEO_INT_REFINE, S_REFINEMENT, None, "2026-10-01"),
(CAP_AUDIO_INT_REFINE, S_REFINEMENT, None, "2026-10-01"),
(CAP_SPLAT_INT_REFINE, S_REFINEMENT, None, "2026-10-01"),
];
const S_FLOOR: &str = "§5 Mandatory floor";
const S_RECOMMENDED: &str = "§5 Recommended modern set";
const S_NEURAL: &str = "§5 Neural capabilities";
const S_PRIOR: &str = "§5 Prior artifacts, general tensors and derivation operations";
const S_INTERACTIVE: &str = "§5 Interactive, temporal & computed content";
const S_IMMERSIVE: &str = "§5 Immersive audio, cinema, volumetric, haptics, HDR";
const S_BROADCAST: &str = "§5 Broadcast and streaming codecs";
const S_REFINEMENT: &str = "§5 Refinement capabilities (staged delivery)";
/// The date the derivation operations were registered.
const DERIVATIONS_REGISTERED: &str = "2026-09-28";
/// The record kinds SPEC §5 registers (see [`Kind::Record`]).
const RECORDS: &[&str] = &[
CAP_ASSET_PROVENANCE, CAP_QUANTUM_CALIBRATION, CAP_QUANTUM_JOB,
CAP_VIDEO_MANIFEST, CAP_VIDEO_SSAI, CAP_VIDEO_KEYS, CAP_VIDEO_PACKAGE, CAP_VIDEO_CHANNEL,
CAP_LIVE_EVENTS, CAP_LIVE_ROOM, CAP_CAPTURE_TAKE, CAP_LIVE_COMPOSE, CAP_LIVE_RECORDING,
CAP_LIVE_METERING, CAP_LIVE_STEERING, CAP_TEXT_TIMED, CAP_LIVE_MODERATION, CAP_LIVE_E2EE,
CAP_LIVE_WATERMARK,
CAP_LIVE_ADS,
CAP_LIVE_PROVENANCE,
CAP_EDGE_DERIVATION,
CAP_MEDIA_SYNTHESIS,
CAP_AI_USAGE,
CAP_MEDIA_CONTRIBUTION,
CAP_DELIVERY_SETTLEMENT,
];
/// A named identifier SPEC uses that has the shape of a capability string but is
/// not a capability: it names a part of a capability's definition.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Identifier {
pub identifier: &'static str,
pub spec_section: &'static str,
pub meaning: &'static str,
}
/// Every [`Identifier`] SPEC uses.
pub const IDENTIFIERS: &[Identifier] = &[
Identifier {
identifier: "wai.det.amp64",
spec_section: S_INTERACTIVE,
meaning: "the complex fixed-point arithmetic of wai.quantum.circuit2: re and im each an i64 at scale 2^frac, products exact then rounded half up, sums exact (quantum-sim §2.1, §3.0)",
},
Identifier {
identifier: "wai.det.fixed64",
spec_section: S_INTERACTIVE,
meaning: "the fixed-point arithmetic floor the deterministic *-equivalence criteria are computed in (Q32.32, interactive-worlds §6.2); inside a wai.quantum.circuit contract it names the quantum-sim §3.0 arithmetic at frac 30, products rounded half up",
},
Identifier {
identifier: "wai.world.sim.feed0",
spec_section: S_INTERACTIVE,
meaning: "the identity simulation step of wai.feed.state",
},
Identifier {
identifier: "wai.world.sim.skeletal0",
spec_section: S_INTERACTIVE,
meaning: "the skeletal-pose simulation step of wai.avatar.pose",
},
];
/// What a [`WireIdentifier`] names.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum WireKind {
/// A media type.
MediaType,
/// The prefix of a `codecs` element.
CodecsPrefix,
/// An ISOBMFF four-character code.
FourCc,
/// The magic number at the start of a binary format.
Magic,
/// An HLS `EXT-X-SESSION-DATA` `DATA-ID`.
DataId,
/// A URI scheme identifier (a DASH `schemeIdUri`).
Scheme,
/// A path suffix or a path segment a resource is named by.
Path,
/// A path under `/.well-known/` (RFC 8615).
WellKnown,
/// A playlist tag.
PlaylistTag,
/// A playlist attribute, or a value a WAI binding gives one (an `EXT-X-DATERANGE`
/// `CLASS`).
PlaylistAttribute,
/// The `kind` member of a JSON document.
DocumentKind,
/// A MoQ catalog value, catalog field or object property.
Catalog,
/// A MOQT Setup Option.
SetupOption,
/// An HTTP field name.
HttpHeader,
}
impl WireKind {
/// Every kind, in declaration order.
pub const fn all() -> [Self; 14] {
[
Self::MediaType, Self::CodecsPrefix, Self::FourCc, Self::Magic, Self::DataId,
Self::Scheme, Self::Path, Self::WellKnown, Self::PlaylistTag,
Self::PlaylistAttribute, Self::DocumentKind, Self::Catalog, Self::SetupOption,
Self::HttpHeader,
]
}
/// The label the export uses.
pub fn label(self) -> &'static str {
match self {
Self::MediaType => "media-type",
Self::CodecsPrefix => "codecs-prefix",
Self::FourCc => "fourcc",
Self::Magic => "magic",
Self::DataId => "data-id",
Self::Scheme => "scheme",
Self::Path => "path",
Self::WellKnown => "well-known",
Self::PlaylistTag => "playlist-tag",
Self::PlaylistAttribute => "playlist-attribute",
Self::DocumentKind => "document-kind",
Self::Catalog => "catalog",
Self::SetupOption => "setup-option",
Self::HttpHeader => "http-header",
}
}
}
/// How settled a [`WireIdentifier`] is.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum WireStatus {
/// Defined by its document, and used as defined.
Defined,
/// Defined by its document for test material only, until a registration
/// authority registers it.
Provisional,
/// Proposed for registration; its document says it is not registered.
Proposed,
}
impl WireStatus {
/// Every status, in declaration order.
pub const fn all() -> [Self; 3] {
[Self::Defined, Self::Provisional, Self::Proposed]
}
/// The label the export uses.
pub fn label(self) -> &'static str {
match self {
Self::Defined => "defined",
Self::Provisional => "provisional",
Self::Proposed => "proposed",
}
}
}
/// A name a WAI text puts on the wire outside a manifest: a media type, a `codecs`
/// prefix, a magic number, a path, a playlist tag or attribute, a document kind, a
/// catalog field. `document` is the text that defines it, relative to `wai/`, and
/// `section` the section there (`§N` or `Appendix X`).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WireIdentifier {
pub name: &'static str,
pub kind: WireKind,
pub document: &'static str,
pub section: &'static str,
pub status: WireStatus,
}
const HTTP_DELIVERY: &str = "extensions/http-delivery.md";
const MOQ_FORMAT: &str = "extensions/moq-streaming-format.md";
const JWP_RECEIPTS: &str = "extensions/jwp-receipts.md";
const PACKAGING: &str = "extensions/packaging.md";
const LIVE_EVENTS: &str = "extensions/live-events.md";
const LIVE_ROOMS: &str = "extensions/live-rooms.md";
const CAPTURE_BINDING: &str = "extensions/capture-binding.md";
const LIVE_COMPOSE: &str = "extensions/live-compose.md";
const LIVE_RECORDING: &str = "extensions/live-recording.md";
const TIMED_TEXT: &str = "extensions/timed-text.md";
const LIVE_METERING: &str = "extensions/live-metering.md";
const ENERGY_STEERING: &str = "extensions/energy-steering.md";
const LIVE_MODERATION: &str = "extensions/live-moderation.md";
const CONFIDENTIALITY: &str = "extensions/confidentiality.md";
const FORENSIC_WATERMARK: &str = "extensions/forensic-watermark.md";
const AI_USAGE: &str = "extensions/ai-usage.md";
const LIVE_ADS: &str = "extensions/live-ads.md";
const LIVE_PROVENANCE: &str = "extensions/live-provenance.md";
const DERIVING_EDGE: &str = "extensions/deriving-edge.md";
const SYNTHESIS: &str = "extensions/synthesis.md";
const CONTRIBUTION: &str = "extensions/contribution.md";
const SETTLEMENT: &str = "extensions/settlement.md";
const fn wire(name: &'static str, kind: WireKind, document: &'static str, section: &'static str,
status: WireStatus) -> WireIdentifier {
WireIdentifier { name, kind, document, section, status }
}
/// The wire identifiers of the container, of its two delivery bindings
/// (http-delivery, moq-streaming-format), of the key discovery those bindings serve
/// (jwp-receipts §7) and of every extension that defines one: grouped by document, each
/// group in its document's order. The export lists them sorted by name and kind.
pub const WIRE_IDENTIFIERS: &[WireIdentifier] = &[
wire("WAI1", WireKind::Magic, "SPEC.md", "§2", WireStatus::Defined),
wire("WAI2", WireKind::Magic, "SPEC.md", "§7.1", WireStatus::Defined),
wire("application/wai", WireKind::MediaType, HTTP_DELIVERY, "§3", WireStatus::Proposed),
wire("wai1", WireKind::CodecsPrefix, HTTP_DELIVERY, "§4.1", WireStatus::Defined),
wire("wai2", WireKind::CodecsPrefix, HTTP_DELIVERY, "§4.1", WireStatus::Defined),
wire(".wai", WireKind::Path, HTTP_DELIVERY, "§5.2", WireStatus::Defined),
wire("WHP1", WireKind::Magic, HTTP_DELIVERY, "§6.2", WireStatus::Defined),
wire(".wai.hp", WireKind::Path, HTTP_DELIVERY, "§6.2", WireStatus::Defined),
wire("rcpt/", WireKind::Path, HTTP_DELIVERY, "§8.1", WireStatus::Defined),
wire(".wai.receipts", WireKind::Path, HTTP_DELIVERY, "§8.2", WireStatus::Defined),
wire("wai-receipt-index", WireKind::DocumentKind, HTTP_DELIVERY, "§8.2", WireStatus::Defined),
wire("/.well-known/wai-key-status", WireKind::WellKnown, HTTP_DELIVERY, "§8.4", WireStatus::Defined),
wire("/.well-known/wai-grants/", WireKind::WellKnown, HTTP_DELIVERY, "§8.4", WireStatus::Defined),
wire("wai-module-grants", WireKind::DocumentKind, HTTP_DELIVERY, "§8.4", WireStatus::Defined),
wire("mr/", WireKind::Path, HTTP_DELIVERY, "§8.6", WireStatus::Defined),
wire("#WAI-LAYER", WireKind::PlaylistTag, HTTP_DELIVERY, "§10.4", WireStatus::Defined),
wire("science.transaction.wai.multivariant", WireKind::DataId, HTTP_DELIVERY, "§11.1", WireStatus::Defined),
wire("X-WAI-FLOOR", WireKind::PlaylistAttribute, HTTP_DELIVERY, "§11.1", WireStatus::Defined),
wire("tag:transaction.science,2026:wai/http-delivery", WireKind::Scheme, HTTP_DELIVERY, "§11.1", WireStatus::Defined),
wire("tag:transaction.science,2026:wai/floor", WireKind::Scheme, HTTP_DELIVERY, "§11.1", WireStatus::Defined),
wire("wai1", WireKind::FourCc, HTTP_DELIVERY, "Appendix B", WireStatus::Provisional),
wire("wai2", WireKind::FourCc, HTTP_DELIVERY, "Appendix B", WireStatus::Provisional),
wire("waiC", WireKind::FourCc, HTTP_DELIVERY, "Appendix B", WireStatus::Provisional),
wire("wai", WireKind::Catalog, MOQ_FORMAT, "§3", WireStatus::Defined),
wire("wai_capabilities", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined),
wire("wai_determinism", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined),
wire("wai_receipts", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined),
wire("wai_receipt_alias", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined),
wire("wai_receipts_track", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined),
wire("wai_priors", WireKind::Catalog, MOQ_FORMAT, "§4.2", WireStatus::Defined),
wire("wai_staged", WireKind::Catalog, MOQ_FORMAT, "§4.1", WireStatus::Defined),
wire("wai-receipts", WireKind::Catalog, MOQ_FORMAT, "§4.1", WireStatus::Defined),
wire("WAI_RECEIPT", WireKind::Catalog, MOQ_FORMAT, "§5", WireStatus::Defined),
wire("WJR1", WireKind::Magic, JWP_RECEIPTS, "§2.7.3", WireStatus::Defined),
wire("/.well-known/wai-keys", WireKind::WellKnown, JWP_RECEIPTS, "§7.1", WireStatus::Defined),
wire("wai-key-status", WireKind::DocumentKind, JWP_RECEIPTS, "§7.9", WireStatus::Defined),
wire("wai-module-grant", WireKind::DocumentKind, JWP_RECEIPTS, "§7.9", WireStatus::Defined),
wire("WSIX", WireKind::Magic, PACKAGING, "§6", WireStatus::Defined),
wire("science.transaction.wai.class", WireKind::DataId, PACKAGING, "§8", WireStatus::Defined),
wire("science.transaction.wai.stages", WireKind::DataId, PACKAGING, "§8", WireStatus::Defined),
wire("tag:transaction.science,2026:wai/class", WireKind::Scheme, PACKAGING, "§8", WireStatus::Defined),
wire("tag:transaction.science,2026:wai/stages", WireKind::Scheme, PACKAGING, "§8", WireStatus::Defined),
wire("wai_delivery_timeout_ms", WireKind::Catalog, PACKAGING, "§8", WireStatus::Defined),
wire("WEV1", WireKind::Magic, LIVE_EVENTS, "§3.1", WireStatus::Defined),
wire("WEP1", WireKind::Magic, LIVE_EVENTS, "§5", WireStatus::Defined),
wire("urn:wai:event:1", WireKind::Catalog, LIVE_EVENTS, "§8.1", WireStatus::Defined),
wire("science.transaction.wai.event", WireKind::PlaylistAttribute, LIVE_EVENTS, "§8.3", WireStatus::Defined),
wire("X-WAI-EVENT", WireKind::PlaylistAttribute, LIVE_EVENTS, "§8.3", WireStatus::Defined),
wire("urn:wai:event:1", WireKind::Scheme, LIVE_EVENTS, "§8.4", WireStatus::Defined),
wire("WRD1", WireKind::Magic, LIVE_ROOMS, "§3.1", WireStatus::Defined),
wire("WRG1", WireKind::Magic, LIVE_ROOMS, "§4.1", WireStatus::Defined),
wire("WRP1", WireKind::Magic, LIVE_ROOMS, "§10.5.1", WireStatus::Defined),
wire("GRANT_CHALLENGE", WireKind::SetupOption, LIVE_ROOMS, "§10.5.2", WireStatus::Proposed),
wire("GRANT_PROOF", WireKind::SetupOption, LIVE_ROOMS, "§10.5.2", WireStatus::Proposed),
wire("WAI-Room-Proof", WireKind::HttpHeader, LIVE_ROOMS, "§10.5.3", WireStatus::Proposed),
wire("WAI-Room-Challenge", WireKind::HttpHeader, LIVE_ROOMS, "§10.5.3", WireStatus::Proposed),
wire("WUR1", WireKind::Magic, CAPTURE_BINDING, "§6.2", WireStatus::Defined),
wire("WTM1", WireKind::Magic, CAPTURE_BINDING, "§7.1", WireStatus::Defined),
wire("WCN1", WireKind::Magic, CAPTURE_BINDING, "§8.1", WireStatus::Defined),
wire("WCD1", WireKind::Magic, LIVE_COMPOSE, "§3.1", WireStatus::Defined),
wire("WCR1", WireKind::Magic, LIVE_COMPOSE, "§8.1", WireStatus::Defined),
wire("WRM1", WireKind::Magic, LIVE_RECORDING, "§4.1", WireStatus::Defined),
wire("WCL1", WireKind::Magic, LIVE_RECORDING, "§5.1", WireStatus::Defined),
wire("WTX1", WireKind::Magic, TIMED_TEXT, "§4.2", WireStatus::Defined),
wire("wai_origin", WireKind::Catalog, TIMED_TEXT, "§7.2", WireStatus::Defined),
wire("wai_model", WireKind::Catalog, TIMED_TEXT, "§7.2", WireStatus::Defined),
wire("wai_machine_generated", WireKind::Catalog, TIMED_TEXT, "§7.4", WireStatus::Defined),
wire("tag:transaction.science,2026:wai/model/", WireKind::Scheme, TIMED_TEXT, "§10.3", WireStatus::Defined),
wire("tag:transaction.science,2026:wai/timed-text", WireKind::Scheme, TIMED_TEXT, "§10.4", WireStatus::Defined),
wire("science.transaction.wai.timed-text", WireKind::DataId, TIMED_TEXT, "§10.5", WireStatus::Defined),
wire("WMH1", WireKind::Magic, LIVE_METERING, "§3.1", WireStatus::Defined),
wire("WMR1", WireKind::Magic, LIVE_METERING, "§4.1", WireStatus::Defined),
wire("WSP1", WireKind::Magic, ENERGY_STEERING, "§3.1", WireStatus::Defined),
wire("WSD1", WireKind::Magic, ENERGY_STEERING, "§7.1", WireStatus::Defined),
wire("WMP1", WireKind::Magic, LIVE_MODERATION, "§3.1", WireStatus::Defined),
wire("WMS1", WireKind::Magic, LIVE_MODERATION, "§4.2", WireStatus::Defined),
wire("WMN1", WireKind::Magic, LIVE_MODERATION, "§5.1", WireStatus::Defined),
wire("WRE1", WireKind::Magic, CONFIDENTIALITY, "§3.1", WireStatus::Defined),
wire("SECURE_OBJECT_KEY_ID", WireKind::Catalog, CONFIDENTIALITY, "§4.3", WireStatus::Defined),
wire("WAI_INNER_DIGEST", WireKind::Catalog, CONFIDENTIALITY, "§4.4", WireStatus::Defined),
wire("WWS1", WireKind::Magic, FORENSIC_WATERMARK, "§5.1", WireStatus::Defined),
wire("WWQ1", WireKind::Magic, FORENSIC_WATERMARK, "§7.1", WireStatus::Defined),
wire("WWD1", WireKind::Magic, FORENSIC_WATERMARK, "§8.1", WireStatus::Defined),
wire("WAP1", WireKind::Magic, LIVE_ADS, "§3.1", WireStatus::Defined),
wire("WAB1", WireKind::Magic, LIVE_ADS, "§4.2", WireStatus::Defined),
wire("wai_c2pa_track", WireKind::Catalog, LIVE_PROVENANCE, "§10.2", WireStatus::Defined),
wire("wai-c2pa", WireKind::Catalog, LIVE_PROVENANCE, "§10.2", WireStatus::Defined),
wire("wai-derivation", WireKind::DocumentKind, DERIVING_EDGE, "§5.1", WireStatus::Defined),
wire("wai-origin", WireKind::DocumentKind, SYNTHESIS, "§3.1", WireStatus::Defined),
wire("wai-marking", WireKind::DocumentKind, SYNTHESIS, "§7.2", WireStatus::Defined),
wire("wai-detection", WireKind::DocumentKind, SYNTHESIS, "§7.3", WireStatus::Defined),
wire("wai-review", WireKind::DocumentKind, SYNTHESIS, "§9.1", WireStatus::Defined),
wire("wai-label-policy", WireKind::DocumentKind, SYNTHESIS, "§10.1", WireStatus::Defined),
wire("wai-player", WireKind::DocumentKind, SYNTHESIS, "§10.3", WireStatus::Defined),
wire("WAU1", WireKind::Magic, AI_USAGE, "§4.2", WireStatus::Defined),
wire("wai_ai_usage", WireKind::Catalog, MOQ_FORMAT, "§4", WireStatus::Defined),
wire("WAI-Usage-Claim", WireKind::HttpHeader, AI_USAGE, "§7.3", WireStatus::Proposed),
wire("wai-session", WireKind::DocumentKind, CONTRIBUTION, "§3.1", WireStatus::Defined),
wire("wai-membership", WireKind::DocumentKind, CONTRIBUTION, "§3.2", WireStatus::Defined),
wire("wai-step", WireKind::DocumentKind, CONTRIBUTION, "§4.1", WireStatus::Defined),
wire("wai-contribution", WireKind::DocumentKind, CONTRIBUTION, "§6", WireStatus::Defined),
wire("wai-authorship-map", WireKind::DocumentKind, CONTRIBUTION, "§7.3", WireStatus::Defined),
wire("WDA1", WireKind::Magic, SETTLEMENT, "§3.1", WireStatus::Defined),
wire("WBR1", WireKind::Magic, SETTLEMENT, "§5.2", WireStatus::Defined),
wire("WSS1", WireKind::Magic, SETTLEMENT, "§7.1", WireStatus::Defined),
];
/// A string with the shape of a capability that the reference implementation uses
/// as a label but that no revision registers, and why.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UnregisteredLabel {
pub label: &'static str,
pub reason: &'static str,
}
const QUANTUM_RECORD_LABEL: &str = "a receipt-kind label the wai-quantum crate seals; no revision of SPEC or of an extension registers it, so it is not a registered record";
/// Every [`UnregisteredLabel`]. The strings are copies of
/// `wai_quantum::quantum_ops::CAP_QUANTUM_{MITIGATE,DECODE,COMPILE,REARRANGE,QBOM,FABRIC}`;
/// a test under the `quantum_ops` feature holds them equal.
pub const UNREGISTERED_LABELS: &[UnregisteredLabel] = &[
UnregisteredLabel { label: "wai.quantum.mitigate", reason: QUANTUM_RECORD_LABEL },
UnregisteredLabel { label: "wai.quantum.decode", reason: QUANTUM_RECORD_LABEL },
UnregisteredLabel { label: "wai.quantum.compile", reason: QUANTUM_RECORD_LABEL },
UnregisteredLabel { label: "wai.quantum.rearrange", reason: QUANTUM_RECORD_LABEL },
UnregisteredLabel { label: "wai.quantum.qbom", reason: QUANTUM_RECORD_LABEL },
UnregisteredLabel { label: "wai.quantum.fabric", reason: QUANTUM_RECORD_LABEL },
];
/// One registered string with every property the registry gives it.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Registration {
pub capability: &'static str,
pub kind: Kind,
pub status: RegistrationStatus,
/// The media class, for a payload or companion capability.
pub media: Option<Media>,
/// `standalone`, `companion`, `enhancement` or `refinement`, for a payload,
/// companion or refinement capability ([`capability_role`]).
pub role: Option<&'static str>,
pub tier: Option<FidelityTier>,
pub licence: Option<LicenseClass>,
pub replicate: Option<ReplicateClass>,
pub floor: bool,
pub recommended: bool,
pub spec_section: &'static str,
/// See [`ROWS`]: a designation, or `None` for the edition current at `registered`.
pub edition: Option<&'static str>,
pub registered: &'static str,
/// The integer operator set the capability decodes through, if it does
/// (`extensions/integer-operators.md` §11).
pub ops: Option<super::OpsMember>,
}
/// Every registered string — payload, companion, derivation and record — sorted
/// by string.
pub fn registrations() -> Vec<Registration> {
let mut v: Vec<Registration> = ROWS
.iter()
.map(|&(cap, section, edition, registered)| Registration {
capability: cap,
kind: capability_kind(cap).expect("every row is registered"),
status: capability_status(cap).expect("every row is registered"),
media: capability_media(cap),
role: capability_role(cap),
tier: capability_tier(cap),
licence: capability_license(cap),
replicate: capability_replicate_class(cap),
floor: mandatory_floor().contains(&cap),
recommended: recommended_set().contains(&cap),
spec_section: section,
edition,
registered,
ops: super::capability_ops(cap),
})
.collect();
for op in derivation::derivation_operations() {
v.push(Registration {
capability: op.capability,
kind: Kind::Derivation,
status: RegistrationStatus::Registered,
media: None,
role: None,
tier: None,
licence: Some(derivation::derivation_license()),
replicate: None,
floor: false,
recommended: false,
spec_section: S_PRIOR,
edition: Some("ISO/IEC 23001-16:2021"),
registered: DERIVATIONS_REGISTERED,
ops: None,
});
}
v.sort_by(|a, b| a.capability.cmp(b.capability));
v
}
/// The [`Kind`] of a registered string, or `None` for a string this revision does
/// not register.
pub fn capability_kind(cap: &str) -> Option<Kind> {
if is_known_capability(cap) {
Some(if is_companion_only(cap) {
Kind::Companion
} else if is_refinement_only(cap) {
Kind::Refinement
} else {
Kind::Payload
})
} else if derivation::is_derivation_operation(cap) {
Some(Kind::Derivation)
} else if RECORDS.contains(&cap) {
Some(Kind::Record)
} else {
None
}
}
/// The [`RegistrationStatus`] of a registered string, or `None` for a string this
/// revision does not register.
pub fn capability_status(cap: &str) -> Option<RegistrationStatus> {
capability_kind(cap)?;
Some(if CANDIDATES.contains(&cap) { RegistrationStatus::Candidate } else { RegistrationStatus::Registered })
}
/// Whether a registered capability is a **candidate**: its string is registered but
/// no revision has pinned its payload format (SPEC §5, *Candidate capabilities*).
/// Until one does, an encoder MUST NOT emit it and a sink MUST treat it as
/// unsupported. False for a string this revision does not register.
pub fn is_candidate(cap: &str) -> bool {
capability_status(cap) == Some(RegistrationStatus::Candidate)
}
/// Whether a sink may dispatch or select `cap`, as far as this revision's
/// registry decides. False for every string this revision registers as something
/// that is not a pinned payload: a companion-only capability (applied with a base,
/// never on its own), a refinement-only capability (applied to the stage below it,
/// never on its own; `extensions/staged-delivery.md` §4 processes it), a candidate
/// (SPEC §5, *Candidate capabilities*), a record and a derivation (neither names a
/// payload format). True for a registered payload
/// capability whose payload is pinned, and for a string this revision does not
/// register: a later MINOR revision may register it (SPEC §8), and whether a sink
/// can decode it is the sink's to say through what it advertises (SPEC §4, step 3).
///
/// Every dispatch and selection function of the reference implementation uses this
/// one predicate, together with what the sink advertises and, where a pin applies,
/// the sink's verification of it (`Wai::dispatch_verified`, `WaiMulti::pick`,
/// `WaiMulti::primary`, `RenditionMeta::is_selectable`, the neural sink's
/// `decode_multi`, the C `wai_envelope_select`, wai-web's `core` module, the CLI's
/// `inspect`); a new one must use it too.
pub fn is_dispatchable(cap: &str) -> bool {
match capability_kind(cap) {
None => true,
Some(Kind::Payload) => !is_candidate(cap),
Some(Kind::Companion | Kind::Refinement | Kind::Derivation | Kind::Record) => false,
}
}
/// The [`Media`] class of a payload or companion capability, or `None` for any
/// other string (a record, a derivation, an unregistered string).
pub fn capability_media(cap: &str) -> Option<Media> {
use Media::*;
if !is_known_capability(cap) {
return None;
}
Some(match cap {
// Learned and generative image paths, and the semantic paths, which
// regenerate an image.
CAP_NEURAL_BMSHJ2018 | CAP_NEURAL_MBT2018_MEAN | CAP_NEURAL_INT_SYNTH
| CAP_NEURAL_INT_HYPER | CAP_NEURAL_INT_MLICPP | CAP_NEURAL_ELIC
| CAP_NEURAL_MLICPP | CAP_NEURAL_MLICV2 | CAP_NEURAL_CMIC | CAP_NEURAL_GLC
| CAP_GENERATE_SPECTRAL | CAP_SEMANTIC_CLIP | CAP_SEMANTIC_PERCO2 => Image,
CAP_NEURAL_ENCODEC32 | CAP_NEURAL_DAC | CAP_NEURAL_MIMI | CAP_NEURAL_WAVTOKENIZER
| CAP_NEURAL_SNAC => Audio,
// The neural video codecs and the films (linear-film gives a film's media
// the value "video").
CAP_NEURAL_VIDEO_BMSHJ2018 | CAP_NEURAL_DCVC_RT | CAP_NEURAL_DCVC_FM
| CAP_FILM_LINEAR | CAP_FILM_REEL => Video,
CAP_WORLD_SCENE | CAP_WORLD_REPLAY | CAP_WORLD_LIVE | CAP_WORLD_MODEL
| CAP_FEED_STATE | CAP_AVATAR_POSE => Interactive,
CAP_PRIOR_NNC | CAP_PRIOR_SET | CAP_TENSOR_NNC | CAP_QUANTUM_CIRCUIT | CAP_QUANTUM_CIRCUIT2
| CAP_TERNARY_TT => Binary,
c if c.starts_with("wai.image.") => Image,
c if c.starts_with("wai.audio.") => Audio,
c if c.starts_with("wai.video.") => Video,
c if c.starts_with("wai.text.") => Text,
c if c.starts_with("wai.mesh.") || c.starts_with("wai.pc.") || c.starts_with("wai.splat.") => Volumetric,
c if c.starts_with("wai.haptic.") => Haptic,
c if c.starts_with("wai.meta.") => Metadata,
_ => return None,
})
}
// ---- The export ------------------------------------------------------------------
/// Where the specification lives on the forge; the export's `$id`s are under it.
const FORGE_TREE: &str = "https://git.transaction.science/Transaction-Science/open-standards/src/branch/main/wai";
/// The namespace of the generated vocabulary.
pub const VOCAB_V2_NS: &str = "https://wai.transaction.science/vocab/v2#";
/// The marker lines between which `wai/REGISTRY.md` carries the generated table.
pub const REGISTRY_MD_BEGIN: &str = "<!-- generated: wai registry export; do not edit by hand -->";
pub const REGISTRY_MD_END: &str = "<!-- end generated -->";
/// The files `wai registry export` writes, as `(path relative to wai/, contents)`.
/// `REGISTRY.md` is not among them: only its generated region is (see
/// [`splice_registry_md`]).
pub fn export_files() -> Vec<(&'static str, String)> {
vec![
("registry/capabilities.json", capabilities_json()),
("registry/capabilities.schema.json", capabilities_schema()),
("vocab/v2.ttl", vocab_v2_ttl()),
("vocab/v2.jsonld", vocab_v2_jsonld()),
("vocab/v2.shapes.ttl", vocab_v2_shapes()),
]
}
fn sets_of(r: &Registration) -> Vec<&'static str> {
let mut s = Vec::new();
if r.floor { s.push("floor"); }
if r.recommended { s.push("recommended"); }
s
}
fn json_text(v: &serde_json::Value) -> String {
let mut s = serde_json::to_string_pretty(v).expect("serialize");
s.push('\n');
s
}
/// `wai/registry/capabilities.json`.
pub fn capabilities_json() -> String {
use serde_json::{json, Value};
let caps: Vec<Value> = registrations()
.iter()
.map(|r| {
let mut v = json!({
"capability": r.capability,
"kind": r.kind.label(),
"status": r.status.label(),
"media": r.media.map(Media::label),
"role": r.role,
"tier": r.tier.map(FidelityTier::label),
"licence": r.licence.map(LicenseClass::label),
"replicate": r.replicate.map(ReplicateClass::label),
"sets": sets_of(r),
"spec_section": r.spec_section,
"edition": r.edition,
"registered": r.registered,
});
if let Some(o) = r.ops {
v["ops"] = ops_json(&o);
}
v
})
.collect();
let mut ids: Vec<&Identifier> = IDENTIFIERS.iter().collect();
ids.sort_by_key(|i| i.identifier);
let ids: Vec<Value> = ids
.iter()
.map(|i| json!({ "identifier": i.identifier, "spec_section": i.spec_section, "meaning": i.meaning }))
.collect();
let mut labels: Vec<&UnregisteredLabel> = UNREGISTERED_LABELS.iter().collect();
labels.sort_by_key(|l| l.label);
let labels: Vec<Value> = labels.iter().map(|l| json!({ "label": l.label, "reason": l.reason })).collect();
let wires: Vec<Value> = sorted_wire_identifiers()
.iter()
.map(|w| json!({
"name": w.name,
"kind": w.kind.label(),
"document": w.document,
"section": w.section,
"status": w.status.label(),
}))
.collect();
json_text(&json!({
"schema": format!("{FORGE_TREE}/registry/capabilities.schema.json"),
"capabilities": caps,
"identifiers": ids,
"unregistered_labels": labels,
"wire_identifiers": wires,
}))
}
/// The registry's `ops` member (`extensions/integer-operators.md` §11), its members in
/// that section's order.
fn ops_json(o: &super::OpsMember) -> serde_json::Value {
use serde_json::{json, Map, Value};
let mut v = json!({ "set": "wai-ops/1" });
for (k, m) in [("profile", o.profile), ("subset", o.subset), ("lowering", o.lowering)] {
if let Some(m) = m {
v[k] = Value::from(m);
}
}
if !o.role_profiles.is_empty() {
v["role_profiles"] = Value::Object(o.role_profiles.iter().map(|(r, p)| (r.to_string(), Value::from(*p))).collect());
}
let mut stage = Map::new();
if let Some((table, escape, end)) = o.rans64 {
stage.insert("rans64".into(), json!({ "table": table, "escape": escape, "end": end }));
}
if let Some(b) = o.bucket {
stage.insert("bucket".into(), Value::from(b));
}
if !stage.is_empty() {
v["stage"] = Value::Object(stage);
}
v
}
fn nullable_enum(labels: &[&str]) -> serde_json::Value {
let mut e: Vec<serde_json::Value> = labels.iter().map(|l| serde_json::Value::from(*l)).collect();
e.push(serde_json::Value::Null);
serde_json::json!({ "enum": e })
}
/// The schema of a capability's `ops` member (`extensions/integer-operators.md` §11).
fn ops_schema() -> serde_json::Value {
serde_json::json!({
"type": "object",
"description": "The integer operator set the capability decodes through (extensions/integer-operators.md §11). Absent for a capability that does not. A capability whose decode runs no graph, only stage operators (§13.5), has no profile, subset or lowering.",
"additionalProperties": false,
"required": ["set"],
"dependentRequired": {
"profile": ["subset", "lowering"],
"subset": ["profile", "lowering"],
"lowering": ["profile", "subset"],
"role_profiles": ["profile"]
},
"anyOf": [{ "required": ["lowering"] }, { "required": ["stage"] }],
"properties": {
"set": { "const": "wai-ops/1" },
"profile": { "enum": ["acc32", "acc64"] },
"subset": { "enum": ["full", "npu"] },
"lowering": { "type": "string" },
"role_profiles": {
"type": "object",
"description": "Roles of the lowering whose graphs every conforming set holds to a stronger profile than `profile`, each with that profile (extensions/integer-operators.md §11).",
"minProperties": 1,
"additionalProperties": { "enum": ["acc32", "acc64"] }
},
"stage": {
"type": "object",
"additionalProperties": false,
"properties": {
"rans64": {
"type": "object",
"additionalProperties": false,
"required": ["table", "escape", "end"],
"properties": {
"table": { "enum": ["t4097", "t2"] },
"escape": { "enum": ["lenient", "strict"] },
"end": { "enum": ["canonical", "final_only"] }
}
},
"bucket": { "enum": ["ceil", "floor"] }
}
}
}
})
}
/// `wai/registry/capabilities.schema.json` (JSON Schema 2020-12). Its enums are
/// the registry's label sets.
pub fn capabilities_schema() -> String {
use serde_json::json;
let kinds: Vec<&str> = Kind::all().iter().map(|k| k.label()).collect();
let statuses: Vec<&str> = RegistrationStatus::all().iter().map(|s| s.label()).collect();
let media: Vec<&str> = Media::all().iter().map(|m| m.label()).collect();
let tiers: Vec<&str> = FidelityTier::all().iter().map(|t| t.label()).collect();
let licences: Vec<&str> = LicenseClass::all().iter().map(|l| l.label()).collect();
let replicates: Vec<&str> = ReplicateClass::all().iter().map(|r| r.label()).collect();
let wire_kinds: Vec<&str> = WireKind::all().iter().map(|k| k.label()).collect();
let wire_statuses: Vec<&str> = WireStatus::all().iter().map(|s| s.label()).collect();
let string_pattern = "^wai(\\.[a-z0-9_]+)+$";
json_text(&json!({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": format!("{FORGE_TREE}/registry/capabilities.schema.json"),
"title": "WAI capability registry",
"description": "Every string SPEC §5 registers, generated by `wai registry export` from the reference implementation's registry (wai-rs/src/codecs/registry.rs). REGISTRY.md states the policy.",
"type": "object",
"additionalProperties": false,
"required": ["schema", "capabilities", "identifiers", "unregistered_labels", "wire_identifiers"],
"properties": {
"schema": { "type": "string" },
"capabilities": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["capability", "kind", "status", "media", "role", "tier", "licence",
"replicate", "sets", "spec_section", "edition", "registered"],
"properties": {
"capability": { "type": "string", "pattern": string_pattern },
"kind": { "enum": kinds },
"status": { "enum": statuses },
"media": nullable_enum(&media),
"role": nullable_enum(&ROLE_LABELS),
"tier": nullable_enum(&tiers),
"licence": nullable_enum(&licences),
"replicate": nullable_enum(&replicates),
"sets": { "type": "array", "uniqueItems": true, "items": { "enum": ["floor", "recommended"] } },
"spec_section": { "type": "string" },
"edition": {
"type": ["string", "null"],
"description": "The edition the registration names; null means the edition of the named standard current on the date in `registered` (SPEC §8)."
},
"registered": {
"type": "string",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
"description": "The date of the first commit of this repository that registers the string; the specification entered the repository on 2026-06-12."
},
"ops": ops_schema()
}
}
},
"identifiers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["identifier", "spec_section", "meaning"],
"properties": {
"identifier": { "type": "string", "pattern": string_pattern },
"spec_section": { "type": "string" },
"meaning": { "type": "string" }
}
}
},
"unregistered_labels": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["label", "reason"],
"properties": {
"label": { "type": "string", "pattern": string_pattern },
"reason": { "type": "string" }
}
}
},
"wire_identifiers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "kind", "document", "section", "status"],
"properties": {
"name": { "type": "string" },
"kind": { "enum": wire_kinds },
"document": { "type": "string" },
"section": { "type": "string", "pattern": "^(§[0-9]+(\\.[0-9]+)*|Appendix [A-Z])$" },
"status": { "enum": wire_statuses }
}
}
}
}
}))
}
/// A Turtle string literal.
fn ttl_str(s: &str) -> String {
let mut o = String::from("\"");
for c in s.chars() {
match c {
'"' => o.push_str("\\\""),
'\\' => o.push_str("\\\\"),
'\n' => o.push_str("\\n"),
_ => o.push(c),
}
}
o.push('"');
o
}
const TTL_PREFIXES: &str = "@prefix wai: <https://wai.transaction.science/vocab/v2#> .\n\
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\
@prefix owl: <http://www.w3.org/2002/07/owl#> .\n\
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n\
@prefix dc: <http://purl.org/dc/terms/> .\n";
/// The local name of an enumeration individual of v2: its class's prefix and its
/// label (`kind-companion`, `role-companion`, `status-registered`, …), so that no
/// two enumerations, and no enumeration and property, share an IRI.
fn individual(prefix: &str, label: &str) -> String {
format!("{prefix}-{label}")
}
/// The enumerations of v2: `(class, individual prefix, labels)`.
fn enumerations() -> [(&'static str, &'static str, Vec<&'static str>); 7] {
[
("Kind", "kind", Kind::all().iter().map(|k| k.label()).collect()),
("Status", "status", RegistrationStatus::all().iter().map(|s| s.label()).collect()),
("Media", "media", Media::all().iter().map(|m| m.label()).collect()),
("Role", "role", ROLE_LABELS.to_vec()),
("Tier", "tier", FidelityTier::all().iter().map(|t| t.label()).collect()),
("Licence", "licence", LicenseClass::all().iter().map(|l| l.label()).collect()),
("ReplicateClass", "replicate", ReplicateClass::all().iter().map(|r| r.label()).collect()),
]
}
/// The registered tier tokens of a pin (SPEC §3.1), from [`TIER_TOKENS`].
fn tier_tokens() -> Vec<&'static str> {
TIER_TOKENS.iter().map(|&(t, _)| t).collect()
}
/// The parameter-set pin's terms (SPEC §3.1), as v1 states them. `pinSha256` and
/// `pinForm` name no domain: they are also the members of a pin's `supersedes`
/// object, which is not itself a pin.
const PIN_TERMS_TTL: &str = "# ─── The parameter-set pin (SPEC section 3.1) ────────────────────────\n\n\
wai:prior a owl:ObjectProperty ; rdfs:range wai:ParameterSetPin ; rdfs:label \"Parameter-set pin (conditioning.prior, or a component's prior)\" .\n\
wai:pinId a owl:DatatypeProperty ; rdfs:domain wai:ParameterSetPin ; rdfs:range xsd:string ; rdfs:label \"Pin name (informative)\" .\n\
wai:pinSha256 a owl:DatatypeProperty ; rdfs:range xsd:string ; rdfs:label \"SHA-256 of the parameter set in its form (64 lowercase hex)\" ;\n rdfs:comment \"A member of a pin and of its supersedes object.\" .\n\
wai:pinDeterminism a owl:DatatypeProperty ; rdfs:domain wai:ParameterSetPin ; rdfs:range xsd:string ; rdfs:label \"How the decode is made reproducible\" .\n\
wai:pinForm a owl:DatatypeProperty ; rdfs:range xsd:string ; rdfs:label \"Registered prior form\" ;\n rdfs:comment \"A member of a pin and of its supersedes object.\" .\n\
wai:pinSupersedes a owl:ObjectProperty ; rdfs:domain wai:ParameterSetPin ; rdfs:label \"The parameter set this one replaces (informative)\" ;\n rdfs:comment \"Names that set by pinSha256 and, if it is pinned in a declared form, pinForm; it is not itself a pin.\" .\n";
/// The SHACL shapes of the parameter-set pin (SPEC §3.1), the same in v1 and v2:
/// the JSON-LD context types no `prior` object, so the pin shape targets whatever
/// `wai:prior` points at; `pinTier` is the closed list [`TIER_TOKENS`] holds; and
/// `supersedes` names a set by its digest and, optionally, its form.
fn pin_shapes() -> String {
let tiers: Vec<String> = tier_tokens().iter().map(|t| format!("\"{t}\"")).collect();
let mut o = String::new();
o.push_str("# The parameter-set pin (SPEC section 3.1). The JSON-LD context types no prior object,\n");
o.push_str("# so the shape targets whatever wai:prior points at rather than a class. pinTier is a\n");
o.push_str("# closed vocabulary; the tokens are the ones codecs::TIER_TOKENS holds.\n");
o.push_str("wai:ParameterSetPinShape a sh:NodeShape ;\n");
o.push_str(" sh:targetObjectsOf wai:prior ;\n");
o.push_str(" sh:property [ sh:path wai:pinId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;\n");
o.push_str(" sh:property [ sh:path wai:pinSha256 ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;\n");
o.push_str(" sh:pattern \"^[a-f0-9]{64}$\" ] ;\n");
o.push_str(" sh:property [ sh:path wai:pinDeterminism ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;\n");
o.push_str(" sh:property [ sh:path wai:pinForm ; sh:datatype xsd:string ; sh:maxCount 1 ] ;\n");
o.push_str(&format!(" sh:property [ sh:path wai:pinTier ; sh:datatype xsd:string ; sh:maxCount 1 ;\n sh:in ( {} ) ] ;\n", tiers.join(" ")));
o.push_str(" sh:property [ sh:path wai:pinSupersedes ; sh:node wai:SupersedesShape ; sh:maxCount 1 ] .\n\n");
o.push_str("# supersedes names a set as a pin names one, by sha256 and, if it is pinned in a\n");
o.push_str("# declared form, form; it has no id, determinism or tier.\n");
o.push_str("wai:SupersedesShape a sh:NodeShape ;\n");
o.push_str(" sh:property [ sh:path wai:pinSha256 ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;\n");
o.push_str(" sh:pattern \"^[a-f0-9]{64}$\" ] ;\n");
o.push_str(" sh:property [ sh:path wai:pinForm ; sh:datatype xsd:string ; sh:maxCount 1 ] .\n");
o
}
/// `wai/vocab/v2.ttl`: one IRI per registered string, with its registry properties
/// as enumeration individuals, and the manifest terms the JSON-LD context maps.
pub fn vocab_v2_ttl() -> String {
let mut o = String::new();
o.push_str("# Generated by `wai registry export` from wai-rs/src/codecs/registry.rs. Do not edit.\n");
o.push_str(TTL_PREFIXES);
o.push_str("@prefix sh: <http://www.w3.org/ns/shacl#> .\n\n");
o.push_str("<https://wai.transaction.science/vocab/v2> a owl:Ontology ;\n");
o.push_str(" dc:title \"WAI vocabulary (v2)\" ;\n");
o.push_str(" dc:description \"The WAI capability registry as RDF: one IRI per string SPEC section 5 registers, with its kind, status, media class, role, fidelity tier, licence class and replicate class; and the manifest terms of the v2 JSON-LD context. Generated from the reference implementation's registry.\" ;\n");
o.push_str(" dc:license <https://www.apache.org/licenses/LICENSE-2.0> ;\n");
o.push_str(" owl:versionInfo \"2\" .\n\n");
o.push_str("# ─── Classes ─────────────────────────────────────────────────────────\n\n");
for (class, label) in [
("Manifest", "WAI manifest"),
("Component", "WAI2 component (an entry of a manifest's renditions)"),
("Capability", "Registered string"),
("Kind", "Kind of registered string"),
("Status", "Registration status"),
("Media", "Media class"),
("Role", "Dispatch role"),
("Tier", "Fidelity tier"),
("Licence", "Licence class"),
("ReplicateClass", "Replicate class"),
("ParameterSetPin", "Parameter-set pin (SPEC section 3.1)"),
] {
o.push_str(&format!("wai:{class} a owl:Class ; rdfs:label {} .\n", ttl_str(label)));
}
o.push('\n');
o.push_str("# ─── Enumerations (individuals named <class prefix>-<label>) ─────────\n\n");
for (class, prefix, labels) in &enumerations() {
for l in labels {
o.push_str(&format!("wai:{} a wai:{class} ; rdfs:label {} .\n", individual(prefix, l), ttl_str(l)));
}
}
o.push('\n');
o.push_str("# ─── Properties ──────────────────────────────────────────────────────\n\n");
for (p, range, label) in [
("capability", "wai:Capability", "Capability (model_requirement.capability, or a component's capability)"),
("fallback", "wai:Capability", "Fallback capability (model_requirement.fallback)"),
("companionOf", "wai:Capability", "Base capability a companion component is applied with (companion_of)"),
("renditions", "wai:Component", "WAI2 component"),
("media", "wai:Media", "Media class (informational in a manifest)"),
("kind", "wai:Kind", "Kind of registered string"),
("status", "wai:Status", "Registration status"),
("role", "wai:Role", "Dispatch role"),
("tier", "wai:Tier", "Fidelity tier"),
("licence", "wai:Licence", "Licence class"),
("replicateClass", "wai:ReplicateClass", "Replicate class"),
] {
o.push_str(&format!("wai:{p} a owl:ObjectProperty ; rdfs:range {range} ; rdfs:label {} .\n", ttl_str(label)));
}
for (p, domain, range, label) in [
("wai", "wai:Manifest", "xsd:string", "WAI version (the manifest's wai field)"),
("intent", "wai:Manifest", "xsd:string", "Intent"),
("payloadKind", "", "xsd:string", "Payload kind (conditioning.kind, or a component's kind)"),
("componentRole", "wai:Component", "xsd:string", "Component role (a component's role)"),
("target", "wai:Manifest", "rdf:JSON", "Target (carried as a JSON literal)"),
("specSection", "wai:Capability", "xsd:string", "Registering section of SPEC"),
("edition", "wai:Capability", "xsd:string", "Edition the registration names"),
("registeredOn", "wai:Capability", "xsd:date", "Date registered"),
] {
let domain = if domain.is_empty() { String::new() } else { format!(" rdfs:domain {domain} ;") };
o.push_str(&format!("wai:{p} a owl:DatatypeProperty ;{domain} rdfs:range {range} ; rdfs:label {} .\n", ttl_str(label)));
}
o.push('\n');
o.push_str(PIN_TERMS_TTL);
o.push_str(&format!("wai:pinTier a owl:DatatypeProperty ; rdfs:domain wai:ParameterSetPin ; rdfs:range xsd:string ; rdfs:label \"Declared reproducibility tier\" ;\n rdfs:comment {} .\n",
ttl_str(&format!("A closed vocabulary: {}.", tier_tokens().join(", ")))));
o.push('\n');
o.push_str("# ─── Registered strings ──────────────────────────────────────────────\n");
for r in registrations() {
o.push('\n');
o.push_str(&format!("wai:{} a wai:Capability ;\n", r.capability));
o.push_str(&format!(" rdfs:label {} ;\n", ttl_str(r.capability)));
o.push_str(&format!(" wai:kind wai:{} ;\n", individual("kind", r.kind.label())));
o.push_str(&format!(" wai:status wai:{} ;\n", individual("status", r.status.label())));
if let Some(m) = r.media { o.push_str(&format!(" wai:media wai:{} ;\n", individual("media", m.label()))); }
if let Some(role) = r.role { o.push_str(&format!(" wai:role wai:{} ;\n", individual("role", role))); }
if let Some(t) = r.tier { o.push_str(&format!(" wai:tier wai:{} ;\n", individual("tier", t.label()))); }
if let Some(l) = r.licence { o.push_str(&format!(" wai:licence wai:{} ;\n", individual("licence", l.label()))); }
if let Some(c) = r.replicate { o.push_str(&format!(" wai:replicateClass wai:{} ;\n", individual("replicate", c.label()))); }
if let Some(e) = r.edition { o.push_str(&format!(" wai:edition {} ;\n", ttl_str(e))); }
o.push_str(&format!(" wai:specSection {} ;\n", ttl_str(r.spec_section)));
o.push_str(&format!(" wai:registeredOn {}^^xsd:date .\n", ttl_str(r.registered)));
}
o
}
/// The registered strings a manifest may name as its `capability`: payload,
/// companion and refinement capabilities whose status is registered (a candidate
/// MUST NOT be emitted). A `WAI1` `fallback` additionally excludes the companions
/// and the refinements.
fn emittable() -> Vec<Registration> {
registrations()
.into_iter()
.filter(|r| matches!(r.kind, Kind::Payload | Kind::Companion | Kind::Refinement) && r.status == RegistrationStatus::Registered)
.collect()
}
/// `wai/vocab/v2.shapes.ttl` (SHACL Core): the capabilities a manifest names,
/// against the registry. A manifest needs no `@type` to be checked: the shape
/// targets every node with a `wai` (version) or an `intent` field (every WAI
/// manifest has both) and every component of a `renditions` list. `media` is informational and a reader MUST
/// accept a value it does not know (SPEC §3, §8), so the shape does not restrict
/// its value.
pub fn vocab_v2_shapes() -> String {
let caps: Vec<String> = emittable().iter().map(|r| format!("wai:{}", r.capability)).collect();
let payloads: Vec<String> = emittable()
.iter()
.filter(|r| r.kind == Kind::Payload)
.map(|r| format!("wai:{}", r.capability))
.collect();
let list = |v: &[String]| {
let mut s = String::from("(");
for x in v {
s.push_str("\n ");
s.push_str(x);
}
s.push_str("\n )");
s
};
let mut o = String::new();
o.push_str("# Generated by `wai registry export` from wai-rs/src/codecs/registry.rs. Do not edit.\n");
o.push_str("@prefix wai: <https://wai.transaction.science/vocab/v2#> .\n");
o.push_str("@prefix sh: <http://www.w3.org/ns/shacl#> .\n");
o.push_str("@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n\n");
o.push_str("# A WAI manifest, typed or not: every manifest has a wai (version) field. A WAI1 manifest names a\n");
o.push_str("# capability, a WAI2 manifest a renditions list, and never both. The capability is a\n");
o.push_str("# registered payload, companion or refinement capability that is not a candidate; the\n");
o.push_str("# fallback a registered payload capability that is not a candidate. (A WAI1 naming a\n");
o.push_str("# companion-only capability, or a refinement-only one without refines, parses but does\n");
o.push_str("# not conform; the reference implementation's role check reports it.) media is\n");
o.push_str("# informational, and a reader accepts a value it does not know\n");
o.push_str("# (SPEC sections 3 and 8), so only its form is checked.\n");
o.push_str("wai:ManifestShape a sh:NodeShape ;\n");
o.push_str(" sh:targetClass wai:Manifest ;\n");
o.push_str(" sh:targetSubjectsOf wai:wai ;\n");
o.push_str(" sh:targetSubjectsOf wai:intent ;\n");
o.push_str(&format!(" sh:property [ sh:path wai:capability ; sh:nodeKind sh:IRI ; sh:maxCount 1 ;\n sh:in {} ] ;\n", list(&caps)));
o.push_str(&format!(" sh:property [ sh:path wai:fallback ; sh:nodeKind sh:IRI ; sh:maxCount 1 ;\n sh:in {} ] ;\n", list(&payloads)));
o.push_str(" sh:property [ sh:path wai:media ; sh:nodeKind sh:IRI ; sh:maxCount 1 ] ;\n");
o.push_str(" sh:property [ sh:path wai:intent ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;\n");
o.push_str(" sh:xone (\n [ sh:property [ sh:path wai:capability ; sh:minCount 1 ] ]\n [ sh:property [ sh:path wai:renditions ; sh:minCount 1 ] ]\n ) .\n\n");
o.push_str("# A WAI2 component, in any role: its capability is a registered payload, companion or\n");
o.push_str("# refinement capability that is not a candidate, and the base a companion names is a\n");
o.push_str("# registered payload capability that is not a candidate.\n");
o.push_str("wai:ComponentShape a sh:NodeShape ;\n");
o.push_str(" sh:targetClass wai:Component ;\n");
o.push_str(" sh:targetObjectsOf wai:renditions ;\n");
o.push_str(&format!(" sh:property [ sh:path wai:capability ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;\n sh:in {} ] ;\n", list(&caps)));
o.push_str(&format!(" sh:property [ sh:path wai:companionOf ; sh:nodeKind sh:IRI ; sh:maxCount 1 ;\n sh:in {} ] .\n\n", list(&payloads)));
o.push_str(&pin_shapes());
o
}
/// `wai/vocab/v2.jsonld`: a JSON-LD context for WAI manifests, `WAI1` and `WAI2`.
/// Under it a manifest's `capability`, `fallback` and a component's `capability`
/// and `companion_of` expand to the v2 capability IRIs, and `media` to a media-class
/// individual; `kind` (of the conditioning, or of a component) and a component's
/// `role` are plain strings with terms of their own, distinct from the registry's
/// kind and role; `target` is carried as a JSON literal.
pub fn vocab_v2_jsonld() -> String {
use serde_json::json;
// No `wai` prefix term: a WAI manifest has a top-level `wai` (version) key,
// which under `@vocab` expands to the namespace's own `wai` property.
let t = |local: &str| format!("{VOCAB_V2_NS}{local}");
json_text(&json!({
"@context": {
"@version": 1.1,
"@vocab": VOCAB_V2_NS,
"xsd": "http://www.w3.org/2001/XMLSchema#",
"Manifest": t("Manifest"),
"Component": t("Component"),
"model_requirement": "@nest",
"capability": { "@id": t("capability"), "@type": "@vocab" },
"fallback": { "@id": t("fallback"), "@type": "@vocab" },
"companion_of": { "@id": t("companionOf"), "@type": "@vocab" },
"media": { "@id": t("media"), "@type": "@vocab", "@context": { "@vocab": t("media-") } },
"intent": { "@id": t("intent"), "@type": "xsd:string" },
"kind": { "@id": t("payloadKind"), "@type": "xsd:string" },
"role": { "@id": t("componentRole"), "@type": "xsd:string" },
"renditions": { "@id": t("renditions") },
"target": { "@id": t("target"), "@type": "@json" },
"ParameterSetPin": t("ParameterSetPin"),
// The pin (SPEC §3.1), as `conditioning.prior` or a component's `prior`:
// its members under the manifest's own names. The scoped context reaches
// the `supersedes` object too. `tier` is an untyped string so that a
// SHACL validator compares it with the shape's tier list.
"prior": { "@id": t("prior"), "@context": {
"id": { "@id": t("pinId"), "@type": "xsd:string" },
"sha256": { "@id": t("pinSha256"), "@type": "xsd:string" },
"determinism": { "@id": t("pinDeterminism"), "@type": "xsd:string" },
"form": { "@id": t("pinForm"), "@type": "xsd:string" },
"tier": { "@id": t("pinTier") },
"supersedes": { "@id": t("pinSupersedes") }
} }
}
}))
}
/// The generated table of `wai/REGISTRY.md` (the text between
/// [`REGISTRY_MD_BEGIN`] and [`REGISTRY_MD_END`], exclusive).
pub fn registry_md_table() -> String {
let dash = |o: Option<&str>| o.unwrap_or("—").to_string();
let mut o = String::new();
o.push_str("| string | kind | status | media | role | licence | replicate | sets | registered in |\n");
o.push_str("|---|---|---|---|---|---|---|---|---|\n");
for r in registrations() {
let sets = sets_of(&r);
o.push_str(&format!(
"| `{}` | {} | {} | {} | {} | {} | {} | {} | {} |\n",
r.capability,
r.kind.label(),
r.status.label(),
dash(r.media.map(Media::label)),
dash(r.role),
dash(r.licence.map(LicenseClass::label)),
dash(r.replicate.map(ReplicateClass::label)),
if sets.is_empty() { "—".to_string() } else { sets.join(", ") },
r.spec_section,
));
}
o.push('\n');
o.push_str("| identifier (not a capability) | meaning | in |\n|---|---|---|\n");
for i in IDENTIFIERS {
o.push_str(&format!("| `{}` | {} | {} |\n", i.identifier, i.meaning, i.spec_section));
}
o.push('\n');
o.push_str("| unregistered label | reason |\n|---|---|\n");
for l in UNREGISTERED_LABELS {
o.push_str(&format!("| `{}` | {} |\n", l.label, l.reason));
}
o.push('\n');
o.push_str("| wire identifier (not a capability) | kind | status | defined in |\n|---|---|---|---|\n");
for w in sorted_wire_identifiers() {
let doc = w.document.trim_end_matches(".md").trim_start_matches("extensions/");
o.push_str(&format!("| `{}` | {} | {} | {} {} |\n", w.name, w.kind.label(), w.status.label(), doc, w.section));
}
o
}
/// [`WIRE_IDENTIFIERS`] sorted by name, then kind: the order the export writes.
pub fn sorted_wire_identifiers() -> Vec<&'static WireIdentifier> {
let mut v: Vec<&WireIdentifier> = WIRE_IDENTIFIERS.iter().collect();
v.sort_by(|a, b| a.name.cmp(b.name).then(a.kind.cmp(&b.kind)));
v
}
/// `md` with the text between its [`REGISTRY_MD_BEGIN`] and [`REGISTRY_MD_END`]
/// lines replaced by [`registry_md_table`], or `None` if the markers are missing.
pub fn splice_registry_md(md: &str) -> Option<String> {
let b = md.find(REGISTRY_MD_BEGIN)? + REGISTRY_MD_BEGIN.len();
let e = md[b..].find(REGISTRY_MD_END)? + b;
Some(format!("{}\n{}{}", &md[..b], registry_md_table(), &md[e..]))
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
fn wai_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("..")
}
fn read(rel: &str) -> String {
let p = wai_dir().join(rel);
std::fs::read_to_string(&p).unwrap_or_else(|e| panic!("read {}: {e}", p.display()))
}
#[test]
fn the_table_covers_every_registered_string_once() {
let rows: Vec<&str> = ROWS.iter().map(|r| r.0).collect();
let mut sorted = rows.clone();
sorted.sort_unstable();
sorted.dedup();
assert_eq!(sorted.len(), rows.len(), "a string has two rows");
// Every payload and companion capability has a row, and every row is one
// of those or a record.
for &c in known_capabilities() {
assert!(rows.contains(&c), "{c} is registered but has no row");
}
for &c in &rows {
assert!(is_known_capability(c) || RECORDS.contains(&c), "{c} has a row but is not registered");
}
for &c in RECORDS {
assert!(rows.contains(&c), "record {c} has no row");
assert!(!is_known_capability(c), "record {c} must not be a dispatchable capability");
assert_eq!(capability_kind(c), Some(Kind::Record));
}
// Derivations are registered through the derivation table.
for op in derivation::derivation_operations() {
assert_eq!(capability_kind(op.capability), Some(Kind::Derivation));
assert!(!rows.contains(&op.capability));
}
// Identifiers and unregistered labels are not registered strings.
for i in IDENTIFIERS {
assert_eq!(capability_kind(i.identifier), None, "{}", i.identifier);
}
for l in UNREGISTERED_LABELS {
assert_eq!(capability_kind(l.label), None, "{}", l.label);
}
for r in registrations() {
assert!(r.registered.len() == 10 && r.registered.as_bytes()[4] == b'-', "{}", r.capability);
assert!(r.registered >= "2026-06-12", "{}: before the specification entered the repository", r.capability);
}
}
#[test]
fn candidates_are_the_registrations_with_no_pinned_payload() {
let mut c: Vec<&str> = known_capabilities().iter().copied().filter(|c| is_candidate(c)).collect();
c.sort_unstable();
assert_eq!(c, vec![CAP_SPLAT_SOG, CAP_TENSOR_NNC]);
for &cap in &c {
assert!(!mandatory_floor().contains(&cap) && !recommended_set().contains(&cap));
assert!(!sink_capabilities().contains(&cap));
assert!(!is_companion_only(cap));
assert!(!is_dispatchable(cap));
}
assert!(!is_candidate("wai.image.nope"));
assert_eq!(capability_status("wai.image.nope"), None);
// Among registered payload, companion and refinement capabilities,
// dispatchable is exactly: not companion-only, not refinement-only, not a
// candidate.
for &cap in known_capabilities() {
assert_eq!(is_dispatchable(cap), !is_companion_only(cap) && !is_refinement_only(cap) && !is_candidate(cap), "{cap}");
}
// Records and derivations name no payload format: never dispatched.
for &cap in RECORDS {
assert!(!is_dispatchable(cap), "{cap}");
}
assert!(!is_dispatchable(derivation::CAP_DERIVE_CROP));
// A string this revision does not register is left to the sink (SPEC §4,
// §8): a later MINOR revision may register it.
assert!(is_dispatchable("wai.image.nope"));
}
#[test]
fn licence_labels_are_the_spec_vocabulary() {
let l: Vec<&str> = LicenseClass::all().iter().map(|c| c.label()).collect();
assert_eq!(l, ["royalty-free", "patent-pool", "proprietary", "non-commercial"]);
}
#[test]
fn every_payload_and_companion_capability_has_a_media_class() {
for &c in known_capabilities() {
let m = capability_media(c).unwrap_or_else(|| panic!("{c} has no media class"));
// The video media class of §7.1 rule 2 is the video media here.
if is_video_class(c) {
assert_eq!(m, Media::Video, "{c}");
}
if is_companion_only(c) && c.starts_with("wai.meta.") {
assert_eq!(m, Media::Metadata, "{c}");
}
}
assert_eq!(capability_media(CAP_NEURAL_BMSHJ2018), Some(Media::Image));
assert_eq!(capability_media(CAP_SPLAT_SPZ), Some(Media::Volumetric));
assert_eq!(capability_media(CAP_VIDEO_MANIFEST), None);
assert_eq!(capability_media("wai.image.nope"), None);
}
/// The committed export is what this module renders, byte for byte. Fails on
/// a registry change that was not exported, and on a hand edit of an export.
/// Regenerate with `cargo run --no-default-features --bin wai -- registry export`.
#[test]
fn registry_export_matches_committed() {
for (rel, want) in export_files() {
assert!(read(rel) == want,
"wai/{rel} differs from the registry: run `cargo run --no-default-features --bin wai -- registry export` from wai/wai-rs");
}
let md = read("REGISTRY.md");
let want = splice_registry_md(&md).expect("REGISTRY.md has the generated markers");
assert!(md == want, "the generated table in wai/REGISTRY.md differs from the registry: run `wai registry export`");
}
/// The `ops` members (`extensions/integer-operators.md` §11). A `NeuralIntegerExact`
/// capability that carries one is at `acc64` with the full subset and names a
/// lowering of §13, and the export writes exactly these. In this revision
/// `wai.neural.int_synth`, `wai.splat.int_codec`, `wai.audio.int_codec`,
/// `wai.neural.int_hyper`, `wai.video.int_hyper` and `wai.neural.int_mlicpp` decode
/// through the operator set.
///
/// `wai.image.jpegai` carries one for its scale path and entropy decodes, at `acc32`
/// (§13.6.1).
///
/// `wai.video.int_motion` and the four `int_refine` capabilities, `StandardDefined`,
/// decode through its stage operators only (§13.5): no graph, so no profile, subset
/// or lowering, and E1's modes.
///
/// `wai.world.model` carries none. Its integer renderer renders through the operator
/// set too, lowered by `world/1`, but that lowering is informative (§13.5): the
/// capability's registered payload is its signed action trace, whose decode is the
/// replay, and no payload text yet binds a trace to a renderer's set.
#[test]
fn ops_members_name_the_operator_set_a_capability_decodes_through() {
const STAGE_ONLY: [&str; 5] = [CAP_VIDEO_INT_MOTION, CAP_IMAGE_INT_REFINE, CAP_VIDEO_INT_REFINE, CAP_AUDIO_INT_REFINE, CAP_SPLAT_INT_REFINE];
let regs = registrations();
let mut with: Vec<&str> = regs.iter().filter(|r| r.ops.is_some()).map(|r| r.capability).collect();
with.sort_unstable();
let mut want = vec![CAP_AUDIO_INT_CODEC, CAP_IMAGE_JPEGAI, CAP_NEURAL_INT_HYPER, CAP_NEURAL_INT_MLICPP, CAP_NEURAL_INT_SYNTH, CAP_SPLAT_INT_CODEC, CAP_VIDEO_INT_HYPER];
want.extend(STAGE_ONLY);
want.sort_unstable();
assert_eq!(with, want);
let world = regs.iter().find(|r| r.capability == CAP_WORLD_MODEL).expect("wai.world.model is registered");
assert!(world.ops.is_none() && world.replicate != Some(ReplicateClass::NeuralIntegerExact), "wai.world.model: its decode is the trace's replay; its renderer's lowering is informative");
for r in regs.iter().filter(|r| r.ops.is_some()) {
let o = r.ops.unwrap();
if STAGE_ONLY.contains(&r.capability) {
// No graph: the stage operators of §13.5, with E1's payload modes.
assert_eq!(r.replicate, Some(ReplicateClass::StandardDefined), "{}", r.capability);
assert_eq!((o.profile, o.subset, o.lowering, o.bucket), (None, None, None, None), "{}", r.capability);
assert_eq!(o.rans64, Some(("t4097", "lenient", "canonical")), "{}", r.capability);
continue;
}
// JPEG AI's integer stages decode through the operator set at acc64, its scale
// path, which its entropy-consistency claim covers, at acc32 (§13.6).
let (class, profile) = if r.capability == CAP_IMAGE_JPEGAI { (ReplicateClass::NeuralEntropyExact, "acc64") } else { (ReplicateClass::NeuralIntegerExact, "acc64") };
assert_eq!(r.replicate, Some(class), "{}", r.capability);
let roles: &[(&str, &str)] = if r.capability == CAP_IMAGE_JPEGAI { &[("hs_y", "acc32"), ("hs_uv", "acc32")] } else { &[] };
assert_eq!(o.role_profiles, roles, "{}", r.capability);
assert_eq!((o.profile, o.subset), (Some(profile), Some("full")), "{}", r.capability);
assert!(o.lowering.is_some_and(|l| ["int_synth/1", "whm1/1", "wam1/1", "wmb1/1", "world/1", "jpegai-int/1"].contains(&l)), "{}", r.capability);
}
let export: serde_json::Value = serde_json::from_str(&read("registry/capabilities.json")).unwrap();
for c in export["capabilities"].as_array().unwrap() {
let want = match c["capability"].as_str().unwrap() {
CAP_NEURAL_INT_SYNTH => serde_json::json!({ "set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "int_synth/1" }),
CAP_SPLAT_INT_CODEC => serde_json::json!({
"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "whm1/1",
"stage": { "rans64": { "table": "t4097", "escape": "lenient", "end": "canonical" } }
}),
CAP_AUDIO_INT_CODEC => serde_json::json!({
"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "wam1/1",
"stage": { "rans64": { "table": "t4097", "escape": "lenient", "end": "canonical" } }
}),
CAP_NEURAL_INT_HYPER | CAP_VIDEO_INT_HYPER => serde_json::json!({
"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "whm1/1",
"stage": { "rans64": { "table": "t4097", "escape": "lenient", "end": "canonical" }, "bucket": "ceil" }
}),
c if STAGE_ONLY.contains(&c) => serde_json::json!({
"set": "wai-ops/1",
"stage": { "rans64": { "table": "t4097", "escape": "lenient", "end": "canonical" } }
}),
CAP_IMAGE_JPEGAI => serde_json::json!({
"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "jpegai-int/1",
"role_profiles": { "hs_y": "acc32", "hs_uv": "acc32" }
}),
CAP_NEURAL_INT_MLICPP => serde_json::json!({
"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "wmb1/1",
"stage": { "rans64": { "table": "t2", "escape": "lenient", "end": "final_only" }, "bucket": "ceil" }
}),
_ => serde_json::Value::Null,
};
assert_eq!(c["ops"], want, "{}", c["capability"]);
}
}
/// The schema's enums are the label sets the registry uses.
#[test]
fn registry_schema_enums_equal_labels() {
let schema: serde_json::Value = serde_json::from_str(&read("registry/capabilities.schema.json")).unwrap();
let props = &schema["properties"]["capabilities"]["items"]["properties"];
let enum_of = |field: &str| -> Vec<String> {
let e = props[field]["enum"].as_array().unwrap_or_else(|| panic!("{field} has no enum"));
e.iter().filter_map(|v| v.as_str().map(String::from)).collect()
};
let labels = |v: Vec<&str>| v.into_iter().map(String::from).collect::<Vec<_>>();
assert_eq!(enum_of("kind"), labels(Kind::all().iter().map(|k| k.label()).collect()));
assert_eq!(enum_of("status"), labels(RegistrationStatus::all().iter().map(|s| s.label()).collect()));
assert_eq!(enum_of("media"), labels(Media::all().iter().map(|m| m.label()).collect()));
assert_eq!(enum_of("role"), labels(ROLE_LABELS.to_vec()));
assert_eq!(enum_of("tier"), labels(FidelityTier::all().iter().map(|t| t.label()).collect()));
assert_eq!(enum_of("licence"), labels(LicenseClass::all().iter().map(|l| l.label()).collect()));
assert_eq!(enum_of("replicate"), labels(ReplicateClass::all().iter().map(|r| r.label()).collect()));
// Every value the export writes is in its enum.
let export: serde_json::Value = serde_json::from_str(&read("registry/capabilities.json")).unwrap();
for c in export["capabilities"].as_array().unwrap() {
for field in ["kind", "status", "media", "role", "tier", "licence", "replicate"] {
let v = &c[field];
let allowed = &props[field]["enum"];
assert!(allowed.as_array().unwrap().contains(v), "{}: {field} {v} not in the schema", c["capability"]);
}
}
}
/// The backticked `wai.*` strings of `wai/SPEC.md` and the export name the same
/// set: every string SPEC uses is a registered string, an identifier, or a
/// pattern (`wai.derive.*`) that matches registered strings; and every
/// registered string appears in SPEC, literally or under a pattern SPEC states
/// as a group registration.
#[test]
fn spec_and_registry_name_the_same_strings() {
let spec = read("SPEC.md");
let mut used: Vec<String> = Vec::new();
for (i, _) in spec.match_indices("`wai.") {
let rest = &spec[i + 1..];
let end = rest.find('`').unwrap_or(0);
let s = &rest[..end];
if s.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || matches!(c, '.' | '_' | '*')) {
used.push(s.to_string());
}
}
used.sort();
used.dedup();
assert!(!used.is_empty());
let regs = registrations();
let registered: Vec<&str> = regs.iter().map(|r| r.capability).collect();
let ids: Vec<&str> = IDENTIFIERS.iter().map(|i| i.identifier).collect();
let mut problems = Vec::new();
for s in &used {
if let Some(prefix) = s.strip_suffix('*') {
if !registered.iter().chain(ids.iter()).any(|r| r.starts_with(prefix)) {
problems.push(format!("SPEC pattern `{s}` matches no registered string"));
}
} else if !registered.contains(&s.as_str()) && !ids.contains(&s.as_str()) {
problems.push(format!("SPEC names `{s}`, which the registry does not register"));
}
}
// Group registrations: SPEC registers the derivation operations as a group,
// `wai.derive.*`, with derived-tracks.md listing each.
const GROUPS: &[&str] = &["wai.derive."];
for r in &regs {
let literal = used.iter().any(|u| u == r.capability);
let grouped = GROUPS.iter().any(|g| r.capability.starts_with(g) && used.iter().any(|u| u == &format!("{g}*")));
if !literal && !grouped {
problems.push(format!("{} is registered but SPEC does not name it", r.capability));
}
}
for i in IDENTIFIERS {
if !used.iter().any(|u| u == i.identifier) {
problems.push(format!("identifier {} does not appear in SPEC", i.identifier));
}
}
// Every section a row names is a heading of SPEC §5.
for r in &regs {
let heading = r.spec_section.strip_prefix("§5 ").expect("a §5 section");
if !spec.lines().any(|l| l.starts_with("### ") && l[4..].starts_with(heading)) {
problems.push(format!("{}: SPEC has no §5 heading `{heading}`", r.capability));
}
}
assert!(problems.is_empty(), "SPEC and the registry disagree:\n{}", problems.join("\n"));
}
/// SPEC §5, *Payloads of the WAI-native integer codecs*, pins exactly the strings
/// and formats of `PINNED_INT_PAYLOADS`, and names each string's parameter-set
/// members as `int_payload` reads them; the extension defines each format in its
/// own section.
#[test]
fn spec_pins_the_integer_payloads_the_registry_lists() {
let spec = read("SPEC.md");
let at = spec.find("### Payloads of the WAI-native integer codecs").expect("the SPEC §5 subsection");
let section = &spec[at..];
let section = &section[..section[4..].find("\n### ").map_or(section.len(), |e| e + 4)];
let mut rows: Vec<(String, String, String)> = Vec::new();
for line in section.lines().filter(|l| l.starts_with("| `wai.")) {
let cells: Vec<&str> = line.split('|').map(str::trim).collect();
let tick = |c: &str| c.split('`').nth(1).unwrap_or_default().to_string();
rows.push((tick(cells[1]), tick(cells[2]), cells[3].to_string()));
}
let mut want: Vec<(String, String)> = super::super::PINNED_INT_PAYLOADS.iter()
.map(|(c, m)| (c.to_string(), String::from_utf8_lossy(m).into_owned())).collect();
let mut got: Vec<(String, String)> = rows.iter().map(|(c, m, _)| (c.clone(), m.clone())).collect();
want.sort();
got.sort();
assert_eq!(got, want, "SPEC's table and PINNED_INT_PAYLOADS");
// Each row's set: its shape is the registry's, and its members are named.
let members: &[(&str, &[&str])] = &[
(CAP_VIDEO_INT_MOTION, &[]),
(CAP_VIDEO_INT_HYPER, &["g_s.whm", "h_s.whm", "entropy.json"]),
(CAP_NEURAL_INT_HYPER, &["g_s.whm", "h_s.whm", "entropy.json"]),
(CAP_AUDIO_INT_CODEC, &["model.wam"]),
(CAP_SPLAT_INT_CODEC, &["g_s.whm"]),
];
for (cap, _, set) in &rows {
let (_, names) = members.iter().find(|(c, _)| c == cap).expect("a pinned string");
let shape = match crate::codecs::parameter_set_shape(cap) {
None => "none",
Some(crate::codecs::ParameterSetShape::OneFile) => "one file",
Some(crate::codecs::ParameterSetShape::SeveralFiles) => "several files",
};
assert!(set.starts_with(shape), "{cap}: SPEC says `{set}`, the registry {shape}");
for n in *names {
assert!(set.contains(&format!("`{n}`")), "{cap}: SPEC names no `{n}`");
}
}
let ext = read("extensions/integer-payloads.md");
for (heading, magic) in [("## 3.", "WIV1"), ("## 4.", "WIH1"), ("## 5.", "WIA1"), ("## 6.", "WIS1")] {
assert!(ext.lines().any(|l| l.starts_with(heading) && l.contains(&format!("`{magic}`"))), "the extension's {heading} is {magic}");
}
}
#[test]
fn vocab_v2_names_every_registered_string_and_no_candidate_as_emittable() {
let shapes = vocab_v2_shapes();
for r in registrations() {
let iri = format!("wai:{}\n", r.capability);
let in_shapes = shapes.contains(&format!(" {iri}"));
let emittable = matches!(r.kind, Kind::Payload | Kind::Companion | Kind::Refinement) && r.status == RegistrationStatus::Registered;
assert_eq!(in_shapes, emittable, "{}", r.capability);
assert!(vocab_v2_ttl().contains(&format!("wai:{} a wai:Capability", r.capability)), "{}", r.capability);
}
}
/// Every IRI v2.ttl defines (a line `wai:<local> a …`) is defined once: no
/// enumeration individual shares an IRI with another enumeration's, with a
/// property, or with a class. And the JSON-LD context maps a manifest's `kind`
/// and a component's `role` to terms of their own, not to the registry's.
#[test]
fn vocab_v2_defines_each_iri_once() {
let ttl = vocab_v2_ttl();
let mut defined: Vec<&str> = ttl
.lines()
.filter_map(|l| l.strip_prefix("wai:"))
.filter_map(|l| l.split_once(" a ").map(|(local, _)| local))
.collect();
let n = defined.len();
defined.sort_unstable();
defined.dedup();
assert_eq!(defined.len(), n, "an IRI of v2.ttl is defined twice");
for (_, prefix, labels) in enumerations() {
for l in labels {
assert!(defined.contains(&individual(prefix, l).as_str()), "{prefix}-{l}");
}
}
let ctx: serde_json::Value = serde_json::from_str(&vocab_v2_jsonld()).unwrap();
let ctx = &ctx["@context"];
assert_eq!(ctx["kind"]["@id"], format!("{VOCAB_V2_NS}payloadKind"));
assert_eq!(ctx["role"]["@id"], format!("{VOCAB_V2_NS}componentRole"));
assert_eq!(ctx["media"]["@context"]["@vocab"], format!("{VOCAB_V2_NS}media-"));
// Every term the context maps to the namespace names an IRI v2.ttl defines.
for (term, def) in ctx.as_object().unwrap().iter().filter(|(t, _)| !t.starts_with('@')) {
let id = def.get("@id").and_then(|v| v.as_str()).or_else(|| def.as_str()).unwrap_or("");
if let Some(local) = id.strip_prefix(VOCAB_V2_NS) {
assert!(defined.contains(&local), "context term {term} maps to wai:{local}, which v2.ttl does not define");
}
}
}
#[test]
fn splice_replaces_only_the_generated_region() {
let md = format!("head\n{REGISTRY_MD_BEGIN}\nstale\n{REGISTRY_MD_END}\ntail\n");
let out = splice_registry_md(&md).unwrap();
assert!(out.starts_with(&format!("head\n{REGISTRY_MD_BEGIN}\n| string |")));
assert!(out.ends_with(&format!("{REGISTRY_MD_END}\ntail\n")));
assert!(!out.contains("stale"));
assert_eq!(splice_registry_md("no markers"), None);
}
/// The body of a numbered section (`§N`) or an appendix (`Appendix X`) of a WAI text:
/// from its heading to the next heading of its level or above, subsections included.
fn section_body<'a>(text: &'a str, section: &str) -> Option<&'a str> {
let level = |l: &str| l.bytes().take_while(|&b| b == b'#').count();
let mut starts = Vec::new();
let mut at = 0;
for l in text.split_inclusive('\n') {
starts.push((at, l));
at += l.len();
}
let is_heading = |l: &str| l.starts_with('#') && l[level(l)..].starts_with(' ');
let (k, (start, line)) = starts.iter().enumerate().find(|(_, (_, l))| {
is_heading(l) && {
let t = l[level(l) + 1..].trim_end();
match section.strip_prefix('§') {
Some(num) => t.starts_with(&format!("{num} ")) || t.starts_with(&format!("{num}. ")) || t == num,
None => t.starts_with(section),
}
}
})?;
let lv = level(line);
let end = starts[k + 1..].iter().find(|(_, l)| is_heading(l) && level(l) <= lv).map_or(text.len(), |(o, _)| *o);
Some(&text[*start..end])
}
/// Every wire identifier is written in the body of the section of the document it
/// names (not just somewhere in the document), and no name is listed twice with one
/// kind.
#[test]
fn wire_identifiers_are_in_their_documents() {
let mut seen = std::collections::BTreeSet::new();
for w in WIRE_IDENTIFIERS {
assert!(seen.insert((w.name, w.kind)), "{} ({}) is listed twice", w.name, w.kind.label());
let text = read(w.document);
let body = section_body(&text, w.section).unwrap_or_else(|| panic!("{} has no section {} for {}", w.document, w.section, w.name));
assert!(body.contains(w.name), "{} is not written in {} {}", w.name, w.document, w.section);
}
}
/// The schema's wire-identifier enums are the labels, and the export writes only
/// values in them.
#[test]
fn wire_identifier_schema_enums_equal_labels() {
let schema: serde_json::Value = serde_json::from_str(&read("registry/capabilities.schema.json")).unwrap();
let props = &schema["properties"]["wire_identifiers"]["items"]["properties"];
let enum_of = |field: &str| -> Vec<String> {
props[field]["enum"].as_array().unwrap_or_else(|| panic!("{field} has no enum"))
.iter().filter_map(|v| v.as_str().map(String::from)).collect()
};
assert_eq!(enum_of("kind"), WireKind::all().iter().map(|k| k.label().to_string()).collect::<Vec<_>>());
assert_eq!(enum_of("status"), WireStatus::all().iter().map(|s| s.label().to_string()).collect::<Vec<_>>());
let export: serde_json::Value = serde_json::from_str(&read("registry/capabilities.json")).unwrap();
let rows = export["wire_identifiers"].as_array().unwrap();
assert_eq!(rows.len(), WIRE_IDENTIFIERS.len());
for r in rows {
for field in ["kind", "status"] {
assert!(enum_of(field).iter().any(|e| r[field] == *e), "{field} {} is not in the schema", r[field]);
}
}
}
/// The record and label strings copied from wai-quantum equal its constants.
#[cfg(feature = "quantum_ops")]
#[test]
fn quantum_strings_equal_the_wai_quantum_constants() {
use wai_quantum::quantum_ops as q;
assert_eq!(CAP_QUANTUM_CALIBRATION, q::CAP_QUANTUM_CALIBRATION);
assert_eq!(CAP_QUANTUM_JOB, q::CAP_QUANTUM_JOB);
let labels: Vec<&str> = UNREGISTERED_LABELS.iter().map(|l| l.label).collect();
assert_eq!(labels, [q::CAP_QUANTUM_MITIGATE, q::CAP_QUANTUM_DECODE, q::CAP_QUANTUM_COMPILE,
q::CAP_QUANTUM_REARRANGE, q::CAP_QUANTUM_QBOM, q::CAP_QUANTUM_FABRIC]);
}
}