qualia_core_db/render/
standpoint.rs1use crate::q_hash;
5use crate::render::telemetry::{
6 ObserverStandpoint, DEONTIC_LANE_BILATERAL, DEONTIC_LANE_COMMONS, FABRIC_VIEWPORT_LOCAL,
7 STANDPOINT_DID, STANDPOINT_EPHEMERAL, STANDPOINT_SPECTATOR, STANDPOINT_VAULT,
8};
9
10#[inline]
12pub fn generate_session_nonce() -> u64 {
13 let mut buf = [0u8; 8];
14 if getrandom::fill(&mut buf).is_err() {
15 let fallback = std::time::SystemTime::now()
16 .duration_since(std::time::UNIX_EPOCH)
17 .map(|d| d.as_nanos() as u64)
18 .unwrap_or(0);
19 buf = fallback.to_le_bytes();
20 }
21 u64::from_le_bytes(buf)
22}
23
24#[inline]
26pub fn spectator_default(session_nonce: u64) -> ObserverStandpoint {
27 let hash = q_hash("q42:observer:ephemeral") ^ session_nonce;
28 ObserverStandpoint::new(
29 hash,
30 session_nonce,
31 STANDPOINT_SPECTATOR,
32 1.0,
33 0.5,
34 1.0,
35 DEONTIC_LANE_COMMONS,
36 FABRIC_VIEWPORT_LOCAL,
37 )
38}
39
40#[inline]
42pub fn ephemeral_session(session_nonce: u64) -> ObserverStandpoint {
43 let hash = q_hash("q42:observer:session") ^ session_nonce;
44 ObserverStandpoint::new(
45 hash,
46 session_nonce,
47 STANDPOINT_EPHEMERAL,
48 1.0,
49 0.5,
50 1.0,
51 DEONTIC_LANE_COMMONS,
52 FABRIC_VIEWPORT_LOCAL,
53 )
54}
55
56#[inline]
58pub fn identifier_standpoint(
59 did_hash: u64,
60 session_nonce: u64,
61 epistemic_q: f32,
62) -> ObserverStandpoint {
63 ObserverStandpoint::new(
64 did_hash,
65 session_nonce,
66 STANDPOINT_DID,
67 epistemic_q.clamp(0.0, 1.0),
68 0.5,
69 1.0,
70 DEONTIC_LANE_COMMONS,
71 FABRIC_VIEWPORT_LOCAL,
72 )
73}
74
75#[inline]
77pub fn vault_standpoint(vault_hash: u64, session_nonce: u64) -> ObserverStandpoint {
78 ObserverStandpoint::new(
79 vault_hash,
80 session_nonce,
81 STANDPOINT_VAULT,
82 0.0,
83 0.5,
84 0.05,
85 DEONTIC_LANE_BILATERAL,
86 FABRIC_VIEWPORT_LOCAL,
87 )
88}
89
90#[inline]
92pub fn resolve_standpoint_hash(
93 standpoint_class: u32,
94 session_nonce: u64,
95 identifier_did: &str,
96) -> u64 {
97 if identifier_did.is_empty() {
98 return match standpoint_class {
99 STANDPOINT_EPHEMERAL => q_hash("q42:observer:session") ^ session_nonce,
100 STANDPOINT_VAULT => q_hash("q42:observer:vault") ^ session_nonce,
101 _ => q_hash("q42:observer:ephemeral") ^ session_nonce,
102 };
103 }
104 q_hash(identifier_did)
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn spectator_hash_is_deterministic_for_nonce() {
113 let a = spectator_default(42);
114 let b = spectator_default(42);
115 assert_eq!(a.standpoint_hash, b.standpoint_hash);
116 assert_eq!(a.standpoint_class, STANDPOINT_SPECTATOR);
117 assert_eq!(a.epistemic_q, 1.0);
118 }
119
120 #[test]
121 fn identifier_standpoint_uses_supplied_hash() {
122 let did = q_hash("did:example:alice");
123 let sp = identifier_standpoint(did, 7, 0.8);
124 assert_eq!(sp.standpoint_hash, did);
125 assert_eq!(sp.standpoint_class, STANDPOINT_DID);
126 }
127}