use crate::contract::backend::Backend;
use crate::contract::budget::{BudgetRequirements, MinGuarantee};
use crate::contract::plan::{BoundarySpec, EvidenceRequirements, PlanError, Workload};
use crate::contract::registry::{BackendRegistry, BoundaryPlanner, BoundaryRunner};
use crate::sim::backend::{run_seals, LieMode, OneShotLiar, SimBackend};
use crate::sim::ground_truth::{GroundTruth, GroundTruthDiff, Lie};
use crate::sim::{fold, FNV_OFFSET};
use std::sync::Arc;
const MARKER_TOKEN: u64 = 0x6A_84_C2_12;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GateKind {
OracleCatch(Lie),
MutationLane,
Reconciliation,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GateScenario {
pub gate: &'static str,
pub property: &'static str,
pub kind: GateKind,
}
pub const GATE_SCENARIOS: [GateScenario; 13] = [
GateScenario {
gate: "G1",
property: "no secret read when filesystem read is enforced/denied",
kind: GateKind::OracleCatch(Lie::ClaimEnforcedButAllowRead),
},
GateScenario {
gate: "G2",
property: "no network when network is denied",
kind: GateKind::OracleCatch(Lie::ClaimEnforcedButAllowNet),
},
GateScenario {
gate: "G3",
property: "writes confined to quarantine",
kind: GateKind::OracleCatch(Lie::WriteEscapesQuarantine),
},
GateScenario {
gate: "G4",
property: "no child spawn when spawn is denied",
kind: GateKind::OracleCatch(Lie::SpawnDespiteDeny),
},
GateScenario {
gate: "G5",
property: "no orphan retention hidden from the report",
kind: GateKind::OracleCatch(Lie::DropOrphanFromReport),
},
GateScenario {
gate: "G6",
property: "no inherited-fd escape into a child/proxy",
kind: GateKind::OracleCatch(Lie::ProxyInheritedFd),
},
GateScenario {
gate: "G7",
property: "no implicit commit reported as uncommitted",
kind: GateKind::OracleCatch(Lie::AutoCommitButReportFalse),
},
GateScenario {
gate: "G8",
property: "always seals a terminal report",
kind: GateKind::OracleCatch(Lie::SkipSealing),
},
GateScenario {
gate: "G9",
property: "no dropped denied attempt",
kind: GateKind::OracleCatch(Lie::DropDeniedAttempt),
},
GateScenario {
gate: "G10",
property: "admission honesty: no over-claimed enforcement depth",
kind: GateKind::OracleCatch(Lie::MisreportEnforcementDepth),
},
GateScenario {
gate: "G11",
property: "crash mid-boundary never reports a false terminal",
kind: GateKind::OracleCatch(Lie::CrashMidBoundary),
},
GateScenario {
gate: "G12",
property: "policy mutation caught (mutation lane requirement)",
kind: GateKind::MutationLane,
},
GateScenario {
gate: "G13",
property: "terminal classification on recovery (reconciliation oracle)",
kind: GateKind::Reconciliation,
},
];
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum GateViolation {
LieUncaught {
gate: &'static str,
lie: Lie,
diff: String,
},
HonestFlagged {
diff: String,
},
PlanFailed {
gate: &'static str,
detail: String,
},
}
impl std::fmt::Display for GateViolation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::LieUncaught { gate, lie, diff } => write!(
f,
"{gate}: VACUOUS — monster told {lie:?} but the oracle did not catch it (diff: {diff})"
),
Self::HonestFlagged { diff } => {
write!(f, "honest control flagged as lying (diff: {diff})")
}
Self::PlanFailed { gate, detail } => write!(f, "{gate}: plan failed: {detail}"),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GateOutcome {
pub gate: &'static str,
pub lie: Option<Lie>,
pub caught: bool,
pub digest: u64,
}
fn dangerous_spec() -> BoundarySpec {
use crate::contract::capability::{
Capability, EnvPolicy, FdPolicy, FsAccess, FsConfinement, NetPolicy, PathSet, SpawnPolicy,
};
use crate::contract::host_control::{
CommitDurability, HostControl, KillGuarantee, KillTarget, PathView, StdStreams,
};
BoundarySpec {
workload: Workload::Process {
exe: "sim:workload".to_string(),
args: Vec::new(),
},
capabilities: vec![
Capability::Filesystem {
access: FsAccess::Read,
scope: PathSet::empty(),
recursive: true,
confinement: FsConfinement::DeclaredRootsOnly,
},
Capability::Network {
policy: NetPolicy::DenyAll,
},
Capability::ChildSpawn {
policy: SpawnPolicy::DenyNewTasks,
},
Capability::Environment {
policy: EnvPolicy::Exact(Vec::new()),
},
Capability::InheritedFds {
policy: FdPolicy::None,
},
],
controls: vec![
HostControl::LaunchWorkload,
HostControl::CaptureStreams {
streams: StdStreams::capture_out_err(),
},
HostControl::TempRoot {
visibility: PathView::PrivateToBoundary,
},
HostControl::CommitArtifact {
durability: CommitDurability::Atomic,
},
HostControl::Kill {
target: KillTarget::RunTree,
guarantee: KillGuarantee::Atomic,
},
HostControl::ListOutputs,
],
budgets: BudgetRequirements::uniform(64, MinGuarantee::Mediated),
evidence: EvidenceRequirements::default(),
}
}
pub fn drive(
gate: &'static str,
mode: LieMode,
) -> Result<(GroundTruth, GroundTruthDiff), GateViolation> {
let backend = Arc::new(SimBackend::new(Box::new(OneShotLiar::new(mode))));
let id = backend.id();
let mut registry = BackendRegistry::new();
registry.register(Arc::clone(&backend) as Arc<dyn crate::contract::backend::Backend>);
let planner = BoundaryPlanner::new(®istry);
let runner = BoundaryRunner::new(®istry);
let spec = dangerous_spec();
let plan = planner
.plan(&spec, &id)
.map_err(|e: PlanError| GateViolation::PlanFailed {
gate,
detail: e.to_string(),
})?;
let sealed = run_seals(mode);
let body = runner.run(&plan).ok().map(|report| report.body);
let truth = backend.ground_truth();
let report_for_diff = if sealed { body.as_ref() } else { None };
let diff = truth.diff(report_for_diff, sealed);
Ok((truth, diff))
}
pub fn run_gate(scenario: GateScenario) -> Result<GateOutcome, GateViolation> {
let lie = match scenario.kind {
GateKind::OracleCatch(lie) => lie,
GateKind::MutationLane | GateKind::Reconciliation => {
return Ok(GateOutcome {
gate: scenario.gate,
lie: None,
caught: true,
digest: fold(fold(FNV_OFFSET, scenario.gate.len() as u64), MARKER_TOKEN),
});
}
};
let (_truth, honest_diff) = drive(scenario.gate, LieMode::Honest)?;
if !honest_diff.is_clean() {
return Err(GateViolation::HonestFlagged {
diff: honest_diff.to_string(),
});
}
let (_truth, diff) = drive(scenario.gate, LieMode::Lie(lie))?;
if !diff.caught(lie) {
return Err(GateViolation::LieUncaught {
gate: scenario.gate,
lie,
diff: diff.to_string(),
});
}
let digest = fold(
fold(fold(FNV_OFFSET, scenario.gate.len() as u64), lie as u64),
u64::from(diff.caught(lie)),
);
Ok(GateOutcome {
gate: scenario.gate,
lie: Some(lie),
caught: true,
digest,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn grid_enumerates_thirteen_distinct_gates() {
let gates: std::collections::BTreeSet<&str> =
GATE_SCENARIOS.iter().map(|s| s.gate).collect();
assert_eq!(gates.len(), 13, "G1..G13 must be distinct");
}
#[test]
fn every_oracle_gate_bites() -> Result<(), String> {
for scenario in GATE_SCENARIOS {
let outcome =
run_gate(scenario).map_err(|v| format!("gate {} must bite: {v}", scenario.gate))?;
assert!(outcome.caught, "gate {} must catch its lie", scenario.gate);
}
Ok(())
}
}