code wiki / _hdl_build / nx_asset_dashboard_gate.nx
nx_asset_dashboard_gate.nx source
↩ module page · 222 lines · 12372 B
1// nx_asset_dashboard_gate.nx -- KAT + TEETH for the asset DASHBOARD emitter (the GOING-ON pillar).
2//
3// Drives the SAME render core (nx_asset_dashboard_lib dp_emit) the production page uses, against a
4// CONTROLLED /tmp catalog (production catalog untouched), and proves:
5// (T1) the live STATS are counted correctly (3 records: 1 doc + 1 image + 1 video; machine/human/
6// downloaded; 2 current + 1 retired) -- the numbers the dashboard renders are real, not typed
7// (T2) MISSING_PROVENANCE signal fires for every record (deny-by-default; the honest TO-DO state)
8// (T3) dp_emit renders an HTML file containing all THREE pillar headings + the correct live total
9// (T4 TEETH) an EMPTY catalog -> all stats ZERO (no fabricated numbers on an empty inventory)
10//
11// Verdict appended to knowledge/status/asset_dashboard_gate.log (additive law #13).
12// expect_exit: 0 license_tier: ORIGINAL
13import "nx_syscalls.nx"
14import "nx_canon_cid.nx"
15import "nx_asset_record.nx"
16import "nx_asset_catalog.nx"
17import "nx_asset_status.nx"
18import "nx_asset_dashboard_lib.nx"
19import "nx_gate_verdict.nx"
20
21func g_puts(logfd: i64, s: *u8) -> i64 {
22 var n: i64 = 0
23 while s[n] != (0 as u8) { n = n + 1 }
24 sys_write(1, s, n)
25 if logfd > 0 { sys_write(logfd, s, n) }
26 return 0
27}
28func g_putn(logfd: i64, v: i64) -> i64 {
29 let bb: *u8 = sys_mmap(28)
30 var m: i64 = v
31 if m < 0 { g_puts(logfd, "-\x00" as *u8); m = 0 - m }
32 let t: *u8 = sys_mmap(28)
33 var k: i64 = 0
34 if m == 0 { t[0] = 48 as u8; k = 1 }
35 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
36 var i: i64 = 0
37 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
38 sys_write(1, bb, k)
39 if logfd > 0 { sys_write(logfd, bb, k) }
40 return 0
41}
42func E() -> *u8 { return "\x00" as *u8 }
43func sset(a: *i64, i: i64, s: *u8) -> i64 { a[i] = s as i64; return 0 }
44
45// build a record: type / prov_class / is_current / id (title="Asset", tags="tag", class=professional).
46func mk_full(typ: *u8, prov: *u8, current: *u8, id: *u8, out: *u8) -> i64 {
47 let core: *i64 = sys_mmap(8 * 8) as *i64
48 sset(core, 0, typ); sset(core, 1, "Asset\x00" as *u8); sset(core, 2, E())
49 sset(core, 3, "2026-06-20\x00" as *u8); sset(core, 4, id); sset(core, 5, E()); sset(core, 6, E())
50 let pz: *i64 = sys_mmap(8 * 8) as *i64
51 sset(pz, 0, prov); sset(pz, 1, E()); sset(pz, 2, E()); sset(pz, 3, E()); sset(pz, 4, E()); sset(pz, 5, E())
52 let mz: *i64 = sys_mmap(8 * 8) as *i64
53 sset(mz, 0, E()); sset(mz, 1, E()); sset(mz, 2, E()); sset(mz, 3, E())
54 let oz: *i64 = sys_mmap(8 * 8) as *i64
55 sset(oz, 0, "tag\x00" as *u8); sset(oz, 1, E()); sset(oz, 2, E()); sset(oz, 3, current); sset(oz, 4, "professional\x00" as *u8); sset(oz, 5, E())
56 let keys: *i64 = sys_mmap(8 * 48) as *i64
57 let vals: *i64 = sys_mmap(8 * 48) as *i64
58 let n: i64 = ar_fields(core, pz, mz, oz, keys, vals)
59 return ar_encode(keys, vals, n, out)
60}
61
62// build a record varying by SOURCE (type / location / identifier; prov=machine).
63func mk_vis(typ: *u8, loc: *u8, ident: *u8, out: *u8) -> i64 {
64 let core: *i64 = sys_mmap(8 * 8) as *i64
65 sset(core, 0, typ); sset(core, 1, "Asset\x00" as *u8); sset(core, 2, E())
66 sset(core, 3, "2026-06-20\x00" as *u8); sset(core, 4, ident); sset(core, 5, E()); sset(core, 6, E())
67 let pz: *i64 = sys_mmap(8 * 8) as *i64
68 sset(pz, 0, "machine\x00" as *u8); sset(pz, 1, E()); sset(pz, 2, E()); sset(pz, 3, E()); sset(pz, 4, E()); sset(pz, 5, E())
69 let mz: *i64 = sys_mmap(8 * 8) as *i64
70 sset(mz, 0, E()); sset(mz, 1, E()); sset(mz, 2, E()); sset(mz, 3, E())
71 let oz: *i64 = sys_mmap(8 * 8) as *i64
72 sset(oz, 0, E()); sset(oz, 1, loc); sset(oz, 2, E()); sset(oz, 3, "1\x00" as *u8); sset(oz, 4, E()); sset(oz, 5, E())
73 let keys: *i64 = sys_mmap(8 * 48) as *i64
74 let vals: *i64 = sys_mmap(8 * 48) as *i64
75 let n: i64 = ar_fields(core, pz, mz, oz, keys, vals)
76 return ar_encode(keys, vals, n, out)
77}
78
79func gt_prefix(prefix: *u8, base: *u8, salt: i64) -> i64 {
80 var po: i64 = 0
81 while base[po] != (0 as u8) { prefix[po] = base[po]; po = po + 1 }
82 var m: i64 = sys_now_ms() + salt
83 let ds: *u8 = sys_mmap(28)
84 var k: i64 = 0
85 if m == 0 { ds[0] = 48 as u8; k = 1 }
86 while m > 0 { ds[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
87 var j: i64 = 0
88 while j < k { prefix[po] = ds[k - 1 - j]; po = po + 1; j = j + 1 }
89 prefix[po] = 45 as u8; po = po + 1
90 prefix[po] = 0 as u8
91 return po
92}
93
94// read a file fully into buf (cap bound); returns bytes read (0 on open fail).
95func g_read(path: *u8, buf: *u8, cap: i64) -> i64 {
96 let fd: i64 = sys_openat_rd(path)
97 if fd < 0 { return 0 }
98 var n: i64 = 0
99 var go: i64 = 1
100 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - 1 - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap - 1 { go = 0 } }
101 sys_close(fd)
102 return n
103}
104// does haystack[0,hn) contain the NUL-terminated needle?
105func g_contains(hay: *u8, hn: i64, needle: *u8) -> i64 {
106 var nl: i64 = 0
107 while needle[nl] != (0 as u8) { nl = nl + 1 }
108 if nl == 0 { return 1 }
109 var i: i64 = 0
110 while i + nl <= hn {
111 var j: i64 = 0
112 var ok: i64 = 1
113 while j < nl { if hay[i + j] != needle[j] { ok = 0; j = nl } else { j = j + 1 } }
114 if ok == 1 { return 1 }
115 i = i + 1
116 }
117 return 0
118}
119
120func expect(logfd: i64, label: *u8, got: i64, want: i64) -> i64 {
121 g_puts(logfd, label); g_puts(logfd, " got=\x00" as *u8); g_putn(logfd, got); g_puts(logfd, " want=\x00" as *u8); g_putn(logfd, want); g_puts(logfd, ": \x00" as *u8)
122 if got == want { g_puts(logfd, "PASS\n\x00" as *u8); return 1 }
123 g_puts(logfd, "FAIL\n\x00" as *u8); return 0
124}
125
126// T5: the public_only view WITHHOLDS a private-by-source (gallery) asset while showing a public one,
127// and the full (operator) view shows the gallery asset. Proves the source->visibility flag is enforced.
128func gt_visfilter(logfd: i64) -> i64 {
129 let p5: *u8 = sys_mmap(256); gt_prefix(p5, "/tmp/asdash-vis-\x00" as *u8, 5)
130 let rGal: *u8 = sys_mmap(8192); let nGal: i64 = mk_vis("image\x00" as *u8, "knowledge/staging/media/gallery/secret_frame.png\x00" as *u8, "secret_gallery_frame.png\x00" as *u8, rGal)
131 let rPub: *u8 = sys_mmap(8192); let nPub: i64 = mk_vis("doc\x00" as *u8, "web_assets/public_doc.html\x00" as *u8, "public_doc_marker\x00" as *u8, rPub)
132 let stv: *i64 = sys_mmap(16) as *i64
133 cat_ingest(p5, rGal, nGal, stv)
134 cat_ingest(p5, rPub, nPub, stv)
135 dp_emit(p5, "assets_pubtest\x00" as *u8, 1)
136 let ph: *u8 = sys_mmap(524288)
137 let phn: i64 = g_read("web_assets/assets_pubtest.html\x00" as *u8, ph, 524288)
138 dp_emit(p5, "assets_fulltest\x00" as *u8, 0)
139 let fh: *u8 = sys_mmap(524288)
140 let fhn: i64 = g_read("web_assets/assets_fulltest.html\x00" as *u8, fh, 524288)
141 var t5: i64 = 1
142 if g_contains(ph, phn, "public_doc_marker\x00" as *u8) == 0 { t5 = 0 }
143 if g_contains(ph, phn, "secret_gallery_frame.png\x00" as *u8) == 1 { t5 = 0 }
144 if g_contains(fh, fhn, "secret_gallery_frame.png\x00" as *u8) == 0 { t5 = 0 }
145 g_puts(logfd, " (T5) public view withholds gallery-by-source, full view shows it: \x00" as *u8)
146 if t5 == 1 { g_puts(logfd, "PASS\n\x00" as *u8); return 1 }
147 g_puts(logfd, "FAIL\n\x00" as *u8); return 0
148}
149
150func main() -> i64 {
151 let logfd: i64 = sys_openat_append("knowledge/status/asset_dashboard_gate.log\x00" as *u8, 0x1a4)
152 g_puts(logfd, "=== ASSET-DASHBOARD-GATE (the GOING-ON pillar: live stats -> HTML) ===\n\x00" as *u8)
153
154 let prefix: *u8 = sys_mmap(256); gt_prefix(prefix, "/tmp/asdash-\x00" as *u8, 0)
155 let rA: *u8 = sys_mmap(8192); let nA: i64 = mk_full("doc\x00" as *u8, "machine\x00" as *u8, "1\x00" as *u8, "d-a\x00" as *u8, rA)
156 let rB: *u8 = sys_mmap(8192); let nB: i64 = mk_full("image\x00" as *u8, "human\x00" as *u8, "1\x00" as *u8, "d-b\x00" as *u8, rB)
157 let rC: *u8 = sys_mmap(8192); let nC: i64 = mk_full("video\x00" as *u8, "downloaded\x00" as *u8, "0\x00" as *u8, "d-c\x00" as *u8, rC)
158 let st0: *i64 = sys_mmap(16) as *i64
159 cat_ingest(prefix, rA, nA, st0)
160 cat_ingest(prefix, rB, nB, st0)
161 cat_ingest(prefix, rC, nC, st0)
162
163 var pass: i64 = 0
164 var total: i64 = 0
165
166 // ---- T1: live stats counted correctly ----
167 let st: *i64 = sys_mmap(8 * st_cap()) as *i64
168 st_compute_live(prefix, st)
169 g_puts(logfd, " stats: total=\x00" as *u8); g_putn(logfd, st[ST_TOTAL()]); g_puts(logfd, " doc=\x00" as *u8); g_putn(logfd, st[ST_T_DOC()])
170 g_puts(logfd, " image=\x00" as *u8); g_putn(logfd, st[ST_T_IMAGE()]); g_puts(logfd, " video=\x00" as *u8); g_putn(logfd, st[ST_T_VIDEO()])
171 g_puts(logfd, " machine=\x00" as *u8); g_putn(logfd, st[ST_P_MACHINE()]); g_puts(logfd, " human=\x00" as *u8); g_putn(logfd, st[ST_P_HUMAN()]); g_puts(logfd, " dl=\x00" as *u8); g_putn(logfd, st[ST_P_DOWNLOAD()])
172 g_puts(logfd, " current=\x00" as *u8); g_putn(logfd, st[ST_CURRENT()]); g_puts(logfd, " retired=\x00" as *u8); g_putn(logfd, st[ST_NOTCURRENT()]); g_puts(logfd, "\n\x00" as *u8)
173 total = total + 1; pass = pass + expect(logfd, " (T1a) total==3\x00" as *u8, st[ST_TOTAL()], 3)
174 total = total + 1; pass = pass + expect(logfd, " (T1b) doc==1\x00" as *u8, st[ST_T_DOC()], 1)
175 total = total + 1; pass = pass + expect(logfd, " (T1c) image==1\x00" as *u8, st[ST_T_IMAGE()], 1)
176 total = total + 1; pass = pass + expect(logfd, " (T1d) video==1\x00" as *u8, st[ST_T_VIDEO()], 1)
177 total = total + 1; pass = pass + expect(logfd, " (T1e) machine==1\x00" as *u8, st[ST_P_MACHINE()], 1)
178 total = total + 1; pass = pass + expect(logfd, " (T1f) human==1\x00" as *u8, st[ST_P_HUMAN()], 1)
179 total = total + 1; pass = pass + expect(logfd, " (T1g) downloaded==1\x00" as *u8, st[ST_P_DOWNLOAD()], 1)
180 total = total + 1; pass = pass + expect(logfd, " (T1h) current==2\x00" as *u8, st[ST_CURRENT()], 2)
181 total = total + 1; pass = pass + expect(logfd, " (T1i) retired==1\x00" as *u8, st[ST_NOTCURRENT()], 1)
182
183 // ---- T2: MISSING_PROVENANCE fires for every record (deny-by-default TO-DO state) ----
184 total = total + 1; pass = pass + expect(logfd, " (T2) MISSING_PROVENANCE==3\x00" as *u8, st[ST_SIG_PROV()], 3)
185
186 // ---- T3: dp_emit renders HTML with all 3 pillars + the correct live total ----
187 let wrote: i64 = dp_emit(prefix, "assets_gatetest\x00" as *u8, 0)
188 g_puts(logfd, " dp_emit wrote=\x00" as *u8); g_putn(logfd, wrote); g_puts(logfd, " bytes -> web_assets/assets_gatetest.html\n\x00" as *u8)
189 let html: *u8 = sys_mmap(524288)
190 let hn: i64 = g_read("web_assets/assets_gatetest.html\x00" as *u8, html, 524288)
191 var t3: i64 = 1
192 if wrote <= 0 { t3 = 0 }
193 if hn <= 0 { t3 = 0 }
194 if g_contains(html, hn, "What we have\x00" as *u8) == 0 { t3 = 0 }
195 if g_contains(html, hn, "What we need to do\x00" as *u8) == 0 { t3 = 0 }
196 if g_contains(html, hn, "What's going on\x00" as *u8) == 0 { t3 = 0 }
197 if g_contains(html, hn, "Total catalogued assets: <strong>3</strong>\x00" as *u8) == 0 { t3 = 0 }
198 total = total + 1; pass = pass + expect(logfd, " (T3) HTML has 3 pillars + live total=3\x00" as *u8, t3, 1)
199
200 // ---- T4 TEETH: an EMPTY catalog -> all stats ZERO ----
201 let ep: *u8 = sys_mmap(256); gt_prefix(ep, "/tmp/asdash-empty-\x00" as *u8, 9)
202 let est: *i64 = sys_mmap(8 * st_cap()) as *i64
203 st_compute_live(ep, est)
204 var t4: i64 = 1
205 if est[ST_TOTAL()] != 0 { t4 = 0 }
206 if est[ST_SIG_TOTAL()] != 0 { t4 = 0 }
207 if est[ST_CURRENT()] != 0 { t4 = 0 }
208 total = total + 1; pass = pass + expect(logfd, " (T4 TEETH) empty catalog -> all zero\x00" as *u8, t4, 1)
209
210 total = total + 1; pass = pass + gt_visfilter(logfd)
211
212 g_puts(logfd, "ASSET-DASHBOARD-GATE passed \x00" as *u8); g_putn(logfd, pass); g_puts(logfd, "/\x00" as *u8); g_putn(logfd, total)
213 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
214 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
215 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
216 let ctr__dry: *i64 = gv_ctr()
217 ctr__dry[0] = pass
218 ctr__dry[1] = total
219 let rc__dry: i64 = gv_verdict("ASSET-DASHBOARD-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
220 sys_exit(rc__dry)
221 return rc__dry
222}