code wiki / (root) / nx_maint_ingest_test.nx

nx_maint_ingest_test.nx source

↩ module page · 102 lines · 4808 B

1// nx_maint_ingest_test.nx -- gate for the hardware-facing ingest rung (R1). 2// 3// Proves: every sensor KIND routes to the right kernel; the data-driven 4// normalize math (Emporia mA->centi-A, DIY deci-degC->milli-degC, offsets); 5// UNKNOWN kind is FIRST-CLASS (value computed + recorded, never dropped, no 6// false routing); bad-arg is loud; liar-kill (value tracks raw + kernel tracks 7// kind, not constants). 8// 9// expect_exit: 0 10// 11// license_tier: ORIGINAL 12 13import "nx_syscalls_x86_64.nx" 14import "nx_maint_ingest.nx" 15 16func main() -> i64 { 17 // ---- sealed enums ---- 18 if nx_sensor_kind_is_valid(NX_SENSOR_USAGE) != 1 { return 1 } 19 if nx_sensor_kind_is_valid(NX_SENSOR_N) != 0 { return 2 } 20 if nx_src_is_valid(NX_SRC_EMPORIA) != 1 { return 3 } 21 if nx_src_is_valid(NX_SRC_N) != 0 { return 4 } 22 23 // ---- routing KAT: kind -> kernel ---- 24 if nx_maint_sensor_kernel(NX_SENSOR_TEMP) != NX_MK_THERMAL { return 5 } 25 if nx_maint_sensor_kernel(NX_SENSOR_RUNTIME) != NX_MK_THERMAL { return 6 } 26 if nx_maint_sensor_kernel(NX_SENSOR_CURRENT) != NX_MK_ELECTRICAL { return 7 } 27 if nx_maint_sensor_kernel(NX_SENSOR_VOLTAGE) != NX_MK_ELECTRICAL { return 8 } 28 if nx_maint_sensor_kernel(NX_SENSOR_VIBRATION) != NX_MK_ROTATING { return 9 } 29 if nx_maint_sensor_kernel(NX_SENSOR_PRESSURE) != NX_MK_FLUID { return 10 } 30 if nx_maint_sensor_kernel(NX_SENSOR_FLOW) != NX_MK_FLUID { return 11 } 31 if nx_maint_sensor_kernel(NX_SENSOR_USAGE) != NX_MK_CONSUMABLE { return 12 } 32 if nx_maint_sensor_kernel(99) != NX_MK_NONE { return 13 } 33 34 let r: *SensorReading = sys_mmap(64) as *SensorReading 35 let out: *NormSample = sys_mmap(64) as *NormSample 36 37 // ===== TEMP (sovereign DIY): deci-degC 215 -> milli-degC 21500 == 38 r.kind = NX_SENSOR_TEMP; r.src = NX_SRC_SOVEREIGN_DIY 39 r.raw_value = 215; r.scale_num = 100; r.scale_den = 1; r.offset = 0 40 if nx_maint_ingest(r, out) != 1 { return 20 } 41 if out.value != 21500 { return 21 } 42 if out.kernel != NX_MK_THERMAL { return 22 } 43 if out.recognized != 1 { return 23 } 44 45 // ===== CURRENT (Emporia): milli-amps 15000 -> centi-amps 1500 === 46 r.kind = NX_SENSOR_CURRENT; r.src = NX_SRC_EMPORIA 47 r.raw_value = 15000; r.scale_num = 1; r.scale_den = 10; r.offset = 0 48 if nx_maint_ingest(r, out) != 1 { return 30 } 49 if out.value != 1500 { return 31 } 50 if out.kernel != NX_MK_ELECTRICAL { return 32 } 51 52 // ===== VIBRATION -> rotating =================================== 53 r.kind = NX_SENSOR_VIBRATION; r.src = NX_SRC_SOVEREIGN_DIY 54 r.raw_value = 2000; r.scale_num = 1; r.scale_den = 1; r.offset = 0 55 if nx_maint_ingest(r, out) != 1 { return 40 } 56 if out.kernel != NX_MK_ROTATING { return 41 } 57 58 // ===== PRESSURE -> fluid ======================================= 59 r.kind = NX_SENSOR_PRESSURE; r.src = NX_SRC_SOVEREIGN_DIY 60 r.raw_value = 6000; r.scale_num = 1; r.scale_den = 1; r.offset = 0 61 if nx_maint_ingest(r, out) != 1 { return 50 } 62 if out.kernel != NX_MK_FLUID { return 51 } 63 64 // ===== USAGE -> consumable ===================================== 65 r.kind = NX_SENSOR_USAGE; r.src = NX_SRC_OBD 66 r.raw_value = 100; r.scale_num = 1; r.scale_den = 1; r.offset = 0 67 if nx_maint_ingest(r, out) != 1 { return 60 } 68 if out.kernel != NX_MK_CONSUMABLE { return 61 } 69 70 // ===== offset applied ========================================== 71 r.kind = NX_SENSOR_TEMP; r.src = NX_SRC_MANUAL 72 r.raw_value = 100; r.scale_num = 1; r.scale_den = 1; r.offset = 5 73 if nx_maint_ingest(r, out) != 1 { return 70 } 74 if out.value != 105 { return 71 } 75 76 // ===== UNKNOWN kind: first-class (value computed, NO kernel, recorded) = 77 r.kind = 99; r.src = NX_SRC_SOVEREIGN_DIY 78 r.raw_value = 42; r.scale_num = 1; r.scale_den = 1; r.offset = 0 79 if nx_maint_ingest(r, out) != 0 { return 80 } 80 if out.kernel != NX_MK_NONE { return 81 } 81 if out.recognized != 0 { return 82 } 82 if out.value != 42 { return 83 } // still computed -- recorded, not dropped 83 84 // ===== BAD_ARG: scale_den 0 (cannot normalize) ================= 85 r.kind = NX_SENSOR_TEMP; r.scale_den = 0 86 if nx_maint_ingest(r, out) != (0 - 2) { return 90 } 87 88 // ===== LIAR-KILL: value tracks raw, kernel tracks kind ========= 89 r.kind = NX_SENSOR_CURRENT; r.src = NX_SRC_EMPORIA 90 r.raw_value = 15000; r.scale_num = 1; r.scale_den = 10; r.offset = 0 91 nx_maint_ingest(r, out) 92 let v1: i64 = out.value 93 let k1: i64 = out.kernel 94 r.raw_value = 30000 95 nx_maint_ingest(r, out) 96 if out.value == v1 { return 92 } // value tracks raw (1500 vs 3000) 97 r.kind = NX_SENSOR_TEMP; r.raw_value = 215; r.scale_num = 100; r.scale_den = 1 98 nx_maint_ingest(r, out) 99 if out.kernel == k1 { return 93 } // kernel tracks kind (electrical vs thermal) 100 101 return 0 102}