code wiki / (root) / nx_sitesweep.nx

nx_sitesweep.nx source

↩ module page · 833 lines · 46601 B

1// nx_sitesweep.nx -- THE STANDING ANSWER TO "HOW MANY PAGES ON OUR PUBLIC SITE SERVE BROKEN ASSETS?" 2// 3// WHY THIS EXISTS. nx_page_verify answers that question for ONE page, browser-grade (fetch, extract 4// every asset ref, refuse a relative ref by law, fetch each asset, deep-decode PNGs). It was BLIND to 5// unquoted HTML attributes until 2026-08-25; the instant it could see, /world/foundation turned out to 6// have had 15 images broken in every browser while reporting GREEN-PARTIAL. NOBODY KNEW HOW MANY OTHER 7// PAGES WERE LIKE THAT, because there was no instrument over the POPULATION -- only over a page a human 8// happened to name. A RULER WITH NO SWEEP MEASURES WHATEVER SOMEONE REMEMBERED TO POINT IT AT, AND ITS 9// SILENCE ON EVERYTHING ELSE READS AS HEALTH. 10// 11// ONE RULER, NEVER TWO. This organ does NOT extract refs, does NOT decode PNGs and does NOT re-state the 12// relative-ref law. It FORKS nx_page_verify per page and reads its verdict. Every judgement about a page 13// is that organ's judgement; this organ enumerates, budgets, classifies and reconciles. The two pieces 14// of judgement it DOES add -- the ref prefilter and the verdict parser -- live in nx_sitesweep_lib.nx, 15// which its gate imports, so the tested copy and the shipped copy cannot differ. 16// 17// COVERAGE IS A BUDGET PROBLEM AND THE BUDGET IS DECLARED. The docroot holds tens of thousands of 18// servable pages (33,243 entries in the generated organ-card tree alone, measured 2026-08-25). 19// Live-verifying all of them every beat would make this sweep the dominant load source on the box, which 20// the operator standing order names a BUG, not thoroughness. So: the ENUMERATION is complete every run 21// (cheap, local), and the LIVE CHECK is a deadline-bounded, cursor-advancing slice that rotates across 22// beats. That is a DECLARED PREFIX WITH A CURSOR, NOT A SAMPLE -- the run prints how many it examined, 23// how many it deferred and where the cursor now sits, and corpus_complete drops to 0 the moment 24// anything is deferred. 25// 26// THE LEDGER IS THE ANSWER, NOT THE RUN. One row per enumerated page, rewritten whole (TRUNCATE) every 27// run: this run's slice gets a fresh result, every other page carries its previous row forward with its 28// own at= epoch so staleness is visible per row. So "how many pages serve broken assets" is answered 29// from the accumulated ledger, and the partition SUMS to the enumeration by construction. 30// 31// THE THIRD STATE IS PLUMBED THROUGH. nx_page_verify already separates "I could not reach it" 32// (UNOBSERVABLE) and "our domain with an unusable registry endpoint" (UNMEASURED) from RED. This organ 33// keeps them as their own buckets and NEVER folds them into broken. A sweep that convicts a page it 34// never reached is reporting on its own environment. A ruler run that yields no readable verdict at all 35// (fork failure, per-page timeout, a capture cut so the tail carrying VERDICT was destroyed) is 36// UNREADABLE -- also never RED. 37// 38// usage: nx_sitesweep [root=<subpath>] [deadline=<secs>] [max=<pages>] [cursor=<n>] [probe=1] 39// root= sweep only docroot/<subpath>. FORCES PROBE: a different population must never write the 40// beat's ledger or cursor, or the coverage claim silently becomes about a subtree. 41// probe=1 run without writing ledger/cursor (stdout + verdict log only). 42// Every effective setting is printed WITH ITS PROVENANCE, because a run whose bounds cannot be read 43// back is a run whose coverage cannot be audited. 44// 45// license_tier: ORIGINAL 46import "nx_syscalls.nx" 47import "nx_dir.nx" 48import "nx_tool_run.nx" 49import "nx_lineconf_lib.nx" 50import "nx_sitesweep_lib.nx" 51 52// ---- this organ's own artifact identities (NOT tunables: a missing conf must still produce an honest 53// verdict artifact, so these cannot live in the conf they would have to read first) ------------------ 54const SS_CONF: *u8 = "knowledge/sitesweep.conf" 55const SS_LOG: *u8 = "knowledge/status/sitesweep.log" 56const SS_LEDGER: *u8 = "knowledge/status/sitesweep.ledger" 57const SS_CURSOR: *u8 = "knowledge/status/sitesweep.cursor" 58// A PROBE MUST NOT OVERWRITE THE BEAT'S PUBLISHED VERDICT EITHER. Measured 2026-08-25: the ledger and 59// the cursor were correctly protected in probe mode and the LOG was not, so a subtree probe silently 60// replaced the whole-site answer with a six-page one -- the same defect the probe guard exists to 61// prevent, left in the one artifact a consumer actually reads. A GUARD APPLIED TO TWO OF THREE 62// ARTIFACTS IS NOT A GUARD, AND THE ONE LEFT OUT WAS THE PUBLISHED ONE. 63const SS_LOG_PROBE: *u8 = "knowledge/status/sitesweep.probe.log" 64 65// ---- exits. 0/1 keep their fleet meaning; 3 is the fleet SKIP/UNOBSERVABLE code (nx_gate_verdict 66// returns 3 and /api/gate_run maps 3 -> SKIP, excluded from RED); 4 = could not even configure. ------ 67const SS_EXIT_GREEN: i64 = 0 68const SS_EXIT_RED: i64 = 1 69const SS_EXIT_USAGE: i64 = 2 70const SS_EXIT_NOEVIDENCE: i64 = 3 71const SS_EXIT_UNMEASURED: i64 = 4 72 73// ---- enumeration bounds. Every one ANNOUNCES on contact and forces enum_complete=0; a cap reached in 74// silence becomes a measurement nobody knows is partial. ---------------------------------------------- 75// SS_DIR_ENTRIES_CAP: the largest directory MEASURED in this docroot is compare/atlas/card at 33,243 76// entries (2026-08-25). 65536 is about 2x that measured maximum, and NX_DIR_TRUNCATED is checked. 77const SS_DIR_ENTRIES_CAP: i64 = 65536 78const SS_DIR_NAME_ARENA: i64 = 8388608 79const SS_MAX_PAGES: i64 = 131072 80const SS_MAX_DIRS: i64 = 16384 81const SS_PATH_CAP: i64 = 1024 82const SS_PAGE_ARENA: i64 = 16777216 83const SS_DIR_ARENA: i64 = 4194304 84// SS_CAPTURE_CAP: worst case is nx_page_verify's own PV_MAXREF=256 refs at roughly 500 bytes of 85// per-asset TLS/decode trace each, about 128 KB. 8x that, because what a cut destroys is the TAIL, and 86// the tail is where VERDICT lives. mmap faults pages in on demand: headroom costs address space, not RSS. 87const SS_CAPTURE_CAP: i64 = 1048576 88const SS_LEDGER_LINE: i64 = 1024 89// SS_LEDGER_ARENA: rows measure about 170 B in practice; 48 MB covers SS_MAX_PAGES of them with margin, 90// and the writer checks the remaining room before every row rather than trusting the estimate. 91const SS_LEDGER_ARENA: i64 = 50331648 92const SS_ARGV_MAX: i64 = 64 93const SS_MS_PER_S: i64 = 1000 94const SS_STAT_SLOTS: i64 = 16 95const SS_SEP_BYTES: i64 = 2 96 97// ---- conf fallbacks. Present ONLY so a torn conf degrades to a STATED default instead of a crash; the 98// run prints keys_defaulted so a silent fallback is impossible. --------------------------------------- 99// SS_DEADLINE_DEFAULT_S is DERIVED, not chosen: the clock scheduler kills a job at its 1800 s window 100// (measured 2026-08-22, the compare beat exiting 124 inside a job stampede). 1440 s is 800 permil of 101// that window, leaving a full 360 s of margin on a loaded box. A bound above the window would make the 102// run's own cursor write unreachable -- the sweep would do the work and lose the record of having done it. 103const SS_DEADLINE_DEFAULT_S: i64 = 1440 104const SS_PAGE_TIMEOUT_DEF_MS: i64 = 120000 105const SS_MAX_LIVE_DEFAULT: i64 = 100000 106 107// ---- CONF KEYS ARE SPELLED WITHOUT THE TRAILING '=' ON PURPOSE. lcf_find matches the key at a line 108// start and then requires the '=' ITSELF, so a key written "docroot=" asks for "docroot==" and misses. 109// MEASURED 2026-08-25 on the first live run: every one of the eight settings fell back to its default 110// while the run printed values that LOOKED right, because two of the defaults happened to equal the 111// conf's real values. A FORMAT MISMATCH FAILS AS A CONFIDENT WRONG ANSWER, NOT AS AN ERROR -- read the 112// parser's contract before choosing the producer's spelling. keys_defaulted is printed so the next 113// occurrence is visible in one number instead of invisible in eight. 114const SS_K_DOCROOT: *u8 = "docroot" 115const SS_K_ORIGIN: *u8 = "origin" 116const SS_K_RULER: *u8 = "ruler_elf" 117const SS_K_VANTAGE: *u8 = "vantage" 118const SS_K_DEADL: *u8 = "deadline_s" 119const SS_K_PTMO: *u8 = "page_timeout_ms" 120const SS_K_MAXLIVE: *u8 = "max_live" 121const SS_K_BEAT: *u8 = "beat_secs" 122 123func ow(s: *u8) -> i64 { sys_write(1, s, ss_len(s)); return 0 } 124func on(v: i64) -> i64 { 125 let t: *u8 = sys_mmap(SS_SCRATCH) 126 var m: i64 = v 127 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 128 var k: i64 = 0 129 if m == 0 { t[0] = SS_CH_ZERO as u8; k = 1 } 130 while m > 0 { t[k] = (SS_CH_ZERO + (m % SS_DEC)) as u8; m = m / SS_DEC; k = k + 1 } 131 let b: *u8 = sys_mmap(SS_SCRATCH) 132 var j: i64 = 0 133 while j < k { b[j] = t[k - 1 - j]; j = j + 1 } 134 sys_write(1, b, k) 135 sys_munmap(t, SS_SCRATCH); sys_munmap(b, SS_SCRATCH) 136 return 0 137} 138 139// ===================================================================================================== 140// RUN THE RULER ON ONE PAGE. Fork + bounded capture; the JUDGEMENT is ss_parse_ruler in the shared lib. 141// ===================================================================================================== 142func ss_verify(ruler: *u8, url: *u8, vantage: *u8, cap_buf: *u8, timeout_ms: i64, outv: *i64) -> i64 { 143 let t0: i64 = sys_now_ms() 144 let av: *i64 = sys_mmap(SS_ARGV_MAX) as *i64 145 av[0] = ruler as i64 146 av[1] = url as i64 147 var an: i64 = 2 148 if vantage[0] != (0 as u8) { av[2] = vantage as i64; an = 3 } 149 av[an] = 0 150 let lenp: *i64 = sys_mmap(SS_WORD * 2) as *i64 151 let trp: *i64 = sys_mmap(SS_WORD * 2) as *i64 152 trp[0] = 0 153 lenp[0] = 0 154 tr_run_capture_tr(ruler, av, cap_buf, SS_CAPTURE_CAP, lenp, timeout_ms, trp) 155 let cl: i64 = ss_parse_ruler(cap_buf, lenp[0], trp[0], outv) 156 outv[SS_V_MS] = sys_now_ms() - t0 157 sys_munmap(av as *u8, SS_ARGV_MAX) 158 sys_munmap(lenp as *u8, SS_WORD * 2) 159 sys_munmap(trp as *u8, SS_WORD * 2) 160 return cl 161} 162 163// ===================================================================================================== 164// THE WALK. Breadth-first over the docroot; every regular file ending .html is a servable page. 165// Order is part of the coverage claim, so it is STATED: breadth-first means shallow curated pages are 166// examined before deep generated trees, and the cursor rotates through the whole list either way. 167// st[0]=dirs_visited st[1]=entries_seen st[2]=other_entries st[3]=dir_truncated st[4]=dirs_capped 168// st[5]=pages_capped st[6]=arena_capped st[7]=dir_open_failed 169// ===================================================================================================== 170func ss_walk(root: *u8, pg_off: *i64, pg_arena: *u8, st: *i64) -> i64 { 171 let dq_off: *i64 = sys_mmap(SS_MAX_DIRS * SS_WORD) as *i64 172 let dq_arena: *u8 = sys_mmap(SS_DIR_ARENA) 173 var dqn: i64 = 1 174 dq_off[0] = 0 175 var dqa: i64 = ss_cat(dq_arena, 0, root) 176 dq_arena[dqa] = 0 as u8 177 dqa = dqa + 1 178 179 let rows: *NxDirRow = sys_mmap(SS_DIR_ENTRIES_CAP * NX_DIR_ROW_BYTES) as *NxDirRow 180 let names: *u8 = sys_mmap(SS_DIR_NAME_ARENA) 181 let res: *NxDirResult = sys_mmap(NX_DIR_RESULT_BYTES) as *NxDirResult 182 183 var pn: i64 = 0 184 var pa: i64 = 0 185 var di: i64 = 0 186 while di < dqn { 187 let dpath: *u8 = ((dq_arena as i64) + dq_off[di]) as *u8 188 let dlen: i64 = ss_len(dpath) 189 let v: i64 = nx_dir_list(dpath, rows, SS_DIR_ENTRIES_CAP, names, SS_DIR_NAME_ARENA, 0, res) 190 st[0] = st[0] + 1 191 if v == NX_DIR_OPEN_FAILED { st[7] = st[7] + 1 } 192 if v == NX_DIR_TRUNCATED { st[3] = st[3] + 1 } 193 if v == NX_DIR_NAME_ARENA_EXHAUSTED { st[3] = st[3] + 1 } 194 let nf: i64 = res.n_filled 195 var k: i64 = 0 196 while k < nf { 197 let row: *NxDirRow = nx_dir_row_at(rows, k) 198 st[1] = st[1] + 1 199 if nx_dir_row_is_subdirectory(row) == 1 { 200 if dqn >= SS_MAX_DIRS { st[4] = st[4] + 1 } else { 201 if dqa + dlen + row.name_len + SS_SEP_BYTES >= SS_DIR_ARENA { st[4] = st[4] + 1 } else { 202 dq_off[dqn] = dqa 203 var o: i64 = ss_cat(dq_arena, dqa, dpath) 204 dq_arena[o] = SS_CH_SLASH as u8; o = o + 1 205 o = ss_cat(dq_arena, o, row.name_ptr) 206 dq_arena[o] = 0 as u8 207 dqa = o + 1 208 dqn = dqn + 1 209 } 210 } 211 st[2] = st[2] + 1 212 } else { 213 if nx_dir_row_is_regular_file(row) == 1 { 214 if ss_ends_html(row.name_ptr) == 1 { 215 if pn >= SS_MAX_PAGES { st[5] = st[5] + 1; st[2] = st[2] + 1 } else { 216 if pa + dlen + row.name_len + SS_SEP_BYTES >= SS_PAGE_ARENA { st[6] = st[6] + 1; st[2] = st[2] + 1 } else { 217 pg_off[pn] = pa 218 var q: i64 = ss_cat(pg_arena, pa, dpath) 219 pg_arena[q] = SS_CH_SLASH as u8; q = q + 1 220 q = ss_cat(pg_arena, q, row.name_ptr) 221 pg_arena[q] = 0 as u8 222 pa = q + 1 223 pn = pn + 1 224 } 225 } 226 } else { st[2] = st[2] + 1 } 227 } else { st[2] = st[2] + 1 } 228 } 229 k = k + 1 230 } 231 di = di + 1 232 } 233 sys_munmap(rows as *u8, SS_DIR_ENTRIES_CAP * NX_DIR_ROW_BYTES) 234 sys_munmap(names, SS_DIR_NAME_ARENA) 235 sys_munmap(dq_off as *u8, SS_MAX_DIRS * SS_WORD) 236 sys_munmap(dq_arena, SS_DIR_ARENA) 237 return pn 238} 239 240// ===================================================================================================== 241// The list's comment marker, named because the nx_cc lexer refuses that byte inside a string literal. 242const SS_LIST_COMMENT: i64 = 35 243 244// ENUMERATION FROM A NAMED LIST (2026-08-26). ss_walk answers -every servable page under here-, which 245// is the right question for the beat and the WRONG one for a named population. MEASURED THE DAY THIS 246// WAS ADDED: root=compare enumerates 17,555 pages, of which the 89 compare DOMAIN pages are 5 permil, 247// so a 900 s cursor-ordered run examined 168 pages -- every one of them a mirrored third-party 248// reference document -- and answered nothing at all about the domains it was pointed at. 249// A POPULATION INSTRUMENT AIMED AT THE WRONG POPULATION IS NOT A MEASUREMENT, IT IS LOAD. 250// One docroot-relative page path per line. Blank and commented lines are counted as other_entries so 251// the ENUM PARTITION still sums, and every cap still announces and still forces enum_complete=0. 252// The population is DATA, so any caller can name one and get the same reconciled partition over it. 253func ss_from_list(listpath: *u8, pg_off: *i64, pg_arena: *u8, st: *i64) -> i64 { 254 let lp: *i64 = sys_mmap(SS_WORD * 2) as *i64 255 let buf: *u8 = sys_read_file(listpath, lp) 256 if (buf as i64) == 0 { st[7] = st[7] + 1; return 0 } 257 let n: i64 = lp[0] 258 var npages: i64 = 0 259 var ao: i64 = 0 260 var ls: i64 = 0 261 while ls < n { 262 var le: i64 = ls 263 while le < n { 264 if (buf[le] as i64) == SS_CH_NL { break } 265 le = le + 1 266 } 267 var e2: i64 = le 268 if e2 > ls { if (buf[e2-1] as i64) == SS_CH_CR { e2 = e2 - 1 } } 269 st[1] = st[1] + 1 270 var keep: i64 = 1 271 if e2 <= ls { keep = 0 } 272 if keep == 1 { if (buf[ls] as i64) == SS_LIST_COMMENT { keep = 0 } } 273 if keep == 1 { if npages >= SS_MAX_PAGES { st[5] = st[5] + 1; keep = 0 } } 274 if keep == 1 { if ao + (e2 - ls) + 1 >= SS_PAGE_ARENA { st[6] = st[6] + 1; keep = 0 } } 275 if keep == 1 { 276 pg_off[npages] = ao 277 var k: i64 = ls 278 while k < e2 { pg_arena[ao] = buf[k]; ao = ao + 1; k = k + 1 } 279 pg_arena[ao] = 0 as u8 280 ao = ao + 1 281 npages = npages + 1 282 } 283 if keep == 0 { st[2] = st[2] + 1 } 284 ls = le + 1 285 } 286 sys_free_file(buf, n) 287 return npages 288} 289 290func main(argc: i64, argv: *i64) -> i64 { 291 ow("=== nx_sitesweep -- how many pages on our public site serve broken assets? ===\n" as *u8) 292 293 // ---- argv ------------------------------------------------------------------------------------ 294 let a_root: *u8 = sys_mmap(SS_PATH_CAP) 295 a_root[0] = 0 as u8 296 let a_list: *u8 = sys_mmap(SS_PATH_CAP) 297 a_list[0] = 0 as u8 298 var a_deadline: i64 = 0 - 1 299 var a_max: i64 = 0 - 1 300 var a_cursor: i64 = 0 - 1 301 var probe: i64 = 0 302 var ai: i64 = 1 303 while ai < argc { 304 let a: *u8 = argv[ai] as *u8 305 let ro: i64 = ss_pfx(a, "root=" as *u8) 306 let li: i64 = ss_pfx(a, "list=" as *u8) 307 let de: i64 = ss_pfx(a, "deadline=" as *u8) 308 let mx: i64 = ss_pfx(a, "max=" as *u8) 309 let cu: i64 = ss_pfx(a, "cursor=" as *u8) 310 let pb: i64 = ss_pfx(a, "probe=" as *u8) 311 if ro >= 0 { let ae: i64 = ss_cat(a_root, 0, ((a as i64) + ro) as *u8); a_root[ae] = 0 as u8 } else { 312 if li >= 0 { let le3: i64 = ss_cat(a_list, 0, ((a as i64) + li) as *u8); a_list[le3] = 0 as u8 } else { 313 if de >= 0 { a_deadline = ss_int_at(a, ss_len(a), de) } else { 314 if mx >= 0 { a_max = ss_int_at(a, ss_len(a), mx) } else { 315 if cu >= 0 { a_cursor = ss_int_at(a, ss_len(a), cu) } else { 316 if pb >= 0 { probe = ss_int_at(a, ss_len(a), pb) } else { 317 ow("usage: nx_sitesweep [root=<subpath>] [list=<file>] [deadline=<secs>] [max=<pages>] [cursor=<n>] [probe=1]\n" as *u8) 318 sys_exit(SS_EXIT_USAGE); return SS_EXIT_USAGE 319 } } } } } } 320 ai = ai + 1 321 } 322 // Set AFTER the loop so no argv ordering (root=x probe=0) can turn the guard off: A GUARD THAT 323 // ARGV ORDER CAN DEFEAT IS NOT A GUARD. 324 if a_root[0] != (0 as u8) { probe = 1 } 325 // A NAMED LIST IS A DIFFERENT POPULATION, so it must never write the beat's ledger, cursor or 326 // published log either -- a coverage claim about 89 named pages silently replacing the whole-site 327 // answer is exactly the defect the probe guard exists to prevent. 328 if a_list[0] != (0 as u8) { probe = 1 } 329 330 // ---- conf. FAIL FAST: a missing conf is a real misconfiguration, and a sweep that invents its own 331 // population bounds is a sweep whose coverage nobody can audit. -------------------------------- 332 let clp: *i64 = sys_mmap(SS_WORD * 2) as *i64 333 let cbuf: *u8 = sys_read_file(SS_CONF, clp) 334 if (cbuf as i64) == 0 { 335 ow("REFUSE conf-absent path=" as *u8); ow(SS_CONF); ow("\n" as *u8) 336 ow("verdict=RED\n" as *u8) 337 sys_exit(SS_EXIT_UNMEASURED); return SS_EXIT_UNMEASURED 338 } 339 let cn: i64 = clp[0] 340 let docroot: *u8 = sys_mmap(SS_PATH_CAP) 341 let origin: *u8 = sys_mmap(SS_PATH_CAP) 342 let ruler: *u8 = sys_mmap(SS_PATH_CAP) 343 let vantage: *u8 = sys_mmap(SS_PATH_CAP) 344 var miss: i64 = 0 345 if lcf_str(cbuf, cn, SS_K_DOCROOT, docroot, SS_PATH_CAP) < 0 { let d0: i64 = ss_cat(docroot, 0, "sites/nishifamily" as *u8); docroot[d0] = 0 as u8; miss = miss + 1 } 346 if lcf_str(cbuf, cn, SS_K_ORIGIN, origin, SS_PATH_CAP) < 0 { let d1: i64 = ss_cat(origin, 0, "https://nishifamily.com" as *u8); origin[d1] = 0 as u8; miss = miss + 1 } 347 if lcf_str(cbuf, cn, SS_K_RULER, ruler, SS_PATH_CAP) < 0 { let d2: i64 = ss_cat(ruler, 0, "nx_page_verify.elf" as *u8); ruler[d2] = 0 as u8; miss = miss + 1 } 348 if lcf_str(cbuf, cn, SS_K_VANTAGE, vantage, SS_PATH_CAP) < 0 { vantage[0] = 0 as u8; miss = miss + 1 } 349 var deadline_s: i64 = lcf_int(cbuf, cn, SS_K_DEADL) 350 var ptmo_ms: i64 = lcf_int(cbuf, cn, SS_K_PTMO) 351 var max_live: i64 = lcf_int(cbuf, cn, SS_K_MAXLIVE) 352 var beat_s: i64 = lcf_int(cbuf, cn, SS_K_BEAT) 353 var dl_src: *u8 = "conf" as *u8 354 var mx_src: *u8 = "conf" as *u8 355 if deadline_s == LCF_MISS { deadline_s = SS_DEADLINE_DEFAULT_S; dl_src = "derived-default" as *u8; miss = miss + 1 } 356 if ptmo_ms == LCF_MISS { ptmo_ms = SS_PAGE_TIMEOUT_DEF_MS; miss = miss + 1 } 357 if max_live == LCF_MISS { max_live = SS_MAX_LIVE_DEFAULT; mx_src = "derived-default" as *u8; miss = miss + 1 } 358 if beat_s == LCF_MISS { beat_s = 0 - 1; miss = miss + 1 } 359 if a_deadline > 0 { deadline_s = a_deadline; dl_src = "argv" as *u8 } 360 if a_max > 0 { max_live = a_max; mx_src = "argv" as *u8 } 361 362 let sweeproot: *u8 = sys_mmap(SS_PATH_CAP) 363 var sr: i64 = ss_cat(sweeproot, 0, docroot) 364 if a_root[0] != (0 as u8) { 365 sweeproot[sr] = SS_CH_SLASH as u8; sr = sr + 1 366 sr = ss_cat(sweeproot, sr, a_root) 367 } 368 sweeproot[sr] = 0 as u8 369 let docroot_len: i64 = ss_len(docroot) 370 371 ow("conf=" as *u8); ow(SS_CONF); ow(" keys_defaulted=" as *u8); on(miss) 372 ow(" (a NON-ZERO value here means a conf row was NOT read -- the defaults can coincide with the\n" as *u8) 373 ow(" conf values and then a total parse failure looks exactly like a working conf)\n" as *u8) 374 ow("docroot=" as *u8); ow(docroot); ow(" origin=" as *u8); ow(origin); ow("\n" as *u8) 375 ow("sweeproot=" as *u8) 376 if a_list[0] == (0 as u8) { ow(sweeproot) } 377 if a_list[0] != (0 as u8) { ow("(named list) " as *u8); ow(a_list) } 378 ow(" ruler=" as *u8); ow(ruler) 379 ow(" vantage=" as *u8) 380 if vantage[0] == (0 as u8) { ow("(ruler auto-override)" as *u8) } else { ow(vantage) } 381 ow("\n" as *u8) 382 ow("deadline_s=" as *u8); on(deadline_s); ow(" src=" as *u8); ow(dl_src) 383 ow(" max_live=" as *u8); on(max_live); ow(" src=" as *u8); ow(mx_src) 384 ow(" page_timeout_ms=" as *u8); on(ptmo_ms) 385 ow(" beat_secs=" as *u8); on(beat_s) 386 ow(" mode=" as *u8) 387 if probe == 1 { ow("PROBE (ledger and cursor NOT written)\n" as *u8) } else { ow("BEAT\n" as *u8) } 388 389 // ---- the ruler must exist before we grade anything with it: AN ABSENT ARTIFACT IS 390 // INDISTINGUISHABLE FROM A DEAD REMOTE SERVER once you are only reading exit codes. ------------- 391 let rfd: i64 = sys_openat_rd(ruler) 392 if rfd < 0 { 393 ow("REFUSE ruler-absent path=" as *u8); ow(ruler) 394 ow(" -- every page would report UNREADABLE and the sweep would look like a fleet-wide outage\n" as *u8) 395 ow("verdict=RED\n" as *u8) 396 sys_exit(SS_EXIT_UNMEASURED); return SS_EXIT_UNMEASURED 397 } 398 sys_close(rfd) 399 400 // ---- enumerate -------------------------------------------------------------------------------- 401 let pg_off: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 402 let pg_arena: *u8 = sys_mmap(SS_PAGE_ARENA) 403 let st: *i64 = sys_mmap(SS_WORD * SS_STAT_SLOTS) as *i64 404 var z: i64 = 0 405 while z < SS_STAT_SLOTS { st[z] = 0; z = z + 1 } 406 let t_enum: i64 = sys_now_ms() 407 var npages: i64 = 0 408 if a_list[0] == (0 as u8) { npages = ss_walk(sweeproot, pg_off, pg_arena, st) } 409 if a_list[0] != (0 as u8) { npages = ss_from_list(a_list, pg_off, pg_arena, st) } 410 let enum_ms: i64 = sys_now_ms() - t_enum 411 412 var enum_complete: i64 = 1 413 if st[3] > 0 { enum_complete = 0 } 414 if st[4] > 0 { enum_complete = 0 } 415 if st[5] > 0 { enum_complete = 0 } 416 if st[6] > 0 { enum_complete = 0 } 417 if st[7] > 0 { enum_complete = 0 } 418 419 ow("-- enumeration --\n" as *u8) 420 ow(" dirs_visited=" as *u8); on(st[0]) 421 ow(" entries_seen=" as *u8); on(st[1]) 422 ow(" pages_found=" as *u8); on(npages) 423 ow(" other_entries=" as *u8); on(st[2]) 424 ow(" ms=" as *u8); on(enum_ms); ow("\n" as *u8) 425 ow(" ENUM PARTITION entries_seen=" as *u8); on(st[1]) 426 ow(" = pages_found " as *u8); on(npages) 427 ow(" + other_entries " as *u8); on(st[2]) 428 ow(" ; sum=" as *u8); on(npages + st[2]) 429 ow(" reconciles=" as *u8) 430 if npages + st[2] == st[1] { ow("1" as *u8) } else { ow("0" as *u8) } 431 ow("\n" as *u8) 432 ow(" enum_complete=" as *u8); on(enum_complete) 433 ow(" dir_truncated=" as *u8); on(st[3]) 434 ow(" dirs_capped=" as *u8); on(st[4]) 435 ow(" pages_capped=" as *u8); on(st[5]) 436 ow(" arena_capped=" as *u8); on(st[6]) 437 ow(" dir_open_failed=" as *u8); on(st[7]); ow("\n" as *u8) 438 if npages <= 0 { 439 ow("SUBJECTS=0 -- no servable page under " as *u8); ow(sweeproot) 440 ow(". A zero population is the ABSENCE OF EVIDENCE about the site, not a pass.\n" as *u8) 441 ow("verdict=RED\n" as *u8) 442 sys_exit(SS_EXIT_NOEVIDENCE); return SS_EXIT_NOEVIDENCE 443 } 444 445 // ---- per-page state; carried forward from the previous ledger where this run does not re-check -- 446 let pg_cls: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 447 let pg_brk: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 448 let pg_ref: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 449 let pg_law: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 450 let pg_at: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 451 // Accessibility and coverage per page. INITIALISED TO -1, NOT 0: a page this run did not check has 452 // not been acquitted of anything, and a zeroed arena would quietly read as a clean bill of health 453 // for every page in the population. 454 let pg_a11: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 455 let pg_gap: *i64 = sys_mmap(SS_MAX_PAGES * SS_WORD) as *i64 456 var az: i64 = 0 457 while az < npages { pg_a11[az] = 0 - 1; pg_gap[az] = 0 - 1; az = az + 1 } 458 var p: i64 = 0 459 while p < npages { pg_cls[p] = SS_C_UNCHECKED; pg_brk[p] = 0; pg_ref[p] = 0 - 1; pg_law[p] = 0; pg_at[p] = 0; p = p + 1 } 460 461 var carried: i64 = 0 462 var resync: i64 = 0 463 if probe == 0 { 464 let llp: *i64 = sys_mmap(SS_WORD * 2) as *i64 465 let lbuf: *u8 = sys_read_file(SS_LEDGER, llp) 466 if (lbuf as i64) != 0 { 467 let ln: i64 = llp[0] 468 var ls: i64 = 0 469 var idx: i64 = 0 470 while ls < ln { 471 var le: i64 = ls 472 while le < ln { if lbuf[le] == (SS_CH_NL as u8) { break } le = le + 1 } 473 if le > ls { 474 if idx < npages { 475 let po: i64 = ss_field(lbuf, ls, le, " page=" as *u8) 476 var okrow: i64 = 0 477 if po >= 0 { if ss_tok_eq(lbuf, le, po, ((pg_arena as i64) + pg_off[idx]) as *u8) == 1 { okrow = 1 } } 478 if okrow == 1 { 479 let co: i64 = ss_field(lbuf, ls, le, " class=" as *u8) 480 if co >= 0 { 481 let cv: i64 = ss_class_of_name(((lbuf as i64) + co) as *u8) 482 pg_cls[idx] = cv 483 if cv != SS_C_UNCHECKED { carried = carried + 1 } 484 } 485 let bo: i64 = ss_field(lbuf, ls, le, " broken=" as *u8) 486 if bo >= 0 { let bv: i64 = ss_int_at(lbuf, le, bo); if bv >= 0 { pg_brk[idx] = bv } } 487 let ro2: i64 = ss_field(lbuf, ls, le, " refs=" as *u8) 488 if ro2 >= 0 { let rv: i64 = ss_int_at(lbuf, le, ro2); if rv >= 0 { pg_ref[idx] = rv } } 489 let wo: i64 = ss_field(lbuf, ls, le, " law=" as *u8) 490 if wo >= 0 { let wv: i64 = ss_int_at(lbuf, le, wo); if wv >= 0 { pg_law[idx] = wv } } 491 let ao: i64 = ss_field(lbuf, ls, le, " at=" as *u8) 492 if ao >= 0 { let av2: i64 = ss_int_at(lbuf, le, ao); if av2 >= 0 { pg_at[idx] = av2 } } 493 } else { resync = resync + 1 } 494 } 495 idx = idx + 1 496 } 497 ls = le + 1 498 } 499 sys_free_file(lbuf, ln) 500 ow("-- ledger carry-forward --\n" as *u8) 501 ow(" prior_rows=" as *u8); on(idx) 502 ow(" carried=" as *u8); on(carried) 503 ow(" resynced=" as *u8); on(resync) 504 ow(" (a row whose page= does not match the enumerated path at its index is DROPPED, never\n" as *u8) 505 ow(" trusted: the page list shifted under it, and an index is not an identity)\n" as *u8) 506 } else { ow("-- ledger carry-forward -- no prior ledger (first run)\n" as *u8) } 507 } 508 509 // ---- the slice --------------------------------------------------------------------------------- 510 var cur: i64 = 0 511 if probe == 0 { 512 let cup: *i64 = sys_mmap(SS_WORD * 2) as *i64 513 let cbf: *u8 = sys_read_file(SS_CURSOR, cup) 514 if (cbf as i64) != 0 { let cv2: i64 = ss_int_at(cbf, cup[0], 0); if cv2 >= 0 { cur = cv2 } sys_free_file(cbf, cup[0]) } 515 } 516 if a_cursor >= 0 { cur = a_cursor } 517 if cur >= npages { cur = 0 } 518 if cur < 0 { cur = 0 } 519 520 let cap_buf: *u8 = sys_mmap(SS_CAPTURE_CAP) 521 let outv: *i64 = sys_mmap(SS_WORD * SS_V_N) as *i64 522 let url: *u8 = sys_mmap(SS_PATH_CAP * 2) 523 let deadline_ms: i64 = deadline_s * SS_MS_PER_S 524 let t0: i64 = sys_now_ms() 525 var i: i64 = cur 526 var visited: i64 = 0 527 var live: i64 = 0 528 var prefilter_unreadable: i64 = 0 529 var prefilter_vetoed: i64 = 0 530 var stop_reason: *u8 = "population-exhausted" as *u8 531 ow("-- slice --\n" as *u8) 532 ow(" cursor_start=" as *u8); on(cur); ow(" of pages_found=" as *u8); on(npages); ow("\n" as *u8) 533 while visited < npages { 534 if sys_now_ms() - t0 >= deadline_ms { stop_reason = "deadline" as *u8; break } 535 if live >= max_live { stop_reason = "max_live" as *u8; break } 536 let path: *u8 = ((pg_arena as i64) + pg_off[i]) as *u8 537 let flp: *i64 = sys_mmap(SS_WORD * 2) as *i64 538 let fb: *u8 = sys_read_file(path, flp) 539 var may: i64 = 1 540 if (fb as i64) == 0 { prefilter_unreadable = prefilter_unreadable + 1 } else { 541 may = ss_may_have_refs(fb, flp[0]) 542 sys_free_file(fb, flp[0]) 543 } 544 sys_munmap(flp as *u8, SS_WORD * 2) 545 // THE PREFILTER READS THE FILE ON DISK; THE RULER CHECKS THE PAGE THE EDGE SERVES. Wherever the 546 // edge INJECTS markup those are two different documents, and the prefilter is then wrong in the 547 // FLATTERING direction -- no_refs is a clean bucket, so a page whose only asset arrives by 548 // injection is skipped and counted as having had nothing to check. 549 // MEASURED 2026-08-26 on the very first list= run: 83 of the 89 compare DOMAIN pages were 550 // vetoed as no_refs, because their sole img is an ad slot injected at serve time. The whole-site 551 // sweep had therefore never checked the SERVED form of any of them, and said so nowhere. 552 // A NAMED LIST IS AN EXPLICIT POPULATION, so the veto is dropped there: the caller has already 553 // decided what to spend the budget on, and deadline/max still bound the run. The BEAT keeps the 554 // veto, because removing it there multiplies its live checks and that is a LOAD decision for an 555 // operator, not a correctness fix to take unilaterally. Either way the count is now PRINTED, so 556 // the blindness is visible instead of hiding inside a clean bucket. 557 if may == 0 { prefilter_vetoed = prefilter_vetoed + 1 } 558 if a_list[0] != (0 as u8) { may = 1 } 559 if may == 0 { 560 pg_cls[i] = SS_C_NOREFS 561 pg_brk[i] = 0 562 pg_ref[i] = 0 563 pg_law[i] = 0 564 pg_at[i] = sys_now_realtime_sec() 565 } else { 566 ss_url_of(origin, docroot_len, path, url) 567 ss_verify(ruler, url, vantage, cap_buf, ptmo_ms, outv) 568 pg_cls[i] = outv[SS_V_CLASS] 569 pg_brk[i] = outv[SS_V_BROKEN] 570 pg_ref[i] = outv[SS_V_CHECKED] 571 pg_law[i] = outv[SS_V_LAW] 572 pg_at[i] = sys_now_realtime_sec() 573 pg_a11[i] = outv[SS_V_A11Y] 574 pg_gap[i] = outv[SS_V_COVGAP] 575 live = live + 1 576 if outv[SS_V_CLASS] == SS_C_BROKEN { 577 ow(" BROKEN " as *u8); ow(url) 578 ow(" broken=" as *u8); on(outv[SS_V_BROKEN]) 579 ow(" law=" as *u8); on(outv[SS_V_LAW]) 580 ow(" refs=" as *u8); on(outv[SS_V_CHECKED]) 581 ow(" ms=" as *u8); on(outv[SS_V_MS]); ow("\n" as *u8) 582 } 583 if outv[SS_V_CLASS] == SS_C_PAGERED { 584 ow(" PAGE-RED " as *u8); ow(url) 585 ow(" (the PAGE did not serve -- a publish or routing fault, NOT a broken asset)\n" as *u8) 586 } 587 // A COUNT WITHOUT A WORKLIST IS NOT ACTIONABLE, and the reason is already in hand here. 588 if outv[SS_V_A11Y] > 0 { 589 ow(" A11Y " as *u8); ow(url) 590 ow(" a11y-issues=" as *u8); on(outv[SS_V_A11Y]); ow("\n" as *u8) 591 } 592 if outv[SS_V_COVGAP] == 1 { 593 ow(" COVERAGE-GAP " as *u8); ow(url) 594 ow(" -- the ruler could not read every img src here, so its whole-page claim is UNPROVEN\n" as *u8) 595 } 596 } 597 visited = visited + 1 598 i = i + 1 599 if i >= npages { i = 0 } 600 } 601 let run_ms: i64 = sys_now_ms() - t0 602 let cursor_next: i64 = i 603 let deferred: i64 = npages - visited 604 605 // ---- tally. This IS the partition: every enumerated page is in exactly one bucket. ------------- 606 let bk: *i64 = sys_mmap(SS_WORD * SS_C_N) as *i64 607 var b: i64 = 0 608 while b < SS_C_N { bk[b] = 0; b = b + 1 } 609 var tot_broken_refs: i64 = 0 610 var tot_law: i64 = 0 611 // ACCESSIBILITY AND COVERAGE ARE THEIR OWN PARTITIONS, NOT MEMBERS OF THE CLASS PARTITION ABOVE. 612 // A page can be GREEN on every asset and still be one no reader can use, so folding either into the 613 // class buckets would silently break a reconcile that currently proves itself. 614 var a11_clean: i64 = 0 615 var a11_pages: i64 = 0 616 var a11_issues: i64 = 0 617 var a11_blind: i64 = 0 618 var gap_no: i64 = 0 619 var gap_yes: i64 = 0 620 var gap_blind: i64 = 0 621 p = 0 622 while p < npages { 623 bk[pg_cls[p]] = bk[pg_cls[p]] + 1 624 if pg_cls[p] == SS_C_BROKEN { tot_broken_refs = tot_broken_refs + pg_brk[p]; tot_law = tot_law + pg_law[p] } 625 if pg_a11[p] < 0 { a11_blind = a11_blind + 1 } 626 if pg_a11[p] == 0 { a11_clean = a11_clean + 1 } 627 if pg_a11[p] > 0 { a11_pages = a11_pages + 1; a11_issues = a11_issues + pg_a11[p] } 628 if pg_gap[p] < 0 { gap_blind = gap_blind + 1 } 629 if pg_gap[p] == 0 { gap_no = gap_no + 1 } 630 if pg_gap[p] == 1 { gap_yes = gap_yes + 1 } 631 p = p + 1 632 } 633 var sum: i64 = 0 634 b = 0 635 while b < SS_C_N { sum = sum + bk[b]; b = b + 1 } 636 let measured: i64 = npages - bk[SS_C_UNCHECKED] 637 var corpus_complete: i64 = 1 638 if enum_complete == 0 { corpus_complete = 0 } 639 if bk[SS_C_UNCHECKED] > 0 { corpus_complete = 0 } 640 let blind: i64 = bk[SS_C_UNOBSERVABLE] + bk[SS_C_UNMEASURED] + bk[SS_C_UNREADABLE] 641 642 // ---- build the report ONCE, print it, then write the SAME BYTES to the durable artifact. One 643 // producer, one text: a summary rendered twice can disagree with itself. ----------------------- 644 let rep: *u8 = sys_mmap(SS_LEDGER_ARENA) 645 var o: i64 = 0 646 o = ss_cat(rep, o, "NX-SITESWEEP epoch=" as *u8); o = ss_catn(rep, o, sys_now_realtime_sec()) 647 o = ss_cat(rep, o, " mode=" as *u8) 648 if probe == 1 { o = ss_cat(rep, o, "PROBE" as *u8) } else { o = ss_cat(rep, o, "BEAT" as *u8) } 649 o = ss_cat(rep, o, " sweeproot=" as *u8); o = ss_cat(rep, o, sweeproot) 650 o = ss_cat(rep, o, " origin=" as *u8); o = ss_cat(rep, o, origin) 651 o = ss_cat(rep, o, " ruler=" as *u8); o = ss_cat(rep, o, ruler) 652 o = ss_cat(rep, o, " keys_defaulted=" as *u8); o = ss_catn(rep, o, miss) 653 rep[o] = SS_CH_NL as u8; o = o + 1 654 655 o = ss_cat(rep, o, "PAGES pages_found=" as *u8); o = ss_catn(rep, o, npages) 656 o = ss_cat(rep, o, " = unchecked " as *u8); o = ss_catn(rep, o, bk[SS_C_UNCHECKED]) 657 o = ss_cat(rep, o, " + no_refs " as *u8); o = ss_catn(rep, o, bk[SS_C_NOREFS]) 658 o = ss_cat(rep, o, " + green " as *u8); o = ss_catn(rep, o, bk[SS_C_GREEN]) 659 o = ss_cat(rep, o, " + green_partial " as *u8); o = ss_catn(rep, o, bk[SS_C_PARTIAL]) 660 o = ss_cat(rep, o, " + broken " as *u8); o = ss_catn(rep, o, bk[SS_C_BROKEN]) 661 o = ss_cat(rep, o, " + page_red " as *u8); o = ss_catn(rep, o, bk[SS_C_PAGERED]) 662 o = ss_cat(rep, o, " + unobservable " as *u8); o = ss_catn(rep, o, bk[SS_C_UNOBSERVABLE]) 663 o = ss_cat(rep, o, " + unmeasured " as *u8); o = ss_catn(rep, o, bk[SS_C_UNMEASURED]) 664 o = ss_cat(rep, o, " + unreadable " as *u8); o = ss_catn(rep, o, bk[SS_C_UNREADABLE]) 665 o = ss_cat(rep, o, " ; partition_sum=" as *u8); o = ss_catn(rep, o, sum) 666 o = ss_cat(rep, o, " reconciles=" as *u8) 667 if sum == npages { o = ss_cat(rep, o, "1" as *u8) } else { o = ss_cat(rep, o, "0" as *u8) } 668 rep[o] = SS_CH_NL as u8; o = o + 1 669 670 o = ss_cat(rep, o, "ANSWER pages_serving_broken_assets=" as *u8); o = ss_catn(rep, o, bk[SS_C_BROKEN]) 671 o = ss_cat(rep, o, " broken_refs=" as *u8); o = ss_catn(rep, o, tot_broken_refs) 672 o = ss_cat(rep, o, " relative_ref_law_violations=" as *u8); o = ss_catn(rep, o, tot_law) 673 o = ss_cat(rep, o, " pages_not_serving=" as *u8); o = ss_catn(rep, o, bk[SS_C_PAGERED]) 674 rep[o] = SS_CH_NL as u8; o = o + 1 675 676 // DELIBERATELY NOT WIRED INTO THE VERDICT. This organ's exit code answers -how many pages serve 677 // broken assets-, and folding accessibility into it would turn a fleet-wide RED on the day it 678 // shipped -- the permanently-red detector everyone learns to ignore. It REPORTS, and the number is 679 // now visible and trended; arming it is a separate, decidable step on evidence. 680 o = ss_cat(rep, o, "A11Y pages_with_issues=" as *u8); o = ss_catn(rep, o, a11_pages) 681 o = ss_cat(rep, o, " issues_total=" as *u8); o = ss_catn(rep, o, a11_issues) 682 o = ss_cat(rep, o, " coverage_gap_pages=" as *u8); o = ss_catn(rep, o, gap_yes) 683 rep[o] = SS_CH_NL as u8; o = o + 1 684 685 o = ss_cat(rep, o, "A11Y PARTITION pages_found=" as *u8); o = ss_catn(rep, o, npages) 686 o = ss_cat(rep, o, " = clean " as *u8); o = ss_catn(rep, o, a11_clean) 687 o = ss_cat(rep, o, " + with_issues " as *u8); o = ss_catn(rep, o, a11_pages) 688 o = ss_cat(rep, o, " + not_audited " as *u8); o = ss_catn(rep, o, a11_blind) 689 o = ss_cat(rep, o, " ; sum=" as *u8); o = ss_catn(rep, o, a11_clean + a11_pages + a11_blind) 690 o = ss_cat(rep, o, " reconciles=" as *u8) 691 if a11_clean + a11_pages + a11_blind == npages { o = ss_cat(rep, o, "1" as *u8) } else { o = ss_cat(rep, o, "0" as *u8) } 692 rep[o] = SS_CH_NL as u8; o = o + 1 693 694 o = ss_cat(rep, o, "COVGAP PARTITION pages_found=" as *u8); o = ss_catn(rep, o, npages) 695 o = ss_cat(rep, o, " = no_gap " as *u8); o = ss_catn(rep, o, gap_no) 696 o = ss_cat(rep, o, " + gap " as *u8); o = ss_catn(rep, o, gap_yes) 697 o = ss_cat(rep, o, " + not_observed " as *u8); o = ss_catn(rep, o, gap_blind) 698 o = ss_cat(rep, o, " ; sum=" as *u8); o = ss_catn(rep, o, gap_no + gap_yes + gap_blind) 699 o = ss_cat(rep, o, " reconciles=" as *u8) 700 if gap_no + gap_yes + gap_blind == npages { o = ss_cat(rep, o, "1" as *u8) } else { o = ss_cat(rep, o, "0" as *u8) } 701 rep[o] = SS_CH_NL as u8; o = o + 1 702 703 o = ss_cat(rep, o, "COVERAGE measured=" as *u8); o = ss_catn(rep, o, measured) 704 o = ss_cat(rep, o, " of " as *u8); o = ss_catn(rep, o, npages) 705 o = ss_cat(rep, o, " corpus_complete=" as *u8); o = ss_catn(rep, o, corpus_complete) 706 o = ss_cat(rep, o, " partial=" as *u8) 707 if corpus_complete == 1 { o = ss_cat(rep, o, "0" as *u8) } else { o = ss_cat(rep, o, "1" as *u8) } 708 o = ss_cat(rep, o, " enum_complete=" as *u8); o = ss_catn(rep, o, enum_complete) 709 rep[o] = SS_CH_NL as u8; o = o + 1 710 711 o = ss_cat(rep, o, "RUN visited=" as *u8); o = ss_catn(rep, o, visited) 712 o = ss_cat(rep, o, " live_checks=" as *u8); o = ss_catn(rep, o, live) 713 o = ss_cat(rep, o, " deferred=" as *u8); o = ss_catn(rep, o, deferred) 714 o = ss_cat(rep, o, " cursor_start=" as *u8); o = ss_catn(rep, o, cur) 715 o = ss_cat(rep, o, " cursor_next=" as *u8); o = ss_catn(rep, o, cursor_next) 716 o = ss_cat(rep, o, " stop=" as *u8); o = ss_cat(rep, o, stop_reason) 717 o = ss_cat(rep, o, " run_ms=" as *u8); o = ss_catn(rep, o, run_ms) 718 o = ss_cat(rep, o, " enum_ms=" as *u8); o = ss_catn(rep, o, enum_ms) 719 o = ss_cat(rep, o, " prefilter_unreadable=" as *u8); o = ss_catn(rep, o, prefilter_unreadable) 720 o = ss_cat(rep, o, " prefilter_vetoed=" as *u8); o = ss_catn(rep, o, prefilter_vetoed) 721 o = ss_cat(rep, o, " prefilter_veto_honoured=" as *u8) 722 if a_list[0] == (0 as u8) { o = ss_cat(rep, o, "1" as *u8) } else { o = ss_cat(rep, o, "0-named-list" as *u8) } 723 o = ss_cat(rep, o, " ledger_carried=" as *u8); o = ss_catn(rep, o, carried) 724 o = ss_cat(rep, o, " ledger_resynced=" as *u8); o = ss_catn(rep, o, resync) 725 rep[o] = SS_CH_NL as u8; o = o + 1 726 727 // AN ABSTAINING AXIS NOBODY SEES IS A LIE NOBODY TOLD: blindness gets its own line so it can be 728 // alarmed on without moving the verdict in either direction. 729 o = ss_cat(rep, o, "AXIS-BLIND pages=" as *u8); o = ss_catn(rep, o, blind) 730 o = ss_cat(rep, o, " (unobservable+unmeasured+unreadable -- NEVER counted as broken; a sweep that\n" as *u8) 731 o = ss_cat(rep, o, " convicts a page it never reached is reporting on its own environment)\n" as *u8) 732 733 if deferred > 0 { 734 o = ss_cat(rep, o, "NOTE this run examined a DECLARED PREFIX of the population and advanced the cursor.\n" as *u8) 735 o = ss_cat(rep, o, " It is not a sample: full coverage is reached across beats and the ledger accumulates.\n" as *u8) 736 } 737 738 // the worklist travels with the count. wdrop is declared OUTSIDE the block so the truncation 739 // announcement below is in scope: a prefix that cannot say it is a prefix is a silent cap. 740 var wdrop: i64 = 0 741 if bk[SS_C_BROKEN] + bk[SS_C_PAGERED] > 0 { 742 o = ss_cat(rep, o, "-- WORKLIST --\n" as *u8) 743 p = 0 744 while p < npages { 745 var want: i64 = 0 746 if pg_cls[p] == SS_C_BROKEN { want = 1 } 747 if pg_cls[p] == SS_C_PAGERED { want = 1 } 748 if want == 1 { 749 if o + SS_LEDGER_LINE >= SS_LEDGER_ARENA { wdrop = wdrop + 1 } else { 750 let pth: *u8 = ((pg_arena as i64) + pg_off[p]) as *u8 751 ss_url_of(origin, docroot_len, pth, url) 752 o = ss_cat(rep, o, " " as *u8); o = ss_cat(rep, o, ss_class_name(pg_cls[p])) 753 o = ss_cat(rep, o, " " as *u8); o = ss_cat(rep, o, url) 754 o = ss_cat(rep, o, " broken=" as *u8); o = ss_catn(rep, o, pg_brk[p]) 755 o = ss_cat(rep, o, " law=" as *u8); o = ss_catn(rep, o, pg_law[p]) 756 o = ss_cat(rep, o, " refs=" as *u8); o = ss_catn(rep, o, pg_ref[p]) 757 o = ss_cat(rep, o, " at=" as *u8); o = ss_catn(rep, o, pg_at[p]) 758 o = ss_cat(rep, o, " src=" as *u8); o = ss_cat(rep, o, pth) 759 rep[o] = SS_CH_NL as u8; o = o + 1 760 } 761 } 762 p = p + 1 763 } 764 } 765 if wdrop > 0 { 766 o = ss_cat(rep, o, " <== THIS LIST IS A PREFIX OF ITS OWN COUNT: unlisted=" as *u8) 767 o = ss_catn(rep, o, wdrop) 768 rep[o] = SS_CH_NL as u8; o = o + 1 769 } 770 771 var green: i64 = 1 772 if bk[SS_C_BROKEN] > 0 { green = 0 } 773 if bk[SS_C_PAGERED] > 0 { green = 0 } 774 var rc: i64 = SS_EXIT_GREEN 775 if green == 0 { rc = SS_EXIT_RED } 776 if measured == 0 { 777 rc = SS_EXIT_NOEVIDENCE 778 o = ss_cat(rep, o, "NO EVIDENCE: not one page has a result, fresh or carried. This is the ABSENCE of a\n" as *u8) 779 o = ss_cat(rep, o, " measurement about the site, and it must not be spelled GREEN.\n" as *u8) 780 } 781 // CANONICAL LAST LINE, anchored by POSITION so a consumer never has to match text in the body. 782 o = ss_cat(rep, o, "verdict=" as *u8) 783 if measured == 0 { o = ss_cat(rep, o, "RED" as *u8) } else { 784 if green == 1 { o = ss_cat(rep, o, "GREEN" as *u8) } else { o = ss_cat(rep, o, "RED" as *u8) } 785 } 786 rep[o] = SS_CH_NL as u8; o = o + 1 787 788 // THE VERDICT LINE MUST BE THE LAST LINE ON STDOUT. Anything printed after the report body -- 789 // even a helpful one-liner naming the artifact -- moves the anchor a positional reader depends on. 790 // MEASURED 2026-08-25 on this organ's own first probe run: the artifact-path announce landed AFTER 791 // verdict= and made stdout unreadable by exactly the gv_last_line discipline the organ enforces 792 // everywhere else. So the announce goes FIRST, and the body -- ending in verdict= -- goes last. 793 var logp: *u8 = SS_LOG 794 if probe == 1 { logp = SS_LOG_PROBE } 795 ow("verdict artifact (TRUNCATE-written, canonical last line): " as *u8); ow(logp); ow("\n" as *u8) 796 sys_write(1, rep, o) 797 if ss_write_all(logp, rep, o) < 0 { ow("WARN could not write " as *u8); ow(logp); ow("\n" as *u8) } 798 799 // ---- ledger + cursor (beat mode only: a probe measures a different population and must never 800 // overwrite the beat's coverage record) --------------------------------------------------------- 801 if probe == 0 { 802 var lo2: i64 = 0 803 var ldrop: i64 = 0 804 p = 0 805 while p < npages { 806 if lo2 + SS_LEDGER_LINE >= SS_LEDGER_ARENA { ldrop = ldrop + 1 } else { 807 let pth2: *u8 = ((pg_arena as i64) + pg_off[p]) as *u8 808 ss_url_of(origin, docroot_len, pth2, url) 809 lo2 = ss_cat(rep, lo2, "idx=" as *u8); lo2 = ss_catn(rep, lo2, p) 810 lo2 = ss_cat(rep, lo2, " page=" as *u8); lo2 = ss_cat(rep, lo2, pth2) 811 lo2 = ss_cat(rep, lo2, " url=" as *u8); lo2 = ss_cat(rep, lo2, url) 812 lo2 = ss_cat(rep, lo2, " class=" as *u8); lo2 = ss_cat(rep, lo2, ss_class_name(pg_cls[p])) 813 lo2 = ss_cat(rep, lo2, " broken=" as *u8); lo2 = ss_catn(rep, lo2, pg_brk[p]) 814 lo2 = ss_cat(rep, lo2, " refs=" as *u8); lo2 = ss_catn(rep, lo2, pg_ref[p]) 815 lo2 = ss_cat(rep, lo2, " law=" as *u8); lo2 = ss_catn(rep, lo2, pg_law[p]) 816 lo2 = ss_cat(rep, lo2, " at=" as *u8); lo2 = ss_catn(rep, lo2, pg_at[p]) 817 rep[lo2] = SS_CH_NL as u8; lo2 = lo2 + 1 818 } 819 p = p + 1 820 } 821 if ldrop > 0 { 822 ow("LEDGER-ARENA-FULL rows_dropped=" as *u8); on(ldrop) 823 ow(" -- this ledger is a PREFIX of the population; raise SS_LEDGER_ARENA deliberately\n" as *u8) 824 } 825 if ss_write_all(SS_LEDGER, rep, lo2) < 0 { ow("WARN could not write " as *u8); ow(SS_LEDGER); ow("\n" as *u8) } 826 var co2: i64 = ss_catn(rep, 0, cursor_next) 827 rep[co2] = SS_CH_NL as u8; co2 = co2 + 1 828 if ss_write_all(SS_CURSOR, rep, co2) < 0 { ow("WARN could not write " as *u8); ow(SS_CURSOR); ow("\n" as *u8) } 829 } 830 831 sys_exit(rc) 832 return rc 833}