code wiki / _hdl_build / nx_domain_admit_lib.nx

nx_domain_admit_lib.nx source

↩ module page · 770 lines · 43192 B

1// nx_domain_admit_lib.nx -- THE PURE DECISION CORE OF nx_domain_admit, THE /compare ADMISSION GATE. 2// 3// WHY THIS FILE EXISTS AT ALL. nx_domain_admit decides whether a /compare domain may publish, and on 4// 2026-08-25 the ship loop reported for it: "PROVE NO-GATE-FOUND -- a NAMED absence, NOT a pass: 5// NOTHING about this target has been proven." The organ that refuses on everyone else's behalf had 6// nothing proven about itself, on a day it shipped TWO changes (C3 both-tree gates resolution, C4 7// fresh-kill from the bite records). 8// 9// A GATE COULD NOT HAVE BEEN WRITTEN AGAINST THE ORGAN AS IT STOOD. nx_domain_admit is a top-level 10// programme, so nothing can import it; and a gate that fork/execs the deployed elf is NOT 11// mutation-provable -- the harness rebuilds the TEST and not the SUBJECT, so every mutant returns 12// NOT-REACHED and the resulting GREEN reads exactly like a proof while proving nothing. Extracting the 13// decision core into a library that sits INSIDE the gate's build closure is what makes the proof 14// possible at all. 15// 16// THIS IS A MOVE, NOT A COPY. Every function below was CUT from nx_domain_admit.nx, which now imports 17// this file. There is still exactly ONE word-boundary ruler, ONE row classifier, ONE bite-record reader 18// and ONE gates-map resolver in the estate. A second copy would be the duplicate-ruler defect wearing a 19// test's clothes, and the two would drift the moment either was fixed. 20// 21// WHY THIS FILE LIVES IN _hdl_build/ AND NOT IN runtime/ BESIDE THE OTHER LIBS -- MEASURED, NOT CHOSEN. 22// The first draft was written to buildroot/runtime/ and the build FAILED with twelve "there are two 23// definitions of dp_read/dp_len/dep_run/..." errors. nx_deploy_lib.nx exists TWICE in this estate -- 24// buildroot/runtime/nx_deploy_lib.nx and buildroot/runtime/_hdl_build/nx_deploy_lib.nx (5,655 B) -- and 25// imports resolve RELATIVE TO THE IMPORTING FILE, so the organ in _hdl_build/ and a library in runtime/ 26// each pulled in a DIFFERENT nx_deploy_lib and the compiler saw every dp_* symbol twice. 27// A SHARED DEPENDENCY THAT EXISTS AS TWO TWINS IS DEDUPED BY PATH, NOT BY NAME: a library and its 28// consumer must sit in the same tree or their common import is textually included twice. The compiler 29// refused loudly, which is the good failure -- had it silently picked one, the organ would have changed 30// which dp_read it runs without a single line of its own code moving. 31// 32// TWO THINGS WERE EXTRACTED RATHER THAN MOVED, and each removes a real duplicate: 33// da_read_2dir / da_gates_read -- C3 (in main) and C4 (in da_c4) EACH built the <domain>.gates path 34// and EACH tried the two trees. That second copy is precisely how the 2026-08-25 defect survived: 35// the 2026-08-20 repoint moved the MATRIX read to the publishing tree and did not move its sibling, 36// so has_gates read 0 for every domain in the estate. ONE resolver, called twice, cannot half-move. 37// da_c4_partition -- the bucket arithmetic, separated from path resolution so it can be measured 38// against a fixture instead of against the live gate fleet. A gate that shares a fixture with a 39// production beat measures the beat and not the code. 40// 100 percent sovereign. No hardware writes (Rule 26). license_tier: ORIGINAL 41import "nx_syscalls.nx" 42import "nx_deploy_lib.nx" 43// C5 COMPOSES THE ESTATE'S ONE ATTESTATION VERIFIER RATHER THAN RE-EXPRESSING IT. at_verify_row is the 44// chokepoint every signed evidence row already passes (nx_sota_status ss_class_load calls exactly this), 45// and at_find/AT_CLASS_*/AT_ERR_* come with it -- so there is still ONE signature check, ONE hex decoder 46// and ONE key registry reader in the estate. A second copy would be the duplicate-ruler defect wearing an 47// admission gate's clothes, and the copy nobody edits is the one the next reader believes. 48// IMPORT-TWIN CHECK, MEASURED BEFORE WRITING THIS LINE (the 2026-08-25 dp_read collision cost a build): 49// nx_evattest.nx pulls nx_syscalls.nx + nx_ed25519_signature.nx, and NEITHER has an _hdl_build twin 50// (nor do nx_sha512, nx_x25519 or any nx_ed25519_field/point/arith/scalar), so every shared dependency 51// resolves to exactly one path from both this file and that one. nx_ed25519_extvec_gate.nx already sits 52// in _hdl_build importing nx_ed25519_signature.nx + nx_gate_verdict.nx and builds, which is the working 53// precedent for the gate side of this closure. 54import "nx_evattest.nx" 55 56const DA_SCAP: i64 = 8388608 57const DA_PATH: i64 = 512 58const DA_NL: i64 = 10 59const DA_PIPE: i64 = 124 60const DA_HASH: i64 = 35 61// THE TREE THIS GATE AUDITS -- ONE literal, replacing three former call sites (main, da_c1, da_sweep). 62// MEASURED 2026-08-20: this gate read the bare "knowledge/compare/" (the nishihost twin) while 63// nx_compare_regen PUBLISHES from "buildroot/knowledge/compare/". The two trees are FORKED, not 64// stale, so converging them by copy would destroy real work in one direction or the other. 65// AN ADMISSION GATE MUST AUDIT THE COPY THAT PUBLISHES, AND REPOINTING THE GATE MOVES NO DATA. 66const DA_CDIRS: *u8 = "buildroot/knowledge/compare/" 67// THE TREE THAT OWNS THE .gates MAPS. Measured 2026-08-25: every one of the *.gates files in the 68// estate lives at knowledge/compare/, NOT in the publishing twin above. C3 built its path from 69// DA_CDIRS, so has_gates read 0 for EVERY domain -- including lang, whose map is real, non-empty and 70// names nx_wasm_craft_gate -- and every ADMIT printed CLAIM-ONLY about domains that DO ship executable 71// evidence. This constant is tried FIRST and the publishing twin second, so a map in either tree is 72// found: strictly additive, it can turn has_gates 0 into 1 and never 1 into 0. 73const DA_GATESDIR: *u8 = "knowledge/compare/" 74const DA_GATESSUF: *u8 = ".gates" 75// C4 fresh-kill: every nx_gate_bite run WRITES a durable record here, shaped 76// killed=1 valid_mutants=1 invalid=0 epoch=<t> subjectdig=<sha256> host=<host> 77const DA_BITEPFX: *u8 = "knowledge/status/bite_" 78const DA_BITESUF: *u8 = ".verdict" 79const DA_ELFSUF: *u8 = ".elf" 80const DA_EQ: i64 = 61 81const DA_D0: i64 = 48 82const DA_D9: i64 = 57 83const DA_DOT: i64 = 46 84const DA_VCAP: i64 = 4096 85 86func da_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 87func da_w(s: *u8) -> i64 { sys_write(1, s, da_slen(s)); return 0 } 88func da_wn(base: *u8, off: i64, len: i64) -> i64 { sys_write(1, ((base as i64)+off) as *u8, len); return 0 } 89func da_n(v: i64) -> i64 { 90 let t: *u8 = sys_mmap(28) 91 var m: i64 = v 92 var k: i64 = 0 93 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 94 if m == 0 { t[0] = 48 as u8; k = 1 } 95 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 96 let b: *u8 = sys_mmap(28) 97 var i: i64 = 0 98 while i < k { b[i] = t[k-1-i]; i = i + 1 } 99 sys_write(1, b, k) 100 return 0 101} 102func da_cat(dst: *u8, pos: i64, s: *u8) -> i64 { 103 var p: i64 = pos 104 var i: i64 = 0 105 let n: i64 = da_slen(s) 106 while i < n { dst[p] = s[i]; p = p + 1; i = i + 1 } 107 return p 108} 109 110// identifier character? letters, digits, underscore -- the word-boundary alphabet. 111func da_isword(c: i64) -> i64 { 112 if c >= 48 { if c <= 57 { return 1 } } 113 if c >= 65 { if c <= 90 { return 1 } } 114 if c >= 97 { if c <= 122 { return 1 } } 115 if c == 95 { return 1 } 116 return 0 117} 118 119// WORD-BOUNDARY search of buf[0..n) for the needle slice ned[na..na+nl). 120// The boundary test is the whole point: a plain substring match is what let prefix symbols pass, and the 121// ADMISSION_STANDARD names 11 prefix rows repaired in arrears because of exactly that. 122func da_wfind(buf: *u8, n: i64, ned: *u8, na: i64, nl: i64) -> i64 { 123 if nl <= 0 { return 0 - 1 } 124 if n < nl { return 0 - 1 } 125 var i: i64 = 0 126 while i <= n - nl { 127 var j: i64 = 0 128 var m: i64 = 1 129 while j < nl { if buf[i+j] != ned[na+j] { m = 0; j = nl } else { j = j + 1 } } 130 if m == 1 { 131 var ok: i64 = 1 132 if i > 0 { if da_isword(buf[i-1] as i64) == 1 { ok = 0 } } 133 if i + nl < n { if da_isword(buf[i+nl] as i64) == 1 { ok = 0 } } 134 if ok == 1 { return i } 135 } 136 i = i + 1 137 } 138 return 0 - 1 139} 140 141func da_eol(buf: *u8, n: i64, i: i64) -> i64 { 142 var e: i64 = i 143 while e < n { if buf[e] == (DA_NL as u8) { return e } e = e + 1 } 144 return n 145} 146 147func da_sl_eq(buf: *u8, a: i64, b: i64, lit: *u8) -> i64 { 148 let l: i64 = da_slen(lit) 149 if b - a != l { return 0 } 150 var i: i64 = 0 151 while i < l { if buf[a+i] != lit[i] { return 0 } i = i + 1 } 152 return 1 153} 154 155// start of the REAL symbol inside a symbol field: a watch row's "_ABSENT_:" contract prefix is stripped 156func da_symstart(mb: *u8, sa: i64, p3: i64) -> i64 { 157 if p3 - sa > 9 { if da_sl_eq(mb, sa, sa + 9, "_ABSENT_:" as *u8) == 1 { return sa + 9 } } 158 return sa 159} 160 161// Resolve the organ path a matrix row DECLARES into a readable path, and read it. 162// Matrix rows are written buildroot-relative (runtime/...); knowledge/ paths are estate-relative. 163func da_try(org: *u8, oa: i64, ob: i64, sb: *u8, pfx: i64) -> i64 { 164 let path: *u8 = sys_mmap(DA_PATH) 165 var p: i64 = 0 166 if pfx == 1 { p = da_cat(path, 0, "buildroot/" as *u8) } 167 var i: i64 = oa 168 while i < ob { path[p] = org[i]; p = p + 1; i = i + 1 } 169 path[p] = 0 as u8 170 return dp_read(path, sb, DA_SCAP - 4) 171} 172 173// RESOLUTION ORDER IS LOAD-BEARING, AND THE FIRST DRAFT GOT IT WRONG. 174// Matrix rows name organs two ways: "runtime/..." is BUILDROOT-relative source, while "knowledge/..." and 175// "sites/..." are ESTATE-relative. Resolving buildroot-first for everything read 176// buildroot/knowledge/status/nishi_os.log -- a STALER TWIN of the real log that also exists -- and reported 177// a TRUE row as UNGROUNDED. A resolver that silently prefers the wrong copy MANUFACTURES false verdicts, 178// which is strictly worse than not checking: it teaches the author to "fix" correct evidence. 179// Prefix decides the order; the other location is still tried, so a moved file is found rather than failed. 180func da_read_organ(org: *u8, oa: i64, ob: i64, sb: *u8) -> i64 { 181 var bfirst: i64 = 0 182 if ob - oa >= 8 { 183 let r: *u8 = "runtime/" as *u8 184 var m: i64 = 1 185 var i: i64 = 0 186 while i < 8 { if org[oa+i] != r[i] { m = 0; i = 8 } else { i = i + 1 } } 187 if m == 1 { bfirst = 1 } 188 } 189 let n: i64 = da_try(org, oa, ob, sb, bfirst) 190 if n > 0 { return n } 191 var alt: i64 = 1 192 if bfirst == 1 { alt = 0 } 193 return da_try(org, oa, ob, sb, alt) 194} 195 196// ONE row classifier, called by BOTH the single-domain path and the sweep. A sweep that re-implements 197// the check is a second opinion, not a wider one -- and a SECOND full copy of the row loop once lived in 198// main(), so the watch-row defect below had to be found and fixed TWICE. 199// THE DEFECT: a gap is either the bare "_ABSENT_" or the WATCH form "_ABSENT_:<future_symbol>" that the 200// matrix format documents and the compare hive runs on. The old code compared the WHOLE field against 201// "_ABSENT_", so a watch row fell through and this organ tried to ground the literal string 202// "_ABSENT_:mp_page_emit" inside the organ source -- a string that can NEVER occur -- which made every 203// watch row an UNGROUNDED CLAIM and FAILED ITS DOMAIN'S ADMISSION outright. 204// Returns 0 = declared gap (bare _ABSENT_, or a watch contract that has NOT landed) 205// 1 = grounded (a real symbol, or a WATCH CONTRACT THAT HAS LANDED) 206// 2 = ungrounded (a claimed symbol absent from the organ its own row names) 207// 3 = organ unreadable (a CLAIMED symbol on a path that cannot be read) 208// 4 = a WATCH contract on an organ that does not exist yet (a NEW-ORGAN contract: counted, named, never a fault) 209func da_classify_row(mb: *u8, p1: i64, p2: i64, p3: i64, sb: *u8) -> i64 { 210 let sa: i64 = p2 + 1 211 if da_sl_eq(mb, sa, p3, "_ABSENT_" as *u8) == 1 { return 0 } 212 var sym: i64 = sa 213 var watch: i64 = 0 214 if p3 - sa > 9 { 215 if da_sl_eq(mb, sa, sa + 9, "_ABSENT_:" as *u8) == 1 { sym = sa + 9; watch = 1 } 216 } 217 let got: i64 = da_read_organ(mb, p1 + 1, p2, sb) 218 // A WATCH CONTRACT ON AN ORGAN THAT DOES NOT EXIST YET IS ITS OWN ANSWER (2026-08-27, measured on the 219 // synthroom admission: 19 of 20 contracts named organs nobody has written, and the domain was REFUSED 220 // for it). A plan for a NEW product necessarily names organs that do not exist; grading that as "an 221 // unresolvable citation" refuses every new-organ contract while a contract on an existing organ sails 222 // through -- the same claim graded two ways by an accident of file layout. It asserts nothing about a 223 // file (not a fault) and it is not the plain gap either (it names WHERE the symbol will land, and the 224 // page keeps watching that path), so it is a fifth class the callers count and NAME. A bare claim on an 225 // absent organ still reads 3: that row asserts coverage no file backs. 226 if got <= 0 { if watch == 1 { return 4 } return 3 } 227 if da_wfind(sb, got, mb, sym, p3 - sym) >= 0 { return 1 } 228 if watch == 1 { return 0 } 229 return 2 230} 231 232// ---- the ratchet's set logic: a floor held as a SET OF NAMES, never a count ---- 233func da_count_lines(b: *u8, n: i64) -> i64 { 234 var c: i64 = 0 235 var i: i64 = 0 236 while i < n { if b[i] == (DA_NL as u8) { c = c + 1 } i = i + 1 } 237 return c 238} 239// WHOLE-LINE membership. A prefix must NOT match: "alpha" is not a member of a set holding "alphabet", 240// and if it were, fixing one offender would silently amnesty another. 241func da_hasline(hay: *u8, hn: i64, ned: *u8, off: i64, len: i64) -> i64 { 242 var i: i64 = 0 243 var found: i64 = 0 244 while i < hn { 245 let e: i64 = da_eol(hay, hn, i) 246 if e - i == len { 247 var k: i64 = 0 248 var same: i64 = 1 249 while k < len { 250 if hay[i + k] != ned[off + k] { same = 0 } 251 k = k + 1 252 } 253 if same == 1 { found = 1 } 254 } 255 i = e + 1 256 } 257 return found 258} 259 260// "1.5" -> 15, "2" -> 20, "0.5" -> 5; anything without a digit -> -1 (an unestimated rung is its own 261// class, and must never read as an estimate of zero). Resolution is TENTHS: a second fractional digit is 262// discarded, so "1.25" -> 12 -- named here because a reader who assumes rounding would misread C7. 263func da_tenths(s: *u8, a: i64, b: i64) -> i64 { 264 var v: i64 = 0 265 var any: i64 = 0 266 var frac: i64 = 0 - 1 267 var i: i64 = a 268 while i < b { 269 let c: i64 = s[i] as i64 270 if c >= DA_D0 { if c <= DA_D9 { 271 if frac < 0 { v = v * 10 + (c - DA_D0); any = 1 } else { if frac == 0 { v = v * 10 + (c - DA_D0); frac = 1; any = 1 } } 272 } } 273 if c == DA_DOT { if frac < 0 { frac = 0 } } 274 i = i + 1 275 } 276 if any == 0 { return 0 - 1 } 277 if frac <= 0 { v = v * 10 } 278 return v 279} 280 281// Integer value following "<key>=" on a word boundary. Returns -1 for an ABSENT key, which must never 282// read the same as a key present with value 0 -- "no record of a kill" and "a run that killed nothing" 283// are different findings with different remedies, and that distinction IS C4. 284// The word boundary is not decoration either: without it "killed" would match inside "notkilled=7". 285func da_kv(buf: *u8, n: i64, key: *u8) -> i64 { 286 let kl: i64 = da_slen(key) 287 let at: i64 = da_wfind(buf, n, key, 0, kl) 288 if at < 0 { return 0 - 1 } 289 var i: i64 = at + kl 290 if i >= n { return 0 - 1 } 291 if buf[i] != (DA_EQ as u8) { return 0 - 1 } 292 i = i + 1 293 var v: i64 = 0 294 var any: i64 = 0 295 var go: i64 = 1 296 while go == 1 { 297 if i >= n { go = 0 } else { 298 let c: i64 = buf[i] as i64 299 if c < DA_D0 { go = 0 } else { 300 if c > DA_D9 { go = 0 } else { v = v * 10 + (c - DA_D0); any = 1; i = i + 1 } 301 } 302 } 303 } 304 if any == 0 { return 0 - 1 } 305 return v 306} 307 308// ---- C3: the <domain>.gates map, resolved in BOTH trees, by ONE resolver ---- 309// d1 is tried first and d2 second. Two callers needed this and each had written it out; the copy that 310// was not repointed on 2026-08-20 is the whole reason C3 read 0 for every domain in the estate. 311// ONE path builder. This body was written out TWICE inside da_read_2dir, which is the same shape of debt 312// that put C3 and C4 each building their own <domain>.gates path -- and C5/C6 need <dir><domain><suffix> 313// in four more places (the evclass carrier, its unsigned twin, the evidence stamp, the board's domain set). 314// Extracting it keeps the count of path builders at one instead of taking it to six. 315func da_read_at(d: *u8, dom: *u8, suf: *u8, sb: *u8, cap: i64) -> i64 { 316 let path: *u8 = sys_mmap(DA_PATH) 317 var p: i64 = da_cat(path, 0, d) 318 p = da_cat(path, p, dom) 319 p = da_cat(path, p, suf) 320 path[p] = 0 as u8 321 return dp_read(path, sb, cap) 322} 323func da_read_2dir(d1: *u8, d2: *u8, dom: *u8, suf: *u8, sb: *u8, cap: i64) -> i64 { 324 let n1: i64 = da_read_at(d1, dom, suf, sb, cap) 325 if n1 > 0 { return n1 } 326 return da_read_at(d2, dom, suf, sb, cap) 327} 328func da_gates_read(dom: *u8, sb: *u8) -> i64 { return da_read_2dir(DA_GATESDIR, DA_CDIRS, dom, DA_GATESSUF, sb, DA_SCAP - 4) } 329 330// ---- C4 FRESH-KILL: the partition, over an ALREADY-READ gates map ---- 331// Path resolution is the caller's job, which is what lets this be measured against a fixture instead of 332// against the live gate fleet. The three outcomes are kept DISTINCT and none of them is silent: 333// bite-proven -- a record exists and killed >= 1: the gate has been shown able to fail. 334// never-bitten -- declared, but no record at all: a green that never had a corresponding red. 335// bitten-zero-kill -- a run happened and killed nothing: the gate may be VACUOUS, which is worse than 336// absent because its existence is counted as coverage while its verdict is empty. 337// out[0]=declared out[1]=bite-proven out[2]=never-bitten out[3]=bitten-zero-kill. Returns bite-proven. 338// A DECLARED GATE BELONGS TO EXACTLY ONE BUCKET: out[1]+out[2]+out[3] must equal out[0], and the caller 339// prints that sum rather than asserting the partition in prose. 340func da_c4_partition(gb: *u8, gn: i64, bitepfx: *u8, out: *i64) -> i64 { 341 out[0] = 0 342 out[1] = 0 343 out[2] = 0 344 out[3] = 0 345 let rec: *u8 = sys_mmap(DA_PATH) 346 let name: *u8 = sys_mmap(DA_PATH) 347 let vb: *u8 = sys_mmap(DA_VCAP) 348 var i: i64 = 0 349 while i < gn { 350 let le: i64 = da_eol(gb, gn, i) 351 if le > i { 352 if gb[i] != (DA_HASH as u8) { 353 var pipe: i64 = 0 - 1 354 var q: i64 = i 355 while q < le { 356 if gb[q] == (DA_PIPE as u8) { if pipe < 0 { pipe = q } } 357 q = q + 1 358 } 359 if pipe > i { 360 out[0] = out[0] + 1 361 var end: i64 = pipe 362 if end - i > 4 { if da_sl_eq(gb, end - 4, end, DA_ELFSUF) == 1 { end = end - 4 } } 363 var o: i64 = 0 364 var k: i64 = i 365 while k < end { if o < DA_PATH - 1 { name[o] = gb[k]; o = o + 1 } k = k + 1 } 366 name[o] = 0 as u8 367 var bp: i64 = da_cat(rec, 0, bitepfx) 368 bp = da_cat(rec, bp, name) 369 bp = da_cat(rec, bp, DA_BITESUF) 370 rec[bp] = 0 as u8 371 let vn: i64 = dp_read(rec, vb, DA_VCAP - 8) 372 if vn <= 0 { 373 out[2] = out[2] + 1 374 da_w(" C4 NEVER-BITTEN gate=" as *u8); da_w(name) 375 da_w(" (declared in the gates map with NO bite record -- a green that never had a red)\n" as *u8) 376 } else { 377 let kills: i64 = da_kv(vb, vn, "killed" as *u8) 378 if kills > 0 { 379 out[1] = out[1] + 1 380 da_w(" C4 BITE-PROVEN gate=" as *u8); da_w(name) 381 da_w(" killed=" as *u8); da_n(kills) 382 da_w(" valid_mutants=" as *u8); da_n(da_kv(vb, vn, "valid_mutants" as *u8)) 383 da_w("\n" as *u8) 384 } else { 385 out[3] = out[3] + 1 386 da_w(" C4 BITTEN-BUT-VACUOUS gate=" as *u8); da_w(name) 387 da_w(" killed=" as *u8); da_n(kills) 388 da_w(" (a mutation run happened and killed nothing -- its existence counts as coverage, its verdict is empty)\n" as *u8) 389 } 390 } 391 } 392 } 393 } 394 i = le + 1 395 } 396 return out[1] 397} 398 399// FRESHNESS IS DELIBERATELY NOT ASSERTED, and the reason is named rather than hidden: subjectdig is the 400// digest of the SUBJECT source passed to the bite, while the .gates 4th field names the GATE source by 401// fleet convention. Those are different files whenever the mutation-provable lib-plus-in-process-gate 402// shape is used, so comparing them would report STALE for correctly-bitten gates. A detector with false 403// positives is worse than none, so the digest is PRINTED for a human and never used to refuse. 404// C4 REPORTS AND DOES NOT REFUSE, exactly like C3. 405func da_c4(dom: *u8, sb: *u8) -> i64 { 406 let gn: i64 = da_gates_read(dom, sb) 407 if gn <= 0 { 408 da_w(" C4 fresh-kill ABSTAIN -- no <domain>.gates to enumerate, so nothing is claimed either way\n" as *u8) 409 return 0 410 } 411 let out: *i64 = sys_mmap(32) as *i64 412 let proven: i64 = da_c4_partition(sb, gn, DA_BITEPFX, out) 413 da_w(" C4 fresh-kill declared=" as *u8); da_n(out[0]) 414 da_w(" bite-proven=" as *u8); da_n(out[1]) 415 da_w(" never-bitten=" as *u8); da_n(out[2]) 416 da_w(" bitten-zero-kill=" as *u8); da_n(out[3]) 417 da_w(" sum=" as *u8); da_n(out[1] + out[2] + out[3]) 418 da_w(" (a declared gate belongs to exactly one bucket: the parts must sum to declared)" as *u8) 419 if out[0] > 0 { if out[1] == out[0] { da_w(" ALL-PROVEN\n" as *u8) } else { da_w(" INCOMPLETE\n" as *u8) } } 420 if out[0] == 0 { da_w(" EMPTY-MAP\n" as *u8) } 421 return proven 422} 423 424// ==== C5 SECOND METHOD CLASS -- READ THE ROW, VERIFY IT, AND KEEP THE ANSWERS APART ==== 425// 426// ADMISSION_STANDARD C5, verbatim: "One signed experiential row (machine attestor) whose witness is 427// OUTSIDE our stack ... always with a negative control that PROVES the witness can fail, and run 428// OBSERVE->WRITE. Unclaimable witnesses are recorded as absences, never faked." 429// From the day this organ was written until now, C5 printed the hard-coded string UNVERIFIED for every 430// domain in the estate. A constant wearing the shape of a measurement is worse than a blank. 431// 432// THREE STATES, NEVER TWO, and each one exists because collapsing it into another one LIES: 433// SIGNED a row in the LOADABLE carrier knowledge/status/evclass_<domain>.conf whose 434// signature verifies over the claim prefix, under a key REGISTERED in 435// knowledge/attest_keys.conf, for a role permitted to make that claim. 436// UNSIGNED-CANDIDATE a row EXISTS, is readable, and is explicitly not signed. It must not read as 437// SIGNED or anyone who can write a file certifies their own work; it must not read 438// as ABSENT or the honest work of producing the witness is invisible and the next 439// reader pays for it again. dcc is exactly this state today. 440// ABSENT no row in either carrier. Nothing was claimed, so nothing is faked. 441// A FOURTH IS DECLARED RATHER THAN FOLDED IN. SIGNED-BUT-REFUSED (a row that carries pub= and sig= and 442// the verifier said no) cannot be reported as UNSIGNED: a valid signature from an unregistered stranger, 443// a machine key reaching for a human row, and a tampered claim are FINDINGS, and an honestly unsigned 444// candidate is not. Folding them together is the bucket-named-for-how-the-reader-failed defect. 445// 446// THE VERIFIER CAN BE UNREACHABLE, AND THEN THE CLAIM GOES DOWN, NEVER UP. With no readable key registry 447// nothing can distinguish a registered key from a stranger, so every row is treated as UNSIGNED at most 448// and the payload says so. Fail-closed is the same direction ss_class_load takes for an absent registry. 449// 450// THE CARRIER NAME IS PART OF THE CLAIM. knowledge/status/evclass_<domain>.conf.UNSIGNED-CANDIDATE is 451// deliberately NOT the name ss_class_load globs, so NOTHING loads it -- and therefore a row inside it is 452// capped at UNSIGNED-CANDIDATE even if its signature verifies. Renaming it is an operator act. A gate 453// that promoted a file by reading it would be minting the authority it exists to check. 454const DA_EVPFX: *u8 = "knowledge/status/evclass_" 455const DA_EVSUF: *u8 = ".conf" 456const DA_EVCAND: *u8 = ".conf.UNSIGNED-CANDIDATE" 457const DA_KEYREG: *u8 = "knowledge/attest_keys.conf" 458const DA_KEYCAP: i64 = 65536 459const DA_C5_ABSENT: i64 = 0 460const DA_C5_UNSIGNED: i64 = 1 461const DA_C5_SIGNED: i64 = 2 462const DA_C5_REFUSED: i64 = 3 463// The two tags at_verify_row itself anchors on, hoisted so their LENGTHS are DERIVED at the one site that 464// needs them. Written as a 5 beside the literal they would drift the moment either tag is retitled, and 465// the shape check would then read a window that is off by one with no diagnostic anywhere. 466const DA_C5_PUBTAG: *u8 = " pub=" 467const DA_C5_SIGTAG: *u8 = " sig=" 468const DA_C5_PUBHEX: i64 = 64 469const DA_C5_SIGHEX: i64 = 128 470 471// Substring presence inside one row, COMPOSED from at_find so there is no second matcher. 472func da_row_has(b: *u8, s: i64, e: i64, lit: *u8) -> i64 { 473 if at_find(b, s, e, lit, da_slen(lit)) >= 0 { return 1 } 474 return 0 475} 476 477// The class vocabulary is nx_sota_status ss_class_load's, restated here because that loader lives inside a 478// top-level programme and nothing can import a main(). The NUMBERS are at_verify_row's own AT_CLASS_*, so 479// the reader and the verifier cannot drift on VALUE -- only on spelling, and the gate pins all five 480// spellings plus the unknown-class answer. 481func da_row_class(b: *u8, s: i64, e: i64) -> i64 { 482 if da_row_has(b, s, e, "class=human" as *u8) == 1 { return AT_CLASS_HUMAN } 483 if da_row_has(b, s, e, "class=llm" as *u8) == 1 { return AT_CLASS_LLM } 484 if da_row_has(b, s, e, "class=mech" as *u8) == 1 { return AT_CLASS_MECH } 485 if da_row_has(b, s, e, "class=oracle" as *u8) == 1 { return AT_CLASS_ORACLE } 486 if da_row_has(b, s, e, "class=experiential" as *u8) == 1 { return AT_CLASS_EXPERIENTIAL } 487 return 0 488} 489 490// Does the row even CARRY a signature of the right shape? This is a cheap pre-answer, not the verdict: a 491// row failing it is honestly unsigned, a row passing it still has to satisfy at_verify_row. 492func da_row_signed_shape(b: *u8, s: i64, e: i64) -> i64 { 493 let pl: i64 = da_slen(DA_C5_PUBTAG) 494 let sl: i64 = da_slen(DA_C5_SIGTAG) 495 let pk: i64 = at_find(b, s, e, DA_C5_PUBTAG, pl) 496 if pk < 0 { return 0 } 497 let sk: i64 = at_find(b, s, e, DA_C5_SIGTAG, sl) 498 if sk < 0 { return 0 } 499 if pk + pl + DA_C5_PUBHEX > e { return 0 } 500 if sk + sl + DA_C5_SIGHEX > e { return 0 } 501 return 1 502} 503 504// THE PURE CLASSIFIER, over an ALREADY-READ carrier. Path resolution is the caller's job, exactly as it is 505// for da_c4_partition, which is what lets every state be measured against a fixture instead of against 506// whatever the live status directory happens to hold this minute. 507// loadable = 1 when the buffer came from evclass_<domain>.conf (the name ss_class_load loads), 508// 0 when it came from the .UNSIGNED-CANDIDATE twin (a name nothing loads). 509// out[0]=rows out[1]=signed-shaped out[2]=verified-and-loadable out[3]=refused out[4]=last refusal rc 510// out[5]=dissent rows (verdict=fail) out[6]=verified-but-in-a-carrier-nothing-loads 511func da_c5_classify(b: *u8, n: i64, keys: *u8, kn: i64, loadable: i64, out: *i64) -> i64 { 512 out[0] = 0 513 out[1] = 0 514 out[2] = 0 515 out[3] = 0 516 out[4] = 0 - 1 517 out[5] = 0 518 out[6] = 0 519 out[7] = 0 520 if n <= 0 { return DA_C5_ABSENT } 521 var ls: i64 = 0 522 var p: i64 = 0 523 while p <= n { 524 var eol: i64 = 0 525 if p == n { eol = 1 } else { if b[p] == (DA_NL as u8) { eol = 1 } } 526 if eol == 1 { 527 if p > ls { if b[ls] != (DA_HASH as u8) { 528 let cls: i64 = da_row_class(b, ls, p) 529 // UNKNOWN IS ITS OWN BUCKET. A row whose class token is none of the five declared classes 530 // is NOT admitted -- permitted by omission is not permitted by declaration, and that 531 // omission is the exact defect nx_evattest records for the oracle class. But it is COUNTED 532 // and printed, because a row dropped in silence is indistinguishable from a file that 533 // never held it, and the carrier would then read ABSENT while plainly containing text. 534 if cls == 0 { out[7] = out[7] + 1 } 535 if cls != 0 { 536 out[0] = out[0] + 1 537 if da_row_has(b, ls, p, "verdict=fail" as *u8) == 1 { out[5] = out[5] + 1 } 538 if da_row_signed_shape(b, ls, p) == 1 { 539 out[1] = out[1] + 1 540 // NO REGISTRY, NO VERDICT. Calling at_verify_row with an empty registry would 541 // return UNKNOWNKEY and manufacture a REFUSED finding out of our own blindness. 542 if kn > 0 { 543 let rc: i64 = at_verify_row(b, ls, p, cls, keys, kn) 544 if rc == AT_OK { 545 if loadable == 1 { out[2] = out[2] + 1 } else { out[6] = out[6] + 1 } 546 } else { 547 out[3] = out[3] + 1 548 out[4] = rc 549 } 550 } 551 } 552 } 553 } } 554 ls = p + 1 555 } 556 p = p + 1 557 } 558 if out[2] > 0 { return DA_C5_SIGNED } 559 if out[3] > 0 { return DA_C5_REFUSED } 560 if out[0] > 0 { return DA_C5_UNSIGNED } 561 return DA_C5_ABSENT 562} 563 564// C5 REPORTS AND DOES NOT REFUSE, exactly like C3 and C4. Strictly additive: no domain that is admitted 565// today can begin to be refused because of this, and the standard's own position is that an unproven 566// domain is admissible when it SAYS so -- what is forbidden is silent unprovenness. 567func da_c5(dom: *u8, sb: *u8) -> i64 { 568 let keys: *u8 = sys_mmap(DA_KEYCAP) 569 let kn: i64 = dp_read(DA_KEYREG, keys, DA_KEYCAP - 4) 570 let out: *i64 = sys_mmap(64) as *i64 571 var loadable: i64 = 1 572 var n: i64 = da_read_at(DA_EVPFX, dom, DA_EVSUF, sb, DA_SCAP - 4) 573 if n <= 0 { 574 loadable = 0 575 n = da_read_at(DA_EVPFX, dom, DA_EVCAND, sb, DA_SCAP - 4) 576 } 577 let st: i64 = da_c5_classify(sb, n, keys, kn, loadable, out) 578 da_w(" C5 second-method " as *u8) 579 if st == DA_C5_SIGNED { da_w("SIGNED" as *u8) } 580 if st == DA_C5_UNSIGNED { da_w("UNSIGNED-CANDIDATE" as *u8) } 581 if st == DA_C5_ABSENT { da_w("ABSENT" as *u8) } 582 if st == DA_C5_REFUSED { da_w("SIGNED-BUT-REFUSED" as *u8) } 583 da_w(" carrier=" as *u8) 584 if n <= 0 { da_w("none" as *u8) } else { 585 da_w(DA_EVPFX); da_w(dom) 586 if loadable == 1 { da_w(DA_EVSUF) } else { da_w(DA_EVCAND) } 587 } 588 da_w(" bytes=" as *u8); da_n(n) 589 da_w(" rows=" as *u8); da_n(out[0]) 590 da_w(" signed_shape=" as *u8); da_n(out[1]) 591 da_w(" verified=" as *u8); da_n(out[2]) 592 da_w(" refused=" as *u8); da_n(out[3]) 593 da_w(" refusal_rc=" as *u8); da_n(out[4]) 594 da_w(" dissent=" as *u8); da_n(out[5]) 595 da_w(" unknown_class=" as *u8); da_n(out[7]) 596 da_w(" verifier=" as *u8) 597 if kn > 0 { da_w("REACHABLE" as *u8) } else { da_w("UNREACHABLE" as *u8) } 598 da_w(" keyreg_bytes=" as *u8); da_n(kn); da_w("\n" as *u8) 599 if kn <= 0 { da_w(" C5 NOTE: the key registry is unreadable, so NO row can be called SIGNED and every row is treated as UNSIGNED at most -- a verifier that cannot be reached must lower the claim, never raise it\n" as *u8) } 600 if loadable == 0 { if n > 0 { da_w(" C5 NOTE: the row sits in the .UNSIGNED-CANDIDATE carrier, a name nx_sota_status ss_class_load never loads, so it cannot count as a second method class whatever it contains -- and that is the recorded-absence the standard asks for, not a fake\n" as *u8) } } 601 if out[6] > 0 { da_w(" C5 NOTE: a row in that unloadable carrier DOES verify, and it is STILL not a second method class, because nothing reads that filename. Renaming it is an operator act, not a gate's\n" as *u8) } 602 if out[3] > 0 { da_w(" C5 NOTE: a row carries a signature and the verifier REFUSED it. rc 1=no-signature-shape 2=bad-signature 3=unregistered-key 4=role-not-permitted 5=oracle-row-names-no-reference. This is NOT the same finding as an honestly unsigned row and must never be reported as one\n" as *u8) } 603 if out[5] > 0 { da_w(" C5 NOTE: a row records verdict=fail -- DISSENT. The outside witness disagreed with us, which is the C5 process working rather than failing\n" as *u8) } 604 if out[7] > 0 { da_w(" C5 NOTE: the carrier holds a line whose class token is none of the five the verifier declares, so it was NOT admitted -- and it is counted here rather than dropped in silence, because a silently dropped row makes a populated carrier read ABSENT\n" as *u8) } 605 return st 606} 607 608// ==== C6 THE STAMP AND THE BOARD AGREE -- A COMPOUND ASSERTION, DECOMPOSED, WITH ITS DEAD CONJUNCT NAMED 609// 610// ADMISSION_STANDARD C6 wants TWO things at once: nx_swcompare_evidence <domain> = MEASURED-HONEST AND 611// nx_sota_status why <domain> = PROVEN. A compound assertion that will not name its failing conjunct is a 612// false-alarm generator, so this splits them and answers each on its own evidence. 613// 614// CONJUNCT 1, THE STAMP -- ANSWERED FROM THE ARTIFACT, NOT BY FORKING. MEASURED 2026-08-25 on the live 615// box: one forked nx_swcompare_evidence run for the domain `lang` (18 axes, ONE declared gate -- the small 616// end of the range) took ~25 s wall, from a launch marker at epoch 1787715057 to the stamp it wrote at 617// epoch 1787715082. The sweep denominator is 61 compare domains, so forking inside the admission call 618// would cost roughly 25 minutes for one --all. The producer already agrees in its own source: ev_stamp 619// exists to "materialize the verdict for the fast status surface" precisely because the deep verdict is 620// too slow to inline. So C6 READS knowledge/status/evstamp_<domain>.verdict, and says which it used. 621// 622// AND THE STAMP GETS FOUR ANSWERS, NOT TWO, BECAUSE ok=0 HAS TWO MEANINGS. MEASURED on dcc the same day: 623// its stamp reads grounded=0/0 -- ZERO present axes -- while this gate counts 65 matrix rows and 47 624// grounded symbols for the same domain. The stamp did not judge dcc harshly; it never saw dcc at all (it 625// enumerates the nishihost compare twin, and dcc.matrix exists only in the publishing tree). Reporting 626// that as RED would publish a verdict about an empty read. BLIND is an abstention: it can neither acquit 627// nor convict, and it names why. 628// 629// CONJUNCT 2, THE BOARD -- STRUCTURALLY UNAVAILABLE, AND THAT IS A MEASUREMENT. nx_sota_status has no 630// `why <domain>` verb: its main() takes argc/argv and never reads argv, so every invocation prints the 631// whole board. It writes ONE estate-aggregate line (NX-EVIDENCE-HONESTY proven= of ... VERDICT=) and no 632// per-domain verdict anywhere, so there is no durable artifact to read either. Forking it cannot answer 633// the question at ANY price -- the cost is not what makes it unavailable, the missing verb is. 634// What IS decidable, and what this gate therefore measures, is whether the domain is in the board's 635// DOMAIN SET at all: the board enumerates knowledge/compare/*.matrix and *.axes. A domain missing there 636// can never appear in its output as PROVEN or as RED -- which is dcc's real situation and is worth saying. 637// ⇒ C6 ALWAYS ABSTAINS, and the abstention carries the conjunct that could not be evaluated and why. 638const DA_STAMPPFX: *u8 = "knowledge/status/evstamp_" 639const DA_STAMPSUF: *u8 = ".verdict" 640// The tree nx_sota_status enumerates to build its domain set. It is the same PATH as DA_GATESDIR today and 641// is declared SEPARATELY on purpose: one constant serving two unrelated purposes can never be moved for 642// either of them, and these two move for different reasons (where .gates maps live, versus which compare 643// twin the board reads). 644const DA_BOARDDIR: *u8 = "knowledge/compare/" 645// ---- SECOND BOARD PREFIX (2026-08-27) ----------------------------------------------------------- 646// This mirror exists to answer "can nx_sota_status see this domain at all", so it must track what 647// that organ ACTUALLY enumerates. On 2026-08-26 nx_sota_status was widened to enumerate BOTH trees, 648// because the /compare regen chdirs to buildroot and every recently admitted domain's .matrix lives 649// there -- roughly forty domains could not appear in the board's output at all, not as RED and not as 650// PROVEN, while its ratio still read like the whole estate. Fixing the board and leaving its mirror 651// pinned to one tree made this check report a blindness that no longer existed. 652// ORDER IS DELIBERATE AND THE CHANGE IS STRICTLY ADDITIVE: the primary tree is probed FIRST and 653// unchanged, buildroot only as a fallback, so this can turn a NOT-IN-SET into an IN-SET and never the 654// reverse. No domain that resolved before can stop resolving. 655const DA_BOARDDIR2: *u8 = "buildroot/knowledge/compare/" 656const DA_BOARDMAT: *u8 = ".matrix" 657const DA_BOARDAXES: *u8 = ".axes" 658const DA_STAMPCAP: i64 = 4096 659const DA_SLASH: i64 = 47 660const DA_C6A_ABSENT: i64 = 0 661const DA_C6A_HONEST: i64 = 1 662const DA_C6A_RED: i64 = 2 663const DA_C6A_BLIND: i64 = 3 664const DA_C6B_NOT_IN_SET: i64 = 0 665const DA_C6B_IN_SET: i64 = 1 666 667// The integer AFTER the slash in "<key>=<num>/<den>". Returns -1 when the key is absent, when there is no 668// numerator, when there is no slash, or when nothing follows it -- ALL of which must read as "I could not 669// look", never as 0, because 0 present axes is precisely the finding this parser exists to detect. 670func da_kv_den(buf: *u8, n: i64, key: *u8) -> i64 { 671 let kl: i64 = da_slen(key) 672 let at: i64 = da_wfind(buf, n, key, 0, kl) 673 if at < 0 { return 0 - 1 } 674 var i: i64 = at + kl 675 if i >= n { return 0 - 1 } 676 if buf[i] != (DA_EQ as u8) { return 0 - 1 } 677 i = i + 1 678 var num: i64 = 0 679 var go: i64 = 1 680 while go == 1 { 681 if i >= n { go = 0 } else { 682 let c: i64 = buf[i] as i64 683 if c < DA_D0 { go = 0 } else { 684 if c > DA_D9 { go = 0 } else { num = num + 1; i = i + 1 } 685 } 686 } 687 } 688 if num == 0 { return 0 - 1 } 689 if i >= n { return 0 - 1 } 690 if buf[i] != (DA_SLASH as u8) { return 0 - 1 } 691 i = i + 1 692 var v: i64 = 0 693 var any: i64 = 0 694 var go2: i64 = 1 695 while go2 == 1 { 696 if i >= n { go2 = 0 } else { 697 let c2: i64 = buf[i] as i64 698 if c2 < DA_D0 { go2 = 0 } else { 699 if c2 > DA_D9 { go2 = 0 } else { v = v * 10 + (c2 - DA_D0); any = 1; i = i + 1 } 700 } 701 } 702 } 703 if any == 0 { return 0 - 1 } 704 return v 705} 706 707// PURE: classify an ALREADY-READ stamp. matrix_rows is what the CALLER counted for the same domain, and it 708// is the only thing that can tell an empty stamp about a real domain (BLIND) from an honest RED about a 709// domain that really has nothing (RED). Without that second opinion the two are indistinguishable. 710// out[0]=ok out[1]=present_axes out[2]=grounded out[3]=epoch out[4]=redseen 711func da_c6a_classify(sbuf: *u8, sn: i64, matrix_rows: i64, out: *i64) -> i64 { 712 out[0] = 0 - 1 713 out[1] = 0 - 1 714 out[2] = 0 - 1 715 out[3] = 0 - 1 716 out[4] = 0 - 1 717 if sn <= 0 { return DA_C6A_ABSENT } 718 out[0] = da_kv(sbuf, sn, "ok" as *u8) 719 out[2] = da_kv(sbuf, sn, "grounded" as *u8) 720 out[1] = da_kv_den(sbuf, sn, "grounded" as *u8) 721 out[3] = da_kv(sbuf, sn, "epoch" as *u8) 722 out[4] = da_kv(sbuf, sn, "redseen" as *u8) 723 if out[0] == 1 { return DA_C6A_HONEST } 724 if out[1] == 0 { if matrix_rows > 0 { return DA_C6A_BLIND } } 725 return DA_C6A_RED 726} 727 728// Is the domain in the board's DOMAIN SET? The directory is a parameter so this is fixturable; the shipped 729// caller pins it to the tree nx_sota_status actually enumerates. 730func da_boardset_in(d: *u8, dom: *u8, sb: *u8) -> i64 { 731 if da_read_at(d, dom, DA_BOARDMAT, sb, DA_SCAP - 4) > 0 { return DA_C6B_IN_SET } 732 if da_read_at(d, dom, DA_BOARDAXES, sb, DA_SCAP - 4) > 0 { return DA_C6B_IN_SET } 733 return DA_C6B_NOT_IN_SET 734} 735func da_c6b_boardset(dom: *u8, sb: *u8) -> i64 { 736 if da_boardset_in(DA_BOARDDIR, dom, sb) == DA_C6B_IN_SET { return DA_C6B_IN_SET } 737 return da_boardset_in(DA_BOARDDIR2, dom, sb) 738} 739 740// C6 REPORTS AND DOES NOT REFUSE, exactly like C3, C4 and C5. Returns the stamp state. 741func da_c6(dom: *u8, sb: *u8, matrix_rows: i64) -> i64 { 742 let stb: *u8 = sys_mmap(DA_STAMPCAP) 743 let sn: i64 = da_read_at(DA_STAMPPFX, dom, DA_STAMPSUF, stb, DA_STAMPCAP - 4) 744 let out: *i64 = sys_mmap(64) as *i64 745 let a: i64 = da_c6a_classify(stb, sn, matrix_rows, out) 746 let b: i64 = da_c6b_boardset(dom, sb) 747 da_w(" C6 stamp/board ABSTAIN conjunct1_stamp=" as *u8) 748 if a == DA_C6A_HONEST { da_w("MEASURED-HONEST" as *u8) } 749 if a == DA_C6A_RED { da_w("RED" as *u8) } 750 if a == DA_C6A_BLIND { da_w("BLIND" as *u8) } 751 if a == DA_C6A_ABSENT { da_w("ABSENT" as *u8) } 752 da_w(" ok=" as *u8); da_n(out[0]) 753 da_w(" grounded=" as *u8); da_n(out[2]); da_w("/" as *u8); da_n(out[1]) 754 da_w(" redseen=" as *u8); da_n(out[4]) 755 da_w(" epoch=" as *u8); da_n(out[3]) 756 da_w(" matrix_rows_here=" as *u8); da_n(matrix_rows) 757 da_w(" source=" as *u8); da_w(DA_STAMPPFX); da_w(dom); da_w(DA_STAMPSUF) 758 da_w(" (READ, NOT FORKED: a forked run measured ~25s for one domain)\n" as *u8) 759 da_w(" conjunct2_board=UNEVALUABLE " as *u8) 760 if b == DA_C6B_IN_SET { 761 da_w("domain-IS-in-the-board-set-but-the-board-publishes-no-per-domain-verdict\n" as *u8) 762 da_w(" C6 NOTE: nx_sota_status has no `why <domain>` verb -- its main ignores argv -- and the only line it makes durable is one estate aggregate, so no per-domain PROVEN or RED exists anywhere for this gate to agree with\n" as *u8) 763 } else { 764 da_w("domain-is-NOT-in-the-board-domain-set\n" as *u8) 765 da_w(" C6 NOTE: the board enumerates knowledge/compare for .matrix and .axes and this domain has neither there, so it can never appear in the board output at all -- neither PROVEN nor RED. That is a missing subject, not a failing one\n" as *u8) 766 } 767 if a == DA_C6A_BLIND { da_w(" C6 NOTE: the stamp reports ZERO present axes for a domain whose matrix this gate reads as non-empty, so the stamp measured an empty subject. Its ok=0 is not a verdict about these claims and is deliberately not published as RED\n" as *u8) } 768 if a == DA_C6A_ABSENT { da_w(" C6 NOTE: no evidence stamp exists for this domain -- nx_swcompare_evidence has never run against it, which is an absence of evidence and not evidence of absence\n" as *u8) } 769 return a 770}