nx_maint_unify.nx source
↩ module page · 120 lines · 5461 B
1// nx_maint_unify.nx -- R3 unify: the 5 physics kernels speak ONE health
2// language. Each kernel's native verdict maps to a common severity scale so the
3// ledger / DIY app / enterprise fleet-rollup present a uniform grade across
4// every asset type -- and safety-critical faults (overheat, ground-fault,
5// overload, burst) UNIFORMLY surface as SAFETY regardless of which kernel found
6// them. Plus a unified MaintResult row.
7//
8// (The kernels keep their own typed entry points -- their inputs genuinely
9// differ -- so "unify" is at the verdict/severity layer, which is what the
10// platform surface actually needs; forcing one input signature would be worse.)
11//
12// Operator (2026-06-23): build "from the hardware rung up each rung" -- this is
13// R3, consolidating R2's five kernels into one engine the fronts can consume.
14//
15// NEVER-BRICK (#26): pure mapping; no syscalls, no device writes.
16//
17// genealogy_id: project-maintenance-platform-sclass-2026-06-23 (R3 unify)
18// license_tier: ORIGINAL
19
20import "nx_maint_ingest.nx" // NX_MK_* kernel ids
21import "nx_hvac_efficiency.nx" // NX_HVAC_*
22import "nx_rot_health.nx" // NX_ROT_*
23import "nx_consumable.nx" // NX_CONS_*
24import "nx_fluid_seal.nx" // NX_FLUID_*
25import "nx_electrical.nx" // NX_ELEC_*
26
27// ---- Common health-severity scale (ascending urgency) --------------
28const NX_HEALTH_NODATA: i64 = 0
29const NX_HEALTH_OK: i64 = 1
30const NX_HEALTH_IDLE: i64 = 2
31const NX_HEALTH_WATCH: i64 = 3 // early warning / monitor
32const NX_HEALTH_DEGRADED: i64 = 4 // plan service
33const NX_HEALTH_URGENT: i64 = 5 // act soon (failure / over-life)
34const NX_HEALTH_SAFETY: i64 = 6 // hazard: fire / shock / burst (highest)
35const NX_HEALTH_UNKNOWN: i64 = 7 // unmapped (first-class)
36const NX_HEALTH_N: i64 = 8
37
38func nx_health_is_valid(h: i64) -> i64 {
39 if h < 0 { return 0 }
40 if h >= NX_HEALTH_N { return 0 }
41 return 1
42}
43
44// ---- Per-kernel verdict -> common severity -------------------------
45func nx_health_from_thermal(v: i64) -> i64 {
46 if v == NX_HVAC_INSUFFICIENT_DATA { return NX_HEALTH_NODATA }
47 if v == NX_HVAC_EFFICIENT { return NX_HEALTH_OK }
48 if v == NX_HVAC_SHORT_CYCLING { return NX_HEALTH_DEGRADED }
49 if v == NX_HVAC_DEGRADED_CAPACITY { return NX_HEALTH_DEGRADED }
50 if v == NX_HVAC_POOR_TRACKING { return NX_HEALTH_WATCH }
51 if v == NX_HVAC_IDLE { return NX_HEALTH_IDLE }
52 return NX_HEALTH_UNKNOWN
53}
54func nx_health_from_rot(v: i64) -> i64 {
55 if v == NX_ROT_INSUFFICIENT_DATA { return NX_HEALTH_NODATA }
56 if v == NX_ROT_HEALTHY { return NX_HEALTH_OK }
57 if v == NX_ROT_ROUGH_WARNING { return NX_HEALTH_WATCH }
58 if v == NX_ROT_ROUGH_ALARM { return NX_HEALTH_DEGRADED }
59 if v == NX_ROT_BEARING_WEAR { return NX_HEALTH_URGENT }
60 if v == NX_ROT_OVERHEAT { return NX_HEALTH_SAFETY }
61 if v == NX_ROT_IDLE { return NX_HEALTH_IDLE }
62 return NX_HEALTH_UNKNOWN
63}
64func nx_health_from_cons(v: i64) -> i64 {
65 if v == NX_CONS_INSUFFICIENT_DATA { return NX_HEALTH_NODATA }
66 if v == NX_CONS_OK { return NX_HEALTH_OK }
67 if v == NX_CONS_DUE_SOON { return NX_HEALTH_WATCH }
68 if v == NX_CONS_DUE { return NX_HEALTH_DEGRADED }
69 if v == NX_CONS_OVERDUE { return NX_HEALTH_URGENT }
70 return NX_HEALTH_UNKNOWN
71}
72func nx_health_from_fluid(v: i64) -> i64 {
73 if v == NX_FLUID_INSUFFICIENT_DATA { return NX_HEALTH_NODATA }
74 if v == NX_FLUID_SEALED { return NX_HEALTH_OK }
75 if v == NX_FLUID_SEEPAGE { return NX_HEALTH_WATCH }
76 if v == NX_FLUID_LEAK { return NX_HEALTH_DEGRADED }
77 if v == NX_FLUID_RAPID_LOSS { return NX_HEALTH_SAFETY }
78 if v == NX_FLUID_NO_PRESSURE { return NX_HEALTH_URGENT }
79 return NX_HEALTH_UNKNOWN
80}
81func nx_health_from_elec(v: i64) -> i64 {
82 if v == NX_ELEC_INSUFFICIENT_DATA { return NX_HEALTH_NODATA }
83 if v == NX_ELEC_NOMINAL { return NX_HEALTH_OK }
84 if v == NX_ELEC_HIGH_LOAD { return NX_HEALTH_WATCH }
85 if v == NX_ELEC_OVERLOAD { return NX_HEALTH_SAFETY }
86 if v == NX_ELEC_VOLTAGE_SAG { return NX_HEALTH_DEGRADED }
87 if v == NX_ELEC_VOLTAGE_SWELL { return NX_HEALTH_DEGRADED }
88 if v == NX_ELEC_GROUND_FAULT { return NX_HEALTH_SAFETY }
89 if v == NX_ELEC_IDLE { return NX_HEALTH_IDLE }
90 return NX_HEALTH_UNKNOWN
91}
92
93// ---- Unified dispatch: (kernel, native verdict) -> common severity ---
94func nx_maint_severity(kernel: i64, verdict: i64) -> i64 {
95 if kernel == NX_MK_THERMAL { return nx_health_from_thermal(verdict) }
96 if kernel == NX_MK_ROTATING { return nx_health_from_rot(verdict) }
97 if kernel == NX_MK_CONSUMABLE { return nx_health_from_cons(verdict) }
98 if kernel == NX_MK_FLUID { return nx_health_from_fluid(verdict) }
99 if kernel == NX_MK_ELECTRICAL { return nx_health_from_elec(verdict) }
100 return NX_HEALTH_UNKNOWN
101}
102
103// ---- Unified result row (what the ledger / fronts / rollup store) ----
104struct MaintResult {
105 asset_class: i64,
106 kernel: i64,
107 native_verdict: i64,
108 severity: i64, // NX_HEALTH_*
109 headline: i64, // the kernel's headline metric (resp / crest / remaining / decay / load)
110}
111
112func nx_maint_result_fill(asset_class: i64, kernel: i64, native_verdict: i64,
113 headline: i64, out: *MaintResult) -> i64 {
114 out.asset_class = asset_class
115 out.kernel = kernel
116 out.native_verdict = native_verdict
117 out.headline = headline
118 out.severity = nx_maint_severity(kernel, native_verdict)
119 return out.severity
120}