Skip to main content

sim/runtime/glasses/proofs/
co_use.rs

1use sim_kernel::{Error, Expr, Result, Symbol};
2use sim_lib_intent::{Origin, intent};
3use sim_lib_view::SurfaceCaps;
4use sim_lib_view_device::{ConsentReceipt, DeviceCapability, EdgeId};
5use sim_lib_web_bridge::GlassesCoUseSession;
6use sim_value::{access, build};
7
8/// Result of the modeled Viture and Halo co-use proof.
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct CoUseProof {
11    /// Number of attached surface peers.
12    pub peers: usize,
13    /// Number of projections receiving the Halo-driven update.
14    pub broadcasts: usize,
15    /// Number of canonical edit-ledger rows appended.
16    pub ledger_rows: usize,
17    /// Whether the Viture review panel records the Halo acknowledgement.
18    pub viture_panel_acked: bool,
19}
20
21impl CoUseProof {
22    /// Encodes the proof as expression data for cookbook recipes.
23    pub fn to_expr(&self) -> Expr {
24        build::map(vec![
25            ("kind", build::qsym("glasses/sdk", "co-use-proof")),
26            ("peers", build::uint(self.peers as u64)),
27            ("broadcasts", build::uint(self.broadcasts as u64)),
28            ("ledger-rows", build::uint(self.ledger_rows as u64)),
29            ("viture-panel-acked", Expr::Bool(self.viture_panel_acked)),
30        ])
31    }
32}
33
34/// Attaches modeled Viture and Halo peers and drives the main panel from Halo.
35pub fn prove_co_use() -> Result<CoUseProof> {
36    let edge = EdgeId::named("sdk-glasses-co-use");
37    let receipt = ConsentReceipt::new(
38        vec![
39            DeviceCapability::Pose.grant_symbol(),
40            DeviceCapability::Mic.grant_symbol(),
41        ],
42        60_000,
43        Vec::new(),
44        edge.clone(),
45        7,
46    );
47    let mut session =
48        GlassesCoUseSession::new(edge, receipt, build::keyword("workspace"), workspace())?;
49    session.attach_viture(
50        SurfaceCaps::from_preset("glasses-luma-ultra", "sdk.co-use.viture")
51            .ok_or_else(|| Error::HostError("Viture surface preset missing".to_owned()))?,
52    )?;
53    session.attach_halo(
54        SurfaceCaps::from_preset("glasses-hud", "sdk.co-use.halo")
55            .ok_or_else(|| Error::HostError("Halo surface preset missing".to_owned()))?,
56    )?;
57    let tap = intent(
58        "invoke",
59        Origin::human(8),
60        vec![
61            ("target", build::sym("workspace")),
62            (
63                "op",
64                Expr::Symbol(Symbol::qualified("glasses/input", "double-tap")),
65            ),
66            ("args", build::list(Vec::new())),
67        ],
68    );
69    let broadcasts =
70        session.acknowledge_review_from_halo(&tap, Symbol::qualified("bridge", "packet-review"))?;
71    let review = access::field(session.workspace()?, "review");
72
73    Ok(CoUseProof {
74        peers: session.live_bindings().len(),
75        broadcasts: broadcasts.len(),
76        ledger_rows: session.ledger().len(),
77        viture_panel_acked: review
78            .and_then(|review| access::field_sym(review, "status"))
79            .is_some_and(|status| status.name.as_ref() == "acked"),
80    })
81}
82
83fn workspace() -> Expr {
84    build::map(vec![
85        ("title", build::text("Bridge review")),
86        (
87            "review",
88            build::map(vec![
89                (
90                    "mission",
91                    Expr::Symbol(Symbol::qualified("bridge", "packet-review")),
92                ),
93                ("status", build::sym("pending")),
94            ]),
95        ),
96    ])
97}