Skip to main content

provable_contracts/schema/
kind.rs

1//! Contract kinds — declare which validation rules apply to a YAML file.
2
3use serde::{Deserialize, Serialize};
4
5/// The kind of contract artifact. Determines which validation rules apply.
6///
7/// - `Kernel` (default): a mathematical kernel contract — the provability
8///   invariant applies (must have `proof_obligations`, `falsification_tests`,
9///   `kani_harnesses`).
10/// - `Registry`: a data registry (lookup tables, enum definitions, config
11///   bounds) — exempt from provability, validated for `metadata` + entries.
12/// - `ModelFamily`: architecture metadata (`HuggingFace` family descriptors,
13///   size variants, vendor) — exempt from provability, validated for
14///   `metadata` fields. Custom top-level fields are preserved but not
15///   enforced by the kernel schema.
16/// - `ModelFamilyVariant`: a concrete size variant of a model family
17///   (e.g. Llama 370M sovereign). Freezes hyperparameters (vocab, hidden
18///   dim, layer count) and delta-dispatches invariants from the parent
19///   family. Exempt from provability.
20/// - `Tokenizer`: a concrete tokenizer contract — vocab bounds, required
21///   special tokens, round-trip gate, normalization form. Exempt from
22///   provability (gates are byte-exact tests, not Kani harnesses).
23/// - `TrainingLoop`: a training-loop contract — loss schedule, optimizer
24///   config, gradient-clipping policy, checkpoint cadence. Exempt from
25///   provability; validated for `metadata` + schedule fields.
26/// - `PretrainingCorpus`: a pretraining-corpus contract — dataset source,
27///   license, total-bytes bound, shard layout. Exempt from provability.
28/// - `TrainingPreconditionGate`: a hard precondition gate that must be
29///   satisfied before training starts (e.g. Chinchilla compute-optimal
30///   token/parameter ratio, GPU memory floor, dataset checksum). Exempt
31///   from provability; validated for `metadata` + gate-formula fields.
32/// - `CorpusAssembly`: a multi-source corpus assembly pipeline contract —
33///   declares input shards, dedup strategy, license-merge policy, and
34///   output manifest. Exempt from provability.
35/// - `Pattern`: a cross-cutting verification pattern (threading safety,
36///   async safety, compute parity) that applies across multiple kernels.
37///   Exempt from the kernel provability invariant but still validated for
38///   metadata and any proof/falsification data present.
39/// - `Schema`: a generic reference/schema document — exempt from provability,
40///   validated only for `metadata.id`, `metadata.version`, `metadata.description`,
41///   and `metadata.references`.
42#[derive(
43    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
44)]
45#[serde(rename_all = "kebab-case")]
46pub enum ContractKind {
47    #[default]
48    Kernel,
49    Registry,
50    ModelFamily,
51    ModelFamilyVariant,
52    Tokenizer,
53    TrainingLoop,
54    PretrainingCorpus,
55    TrainingPreconditionGate,
56    CorpusAssembly,
57    Pattern,
58    Schema,
59    /// A head-to-head BEAT benchmark: a committed, CI-wired claim that aprender
60    /// beats an incumbent (sklearn / PyTorch / Unsloth / Ollama) on a canonical
61    /// task, with a pinned baseline that fails CI on regression. The measurement
62    /// backbone for the four-pillar "replace AND beat" mission (PMAT-741).
63    BeatBenchmark,
64}
65
66impl std::fmt::Display for ContractKind {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        let s = match self {
69            Self::Kernel => "kernel",
70            Self::Registry => "registry",
71            Self::ModelFamily => "model-family",
72            Self::ModelFamilyVariant => "model-family-variant",
73            Self::Tokenizer => "tokenizer",
74            Self::TrainingLoop => "training-loop",
75            Self::PretrainingCorpus => "pretraining-corpus",
76            Self::TrainingPreconditionGate => "training-precondition-gate",
77            Self::CorpusAssembly => "corpus-assembly",
78            Self::Pattern => "pattern",
79            Self::Schema => "schema",
80            Self::BeatBenchmark => "beat-benchmark",
81        };
82        write!(f, "{s}")
83    }
84}
85
86#[cfg(test)]
87mod beat_benchmark_tests {
88    use super::*;
89    use crate::error::Severity;
90    use crate::schema::{parse_contract_str, validate_contract};
91
92    /// BeatBenchmark serde round-trips through its kebab-case "beat-benchmark".
93    #[test]
94    fn beat_benchmark_kind_round_trips() {
95        assert_eq!(ContractKind::BeatBenchmark.to_string(), "beat-benchmark");
96        let k: ContractKind = serde_yaml::from_str("beat-benchmark").unwrap();
97        assert_eq!(k, ContractKind::BeatBenchmark);
98    }
99
100    /// The pilot beat contract (contracts/beat-sklearn-iris-v1.yaml) parses as a
101    /// BeatBenchmark and validates with zero Error-severity violations (PMAT-741).
102    #[test]
103    fn pilot_beat_contract_validates() {
104        let yaml = include_str!("../../../../contracts/beat-sklearn-iris-v1.yaml");
105        let contract = parse_contract_str(yaml).expect("pilot beat contract parses");
106        assert_eq!(contract.kind(), ContractKind::BeatBenchmark);
107        let errors: Vec<_> = validate_contract(&contract)
108            .into_iter()
109            .filter(|v| v.severity == Severity::Error)
110            .collect();
111        assert!(
112            errors.is_empty(),
113            "pilot beat contract has errors: {errors:?}"
114        );
115    }
116}