code wiki / (root) / nx_gate_verdict.nx

nx_gate_verdict.nx source

↩ module page · 906 lines · 44993 B

1// nx_gate_verdict.nx -- THE canonical gate-AUTHORING verdict lib (D001 first rung, 2026-07-18). 2// The debt: 2555 gate organs each hand-roll puts/num/pass/ttl/PASS-FAIL/verdict -- zero DRY. 3// This is the ONE copy gates import instead. Sibling of nx_gate_green.nx (which JUDGES a gate's 4// output from outside; this lib EMITS it from inside). Contract emitted: 5// " <check-name>: PASS\n" | " <check-name>: FAIL\n" per check 6// "\nNX-<GATE-NAME> passed <p>/<t> verdict=GREEN (<note>)\n" | " verdict=RED\n" 7// -- the exact shape nx_gate_green / nx_autograde already judge (anchor "verdict=", pat "GREEN"). 8// Usage: 9// let ctr: *i64 = gv_ctr() // [0]=pass [1]=ttl 10// gv_head("my gate -- what it proves") 11// gv_check("T1 the thing holds", t1_ok, ctr) // t1_ok: 1 pass, else fail 12// ... 13// let rc: i64 = gv_verdict("MY-GATE", ctr, "green note") // prints summary; 0 GREEN / 1 RED 14// sys_exit(rc) 15// license_tier: ORIGINAL No hw writes (Rule 26). 16import "nx_syscalls.nx" 17 18const GV_NL: i64 = 10 19 20// Named plans make completeness independent of the number of checks that happened to execute. 21// Layout: header(count, valid, undeclared); entries(name pointer, byte length, executions). 22const GV_PLAN_HEADER: i64 = 3 23const GV_PLAN_ENTRY: i64 = 3 24const GV_I64_BYTES: i64 = 8 25 26func gv_plan_name_eq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 { 27 if an != bn { return 0 } 28 var i: i64 = 0 29 while i < an { if a[i] != b[i] { return 0 }; i = i+1 } 30 return 1 31} 32func gv_plan_new(names: *u8) -> *i64 { 33 var size: i64 = 0 34 var count: i64 = 0 35 while names[size] != (0 as u8) { 36 if names[size] == (GV_NL as u8) { count = count+1 } 37 size = size+1 38 } 39 let plan: *i64 = sys_mmap(GV_I64_BYTES*(GV_PLAN_HEADER+GV_PLAN_ENTRY*count)) as *i64 40 plan[0]=count; plan[1]=1; plan[2]=0 41 if count == 0 { plan[1]=0 } 42 if size > 0 { if names[size-1] != (GV_NL as u8) { plan[1]=0 } } 43 var start: i64 = 0 44 var pos: i64 = 0 45 var row: i64 = 0 46 while pos < size { 47 if names[pos] == (GV_NL as u8) { 48 let cell: i64 = GV_PLAN_HEADER+GV_PLAN_ENTRY*row 49 plan[cell]=(names as i64)+start 50 plan[cell+1]=pos-start 51 plan[cell+2]=0 52 if pos == start { plan[1]=0 } 53 var previous: i64 = 0 54 while previous < row { 55 let old: i64 = GV_PLAN_HEADER+GV_PLAN_ENTRY*previous 56 if gv_plan_name_eq(plan[cell] as *u8,plan[cell+1],plan[old] as *u8,plan[old+1]) == 1 { plan[1]=0 } 57 previous=previous+1 58 } 59 row=row+1; start=pos+1 60 } 61 pos=pos+1 62 } 63 return plan 64} 65func gv_plan_take(plan: *i64, name: *u8) -> i64 { 66 var size: i64 = 0 67 while name[size] != (0 as u8) { size=size+1 } 68 var row: i64 = 0 69 while row < plan[0] { 70 let cell: i64 = GV_PLAN_HEADER+GV_PLAN_ENTRY*row 71 if gv_plan_name_eq(plan[cell] as *u8,plan[cell+1],name,size) == 1 { 72 plan[cell+2]=plan[cell+2]+1 73 return (plan[cell+2] == 1) as i64 74 } 75 row=row+1 76 } 77 plan[2]=plan[2]+1 78 return 0 79} 80func gv_plan_complete(plan: *i64) -> i64 { 81 if plan[1] != 1 { return 0 } 82 if plan[2] != 0 { return 0 } 83 var row: i64 = 0 84 while row < plan[0] { 85 if plan[GV_PLAN_HEADER+GV_PLAN_ENTRY*row+2] != 1 { return 0 } 86 row=row+1 87 } 88 return 1 89} 90func gv_plan_check(plan: *i64, name: *u8, cond: i64, ctr: *i64) -> i64 { 91 let accepted: i64 = gv_plan_take(plan,name) 92 return gv_check(name,((accepted == 1)&&(cond == 1)) as i64,ctr) 93} 94func gv_plan_finish(plan: *i64, ctr: *i64) -> i64 { 95 var row: i64 = 0 96 while row < plan[0] { 97 let cell: i64 = GV_PLAN_HEADER+GV_PLAN_ENTRY*row 98 if plan[cell+2] != 1 { 99 gv_puts(" PLAN case=" as *u8) 100 sys_write(1,plan[cell] as *u8,plan[cell+1]) 101 gv_puts(" executions=" as *u8); gv_num(plan[cell+2]); gv_puts("\n" as *u8) 102 } 103 row=row+1 104 } 105 let result: i64 = gv_check("declared-plan-executed-exactly-once" as *u8,gv_plan_complete(plan),ctr) 106 gv_puts(" PLAN declared=" as *u8); gv_num(plan[0]) 107 gv_puts(" valid=" as *u8); gv_num(plan[1]) 108 gv_puts(" undeclared=" as *u8); gv_num(plan[2]); gv_puts("\n" as *u8) 109 sys_munmap(plan as *u8,GV_I64_BYTES*(GV_PLAN_HEADER+GV_PLAN_ENTRY*plan[0])) 110 return result 111} 112 113const GV_CTR_BYTES: i64 = 24 114const GV_NUM_SCRATCH: i64 = 28 115const GV_ZERO: i64 = 48 116const GV_B10: i64 = 10 117 118func gv_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 119func gv_num(v: i64) -> i64 { 120 let b: *u8 = sys_mmap(GV_NUM_SCRATCH) 121 let t: *u8 = sys_mmap(GV_NUM_SCRATCH) 122 var m: i64 = v 123 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 124 var k: i64 = 0 125 if m == 0 { t[0] = GV_ZERO as u8; k = 1 } 126 while m > 0 { t[k] = (GV_ZERO + (m % GV_B10)) as u8; m = m / GV_B10; k = k + 1 } 127 var i: i64 = 0 128 while i < k { b[i] = t[k-1-i]; i = i + 1 } 129 sys_write(1, b, k) 130 sys_munmap(b, GV_NUM_SCRATCH) 131 sys_munmap(t, GV_NUM_SCRATCH) 132 return 0 133} 134// EMIT ONE MEASURED KEY AND ITS VALUE, so a gate's GREEN can be checked from OUTSIDE the estate. 135// ★★★★★★A GATE THAT PRINTS ONLY PASS IS UNFALSIFIABLE FROM THE OUTSIDE: an arithmetic that cannot see a 136// number can never contradict one, so a pass-only gate makes an independent SECOND METHOD CLASS 137// structurally impossible -- and PROVEN requires two independent method classes. The estate already had 138// the law ("PRINT THE VALUES, NOT JUST PASS/FAIL") and no primitive for it, so every gate that obeyed the 139// law hand-rolled its own printer and most gates simply did not obey it. This is that primitive. 140// MEASURED 2026-09-03: nx_appliedmath_gate was 26/26 GREEN while emitting NOT ONE NUMBER; once it emitted 141// the 28 values its teeth rest on, CPython recomputed 24 of them from the declared inputs, AGREED on all 142// 24 with 15 at zero tolerance, and REFUSED two perturbed controls. None of that was possible the hour before. 143// Call it AFTER the teeth and BEFORE gv_verdict: the verdict line must stay LAST for gv_last_line, which 144// anchors by POSITION rather than by text. 145func gv_kv(k: *u8, v: i64) -> i64 { 146 gv_puts(" " as *u8); gv_puts(k); gv_puts("=" as *u8); gv_num(v); gv_puts("\n" as *u8) 147 return 0 148} 149 150// The header a reader (or an outside adjudicator) looks for to find the emitted block. 151// ce_number_envelope -- CE6 (codeeffectiveness): AN EFFECTIVENESS FIGURE PUBLISHES WITH ITS ENVELOPE OR NOT AT ALL. 152// A replay script that never observed the work matched frontier agents on static benchmarks, so a bare percentage 153// is not evidence. ONE ruler for every board: the value, n (observations behind it), the interval [lo, hi] it sits 154// in, and the null-control value (what the same ruler reads on a subject with nothing in it). A figure with n <= 0, 155// no interval (lo > hi), or an interval that excludes its own value is REFUSED BY NAME and never printed as a value 156// -- the refusal line replaces it, so no reader can mistake a bare number for a measured one. Returns 157// CE_ENV_PUBLISHED or the named refusal code so a gate can assert it. Same placement as gv_kv: after the teeth, 158// before gv_verdict, so the verdict line stays LAST. 159const CE_ENV_PUBLISHED: i64 = 0 160const CE_ENV_REFUSED_BARE: i64 = 1 161const CE_ENV_REFUSED_NO_INTERVAL: i64 = 2 162const CE_ENV_REFUSED_EXCLUDES: i64 = 3 163func ce_env_refuse(k: *u8, why: *u8, n: i64, lo: i64, hi: i64, code: i64) -> i64 { 164 gv_puts(" REFUSED-" as *u8); gv_puts(why); gv_puts(" key=" as *u8); gv_puts(k) 165 gv_puts(" rule=ce_number_envelope n=" as *u8); gv_num(n); gv_puts(" lo=" as *u8); gv_num(lo); gv_puts(" hi=" as *u8); gv_num(hi) 166 gv_puts(" -- a figure without n and an interval containing it does not publish\n" as *u8) 167 return code 168} 169func ce_number_envelope(k: *u8, v: i64, n: i64, lo: i64, hi: i64, null_v: i64) -> i64 { 170 if n <= 0 { return ce_env_refuse(k, "BARE-NUMBER" as *u8, n, lo, hi, CE_ENV_REFUSED_BARE) } 171 if lo > hi { return ce_env_refuse(k, "NO-INTERVAL" as *u8, n, lo, hi, CE_ENV_REFUSED_NO_INTERVAL) } 172 if v < lo { return ce_env_refuse(k, "INTERVAL-EXCLUDES-VALUE" as *u8, n, lo, hi, CE_ENV_REFUSED_EXCLUDES) } 173 if v > hi { return ce_env_refuse(k, "INTERVAL-EXCLUDES-VALUE" as *u8, n, lo, hi, CE_ENV_REFUSED_EXCLUDES) } 174 gv_puts(" " as *u8); gv_puts(k); gv_puts("=" as *u8); gv_num(v) 175 gv_puts(" n=" as *u8); gv_num(n); gv_puts(" lo=" as *u8); gv_num(lo); gv_puts(" hi=" as *u8); gv_num(hi) 176 gv_puts(" null=" as *u8); gv_num(null_v); gv_puts("\n" as *u8) 177 return CE_ENV_PUBLISHED 178} 179 180func gv_values_head() -> i64 { 181 gv_puts("\n VALUES emitted for independent adjudication -- recompute each from the declared inputs\n" as *u8) 182 return 0 183} 184 185// ★★★★★★ASSERT AND EMIT IN ONE CALL, SO THE NUMBER PUBLISHED AND THE NUMBER TESTED CANNOT DRIFT APART. 186// gv_kv alone leaves a gate author two jobs -- check a value, then remember to print it -- and the estate 187// has measured what happens to any invariant that depends on two places agreeing by discipline: 666 gates 188// sit on this base class and emit nothing at all. These make emission a SIDE EFFECT of the assertion, so 189// there is exactly ONE expression and disagreement is impossible by construction rather than by care. 190// MIGRATION IS MECHANICAL AND GREPPABLE: 191// gv_check("name", (a == b) as i64, ctr) -> gv_check_eq("name", a, b, ctr) 192// gv_check("name", (am_abs(a-b) <= t) as i64, ctr) -> gv_check_near("name", a, b, t, ctr) 193// The tooth line keeps its exact leading shape, so every existing reader, rollup and last-line judge is 194// unaffected; the values are APPENDED after the verdict word. 195func gv_check_eq(name: *u8, actual: i64, expected: i64, ctr: *i64) -> i64 { 196 let ok: i64 = (actual == expected) as i64 197 gv_check(name, ok, ctr) 198 gv_puts(" actual=" as *u8); gv_num(actual) 199 gv_puts(" expected=" as *u8); gv_num(expected) 200 gv_puts(" delta=" as *u8); gv_num(actual - expected) 201 gv_puts("\n" as *u8) 202 return ok 203} 204 205// The same, for a value the gate can only hold to a DECLARED tolerance. The tolerance is EMITTED beside 206// the delta on purpose: an outside adjudicator must be told what bar it is checking against, or it will 207// invent one -- and a tolerance that lives only in a tooth name cannot be read by a machine. 208func gv_check_near(name: *u8, actual: i64, expected: i64, tol: i64, ctr: *i64) -> i64 { 209 var d: i64 = actual - expected 210 if d < 0 { d = 0 - d } 211 let ok: i64 = (d <= tol) as i64 212 gv_check(name, ok, ctr) 213 gv_puts(" actual=" as *u8); gv_num(actual) 214 gv_puts(" expected=" as *u8); gv_num(expected) 215 gv_puts(" delta=" as *u8); gv_num(d) 216 gv_puts(" tol=" as *u8); gv_num(tol) 217 gv_puts("\n" as *u8) 218 return ok 219} 220 221func gv_ctr() -> *i64 { 222 let c: *i64 = sys_mmap(GV_CTR_BYTES) as *i64 223 c[0] = 0 224 c[1] = 0 225 c[2] = 0 226 return c 227} 228 229// ---- THE THIRD STATE: "I COULD NOT TEST" IS NOT "IT IS BROKEN" -------------------------------- 230// ADDED 2026-08-07. Ten service-facing gates were built and run for the first time; SIX came back RED 231// and NOT ONE was a regression: missing fixtures (/tmp/sni_nishi_chain.der, /tmp/mozilla_certdata.txt), 232// missing config+creds (golive_dns.conf, porkbun), or the service under test simply not running. 233// A gate that reports FAIL when its PRECONDITIONS are absent is not reporting on the system at all -- 234// it is reporting on its own environment, in the same word. 235// ★★★★★★ A DETECTOR THAT CANNOT DISTINGUISH "I COULD NOT LOOK" FROM "I LOOKED AND IT IS BROKEN" 236// TEACHES EVERYONE TO IGNORE IT, AND THEN IT IS WORSE THAN ABSENT. 237// This estate already learned the law twice: nx_gonogo grew a third state because a two-state verdict 238// WILL fabricate, and nx_commons_price returns UNPRICED rather than inventing a rate. Same rule here. 239// gv_need declares a precondition. If it is absent the gate ends SKIP (evidence=none), never RED. 240// SKIP is NOT a pass: it blocks any claim that the thing works, exactly as missing evidence blocks a 241// GO but never a NO-GO. 242func gv_need(name: *u8, present: i64, ctr: *i64) -> i64 { 243 if present == 1 { return 1 } 244 ctr[2] = ctr[2] + 1 245 gv_puts(" PRECONDITION MISSING: " as *u8) 246 gv_puts(name) 247 gv_puts(" -- cannot test, NOT a failure of the system under test\n" as *u8) 248 return 0 249} 250// ---- gv_subjects: THE EMPTY-SET LAW, MADE STRUCTURAL (2026-08-22) --------------------------------- 251// THE DEFECT: ctr[0]/ctr[1] count TEETH, never SUBJECTS. A gate with ten teeth over ZERO files reports 252// 10/10 GREEN and every consumer reads a pass. This estate has WRITTEN the law repeatedly -- 253// "A TOOTH THAT PASSES ON THE EMPTY SET IS NOT A TOOTH", "BIND EVERY AGGREGATE ASSERTION TO ITS 254// DENOMINATOR" -- and never built the mechanism, so the discipline lived per-organ and hand-rolled 255// (nx_plane_check exits 4 EMPTY-not-a-pass; nx_battery_grade returns UNMEASURED on zero answer rows). 256// *A LAW EVERY AUTHOR MUST REMEMBER IS A LAW THAT WILL BE FORGOTTEN; ONLY A PRIMITIVE IN THE PATH HOLDS. 257// MEASURED THE DAY THIS WAS WRITTEN: a ship harness skipped its work behind a load guard, wrote no log, 258// and EXITED 0 -- inconclusive reading as success, inside the tooling built to enforce the opposite. 259// 260// A ZERO POPULATION IS NOT A FAILURE OF THE SUBJECT, IT IS THE ABSENCE OF EVIDENCE ABOUT IT. So this is 261// DELIBERATELY a precondition (SKIP), never a RED -- and it COMPOSES gv_need rather than inventing a 262// fourth state, so it inherits the already-proven ordering: a SKIP co-occurring with a real failure 263// still escalates to RED and can never amnesty it. 264// Fail-CLOSED on a negative count: an unreadable population is not permission to claim coverage. 265// The count PRINTS ALWAYS, pass or not, so coverage is on the record instead of inferred. 266func gv_subjects(name: *u8, n: i64, ctr: *i64) -> i64 { 267 gv_puts(" subjects=" as *u8) 268 gv_num(n) 269 gv_puts(" [" as *u8) 270 gv_puts(name) 271 gv_puts("]\n" as *u8) 272 var present: i64 = 0 273 if n > 0 { present = 1 } 274 return gv_need(name, present, ctr) 275} 276func gv_head(title: *u8) -> i64 { gv_puts(title); gv_puts("\n\n" as *u8); return 0 } 277// one check: prints " <name>: PASS|FAIL", bumps counters, returns cond 278func gv_check(name: *u8, cond: i64, ctr: *i64) -> i64 { 279 ctr[1] = ctr[1] + 1 280 gv_puts(" " as *u8) 281 gv_puts(name) 282 gv_puts(": " as *u8) 283 if cond == 1 { ctr[0] = ctr[0] + 1; gv_puts("PASS\n" as *u8) } else { gv_puts("FAIL\n" as *u8) } 284 return cond 285} 286// ---- HOISTED FROM THE NAS COPY 2026-07-31 (ws=gate-dry-d001). THE BASE CLASS HAD FORKED: the NAS tree 287// carried gv_bite/gv_cat/gv_catn/gv_journal and this tree carried only the original six, so a gate written 288// against one tree would not compile on the other -- and, worse, an identical migration bought DIFFERENT 289// capability depending on where it happened. Converging the ANCESTOR is the fix; every descendant gains 290// these without being touched, including the ones not written yet. That is the whole point of a base class. 291// 292// BITE-PROVEN cell: the non-vacuity law made structural. A detector counts ONLY if it FIRES on the crafted 293// bad input AND stays SILENT on the crafted good one. A cell green before the defect exists is VACUOUS and 294// proves nothing (the gates-green-on-garbage class). Prints the sub-verdict so vacuity is SEEN, not counted. 295func gv_bite(name: *u8, bad: i64, good: i64, ctr: *i64) -> i64 { 296 var ok: i64 = 0 297 if bad == 1 { if good == 0 { ok = 1 } } 298 ctr[1] = ctr[1] + 1 299 gv_puts(" " as *u8) 300 gv_puts(name) 301 if ok == 1 { ctr[0] = ctr[0] + 1; gv_puts(": BITE-PROVEN (fires on bad, silent on good)\n" as *u8) } 302 if ok == 0 { 303 gv_puts(": FAIL " as *u8) 304 if bad != 1 { gv_puts("[VACUOUS: did not fire on the bad input]" as *u8) } 305 if good != 0 { gv_puts("[FALSE-POSITIVE: fired on the good input]" as *u8) } 306 gv_puts("\n" as *u8) 307 } 308 return ok 309} 310 311const GV_MODE_644: i64 = 420 312const GV_LINE: i64 = 512 313const GV_TAB: i64 = 9 314const GV_SLASH: i64 = 47 315const GV_MINUS: i64 = 45 316 317func gv_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } return p } 318func gv_catn(d: *u8, o: i64, v: i64) -> i64 { 319 let t: *u8 = sys_mmap(GV_NUM_SCRATCH) 320 var m: i64 = v 321 var p: i64 = o 322 if m < 0 { d[p] = GV_MINUS as u8; p = p + 1; m = 0 - m } 323 var k: i64 = 0 324 if m == 0 { t[0] = GV_ZERO as u8; k = 1 } 325 while m > 0 { t[k] = (GV_ZERO + (m % GV_B10)) as u8; m = m / GV_B10; k = k + 1 } 326 var i: i64 = 0 327 while i < k { d[p] = t[k-1-i]; p = p + 1; i = i + 1 } 328 sys_munmap(t, GV_NUM_SCRATCH) 329 return p 330} 331 332// FAIL-SOFT outcome journal: every gate that emits a verdict self-records ONE actlog-grammar frame, so 333// the HARNESS class finally has evidence at all -- flake and EROSION (a banked GREEN later going RED) 334// become derivable, and the frames are minable for free. A write failure NEVER touches the verdict: 335// no permission, no journal, no problem. Append-only, single line, conflict-free (O_APPEND). 336// Deliberately self-contained (no new imports): organs define their own sj_*/cat helpers, so importing a 337// json lib here would collide across hundreds of consumers. 338func gv_journal(name: *u8, passed: i64, total: i64, green: i64) -> i64 { 339 let fd: i64 = sys_openat_append("knowledge/status/harness.jrnl" as *u8, GV_MODE_644) 340 if fd < 0 { return 0 } 341 let ln: *u8 = sys_mmap(GV_LINE) 342 var o: i64 = gv_catn(ln, 0, sys_now_realtime_sec()) 343 ln[o] = GV_TAB as u8; o = o + 1 344 o = gv_cat(ln, o, "harness" as *u8) 345 ln[o] = GV_TAB as u8; o = o + 1 346 o = gv_cat(ln, o, name) 347 ln[o] = GV_TAB as u8; o = o + 1 348 o = gv_cat(ln, o, "run" as *u8) 349 ln[o] = GV_TAB as u8; o = o + 1 350 if green == 1 { o = gv_cat(ln, o, "GREEN" as *u8) } else { o = gv_cat(ln, o, "RED" as *u8) } 351 ln[o] = GV_TAB as u8; o = o + 1 352 o = gv_catn(ln, o, passed) 353 ln[o] = GV_SLASH as u8; o = o + 1 354 o = gv_catn(ln, o, total) 355 ln[o] = GV_NL as u8; o = o + 1 356 sys_write(fd, ln, o) 357 sys_close(fd) 358 sys_munmap(ln, GV_LINE) 359 return 0 360} 361 362// summary + verdict; returns exit code (0 GREEN / 1 RED). Caller gv_exit(rc), never the raw thread exit: a gate that 363// created a thread pool (nf_pool, mm_pool_i8, nsv_init, nx_pool_submit) and ends with sys_exit retires only the calling 364// thread; the workers stay parked in futex wait, the verdict is on disk and the process is a runaway with no kill surface 365// (two gates sat twenty minutes with fifteen threads each on 2026-09-17; nx_syscalls.nx had named the class on 2026-07-07 366// and left it to discipline, and this line prescribed the raw exit). gv_exit is exit_group, which is what return-from-main 367// already does, so a single-threaded gate loses nothing by taking it. nx_gatelaw_gate's L5 axis names the stragglers. 368// ============================================================================================ 369// AD1's REFUSING HALF, WIRED (2026-09-03, lane K). MEASURED FIRST: gv_bare_rate had sat in this file 370// since 2026-08-27 with ZERO PRODUCTION CALLERS -- a grep for gv_bare_rate over buildroot/runtime 371// returns matches=8 over files=23592 with coverage_complete=1 corpus_complete=1, and every one of 372// those eight is this file's own comment, this file's own definition, or nx_rigor_envelope_gate, 373// which is its own gate. Its sibling gv_envelope_check returns matches=1 on that same corpus: its 374// definition, and nothing else. The rigor-envelope header above argues that a ruler in a sibling lib 375// is adopted at advice rates while a ruler in the base class is adopted by every gate that imports 376// it -- the ruler was duly placed in the base class and then never called from the emitter. 377// ***THE ADOPTION ARGUMENT WAS MADE AND THE WIRING WAS NOT DONE***, so the refusal was built, 378// gate-proven, and unreachable from every production emitter in the estate. 379// 380// SILENT WHEN CLEAN, BY CONSTRUCTION. This prints NOTHING unless the note actually carries a rate 381// with no denominator, so stdout stays BYTE-IDENTICAL for every gate that does not have the defect 382// and no existing judge-equivalence proof is invalidated by wiring it in. 383// 384// IT ANNOUNCES AND COUNTS, IT DOES NOT REFUSE -- CHOSEN, NOT CONCEDED. gv_verdict's return value IS 385// the fleet verdict (/api/gate_run derives GREEN/RED/SKIP from it), so letting a bare rate flip that 386// return would turn every gate whose note quotes a rate RED in one edit to the base class every gate 387// imports: the permanently-red detector everyone learns to ignore, installed at the root. The 388// refusing direction belongs to the QA admission contract, which can weigh it per candidate and 389// abstain when it cannot look. 390// 391// PRINTED ABOVE THE VERDICT LINE ON PURPOSE: gv_last_line and every positional reader in the estate 392// anchor on the FINAL line, so an announcement appended after the verdict would silently break all 393// of them. Emitting before the first verdict byte is what keeps the verdict last. 394func gv_note_bare_rate(note: *u8) -> i64 { 395 if (note as i64) == 0 { return 0 } 396 var n: i64 = 0 397 while note[n] != (0 as u8) { n = n + 1 } 398 let off: i64 = gv_bare_rate(note, n) 399 if off < 0 { return 0 } 400 gv_puts("\nNX-RIGOR bare-rate-in-note byte_offset=" as *u8) 401 gv_num(off) 402 gv_puts(" note_bytes=" as *u8) 403 gv_num(n) 404 gv_puts(" rule=AD1-gv_bare_rate\n" as *u8) 405 gv_puts(" A rate is published here whose enclosing object carries no n. Bind it to its denominator\n" as *u8) 406 gv_puts(" via gv_envelope / gv_envelope_json. ADVISORY: the verdict line below is UNCHANGED by this.\n" as *u8) 407 return 1 408} 409 410func gv_verdict(name: *u8, ctr: *i64, note: *u8) -> i64 { 411 // AD1 REFUSING HALF, WIRED: scan the note we are about to publish BEFORE any verdict byte is 412 // emitted, so this announcement can never displace the verdict line from the tail of the output. 413 gv_note_bare_rate(note) 414 // THIRD STATE FIRST. If any precondition was missing the run produced NO EVIDENCE about the 415 // system under test, so it must not be reported in the same word as a real failure. 416 // The third state IS plumbed, end to end: this returns 3, and nx_mgmt_api maps rc==3 to SKIP and 417 // excludes it from RED. It used to return 1 under a comment admitting that was hand-waving. 418 // A COMMENT THAT OUTLIVES THE DEFECT IT DESCRIBES BECOMES A FALSE CLAIM WITH A TRUSTED BYLINE -- 419 // AND OTHERS BUILD WORKAROUNDS AGAINST IT. MEASURED: nx_mcu_ready_gate hand-rolled its own exit 420 // code because this paragraph told it not to trust the return value, and that hand-rolled version 421 // A FAILURE IS EVIDENCE, AND EVIDENCE MUST NOT BE AMNESTIED. The third state answers "I could not 422 // look". It must not also answer "I looked, I found a defect, and something ELSE was missing too". 423 // MEASURED 2026-08-15 on nx_adversarial_sov_gate: three checks RAN, one FAILED, one precondition was 424 // missing -- and this function reported `verdict=SKIP ... proved NOTHING about the system under test` 425 // while holding a real failure. The one failure a gate exists to catch was the one it could not 426 // report. A SKIP THAT CAN SWALLOW A RED IS NOT A THIRD STATE, IT IS AN AMNESTY. 427 // ORDERING IS THE WHOLE FIX, and it is a strict TIGHTENING: the only verdict that moves is 428 // (preconditions missing AND at least one check failed), SKIP -> RED. A clean run cannot become RED, 429 // a RED cannot become GREEN, and a SKIP with nothing failing is still SKIP. This can never bless 430 // anything -- it can only stop something being blessed. 431 // The missing preconditions are still NAMED on the verdict line, because "RED, and also partly 432 // unobservable" is a different situation from "RED, fully measured", and a reader needs both. 433 if ctr[1] > ctr[0] { 434 gv_puts("\nNX-" as *u8) 435 gv_puts(name) 436 gv_puts(" passed " as *u8) 437 gv_num(ctr[0]) 438 gv_puts("/" as *u8) 439 gv_num(ctr[1]) 440 if ctr[2] > 0 { 441 gv_puts(" (with " as *u8) 442 gv_num(ctr[2]) 443 gv_puts(" precondition(s) ALSO missing -- a failed check is evidence, so this is RED, not SKIP)" as *u8) 444 } 445 gv_puts(" verdict=RED\n" as *u8) 446 gv_journal(name, ctr[0], ctr[1], 0) 447 return 1 448 } 449 // silently collapsed SKIP into RED -- the very class of bug it was avoiding. 450 if ctr[2] > 0 { 451 gv_puts("\nNX-" as *u8) 452 gv_puts(name) 453 gv_puts(" verdict=SKIP -- " as *u8) 454 gv_num(ctr[2]) 455 gv_puts(" precondition(s) missing; ran " as *u8) 456 gv_num(ctr[1]) 457 gv_puts(" checks, proved NOTHING about the system under test.\n" as *u8) 458 gv_puts(" SKIP is not a pass: it blocks any claim that this works, exactly as missing\n" as *u8) 459 gv_puts(" evidence blocks a GO but never a NO-GO.\n" as *u8) 460 gv_journal(name, ctr[0], ctr[1], 0) 461 // EXIT 3 = SKIP, distinct from 1 = RED. This used to return 1 with a comment admitting the 462 // distinction "lives in the output text until gate_run maps a third exit code". That was 463 // hand-waving: a third state that collapses to RED at the transport is not a third state. 464 // /api/gate_run now maps 3 -> SKIP, so "I could not look" is machine-readable fleet-wide. 465 return 3 466 } 467 gv_puts("\nNX-" as *u8) 468 gv_puts(name) 469 gv_puts(" passed " as *u8) 470 gv_num(ctr[0]) 471 gv_puts("/" as *u8) 472 gv_num(ctr[1]) 473 if ctr[0] == ctr[1] { 474 if ctr[1] > 0 { 475 gv_puts(" verdict=GREEN (" as *u8) 476 gv_puts(note) 477 gv_puts(")\n" as *u8) 478 // The journal write is a FILE side-effect only -- stdout, the PASS/FAIL vector and the 479 // verdict line are byte-unchanged, so every migration already proven judge-equivalent 480 // stays valid. Every inheriting gate now records its own outcome without being touched. 481 gv_journal(name, ctr[0], ctr[1], 1) 482 return 0 483 } 484 } 485 gv_puts(" verdict=RED\n" as *u8) 486 gv_journal(name, ctr[0], ctr[1], 0) 487 return 1 488} 489 490// ============================================================================================ 491// THE RIGOR ENVELOPE (AD1, 2026-08-27): A PUBLISHED NUMBER IS A STRUCT, NEVER A BARE RATE. 492// ============================================================================================ 493// WHY IT LIVES IN THE BASE CLASS: /compare/autograde published "92 percent resolved" with no 494// denominator (the July record says n=14: 13 of 14); /compare/gen's referee rows publish HPSv2 / 495// PickScore / GenEval values with no n, no interval, no engine hash. Both boards were made to share 496// ONE ruler by the operator's standing order (proven evidence mandatory on BOTH), and the only place 497// every gate already inherits from is this file. A ruler in a sibling lib is adopted at advice 498// rates; a ruler in the base class is adopted at 100 percent of the gates that import it. 499// 500// THE STRUCT (out[GV_ENV_FIELDS], every field an i64, rates in PERMIL): 501// k n rate wilson_lo wilson_hi boot_lo boot_hi env_lo env_hi clusters B seed measured z_micro width target 502// THE METHOD, with its sources named so a reader can refute it rather than trust it: 503// * Wilson score interval (Wilson 1927, JASA 22:209-212), z = Phi^-1(0.975) = 1.959964 for a 504// two-sided 95 percent interval. Chosen over the Wald interval because Wald collapses to zero width 505// at k=0 and k=n, which is exactly where a small benchmark lives (0 of 14, 14 of 14). 506// * A HIERARCHICAL (two-level) bootstrap over the task nesting (Miller et al. 2025, "Statistical 507// Precipice" -- agent benchmarks nest runs inside tasks, and a flat interval under-covers): 508// resample clusters with replacement, then each chosen cluster's outcomes with replacement, B 509// replicates, percentile interval. The envelope is the WIDER of the two -- the bootstrap can only 510// widen Wilson, never narrow it, so a caller cannot launder a small n through clustering. 511// * A Park-Miller minimal-standard generator (Park and Miller 1988, CACM 31(10)): multiply-and-mod 512// only, so no bitwise or shift semantics are relied on, seed-deterministic so two runs of the same 513// ledger publish the same interval. 514// * INTEGER ARITHMETIC THROUGHOUT (this is the no-float estate). Micro-units (1e6) carry z and the 515// radicand; the square root is bisection on i64. The five reference values below were checked by 516// hand against the closed form before this shipped: 7/14 -> [268,732], 13/14 -> [685,987], 517// 0/14 -> [0,215], 14/14 -> [785,1000], 1/1 -> [207,1000] permil. 518// THE REFUSAL: gv_bare_rate scans a text body for digits followed by "%" or " percent" whose enclosing 519// JSON object carries no "n" field, and returns the offender's byte offset. A page emitted through 520// gv_envelope_json never trips it, because that object always carries "n". A hand-typed percent does. 521// THE PARAMETERS are ARGUMENTS, not literals read here: z_micro, B, seed and the width target come 522// from knowledge/rigor.conf through nx_stage_path.sp_rigor_int (this lib deliberately imports nothing 523// new -- `const EP_MAGIC_1024` already exists independently in nx_ecomat_put.nx:12, so importing 524// nx_estate_path here would collide at some gate's next build). The bootstrap defaults below are 525// the fallback when no conf row exists, and every printed line names the values it used. 526// UNMEASURED IS ITS OWN STATE: n=0 returns 0 and prints UNMEASURED; a cluster partition that does not 527// sum to (k,n) returns GV_ENV_REFUSED_PARTITION and prints REFUSED-PARTITION -- a partition is a claim. 528const GV_ENV_FIELDS: i64 = 16 529const GV_ENV_BYTES: i64 = 128 // GV_ENV_FIELDS * 8 530const GV_ENV_K: i64 = 0 531const GV_ENV_N: i64 = 1 532const GV_ENV_RATE: i64 = 2 533const GV_ENV_WLO: i64 = 3 534const GV_ENV_WHI: i64 = 4 535const GV_ENV_BLO: i64 = 5 536const GV_ENV_BHI: i64 = 6 537const GV_ENV_LO: i64 = 7 538const GV_ENV_HI: i64 = 8 539const GV_ENV_CLUSTERS: i64 = 9 540const GV_ENV_B: i64 = 10 541const GV_ENV_SEED: i64 = 11 542const GV_ENV_MEASURED: i64 = 12 543const GV_ENV_Z: i64 = 13 544const GV_ENV_WIDTH: i64 = 14 545const GV_ENV_TARGET: i64 = 15 546const GV_ENV_REFUSED_PARTITION: i64 = 0 - 1 547const GV_MICRO: i64 = 1000000 548const GV_PERMIL: i64 = 1000 549// Phi^-1(0.975) in micro-units: the two-sided 95 percent normal quantile (Wilson 1927). 550const GV_Z95_MICRO: i64 = 1959964 551// the radicand is carried in micro-units; multiplying by 100 before the integer sqrt makes the root 552// come out scaled by 1e4 (sqrt(1e6 * 1e2) = 1e4), i.e. four decimals of the root survive the floor. 553const GV_SQRT_IN_SCALE: i64 = 100 554const GV_SQRT_OUT_SCALE: i64 = 10000 555// B=1000 is the textbook floor for a bootstrap percentile interval (Efron and Tibshirani 1993, ch.13). 556const GV_BOOT_B_DEFAULT: i64 = 1000 557// any fixed seed is reproducible; this one names the day the envelope shipped, so a reader can date it. 558const GV_BOOT_SEED_DEFAULT: i64 = 20260827 559// Park-Miller minimal standard: x' = 16807 * x mod (2^31 - 1). Period 2^31-2, far above B * n here. 560const GV_PM_A: i64 = 16807 561const GV_PM_M: i64 = 2147483647 562// n*n must fit an i64 for the radicand 4k(n-k): the exact limit is 3,037,000,499; floored with headroom. 563const GV_ENV_N_MAX: i64 = 2000000000 564// isqrt bisection upper bound: the largest v with v*v <= 2^63-1 is 3,037,000,499 (no mid*mid overflow). 565const GV_ISQRT_HI: i64 = 3037000499 566// replicate rates are permil, so a 1001-bin histogram makes the percentile walk O(B) with no sort. 567const GV_HIST_BINS: i64 = 1001 568const GV_HIST_BYTES: i64 = 8008 // GV_HIST_BINS * 8 569// the 2.5th and 97.5th percentiles of the replicate distribution bound a two-sided 95 percent interval. 570const GV_PCT_LO_PERMIL: i64 = 25 571const GV_PCT_HI_PERMIL: i64 = 975 572const GV_ENV_UNDECLARED: *u8 = "UNDECLARED" 573 574func gv_isqrt(v: i64) -> i64 { 575 if v <= 0 { return 0 } 576 var lo: i64 = 0 577 var hi: i64 = v 578 if hi > GV_ISQRT_HI { hi = GV_ISQRT_HI } 579 while lo < hi { 580 let mid: i64 = (lo + hi + 1) / 2 581 if mid * mid <= v { lo = mid } else { hi = mid - 1 } 582 } 583 return lo 584} 585 586// Wilson bounds in permil for k of n at z (micro). out[0]=lo out[1]=hi. Returns 1, or 0 UNMEASURED. 587// bounds = (2k + z^2 +- z * sqrt(4k(n-k)/n + z^2)) / (2(n + z^2)) 588func gv_wilson_permil(k: i64, n: i64, z_micro: i64, out: *i64) -> i64 { 589 if n <= 0 { return 0 } 590 if n > GV_ENV_N_MAX { return 0 } 591 if k < 0 { return 0 } 592 if k > n { return 0 } 593 let z2: i64 = (z_micro * z_micro) / GV_MICRO 594 let a: i64 = 2 * k * GV_MICRO + z2 595 let d: i64 = 2 * (n * GV_MICRO + z2) 596 let f: i64 = 4 * k * (n - k) 597 let q: i64 = f / n 598 let r: i64 = f - q * n 599 let rad: i64 = q * GV_MICRO + (r * GV_MICRO) / n + z2 600 let s: i64 = gv_isqrt(rad * GV_SQRT_IN_SCALE) 601 let t: i64 = (z_micro * s) / GV_SQRT_OUT_SCALE 602 var lo: i64 = ((a - t) * GV_PERMIL + d / 2) / d 603 var hi: i64 = ((a + t) * GV_PERMIL + d / 2) / d 604 if lo < 0 { lo = 0 } 605 if hi > GV_PERMIL { hi = GV_PERMIL } 606 out[0] = lo 607 out[1] = hi 608 return 1 609} 610 611func gv_rng_next(state: *i64) -> i64 { 612 var x: i64 = state[0] 613 if x <= 0 { x = 1 } 614 if x >= GV_PM_M { x = x % GV_PM_M } 615 if x == 0 { x = 1 } 616 x = (GV_PM_A * x) % GV_PM_M 617 state[0] = x 618 return x 619} 620 621// Two-level bootstrap over clusters (ck[c] successes of cn[c] outcomes). out[0]=lo out[1]=hi permil. 622// Returns 1, or 0 when there is nothing to resample. 623func gv_boot_hier(ck: *i64, cn: *i64, nc: i64, b: i64, seed: i64, out: *i64) -> i64 { 624 if nc <= 0 { return 0 } 625 if b <= 0 { return 0 } 626 var ntot: i64 = 0 627 var c0: i64 = 0 628 while c0 < nc { ntot = ntot + cn[c0]; c0 = c0 + 1 } 629 if ntot <= 0 { return 0 } 630 let hist: *i64 = sys_mmap(GV_HIST_BYTES) as *i64 631 var hz: i64 = 0 632 while hz < GV_HIST_BINS { hist[hz] = 0; hz = hz + 1 } 633 let st: *i64 = sys_mmap(8) as *i64 634 st[0] = seed 635 var rep: i64 = 0 636 while rep < b { 637 var succ: i64 = 0 638 var tot: i64 = 0 639 var pick: i64 = 0 640 while pick < nc { 641 let c: i64 = gv_rng_next(st) % nc 642 let kc: i64 = ck[c] 643 let ncc: i64 = cn[c] 644 var dd: i64 = 0 645 while dd < ncc { 646 if (gv_rng_next(st) % ncc) < kc { succ = succ + 1 } 647 tot = tot + 1 648 dd = dd + 1 649 } 650 pick = pick + 1 651 } 652 var rate: i64 = 0 653 if tot > 0 { rate = (succ * GV_PERMIL + tot / 2) / tot } 654 if rate < 0 { rate = 0 } 655 if rate > GV_PERMIL { rate = GV_PERMIL } 656 hist[rate] = hist[rate] + 1 657 rep = rep + 1 658 } 659 let lo_need: i64 = (b * GV_PCT_LO_PERMIL + GV_PERMIL - 1) / GV_PERMIL 660 let hi_need: i64 = (b * GV_PCT_HI_PERMIL + GV_PERMIL - 1) / GV_PERMIL 661 var cum: i64 = 0 662 var lo: i64 = 0 - 1 663 var hi: i64 = 0 - 1 664 var bin: i64 = 0 665 while bin < GV_HIST_BINS { 666 cum = cum + hist[bin] 667 if lo < 0 { if cum >= lo_need { lo = bin } } 668 if hi < 0 { if cum >= hi_need { hi = bin } } 669 bin = bin + 1 670 } 671 if lo < 0 { lo = 0 } 672 if hi < 0 { hi = GV_PERMIL } 673 sys_munmap(hist as *u8, GV_HIST_BYTES) 674 sys_munmap(st as *u8, 8) 675 out[0] = lo 676 out[1] = hi 677 return 1 678} 679 680// THE ENVELOPE. ck/cn/nc describe the task nesting (pass nc=0 for "no nesting known": the plain 681// bootstrap is the degenerate hierarchy and clusters=1 is printed so the reader can see that). 682// width_target is the conf row (permil); width_ok is derived from it and printed, never decided here. 683// Returns 1 MEASURED, 0 UNMEASURED (n<=0 or k out of range), GV_ENV_REFUSED_PARTITION when the 684// clusters do not sum to (k, n). 685func gv_envelope(k: i64, n: i64, ck: *i64, cn: *i64, nc: i64, z_micro: i64, b: i64, seed: i64, width_target: i64, out: *i64) -> i64 { 686 var i: i64 = 0 687 while i < GV_ENV_FIELDS { out[i] = 0; i = i + 1 } 688 out[GV_ENV_K] = k 689 out[GV_ENV_N] = n 690 out[GV_ENV_Z] = z_micro 691 out[GV_ENV_B] = b 692 out[GV_ENV_SEED] = seed 693 out[GV_ENV_TARGET] = width_target 694 out[GV_ENV_CLUSTERS] = nc 695 if n <= 0 { return 0 } 696 if k < 0 { return 0 } 697 if k > n { return 0 } 698 if nc > 0 { 699 var sk: i64 = 0 700 var sn: i64 = 0 701 var c: i64 = 0 702 while c < nc { sk = sk + ck[c]; sn = sn + cn[c]; c = c + 1 } 703 if sk != k { return GV_ENV_REFUSED_PARTITION } 704 if sn != n { return GV_ENV_REFUSED_PARTITION } 705 } 706 out[GV_ENV_RATE] = (k * GV_PERMIL + n / 2) / n 707 let w: *i64 = sys_mmap(16) as *i64 708 if gv_wilson_permil(k, n, z_micro, w) == 0 { return 0 } 709 out[GV_ENV_WLO] = w[0] 710 out[GV_ENV_WHI] = w[1] 711 var kk: *i64 = ck 712 var nn: *i64 = cn 713 var ncl: i64 = nc 714 if ncl <= 0 { 715 let one: *i64 = sys_mmap(16) as *i64 716 one[0] = k 717 one[1] = n 718 kk = one 719 nn = ((one as i64) + 8) as *i64 720 ncl = 1 721 } 722 out[GV_ENV_CLUSTERS] = ncl 723 let bb: *i64 = sys_mmap(16) as *i64 724 if gv_boot_hier(kk, nn, ncl, b, seed, bb) == 1 { 725 out[GV_ENV_BLO] = bb[0] 726 out[GV_ENV_BHI] = bb[1] 727 } else { 728 out[GV_ENV_BLO] = w[0] 729 out[GV_ENV_BHI] = w[1] 730 } 731 var lo: i64 = w[0] 732 if out[GV_ENV_BLO] < lo { lo = out[GV_ENV_BLO] } 733 var hi: i64 = w[1] 734 if out[GV_ENV_BHI] > hi { hi = out[GV_ENV_BHI] } 735 out[GV_ENV_LO] = lo 736 out[GV_ENV_HI] = hi 737 out[GV_ENV_WIDTH] = hi - lo 738 out[GV_ENV_MEASURED] = 1 739 return 1 740} 741 742// width_ok: 1 when a target was given and the envelope is no wider than it; 0 otherwise. A target of 743// 0 means "none declared" and reads as 0 -- an undeclared bar can never be met. 744func gv_envelope_width_ok(out: *i64) -> i64 { 745 if out[GV_ENV_MEASURED] != 1 { return 0 } 746 if out[GV_ENV_TARGET] <= 0 { return 0 } 747 if out[GV_ENV_WIDTH] <= out[GV_ENV_TARGET] { return 1 } 748 return 0 749} 750 751func gv_env_pair(a: i64, b: i64) -> i64 { 752 gv_puts("[" as *u8); gv_num(a); gv_puts("," as *u8); gv_num(b); gv_puts("]" as *u8) 753 return 0 754} 755 756// the canonical printed line: one row, every parameter on it, so the number can be re-derived. 757func gv_envelope_print(label: *u8, out: *i64, harness: *u8) -> i64 { 758 gv_puts(" ENVELOPE " as *u8) 759 gv_puts(label) 760 gv_puts(" k=" as *u8); gv_num(out[GV_ENV_K]) 761 gv_puts(" n=" as *u8); gv_num(out[GV_ENV_N]) 762 if out[GV_ENV_MEASURED] == 1 { 763 gv_puts(" rate_permil=" as *u8); gv_num(out[GV_ENV_RATE]) 764 gv_puts(" ci_permil=" as *u8); gv_env_pair(out[GV_ENV_LO], out[GV_ENV_HI]) 765 gv_puts(" wilson=" as *u8); gv_env_pair(out[GV_ENV_WLO], out[GV_ENV_WHI]) 766 gv_puts(" boot=" as *u8); gv_env_pair(out[GV_ENV_BLO], out[GV_ENV_BHI]) 767 gv_puts(" width=" as *u8); gv_num(out[GV_ENV_WIDTH]) 768 gv_puts(" target=" as *u8); gv_num(out[GV_ENV_TARGET]) 769 gv_puts(" width_ok=" as *u8); gv_num(gv_envelope_width_ok(out)) 770 } else { 771 gv_puts(" UNMEASURED (no population -- a rate over nothing is not a rate)" as *u8) 772 } 773 gv_puts(" clusters=" as *u8); gv_num(out[GV_ENV_CLUSTERS]) 774 gv_puts(" B=" as *u8); gv_num(out[GV_ENV_B]) 775 gv_puts(" seed=" as *u8); gv_num(out[GV_ENV_SEED]) 776 gv_puts(" z_micro=" as *u8); gv_num(out[GV_ENV_Z]) 777 gv_puts(" harness=" as *u8) 778 if (harness as i64) == 0 { gv_puts(GV_ENV_UNDECLARED) } else { if harness[0] == (0 as u8) { gv_puts(GV_ENV_UNDECLARED) } else { gv_puts(harness) } } 779 gv_puts(" method=wilson+hierarchical-bootstrap\n" as *u8) 780 return 0 781} 782 783// JSON object for a published page. Always carries "n" (the field the refusal looks for). 784func gv_envelope_json(d: *u8, o0: i64, out: *i64, harness: *u8) -> i64 { 785 var o: i64 = o0 786 o = gv_cat(d, o, "{\"k\":" as *u8); o = gv_catn(d, o, out[GV_ENV_K]) 787 o = gv_cat(d, o, ",\"n\":" as *u8); o = gv_catn(d, o, out[GV_ENV_N]) 788 if out[GV_ENV_MEASURED] == 1 { 789 o = gv_cat(d, o, ",\"rate_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_RATE]) 790 o = gv_cat(d, o, ",\"ci_lo_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_LO]) 791 o = gv_cat(d, o, ",\"ci_hi_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_HI]) 792 o = gv_cat(d, o, ",\"wilson_lo_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_WLO]) 793 o = gv_cat(d, o, ",\"wilson_hi_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_WHI]) 794 o = gv_cat(d, o, ",\"boot_lo_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_BLO]) 795 o = gv_cat(d, o, ",\"boot_hi_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_BHI]) 796 o = gv_cat(d, o, ",\"width_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_WIDTH]) 797 o = gv_cat(d, o, ",\"width_target_permil\":" as *u8); o = gv_catn(d, o, out[GV_ENV_TARGET]) 798 o = gv_cat(d, o, ",\"width_ok\":" as *u8); o = gv_catn(d, o, gv_envelope_width_ok(out)) 799 o = gv_cat(d, o, ",\"verdict\":\"MEASURED\"" as *u8) 800 } else { 801 o = gv_cat(d, o, ",\"rate_permil\":null,\"ci_lo_permil\":null,\"ci_hi_permil\":null,\"verdict\":\"UNMEASURED\"" as *u8) 802 } 803 o = gv_cat(d, o, ",\"clusters\":" as *u8); o = gv_catn(d, o, out[GV_ENV_CLUSTERS]) 804 o = gv_cat(d, o, ",\"boot_reps\":" as *u8); o = gv_catn(d, o, out[GV_ENV_B]) 805 o = gv_cat(d, o, ",\"seed\":" as *u8); o = gv_catn(d, o, out[GV_ENV_SEED]) 806 o = gv_cat(d, o, ",\"z_micro\":" as *u8); o = gv_catn(d, o, out[GV_ENV_Z]) 807 o = gv_cat(d, o, ",\"harness\":\"" as *u8) 808 if (harness as i64) == 0 { o = gv_cat(d, o, GV_ENV_UNDECLARED) } else { if harness[0] == (0 as u8) { o = gv_cat(d, o, GV_ENV_UNDECLARED) } else { o = gv_cat(d, o, harness) } } 809 o = gv_cat(d, o, "\",\"method\":\"wilson+hierarchical-bootstrap\"}" as *u8) 810 return o 811} 812 813// does buf[at..] begin with lit (NUL-terminated), inside n? 814func gv_at(buf: *u8, n: i64, at: i64, lit: *u8) -> i64 { 815 var i: i64 = 0 816 while lit[i] != (0 as u8) { 817 if at + i >= n { return 0 } 818 if buf[at + i] != lit[i] { return 0 } 819 i = i + 1 820 } 821 return 1 822} 823 824// does the JSON object enclosing position `at` (nearest '{' before, nearest '}' after) carry "n":? 825func gv_obj_has_n(buf: *u8, n: i64, at: i64) -> i64 { 826 var s: i64 = at 827 var go: i64 = 1 828 while go == 1 { 829 if s <= 0 { s = 0; go = 0 } else { 830 if buf[s] == (123 as u8) { go = 0 } else { s = s - 1 } 831 } 832 } 833 var e: i64 = at 834 go = 1 835 while go == 1 { 836 if e >= n { e = n; go = 0 } else { 837 if buf[e] == (125 as u8) { go = 0 } else { e = e + 1 } 838 } 839 } 840 var i: i64 = s 841 while i < e { 842 if gv_at(buf, e, i, "\"n\":" as *u8) == 1 { return 1 } 843 i = i + 1 844 } 845 return 0 846} 847 848// THE REFUSAL. Returns the byte offset of the first bare rate (digits + "%" or " percent" with no "n" 849// in the enclosing object), or -1 when the body is clean. 850func gv_bare_rate(buf: *u8, n: i64) -> i64 { 851 var i: i64 = 0 852 while i < n { 853 let c: i64 = buf[i] as i64 854 var isd: i64 = 0 855 if c >= 48 { if c <= 57 { isd = 1 } } 856 if isd == 1 { 857 var j: i64 = i 858 var scan: i64 = 1 859 while scan == 1 { 860 if j >= n { scan = 0 } else { 861 let dch: i64 = buf[j] as i64 862 var dd: i64 = 0 863 if dch >= 48 { if dch <= 57 { dd = 1 } } 864 if dd == 1 { j = j + 1 } else { scan = 0 } 865 } 866 } 867 var hit: i64 = 0 868 if j < n { if buf[j] == (37 as u8) { hit = 1 } } 869 if hit == 0 { if gv_at(buf, n, j, " percent" as *u8) == 1 { hit = 1 } } 870 if hit == 1 { if gv_obj_has_n(buf, n, i) == 0 { return i } } 871 i = j 872 } else { i = i + 1 } 873 } 874 return 0 - 1 875} 876 877// AD2's half of the contract: two envelopes are directly comparable only when their harness manifests 878// are the SAME declared hash. UNDECLARED (or empty) on either side refuses -- an undeclared harness is 879// not a matching one. 880func gv_envelope_comparable(ha: *u8, hb: *u8) -> i64 { 881 if (ha as i64) == 0 { return 0 } 882 if (hb as i64) == 0 { return 0 } 883 if ha[0] == (0 as u8) { return 0 } 884 if hb[0] == (0 as u8) { return 0 } 885 if gv_at(ha, GV_LINE, 0, GV_ENV_UNDECLARED) == 1 { return 0 } 886 if gv_at(hb, GV_LINE, 0, GV_ENV_UNDECLARED) == 1 { return 0 } 887 var i: i64 = 0 888 while ha[i] != (0 as u8) { 889 if ha[i] != hb[i] { return 0 } 890 i = i + 1 891 } 892 if hb[i] != (0 as u8) { return 0 } 893 return 1 894} 895 896// a tooth that binds a published rate to its denominator: passes only when the envelope MEASURED, and 897// prints the envelope line beside the PASS/FAIL so the reader sees the numbers, not a boolean. 898func gv_envelope_check(name: *u8, out: *i64, harness: *u8, ctr: *i64) -> i64 { 899 gv_envelope_print(name, out, harness) 900 var ok: i64 = 0 901 if out[GV_ENV_MEASURED] == 1 { ok = 1 } 902 return gv_check(name, ok, ctr) 903} 904 905// THE EXIT (2026-09-17): exit_group, so a gate takes its pool workers with it -- see the note above gv_verdict. 906func gv_exit(rc: i64) -> i64 { sys_exit_group(rc); return rc }