code wiki / (root) / nx_sitesweep_gate.nx

nx_sitesweep_gate.nx source

↩ module page · 282 lines · 15995 B

1// nx_sitesweep_gate.nx -- the referee for the site-wide broken-asset sweep. 2// 3// WHAT IT CAN AND CANNOT PROVE, STATED UP FRONT. nx_sitesweep adds exactly TWO pieces of judgement to 4// nx_page_verify: the ref PREFILTER (which pages can be proven ref-free without a fetch) and the RULER 5// VERDICT PARSER (how nx_page_verify's output is read). Everything else about a page is the ruler's 6// judgement, already refereed by nx_page_verify_gate. So this gate bites those two, and it bites them 7// IN PROCESS by importing nx_sitesweep_lib -- the same copy the sweep ships. There is no second 8// implementation for the teeth to agree with. 9// 10// The in-process teeth need no fork and no network, so they run in milliseconds and are safe on the 11// fast gate roster. The END-TO-END cell is a different cost class: it forks the deployed sweep against 12// six live pages and takes minutes. It is therefore OPT-IN (e2e=1) and, when it does not run, the gate 13// SAYS SO IN A NAMED LINE rather than silently counting one fewer tooth. A skipped cell that announces 14// itself is a fact; a skipped cell that does not is a false sense of coverage. 15// 16// FIXTURES. The bite cells read two PERMANENT PUBLISHED negative controls that exist for exactly this 17// purpose -- sites/nishifamily/render3d/negctl_bare.html (unquoted src=, the form the ruler was blind to 18// until 2026-08-25) and negctl_sq.html (single-quoted src=, the form it was blind to until 2026-08-18). 19// They are read ONLY, never written, so this gate shares no scratch with any production beat; the 20// fixture-ratchet law is about a gate WRITING where a beat writes, and there is no write here at all. 21// Synthetic fixtures are built in memory at RUNTIME, byte by byte, so no detector that scans source can 22// mistake a gate fixture for a real occurrence, and no literal newline inside a string is required. 23// 24// usage: nx_sitesweep_gate [e2e=1] 25// license_tier: ORIGINAL 26import "nx_syscalls.nx" 27import "nx_gate_verdict.nx" 28import "nx_sitesweep_lib.nx" 29import "nx_tool_run.nx" 30 31const SG_NAME: *u8 = "nx_sitesweep_gate" 32const SG_FIX_BARE: *u8 = "sites/nishifamily/render3d/negctl_bare.html" 33const SG_FIX_SQ: *u8 = "sites/nishifamily/render3d/negctl_sq.html" 34const SG_SWEEP_ELF: *u8 = "nx_sitesweep.elf" 35const SG_DOCROOT: *u8 = "sites/nishifamily" 36const SG_ORIGIN: *u8 = "https://nishifamily.com" 37 38const SG_BUF: i64 = 65536 39const SG_E2E_BUF: i64 = 1048576 40// 300 s: the e2e cell sweeps six live pages and one measured page costs ~5.5 s of TLS plus asset 41// decode (measured 2026-08-25 over 24 live checks in 131 s). 300 s is roughly 9x the expected 33 s, so 42// the bound fires only on a genuine hang. 43const SG_E2E_TMO_MS: i64 = 300000 44const SG_ARGVN: i64 = 32 45 46// URLs the end-to-end cell discriminates between. All three live in ONE directory and come from ONE 47// generator, so the cell varies the DEFECT and holds everything else fixed. 48const SG_URL_BARE: *u8 = "/render3d/negctl_bare" 49const SG_URL_SQ: *u8 = "/render3d/negctl_sq" 50const SG_URL_GOOD: *u8 = "/render3d/negctl_noviewport" 51 52func sgw(s: *u8) -> i64 { sys_write(1, s, ss_len(s)); return 0 } 53 54// build a synthetic nx_page_verify tail in buf; returns length. Newlines are CONSTRUCTED, never written 55// as a literal inside a string: this dialect permits a literal newline in a string and that has silently 56// shifted a scanner's mask before. 57func sg_tail(buf: *u8, summary: *u8, verdict: *u8) -> i64 { 58 var o: i64 = ss_cat(buf, 0, "page status=200 bytes=4096" as *u8) 59 buf[o] = SS_CH_NL as u8; o = o + 1 60 if summary[0] != (0 as u8) { 61 o = ss_cat(buf, o, summary) 62 buf[o] = SS_CH_NL as u8; o = o + 1 63 } 64 o = ss_cat(buf, o, verdict) 65 buf[o] = SS_CH_NL as u8; o = o + 1 66 return o 67} 68 69func main(argc: i64, argv: *i64) -> i64 { 70 var e2e: i64 = 0 71 var ai: i64 = 1 72 while ai < argc { 73 let a: *u8 = argv[ai] as *u8 74 let eo: i64 = ss_pfx(a, "e2e=" as *u8) 75 if eo >= 0 { e2e = ss_int_at(a, ss_len(a), eo) } 76 ai = ai + 1 77 } 78 gv_head("=== nx_sitesweep_gate -- referee for the site-wide broken-asset sweep ===" as *u8) 79 let ctr: *i64 = gv_ctr() 80 let outv: *i64 = sys_mmap(SS_WORD * SS_V_N) as *i64 81 let buf: *u8 = sys_mmap(SG_BUF) 82 let url: *u8 = sys_mmap(SG_BUF) 83 let dl: i64 = ss_len(SG_DOCROOT) 84 85 // ---- SUBJECTS: bind every aggregate below to a NON-ZERO denominator of REAL published bytes. ---- 86 let lp: *i64 = sys_mmap(SS_WORD * 2) as *i64 87 let bare: *u8 = sys_read_file(SG_FIX_BARE, lp) 88 var bare_n: i64 = 0 89 if (bare as i64) != 0 { bare_n = lp[0] } 90 let lp2: *i64 = sys_mmap(SS_WORD * 2) as *i64 91 let sq: *u8 = sys_read_file(SG_FIX_SQ, lp2) 92 var sq_n: i64 = 0 93 if (sq as i64) != 0 { sq_n = lp2[0] } 94 var nfix: i64 = 0 95 if bare_n > 0 { nfix = nfix + 1 } 96 if sq_n > 0 { nfix = nfix + 1 } 97 sgw(" fixture bytes: negctl_bare=" as *u8); gv_num(bare_n) 98 sgw(" negctl_sq=" as *u8); gv_num(sq_n); sgw("\n" as *u8) 99 let have_fix: i64 = gv_subjects("published-negative-control-fixtures-readable" as *u8, nfix, ctr) 100 101 // ---- THE PREFILTER: bite it against the two attribute forms the ruler was once blind to. -------- 102 // A ref-free control is built in memory so the good side is fully determined. 103 var gn: i64 = ss_cat(buf, 0, "<html lang=en><head><title>t</title></head><body><h1>x</h1>" as *u8) 104 gn = ss_cat(buf, gn, "<p>no assets here at all</p></body></html>" as *u8) 105 let good_free: i64 = ss_may_have_refs(buf, gn) 106 107 if have_fix == 1 { 108 var bad_bare: i64 = 0 109 if bare_n > 0 { bad_bare = ss_may_have_refs(bare, bare_n) } 110 gv_bite("prefilter-sees-the-UNQUOTED-src-fixture-and-not-a-ref-free-page" as *u8, bad_bare, good_free, ctr) 111 var bad_sq: i64 = 0 112 if sq_n > 0 { bad_sq = ss_may_have_refs(sq, sq_n) } 113 gv_bite("prefilter-sees-the-SINGLE-QUOTED-src-fixture-and-not-a-ref-free-page" as *u8, bad_sq, good_free, ctr) 114 } 115 116 // The prefilter must key on the ruler's actual trigger TOKEN, not on the word. A page whose only 117 // "src" is inside another attribute name has no ref for the ruler to find, and treating it as one 118 // would quietly convert a proof into a guess in the direction of extra network load. 119 var dn: i64 = ss_cat(buf, 0, "<html><body><img data-source=x.png alt=a></body></html>" as *u8) 120 gv_check("neg-control-prefilter-must-not-fire-on-data-source-attribute" as *u8, 1 - ss_may_have_refs(buf, dn), ctr) 121 // ...and it MUST fire on a stylesheet link, the ruler's other trigger. 122 var kn: i64 = ss_cat(buf, 0, "<html><head><link rel=stylesheet href=/s.css></head></html>" as *u8) 123 gv_check("prefilter-fires-on-a-link-tag-the-rulers-other-trigger" as *u8, ss_may_have_refs(buf, kn), ctr) 124 125 // ---- THE VERDICT PARSER: both signals present, so the cell proves DISCRIMINATION, not detection -- 126 let tail: *u8 = sys_mmap(SG_BUF) 127 let tn_red: i64 = sg_tail(tail, "checked=16 skipped=0 law-violations=15 broken=15" as *u8, "VERDICT=RED broken=15" as *u8) 128 let c_red: i64 = ss_parse_ruler(tail, tn_red, 0, outv) 129 let red_broken: i64 = outv[SS_V_BROKEN] 130 let red_law: i64 = outv[SS_V_LAW] 131 let red_checked: i64 = outv[SS_V_CHECKED] 132 133 let tail2: *u8 = sys_mmap(SG_BUF) 134 let tn_grn: i64 = sg_tail(tail2, "checked=16 skipped=0 law-violations=0 broken=0" as *u8, "VERDICT=GREEN (every referenced asset fetches AND decodes)" as *u8) 135 let c_grn: i64 = ss_parse_ruler(tail2, tn_grn, 0, outv) 136 137 var f_red: i64 = 0 138 if c_red == SS_C_BROKEN { f_red = 1 } 139 var f_grn: i64 = 0 140 if c_grn == SS_C_BROKEN { f_grn = 1 } 141 gv_bite("verdict-parser-fires-on-RED-and-is-silent-on-GREEN" as *u8, f_red, f_grn, ctr) 142 143 sgw(" parsed RED: broken=" as *u8); gv_num(red_broken) 144 sgw(" law=" as *u8); gv_num(red_law) 145 sgw(" checked=" as *u8); gv_num(red_checked); sgw("\n" as *u8) 146 var nums_ok: i64 = 0 147 if red_broken == 15 { if red_law == 15 { if red_checked == 16 { nums_ok = 1 } } } 148 gv_check("parser-carries-the-rulers-own-numbers-not-just-its-word" as *u8, nums_ok, ctr) 149 150 // A RED with NO asset-summary line means the ruler exited before it ever looked at an asset: the 151 // PAGE did not serve. Folding that into the broken-image count sends the next reader to fix the 152 // wrong thing. Both cases are asserted TOGETHER so the tooth proves the split, not one half of it. 153 let tail3: *u8 = sys_mmap(SG_BUF) 154 let tn_pr: i64 = sg_tail(tail3, "" as *u8, "VERDICT=RED (page not 200)" as *u8) 155 let c_pr: i64 = ss_parse_ruler(tail3, tn_pr, 0, outv) 156 var split_ok: i64 = 0 157 if c_pr == SS_C_PAGERED { if c_red == SS_C_BROKEN { split_ok = 1 } } 158 gv_check("parser-splits-PAGE-RED-from-BROKEN-both-signals-present" as *u8, split_ok, ctr) 159 160 // GREEN-PARTIAL must never be read as GREEN: the ruler emits it precisely when its own coverage is 161 // UNPROVEN, and a prefix match on the shorter word would launder that into a clean pass. 162 let tail4: *u8 = sys_mmap(SG_BUF) 163 let tn_gp: i64 = sg_tail(tail4, "checked=1 skipped=0 law-violations=0 broken=0" as *u8, "VERDICT=GREEN-PARTIAL (examined assets fetch AND decode; 15 img ref(s) unread)" as *u8) 164 let c_gp: i64 = ss_parse_ruler(tail4, tn_gp, 0, outv) 165 var gp_ok: i64 = 0 166 if c_gp == SS_C_PARTIAL { gp_ok = 1 } 167 gv_check("green-partial-is-its-own-class-never-folded-into-green" as *u8, gp_ok, ctr) 168 169 // THE THIRD STATE, twice. A vantage failure and a destroyed capture are both "I could not look", 170 // and neither may be spelled RED. The cut case reuses the REAL RED bytes, so the only thing that 171 // changes is the truncation flag -- if the parser ignored it, this tooth reads BROKEN and fails. 172 let tail5: *u8 = sys_mmap(SG_BUF) 173 let tn_uo: i64 = sg_tail(tail5, "" as *u8, "VERDICT=UNOBSERVABLE vantage=pinned:127.0.0.1:8443 reason=no-connection(connect)" as *u8) 174 let c_uo: i64 = ss_parse_ruler(tail5, tn_uo, 0, outv) 175 var uo_ok: i64 = 0 176 if c_uo == SS_C_UNOBSERVABLE { uo_ok = 1 } 177 gv_check("unobservable-stays-unobservable-never-red" as *u8, uo_ok, ctr) 178 179 let c_cut: i64 = ss_parse_ruler(tail, tn_red, 1, outv) 180 var cut_ok: i64 = 0 181 if c_cut == SS_C_UNREADABLE { cut_ok = 1 } 182 gv_check("neg-control-a-CUT-capture-reads-UNREADABLE-not-BROKEN" as *u8, cut_ok, ctr) 183 184 // An empty capture is a fork that produced nothing, not a clean page. 185 let c_empty: i64 = ss_parse_ruler(tail, 0, 0, outv) 186 var emp_ok: i64 = 0 187 if c_empty == SS_C_UNREADABLE { emp_ok = 1 } 188 gv_check("neg-control-an-EMPTY-capture-reads-UNREADABLE-not-GREEN" as *u8, emp_ok, ctr) 189 190 // POSITIONAL ANCHORING. The ruler quotes verdict words in its own prose, so the answer is the LAST 191 // occurrence and only the last. This fixture puts a GREEN ahead of the real RED: a first-match or 192 // unanchored parser reads GREEN and the whole sweep silently acquits every broken page. 193 let tail6: *u8 = sys_mmap(SG_BUF) 194 var t6: i64 = ss_cat(tail6, 0, "note: a page that passes prints VERDICT=GREEN here" as *u8) 195 tail6[t6] = SS_CH_NL as u8; t6 = t6 + 1 196 t6 = ss_cat(tail6, t6, "checked=3 skipped=0 law-violations=2 broken=2" as *u8) 197 tail6[t6] = SS_CH_NL as u8; t6 = t6 + 1 198 t6 = ss_cat(tail6, t6, "VERDICT=RED broken=2" as *u8) 199 tail6[t6] = SS_CH_NL as u8; t6 = t6 + 1 200 let c_anch: i64 = ss_parse_ruler(tail6, t6, 0, outv) 201 var anch_ok: i64 = 0 202 if c_anch == SS_C_BROKEN { anch_ok = 1 } 203 gv_check("verdict-read-from-the-LAST-occurrence-not-the-first" as *u8, anch_ok, ctr) 204 205 // ---- THE PATH -> URL MAP. These three cases are the whole contract. ----------------------------- 206 ss_url_of(SG_ORIGIN, dl, "sites/nishifamily/world/foundation.html" as *u8, url) 207 var u1: i64 = 0 208 if ss_tok_eq(url, ss_len(url), 0, "https://nishifamily.com/world/foundation" as *u8) == 1 { u1 = 1 } 209 sgw(" url(world/foundation.html) = " as *u8); sgw(url); sgw("\n" as *u8) 210 gv_check("url-map-drops-the-html-extension" as *u8, u1, ctr) 211 212 ss_url_of(SG_ORIGIN, dl, "sites/nishifamily/world/index.html" as *u8, url) 213 var u2: i64 = 0 214 if ss_tok_eq(url, ss_len(url), 0, "https://nishifamily.com/world" as *u8) == 1 { u2 = 1 } 215 sgw(" url(world/index.html) = " as *u8); sgw(url); sgw("\n" as *u8) 216 gv_check("url-map-collapses-index-to-its-own-directory" as *u8, u2, ctr) 217 218 ss_url_of(SG_ORIGIN, dl, "sites/nishifamily/index.html" as *u8, url) 219 var u3: i64 = 0 220 if ss_tok_eq(url, ss_len(url), 0, "https://nishifamily.com/" as *u8) == 1 { u3 = 1 } 221 sgw(" url(index.html) = " as *u8); sgw(url); sgw("\n" as *u8) 222 gv_check("url-map-root-index-is-the-site-root" as *u8, u3, ctr) 223 224 // ---- CLASS NAMES ROUND-TRIP. The ledger is rewritten every run and re-read the next run, so a 225 // name that does not survive the round trip silently resets a page to UNCHECKED and the coverage 226 // number quietly falls without anything reporting a fault. 227 var c: i64 = 0 228 var rt_ok: i64 = 1 229 var rt_n: i64 = 0 230 while c < SS_C_N { 231 if ss_class_of_name(ss_class_name(c)) != c { rt_ok = 0 } 232 rt_n = rt_n + 1 233 c = c + 1 234 } 235 sgw(" class round-trip checked=" as *u8); gv_num(rt_n); sgw("\n" as *u8) 236 var rt_pop: i64 = 0 237 if rt_n == SS_C_N { rt_pop = 1 } 238 gv_check("class-roundtrip-covers-EVERY-declared-class" as *u8, rt_pop, ctr) 239 gv_check("every-class-name-round-trips-through-the-ledger-spelling" as *u8, rt_ok, ctr) 240 241 // ---- THE END-TO-END CELL -------------------------------------------------------------------- 242 if e2e == 1 { 243 let eb: *u8 = sys_mmap(SG_E2E_BUF) 244 let av: *i64 = sys_mmap(SG_ARGVN) as *i64 245 av[0] = SG_SWEEP_ELF as i64 246 av[1] = "root=render3d" as *u8 as i64 247 av[2] = 0 248 let elp: *i64 = sys_mmap(SS_WORD * 2) as *i64 249 let etr: *i64 = sys_mmap(SS_WORD * 2) as *i64 250 etr[0] = 0 251 elp[0] = 0 252 tr_run_capture_tr(SG_SWEEP_ELF, av, eb, SG_E2E_BUF, elp, SG_E2E_TMO_MS, etr) 253 let en: i64 = elp[0] 254 sgw(" e2e capture bytes=" as *u8); gv_num(en) 255 sgw(" cut=" as *u8); gv_num(etr[0]); sgw("\n" as *u8) 256 var ran: i64 = 0 257 if en > 0 { if etr[0] == 0 { ran = 1 } } 258 if gv_need("e2e-sweep-produced-a-readable-capture" as *u8, ran, ctr) == 1 { 259 var e_bare: i64 = ss_contains(eb, en, SG_URL_BARE) 260 var e_sq: i64 = ss_contains(eb, en, SG_URL_SQ) 261 var e_good: i64 = ss_contains(eb, en, SG_URL_GOOD) 262 var e_bad: i64 = 0 263 if e_bare == 1 { if e_sq == 1 { e_bad = 1 } } 264 sgw(" e2e worklist: bare=" as *u8); gv_num(e_bare) 265 sgw(" sq=" as *u8); gv_num(e_sq) 266 sgw(" good=" as *u8); gv_num(e_good); sgw("\n" as *u8) 267 // Both fixtures named AND the asset-clean sibling absent, from ONE run over ONE directory 268 // produced by ONE generator: the only thing that varies between them is the defect. 269 gv_bite("e2e-sweep-names-both-published-fixtures-and-not-their-clean-sibling" as *u8, e_bad, e_good, ctr) 270 gv_check("e2e-verdict-line-is-present-and-last" as *u8, ss_contains(eb, en, "verdict=RED" as *u8), ctr) 271 } 272 } else { 273 // A NAMED ABSENCE, NOT A PASS. The cell simply does not run, the denominator is smaller, and the 274 // reader is told which proof is missing and exactly how to obtain it. 275 sgw(" E2E-CELL: NOT EXERCISED THIS RUN -- the end-to-end bite forks the deployed sweep against\n" as *u8) 276 sgw(" six live pages (~35 s) and is opt-in so this gate stays safe on the fast roster.\n" as *u8) 277 sgw(" Run `nx_sitesweep_gate e2e=1` to exercise it. The tooth count below is SMALLER by 3\n" as *u8) 278 sgw(" because those teeth did not run -- it is not that they passed.\n" as *u8) 279 } 280 281 return gv_verdict(SG_NAME, ctr, "prefilter and verdict-parser bitten against the PUBLISHED unquoted and single-quoted negative controls; third state proven for cut, empty and unobservable captures" as *u8) 282}