Skip to main content

qualia_core_db/render/
telemetry.rs

1//! GPU telemetry and observer contracts for the Qualia portal (U2 viewport).
2
3use bytemuck::{Pod, Zeroable};
4
5use crate::gpu_context::sample_ambient_telemetry;
6
7/// Untethered commons spectator (default onboarding ramp).
8pub const STANDPOINT_SPECTATOR: u32 = 0;
9/// Ephemeral session — local activity qualia, no cryptographic permanence.
10pub const STANDPOINT_EPHEMERAL: u32 = 1;
11/// Verified Human-Centric identifier (DID) — opt-in permanence; vault data plane is sealed.
12pub const STANDPOINT_DID: u32 = 2;
13/// Private vault slice — bilateral lane, collapsed epistemic aperture.
14pub const STANDPOINT_VAULT: u32 = 3;
15
16/// Permissive Commons routing lane (`PermissiveRoutingLane::EnforcePermissiveCommons`).
17pub const DEONTIC_LANE_COMMONS: u32 = 1;
18/// Bilateral Micro-Commons (`PermissiveRoutingLane::EnforceBilateralMicroCommons`).
19pub const DEONTIC_LANE_BILATERAL: u32 = 2;
20
21/// Telemetry and fabric writes stay on the local viewport machine.
22pub const FABRIC_VIEWPORT_LOCAL: u32 = 0;
23/// Shared tensor fabric (requires authenticated standpoint).
24pub const FABRIC_SHARED: u32 = 1;
25
26/// System telemetry for ambient / projector shaders (`#[repr(C)]`, 48 bytes).
27#[repr(C)]
28#[derive(Clone, Copy, Debug, Default, Pod, Zeroable, serde::Serialize, serde::Deserialize)]
29pub struct SystemTelemetry {
30    pub memory_pressure: f32,
31    pub network_ripple: f32,
32    pub baking_crystallization: f32,
33    pub logic_flashes: f32,
34    pub llm_heat: f32,
35    pub quantum_activity: f32,
36    pub spectral_shift: f32,
37    pub temporal_pulse: f32,
38    pub epistemic_density: f32,
39    pub manifold_pressure: f32,
40    pub _padding: [f32; 2],
41}
42
43impl SystemTelemetry {
44    #[inline]
45    pub fn from_samples(samples: &[f32; 11]) -> Self {
46        Self {
47            memory_pressure: samples[0],
48            network_ripple: samples[1],
49            baking_crystallization: samples[2],
50            logic_flashes: samples[3],
51            llm_heat: samples[4],
52            quantum_activity: samples[5],
53            spectral_shift: samples[6],
54            temporal_pulse: samples[7],
55            epistemic_density: samples[8],
56            manifold_pressure: samples[9],
57            _padding: [0.0, samples[10]],
58        }
59    }
60
61    #[inline]
62    pub fn refresh_from_ledger(&mut self) {
63        *self = Self::from_samples(&sample_ambient_telemetry());
64    }
65
66    #[inline]
67    pub fn apply_floats(&mut self, floats: &[f32]) {
68        let mut samples = sample_ambient_telemetry();
69        for (i, slot) in samples.iter_mut().enumerate() {
70            if let Some(v) = floats.get(i) {
71                *slot = *v;
72            }
73        }
74        *self = Self::from_samples(&samples);
75    }
76}
77
78#[repr(C)]
79#[derive(Clone, Copy, Debug, Pod, Zeroable)]
80pub struct AmbientUniforms {
81    pub time: f32,
82    pub view_width: f32,
83    pub view_height: f32,
84    pub _padding: f32,
85}
86
87#[repr(C)]
88#[derive(Clone, Copy, Debug, Pod, Zeroable)]
89pub struct ParticleInstance {
90    pub position: [f32; 3],
91    /// Epistemic q-state: 0 = collapsed ground truth, >0 = generative sandbox.
92    pub epistemic_q: f32,
93}
94
95/// Vertex instance for `projector.wgsl` (vec3 position + vec4 color, 32 B aligned).
96#[repr(C)]
97#[derive(Clone, Copy, Debug, Pod, Zeroable)]
98pub struct TensorRenderInstance {
99    pub position: [f32; 3],
100    pub _pad0: f32,
101    pub color: [f32; 4],
102}
103
104/// Camera IPC uniform — shared by ambient (binding 3) and `projector.wgsl` (binding 0).
105///
106/// `view_projection` is pre-multiplied on the CPU; PGA motors in the projector shader
107/// apply per-object semantic transforms on top of this view.
108#[repr(C)]
109#[derive(Clone, Copy, Debug, Pod, Zeroable)]
110pub struct CameraUniform {
111    pub view_projection: [[f32; 4]; 4],
112    pub yaw: f32,
113    pub pitch: f32,
114    pub zoom: f32,
115    /// Non-zero when tensor SOA is resident — ambient/projector use `view_projection`.
116    pub tensor_mode: u32,
117    /// `_padding[0]` = frame time (seconds) for PGA epistemic spin in `projector.wgsl`.
118    /// `_padding[1..4]` = camera eye `(x, y, z)` for Phase 2c bilateral `T_pull`.
119    pub _padding: [f32; 12],
120}
121
122/// Human-Centric observer standpoint — semantic right to perceive (decoupled from `CameraUniform`).
123///
124/// Anchors the viewport to the human and their chosen context (spectator → ephemeral → DID → vault),
125/// not to cryptographic vault weight alone. WGSL reads `standpoint_hash` / `session_nonce` as
126/// `vec2<u32>` (little-endian u64). Temporal scrub: projector discards vertices when
127/// `|tensor.t - t_slice| > t_window`.
128#[repr(C)]
129#[derive(Clone, Copy, Debug, Pod, Zeroable)]
130pub struct ObserverStandpoint {
131    pub standpoint_hash: u64,
132    pub session_nonce: u64,
133    /// Spectator default = 1.0 (full commons aperture); vault collapse → 0.0.
134    pub epistemic_q: f32,
135    /// Active temporal slice coordinate (scrub axis).
136    pub t_slice: f32,
137    /// Half-width of visible temporal band; large values show the full trace.
138    pub t_window: f32,
139    /// Deontic routing lane (`DEONTIC_LANE_COMMONS` for spectator).
140    pub deontic_lane: u32,
141    /// `STANDPOINT_*` class — spectator / ephemeral / DID / vault.
142    pub standpoint_class: u32,
143    /// `FABRIC_VIEWPORT_LOCAL` until authenticated DID opens shared fabric.
144    pub fabric_gate: u32,
145    pub _padding: [f32; 22],
146}
147
148impl ObserverStandpoint {
149    #[inline]
150    pub const fn new(
151        standpoint_hash: u64,
152        session_nonce: u64,
153        standpoint_class: u32,
154        epistemic_q: f32,
155        t_slice: f32,
156        t_window: f32,
157        deontic_lane: u32,
158        fabric_gate: u32,
159    ) -> Self {
160        Self {
161            standpoint_hash,
162            session_nonce,
163            epistemic_q,
164            t_slice,
165            t_window,
166            deontic_lane,
167            standpoint_class,
168            fabric_gate,
169            _padding: [0.0; 22],
170        }
171    }
172
173    #[inline]
174    pub fn with_temporal(mut self, t_slice: f32, t_window: f32) -> Self {
175        self.t_slice = t_slice;
176        self.t_window = t_window.max(0.0);
177        self
178    }
179
180    #[inline]
181    pub fn temporal_visible(&self, tensor_t: f32) -> bool {
182        (tensor_t - self.t_slice).abs() <= self.t_window
183    }
184}
185
186#[cfg(test)]
187mod tests {
188    use super::*;
189
190    #[test]
191    fn system_telemetry_is_48_bytes() {
192        assert_eq!(std::mem::size_of::<SystemTelemetry>(), 48);
193        assert_eq!(std::mem::size_of::<AmbientUniforms>(), 16);
194        assert_eq!(std::mem::size_of::<ParticleInstance>(), 16);
195        assert_eq!(std::mem::size_of::<CameraUniform>(), 128);
196        assert_eq!(std::mem::size_of::<ObserverStandpoint>(), 128);
197    }
198
199    #[test]
200    fn temporal_filter_respects_window() {
201        let sp = ObserverStandpoint::new(0, 0, STANDPOINT_SPECTATOR, 1.0, 0.5, 0.1, 1, 0);
202        assert!(sp.temporal_visible(0.45));
203        assert!(!sp.temporal_visible(0.7));
204    }
205}