Skip to main content

sim/runtime/
reference_device.rs

1//! Hardware-free reference device profiles, adapters, and cookbook proofs.
2//!
3//! The reference device is a reusable modeled target for device bootstrapping:
4//! it exposes one rich pose-coupled profile, one compact glance profile, a
5//! deterministic sample source, and proof callables that exercise timing,
6//! consent, retention, and route rebinding without touching real hardware.
7
8use std::sync::Arc;
9
10use sim_kernel::{AbiVersion, Cx, Export, Lib, LibManifest, LibTarget, Linker, Result, Version};
11
12mod consent;
13#[cfg(feature = "cookbook")]
14mod cookbook;
15mod profiles;
16mod proof_functions;
17mod route;
18mod two_rate;
19
20pub use consent::{
21    ConsentProof, RetentionProof, prove_consent_without_kernel_grant, prove_retention_reaper,
22    reference_edge_id, reference_pose_receipt, require_reference_pose,
23};
24#[cfg(feature = "cookbook")]
25pub use cookbook::RECIPES;
26pub use profiles::{
27    ReferencePose, ReferenceRichAdapter, ReferenceSceneEncoder, reference_caps_source,
28    reference_glance_profile, reference_glance_profile_symbol, reference_rich_profile,
29    reference_rich_profile_symbol, reference_scene,
30};
31use proof_functions::{ProofKind, ReferenceProofFunction, proof_function_symbol};
32pub use route::{RouteSwapProof, prove_route_swap};
33pub use two_rate::{TwoRateProof, prove_two_rate};
34
35/// Host-registered lib that exposes reference profiles and proof callables.
36pub struct ReferenceDeviceLib;
37
38impl Lib for ReferenceDeviceLib {
39    fn manifest(&self) -> LibManifest {
40        LibManifest {
41            id: reference_device_manifest_symbol(),
42            version: Version(env!("CARGO_PKG_VERSION").to_owned()),
43            abi: AbiVersion { major: 0, minor: 1 },
44            target: LibTarget::HostRegistered,
45            requires: Vec::new(),
46            capabilities: Vec::new(),
47            exports: vec![
48                Export::Value {
49                    symbol: reference_rich_profile_symbol(),
50                },
51                Export::Value {
52                    symbol: reference_glance_profile_symbol(),
53                },
54                Export::Value {
55                    symbol: proof_function_symbol(ProofKind::TwoRate),
56                },
57                Export::Value {
58                    symbol: proof_function_symbol(ProofKind::Consent),
59                },
60                Export::Value {
61                    symbol: proof_function_symbol(ProofKind::RouteSwap),
62                },
63            ],
64        }
65    }
66
67    fn load(&self, cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
68        linker.value(
69            reference_rich_profile_symbol(),
70            cx.factory().expr(reference_rich_profile().to_expr())?,
71        )?;
72        linker.value(
73            reference_glance_profile_symbol(),
74            cx.factory().expr(reference_glance_profile().to_expr())?,
75        )?;
76        for kind in ProofKind::ALL {
77            linker.value(
78                proof_function_symbol(kind),
79                cx.factory()
80                    .opaque(Arc::new(ReferenceProofFunction { kind }))?,
81            )?;
82        }
83        Ok(())
84    }
85}
86
87/// Installs the device base and the SDK reference-device exports.
88pub fn install_device_base(cx: &mut Cx) -> Result<()> {
89    sim_lib_stream_device::install_device_stream_base(cx)?;
90    sim_lib_core::install_once(cx, &ReferenceDeviceLib)?;
91    Ok(())
92}
93
94/// Installs the modeled reference device into a context.
95pub fn install_reference_device(cx: &mut Cx) -> Result<()> {
96    install_device_base(cx)
97}
98
99/// Returns the manifest id for the reference-device facade.
100pub fn reference_device_manifest_symbol() -> sim_kernel::Symbol {
101    sim_kernel::Symbol::qualified("device", "reference")
102}
103
104/// Reads a boolean field from a proof expression.
105#[cfg(test)]
106pub(crate) fn bool_field(expr: &sim_kernel::Expr, field: &'static str) -> bool {
107    sim_value::access::field_bool(expr, field).unwrap_or(false)
108}