code wiki / (root) / nx_gen_ui_gate.nx

nx_gen_ui_gate.nx source

↩ module page · 157 lines · 7642 B

1// nx_gen_ui_gate.nx -- the REFEREE for gen G19 (nx_gen_ui_emit): the /gen companion page is EMITTED from data, 2// deterministic, behaviourally complete, fail-closed on a missing key, and THE SERVED FILE IS THE EMITTED FILE. 3// DONE-RULE (gen.plan G19): two emits from the live conf are byte-identical; the page carries every required 4// behaviour marker; a conf missing a key REFUSES by name and writes nothing; the bytes at the daemon's served path 5// equal the emitted bytes (so a hand edit to the served page is a RED, never a silent fork of the design). 6// FIXTURE LAW: scratch under /tmp/<gate>/, cleared at SETUP; the neg-control conf is DERIVED from the live conf 7// at run time (never a checked-in fixture a scanner could find), and a tooth asserts the fixture reached its condition. 8// license_tier: ORIGINAL expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_gate_verdict.nx" 11import "nx_tool_run.nx" 12 13const UG_ELF: *u8 = "/volume1/homes/elderwesto/nishihost/nx_gen_ui_emit.elf" as *u8 14const UG_CONF: *u8 = "/volume1/homes/elderwesto/nishihost/knowledge/gen_ui.conf" as *u8 15const UG_SERVED: *u8 = "/volume1/ai/gen/elara_ui.html" as *u8 16const UG_DIR: *u8 = "/tmp/nx_gen_ui_gate" as *u8 17const UG_A: *u8 = "/tmp/nx_gen_ui_gate/a.html" as *u8 18const UG_B: *u8 = "/tmp/nx_gen_ui_gate/b.html" as *u8 19const UG_BAD_CONF: *u8 = "/tmp/nx_gen_ui_gate/bad.conf" as *u8 20const UG_BAD_OUT: *u8 = "/tmp/nx_gen_ui_gate/bad.html" as *u8 21const UG_DROP_KEY: *u8 = "api_base|" as *u8 22const UG_MODE_DIR: i64 = 511 23const UG_MODE_FILE: i64 = 420 24const UG_CAP: i64 = 262144 25const UG_MIN_PAGE: i64 = 4096 26const UG_TIMEOUT_MS: i64 = 10000 27const UG_EXIT_REFUSED: i64 = 3 28const UG_CH_NL: i64 = 10 29 30func ug_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 31func ug_find(buf: *u8, n: i64, needle: *u8) -> i64 { 32 let nl: i64 = ug_len(needle) 33 if nl <= 0 { return 0 - 1 } 34 var i: i64 = 0 35 while i + nl <= n { 36 var j: i64 = 0 37 var same: i64 = 1 38 var scan: i64 = 1 39 while scan == 1 { if j >= nl { scan = 0 } else { if buf[i + j] != needle[j] { same = 0; scan = 0 } else { j = j + 1 } } } 40 if same == 1 { return i } 41 i = i + 1 42 } 43 return 0 - 1 44} 45func ug_starts(buf: *u8, at: i64, n: i64, pre: *u8) -> i64 { 46 var i: i64 = 0 47 while pre[i] != (0 as u8) { if at + i >= n { return 0 } if buf[at + i] != pre[i] { return 0 } i = i + 1 } 48 return 1 49} 50 51// fork the emitter with (conf, out); returns its exit code (tr semantics: negative = harness failure, -5 = timeout) 52func ug_run(conf: *u8, outp: *u8) -> i64 { 53 let argv: *i64 = sys_mmap(32) as *i64 54 argv[0] = UG_ELF as i64 55 argv[1] = conf as i64 56 argv[2] = outp as i64 57 argv[3] = 0 58 let cap: *u8 = sys_mmap(UG_CAP) 59 let olen: *i64 = sys_mmap(16) as *i64 60 olen[0] = 0 61 return tr_run_capture_to(UG_ELF, argv, cap, UG_CAP - 1, olen, UG_TIMEOUT_MS) 62} 63 64// byte-identity of two files (0 when either is unreadable) 65func ug_same(pa: *u8, pb: *u8) -> i64 { 66 let la: *i64 = sys_mmap(16) as *i64 67 let lb: *i64 = sys_mmap(16) as *i64 68 la[0] = 0; lb[0] = 0 69 let a: *u8 = sys_read_file(pa, la) 70 let b: *u8 = sys_read_file(pb, lb) 71 if (a as i64) == 0 { return 0 } 72 if (b as i64) == 0 { return 0 } 73 if la[0] != lb[0] { return 0 } 74 var i: i64 = 0 75 while i < la[0] { if a[i] != b[i] { return 0 } i = i + 1 } 76 return 1 77} 78 79// the neg-control conf: the LIVE conf with every line starting UG_DROP_KEY removed. Returns lines dropped. 80func ug_write_bad_conf() -> i64 { 81 let lp: *i64 = sys_mmap(16) as *i64 82 lp[0] = 0 83 let b: *u8 = sys_read_file(UG_CONF, lp) 84 if (b as i64) == 0 { return 0 - 1 } 85 let n: i64 = lp[0] 86 let fd: i64 = sys_openat_wr(UG_BAD_CONF, UG_MODE_FILE) 87 if fd < 0 { return 0 - 2 } 88 var dropped: i64 = 0 89 var i: i64 = 0 90 while i < n { 91 let ls: i64 = i 92 var eol: i64 = i 93 var scan: i64 = 1 94 while scan == 1 { if eol >= n { scan = 0 } else { if b[eol] == (UG_CH_NL as u8) { scan = 0 } else { eol = eol + 1 } } } 95 var stop: i64 = eol 96 if stop < n { stop = stop + 1 } 97 if ug_starts(b, ls, n, UG_DROP_KEY) == 1 { dropped = dropped + 1 } else { sys_write(fd, ((b as i64) + ls) as *u8, stop - ls) } 98 i = stop 99 } 100 sys_close(fd) 101 return dropped 102} 103 104func main() -> i64 { 105 gv_head("nx_gen_ui_gate -- G19: the /gen page is emitted from data, deterministic, complete, fail-closed, and the served file is the emitted file" as *u8) 106 let ctr: *i64 = gv_ctr() 107 108 // SETUP: fresh scratch every run (idempotent) -- a leftover output could never satisfy a tooth by accident 109 sys_mkdir(UG_DIR, UG_MODE_DIR) 110 sys_unlinkat(UG_A) 111 sys_unlinkat(UG_B) 112 sys_unlinkat(UG_BAD_OUT) 113 sys_unlinkat(UG_BAD_CONF) 114 115 // T1 the emitter emits from the LIVE conf 116 let rc1: i64 = ug_run(UG_CONF, UG_A) 117 let la: *i64 = sys_mmap(16) as *i64 118 la[0] = 0 119 let a: *u8 = sys_read_file(UG_A, la) 120 var na: i64 = 0 121 if (a as i64) != 0 { na = la[0] } 122 gv_check("emit-succeeds-on-the-live-conf" as *u8, (rc1 == 0) & (na > UG_MIN_PAGE), ctr) 123 124 // T2 deterministic: a second emit is byte-identical 125 let rc2: i64 = ug_run(UG_CONF, UG_B) 126 gv_check("two-emits-are-byte-identical" as *u8, (rc2 == 0) & (ug_same(UG_A, UG_B) == 1), ctr) 127 128 // T3 required behaviours are present in the emitted page (each a separate tooth so a regression names itself) 129 gv_check("page-carries-the-nx-derived-stamp" as *u8, ug_find(a, na, "NX-DERIVED" as *u8) >= 0, ctr) 130 gv_check("page-posts-chat-to-the-daemon" as *u8, ug_find(a, na, "/api/chat" as *u8) >= 0, ctr) 131 gv_check("page-submits-studio-renders-async" as *u8, ug_find(a, na, "/api/batch" as *u8) >= 0, ctr) 132 gv_check("page-surfaces-a-render-error-instead-of-spinning" as *u8, ug_find(a, na, "if(r.error)" as *u8) >= 0, ctr) 133 gv_check("page-surfaces-a-chat-refusal-instead-of-an-empty-bubble" as *u8, ug_find(a, na, "could not answer" as *u8) >= 0, ctr) 134 gv_check("page-has-chat-gallery-and-studio-tabs" as *u8, (ug_find(a, na, "id=t-chat" as *u8) >= 0) & (ug_find(a, na, "id=t-gallery" as *u8) >= 0) & (ug_find(a, na, "id=t-studio" as *u8) >= 0), ctr) 135 gv_check("page-links-the-family-gallery" as *u8, ug_find(a, na, "/gallery" as *u8) >= 0, ctr) 136 gv_check("gallery-tab-is-the-conversation-album-by-day" as *u8, (ug_find(a, na, "/api/album" as *u8) >= 0) & (ug_find(a, na, "dayh" as *u8) >= 0), ctr) 137 138 // T4 NEG-CONTROL: a conf missing a required key refuses by name and writes NOTHING 139 let dropped: i64 = ug_write_bad_conf() 140 let lbad: *i64 = sys_mmap(16) as *i64 141 lbad[0] = 0 142 let bc: *u8 = sys_read_file(UG_BAD_CONF, lbad) 143 var badlacks: i64 = 0 144 if (bc as i64) != 0 { if ug_find(bc, lbad[0], UG_DROP_KEY) < 0 { badlacks = 1 } } 145 gv_check("fixture-reached-condition-bad-conf-lacks-the-key" as *u8, (dropped >= 1) & (badlacks == 1), ctr) 146 let rcb: i64 = ug_run(UG_BAD_CONF, UG_BAD_OUT) 147 gv_check("neg-control-missing-key-refuses-with-exit-3" as *u8, rcb == UG_EXIT_REFUSED, ctr) 148 let lbo: *i64 = sys_mmap(16) as *i64 149 lbo[0] = 0 150 let bo: *u8 = sys_read_file(UG_BAD_OUT, lbo) 151 gv_check("neg-control-missing-key-writes-nothing" as *u8, (bo as i64) == 0, ctr) 152 153 // T5 THE FLIP TOOTH: what the daemon serves IS what the emitter emits (a hand edit to the served page is a RED) 154 gv_check("served-page-is-the-emitted-page" as *u8, ug_same(UG_A, UG_SERVED) == 1, ctr) 155 156 return gv_verdict("GEN-UI-GATE" as *u8, ctr, "G19 done-rule: emitted from data, deterministic, behaviourally complete, fail-closed on a missing key, served bytes equal emitted bytes" as *u8) 157}