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}