Skip to main content

ferrum_interfaces/vnext/execution/
determinism_coverage.rs

1use std::collections::{BTreeMap, BTreeSet};
2
3use serde::{Deserialize, Serialize};
4use sha2::{Digest, Sha256};
5
6use super::is_canonical_sha256;
7use crate::vnext::{
8    CapabilityCatalog, ContractVersion, DeviceId, ExternalModelMetadataId, NodeId, OperationId,
9    PlanHash, ProviderExecutionContractFingerprint, ProviderId, ProviderReplayEquivalence,
10    ResolvedModelPlan, VNextError,
11};
12
13use super::{invalid_plan, ExecutionDeterminismWitnessPlan};
14
15pub const EXECUTION_DETERMINISM_COVERAGE_VERSION: ContractVersion = ContractVersion::new(1, 0);
16pub const EXECUTION_DETERMINISM_EVIDENCE_DENOMINATOR_VERSION: ContractVersion =
17    ContractVersion::new(1, 1);
18
19const MAX_COVERAGE_WIRE_BYTES: usize = 16 * 1024 * 1024;
20const MAX_EVIDENCE_DENOMINATOR_WIRE_BYTES: usize = 128 * 1024 * 1024;
21const MAX_COVERAGE_MODELS: usize = 32;
22const MAX_COVERAGE_PROVIDERS: usize = 512;
23const MAX_COVERAGE_NODES_PER_MODEL: usize = 65_536;
24const MAX_MODEL_KEY_BYTES: usize = 96;
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
27#[serde(rename_all = "snake_case")]
28pub enum ExecutionDeterminismComparisonKind {
29    EagerEager,
30    ReplayReplay,
31    EagerReplay,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum ExecutionDeterminismProviderCoverage {
37    AllCatalogProviders,
38    SelectedPlanProviders,
39}
40
41impl ExecutionDeterminismComparisonKind {
42    fn for_replay_equivalence(
43        replay_equivalence: ProviderReplayEquivalence,
44    ) -> Vec<ExecutionDeterminismComparisonKind> {
45        let mut comparisons = vec![Self::EagerEager];
46        if replay_equivalence == ProviderReplayEquivalence::BitwiseEagerEquivalent {
47            comparisons.extend([Self::ReplayReplay, Self::EagerReplay]);
48        }
49        comparisons
50    }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
54#[serde(deny_unknown_fields)]
55pub struct ExecutionDeterminismModelPlanIdentity {
56    model_key: String,
57    external_metadata_id: ExternalModelMetadataId,
58    resolved_plan_fingerprint: String,
59    plan_hash: PlanHash,
60    node_ids: Vec<NodeId>,
61}
62
63impl ExecutionDeterminismModelPlanIdentity {
64    pub fn model_key(&self) -> &str {
65        &self.model_key
66    }
67
68    pub fn external_metadata_id(&self) -> &ExternalModelMetadataId {
69        &self.external_metadata_id
70    }
71
72    pub fn resolved_plan_fingerprint(&self) -> &str {
73        &self.resolved_plan_fingerprint
74    }
75
76    pub fn plan_hash(&self) -> &PlanHash {
77        &self.plan_hash
78    }
79
80    pub fn node_ids(&self) -> &[NodeId] {
81        &self.node_ids
82    }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(deny_unknown_fields)]
87pub struct ExecutionDeterminismModelProviderSelection {
88    model_key: String,
89    resolved_plan_fingerprint: String,
90    plan_hash: PlanHash,
91    node_ids: Vec<NodeId>,
92}
93
94impl ExecutionDeterminismModelProviderSelection {
95    pub fn model_key(&self) -> &str {
96        &self.model_key
97    }
98
99    pub fn resolved_plan_fingerprint(&self) -> &str {
100        &self.resolved_plan_fingerprint
101    }
102
103    pub fn plan_hash(&self) -> &PlanHash {
104        &self.plan_hash
105    }
106
107    pub fn node_ids(&self) -> &[NodeId] {
108        &self.node_ids
109    }
110}
111
112#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
113#[serde(deny_unknown_fields)]
114pub struct ExecutionDeterminismCatalogProviderRequirement {
115    operation_id: OperationId,
116    operation_version: ContractVersion,
117    operation_fingerprint: String,
118    provider_id: ProviderId,
119    provider_version: ContractVersion,
120    provider_implementation_fingerprint: String,
121    provider_execution_contract_fingerprint: ProviderExecutionContractFingerprint,
122    replay_equivalence: ProviderReplayEquivalence,
123    required_comparisons: Vec<ExecutionDeterminismComparisonKind>,
124    model_selections: Vec<ExecutionDeterminismModelProviderSelection>,
125}
126
127impl ExecutionDeterminismCatalogProviderRequirement {
128    pub fn operation_id(&self) -> &OperationId {
129        &self.operation_id
130    }
131
132    pub const fn operation_version(&self) -> ContractVersion {
133        self.operation_version
134    }
135
136    pub fn operation_fingerprint(&self) -> &str {
137        &self.operation_fingerprint
138    }
139
140    pub fn provider_id(&self) -> &ProviderId {
141        &self.provider_id
142    }
143
144    pub const fn provider_version(&self) -> ContractVersion {
145        self.provider_version
146    }
147
148    pub fn provider_implementation_fingerprint(&self) -> &str {
149        &self.provider_implementation_fingerprint
150    }
151
152    pub const fn provider_execution_contract_fingerprint(
153        &self,
154    ) -> ProviderExecutionContractFingerprint {
155        self.provider_execution_contract_fingerprint
156    }
157
158    pub const fn replay_equivalence(&self) -> ProviderReplayEquivalence {
159        self.replay_equivalence
160    }
161
162    pub fn required_comparisons(&self) -> &[ExecutionDeterminismComparisonKind] {
163        &self.required_comparisons
164    }
165
166    pub fn model_selections(&self) -> &[ExecutionDeterminismModelProviderSelection] {
167        &self.model_selections
168    }
169
170    fn canonical_key(&self) -> (&OperationId, &ProviderId) {
171        (&self.operation_id, &self.provider_id)
172    }
173}
174
175/// Runtime-derived proof denominator for one CUDA catalog and every resolved
176/// model plan admitted to the release matrix.
177///
178/// Providers with no selected model nodes remain present with an empty
179/// `model_selections` list. The hardware validator must reject that gap rather
180/// than silently shrinking the denominator.
181#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
182#[serde(deny_unknown_fields)]
183pub struct ExecutionDeterminismCoverageRegistry {
184    schema_version: ContractVersion,
185    device_id: DeviceId,
186    device_runtime_implementation_fingerprint: String,
187    capability_catalog_fingerprint: String,
188    models: Vec<ExecutionDeterminismModelPlanIdentity>,
189    provider_requirements: Vec<ExecutionDeterminismCatalogProviderRequirement>,
190}
191
192impl ExecutionDeterminismCoverageRegistry {
193    pub fn from_catalog(catalog: &CapabilityCatalog) -> Result<Self, VNextError> {
194        let mut provider_requirements = Vec::new();
195        for (operation_id, providers) in catalog.providers() {
196            let operation = catalog.operations().get(operation_id).ok_or_else(|| {
197                invalid_plan(format!(
198                    "determinism coverage catalog provider row `{operation_id}` has no operation"
199                ))
200            })?;
201            let operation_fingerprint = operation.fingerprint()?;
202            for provider in providers {
203                let semantics = provider.execution_semantics();
204                provider_requirements.push(ExecutionDeterminismCatalogProviderRequirement {
205                    operation_id: operation_id.clone(),
206                    operation_version: operation.version,
207                    operation_fingerprint: operation_fingerprint.clone(),
208                    provider_id: provider.provider_id().clone(),
209                    provider_version: provider.version(),
210                    provider_implementation_fingerprint: provider
211                        .provider_implementation_fingerprint()
212                        .to_owned(),
213                    provider_execution_contract_fingerprint: semantics.contract_fingerprint(),
214                    replay_equivalence: semantics.replay_equivalence(),
215                    required_comparisons:
216                        ExecutionDeterminismComparisonKind::for_replay_equivalence(
217                            semantics.replay_equivalence(),
218                        ),
219                    model_selections: Vec::new(),
220                });
221            }
222        }
223        provider_requirements
224            .sort_by(|left, right| left.canonical_key().cmp(&right.canonical_key()));
225        let registry = Self {
226            schema_version: EXECUTION_DETERMINISM_COVERAGE_VERSION,
227            device_id: catalog.device().id.clone(),
228            device_runtime_implementation_fingerprint: catalog
229                .device()
230                .runtime_implementation_fingerprint
231                .clone(),
232            capability_catalog_fingerprint: catalog.fingerprint()?,
233            models: Vec::new(),
234            provider_requirements,
235        };
236        registry.validate_shape(false)?;
237        Ok(registry)
238    }
239
240    pub fn try_add_resolved_model_plan(
241        &mut self,
242        model_key: impl Into<String>,
243        plan: &ResolvedModelPlan,
244    ) -> Result<(), VNextError> {
245        let model_key = model_key.into();
246        validate_model_key(&model_key)?;
247        if self.models.len() >= MAX_COVERAGE_MODELS {
248            return Err(invalid_plan(
249                "execution determinism coverage model count exceeds its bound",
250            ));
251        }
252        if self.models.iter().any(|model| {
253            model.model_key == model_key
254                || model.external_metadata_id == plan.parts().external_metadata_id
255                || model.resolved_plan_fingerprint == plan.fingerprint()
256        }) {
257            return Err(invalid_plan(
258                "execution determinism coverage cannot reuse a model key, metadata identity, or resolved plan",
259            ));
260        }
261        if plan.parts().device.id != self.device_id
262            || plan.parts().device.runtime_implementation_fingerprint
263                != self.device_runtime_implementation_fingerprint
264            || plan.parts().capabilities.fingerprint()? != self.capability_catalog_fingerprint
265        {
266            return Err(invalid_plan(
267                "resolved model plan differs from the determinism coverage catalog or device runtime",
268            ));
269        }
270        let plan_nodes = plan.execution_plan().payload().nodes();
271        if plan_nodes.is_empty() || plan_nodes.len() > MAX_COVERAGE_NODES_PER_MODEL {
272            return Err(invalid_plan(
273                "resolved model plan is empty or exceeds the determinism coverage node bound",
274            ));
275        }
276
277        let mut selected_nodes = BTreeMap::<(OperationId, ProviderId), Vec<NodeId>>::new();
278        for node in plan_nodes {
279            let key = (
280                node.operation_id().clone(),
281                node.selection().selected_provider().clone(),
282            );
283            let requirement = self
284                .provider_requirements
285                .binary_search_by(|candidate| candidate.canonical_key().cmp(&(&key.0, &key.1)))
286                .ok()
287                .and_then(|index| self.provider_requirements.get(index))
288                .ok_or_else(|| {
289                    invalid_plan(format!(
290                        "resolved node `{}` selected provider `{}` absent from the live determinism catalog",
291                        node.id(),
292                        node.selection().selected_provider()
293                    ))
294                })?;
295            if !requirement
296                .operation_version
297                .satisfies(node.operation_version())
298            {
299                return Err(invalid_plan(format!(
300                    "resolved node `{}` requires operation version {}, but the live catalog provides {}",
301                    node.id(),
302                    node.operation_version(),
303                    requirement.operation_version
304                )));
305            }
306            if node.operation_fingerprint() != requirement.operation_fingerprint {
307                return Err(invalid_plan(format!(
308                    "resolved node `{}` differs from its live catalog operation fingerprint",
309                    node.id()
310                )));
311            }
312            if node.provider_implementation_fingerprint()
313                != requirement.provider_implementation_fingerprint
314            {
315                return Err(invalid_plan(format!(
316                    "resolved node `{}` differs from its live catalog provider implementation fingerprint",
317                    node.id()
318                )));
319            }
320            if node.provider_execution_semantics().contract_fingerprint()
321                != requirement.provider_execution_contract_fingerprint
322            {
323                return Err(invalid_plan(format!(
324                    "resolved node `{}` differs from its live catalog provider execution contract",
325                    node.id()
326                )));
327            }
328            if node.provider_execution_semantics().replay_equivalence()
329                != requirement.replay_equivalence
330            {
331                return Err(invalid_plan(format!(
332                    "resolved node `{}` differs from its live catalog replay equivalence",
333                    node.id()
334                )));
335            }
336            selected_nodes
337                .entry(key)
338                .or_default()
339                .push(node.id().clone());
340        }
341
342        let identity = ExecutionDeterminismModelPlanIdentity {
343            model_key: model_key.clone(),
344            external_metadata_id: plan.parts().external_metadata_id.clone(),
345            resolved_plan_fingerprint: plan.fingerprint().to_owned(),
346            plan_hash: plan.execution_plan().plan_hash().clone(),
347            node_ids: plan_nodes.iter().map(|node| node.id().clone()).collect(),
348        };
349        let mut next_requirements = self.provider_requirements.clone();
350        for requirement in &mut next_requirements {
351            if let Some(node_ids) = selected_nodes.remove(&(
352                requirement.operation_id.clone(),
353                requirement.provider_id.clone(),
354            )) {
355                requirement
356                    .model_selections
357                    .push(ExecutionDeterminismModelProviderSelection {
358                        model_key: model_key.clone(),
359                        resolved_plan_fingerprint: identity.resolved_plan_fingerprint.clone(),
360                        plan_hash: identity.plan_hash.clone(),
361                        node_ids,
362                    });
363                requirement
364                    .model_selections
365                    .sort_by(|left, right| left.model_key.cmp(&right.model_key));
366            }
367        }
368        if !selected_nodes.is_empty() {
369            return Err(invalid_plan(
370                "resolved model plan left unmatched determinism provider selections",
371            ));
372        }
373
374        let mut next_models = self.models.clone();
375        next_models.push(identity);
376        next_models.sort_by(|left, right| left.model_key.cmp(&right.model_key));
377        let candidate = Self {
378            schema_version: self.schema_version,
379            device_id: self.device_id.clone(),
380            device_runtime_implementation_fingerprint: self
381                .device_runtime_implementation_fingerprint
382                .clone(),
383            capability_catalog_fingerprint: self.capability_catalog_fingerprint.clone(),
384            models: next_models,
385            provider_requirements: next_requirements,
386        };
387        candidate.validate_shape(true)?;
388        *self = candidate;
389        Ok(())
390    }
391
392    pub const fn schema_version(&self) -> ContractVersion {
393        self.schema_version
394    }
395
396    pub fn device_id(&self) -> &DeviceId {
397        &self.device_id
398    }
399
400    pub fn device_runtime_implementation_fingerprint(&self) -> &str {
401        &self.device_runtime_implementation_fingerprint
402    }
403
404    pub fn capability_catalog_fingerprint(&self) -> &str {
405        &self.capability_catalog_fingerprint
406    }
407
408    pub fn models(&self) -> &[ExecutionDeterminismModelPlanIdentity] {
409        &self.models
410    }
411
412    pub fn provider_requirements(&self) -> &[ExecutionDeterminismCatalogProviderRequirement] {
413        &self.provider_requirements
414    }
415
416    pub fn unselected_provider_requirements(
417        &self,
418    ) -> impl Iterator<Item = &ExecutionDeterminismCatalogProviderRequirement> {
419        self.provider_requirements
420            .iter()
421            .filter(|requirement| requirement.model_selections.is_empty())
422    }
423
424    pub fn to_json(&self) -> Result<Vec<u8>, VNextError> {
425        self.validate_shape(true)?;
426        serde_json::to_vec_pretty(self).map_err(|error| VNextError::Serialization {
427            context: "serialize execution determinism coverage registry",
428            message: error.to_string(),
429        })
430    }
431
432    pub fn fingerprint(&self) -> Result<String, VNextError> {
433        Ok(format!("{:x}", Sha256::digest(self.to_json()?)))
434    }
435
436    pub fn decode_untrusted(bytes: &[u8]) -> Result<Self, VNextError> {
437        if bytes.len() > MAX_COVERAGE_WIRE_BYTES {
438            return Err(invalid_plan(
439                "execution determinism coverage registry exceeds its wire bound",
440            ));
441        }
442        let registry =
443            serde_json::from_slice::<Self>(bytes).map_err(|error| VNextError::Serialization {
444                context: "decode execution determinism coverage registry",
445                message: error.to_string(),
446            })?;
447        registry.validate_shape(true)?;
448        Ok(registry)
449    }
450
451    fn validate_shape(&self, require_models: bool) -> Result<(), VNextError> {
452        if self.schema_version != EXECUTION_DETERMINISM_COVERAGE_VERSION
453            || !is_canonical_sha256(&self.device_runtime_implementation_fingerprint)
454            || !is_canonical_sha256(&self.capability_catalog_fingerprint)
455            || self.provider_requirements.is_empty()
456            || self.provider_requirements.len() > MAX_COVERAGE_PROVIDERS
457            || self.models.len() > MAX_COVERAGE_MODELS
458            || (require_models && self.models.is_empty())
459        {
460            return Err(invalid_plan(
461                "execution determinism coverage registry identity or cardinality is invalid",
462            ));
463        }
464        if self
465            .models
466            .windows(2)
467            .any(|pair| pair[0].model_key >= pair[1].model_key)
468            || self
469                .provider_requirements
470                .windows(2)
471                .any(|pair| pair[0].canonical_key() >= pair[1].canonical_key())
472        {
473            return Err(invalid_plan(
474                "execution determinism coverage rows are not canonical and unique",
475            ));
476        }
477
478        let mut model_nodes = BTreeMap::<&str, BTreeSet<&NodeId>>::new();
479        let mut model_identities = BTreeMap::new();
480        let mut metadata_ids = BTreeSet::new();
481        let mut resolved_fingerprints = BTreeSet::new();
482        for model in &self.models {
483            validate_model_key(&model.model_key)?;
484            if !is_canonical_sha256(&model.resolved_plan_fingerprint)
485                || model.node_ids.is_empty()
486                || model.node_ids.len() > MAX_COVERAGE_NODES_PER_MODEL
487                || model.node_ids.iter().collect::<BTreeSet<_>>().len() != model.node_ids.len()
488                || !metadata_ids.insert(&model.external_metadata_id)
489                || !resolved_fingerprints.insert(model.resolved_plan_fingerprint.as_str())
490            {
491                return Err(invalid_plan(
492                    "execution determinism model identity or node denominator is invalid",
493                ));
494            }
495            model_nodes.insert(model.model_key.as_str(), BTreeSet::new());
496            model_identities.insert(model.model_key.as_str(), model);
497        }
498
499        for requirement in &self.provider_requirements {
500            let expected_comparisons = ExecutionDeterminismComparisonKind::for_replay_equivalence(
501                requirement.replay_equivalence,
502            );
503            if requirement.operation_version.major == 0
504                || requirement.provider_version.major == 0
505                || !is_canonical_sha256(&requirement.operation_fingerprint)
506                || !is_canonical_sha256(&requirement.provider_implementation_fingerprint)
507                || requirement.required_comparisons != expected_comparisons
508                || requirement
509                    .model_selections
510                    .windows(2)
511                    .any(|pair| pair[0].model_key >= pair[1].model_key)
512            {
513                return Err(invalid_plan(
514                    "execution determinism provider requirement is invalid",
515                ));
516            }
517            for selection in &requirement.model_selections {
518                let model = model_identities
519                    .get(selection.model_key.as_str())
520                    .ok_or_else(|| {
521                        invalid_plan(
522                            "execution determinism provider selection references an unknown model",
523                        )
524                    })?;
525                if selection.resolved_plan_fingerprint != model.resolved_plan_fingerprint
526                    || selection.plan_hash != model.plan_hash
527                    || selection.node_ids.is_empty()
528                    || selection.node_ids.iter().collect::<BTreeSet<_>>().len()
529                        != selection.node_ids.len()
530                {
531                    return Err(invalid_plan(
532                        "execution determinism provider selection identity is invalid",
533                    ));
534                }
535                let covered = model_nodes
536                    .get_mut(selection.model_key.as_str())
537                    .expect("validated model coverage denominator exists");
538                for node_id in &selection.node_ids {
539                    if !covered.insert(node_id) {
540                        return Err(invalid_plan(
541                            "execution determinism model node is selected by multiple providers",
542                        ));
543                    }
544                }
545            }
546        }
547        for (model_key, covered) in model_nodes {
548            let expected = model_identities[model_key]
549                .node_ids
550                .iter()
551                .collect::<BTreeSet<_>>();
552            if covered != expected {
553                return Err(invalid_plan(
554                    "execution determinism provider selections do not cover the resolved plan exactly",
555                ));
556            }
557        }
558        Ok(())
559    }
560}
561
562/// Exact immutable witness denominator for one provider selection in one
563/// resolved model plan.
564///
565/// The duplicated plan/provider identities are intentional. They make a
566/// detached hardware artifact self-describing while `validate_shape` proves
567/// that every row is still derived from the nested live coverage registry.
568#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
569#[serde(deny_unknown_fields)]
570pub struct ExecutionDeterminismProviderEvidenceDenominator {
571    model_key: String,
572    resolved_plan_fingerprint: String,
573    plan_hash: PlanHash,
574    operation_id: OperationId,
575    operation_fingerprint: String,
576    provider_id: ProviderId,
577    provider_implementation_fingerprint: String,
578    provider_execution_contract_fingerprint: ProviderExecutionContractFingerprint,
579    replay_equivalence: ProviderReplayEquivalence,
580    required_comparisons: Vec<ExecutionDeterminismComparisonKind>,
581    node_ids: Vec<NodeId>,
582    witness_plan_fingerprint: String,
583    witness_plan: ExecutionDeterminismWitnessPlan,
584}
585
586impl ExecutionDeterminismProviderEvidenceDenominator {
587    pub fn model_key(&self) -> &str {
588        &self.model_key
589    }
590
591    pub fn operation_id(&self) -> &OperationId {
592        &self.operation_id
593    }
594
595    pub fn provider_id(&self) -> &ProviderId {
596        &self.provider_id
597    }
598
599    pub fn node_ids(&self) -> &[NodeId] {
600        &self.node_ids
601    }
602
603    pub fn required_comparisons(&self) -> &[ExecutionDeterminismComparisonKind] {
604        &self.required_comparisons
605    }
606
607    pub fn witness_plan_fingerprint(&self) -> &str {
608        &self.witness_plan_fingerprint
609    }
610
611    pub fn witness_plan(&self) -> &ExecutionDeterminismWitnessPlan {
612        &self.witness_plan
613    }
614
615    fn canonical_key(&self) -> (&str, &OperationId, &ProviderId) {
616        (&self.model_key, &self.operation_id, &self.provider_id)
617    }
618}
619
620/// Current-binary source of truth consumed by the CUDA determinism collector.
621///
622/// Construction requires the live capability catalog and every resolved model
623/// plan in the release matrix in the same process. This prevents Python gate
624/// code or an artifact author from inventing provider counts, node scopes, or
625/// output/state witness ranges.
626#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
627#[serde(deny_unknown_fields)]
628pub struct ExecutionDeterminismEvidenceDenominator {
629    schema_version: ContractVersion,
630    provider_coverage: ExecutionDeterminismProviderCoverage,
631    coverage: ExecutionDeterminismCoverageRegistry,
632    provider_evidence: Vec<ExecutionDeterminismProviderEvidenceDenominator>,
633}
634
635impl ExecutionDeterminismEvidenceDenominator {
636    pub fn from_catalog_and_resolved_plans(
637        catalog: &CapabilityCatalog,
638        plans: &[(&str, &ResolvedModelPlan)],
639    ) -> Result<Self, VNextError> {
640        Self::from_catalog_and_resolved_plans_with_provider_coverage(
641            catalog,
642            plans,
643            ExecutionDeterminismProviderCoverage::AllCatalogProviders,
644        )
645    }
646
647    pub fn from_catalog_and_resolved_plans_with_provider_coverage(
648        catalog: &CapabilityCatalog,
649        plans: &[(&str, &ResolvedModelPlan)],
650        provider_coverage: ExecutionDeterminismProviderCoverage,
651    ) -> Result<Self, VNextError> {
652        if plans.is_empty() || plans.len() > MAX_COVERAGE_MODELS {
653            return Err(invalid_plan(
654                "execution determinism evidence model denominator is empty or exceeds its bound",
655            ));
656        }
657        let mut plan_by_key = BTreeMap::new();
658        let mut coverage = ExecutionDeterminismCoverageRegistry::from_catalog(catalog)?;
659        for (model_key, plan) in plans {
660            validate_model_key(model_key)?;
661            if plan_by_key.insert((*model_key).to_owned(), *plan).is_some() {
662                return Err(invalid_plan(
663                    "execution determinism evidence model keys must be unique",
664                ));
665            }
666            coverage.try_add_resolved_model_plan(*model_key, plan)?;
667        }
668        if provider_coverage == ExecutionDeterminismProviderCoverage::AllCatalogProviders
669            && coverage.unselected_provider_requirements().next().is_some()
670        {
671            return Err(invalid_plan(
672                "execution determinism live catalog contains a provider absent from all resolved plans",
673            ));
674        }
675
676        let mut provider_evidence = Vec::new();
677        for requirement in &coverage.provider_requirements {
678            for selection in &requirement.model_selections {
679                let plan = plan_by_key
680                    .get(selection.model_key.as_str())
681                    .expect("coverage model came from the exact plan map");
682                let witness_plan = plan
683                    .execution_plan()
684                    .determinism_witness_plan_for_nodes(&selection.node_ids)?;
685                let witness_plan_fingerprint = witness_plan.fingerprint()?;
686                provider_evidence.push(ExecutionDeterminismProviderEvidenceDenominator {
687                    model_key: selection.model_key.clone(),
688                    resolved_plan_fingerprint: selection.resolved_plan_fingerprint.clone(),
689                    plan_hash: selection.plan_hash.clone(),
690                    operation_id: requirement.operation_id.clone(),
691                    operation_fingerprint: requirement.operation_fingerprint.clone(),
692                    provider_id: requirement.provider_id.clone(),
693                    provider_implementation_fingerprint: requirement
694                        .provider_implementation_fingerprint
695                        .clone(),
696                    provider_execution_contract_fingerprint: requirement
697                        .provider_execution_contract_fingerprint,
698                    replay_equivalence: requirement.replay_equivalence,
699                    required_comparisons: requirement.required_comparisons.clone(),
700                    node_ids: selection.node_ids.clone(),
701                    witness_plan_fingerprint,
702                    witness_plan,
703                });
704            }
705        }
706        provider_evidence.sort_by(|left, right| left.canonical_key().cmp(&right.canonical_key()));
707        let denominator = Self {
708            schema_version: EXECUTION_DETERMINISM_EVIDENCE_DENOMINATOR_VERSION,
709            provider_coverage,
710            coverage,
711            provider_evidence,
712        };
713        denominator.validate_shape()?;
714        Ok(denominator)
715    }
716
717    pub const fn schema_version(&self) -> ContractVersion {
718        self.schema_version
719    }
720
721    pub const fn provider_coverage(&self) -> ExecutionDeterminismProviderCoverage {
722        self.provider_coverage
723    }
724
725    pub fn coverage(&self) -> &ExecutionDeterminismCoverageRegistry {
726        &self.coverage
727    }
728
729    pub fn provider_evidence(&self) -> &[ExecutionDeterminismProviderEvidenceDenominator] {
730        &self.provider_evidence
731    }
732
733    pub fn to_json(&self) -> Result<Vec<u8>, VNextError> {
734        self.validate_shape()?;
735        serde_json::to_vec_pretty(self).map_err(|error| VNextError::Serialization {
736            context: "serialize execution determinism evidence denominator",
737            message: error.to_string(),
738        })
739    }
740
741    pub fn fingerprint(&self) -> Result<String, VNextError> {
742        Ok(format!("{:x}", Sha256::digest(self.to_json()?)))
743    }
744
745    pub fn decode_untrusted(bytes: &[u8]) -> Result<Self, VNextError> {
746        if bytes.len() > MAX_EVIDENCE_DENOMINATOR_WIRE_BYTES {
747            return Err(invalid_plan(
748                "execution determinism evidence denominator exceeds its wire bound",
749            ));
750        }
751        let denominator =
752            serde_json::from_slice::<Self>(bytes).map_err(|error| VNextError::Serialization {
753                context: "decode execution determinism evidence denominator",
754                message: error.to_string(),
755            })?;
756        denominator.validate_shape()?;
757        Ok(denominator)
758    }
759
760    fn validate_shape(&self) -> Result<(), VNextError> {
761        self.coverage.validate_shape(true)?;
762        if self.schema_version != EXECUTION_DETERMINISM_EVIDENCE_DENOMINATOR_VERSION
763            || self.provider_evidence.is_empty()
764            || self.provider_evidence.len()
765                > MAX_COVERAGE_MODELS.saturating_mul(MAX_COVERAGE_PROVIDERS)
766            || (self.provider_coverage == ExecutionDeterminismProviderCoverage::AllCatalogProviders
767                && self
768                    .coverage
769                    .unselected_provider_requirements()
770                    .next()
771                    .is_some())
772            || self
773                .provider_evidence
774                .windows(2)
775                .any(|pair| pair[0].canonical_key() >= pair[1].canonical_key())
776        {
777            return Err(invalid_plan(
778                "execution determinism evidence denominator identity or cardinality is invalid",
779            ));
780        }
781
782        let requirements = self
783            .coverage
784            .provider_requirements
785            .iter()
786            .map(|requirement| (requirement.canonical_key(), requirement))
787            .collect::<BTreeMap<_, _>>();
788        let models = self
789            .coverage
790            .models
791            .iter()
792            .map(|model| (model.model_key.as_str(), model))
793            .collect::<BTreeMap<_, _>>();
794        let mut expected = BTreeSet::new();
795        for requirement in &self.coverage.provider_requirements {
796            for selection in &requirement.model_selections {
797                expected.insert((
798                    selection.model_key.as_str(),
799                    &requirement.operation_id,
800                    &requirement.provider_id,
801                ));
802            }
803        }
804        let actual = self
805            .provider_evidence
806            .iter()
807            .map(ExecutionDeterminismProviderEvidenceDenominator::canonical_key)
808            .collect::<BTreeSet<_>>();
809        if actual != expected {
810            return Err(invalid_plan(
811                "execution determinism provider evidence does not equal the live plan denominator",
812            ));
813        }
814
815        for evidence in &self.provider_evidence {
816            let requirement = requirements
817                .get(&(&evidence.operation_id, &evidence.provider_id))
818                .expect("validated evidence key exists in coverage");
819            let selection = requirement
820                .model_selections
821                .iter()
822                .find(|selection| selection.model_key == evidence.model_key)
823                .expect("validated evidence key has a model selection");
824            let model = models
825                .get(evidence.model_key.as_str())
826                .expect("validated evidence model exists in coverage");
827            evidence.witness_plan.validate_shape()?;
828            if evidence.resolved_plan_fingerprint != selection.resolved_plan_fingerprint
829                || evidence.resolved_plan_fingerprint != model.resolved_plan_fingerprint
830                || evidence.plan_hash != selection.plan_hash
831                || evidence.plan_hash != model.plan_hash
832                || evidence.operation_fingerprint != requirement.operation_fingerprint
833                || evidence.provider_implementation_fingerprint
834                    != requirement.provider_implementation_fingerprint
835                || evidence.provider_execution_contract_fingerprint
836                    != requirement.provider_execution_contract_fingerprint
837                || evidence.replay_equivalence != requirement.replay_equivalence
838                || evidence.required_comparisons != requirement.required_comparisons
839                || evidence.node_ids != selection.node_ids
840                || evidence.witness_plan.plan_hash() != &evidence.plan_hash
841                || evidence.witness_plan.node_ids() != evidence.node_ids
842                || evidence.witness_plan.fingerprint()? != evidence.witness_plan_fingerprint
843                || evidence.witness_plan.witnesses().iter().any(|witness| {
844                    witness.provider_id() != &evidence.provider_id
845                        || witness.provider_implementation_fingerprint()
846                            != evidence.provider_implementation_fingerprint
847                        || witness.provider_execution_contract_fingerprint()
848                            != evidence.provider_execution_contract_fingerprint
849                })
850            {
851                return Err(invalid_plan(
852                    "execution determinism provider evidence differs from its live catalog, plan, or witness denominator",
853                ));
854            }
855        }
856        Ok(())
857    }
858}
859
860fn validate_model_key(model_key: &str) -> Result<(), VNextError> {
861    if model_key.is_empty()
862        || model_key.len() > MAX_MODEL_KEY_BYTES
863        || !model_key
864            .bytes()
865            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b'-' | b'/'))
866    {
867        return Err(invalid_plan(
868            "execution determinism model key is empty or non-canonical",
869        ));
870    }
871    Ok(())
872}