nx_vitals.nx source
↩ module page · 263 lines · 10784 B
1// nx_vitals.nx -- metabolic-signature attestation via external
2// instrumentation.
3//
4// Per META-CARDINAL feedback-ecosystem-defense-risk-register-three-fears
5// §2.7: external sensors (power / thermal / EM / acoustic / mass / network-
6// tap) compare observed device metabolic signatures against expected
7// envelopes derived from device's Bill-of-Materials. Detects hidden
8// silicon + tampered firmware + Hezbollah-pager-class trigger circuits
9// + supply-chain modifications -- physics doesn't lie.
10//
11// Biology anchor: vital signs (pulse / breath / temperature / blood pressure)
12// are externally-measurable indicators of metabolic state. Predators
13// detect prey via metabolic signatures all the time (pit vipers IR;
14// mosquitoes CO2 plumes; owls heartbeat-through-snow; sharks bioelectric).
15// The active organism cannot fully hide its metabolism from a properly-
16// instrumented observer.
17//
18// The positive-security hardware model: enumerate every legitimate
19// electronic component + its expected power+mass+thermal+RF profile
20// = expected envelope. Any deviation = unaccounted-for component =
21// possible compromise. Physics doesn't lie.
22//
23// Composes:
24// nx_attest_silicon -- vitals-clean elevates trust on commodity host
25// nx_thymus_audit_report -- aggregated vitals metrics + alerts
26// nx_immune -- runtime anomaly fires lysis pathway
27// nx_provenance_chain -- every vitals reading + alert chain-logged
28//
29// V1 ships:
30// - sealed enum of measurement sources (DC_RAIL / AC_WALL / THERMAL /
31// SDR_RF / NETWORK_TAP / ACOUSTIC / MASS)
32// - BOM-envelope struct + per-source expected window (min, max, units)
33// - reading struct + deviation predicate
34// - aggregator across sources + verdict
35//
36// Gap list (V1 honest perf verdict):
37// - per-host BOM is operator-attested + community-maintained;
38// vendor BOMs incomplete; reverse-engineering expensive
39// - statistical-envelope thresholds are caller-supplied (V2 makes
40// per-niche policy from accumulated baseline readings)
41// - V1 cannot fully detect sophisticated power-shaping camouflage;
42// raises detection threshold, does not eliminate
43// - V1 cannot detect supply-chain physical modification at receive
44// time -- requires mass + thermal + RF baseline measurement
45// workflow built around this primitive (queued in audit dashboard)
46//
47// genealogy_id: nishi_metacardinal_2026-05-19_ecosystem_defense_three_fears
48// lineage_id: substrate_vitals_v1
49//
50// nx_safety_envelope:
51// intended_use: "External-instrumentation metabolic-signature
52// attestation via BOM envelope + per-source
53// deviation detection; substrate informs,
54// operator decides actions"
55// sil_target: SIL2
56// evidence: [enum_sealed, envelope_data_driven,
57// operator_review_for_alerts]
58// verdict: NOT_YET_EVALUATED
59
60import "nx_syscalls.nx"
61import "nx_tier.nx"
62
63// ===== Sealed enum: NxVitalsSource ================================
64
65const NX_VS_DC_RAIL: nx_int = 0
66const NX_VS_AC_WALL: nx_int = 1
67const NX_VS_THERMAL: nx_int = 2
68const NX_VS_SDR_RF: nx_int = 3
69const NX_VS_NETWORK_TAP: nx_int = 4
70const NX_VS_ACOUSTIC: nx_int = 5
71const NX_VS_MASS: nx_int = 6
72const NX_VS_N_SOURCES: nx_int = 7
73
74// ===== Sealed enum: NxVitalsState =================================
75//
76// Operational state at which the envelope applies. ME activity at OFF
77// state is detection-class; the same draw at HEAVY_LOAD is normal.
78
79const NX_VS_STATE_OFF: nx_int = 0
80const NX_VS_STATE_STANDBY: nx_int = 1
81const NX_VS_STATE_IDLE: nx_int = 2
82const NX_VS_STATE_TYPICAL_LOAD: nx_int = 3
83const NX_VS_STATE_HEAVY_LOAD: nx_int = 4
84const NX_VS_STATE_N_STATES: nx_int = 5
85
86// ===== Sealed enum: NxVitalsVerdict ===============================
87
88const NX_VV_WITHIN_ENVELOPE: nx_int = 0
89const NX_VV_LOW_DEVIATION: nx_int = 1
90const NX_VV_HIGH_DEVIATION: nx_int = 2
91const NX_VV_CRITICAL_DEVIATION: nx_int = 3
92const NX_VV_INVALID: nx_int = 99
93const NX_VV_N_VERDICTS: nx_int = 4
94
95// ===== Struct: NxVitalsEnvelope ===================================
96//
97// Expected reading window for one (source, state) tuple. units_q10
98// is a units-tag (0=raw, 1=mA, 2=mW, 3=Celsius, etc.) for forensic
99// display; V1 envelope comparisons are unit-agnostic (caller supplies
100// values in consistent units).
101
102struct NxVitalsEnvelope {
103 source: nx_int,
104 state: nx_int,
105 min_value: nx_size,
106 max_value: nx_size,
107 units_tag: nx_int,
108 low_dev_threshold: nx_size, // bytes outside [min,max] for LOW
109 high_dev_threshold: nx_size, // bytes outside [min,max] for HIGH
110 critical_dev_threshold: nx_size, // bytes outside [min,max] for CRITICAL
111}
112
113const NX_VS_ENV_BYTES: nx_int = 64
114
115// ===== Struct: NxVitalsReading ====================================
116
117struct NxVitalsReading {
118 source: nx_int,
119 state: nx_int,
120 measured_value: nx_size,
121 measured_at_us: nx_size,
122}
123
124const NX_VS_RD_BYTES: nx_int = 32
125
126// ===== nx_vs_source_is_valid ======================================
127
128func nx_vs_source_is_valid(s: nx_int) -> nx_int {
129 if s < 0 { return 0 }
130 if s >= NX_VS_N_SOURCES { return 0 }
131 return 1
132}
133
134// ===== nx_vs_state_is_valid =======================================
135
136func nx_vs_state_is_valid(s: nx_int) -> nx_int {
137 if s < 0 { return 0 }
138 if s >= NX_VS_STATE_N_STATES { return 0 }
139 return 1
140}
141
142// ===== nx_vv_verdict_is_valid =====================================
143
144func nx_vv_verdict_is_valid(v: nx_int) -> nx_int {
145 if v < 0 { return 0 }
146 if v >= NX_VV_N_VERDICTS { return 0 }
147 return 1
148}
149
150// ===== nx_vv_is_concerning ========================================
151//
152// Predicate: returns 1 if the verdict requires operator attention.
153// WITHIN_ENVELOPE returns 0; every deviation level returns 1.
154
155func nx_vv_is_concerning(v: nx_int) -> nx_int {
156 if v == NX_VV_WITHIN_ENVELOPE { return 0 }
157 if nx_vv_verdict_is_valid(v) == 0 { return 0 }
158 return 1
159}
160
161// ===== nx_vs_envelope_new =========================================
162
163func nx_vs_envelope_new(source: nx_int,
164 state: nx_int,
165 min_value: nx_size,
166 max_value: nx_size,
167 low_dev: nx_size,
168 high_dev: nx_size,
169 critical_dev: nx_size) -> *NxVitalsEnvelope {
170 let raw: *u8 = sys_mmap(NX_VS_ENV_BYTES)
171 let e: *NxVitalsEnvelope = raw as *NxVitalsEnvelope
172 e.source = source
173 e.state = state
174 e.min_value = min_value
175 e.max_value = max_value
176 e.units_tag = 0
177 e.low_dev_threshold = low_dev
178 e.high_dev_threshold = high_dev
179 e.critical_dev_threshold = critical_dev
180 return e
181}
182
183// ===== nx_vs_reading_new ==========================================
184
185func nx_vs_reading_new(source: nx_int,
186 state: nx_int,
187 measured_value: nx_size,
188 measured_at_us: nx_size) -> *NxVitalsReading {
189 let raw: *u8 = sys_mmap(NX_VS_RD_BYTES)
190 let r: *NxVitalsReading = raw as *NxVitalsReading
191 r.source = source
192 r.state = state
193 r.measured_value = measured_value
194 r.measured_at_us = measured_at_us
195 return r
196}
197
198// ===== _vs_deviation ==============================================
199//
200// Compute deviation from envelope range. Returns 0 if reading is
201// within [min,max]; returns absolute distance to nearest bound
202// otherwise.
203
204func _vs_deviation(value: nx_size, min_v: nx_size, max_v: nx_size) -> nx_size {
205 if value < min_v { return min_v - value }
206 if value > max_v { return value - max_v }
207 return 0
208}
209
210// ===== nx_vs_classify =============================================
211//
212// Compare reading against envelope + emit verdict. Verdict reflects
213// the worst-case threshold crossed:
214// deviation == 0 -> WITHIN_ENVELOPE
215// 0 < deviation < low_dev_threshold -> WITHIN_ENVELOPE
216// low_dev_threshold <= deviation < high_dev -> LOW_DEVIATION
217// high_dev <= deviation < critical_dev -> HIGH_DEVIATION
218// critical_dev <= deviation -> CRITICAL_DEVIATION
219// source/state mismatch -> INVALID
220
221func nx_vs_classify(reading: *NxVitalsReading,
222 env: *NxVitalsEnvelope) -> nx_int {
223 if (reading as i64) == 0 { return NX_VV_INVALID }
224 if (env as i64) == 0 { return NX_VV_INVALID }
225 if reading.source != env.source { return NX_VV_INVALID }
226 if reading.state != env.state { return NX_VV_INVALID }
227 let dev: nx_size = _vs_deviation(reading.measured_value,
228 env.min_value, env.max_value)
229 if dev == 0 { return NX_VV_WITHIN_ENVELOPE }
230 if dev < env.low_dev_threshold { return NX_VV_WITHIN_ENVELOPE }
231 if dev < env.high_dev_threshold { return NX_VV_LOW_DEVIATION }
232 if dev < env.critical_dev_threshold { return NX_VV_HIGH_DEVIATION }
233 return NX_VV_CRITICAL_DEVIATION
234}
235
236// ===== nx_vs_verdict_priority =====================================
237//
238// When aggregating across multiple readings, return the highest
239// concern level. Higher numeric value = more concerning.
240
241func nx_vs_verdict_priority(v: nx_int) -> nx_int {
242 if nx_vv_verdict_is_valid(v) == 0 { return 0 }
243 return v
244}
245
246// ===== nx_vs_classify_off_state_active_ME =========================
247//
248// Convenience: the canonical Intel-ME-active-while-system-off check.
249// At STATE_OFF, the host's expected DC rail draw is near zero (~0-5mA);
250// observed draw of 100mA+ indicates a hidden processor is active.
251// This is the proven-shipping detection vector documented in
252// ecosystem-defense roadmap §3.2.1.
253
254func nx_vs_classify_off_state_active_ME(dc_rail_ma: nx_size) -> nx_int {
255 let env: *NxVitalsEnvelope = nx_vs_envelope_new(NX_VS_DC_RAIL,
256 NX_VS_STATE_OFF,
257 0, 5, // 0-5mA at OFF
258 10, 50, 100)
259 let r: *NxVitalsReading = nx_vs_reading_new(NX_VS_DC_RAIL,
260 NX_VS_STATE_OFF,
261 dc_rail_ma, 0)
262 return nx_vs_classify(r, env)
263}