code wiki / (root) / nx_maint_render.nx

nx_maint_render.nx source

↩ module page · 148 lines · 6506 B

1// nx_maint_render.nx -- R6: the fronts. Renders a MaintResult + ActionPlan into 2// a self-contained, ZERO-JS, privacy-first HTML card -- in two modes: DIY 3// ("what to do yourself") and ENTERPRISE ("work order / dispatch"). Same core, 4// two fronts (the operator's monitor/fix/replace, DIYer -> enterprise). 5// 6// Operator doctrine (Vizsla/IoT render arcs): 0 <script>, 0 third-party loads, 7// data treated as valuable not stolen -> FAIL-CLOSED: the card self-scans and 8// nx_maint_render_is_clean REFUSES anything containing a script or an http load. 9// 10// Operator (2026-06-23): "from the hardware rung up each rung" -- R6 on top of 11// R5's ActionPlan. The last SOLO rung before R0 (live) needs hardware. 12// 13// NEVER-BRICK (#26): builds bytes into a caller buffer; no syscalls, no writes. 14// 15// genealogy_id: project-maintenance-platform-sclass-2026-06-23 (R6 fronts) 16// license_tier: ORIGINAL 17 18import "nx_maint_action.nx" // NX_HEALTH_* / NX_CAUSE_* / NX_ACT_* + plan 19const NX_MAGIC_2048: i64 = 2048 20 21const NX_RENDER_DIY: i64 = 0 22const NX_RENDER_ENTERPRISE: i64 = 1 23 24// ---- labels (human-readable; the front shows these, not enum ints) ---- 25func nx_health_name(s: i64) -> *u8 { 26 if s == NX_HEALTH_OK { return "Healthy" as *u8 } 27 if s == NX_HEALTH_IDLE { return "Idle" as *u8 } 28 if s == NX_HEALTH_WATCH { return "Watch" as *u8 } 29 if s == NX_HEALTH_DEGRADED { return "Degraded" as *u8 } 30 if s == NX_HEALTH_URGENT { return "Urgent" as *u8 } 31 if s == NX_HEALTH_SAFETY { return "SAFETY HAZARD" as *u8 } 32 if s == NX_HEALTH_NODATA { return "No data" as *u8 } 33 return "Unknown" as *u8 34} 35func nx_health_color(s: i64) -> *u8 { 36 if s == NX_HEALTH_OK { return "#2e7d32" as *u8 } 37 if s == NX_HEALTH_WATCH { return "#f9a825" as *u8 } 38 if s == NX_HEALTH_DEGRADED { return "#ef6c00" as *u8 } 39 if s == NX_HEALTH_URGENT { return "#c62828" as *u8 } 40 if s == NX_HEALTH_SAFETY { return "#7f0000" as *u8 } 41 return "#9e9e9e" as *u8 42} 43func nx_cause_name(c: i64) -> *u8 { 44 if c == NX_CAUSE_OVERSIZED { return "Oversized / short-cycling" as *u8 } 45 if c == NX_CAUSE_DIRTY_FILTER { return "Dirty filter / fouled coil" as *u8 } 46 if c == NX_CAUSE_CONTROL_CAL { return "Control calibration" as *u8 } 47 if c == NX_CAUSE_IMBALANCE { return "Imbalance / wear" as *u8 } 48 if c == NX_CAUSE_BEARING { return "Failing bearing" as *u8 } 49 if c == NX_CAUSE_CONSUMABLE_SPENT { return "Consumable spent" as *u8 } 50 if c == NX_CAUSE_SEAL_LEAK { return "Seal / joint leak" as *u8 } 51 if c == NX_CAUSE_PUMP_OR_BIGLEAK { return "Weak pump / major leak" as *u8 } 52 if c == NX_CAUSE_CIRCUIT_LOAD { return "Circuit near capacity" as *u8 } 53 if c == NX_CAUSE_VOLTAGE_SUPPLY { return "Voltage supply issue" as *u8 } 54 if c == NX_CAUSE_SAFETY_HAZARD { return "Safety hazard" as *u8 } 55 return "Healthy" as *u8 56} 57func nx_action_name(a: i64) -> *u8 { 58 if a == NX_ACT_MONITOR { return "Monitor" as *u8 } 59 if a == NX_ACT_FIX_DIY { return "Fix yourself" as *u8 } 60 if a == NX_ACT_FIX_PRO { return "Call a pro" as *u8 } 61 if a == NX_ACT_REPLACE_CONSUMABLE { return "Replace consumable" as *u8 } 62 if a == NX_ACT_REPLACE_COMPONENT { return "Replace component" as *u8 } 63 if a == NX_ACT_REPLACE_UNIT { return "Replace unit" as *u8 } 64 if a == NX_ACT_SHUTDOWN_SAFETY { return "SHUT DOWN -- call a pro now" as *u8 } 65 return "No action needed" as *u8 66} 67 68// append a NUL-terminated string to buf at off; return new offset. 69func mr_cat(buf: *u8, off: i64, s: *u8) -> i64 { 70 var i: i64 = 0 71 while s[i] != (0 as u8) { 72 buf[off + i] = s[i] 73 i = i + 1 74 } 75 return off + i 76} 77 78func mr_contains(buf: *u8, len: i64, needle: *u8) -> i64 { 79 var i: i64 = 0 80 while i < len { 81 var j: i64 = 0 82 var m: i64 = 1 83 var go: i64 = 1 84 while go == 1 { 85 if needle[j] == (0 as u8) { go = 0 } 86 else { 87 if (i + j) >= len { m = 0; go = 0 } 88 else { 89 if buf[i + j] != needle[j] { m = 0; go = 0 } 90 else { j = j + 1 } 91 } 92 } 93 } 94 if m == 1 { return 1 } 95 i = i + 1 96 } 97 return 0 98} 99 100// FAIL-CLOSED privacy guarantee: refuse anything with a script or an http load. 101func nx_maint_render_is_clean(buf: *u8, len: i64) -> i64 { 102 if mr_contains(buf, len, "<script" as *u8) == 1 { return 0 } 103 if mr_contains(buf, len, "http" as *u8) == 1 { return 0 } 104 return 1 105} 106 107// Render the card. Returns length (>=0), or -1 if cap too small. 108func nx_maint_render_card(buf: *u8, cap: i64, asset_name: *u8, severity: i64, 109 cause: i64, action: i64, diy: i64, urgency: i64, mode: i64) -> i64 { 110 if cap < NX_MAGIC_2048 { return 0 - 1 } 111 var o: i64 = 0 112 o = mr_cat(buf, o, "<!doctype html><html><head><meta charset=utf-8><style>" as *u8) 113 o = mr_cat(buf, o, "body{font:15px sans-serif;margin:20px;color:#222}" as *u8) 114 o = mr_cat(buf, o, ".card{border:1px solid #ddd;border-left:6px solid " as *u8) 115 o = mr_cat(buf, o, nx_health_color(severity)) 116 o = mr_cat(buf, o, ";border-radius:8px;padding:16px;max-width:440px}" as *u8) 117 o = mr_cat(buf, o, ".badge{display:inline-block;padding:2px 9px;border-radius:4px;color:#fff;background:" as *u8) 118 o = mr_cat(buf, o, nx_health_color(severity)) 119 o = mr_cat(buf, o, "}.who{color:#666}</style></head><body><div class=card><div class=badge>" as *u8) 120 o = mr_cat(buf, o, nx_health_name(severity)) 121 o = mr_cat(buf, o, "</div><h2>" as *u8) 122 o = mr_cat(buf, o, asset_name) 123 o = mr_cat(buf, o, "</h2>" as *u8) 124 if mode == NX_RENDER_ENTERPRISE { 125 o = mr_cat(buf, o, "<p><b>Work order</b> &middot; Priority: " as *u8) 126 o = mr_cat(buf, o, nx_health_name(urgency)) 127 o = mr_cat(buf, o, "</p>" as *u8) 128 } 129 o = mr_cat(buf, o, "<p><b>Likely cause:</b> " as *u8) 130 o = mr_cat(buf, o, nx_cause_name(cause)) 131 o = mr_cat(buf, o, "</p><p><b>" as *u8) 132 if mode == NX_RENDER_ENTERPRISE { 133 o = mr_cat(buf, o, "Dispatch:" as *u8) 134 } else { 135 o = mr_cat(buf, o, "What to do:" as *u8) 136 } 137 o = mr_cat(buf, o, "</b> " as *u8) 138 o = mr_cat(buf, o, nx_action_name(action)) 139 o = mr_cat(buf, o, "</p><p class=who>" as *u8) 140 if diy == 1 { 141 o = mr_cat(buf, o, "You can do this yourself." as *u8) 142 } else { 143 o = mr_cat(buf, o, "Route to a professional." as *u8) 144 } 145 o = mr_cat(buf, o, "</p></div></body></html>" as *u8) 146 buf[o] = 0 as u8 147 return o 148}