code wiki / _hdl_build / nx_evindep_gate.nx

nx_evindep_gate.nx source

↩ module page · 240 lines · 12353 B

1// nx_evindep_gate.nx -- THE INDEPENDENCE AXIS, LIVE ON THE BOARD THAT JUDGES CLAIMS. 2// 3// The independence law (nx_evoracle) was live on the NAS but nothing CONSUMED it, so no claim's standing 4// changed. A capability that beats the baseline in a gate but is not wired at the live chokepoint IS the 5// baseline -- this ecosystem has paid for that law four times. This organ is the consumer. 6// 7// WHAT IT ANSWERS, per compare domain that declares executable evidence: 8// does ANY of its declared gates rest on an authority OUTSIDE this ecosystem? 9// It reads <domain>.gates, takes the 4th field (the declared SUBJECT SOURCE), and classifies that subject's 10// party-ness with evo_classify. THIRD => the domain has at least one externally-anchored gate. FIRST or 11// UNRESOLVED => every gate it declares is graded against answers we wrote ourselves. 12// 13// ★DELIBERATELY A SEPARATE ORGAN FROM nx_sota_status (rule 9). nx_sota_status feeds deploy check #12, and a 14// sibling is landing a change that makes POST /api/deploy REFUSE on RED. Adding an axis there could flip a 15// domain and stop every deploy in the ecosystem the hour it shipped. This reports; it never convicts. 16// ★AND IT IS GENUINELY A READ-ONLY VERIFIER, which is why running it through /api/gate_run is honest -- 17// that route executes verifiers only, and that bound is what makes it never-brick. My row-DERIVING organ 18// (nx_evoracle_sweep) writes a file and is correctly refused by that same route; I did not rename it to 19// slip past the bound. 20// 21// ★SELF-CHECK TEETH FIRST (T1/T2). A census that silently finds nothing reads exactly like a corpus that 22// contains nothing -- the single most repeated failure in this ecosystem. So before reporting anything the 23// organ proves its classifier still separates a known third-party header from a known first-party one, and 24// FAILS RED if it cannot. An instrument must prove itself before it grades a corpus. 25// ⚠A domain whose .gates file is absent is reported NO-GATES, never skipped: a domain we could not measure 26// and a domain with no external anchor must never look the same. 27// license_tier: ORIGINAL expect_exit: 0 28import "nx_syscalls.nx" 29import "nx_evoracle.nx" 30 31func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 32 33func nn(v: i64) -> i64 { 34 var m: i64 = v 35 if m < 0 { w("-" as *u8); m = 0 - m } 36 let t: *u8 = sys_mmap(32) 37 var k: i64 = 0 38 if m == 0 { t[0] = 48 as u8; k = 1 } 39 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 40 let b: *u8 = sys_mmap(32) 41 var j: i64 = 0 42 while j < k { b[j] = t[k - 1 - j]; j = j + 1 } 43 sys_write(1, b, k) 44 return 0 45} 46 47func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 48 49func bcat(buf: *u8, at: i64, s: *u8) -> i64 { 50 var i: i64 = 0 51 while s[i] != (0 as u8) { buf[at + i] = s[i]; i = i + 1 } 52 return at + i 53} 54 55// Resolve a declared subject path against the roots this host actually uses. Tried as written first, then 56// under buildroot/. Returns the length loaded, 0 if unresolvable. An eager resolver is a WORSE bug than a 57// blind one -- it would ground a claim against whatever file it happened to land on -- so this only ever 58// tries two EXACT candidates and never guesses a basename. 59func load_subject(rel: *u8, rl: i64, lp: *i64) -> *u8 { 60 let p1: *u8 = sys_mmap(512) 61 var i: i64 = 0 62 while i < rl { p1[i] = rel[i]; i = i + 1 } 63 p1[rl] = 0 as u8 64 lp[0] = 0 65 let b1: *u8 = sys_read_file(p1, lp) 66 if lp[0] > 0 { return b1 } 67 let p2: *u8 = sys_mmap(512) 68 var o: i64 = bcat(p2, 0, "buildroot/" as *u8) 69 i = 0 70 while i < rl { p2[o + i] = rel[i]; i = i + 1 } 71 p2[o + rl] = 0 as u8 72 lp[0] = 0 73 let b2: *u8 = sys_read_file(p2, lp) 74 if lp[0] > 0 { return b2 } 75 lp[0] = 0 76 return p1 77} 78 79// c[0]=domains with a THIRD anchor c[1]=domains with gates but NO third anchor c[2]=NO-GATES 80// c[3]=gates rows seen c[4]=rows with a THIRD subject c[5]=rows whose subject would not resolve 81func domain(c: *i64, dom: *u8) -> i64 { 82 let path: *u8 = sys_mmap(512) 83 var o: i64 = bcat(path, 0, "knowledge/compare/" as *u8) 84 o = bcat(path, o, dom) 85 o = bcat(path, o, ".gates" as *u8) 86 path[o] = 0 as u8 87 88 let lp: *i64 = sys_mmap(16) as *i64 89 lp[0] = 0 90 let b: *u8 = sys_read_file(path, lp) 91 if lp[0] <= 0 { 92 c[2] = c[2] + 1 93 w(" NO-GATES " as *u8); w(dom); w(" (no executable evidence declared -- not measurable here)\n" as *u8) 94 return 0 95 } 96 97 var rows: i64 = 0 98 var third: i64 = 0 99 var unres: i64 = 0 100 // NO-SUBJECT-DECLARED is a DIFFERENT finding from SUBJECT-WONT-RESOLVE and must never share a counter. 101 // Measured 2026-07-31: finance.gates declares `<elf>|<argv|->|<label>` -- THREE fields. The 4th field 102 // (subject source) is an additive extension those domains were never migrated to. My first cut called 103 // all 26 of them `unresolved`, which named the artifact-root class and sent the reader hunting a roots 104 // table that would have fixed nothing. The two demand OPPOSITE work: no-subject needs a DECLARATION 105 // (nx_subject_infer derives it; never guess -- a wrong subject slanders a working gate), wont-resolve 106 // needs a ROOTS fix. A diagnostic that misnames the defect IS the defect. 107 var nosub: i64 = 0 108 var ls: i64 = 0 109 var p: i64 = 0 110 while p <= lp[0] { 111 var eol: i64 = 0 112 if p == lp[0] { eol = 1 } else { if b[p] == (10 as u8) { eol = 1 } } 113 if eol == 1 { 114 if p > ls { 115 if b[ls] != (35 as u8) { 116 rows = rows + 1 117 // 4th pipe-separated field = the declared subject source 118 var bars: i64 = 0 119 var q: i64 = ls 120 var sstart: i64 = 0 - 1 121 while q < p { 122 if b[q] == (124 as u8) { 123 bars = bars + 1 124 if bars == 3 { sstart = q + 1 } 125 } 126 q = q + 1 127 } 128 if sstart < 0 { nosub = nosub + 1 } 129 else { 130 var send: i64 = sstart 131 while send < p { if b[send] == (124 as u8) { send = p } else { send = send + 1 } } 132 let sl: i64 = send - sstart 133 if sl <= 0 { nosub = nosub + 1 } 134 else { 135 let sp: i64 = (b as i64) + sstart 136 let slp: *i64 = sys_mmap(16) as *i64 137 let sb: *u8 = load_subject(sp as *u8, sl, slp) 138 if slp[0] <= 0 { unres = unres + 1 } 139 else { 140 if evo_classify(sb, slp[0]) == EVO_P_THIRD { 141 third = third + 1 142 // NEVER SUMMED: a VALIDATED row is graded against answers published 143 // outside; a SPECIFIED row implements an external rule but is tested 144 // with cases we chose. Reporting one mixed total reads as validation. 145 if evo_validation_tier(sb, slp[0]) == EVO_V_VALIDATED { c[7] = c[7] + 1 } 146 else { c[8] = c[8] + 1 } 147 } 148 } 149 } 150 } 151 } 152 } 153 ls = p + 1 154 } 155 p = p + 1 156 } 157 158 c[3] = c[3] + rows 159 c[4] = c[4] + third 160 c[5] = c[5] + unres 161 c[6] = c[6] + nosub 162 if third > 0 { 163 c[0] = c[0] + 1 164 w(" THIRD-ANCHOR " as *u8); w(dom); w(" gates=" as *u8); nn(rows) 165 w(" externally-anchored=" as *u8); nn(third); w("\n" as *u8) 166 return 0 167 } 168 c[1] = c[1] + 1 169 w(" self-graded " as *u8); w(dom); w(" gates=" as *u8); nn(rows) 170 w(" externally-anchored=0 no-subject-declared=" as *u8); nn(nosub) 171 w(" subject-wont-resolve=" as *u8); nn(unres); w("\n" as *u8) 172 return 0 173} 174 175func main() -> i64 { 176 w("nx_evindep_gate -- THE INDEPENDENCE AXIS over the compare corpus\n" as *u8) 177 178 // ---- SELF-CHECK: prove the instrument before grading the corpus ---- 179 let k3: *u8 = "standing KAT for X25519 (RFC 7748), OpenSSL-verified\x00" as *u8 180 let k1: *u8 = "all 256 bytes vs inlined ground truth. func gt_ws(c: i64)\x00" as *u8 181 var self_ok: i64 = 0 182 if evo_classify(k3, slen(k3)) == EVO_P_THIRD { 183 if evo_classify(k1, slen(k1)) == EVO_P_FIRST { self_ok = 1 } 184 } 185 if self_ok == 1 { w(" T1/T2 self-check: classifier separates THIRD from FIRST -- PASS\n\n" as *u8) } 186 else { 187 w(" T1/T2 self-check FAILED -- the instrument is broken; refusing to grade the corpus\n" as *u8) 188 w("nx_evindep_gate: verdict=RED\n" as *u8) 189 return 1 190 } 191 192 let c: *i64 = sys_mmap(128) as *i64 193 var z: i64 = 0 194 while z < 10 { c[z] = 0; z = z + 1 } 195 196 domain(c, "authz\x00" as *u8) 197 domain(c, "warden\x00" as *u8) 198 domain(c, "surveys\x00" as *u8) 199 domain(c, "librarian\x00" as *u8) 200 domain(c, "medbilling\x00" as *u8) 201 domain(c, "projectmgmt\x00" as *u8) 202 domain(c, "ecosysdesign\x00" as *u8) 203 domain(c, "toolchain-syscall-abi\x00" as *u8) 204 domain(c, "finance\x00" as *u8) 205 domain(c, "videocodec\x00" as *u8) 206 // ADDED after ENUMERATING instead of assuming: `glob *.gates knowledge/compare` returns TWELVE files, 207 // not the ten I hardcoded. I had missed legal, deploy and media entirely -- so my first two runs 208 // reported a census over a denominator I had chosen rather than measured. CHECK THE DENOMINATOR BEFORE 209 // SIZING THE WORK is a banked law of this very lane, and I broke it inside the instrument built to 210 // audit exactly this class. toolchain-syscall-abi is KEPT deliberately: it has no .gates and reporting 211 // it as NO-GATES is information, not noise. 212 domain(c, "legal\x00" as *u8) 213 domain(c, "deploy\x00" as *u8) 214 domain(c, "media\x00" as *u8) 215 216 w("\n-- INDEPENDENCE OF THE EVIDENCE (not its quantity) --\n" as *u8) 217 w(" domains with >=1 EXTERNALLY-ANCHORED gate : " as *u8); nn(c[0]); w("\n" as *u8) 218 w(" domains whose gates are ALL self-graded : " as *u8); nn(c[1]); w("\n" as *u8) 219 w(" domains declaring NO executable evidence : " as *u8); nn(c[2]); w("\n" as *u8) 220 w(" declared gate rows seen : " as *u8); nn(c[3]); w("\n" as *u8) 221 w(" rows with a THIRD-party subject : " as *u8); nn(c[4]); w("\n" as *u8) 222 w(" rows with NO SUBJECT DECLARED (3-field) : " as *u8); nn(c[6]); w(" <- needs a DECLARATION\n" as *u8) 223 w(" rows whose declared subject won't resolve : " as *u8); nn(c[5]); w(" <- needs a ROOTS fix\n" as *u8) 224 let gradable: i64 = c[3] - c[5] - c[6] 225 w(" GRADABLE rows (subject present+readable) : " as *u8); nn(gradable); w("\n" as *u8) 226 w(" ** of those gradable, THIRD-party : " as *u8); nn(c[4]) 227 w(" -- not third/total\n" as *u8) 228 w(" of which VALIDATED (graded against externally-published answers) : " as *u8); nn(c[7]); w("\n" as *u8) 229 w(" of which SPECIFIED (external RULE, but OUR test cases) : " as *u8); nn(c[8]); w("\n" as *u8) 230 w(" ** VALIDATED IS THE ONLY TRUE THIRD-PARTY NUMBER. Do not sum it with SPECIFIED: a mixed\n" as *u8) 231 w(" total reads as validation and is not. A framework we merely DESIGNED TOWARD (EDRM,\n" as *u8) 232 w(" 'TigerBeetle is the reference design') counts as NEITHER -- that is influence, not evidence.\n" as *u8) 233 w("\nSELF-GRADED IS NOT WORTHLESS -- it is a consistency test. It cannot detect an error we and it\n" as *u8) 234 w("share. Only the externally-anchored column is evidence that something OUTSIDE this ecosystem\n" as *u8) 235 w("agrees with us. An unresolved subject is UNMEASURED and is counted apart from both, so a domain\n" as *u8) 236 w("we could not grade can never be mistaken for one that has no external anchor.\n" as *u8) 237 w("\nnx_evindep_gate: verdict=GREEN (census reports; it never convicts -- unmet independence costs a\n" as *u8) 238 w("domain PROVEN, never RED, so this axis can never brick a deploy)\n" as *u8) 239 return 0 240}