code wiki / (root) / nx_provcensus.nx

nx_provcensus.nx source

↩ module page · 334 lines · 18188 B

1// nx_provcensus.nx -- THE FLEET PROVENANCE-DRIFT CENSUS (2026-08-26). 2// 3// nx_organ_ship consults nx_provcheck so a gate is rebuilt when its import CLOSURE drifted even with no 4// import edge to notice. Two gates were caught DRIFTED by hand the day that shipped. NOBODY HAD MEASURED 5// THE FLEET, so nobody knew how many ships had already proved the wrong subject -- and a rate nobody has 6// measured is not a small number, it is an unknown one. This organ measures it. 7// 8// POPULATION: every "<name>_gate.provenance" sidecar in the estate root -- exactly "the gates that have a 9// provenance record" -- enumerated from ONE directory via nx_dir_list rather than a tree walk. That is 10// deliberate and measured: nx_shelltool find AND glob both return matches=0 with corpus_complete=0 over 11// this root for sidecars that demonstrably exist (2026-08-26), because the walk exhausts its budget in 12// the subtrees before it reports the root's own files. A tree scanner cannot establish this population at 13// all, and only its coverage envelope stops the zero being published as absence. 14// 15// PARTITION -- each bucket its own remedy, printed with the count, and the parts are SUMMED against the 16// population rather than assumed to agree: 17// CURRENT | DRIFTED | UNRECORDED | NOSIDECAR | UNREADABLE (+ SKIPPED-OVER-BUDGET, reconciled too) 18// 19// NO-RECORD is reported BESIDE the partition, never inside it: it counts "<name>_gate.elf" at the root 20// with no sidecar at all. That is a different question with a different denominator, and folding it in 21// would silently break the reconciliation -- a bucket that overlaps a partition must be a separate axis. 22// 23// Composes nx_provcheck per row instead of re-deriving CURRENT/DRIFTED, so there stays exactly ONE 24// definition of the verdict in the estate and this inherits every future fix to it. All judgement lives 25// in nx_provcensus_lib.nx so the gate can mutation-prove it in-process. 26// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 27import "nx_dir.nx" 28import "nx_tool_run.nx" 29import "nx_provcensus_lib.nx" 30 31// Root holds 34,931 entries (measured 2026-08-26). These caps sit far above that and REFUSE rather than 32// truncate: a cap reached in silence becomes a measurement nobody knows is partial. 33const PV_MAXENT: i64 = 262144 34const PV_ROWBYTES: i64 = 32 35const PV_ARENA: i64 = 16777216 36const PV_RESBYTES: i64 = 40 37const PV_CAP: i64 = 262144 38const PV_TMO: i64 = 90000 // per child, matching nx_provcheck's own child timeout 39const PV_PATHMAX: i64 = 1024 40const PV_MAXCLASS: i64 = 16384 41const PV_COUNTS: i64 = 40 // PCX_NBUCKET slots of 8 42const PV_ARGVSLOTS: i64 = 64 43const PV_NUMSCRATCH: i64 = 32 44const PV_B10: i64 = 10 45const PV_ZERO: i64 = 48 46const PV_LENSLOT: i64 = 16 // one i64 out-parameter slot for sys_read_file's length 47// Default wall budget. Derived, not picked: nx_provcheck forks nx_closurehash once per row and the two 48// together were measured in the low tens of milliseconds, so 20 minutes covers several thousand rows 49// with headroom. Over-budget rows are SKIPPED, COUNTED, and force coverage_complete=0 -- announced, 50// never silent. Override with argv[2]. 51const PV_BUDGET_MS: i64 = 1200000 52 53func pv_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 54func pv_num(v: i64) -> i64 { 55 let b: *u8 = sys_mmap(PV_NUMSCRATCH) 56 var m: i64 = v 57 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 58 var i: i64 = PV_NUMSCRATCH - 1 59 if m == 0 { b[i] = PV_ZERO as u8; i = i - 1 } 60 while m > 0 { b[i] = (PV_ZERO + m % PV_B10) as u8; m = m / PV_B10; i = i - 1 } 61 sys_write(1, (b as i64 + i + 1) as *u8, PV_NUMSCRATCH - 1 - i) 62 return 0 63} 64func pv_cat(d: *u8, o: i64, s: *u8) -> i64 { var p: i64 = o; var i: i64 = 0; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } return p } 65 66func main(argc: i64, argv: *i64) -> i64 { 67 var root: *u8 = "." as *u8 68 if argc >= 2 { let r: *u8 = argv[1] as *u8; if r[0] != (0 as u8) { root = r } } 69 var budget: i64 = PV_BUDGET_MS 70 71 pv_puts("=== NX-PROVCENSUS -- fleet provenance drift: does each gate binary match the sources it was built from?\n" as *u8) 72 pv_puts("population = every *_gate.provenance sidecar under root=" as *u8); pv_puts(root); pv_puts("\n" as *u8) 73 74 // ---- the instrument must exist before we report on anything ------------------------------------- 75 let pcpath: *u8 = sys_mmap(PV_PATHMAX) 76 var po: i64 = pv_cat(pcpath, 0, root) 77 po = pv_cat(pcpath, po, "/nx_provcheck.elf" as *u8) 78 pcpath[po] = 0 as u8 79 let pfd: i64 = sys_openat_rd(pcpath) 80 if pfd < 0 { 81 pv_puts("REFUSED: nx_provcheck.elf not found at " as *u8); pv_puts(pcpath) 82 pv_puts(" -- the census composes it and will not re-derive its verdict. Nothing measured.\n" as *u8) 83 sys_exit(2); return 2 84 } 85 sys_close(pfd) 86 87 // ---- enumerate the root directory --------------------------------------------------------------- 88 let rows: *NxDirRow = sys_mmap(PV_MAXENT * PV_ROWBYTES) as *NxDirRow 89 let arena: *u8 = sys_mmap(PV_ARENA) 90 let res: *NxDirResult = sys_mmap(PV_RESBYTES) as *NxDirResult 91 let dv: i64 = nx_dir_list(root, rows, PV_MAXENT, arena, PV_ARENA, 0, res) 92 if dv != NX_DIR_OK { 93 pv_puts("REFUSED: directory enumeration returned " as *u8); pv_puts(nx_dir_verdict_name(dv)) 94 pv_puts(" -- a partial listing cannot establish a population, so no partition is published.\n" as *u8) 95 sys_exit(2); return 2 96 } 97 let nent: i64 = res.n_filled 98 pv_puts("root entries enumerated=" as *u8); pv_num(nent); pv_puts(" (verdict=OK, so this is the whole directory, not a prefix)\n" as *u8) 99 100 // ---- split the two name classes ----------------------------------------------------------------- 101 let sidecars: *i64 = sys_mmap(PV_MAXCLASS * 8) as *i64 102 let gateelfs: *i64 = sys_mmap(PV_MAXCLASS * 8) as *i64 103 var nside: i64 = 0 104 var nelf: i64 = 0 105 var overflow: i64 = 0 106 var i: i64 = 0 107 while i < nent { 108 let row: *NxDirRow = nx_dir_row_at(rows, i) 109 if nx_dir_row_is_regular_file(row) == 1 { 110 if pcx_ends_with(row.name_ptr, row.name_len, "_gate.provenance" as *u8) == 1 { 111 if nside < PV_MAXCLASS { sidecars[nside] = i; nside = nside + 1 } else { overflow = 1 } 112 } 113 if pcx_ends_with(row.name_ptr, row.name_len, "_gate.elf" as *u8) == 1 { 114 if nelf < PV_MAXCLASS { gateelfs[nelf] = i; nelf = nelf + 1 } else { overflow = 1 } 115 } 116 } 117 i = i + 1 118 } 119 if overflow == 1 { 120 pv_puts("REFUSED: a name-class index filled its cap -- this would publish a FLOOR as a population.\n" as *u8) 121 sys_exit(2); return 2 122 } 123 pv_puts("population (gates WITH a provenance record) = " as *u8); pv_num(nside); pv_puts("\n" as *u8) 124 pv_puts("gate binaries at root = " as *u8); pv_num(nelf); pv_puts("\n\n" as *u8) 125 126 // ---- roster membership: which of these gates does anything actually RUN? ------------------------ 127 // A DRIFTED artifact nothing invokes is a hazard sitting still. A DRIFTED artifact the roster beat 128 // fires every beat is publishing a verdict about code that is not the tree. A bare DRIFTED count 129 // cannot separate them, so it sizes a campaign nobody can act on -- the reason has to travel with 130 // the count, and here the reason is "something runs this". 131 // 132 // TWO SURFACES, deliberately. Reading only the fast roster would report every slow-roster gate as 133 // uninvoked. nx_gate_roster_run's own GRR_CONF is the BARE path "knowledge/gateroster.conf", 134 // resolved against the beat's CWD -- the estate root -- so with root="." these are the SAME files 135 // the beat reads, not a same-named twin in the other knowledge tree. Composes sys_read_file, which 136 // sizes its buffer from the file and cannot short-read. 137 let rlen: *i64 = sys_mmap(PV_LENSLOT) as *i64 138 let fastp: *u8 = sys_mmap(PV_PATHMAX) 139 var fpo: i64 = pv_cat(fastp, 0, root) 140 fpo = pv_cat(fastp, fpo, "/knowledge/gateroster.conf" as *u8) 141 fastp[fpo] = 0 as u8 142 rlen[0] = 0 143 let fastb: *u8 = sys_read_file(fastp, rlen) 144 let fastn: i64 = rlen[0] 145 146 let slowp: *u8 = sys_mmap(PV_PATHMAX) 147 var spo: i64 = pv_cat(slowp, 0, root) 148 spo = pv_cat(slowp, spo, "/knowledge/gateroster_slow.conf" as *u8) 149 slowp[spo] = 0 as u8 150 rlen[0] = 0 151 let slowb: *u8 = sys_read_file(slowp, rlen) 152 let slown: i64 = rlen[0] 153 154 // sys_read_file returns a NULL pointer when it could not OPEN the file, and a non-null pointer with 155 // length 0 for a file that is merely empty. Those are different facts and only the pointer 156 // separates them, so the readability flag is taken from the pointer, never from the length. 157 var fastok: i64 = 0 158 if fastb as i64 != 0 { fastok = 1 } 159 var slowok: i64 = 0 160 if slowb as i64 != 0 { slowok = 1 } 161 var roster_readable: i64 = 0 162 if fastok == 1 { if slowok == 1 { roster_readable = 1 } } 163 let fastrows: i64 = pcx_roster_rows(fastb, fastn) 164 let slowrows: i64 = pcx_roster_rows(slowb, slown) 165 166 pv_puts("roster surfaces -- a gate is INVOKED iff it is a LIVE row of one of these:\n" as *u8) 167 pv_puts(" knowledge/gateroster.conf readable=" as *u8); pv_num(fastok) 168 pv_puts(" live_rows=" as *u8); pv_num(fastrows); pv_puts("\n" as *u8) 169 pv_puts(" knowledge/gateroster_slow.conf readable=" as *u8); pv_num(slowok) 170 pv_puts(" live_rows=" as *u8); pv_num(slowrows); pv_puts("\n" as *u8) 171 pv_puts(" (live rows exclude ';' comments and blanks -- gateroster.conf carries re-homing notes that\n" as *u8) 172 pv_puts(" NAME DOZENS OF GATES IN PROSE, and a substring search would count every one as rostered)\n\n" as *u8) 173 174 var d_on: i64 = 0 175 var d_off: i64 = 0 176 var d_on_fast: i64 = 0 177 var d_on_slow: i64 = 0 178 179 // ---- measure each row by composing nx_provcheck -------------------------------------------------- 180 let counts: *i64 = sys_mmap(PV_COUNTS) as *i64 181 var b: i64 = 0 182 while b < PCX_NBUCKET { counts[b] = 0; b = b + 1 } 183 let gname: *u8 = sys_mmap(PV_PATHMAX) 184 let out: *u8 = sys_mmap(PV_CAP) 185 let ol: *i64 = sys_mmap(16) as *i64 186 let av: *i64 = sys_mmap(PV_ARGVSLOTS) as *i64 187 let suflen: i64 = pcx_slen(".provenance" as *u8) 188 let t0: i64 = sys_now_ms() 189 var skipped: i64 = 0 190 var examined: i64 = 0 191 192 pv_puts("-- WORKLIST: every row that is not CURRENT is named here with its remedy --\n" as *u8) 193 var k: i64 = 0 194 while k < nside { 195 let el: i64 = sys_now_ms() - t0 196 if el > budget { 197 skipped = skipped + 1 198 } else { 199 let row: *NxDirRow = nx_dir_row_at(rows, sidecars[k]) 200 var c: i64 = 0 201 while c < row.name_len - suflen { gname[c] = row.name_ptr[c]; c = c + 1 } 202 gname[c] = 0 as u8 203 av[0] = pcpath as i64 204 av[1] = gname as i64 205 av[2] = root as i64 206 av[3] = 0 207 ol[0] = 0 208 tr_run_capture_to(pcpath, av, out, PV_CAP - 4, ol, PV_TMO) 209 let bkt: i64 = pcx_classify(out, ol[0]) 210 counts[bkt] = counts[bkt] + 1 211 examined = examined + 1 212 213 // Membership is asked of BOTH surfaces, and only of a surface that actually loaded. 214 var on_f: i64 = 0 215 var on_s: i64 = 0 216 if fastok == 1 { on_f = pcx_roster_has(fastb, fastn, gname) } 217 if slowok == 1 { on_s = pcx_roster_has(slowb, slown, gname) } 218 var onr: i64 = 0 219 if on_f == 1 { onr = 1 } 220 if on_s == 1 { onr = 1 } 221 222 if bkt == PCX_DRIFTED { 223 if onr == 1 { d_on = d_on + 1 } else { d_off = d_off + 1 } 224 if on_f == 1 { d_on_fast = d_on_fast + 1 } 225 if on_s == 1 { d_on_slow = d_on_slow + 1 } 226 } 227 228 if bkt != PCX_CURRENT { 229 // ON-ROSTER is a POSITIVE witness: one live row is enough, so it stands even if the 230 // other surface failed to load. off-roster is an ABSENCE claim and is only credible 231 // when BOTH loaded -- otherwise the row says so, rather than being quietly demoted to 232 // "nothing runs this", which is the direction that shrinks the worklist and flatters. 233 var tag: *u8 = " [off-roster]" as *u8 234 if roster_readable == 0 { tag = " [roster-UNREADABLE]" as *u8 } 235 if onr == 1 { tag = " [ON-ROSTER]" as *u8 } 236 pv_puts(" " as *u8); pv_puts(pcx_bucket_name(bkt)); pv_puts(tag); pv_puts(" " as *u8); pv_puts(gname) 237 pv_puts(" -- " as *u8); pv_puts(pcx_bucket_remedy(bkt)); pv_puts("\n" as *u8) 238 } 239 } 240 k = k + 1 241 } 242 243 // ---- NO-RECORD: a SEPARATE AXIS, deliberately not a partition member ------------------------------ 244 let sp: *u8 = sys_mmap(PV_PATHMAX) 245 let elflen: i64 = pcx_slen(".elf" as *u8) 246 var norecord: i64 = 0 247 var e: i64 = 0 248 while e < nelf { 249 let row: *NxDirRow = nx_dir_row_at(rows, gateelfs[e]) 250 var so: i64 = pv_cat(sp, 0, root) 251 sp[so] = 47 as u8 252 so = so + 1 253 var c2: i64 = 0 254 while c2 < row.name_len - elflen { sp[so + c2] = row.name_ptr[c2]; c2 = c2 + 1 } 255 so = so + c2 256 so = pv_cat(sp, so, ".provenance" as *u8) 257 sp[so] = 0 as u8 258 let sfd: i64 = sys_openat_rd(sp) 259 if sfd < 0 { norecord = norecord + 1 } else { sys_close(sfd) } 260 e = e + 1 261 } 262 263 // ---- publish ------------------------------------------------------------------------------------- 264 pv_puts("\n-- PARTITION over the " as *u8); pv_num(nside); pv_puts(" gates that HAVE a provenance record --\n" as *u8) 265 var q: i64 = 0 266 while q < PCX_NBUCKET { 267 pv_puts(" " as *u8); pv_puts(pcx_bucket_name(q)); pv_puts("=" as *u8); pv_num(counts[q]); pv_puts("\n" as *u8) 268 q = q + 1 269 } 270 pv_puts(" SKIPPED-OVER-BUDGET=" as *u8); pv_num(skipped); pv_puts("\n" as *u8) 271 let tot: i64 = pcx_total(counts) 272 pv_puts(" sum(buckets)=" as *u8); pv_num(tot) 273 pv_puts(" + skipped=" as *u8); pv_num(skipped) 274 pv_puts(" = " as *u8); pv_num(tot + skipped) 275 pv_puts(" population=" as *u8); pv_num(nside); pv_puts("\n" as *u8) 276 277 var reconciled: i64 = 0 278 if tot + skipped == nside { reconciled = 1 } 279 var coverage_complete: i64 = 0 280 if skipped == 0 { if reconciled == 1 { coverage_complete = 1 } } 281 pv_puts(" partition_reconciles=" as *u8); pv_num(reconciled) 282 pv_puts(" coverage_complete=" as *u8); pv_num(coverage_complete); pv_puts("\n" as *u8) 283 // ---- the split that turns a count into a worklist ------------------------------------------------ 284 var split_ok: i64 = 1 285 pv_puts("\n-- DRIFTED SPLIT BY INVOCATION: the actionable subset --\n" as *u8) 286 if roster_readable == 0 { 287 split_ok = 0 288 pv_puts(" ABSTAINED: at least one roster conf could not be READ, so NO split is published.\n" as *u8) 289 pv_puts(" Every gate would otherwise read off-roster, which shrinks the actionable worklist to\n" as *u8) 290 pv_puts(" nothing and looks like good news. An axis that cannot see must abstain, never acquit.\n" as *u8) 291 } 292 if roster_readable == 1 { 293 pv_puts(" DRIFTED-ON-ROSTER=" as *u8); pv_num(d_on) 294 pv_puts(" <== a verdict about code that is not the tree, published EVERY BEAT. Rebuild these first.\n" as *u8) 295 pv_puts(" DRIFTED-OFF-ROSTER=" as *u8); pv_num(d_off) 296 pv_puts(" <== hazard sitting still: nothing invokes them, so nothing is consuming a wrong verdict.\n" as *u8) 297 pv_puts(" sum=" as *u8); pv_num(d_on + d_off) 298 pv_puts(" DRIFTED=" as *u8); pv_num(counts[PCX_DRIFTED]); pv_puts("\n" as *u8) 299 var dsplit: i64 = 0 300 if d_on + d_off == counts[PCX_DRIFTED] { dsplit = 1 } 301 if dsplit == 0 { split_ok = 0 } 302 pv_puts(" drifted_split_reconciles=" as *u8); pv_num(dsplit); pv_puts("\n" as *u8) 303 pv_puts(" witnesses by surface: fast=" as *u8); pv_num(d_on_fast) 304 pv_puts(" slow=" as *u8); pv_num(d_on_slow); pv_puts("\n" as *u8) 305 pv_puts(" (these two are OVERLAPPING WITNESSES, not a partition: a gate may be a live row of both,\n" as *u8) 306 pv_puts(" so they may sum above ON-ROSTER. The partition is ON-ROSTER + OFF-ROSTER = DRIFTED.)\n" as *u8) 307 } 308 309 pv_puts("\n-- SEPARATE AXIS (different denominator, deliberately NOT a partition member) --\n" as *u8) 310 pv_puts(" gate binaries at root with NO .provenance at all: NO-RECORD=" as *u8); pv_num(norecord) 311 pv_puts(" of " as *u8); pv_num(nelf); pv_puts("\n" as *u8) 312 313 // An abstained or unreconciled invocation split is not a result, and must not be read as one. The 314 // EXIT CODE IS DELIBERATELY NOT CHANGED here: exit 0/1/3 are this organ's published contract about 315 // the PARTITION, which stands on its own reconciliation and is unaffected by the roster surfaces. 316 // Overloading exit 3 would conflate "the census ran out of budget" with "the roster was unreadable", 317 // two states with different remedies. That is a stated imprecision, not an oversight: the alarm here 318 // is this line, and a consumer that needs to branch on it should read drifted_split_reconciles. 319 if split_ok == 0 { 320 pv_puts("\nSPLIT NOT PUBLISHED: the invocation split abstained or failed to reconcile, so the\n" as *u8) 321 pv_puts("ON-ROSTER / OFF-ROSTER numbers above must NOT be used to size a drain.\n" as *u8) 322 } 323 if reconciled == 0 { 324 pv_puts("\nREFUSED: the parts do not sum to the population -- an unreconciled partition is a leak, not a result.\n" as *u8) 325 sys_exit(1); return 1 326 } 327 if coverage_complete == 0 { 328 pv_puts("\nPARTIAL: the wall budget was reached. The DRIFTED count above is a FLOOR -- it bounds the true\n" as *u8) 329 pv_puts("count from BELOW, because every unexamined row could only add to it. Raise argv[2] to finish.\n" as *u8) 330 sys_exit(3); return 3 331 } 332 pv_puts("\nCENSUS COMPLETE -- every gate with a provenance record was examined.\n" as *u8) 333 return 0 334}