code wiki / _hdl_build / nx_hub_render.nx
nx_hub_render.nx source
↩ module page · 136 lines · 9969 B
1// nx_hub_render.nx -- the LEVELED hub index renderer: registry + a viewer's level -> the HTML they may see.
2// Realizes the operator's "/hub access levels": the gateway resolves the session's level, then this emits a
3// card ONLY for each CURRENT hub-zone artifact whose required level <= the viewer's level. NO-LEAK AT THE
4// RENDER LAYER: a viewer's bytes never contain a member/operator card (not hidden by CSS -- absent from the
5// HTML), so even view-source cannot reveal a gated area. "Current" = the latest load_date row per path with
6// is_current=1 (a tombstone/older row is skipped). Sovereign: slk_* + nx_maturity_registry classifiers. ORIGINAL.
7import "nx_site_lock_lib.nx"
8import "nx_maturity_registry.nx"
9import "nx_native_config.nx" // sovereign content-addressed data store (ncfg_*), NOT tsv -- the card registry
10
11// 2026-07-29 seq1232 (P2 safe-subset): per-call scratch -> lazy statics (page-granular mmaps with no
12// munmap leaked ~4KB/site/call in the hub_gw request path; daemon never forks, boxes consumed before reuse).
13static hr_scr_fs: *i64
14static hr_scr_fe: *i64
15static hr_scr_crk: *i64
16static hr_scr_crv: *i64
17func hr_app(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){dst[o]=s[i]; o=o+1; i=i+1} return o }
18func hr_appb(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { var o: i64=off; var i: i64=0; while i<n {dst[o]=src[i]; o=o+1; i=i+1} return o }
19
20// emit ONE core card ONLY if its required level <= the viewer's level. NO-LEAK: a gated card is
21// ABSENT from the HTML (never CSS-hidden) so view-source cannot reveal it. req: 0=open/anon 1=family
22// 2=member 3=operator (matches nx_maturity_registry mr_level_of public/viewer/member/operator).
23func hr_card(out: *u8, o: i64, level: i64, req: i64, href: *u8, title: *u8, badge: *u8) -> i64 {
24 if req > level { return o }
25 var p: i64 = o
26 p = hr_app(out, p, " <a class=\"card\" href=\"" as *u8)
27 p = hr_app(out, p, href)
28 p = hr_app(out, p, "\"><b>" as *u8)
29 p = hr_app(out, p, title)
30 p = hr_app(out, p, "</b><span class=\"lvl\">" as *u8)
31 p = hr_app(out, p, badge)
32 p = hr_app(out, p, "</span></a>\n" as *u8)
33 return p
34}
35
36// is the row at exact path [path_s,path_e) with load=`load` the LATEST row for that path? (dedup for promotes)
37func hr_is_latest(reg: *u8, reglen: i64, path_s: i64, path_e: i64, load: i64) -> i64 {
38 if (hr_scr_fs as i64) == 0 { hr_scr_fs = sys_mmap(8) as *i64 }
39 if (hr_scr_fe as i64) == 0 { hr_scr_fe = sys_mmap(8) as *i64 }
40 let fs: *i64 = hr_scr_fs; let fe: *i64 = hr_scr_fe
41 let plen: i64 = path_e - path_s
42 var ls: i64 = 0; var latest: i64 = 1
43 while ls < reglen {
44 let le: i64 = slk_line_end(reg, reglen, ls)
45 if le > ls { if reg[ls] != (35 as u8) {
46 if slk_field(reg, ls, le, 6, fs, fe) == 1 {
47 slk_field(reg, ls, le, 3, fs, fe)
48 if slk_eq(slk_at(reg, fs[0]), fe[0] - fs[0], slk_at(reg, path_s), plen) == 1 {
49 slk_field(reg, ls, le, 5, fs, fe)
50 if slk_atoi(reg, fs[0], fe[0]) > load { latest = 0 }
51 }
52 }
53 } }
54 ls = le + 1
55 }
56 return latest
57}
58
59// emit the leveled hub index HTML into out; return byte length.
60func mr_render_index(reg: *u8, reglen: i64, level: i64, with_upgrade: i64, out: *u8, cap: i64) -> i64 {
61 var o: i64 = 0
62 o = hr_app(out, o, "<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Nishi Family Hub</title>\n" as *u8)
63 o = hr_app(out, o, "<style>body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;max-width:760px;margin:6vh auto;padding:0 24px;color:#161622;line-height:1.6}h1{font-size:2rem;margin-bottom:4px}.sub{color:#555}.cards{display:grid;gap:14px;margin-top:28px}.card{display:block;padding:18px 20px;border:1px solid #d8d8e0;border-radius:12px;text-decoration:none;color:#161622}.card:hover{border-color:#2a4d8f;background:#f6f8fc}.card b{color:#2a4d8f;font-size:1.1rem}.lvl{float:right;font-size:.78rem;color:#999;border:1px solid #e3e3ea;border-radius:20px;padding:1px 9px}footer{margin-top:36px;color:#aaa;font-size:.8rem}</style></head>\n" as *u8)
64 o = hr_app(out, o, "<body>\n<h1>Nishi Family Hub</h1>\n<p class=\"sub\">Welcome home — jump into any area.</p>\n<div class=\"cards\">\n" as *u8)
65 // ---- core FAMILY AREAS (always present in the hub, the operator's "built-out" hub) ----
66 // ---- CORE AREAS, from the SOVEREIGN native store (nx_native_config, NOT tsv). Each card row is
67 // {href, title, access}; emit level-gated (no-leak): req = mr_level_of(access), shown iff
68 // req <= viewer level. Seeded by nx_hub_cards_seed. Store missing -> zero cards (fail-closed). ----
69 let ch: *i64 = ncfg_open("knowledge/store/hub-cards-\x00" as *u8)
70 if (ch as i64) != 0 {
71 let ccnt: i64 = ncfg_count(ch, "card\x00" as *u8)
72 if (hr_scr_crk as i64) == 0 { hr_scr_crk = sys_mmap(8 * 8) as *i64 }
73 if (hr_scr_crv as i64) == 0 { hr_scr_crv = sys_mmap(8 * 8) as *i64 }
74 let crk: *i64 = hr_scr_crk
75 let crv: *i64 = hr_scr_crv
76 var ci: i64 = 0
77 while ci < ccnt {
78 let crf: i64 = ncfg_row(ch, "card\x00" as *u8, ci, crk, crv, 8)
79 if crf > 0 {
80 let chref: *u8 = ncfg_field(crk, crv, crf, "href\x00" as *u8)
81 let ctitle: *u8 = ncfg_field(crk, crv, crf, "title\x00" as *u8)
82 let caccess: *u8 = ncfg_field(crk, crv, crf, "access\x00" as *u8)
83 var can: i64 = 0
84 while caccess[can] != (0 as u8) { can = can + 1 }
85 let creq: i64 = mr_level_of(caccess, can)
86 // CONSOLIDATE: the Games card links to the UNIFIED /hub/games portal (all games in one space,
87 // registry-driven) instead of the legacy sites.elf /games board-games page.
88 var chn: i64 = 0
89 while chref[chn] != (0 as u8) { chn = chn + 1 }
90 var href2: *u8 = chref
91 if slk_eq(chref, chn, "/games" as *u8, 6) == 1 { href2 = "/hub/games" as *u8 }
92 o = hr_card(out, o, level, creq, href2, ctitle, caccess)
93 }
94 ci = ci + 1
95 }
96 }
97 if (hr_scr_fs as i64) == 0 { hr_scr_fs = sys_mmap(8) as *i64 }
98 if (hr_scr_fe as i64) == 0 { hr_scr_fe = sys_mmap(8) as *i64 }
99 let fs: *i64 = hr_scr_fs; let fe: *i64 = hr_scr_fe
100 var ls: i64 = 0
101 while ls < reglen {
102 let le: i64 = slk_line_end(reg, reglen, ls)
103 if le > ls { if reg[ls] != (35 as u8) {
104 if slk_field(reg, ls, le, 6, fs, fe) == 1 {
105 slk_field(reg, ls, le, 6, fs, fe); let cur: i64 = slk_atoi(reg, fs[0], fe[0])
106 slk_field(reg, ls, le, 1, fs, fe); let zone: i64 = mr_zone_of(mr_tier_of(slk_at(reg, fs[0]), fe[0] - fs[0]))
107 slk_field(reg, ls, le, 2, fs, fe); let acc_s: i64 = fs[0]; let acc_e: i64 = fe[0]; let req: i64 = mr_level_of(slk_at(reg, fs[0]), fe[0] - fs[0])
108 slk_field(reg, ls, le, 3, fs, fe); let p_s: i64 = fs[0]; let p_e: i64 = fe[0]
109 slk_field(reg, ls, le, 5, fs, fe); let load: i64 = slk_atoi(reg, fs[0], fe[0])
110 slk_field(reg, ls, le, 4, fs, fe); let t_s: i64 = fs[0]; let t_e: i64 = fe[0]
111 if cur == 1 { if zone == 3 { if req <= level { if hr_is_latest(reg, reglen, p_s, p_e, load) == 1 {
112 o = hr_app(out, o, " <a class=\"card\" href=\"/hub/" as *u8)
113 o = hr_appb(out, o, slk_at(reg, p_s), p_e - p_s)
114 o = hr_app(out, o, "\"><b>" as *u8)
115 o = hr_appb(out, o, slk_at(reg, t_s), t_e - t_s)
116 o = hr_app(out, o, "</b><span class=\"lvl\">" as *u8)
117 o = hr_appb(out, o, slk_at(reg, acc_s), acc_e - acc_s)
118 o = hr_app(out, o, "</span></a>\n" as *u8)
119 } } } }
120 }
121 } }
122 ls = le + 1
123 }
124 o = hr_app(out, o, "</div>\n<footer>Nishi sovereign hub · nx_hub_gw · leveled by your session</footer>\n" as *u8)
125 // ANON render (with_upgrade=1, served on a no-token navigation): if the visitor DOES have a session
126 // token in sessionStorage, re-fetch /hub WITH the header to upgrade to their full leveled hub. Guests
127 // have no token -> they stay on the open games hub. Only emitted here (not on the full render) so a
128 // valid session never re-fetches -> no loop.
129 if with_upgrade == 1 {
130 o = hr_app(out, o, "<script>(function(){var t=sessionStorage.getItem('nsess');if(t){fetch('/hub',{headers:{'X-Nishi-Session':t}}).then(function(r){return r.ok?r.text():null}).then(function(x){if(x){document.open();document.write(x);document.close()}})}})();</script>\n" as *u8)
131 }
132 // no-cookie click-shim: card clicks (/hub/*) are fetched WITH the X-Nishi-Session header + document.write'd,
133 // so the session rides every gated navigation (mirrors the wiki OLGD_SPA). 403 -> shown inline, no leak.
134 o = hr_app(out, o, "<script>(function(){var t=sessionStorage.getItem('nsess');document.addEventListener('click',function(e){var a=e.target.closest&&e.target.closest('a');if(!a)return;var h=a.getAttribute('href');if(!h)return;if(h.indexOf('/hub/')!=0)return;e.preventDefault();fetch(h,{headers:{'X-Nishi-Session':t}}).then(function(r){return r.ok?r.text():(r.status==403?'<h1>Your access level cannot open this area.</h1><p><a href=/hub>Back to the hub</a></p>':null)}).then(function(x){if(x){document.open();document.write(x);document.close()}else{location='/login'}})})})();</script>\n<script>(function(){setInterval(function(){var s=sessionStorage.getItem('nsess');if(!s)return;fetch('/whoami',{headers:{'X-Nishi-Session':s}}).then(function(r){return r.ok?r.json():null}).then(function(j){if(j&&j.nsess)sessionStorage.setItem('nsess',j.nsess)})},600000)})();</script>\n</body></html>\n" as *u8)
135 return o
136}