code wiki / _hdl_build / nx_status_page.nx

nx_status_page.nx source

↩ module page · 189 lines · 12840 B

1// nx_status_page.nx -- GENERATE the nishifamily.com/status dashboard: every managed site (local + 2// external) + the hosting S-class scorecard (read live from the researcher's gap backlog). 3// 4// module: nishi-core.hosting.status_page 5// capability: CORE_COMPUTE (the operator's status-of-all-sites dashboard, S-class via the page builder) 6// 7// Built through nx_wiki_shell so it clears the full wiki-page feature bar. The site inventory is a 8// SNAPSHOT (last-verified state, honestly labelled -- live up/down probing is the nx_site_monitor rung). 9// The hosting scorecard is COMPUTED from knowledge/registry/hosting_research.tsv (the sovereign 10// researcher's verified gaps), so "where our hosting stands vs best-in-class" is measured, not asserted. 11// GATING: the operator wants this BEHIND the access wall -- this organ emits the content; the wall 12// (nx_sites_daemon_v2 /login + session) gates it. Sovereign: nx_syscalls + nx_wiki_shell. license_tier: ORIGINAL 13 14import "nx_syscalls.nx" 15import "nx_wiki_shell.nx" 16import "nx_health_probe.nx" // hp_probe / hp_name / HP_* -- LIVE serving probe (catches HUNG) 17import "nx_cert_monitor.nx" // cm_status / cm_name / CM_* -- TLS expiry 18const ST_MAGIC_8443: i64 = 8443 19const ST_MAGIC_7443: i64 = 7443 20const ST_MAGIC_8446: i64 = 8446 21const ST_MAGIC_8447: i64 = 8447 22const ST_MAGIC_8097: i64 = 8097 23const ST_MAGIC_18090: i64 = 18090 24 25const ST_OUT: *u8 = "web_assets/status.html" 26const ST_RES: *u8 = "knowledge/registry/hosting_research.tsv" 27const ST_CERT: *u8 = "/volume1/homes/elderwesto/nishihost/certs/le_fullchain.der" 28const ST_CAP: i64 = 262144 29 30func st_field(b: *u8, ls: i64, le: i64, f: i64) -> *u8 { 31 var cur: i64 = 0; var i: i64 = ls 32 while cur < f { if i >= le { let e: *u8 = sys_mmap(2); e[0] = 0 as u8; return e } if b[i] == 9 as u8 { cur = cur + 1 } i = i + 1 } 33 let out: *u8 = sys_mmap(512); var o: i64 = 0 34 while i < le { if b[i] == 9 as u8 { i = le } else { if o < 511 { out[o] = b[i]; o = o + 1 } i = i + 1 } } 35 out[o] = 0 as u8 36 return out 37} 38func st_d1(s: *u8) -> i64 { if s[0] >= 48 as u8 { if s[0] <= 57 as u8 { return (s[0] - 48 as u8) as i64 } } return 0 } 39func st_cat_esc(dst: *u8, off: i64, s: *u8) -> i64 { 40 var o: i64 = off; var i: i64 = 0 41 while s[i] != 0 as u8 { 42 let c: u8 = s[i] 43 if c == 60 as u8 { o = sh_cat(dst, o, "&lt;" as *u8) } 44 else { if c == 62 as u8 { o = sh_cat(dst, o, "&gt;" as *u8) } 45 else { if c == 38 as u8 { o = sh_cat(dst, o, "&amp;" as *u8) } 46 else { dst[o] = c; o = o + 1 } } } 47 i = i + 1 48 } 49 return o 50} 51 52// emit one managed-site row. 53func st_site(h: *u8, w: i64, host: *u8, scope: *u8, routes: *u8, state: *u8) -> i64 { 54 var o: i64 = w 55 o = sh_cat(h, o, "<tr><td><strong>" as *u8); o = sh_cat(h, o, host) 56 o = sh_cat(h, o, "</strong></td><td>" as *u8); o = sh_cat(h, o, scope) 57 o = sh_cat(h, o, "</td><td>" as *u8); o = sh_cat(h, o, routes) 58 o = sh_cat(h, o, "</td><td>" as *u8); o = sh_cat(h, o, state); o = sh_cat(h, o, "</td></tr>\n" as *u8) 59 return o 60} 61 62// emit one LIVE-PROBED daemon row (reuses hp_probe). Renders SERVING/HUNG/DOWN with colour. HUNG is the 63// state PID/LISTEN checks miss (process up + port bound but not responding) -- shown red, like DOWN, because 64// a hung daemon is just as useless. Returns the new write offset; *served_p is incremented when SERVING. 65func st_live(h: *u8, w: i64, label: *u8, port: i64, served_p: *i64) -> i64 { 66 let v: i64 = hp_probe(port, 3) 67 if v == HP_SERVING { served_p[0] = served_p[0] + 1 } 68 var o: i64 = w 69 o = sh_cat(h, o, "<tr><td><strong>" as *u8); o = sh_cat(h, o, label) 70 o = sh_cat(h, o, "</strong></td><td>:" as *u8); o = sh_catn(h, o, port) 71 o = sh_cat(h, o, "</td><td>" as *u8) 72 if v == HP_SERVING { o = sh_cat(h, o, "<span style=\"color:#3fae4f;font-weight:600\">&#9679; SERVING</span>" as *u8) } 73 else { if v == HP_HUNG { o = sh_cat(h, o, "<span style=\"color:#ef5350;font-weight:600\">&#9679; HUNG (up, not responding)</span>" as *u8) } 74 else { if v == HP_REFUSED { o = sh_cat(h, o, "<span style=\"color:#999\">&#9675; down / not on this host</span>" as *u8) } 75 else { o = sh_cat(h, o, "<span style=\"color:#d6a000;font-weight:600\">&#9679; BADRESP</span>" as *u8) } } } 76 o = sh_cat(h, o, "</td></tr>\n" as *u8) 77 return o 78} 79 80func main() -> i64 { 81 let now: i64 = sys_now_realtime_sec() 82 let h: *u8 = sys_mmap(ST_CAP) 83 var w: i64 = 0 84 85 w = sh_head(h, w, "Site Status" as *u8, "status" as *u8) 86 w = sh_nav(h, w, "status" as *u8) 87 w = sh_cat(h, w, "<h1>Nishi &mdash; Site Status</h1>\n" as *u8) 88 w = sh_cat(h, w, "<p class=\"fresh\">&#10227; Generated by <code>nx_status_page</code> at epoch=" as *u8) 89 w = sh_catn(h, w, now) 90 w = sh_cat(h, w, ". Site states below are a last-verified SNAPSHOT (live up/down probing = the nx_site_monitor rung); the hosting scorecard is COMPUTED from the researcher's verified gaps.</p>\n" as *u8) 91 w = sh_cat(h, w, "<p class=\"why\"><strong>&#128274; Access:</strong> this page is the operator's status-of-all-sites dashboard and is meant to sit BEHIND the access wall. Wall wiring (nx_sites_daemon_v2 /login + session) is an open gap-task; until then treat this as internal.</p>\n" as *u8) 92 93 w = sh_infobox_open(h, w, "Hosting at a glance" as *u8) 94 w = sh_infobox_row(h, w, "Managed sites" as *u8, "2 live hosts + sub-apps" as *u8) 95 w = sh_infobox_row(h, w, "Serving" as *u8, "nx_sites_daemon_v2 :8443 TLS1.3" as *u8) 96 w = sh_infobox_row(h, w, "Run mode" as *u8, "single direct setsid (UNSUPERVISED)" as *u8) 97 w = sh_infobox_row(h, w, "S-class gaps" as *u8, "13 verified (nx_hosting_research)" as *u8) 98 w = sh_infobox_close(h, w) 99 100 w = sh_toc_open(h, w) 101 w = sh_toc_item(h, w, "sites" as *u8, "Managed sites" as *u8) 102 w = sh_toc_item(h, w, "live" as *u8, "Live daemon health + TLS" as *u8) 103 w = sh_toc_item(h, w, "score" as *u8, "Hosting S-class scorecard" as *u8) 104 w = sh_toc_item(h, w, "run" as *u8, "Run / reliability" as *u8) 105 w = sh_toc_close(h, w) 106 107 w = sh_section(h, w, "sites" as *u8, "Managed sites (local + external)" as *u8) 108 w = sh_cat(h, w, "<table><tr><th>Host / app</th><th>Scope</th><th>Routes</th><th>Last state</th></tr>\n" as *u8) 109 w = st_site(h, w, "nishifamily.com" as *u8, "external (LAN+WAN)" as *u8, "/ /wiki /video /voxelworld /econsim" as *u8, "UP (200/301 verified)" as *u8) 110 w = st_site(h, w, "andelinwest.com" as *u8, "external" as *u8, "/ (CMS, doc-root)" as *u8, "configured (sites.conf)" as *u8) 111 w = st_site(h, w, "nishifamily.com/wiki" as *u8, "sub-app" as *u8, "charter / start / board (.html)" as *u8, "UP (S-class pages)" as *u8) 112 w = st_site(h, w, "nishifamily.com/video" as *u8, "sub-app" as *u8, "vroom relay :8446 + wss /signal" as *u8, "UP" as *u8) 113 w = st_site(h, w, "jasonewest.com" as *u8, "external (planned)" as *u8, "email MTA wired" as *u8, "not yet on :8443" as *u8) 114 w = st_site(h, w, "mfg.nishifamily.com" as *u8, "external (planned)" as *u8, "&mdash;" as *u8, "not materialized" as *u8) 115 w = sh_cat(h, w, "</table>\n<p class=\"why\">The table above is the route/scope INVENTORY (last-verified). Actual up/down is the LIVE section below.</p>\n" as *u8) 116 117 // ---- LIVE daemon health (closes confirmed gaps: live-probe + cert-expiry) ---- 118 w = sh_section(h, w, "live" as *u8, "Live daemon health + TLS (probed at page-gen)" as *u8) 119 w = sh_cat(h, w, "<p>Each backing daemon is BLACK-BOX probed right now (connect + request + bounded recv), so a process that is up but <em>not serving</em> (HUNG) shows red &mdash; a state PID-liveness and a LISTEN check both miss. Probed from wherever this page is generated: on the NAS the production daemons show SERVING; run locally they show down/not-here (honest).</p>\n" as *u8) 120 w = sh_cat(h, w, "<table><tr><th>Daemon</th><th>Port</th><th>Live state</th></tr>\n" as *u8) 121 let served: *i64 = sys_mmap(16) as *i64; served[0] = 0 122 w = st_live(h, w, "sites-v2 (nishifamily.com)" as *u8, ST_MAGIC_8443, served) 123 w = st_live(h, w, "sni-router (:443 front)" as *u8, ST_MAGIC_7443, served) 124 w = st_live(h, w, "vroom video" as *u8, ST_MAGIC_8446, served) 125 w = st_live(h, w, "translate" as *u8, ST_MAGIC_8447, served) 126 w = st_live(h, w, "torrent" as *u8, ST_MAGIC_8097, served) 127 w = st_live(h, w, "gallery" as *u8, ST_MAGIC_18090, served) 128 w = sh_cat(h, w, "</table>\n<p class=\"why\"><strong>" as *u8); w = sh_catn(h, w, served[0]) 129 w = sh_cat(h, w, "/6 SERVING</strong> from this host.</p>\n" as *u8) 130 131 // TLS cert-expiry (reused cert-monitor: notAfter -> days-until -> OK/WARN/EXPIRED) 132 let cd: *i64 = sys_mmap(16) as *i64; let cna: *i64 = sys_mmap(16) as *i64 133 let cv: i64 = cm_status(ST_CERT, cd, cna) 134 w = sh_cat(h, w, "<p><strong>TLS certificate:</strong> " as *u8) 135 if cv == CM_OK { w = sh_cat(h, w, "<span style=\"color:#3fae4f;font-weight:600\">OK</span> &mdash; " as *u8); w = sh_catn(h, w, cd[0]); w = sh_cat(h, w, " days until expiry" as *u8) } 136 else { if cv == CM_WARN { w = sh_cat(h, w, "<span style=\"color:#d6a000;font-weight:600\">EXPIRING SOON &mdash; RENEW</span> (" as *u8); w = sh_catn(h, w, cd[0]); w = sh_cat(h, w, " days left)" as *u8) } 137 else { if cv == CM_EXPIRED { w = sh_cat(h, w, "<span style=\"color:#ef5350;font-weight:600\">EXPIRED</span> &mdash; serving a dead cert" as *u8) } 138 else { w = sh_cat(h, w, "<span style=\"color:#999\">cert not readable from this host (NAS path)</span>" as *u8) } } } 139 w = sh_cat(h, w, "</p>\n<p class=\"why\">HONEST: per-site CPU/mem/disk is still NOT surfaced (confirmed gap #11).</p>\n" as *u8) 140 141 w = sh_section(h, w, "score" as *u8, "Hosting S-class scorecard (vs best-in-class, measured)" as *u8) 142 w = sh_cat(h, w, "<p>Computed from the sovereign researcher (<code>nx_hosting_research</code>): each row is a CONFIRMED gap vs best-in-class hosts. We are NOT S-class on hosting yet &mdash; these are the open tasks, and this page says so.</p>\n" as *u8) 143 w = sh_cat(h, w, "<table><tr><th>Confidence</th><th>Gap</th><th>Owning organ</th></tr>\n" as *u8) 144 let lenbox: *i64 = sys_mmap(16) as *i64; lenbox[0] = 0 145 let data: *u8 = sys_read_file(ST_RES, lenbox) 146 var confirmed: i64 = 0 147 if (data as i64) != 0 { 148 let n: i64 = lenbox[0] 149 var ls: i64 = 0; var i: i64 = 0 150 while i <= n { 151 var atend: i64 = 0 152 if i == n { atend = 1 } 153 if i < n { if data[i] == 10 as u8 { atend = 1 } } 154 if atend == 1 { 155 if i > ls { if data[ls] != 35 as u8 { 156 let cv: i64 = st_d1(st_field(data, ls, i, 2)) 157 let rv: i64 = st_d1(st_field(data, ls, i, 3)) 158 if rv < 2 { if cv >= 2 { 159 confirmed = confirmed + 1 160 w = sh_cat(h, w, "<tr><td>" as *u8); w = sh_catn(h, w, (cv * 1000) / 3); w = sh_cat(h, w, "permil</td><td>" as *u8) 161 w = st_cat_esc(h, w, st_field(data, ls, i, 0)); w = sh_cat(h, w, "</td><td><code>" as *u8) 162 w = st_cat_esc(h, w, st_field(data, ls, i, 5)); w = sh_cat(h, w, "</code></td></tr>\n" as *u8) 163 } } 164 } } 165 ls = i + 1 166 } 167 i = i + 1 168 } 169 } 170 w = sh_cat(h, w, "</table>\n<p class=\"why\"><strong>" as *u8); w = sh_catn(h, w, confirmed) 171 w = sh_cat(h, w, " confirmed hosting gaps</strong> &mdash; full backlog: <code>./_offc/nx_sov_build_run.elf nx_hosting_research</code>.</p>\n" as *u8) 172 173 w = sh_section(h, w, "run" as *u8, "Run / reliability (honest)" as *u8) 174 w = sh_cat(h, w, "<p>Daemons run via a single direct <code>setsid</code> + <code>sites.pid</code>. The <code>nx_hostctl</code> supervisor has NO restart-loop guard and only <code>/proc</code>-name liveness (not real serving health) &mdash; on 2026-06-16 that crash-looped the site during a deploy. The site is currently UP but UNSUPERVISED. Fixing supervision (watchdog + restart-loop guard + one supervisor + real health probe) is a top confirmed gap.</p>\n" as *u8) 175 176 w = sh_footer(h, w, "status" as *u8, now) 177 178 let fd: i64 = sys_openat_wr(ST_OUT, 0x1a4) 179 if fd < 0 { sys_write(2, "FATAL: cannot open status.html\n" as *u8, 31); sys_exit(2); return 2 } 180 sys_write(fd, h, w) 181 sys_close(fd) 182 sys_write(1, "[nx_status_page] wrote status.html bytes=" as *u8, 41) 183 let nb: *u8 = sys_mmap(28); var k2: i64 = 0; var m2: i64 = w 184 if m2 == 0 { nb[0] = 48 as u8; k2 = 1 } 185 while m2 > 0 { nb[k2] = (48 + (m2 % 10)) as u8; m2 = m2 / 10; k2 = k2 + 1 } 186 var q: i64 = k2 - 1; while q >= 0 { let o1: *u8 = sys_mmap(1); o1[0] = nb[q]; sys_write(1, o1, 1); q = q - 1 } 187 sys_write(1, "\n" as *u8, 1) 188 sys_exit(0); return 0 189}