use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
use crate::determinism::DeterminismMode;
use crate::engine::ProtocolMachineConfig;
use crate::output_condition::OutputConditionPolicy;
use crate::scheduler::SchedPolicy;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum RuntimeAdmissionResult {
Admitted,
RejectedMissingContracts,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum RuntimeGateResult {
Admitted,
RejectedMissingContracts,
RejectedUnsupportedDeterminismProfile,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeTransportContract {
pub transport_name: String,
pub transport_type: String,
pub role_addressed_routing: bool,
pub authenticated_peers: bool,
pub per_peer_fifo_delivery: bool,
pub fail_closed_unknown_role: bool,
pub no_message_synthesis: bool,
pub explicit_readiness_errors: bool,
pub deterministic_for_regression: bool,
}
impl RuntimeTransportContract {
#[must_use]
pub fn new(transport_name: impl Into<String>, transport_type: impl Into<String>) -> Self {
Self {
transport_name: transport_name.into(),
transport_type: transport_type.into(),
role_addressed_routing: false,
authenticated_peers: false,
per_peer_fifo_delivery: false,
fail_closed_unknown_role: false,
no_message_synthesis: false,
explicit_readiness_errors: false,
deterministic_for_regression: false,
}
}
#[must_use]
pub fn first_party_in_memory() -> Self {
Self::new("InMemoryChannelTransport", "InMemory")
.with_role_addressed_routing(true)
.with_authenticated_peers(true)
.with_per_peer_fifo_delivery(true)
.with_fail_closed_unknown_role(true)
.with_no_message_synthesis(true)
.with_deterministic_for_regression(true)
}
#[must_use]
pub fn with_role_addressed_routing(mut self, value: bool) -> Self {
self.role_addressed_routing = value;
self
}
#[must_use]
pub fn with_authenticated_peers(mut self, value: bool) -> Self {
self.authenticated_peers = value;
self
}
#[must_use]
pub fn with_per_peer_fifo_delivery(mut self, value: bool) -> Self {
self.per_peer_fifo_delivery = value;
self
}
#[must_use]
pub fn with_fail_closed_unknown_role(mut self, value: bool) -> Self {
self.fail_closed_unknown_role = value;
self
}
#[must_use]
pub fn with_no_message_synthesis(mut self, value: bool) -> Self {
self.no_message_synthesis = value;
self
}
#[must_use]
pub fn with_explicit_readiness_errors(mut self, value: bool) -> Self {
self.explicit_readiness_errors = value;
self
}
#[must_use]
pub fn with_deterministic_for_regression(mut self, value: bool) -> Self {
self.deterministic_for_regression = value;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct TheoremTransportRequirements {
pub role_addressed_routing: bool,
pub authenticated_peers: bool,
pub per_peer_fifo_delivery: bool,
pub fail_closed_unknown_role: bool,
pub no_message_synthesis: bool,
}
impl TheoremTransportRequirements {
#[must_use]
pub const fn none() -> Self {
Self {
role_addressed_routing: false,
authenticated_peers: false,
per_peer_fifo_delivery: false,
fail_closed_unknown_role: false,
no_message_synthesis: false,
}
}
#[must_use]
pub const fn protocol_origin_integrity() -> Self {
Self {
role_addressed_routing: true,
authenticated_peers: true,
per_peer_fifo_delivery: true,
fail_closed_unknown_role: true,
no_message_synthesis: true,
}
}
#[must_use]
pub const fn is_empty(self) -> bool {
!self.role_addressed_routing
&& !self.authenticated_peers
&& !self.per_peer_fifo_delivery
&& !self.fail_closed_unknown_role
&& !self.no_message_synthesis
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TransportContractGateError {
MissingTransportContracts,
UnsatisfiedTransportRequirement {
transport_name: String,
requirement: &'static str,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TransportedTheoremUsageClass {
BlackBoxPremiseOnly,
RuntimeCriticalInstantiatedPremise,
DocumentationBackgroundOnly,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TransportedTheoremBoundaryEntry {
pub key: String,
pub usage_class: TransportedTheoremUsageClass,
pub consumed_by_rust_runtime_admission: bool,
pub consumed_by_lean_runtime_gate: bool,
pub assumption_boundary: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TransportedTheoremBoundaryValidationError {
RustAdmissionKeyNotRuntimeCritical(String),
LeanOnlyRuntimeCriticalMissingAssumptionBoundary(String),
RuntimeProfileMissingRustAdmissionKey(String),
RuntimeProfileDisablesRustAdmissionKey(String),
RuntimeProfileEnablesUnknownRustAdmissionKey(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DeterminismArtifacts {
pub full: bool,
pub modulo_effect_trace: bool,
pub modulo_commutativity: bool,
pub replay: bool,
}
impl Default for DeterminismArtifacts {
fn default() -> Self {
Self {
full: true,
modulo_effect_trace: true,
modulo_commutativity: true,
replay: true,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RuntimeCapability {
LiveMigration,
AutoscaleRepartition,
PlacementRefinement,
RelaxedReordering,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProtocolMachineFairnessAssumption {
ScheduleConfluence,
StarvationFreedom,
LivenessFairness,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProtocolMachineAdmissibilityClass {
LocalEnvelope,
ShardedEnvelope,
ProtocolEnvelopeBridge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProtocolMachineEscalationWindowClass {
ProgressContract,
AdmissionComplexity,
ProtocolBridge,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProtocolMachineExecutionProfile {
pub fairness_assumptions: BTreeSet<ProtocolMachineFairnessAssumption>,
pub admissibility_classes: BTreeSet<ProtocolMachineAdmissibilityClass>,
pub escalation_window_classes: BTreeSet<ProtocolMachineEscalationWindowClass>,
pub theorem_pack_eligibility: Vec<(String, bool)>,
}
impl ProtocolMachineExecutionProfile {
#[must_use]
pub fn full() -> Self {
Self {
fairness_assumptions: [
ProtocolMachineFairnessAssumption::ScheduleConfluence,
ProtocolMachineFairnessAssumption::StarvationFreedom,
ProtocolMachineFairnessAssumption::LivenessFairness,
]
.into_iter()
.collect(),
admissibility_classes: [
ProtocolMachineAdmissibilityClass::LocalEnvelope,
ProtocolMachineAdmissibilityClass::ShardedEnvelope,
ProtocolMachineAdmissibilityClass::ProtocolEnvelopeBridge,
]
.into_iter()
.collect(),
escalation_window_classes: [
ProtocolMachineEscalationWindowClass::ProgressContract,
ProtocolMachineEscalationWindowClass::AdmissionComplexity,
ProtocolMachineEscalationWindowClass::ProtocolBridge,
]
.into_iter()
.collect(),
theorem_pack_eligibility: vec![
("protocol_machine_envelope_adherence".to_string(), true),
("protocol_machine_envelope_admission".to_string(), true),
("protocol_envelope_bridge".to_string(), true),
],
}
}
fn eligibility(&self, key: &str) -> bool {
self.theorem_pack_eligibility
.iter()
.find(|entry| entry.0 == key)
.map(|entry| entry.1)
.unwrap_or(false)
}
#[must_use]
pub fn supports_protocol_machine_envelope_adherence(&self) -> bool {
self.eligibility("protocol_machine_envelope_adherence")
}
#[must_use]
pub fn supports_protocol_machine_envelope_admission(&self) -> bool {
self.eligibility("protocol_machine_envelope_admission")
}
#[must_use]
pub fn supports_protocol_envelope_bridge(&self) -> bool {
self.eligibility("protocol_envelope_bridge")
}
#[must_use]
pub fn transport_requirements(&self) -> TheoremTransportRequirements {
if self
.theorem_pack_eligibility
.iter()
.any(|(_, enabled)| *enabled)
{
TheoremTransportRequirements::protocol_origin_integrity()
} else {
TheoremTransportRequirements::none()
}
}
}
fn missing_transport_requirement(
requirements: TheoremTransportRequirements,
transport: &RuntimeTransportContract,
) -> Option<&'static str> {
if requirements.role_addressed_routing && !transport.role_addressed_routing {
Some("role_addressed_routing")
} else if requirements.authenticated_peers && !transport.authenticated_peers {
Some("authenticated_peers")
} else if requirements.per_peer_fifo_delivery && !transport.per_peer_fifo_delivery {
Some("per_peer_fifo_delivery")
} else if requirements.fail_closed_unknown_role && !transport.fail_closed_unknown_role {
Some("fail_closed_unknown_role")
} else if requirements.no_message_synthesis && !transport.no_message_synthesis {
Some("no_message_synthesis")
} else {
None
}
}
pub fn validate_transport_contracts_for_execution_profile(
profile: &ProtocolMachineExecutionProfile,
transports: &[RuntimeTransportContract],
) -> Result<(), TransportContractGateError> {
let requirements = profile.transport_requirements();
if requirements.is_empty() {
return Ok(());
}
if transports.is_empty() {
return Err(TransportContractGateError::MissingTransportContracts);
}
for transport in transports {
if let Some(requirement) = missing_transport_requirement(requirements, transport) {
return Err(
TransportContractGateError::UnsatisfiedTransportRequirement {
transport_name: transport.transport_name.clone(),
requirement,
},
);
}
}
Ok(())
}
#[must_use]
pub fn transported_theorem_boundary() -> Vec<TransportedTheoremBoundaryEntry> {
let mut boundary = black_box_transported_theorem_entries();
boundary.extend(runtime_critical_transported_theorem_entries());
boundary.extend(documentation_background_transported_theorem_entries());
boundary
}
fn boundary_entry(
key: &str,
usage_class: TransportedTheoremUsageClass,
consumed_by_rust_runtime_admission: bool,
consumed_by_lean_runtime_gate: bool,
assumption_boundary: Option<&str>,
) -> TransportedTheoremBoundaryEntry {
TransportedTheoremBoundaryEntry {
key: key.to_string(),
usage_class,
consumed_by_rust_runtime_admission,
consumed_by_lean_runtime_gate,
assumption_boundary: assumption_boundary.map(str::to_string),
}
}
fn black_box_transported_theorem_entries() -> Vec<TransportedTheoremBoundaryEntry> {
use TransportedTheoremUsageClass::BlackBoxPremiseOnly;
[
"termination",
"output_condition_soundness",
"flp_lower_bound",
"flp_impossibility",
"cap_impossibility",
"quorum_geometry_safety",
"partial_synchrony_liveness",
"responsiveness",
"nakamoto_security",
"reconfiguration_safety",
"atomic_broadcast_ordering",
"accountable_safety",
"failure_detector_boundaries",
"data_availability_retrievability",
"coordination_characterization",
"crdt_envelope_and_equivalence",
"consensus_envelope",
"failure_envelope",
"effect_interface_bridge",
]
.into_iter()
.map(|key| boundary_entry(key, BlackBoxPremiseOnly, false, false, None))
.collect()
}
fn runtime_critical_transported_theorem_entries() -> Vec<TransportedTheoremBoundaryEntry> {
use TransportedTheoremUsageClass::RuntimeCriticalInstantiatedPremise;
vec![
boundary_entry(
"byzantine_safety_characterization",
RuntimeCriticalInstantiatedPremise,
false,
true,
Some(
"Lean theorem-pack gate only. Rust runtime admission does not currently consume this key.",
),
),
boundary_entry(
"protocol_machine_envelope_adherence",
RuntimeCriticalInstantiatedPremise,
true,
true,
None,
),
boundary_entry(
"protocol_machine_envelope_admission",
RuntimeCriticalInstantiatedPremise,
true,
true,
None,
),
boundary_entry(
"protocol_envelope_bridge",
RuntimeCriticalInstantiatedPremise,
true,
true,
None,
),
]
}
fn documentation_background_transported_theorem_entries() -> Vec<TransportedTheoremBoundaryEntry> {
use TransportedTheoremUsageClass::DocumentationBackgroundOnly;
[
"classical_foster",
"classical_maxweight",
"classical_ldp",
"classical_mean_field",
"classical_heavy_traffic",
"classical_mixing",
"classical_fluid",
"classical_concentration",
"classical_littles_law",
"classical_functional_clt",
"classical_spectral_gap_termination",
]
.into_iter()
.map(|key| boundary_entry(key, DocumentationBackgroundOnly, false, false, None))
.collect()
}
#[must_use]
pub fn runtime_critical_transported_theorem_boundary() -> Vec<TransportedTheoremBoundaryEntry> {
transported_theorem_boundary()
.into_iter()
.filter(|entry| {
matches!(
entry.usage_class,
TransportedTheoremUsageClass::RuntimeCriticalInstantiatedPremise
)
})
.collect()
}
#[must_use]
pub fn rust_runtime_critical_transport_theorem_keys() -> Vec<String> {
runtime_critical_transported_theorem_boundary()
.into_iter()
.filter(|entry| entry.consumed_by_rust_runtime_admission)
.map(|entry| entry.key)
.collect()
}
pub fn validate_transported_theorem_boundary_consistency(
boundary: &[TransportedTheoremBoundaryEntry],
profile: &ProtocolMachineExecutionProfile,
) -> Result<(), TransportedTheoremBoundaryValidationError> {
use TransportedTheoremBoundaryValidationError::{
LeanOnlyRuntimeCriticalMissingAssumptionBoundary, RuntimeProfileDisablesRustAdmissionKey,
RuntimeProfileEnablesUnknownRustAdmissionKey, RuntimeProfileMissingRustAdmissionKey,
RustAdmissionKeyNotRuntimeCritical,
};
use TransportedTheoremUsageClass::RuntimeCriticalInstantiatedPremise;
let rust_runtime_keys: BTreeSet<_> = boundary
.iter()
.filter(|entry| entry.consumed_by_rust_runtime_admission)
.map(|entry| entry.key.as_str())
.collect();
let enabled_profile_keys: BTreeSet<_> = profile
.theorem_pack_eligibility
.iter()
.filter_map(|(key, enabled)| enabled.then_some(key.as_str()))
.collect();
for entry in boundary {
if entry.consumed_by_rust_runtime_admission
&& !matches!(entry.usage_class, RuntimeCriticalInstantiatedPremise)
{
return Err(RustAdmissionKeyNotRuntimeCritical(entry.key.clone()));
}
if matches!(entry.usage_class, RuntimeCriticalInstantiatedPremise)
&& !entry.consumed_by_rust_runtime_admission
&& entry.consumed_by_lean_runtime_gate
&& entry.assumption_boundary.is_none()
{
return Err(LeanOnlyRuntimeCriticalMissingAssumptionBoundary(
entry.key.clone(),
));
}
if entry.consumed_by_rust_runtime_admission {
match profile
.theorem_pack_eligibility
.iter()
.find(|(key, _)| key == &entry.key)
{
None => return Err(RuntimeProfileMissingRustAdmissionKey(entry.key.clone())),
Some((_, false)) => {
return Err(RuntimeProfileDisablesRustAdmissionKey(entry.key.clone()))
}
Some((_, true)) => {}
}
}
}
for key in enabled_profile_keys {
if !rust_runtime_keys.contains(key) {
return Err(RuntimeProfileEnablesUnknownRustAdmissionKey(
key.to_string(),
));
}
}
Ok(())
}
impl RuntimeCapability {
const ALL: [Self; 4] = [
Self::LiveMigration,
Self::AutoscaleRepartition,
Self::PlacementRefinement,
Self::RelaxedReordering,
];
const fn key(self) -> &'static str {
match self {
Self::LiveMigration => "live_migration",
Self::AutoscaleRepartition => "autoscale_repartition",
Self::PlacementRefinement => "placement_refinement",
Self::RelaxedReordering => "relaxed_reordering",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeContracts {
pub determinism_artifacts: DeterminismArtifacts,
pub can_use_mixed_determinism_profiles: bool,
pub capabilities: BTreeSet<RuntimeCapability>,
pub execution_profile: ProtocolMachineExecutionProfile,
pub transport_contracts: Vec<RuntimeTransportContract>,
}
impl RuntimeContracts {
#[must_use]
pub fn full() -> Self {
Self {
determinism_artifacts: DeterminismArtifacts::default(),
can_use_mixed_determinism_profiles: true,
capabilities: RuntimeCapability::ALL.into_iter().collect(),
execution_profile: ProtocolMachineExecutionProfile::full(),
transport_contracts: vec![RuntimeTransportContract::first_party_in_memory()],
}
}
#[must_use]
pub fn with_transport_contracts(
mut self,
contracts: impl IntoIterator<Item = RuntimeTransportContract>,
) -> Self {
self.transport_contracts = contracts.into_iter().collect();
self
}
}
#[must_use]
pub fn runtime_execution_profile(
cfg: &ProtocolMachineConfig,
contracts: Option<&RuntimeContracts>,
) -> ProtocolMachineExecutionProfile {
let mut profile = ProtocolMachineExecutionProfile {
fairness_assumptions: [ProtocolMachineFairnessAssumption::ScheduleConfluence]
.into_iter()
.collect(),
admissibility_classes: [
ProtocolMachineAdmissibilityClass::LocalEnvelope,
ProtocolMachineAdmissibilityClass::ShardedEnvelope,
]
.into_iter()
.collect(),
escalation_window_classes: [ProtocolMachineEscalationWindowClass::ProgressContract]
.into_iter()
.collect(),
theorem_pack_eligibility: vec![
("protocol_machine_envelope_adherence".to_string(), true),
(
"protocol_machine_envelope_admission".to_string(),
contracts.is_some(),
),
(
"protocol_envelope_bridge".to_string(),
!matches!(cfg.output_condition_policy, OutputConditionPolicy::Disabled),
),
],
};
if !matches!(cfg.sched_policy, SchedPolicy::Cooperative) {
profile
.fairness_assumptions
.insert(ProtocolMachineFairnessAssumption::StarvationFreedom);
}
if matches!(cfg.sched_policy, SchedPolicy::ProgressAware)
|| !matches!(cfg.output_condition_policy, OutputConditionPolicy::Disabled)
{
profile
.fairness_assumptions
.insert(ProtocolMachineFairnessAssumption::LivenessFairness);
}
if contracts.is_some() {
profile
.escalation_window_classes
.insert(ProtocolMachineEscalationWindowClass::AdmissionComplexity);
}
if !matches!(cfg.output_condition_policy, OutputConditionPolicy::Disabled) {
profile
.admissibility_classes
.insert(ProtocolMachineAdmissibilityClass::ProtocolEnvelopeBridge);
profile
.escalation_window_classes
.insert(ProtocolMachineEscalationWindowClass::ProtocolBridge);
}
profile
}
#[must_use]
pub fn execution_profile_supported(
profile: &ProtocolMachineExecutionProfile,
cfg: &ProtocolMachineConfig,
contracts: Option<&RuntimeContracts>,
) -> bool {
let required = runtime_execution_profile(cfg, contracts);
let supports_adherence = required.supports_protocol_machine_envelope_adherence();
let supports_admission = required.supports_protocol_machine_envelope_admission();
let supports_bridge = required.supports_protocol_envelope_bridge();
required
.fairness_assumptions
.into_iter()
.all(|assumption| profile.fairness_assumptions.contains(&assumption))
&& required
.admissibility_classes
.into_iter()
.all(|class| profile.admissibility_classes.contains(&class))
&& required
.escalation_window_classes
.into_iter()
.all(|class| profile.escalation_window_classes.contains(&class))
&& (!supports_adherence || profile.supports_protocol_machine_envelope_adherence())
&& (!supports_admission || profile.supports_protocol_machine_envelope_admission())
&& (!supports_bridge || profile.supports_protocol_envelope_bridge())
}
fn sched_policy_requires_contracts(policy: &SchedPolicy) -> bool {
!matches!(policy, SchedPolicy::Cooperative)
}
#[must_use]
pub fn requires_protocol_machine_runtime_contracts(cfg: &ProtocolMachineConfig) -> bool {
sched_policy_requires_contracts(&cfg.sched_policy) || cfg.speculation_enabled
}
#[must_use]
pub fn admit_protocol_machine_runtime(
cfg: &ProtocolMachineConfig,
contracts: Option<&RuntimeContracts>,
) -> RuntimeAdmissionResult {
if requires_protocol_machine_runtime_contracts(cfg) && contracts.is_none() {
RuntimeAdmissionResult::RejectedMissingContracts
} else {
RuntimeAdmissionResult::Admitted
}
}
#[must_use]
pub fn determinism_profile_supported(
artifacts: &DeterminismArtifacts,
profile: DeterminismMode,
) -> bool {
match profile {
DeterminismMode::Full => artifacts.full,
DeterminismMode::ModuloEffects => artifacts.modulo_effect_trace,
DeterminismMode::ModuloCommutativity => artifacts.modulo_commutativity,
DeterminismMode::Replay => artifacts.replay,
}
}
#[must_use]
pub fn request_determinism_profile(
contracts: &RuntimeContracts,
profile: DeterminismMode,
) -> Option<DeterminismMode> {
let supported = determinism_profile_supported(&contracts.determinism_artifacts, profile);
if !supported {
return None;
}
match profile {
DeterminismMode::Full => Some(profile),
DeterminismMode::ModuloEffects
| DeterminismMode::ModuloCommutativity
| DeterminismMode::Replay => contracts
.can_use_mixed_determinism_profiles
.then_some(profile),
}
}
#[must_use]
pub fn enforce_protocol_machine_runtime_gates(
cfg: &ProtocolMachineConfig,
contracts: Option<&RuntimeContracts>,
) -> RuntimeGateResult {
match admit_protocol_machine_runtime(cfg, contracts) {
RuntimeAdmissionResult::RejectedMissingContracts => {
RuntimeGateResult::RejectedMissingContracts
}
RuntimeAdmissionResult::Admitted => match contracts {
Some(contracts) => {
if request_determinism_profile(contracts, cfg.determinism_mode).is_some() {
RuntimeGateResult::Admitted
} else {
RuntimeGateResult::RejectedUnsupportedDeterminismProfile
}
}
None => {
if matches!(cfg.determinism_mode, DeterminismMode::Full) {
RuntimeGateResult::Admitted
} else {
RuntimeGateResult::RejectedUnsupportedDeterminismProfile
}
}
},
}
}
#[must_use]
pub fn runtime_capability_snapshot(contracts: &RuntimeContracts) -> Vec<(String, bool)> {
RuntimeCapability::ALL
.into_iter()
.map(|capability| {
(
capability.key().to_string(),
contracts.capabilities.contains(&capability),
)
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn admission_requires_contracts_for_advanced_modes() {
let mut cfg = ProtocolMachineConfig::default();
assert_eq!(
admit_protocol_machine_runtime(&cfg, None),
RuntimeAdmissionResult::Admitted
);
cfg.speculation_enabled = true;
assert_eq!(
admit_protocol_machine_runtime(&cfg, None),
RuntimeAdmissionResult::RejectedMissingContracts
);
assert_eq!(
admit_protocol_machine_runtime(&cfg, Some(&RuntimeContracts::full())),
RuntimeAdmissionResult::Admitted
);
}
#[test]
fn request_determinism_profile_obeys_artifacts_and_mixed_gate() {
let mut contracts = RuntimeContracts::full();
contracts.can_use_mixed_determinism_profiles = false;
assert_eq!(
request_determinism_profile(&contracts, DeterminismMode::Full),
Some(DeterminismMode::Full)
);
assert_eq!(
request_determinism_profile(&contracts, DeterminismMode::Replay),
None
);
contracts.can_use_mixed_determinism_profiles = true;
contracts.determinism_artifacts.replay = false;
assert_eq!(
request_determinism_profile(&contracts, DeterminismMode::Replay),
None
);
contracts.determinism_artifacts.replay = true;
assert_eq!(
request_determinism_profile(&contracts, DeterminismMode::Replay),
Some(DeterminismMode::Replay)
);
}
#[test]
#[allow(clippy::field_reassign_with_default)]
fn unified_runtime_gate_combines_admission_and_profile_checks() {
let mut cfg = ProtocolMachineConfig::default();
cfg.speculation_enabled = true;
assert_eq!(
enforce_protocol_machine_runtime_gates(&cfg, None),
RuntimeGateResult::RejectedMissingContracts
);
let mut contracts = RuntimeContracts::full();
contracts.determinism_artifacts.replay = false;
cfg.determinism_mode = DeterminismMode::Replay;
assert_eq!(
enforce_protocol_machine_runtime_gates(&cfg, Some(&contracts)),
RuntimeGateResult::RejectedUnsupportedDeterminismProfile
);
contracts.determinism_artifacts.replay = true;
assert_eq!(
enforce_protocol_machine_runtime_gates(&cfg, Some(&contracts)),
RuntimeGateResult::Admitted
);
}
#[test]
fn capability_snapshot_is_derived_from_canonical_capability_set() {
let mut contracts = RuntimeContracts::full();
contracts
.capabilities
.remove(&RuntimeCapability::RelaxedReordering);
let snapshot = runtime_capability_snapshot(&contracts);
assert_eq!(
snapshot,
vec![
("live_migration".to_string(), true),
("autoscale_repartition".to_string(), true),
("placement_refinement".to_string(), true),
("relaxed_reordering".to_string(), false),
]
);
}
#[test]
#[allow(clippy::field_reassign_with_default)]
fn runtime_execution_profile_tracks_scheduler_and_bridge_requirements() {
let mut cfg = ProtocolMachineConfig::default();
cfg.sched_policy = SchedPolicy::ProgressAware;
cfg.output_condition_policy = OutputConditionPolicy::AllowAll;
let profile = runtime_execution_profile(&cfg, Some(&RuntimeContracts::full()));
assert!(profile
.fairness_assumptions
.contains(&ProtocolMachineFairnessAssumption::LivenessFairness));
assert!(profile
.admissibility_classes
.contains(&ProtocolMachineAdmissibilityClass::ProtocolEnvelopeBridge));
assert!(profile.supports_protocol_envelope_bridge());
assert!(execution_profile_supported(
&ProtocolMachineExecutionProfile::full(),
&cfg,
Some(&RuntimeContracts::full())
));
}
#[test]
fn theorem_transport_requirements_reject_missing_contracts() {
let profile = ProtocolMachineExecutionProfile::full();
assert_eq!(
validate_transport_contracts_for_execution_profile(&profile, &[]),
Err(TransportContractGateError::MissingTransportContracts)
);
}
#[test]
fn theorem_transport_requirements_accept_in_memory_profile() {
let profile = ProtocolMachineExecutionProfile::full();
assert_eq!(
validate_transport_contracts_for_execution_profile(
&profile,
&[RuntimeTransportContract::first_party_in_memory()]
),
Ok(())
);
}
#[test]
fn theorem_transport_requirements_reject_unauthenticated_profile_for_authenticated_claims() {
let profile = ProtocolMachineExecutionProfile::full();
let unauthenticated = RuntimeTransportContract::new("UnauthenticatedTransport", "Network")
.with_role_addressed_routing(true)
.with_per_peer_fifo_delivery(true)
.with_fail_closed_unknown_role(true)
.with_no_message_synthesis(true)
.with_explicit_readiness_errors(true);
assert_eq!(
validate_transport_contracts_for_execution_profile(&profile, &[unauthenticated]),
Err(
TransportContractGateError::UnsatisfiedTransportRequirement {
transport_name: "UnauthenticatedTransport".to_string(),
requirement: "authenticated_peers",
}
)
);
}
#[test]
fn transported_theorem_boundary_makes_rust_runtime_subset_exact() {
let boundary = transported_theorem_boundary();
let rust_runtime_keys = rust_runtime_critical_transport_theorem_keys();
let profile = ProtocolMachineExecutionProfile::full();
let profile_keys: Vec<_> = profile
.theorem_pack_eligibility
.iter()
.map(|(key, _)| key.clone())
.collect();
assert_eq!(
rust_runtime_keys, profile_keys,
"shipped Rust runtime admission must consume exactly the classified runtime-critical theorem keys"
);
assert_eq!(
validate_transported_theorem_boundary_consistency(&boundary, &profile),
Ok(())
);
assert!(
boundary.iter().any(|entry| {
entry.key == "byzantine_safety_characterization"
&& matches!(
entry.usage_class,
TransportedTheoremUsageClass::RuntimeCriticalInstantiatedPremise
)
&& !entry.consumed_by_rust_runtime_admission
&& entry.consumed_by_lean_runtime_gate
}),
"Lean-only runtime-critical theorem gates must remain explicit in the boundary ledger"
);
}
#[test]
fn transported_theorem_boundary_requires_instantiation_or_assumption_boundary() {
for entry in runtime_critical_transported_theorem_boundary() {
assert!(
entry.consumed_by_rust_runtime_admission || entry.assumption_boundary.is_some(),
"runtime-critical theorem {} must have a Rust instantiation path or an explicit assumption boundary",
entry.key
);
}
}
#[test]
fn transported_theorem_boundary_fail_closes_when_runtime_profile_key_drifts() {
let boundary = transported_theorem_boundary();
let mut profile = ProtocolMachineExecutionProfile::full();
profile.theorem_pack_eligibility[0].0 = "protocol_machine_envelope_adherence_typo".into();
assert_eq!(
validate_transported_theorem_boundary_consistency(&boundary, &profile),
Err(
TransportedTheoremBoundaryValidationError::RuntimeProfileMissingRustAdmissionKey(
"protocol_machine_envelope_adherence".into()
)
)
);
}
#[test]
fn transported_theorem_boundary_fail_closes_when_runtime_profile_enables_unknown_key() {
let boundary = transported_theorem_boundary();
let mut profile = ProtocolMachineExecutionProfile::full();
profile
.theorem_pack_eligibility
.push(("unknown_runtime_boundary".into(), true));
assert_eq!(
validate_transported_theorem_boundary_consistency(&boundary, &profile),
Err(
TransportedTheoremBoundaryValidationError::RuntimeProfileEnablesUnknownRustAdmissionKey(
"unknown_runtime_boundary".into()
)
)
);
}
#[test]
fn transported_theorem_boundary_fail_closes_when_runtime_classification_drifts() {
let mut boundary = transported_theorem_boundary();
let profile = ProtocolMachineExecutionProfile::full();
let bridge_entry = boundary
.iter_mut()
.find(|entry| entry.key == "protocol_envelope_bridge")
.expect("canonical boundary should classify protocol_envelope_bridge");
bridge_entry.usage_class = TransportedTheoremUsageClass::BlackBoxPremiseOnly;
assert_eq!(
validate_transported_theorem_boundary_consistency(&boundary, &profile),
Err(
TransportedTheoremBoundaryValidationError::RustAdmissionKeyNotRuntimeCritical(
"protocol_envelope_bridge".into()
)
)
);
}
#[test]
fn transported_theorem_boundary_fail_closes_when_lean_only_runtime_critical_entry_loses_assumption_boundary(
) {
let mut boundary = transported_theorem_boundary();
let profile = ProtocolMachineExecutionProfile::full();
let byzantine = boundary
.iter_mut()
.find(|entry| entry.key == "byzantine_safety_characterization")
.expect("canonical boundary should classify byzantine_safety_characterization");
byzantine.assumption_boundary = None;
assert_eq!(
validate_transported_theorem_boundary_consistency(&boundary, &profile),
Err(
TransportedTheoremBoundaryValidationError::LeanOnlyRuntimeCriticalMissingAssumptionBoundary(
"byzantine_safety_characterization".into()
)
)
);
}
}