code wiki / _hdl_build / nx_ws_board_html.nx

nx_ws_board_html.nx source

↩ module page · 194 lines · 10002 B

1// nx_ws_board_html.nx -- WMS rung M2.5: the VIEWABLE board (Language-Export HAL last-mile). 2// 3// module: nishi-core.wms.ws_board_html 4// capability: CORE_COMPUTE (a Nishi-EMITTED last-mile HTML view of the M2 derived board) 5// 6// WHAT THIS CLOSES: the M2 charter says the live board "REPLACES the stale THREADS 7// worksheet". nx_ws_board renders to stdout + a log -- not a VIEWABLE artifact. This 8// additive organ produces the viewable form WITHOUT violating sovereign/NO-BLEED: the 9// HTML is the genuine last-mile wire format (HTML is to a browser what a syscall is to 10// the OS) and EVERY byte is EMITTED BY this Nishi organ -- never hand-authored, never a 11// node/playwright dependency. This is the wheeler flip the Language-Export HAL encodes 12// (nx_lang_export): Nishi is the TRUTH; the emitted artifact is a verified OUTPUT. 13// 14// TRUTH-PRESERVING: the table is derived by calling the SAME wb_board_p that the M2 gate 15// proved correct -- the HTML cannot disagree with the board (single source of truth, no 16// re-derivation). And it honors the board's refusals: if wb_board_p returns a negative 17// WB_* code (incomplete registry / torn reflog), this organ emits a REFUSED banner page, 18// NOT a wrong table. A silently-wrong viewable board would defeat the whole point. 19// 20// REUSE / lineage: wb_board_p / WB_ROWW / WB_MAXEMP / WB_INCOMPLETE / WB_TORNREFLOG 21// (nx_ws_board, WMS-M2); fa_cat / fa_catn / fa_appendz (nx_framed_append, WMS-R0b -- the 22// one-buffer-one-locked-write discipline for the evidence channel); the byte-emit + wfile 23// idiom mirrors nx_lang_export (Language-Export HAL). Additive: no organ modified. 24// Sovereign: imports only the WMS/HAL stack + nx_syscalls (no gcc/openssl/node). 25// license_tier: ORIGINAL 26import "nx_ws_board.nx" 27import "nx_framed_append.nx" 28import "nx_syscalls.nx" 29 30const WBH_OUT: *u8 = "web_assets/_ws_build/ws_board.html" 31const WBH_LOG: *u8 = "knowledge/status/ws_board_html.log" 32const WBH_RECCAP: i64 = 512 33const WBH_HTMLCAP: i64 = 65536 // bounded HTML buffer (no magic number) 34 35// emit-status codes the gate asserts (data-driven; no magic numbers). 36const WBH_TABLE: i64 = 1 // a real per-empire table was emitted 37const WBH_REFUSED: i64 = 2 // a REFUSED banner was emitted (board refused) 38 39func wbh_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 40 41// append nul-terminated string into the HTML buffer at off; return new off (fa_cat alias 42// kept local so the HTML builder reads like the lang_export `cat` idiom). 43func wbh_cat(dst: *u8, off: i64, s: *u8) -> i64 { return fa_cat(dst, off, s) } 44func wbh_catn(dst: *u8, off: i64, v: i64) -> i64 { return fa_catn(dst, off, v) } 45 46// one-write-out of the assembled HTML buffer (last-mile file sink, like lang_export wfile). 47func wbh_wfile(path: *u8, buf: *u8, n: i64) -> i64 { 48 let fd: i64 = sys_openat_wr(path, 420) // 0644 49 if fd < 0 { return 0 - 1 } 50 var off: i64 = 0 51 while off < n { 52 let tail: *u8 = ((buf as i64) + off) as *u8 53 let wr: i64 = sys_write(fd, tail, n - off) 54 if wr <= 0 { sys_close(fd); return 0 - 2 } 55 off = off + wr 56 } 57 sys_close(fd) 58 return n 59} 60 61// emit the HTML <head> + open <body> into out at off; returns new off. 62func wbh_head(out: *u8, off: i64) -> i64 { 63 var o: i64 = off 64 o = wbh_cat(out, o, "<!DOCTYPE html>\n<html><head><meta charset=\"utf-8\">\n" as *u8) 65 o = wbh_cat(out, o, "<title>Nishi WMS Live Status Board</title>\n" as *u8) 66 o = wbh_cat(out, o, "<style>body{font-family:monospace;background:#0b0e14;color:#cdd6f4}" as *u8) 67 o = wbh_cat(out, o, "table{border-collapse:collapse}td,th{border:1px solid #45475a;padding:4px 10px}" as *u8) 68 o = wbh_cat(out, o, "th{background:#181825}.done{color:#a6e3a1}.active{color:#f9e2af}.blocked{color:#f38ba8}" as *u8) 69 o = wbh_cat(out, o, ".refused{color:#f38ba8;font-weight:bold}</style></head>\n<body>\n" as *u8) 70 return o 71} 72 73// THE EMITTER. Derives the board via wb_board_p (the M2 truth), then emits a viewable 74// HTML artifact. Parameterized by prefix+refpath so the gate drives HERMETIC stores. 75// returns WBH_TABLE (1) when a real per-empire table was emitted, 76// WBH_REFUSED (2) when the board refused and a REFUSED banner was emitted, 77// negative on a hard emit/file error. 78// status_out[]: [0]=board rc (wb_board_p return) [1]=empire count emitted [2]=total streams. 79func wbh_emit_p(prefix: *u8, refpath: *u8, outpath: *u8, status_out: *i64) -> i64 { 80 let rows: *i64 = sys_mmap(8 * WB_MAXEMP * WB_ROWW) as *i64 81 let ec: *i64 = sys_mmap(16) as *i64 82 let sm: *i64 = sys_mmap(64) as *i64 83 let rc: i64 = wb_board_p(prefix, refpath, rows, WB_MAXEMP, ec, sm) 84 85 let html: *u8 = sys_mmap(WBH_HTMLCAP) 86 var o: i64 = wbh_head(html, 0) 87 88 status_out[0] = rc 89 status_out[1] = 0 90 status_out[2] = 0 91 92 // ---- REFUSAL PATH: the board refused -> emit a REFUSED banner, NOT a wrong table. ---- 93 if rc < 0 { 94 o = wbh_cat(html, o, "<h1>Nishi WMS Status Board</h1>\n" as *u8) 95 o = wbh_cat(html, o, "<p class=\"refused\">BOARD REFUSED rc=" as *u8) 96 o = wbh_catn(html, o, rc) 97 if rc == WB_INCOMPLETE { o = wbh_cat(html, o, " reason=registry-incomplete (lost segment) -- NOT rendered" as *u8) } 98 if rc == WB_NOIDS { o = wbh_cat(html, o, " reason=no-ws:ids -- nothing registered" as *u8) } 99 if rc == WB_TORNREFLOG { o = wbh_cat(html, o, " reason=torn/old-reflog -- view REJECTED" as *u8) } 100 o = wbh_cat(html, o, "</p>\n</body></html>\n" as *u8) 101 html[o] = 0 as u8 102 let wrr: i64 = wbh_wfile(outpath, html, o) 103 if wrr < 0 { return wrr } 104 return WBH_REFUSED 105 } 106 107 // ---- TABLE PATH: derive-from-truth per-empire rollup. ---- 108 let necount: i64 = ec[0] 109 o = wbh_cat(html, o, "<h1>Nishi WMS Live Status Board</h1>\n" as *u8) 110 o = wbh_cat(html, o, "<p>derived from WMS-R1 registry + WMS-R2 reflog overlay</p>\n" as *u8) 111 o = wbh_cat(html, o, "<table>\n<tr><th>empire</th><th>streams</th>" as *u8) 112 o = wbh_cat(html, o, "<th class=\"done\">done</th><th class=\"active\">active</th><th class=\"blocked\">blocked</th></tr>\n" as *u8) 113 var e: i64 = 0 114 while e < necount { 115 let base: i64 = e * WB_ROWW 116 let empire: *u8 = rows[base + 0] as *u8 117 o = wbh_cat(html, o, "<tr><td>" as *u8) 118 o = wbh_cat(html, o, empire) 119 o = wbh_cat(html, o, "</td><td>" as *u8); o = wbh_catn(html, o, rows[base + 1]) 120 o = wbh_cat(html, o, "</td><td class=\"done\">" as *u8); o = wbh_catn(html, o, rows[base + 2]) 121 o = wbh_cat(html, o, "</td><td class=\"active\">" as *u8); o = wbh_catn(html, o, rows[base + 3]) 122 o = wbh_cat(html, o, "</td><td class=\"blocked\">" as *u8); o = wbh_catn(html, o, rows[base + 4]) 123 o = wbh_cat(html, o, "</td></tr>\n" as *u8) 124 e = e + 1 125 } 126 // summary footer row. 127 o = wbh_cat(html, o, "<tr><th>SUMMARY</th><th>" as *u8); o = wbh_catn(html, o, sm[0]) 128 o = wbh_cat(html, o, "</th><th class=\"done\">" as *u8); o = wbh_catn(html, o, sm[1]) 129 o = wbh_cat(html, o, "</th><th class=\"active\">" as *u8); o = wbh_catn(html, o, sm[2]) 130 o = wbh_cat(html, o, "</th><th class=\"blocked\">" as *u8); o = wbh_catn(html, o, sm[3]) 131 o = wbh_cat(html, o, "</th></tr>\n</table>\n</body></html>\n" as *u8) 132 html[o] = 0 as u8 133 134 status_out[1] = necount 135 status_out[2] = sm[0] 136 let wrt: i64 = wbh_wfile(outpath, html, o) 137 if wrt < 0 { return wrt } 138 return WBH_TABLE 139} 140 141// convenience: live ws- prefix -> the real web asset path. 142func wbh_emit(refpath: *u8, status_out: *i64) -> i64 { 143 return wbh_emit_p(WS_PREFIX, refpath, WBH_OUT, status_out) 144} 145 146// MANDATORY WRITE DISCIPLINE: one evidence line into one buffer, ONE locked fa_appendz. 147func wbh_emit_log(emitcode: i64, empires: i64, total: i64) -> i64 { 148 let buf: *u8 = sys_mmap(WBH_RECCAP + 16) 149 var o: i64 = 0 150 o = fa_cat(buf, o, "WS-BOARD-HTML emit=\x00" as *u8) 151 if emitcode == WBH_TABLE { o = fa_cat(buf, o, "TABLE\x00" as *u8) } 152 if emitcode == WBH_REFUSED { o = fa_cat(buf, o, "REFUSED\x00" as *u8) } 153 o = fa_cat(buf, o, " empires=\x00" as *u8); o = fa_catn(buf, o, empires) 154 o = fa_cat(buf, o, " total=\x00" as *u8); o = fa_catn(buf, o, total) 155 o = fa_cat(buf, o, " file=web_assets/_ws_build/ws_board.html END\x00" as *u8) 156 buf[o] = 0 as u8 157 return fa_appendz(WBH_LOG, buf, WBH_RECCAP) 158} 159 160func wbh_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 161func wbh_pn(v: i64) -> i64 { 162 let bb: *u8 = sys_mmap(28); var m: i64 = v 163 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 164 let t: *u8 = sys_mmap(28); var k: i64 = 0 165 if m == 0 { t[0] = 48 as u8; k = 1 } 166 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 167 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 168 sys_write(1, bb, k); return 0 169} 170 171// main(): emit the LIVE board to web_assets/_ws_build/ws_board.html. Reflog overlay 172// skipped (refpath=0) for the same reason nx_ws_board's main does -- the live transition 173// log is an OPTIONAL freshness check; the R1 registry is the SSOT. 174func main() -> i64 { 175 wbh_p("=== WMS-M2.5 BOARD->HTML (Language-Export HAL last-mile, Nishi-emitted) ===\n" as *u8) 176 let st: *i64 = sys_mmap(64) as *i64 177 let code: i64 = wbh_emit(0 as *u8, st) 178 if code < 0 { 179 wbh_p(" EMIT FAILED rc=\x00" as *u8); wbh_pn(code); wbh_p("\n\x00" as *u8) 180 sys_exit(1); return 1 181 } 182 if code == WBH_TABLE { 183 wbh_p(" emitted TABLE empires=\x00" as *u8); wbh_pn(st[1]) 184 wbh_p(" total=\x00" as *u8); wbh_pn(st[2]) 185 wbh_p(" -> web_assets/_ws_build/ws_board.html\n\x00" as *u8) 186 } 187 if code == WBH_REFUSED { 188 wbh_p(" emitted REFUSED banner (board rc=\x00" as *u8); wbh_pn(st[0]) 189 wbh_p(") -> web_assets/_ws_build/ws_board.html\n\x00" as *u8) 190 } 191 wbh_emit_log(code, st[1], st[2]) 192 sys_exit(0) 193 return 0 194}