code wiki / _hdl_build / nx_anchorsweep.nx
nx_anchorsweep.nx source
↩ module page · 358 lines · 18101 B
1// nx_anchorsweep.nx -- DRIVE THE ANCHOR RUNG OVER THE 860-GATE NOANCHOR FAMILY.
2//
3// ★WHY THIS EXISTS AND WHY IT IS NOT A DESIGN DECISION. I reported the NOANCHOR family as blocked on
4// human judgement -- "establishing a verdict= tail where none exists" -- and filed that as the reason the
5// D001 lane could not be finished. TWO CALLS REFUTED IT (debt 1786239110): on nx_aa_gate,
6// nx_gate_anchor_edit proposed a candidate and nx_gate_migrate anchor answered
7// exit-code IDENTICAL / PASS-FAIL vector IDENTICAL / before anchor-free YES / after emits anchor YES /
8// verdict==exit AGREES -> GREEN ANCHORED.
9// The judge supplies the judgement, and it checks verdict==exit so it REFUSES A LYING ANCHOR rather than
10// blessing a wrong verdict. ★A CLAIM THAT SOMETHING NEEDS HUMAN AUTHORITY MUST BE EARNED BY TRYING THE
11// TOOL FIRST -- the cheapest experiment was two calls and I declared a blocker without running them.
12//
13// ★COMPOSES TWO RULERS, RE-IMPLEMENTS NEITHER: worklist from knowledge/status/drysweep.log (the census is
14// the single source of truth), judgement from nx_gate_anchor_edit + nx_gate_migrate anchor. This TALLIES.
15//
16// ★ALL FOUR DEFECTS FOUND IN nx_adoptsweep ARE FIXED HERE FROM THE START, not rediscovered:
17// 1. GENERATION SCAN -- drysweep.log is append-only with one block per census, each ended by
18// DRYSWEEP-TOTAL. Reading the whole file sums generations (measured: 605+586=1191 reported as the
19// population). Read between the SECOND-TO-LAST and LAST totals; that also picks up reclassification.
20// 2. EMPTY-WORKLIST REFUSAL -- a sweep that processes nothing must NOT report a clean run. The broken
21// v1 scan printed `partition: 0 of 0 -- SUMS` with no errors. A tooth that passes on the empty set
22// is not a tooth.
23// 3. PER-RUN CANDIDATE PATH -- a fixed /tmp path lets two concurrent sweeps hand each other's candidate
24// to the judge. Suffixed by <skip> so batches are disjoint BY CONSTRUCTION, not by luck.
25// 4. ALREADY-ANCHORED IS A SUCCESS, NOT AN ERROR -- and it is excluded from the rate's denominator.
26//
27// ⚠MUTATES SOURCE: nx_gate_migrate anchor COMMITS on acceptance (.premigrate kept, rule 13) and RESTORES
28// on divergence. <max> is mandatory; measure a batch, read it, then size the next one.
29//
30// nx_anchorsweep <max> [skip]
31// exit: 0 all anchored | 1 any REFUSED/ERROR | 2 usage | 3 NO-CONCLUSION (empty worklist / ruler missing)
32// license_tier: ORIGINAL No hw writes (Rule 26).
33import "nx_syscalls.nx"
34import "nx_artifact_root.nx"
35import "nx_tool_run.nx"
36const AN_MAGIC_20000: i64 = 20000
37const AN_MAGIC_4096: i64 = 4096
38const AN_MAGIC_4095: i64 = 4095
39
40const AN_CENSUS: *u8 = "knowledge/status/drysweep.log"
41const AN_LOG: *u8 = "knowledge/status/anchorsweep.log"
42const AN_SRCCAP: i64 = 4194304
43const AN_OUTCAP: i64 = 65536
44const AN_TIMEOUT: i64 = 120000
45const AN_NAMECAP: i64 = 512
46
47func an_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
48func an_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
49func an_n(fd: i64, v: i64) -> i64 {
50 if v == 0 { sys_write(fd, "0" as *u8, 1); return 0 }
51 var m: i64 = v
52 if m < 0 { sys_write(fd, "-" as *u8, 1); m = 0 - m }
53 let t: *u8 = sys_mmap(32); var k: i64 = 0
54 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
55 let o: *u8 = sys_mmap(32); var i: i64 = 0
56 while i < k { o[i] = t[k-1-i]; i = i + 1 }
57 sys_write(fd, o, k)
58 return 0
59}
60func an_has(buf: *u8, n: i64, pat: *u8) -> i64 {
61 var pl: i64 = 0
62 while pat[pl] != (0 as u8) { pl = pl + 1 }
63 if pl == 0 { return 0 }
64 var i: i64 = 0
65 while i + pl <= n {
66 var k: i64 = 0
67 var ok: i64 = 1
68 while k < pl { if buf[i+k] != pat[k] { ok = 0; k = pl } else { k = k + 1 } }
69 if ok == 1 { return 1 }
70 i = i + 1
71 }
72 return 0
73}
74func an_lastidx(buf: *u8, n: i64, pat: *u8) -> i64 {
75 var pl: i64 = 0
76 while pat[pl] != (0 as u8) { pl = pl + 1 }
77 if pl == 0 { return 0 - 1 }
78 var best: i64 = 0 - 1
79 var i: i64 = 0
80 while i + pl <= n {
81 var k: i64 = 0
82 var ok: i64 = 1
83 while k < pl { if buf[i+k] != pat[k] { ok = 0; k = pl } else { k = k + 1 } }
84 if ok == 1 { best = i }
85 i = i + 1
86 }
87 return best
88}
89func an_atoi(s: *u8) -> i64 {
90 var n: i64 = 0
91 var i: i64 = 0
92 while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { n = n*10 + (c-48) } } i = i + 1 }
93 return n
94}
95func an_cat(dst: *u8, o: i64, s: *u8) -> i64 {
96 var i: i64 = 0
97 var w: i64 = o
98 while s[i] != (0 as u8) { dst[w] = s[i]; w = w + 1; i = i + 1 }
99 dst[w] = 0 as u8
100 return w
101}
102
103// ★RESOLVE THE GATE'S SOURCE, DO NOT ASSUME ONE DIRECTORY. Gates live in BOTH runtime/_hdl_build/ and
104// runtime/ (nx_security_census_gate is in the latter). Guessing one and reporting ERROR for the other
105// would slander half the family as unprocessable. Try both through the estate's ONE resolver.
106func an_srcpath(gname: *u8, out: *u8) -> i64 {
107 let probe: *u8 = sys_mmap(AN_NAMECAP)
108 var o: i64 = an_cat(probe, 0, "runtime/_hdl_build/" as *u8)
109 o = an_cat(probe, o, gname)
110 o = an_cat(probe, o, ".nx" as *u8)
111 if ar_resolve(probe, out) == 1 { return 1 }
112 o = an_cat(probe, 0, "runtime/" as *u8)
113 o = an_cat(probe, o, gname)
114 o = an_cat(probe, o, ".nx" as *u8)
115 if ar_resolve(probe, out) == 1 { return 1 }
116 return 0
117}
118
119func main(argc: i64, argv: *i64) -> i64 {
120 if argc < 2 { an_puts("usage: nx_anchorsweep <max> [skip] -- MUTATES SOURCE via nx_gate_migrate anchor; max is mandatory\n" as *u8); sys_exit(2); return 2 }
121 let maxn: i64 = an_atoi(argv[1] as *u8)
122 var skipn: i64 = 0
123 if argc >= 3 { skipn = an_atoi(argv[2] as *u8) }
124 if maxn <= 0 { an_puts("nx_anchorsweep: max must be > 0 -- refusing an unbounded batch\n" as *u8); sys_exit(2); return 2 }
125
126 let aelf: *u8 = sys_mmap(AN_NAMECAP)
127 let melf: *u8 = sys_mmap(AN_NAMECAP)
128 if ar_resolve("nx_gate_anchor_edit.elf" as *u8, aelf) == 0 { an_puts("nx_anchorsweep: nx_gate_anchor_edit.elf unresolvable -- NO CONCLUSION\n" as *u8); sys_exit(3); return 3 }
129 if ar_resolve("nx_gate_migrate.elf" as *u8, melf) == 0 { an_puts("nx_anchorsweep: nx_gate_migrate.elf unresolvable -- NO CONCLUSION\n" as *u8); sys_exit(3); return 3 }
130
131 let cpath: *u8 = sys_mmap(AN_NAMECAP)
132 if ar_resolve(AN_CENSUS, cpath) == 0 { an_puts("nx_anchorsweep: drysweep.log not found -- run nx_drysweep first. NO CONCLUSION\n" as *u8); sys_exit(3); return 3 }
133 let src: *u8 = sys_mmap(AN_SRCCAP)
134 let n: i64 = ar_read(cpath, src, AN_SRCCAP - 1)
135 if n <= 0 { an_puts("nx_anchorsweep: census unreadable -- NO CONCLUSION\n" as *u8); sys_exit(3); return 3 }
136
137 // per-run candidate path (fix 3)
138 let candp: *u8 = sys_mmap(AN_NAMECAP)
139 var co: i64 = an_cat(candp, 0, "/tmp/anchorsweep_cand_" as *u8)
140 if skipn == 0 { candp[co] = 48 as u8; co = co + 1; candp[co] = 0 as u8 }
141 if skipn > 0 {
142 let ct: *u8 = sys_mmap(32)
143 var ck: i64 = 0
144 var cm: i64 = skipn
145 while cm > 0 { ct[ck] = (48 + (cm % 10)) as u8; cm = cm / 10; ck = ck + 1 }
146 var cj: i64 = 0
147 while cj < ck { candp[co] = ct[ck - 1 - cj]; co = co + 1; cj = cj + 1 }
148 candp[co] = 0 as u8
149 }
150 co = an_cat(candp, co, ".nx" as *u8)
151 an_puts(" candidate path: " as *u8); an_puts(candp); an_puts("\n" as *u8)
152
153 // ★ADMISSION CONTROL -- SHARES THE SAME 3 LEASES AS nx_adoptsweep ON PURPOSE. The saturating
154 // resource is CONCURRENT SOVEREIGN BUILDS across ALL sweeps, not per-organ; separate lease pools
155 // per organ would let 3 adopter + 3 anchor sweeps run and reproduce the outage exactly.
156 // Proven contract: LS-ACQUIRED / LS-BUSY <holder> / LS-RELEASED.
157 let lelf: *u8 = sys_mmap(AN_NAMECAP)
158 var gotlease: i64 = 0
159 if ar_resolve("nx_lease.elf" as *u8, lelf) == 1 {
160 let lout: *u8 = sys_mmap(AN_OUTCAP)
161 let llen: *i64 = sys_mmap(16) as *i64
162 let lav: *i64 = sys_mmap(64) as *i64
163 let s1: *u8 = "gatesweep_1"
164 let s2: *u8 = "gatesweep_2"
165 let s3: *u8 = "gatesweep_3"
166 var slot: i64 = 1
167 while slot <= 3 {
168 var lname: *u8 = s1
169 if slot == 2 { lname = s2 }
170 if slot == 3 { lname = s3 }
171 lout[0] = 0 as u8; llen[0] = 0
172 lav[0] = lelf as i64; lav[1] = "acquire" as *u8 as i64; lav[2] = lname as i64
173 lav[3] = candp as i64; lav[4] = "7200" as *u8 as i64; lav[5] = 0
174 tr_run_capture_to(lelf, lav, lout, AN_OUTCAP - 1, llen, AN_MAGIC_20000)
175 if llen[0] > 0 { if an_has(lout, llen[0], "LS-ACQUIRED" as *u8) == 1 {
176 gotlease = 1
177 an_puts(" lease: " as *u8); an_puts(lname); an_puts("\n" as *u8)
178 slot = 4
179 } }
180 if gotlease == 0 { slot = slot + 1 }
181 }
182 if gotlease == 0 {
183 an_puts(" ★ALL 3 SWEEP LEASES HELD -- refusing to start another concurrent sweep.\n" as *u8)
184 an_puts(" verdict=NO-CONCLUSION\n" as *u8)
185 sys_exit(3); return 3
186 }
187 }
188 if ar_resolve("nx_lease.elf" as *u8, lelf) == 0 {
189 an_puts(" ⚠nx_lease.elf unresolvable -- running WITHOUT concurrency admission control.\n" as *u8)
190 }
191
192 let lf: i64 = sys_openat_append(AN_LOG, 0x1a4)
193 let out: *u8 = sys_mmap(AN_OUTCAP)
194 let olen: *i64 = sys_mmap(16) as *i64
195 let gname: *u8 = sys_mmap(AN_NAMECAP)
196 let spath: *u8 = sys_mmap(AN_NAMECAP)
197 let av: *i64 = sys_mmap(64) as *i64
198
199 var seen: i64 = 0
200 var done: i64 = 0
201 var anch: i64 = 0
202 var refu: i64 = 0
203 var alrdy: i64 = 0
204 var errn: i64 = 0
205 an_puts("=== nx_anchorsweep -- anchoring the NOANCHOR family; nx_gate_migrate anchor is the judge ===\n" as *u8)
206
207 // newest generation only (fix 1)
208 var i: i64 = 0
209 let l1: i64 = an_lastidx(src, n, "DRYSWEEP-TOTAL" as *u8)
210 if l1 > 0 {
211 let l2: i64 = an_lastidx(src, l1, "DRYSWEEP-TOTAL" as *u8)
212 if l2 >= 0 { i = l2 }
213 }
214 while i < n {
215 var e: i64 = i
216 var eol: i64 = 0
217 while eol == 0 { if e >= n { eol = 1 } else { if src[e] == (10 as u8) { eol = 1 } else { e = e + 1 } } }
218 let ll: i64 = e - i
219 if ll > 20 {
220 let line: *u8 = (src as i64 + i) as *u8
221 if an_has(line, ll, "class=SKIP-NOANCHOR" as *u8) == 1 {
222 seen = seen + 1
223 if seen > skipn { if done < maxn {
224 var p: i64 = 0
225 var gs: i64 = 0 - 1
226 while p + 5 <= ll {
227 if line[p] == (103 as u8) { if line[p+1] == (97 as u8) { if line[p+2] == (116 as u8) { if line[p+3] == (101 as u8) { if line[p+4] == (61 as u8) { if gs < 0 { gs = p + 5 } } } } } }
228 p = p + 1
229 }
230 if gs >= 0 {
231 var k: i64 = 0
232 var stop: i64 = 0
233 while stop == 0 {
234 if gs + k >= ll { stop = 1 }
235 if gs + k < ll {
236 let c: i64 = line[gs+k] as i64
237 if c == 32 { stop = 1 }
238 if c != 32 {
239 if k >= AN_NAMECAP - 1 { stop = 1 }
240 if k < AN_NAMECAP - 1 { gname[k] = line[gs+k]; k = k + 1 }
241 }
242 }
243 }
244 gname[k] = 0 as u8
245 var cls: *u8 = "ERROR-NOSRC" as *u8
246 if an_srcpath(gname, spath) == 1 {
247 out[0] = 0 as u8; olen[0] = 0
248 av[0] = aelf as i64; av[1] = spath as i64; av[2] = candp as i64; av[3] = 0
249 tr_run_capture_to(aelf, av, out, AN_OUTCAP - 1, olen, AN_TIMEOUT)
250 cls = "ERROR-EDIT" as *u8
251 if olen[0] > 0 {
252 if an_has(out, olen[0], "NOEDIT" as *u8) == 1 { cls = "ALREADY-ANCHORED" as *u8 }
253 if an_has(out, olen[0], "CANDIDATE-WRITTEN" as *u8) == 1 {
254 out[0] = 0 as u8; olen[0] = 0
255 av[0] = melf as i64; av[1] = "anchor" as *u8 as i64; av[2] = gname as i64; av[3] = candp as i64; av[4] = 0
256 tr_run_capture_to(melf, av, out, AN_OUTCAP - 1, olen, AN_TIMEOUT)
257 cls = "ERROR-JUDGE" as *u8
258 if olen[0] > 0 {
259 if an_has(out, olen[0], "ALREADY-ANCHORED" as *u8) == 1 { cls = "ALREADY-ANCHORED" as *u8 }
260 if an_has(out, olen[0], "ANCHORED" as *u8) == 1 { if an_has(out, olen[0], "ALREADY-ANCHORED" as *u8) == 0 { cls = "ANCHORED" as *u8 } }
261 if an_has(out, olen[0], "ANCHORED" as *u8) == 0 { cls = "REFUSED" as *u8 }
262 }
263 }
264 }
265 }
266 if an_has(cls, 8, "ANCHORED" as *u8) == 1 { if an_has(cls, 16, "ALREADY-ANCHORED" as *u8) == 0 { anch = anch + 1 } }
267 if an_has(cls, 16, "ALREADY-ANCHORED" as *u8) == 1 { alrdy = alrdy + 1 }
268 if an_has(cls, 7, "REFUSED" as *u8) == 1 { refu = refu + 1 }
269 if an_has(cls, 5, "ERROR" as *u8) == 1 { errn = errn + 1 }
270 an_puts(" " as *u8); an_puts(cls); an_puts(" " as *u8); an_puts(gname); an_puts("\n" as *u8)
271 if lf >= 0 {
272 an_w(lf, "ANCHORSWEEP gate=" as *u8); an_w(lf, gname)
273 an_w(lf, " class=" as *u8); an_w(lf, cls); an_w(lf, "\n" as *u8)
274 }
275 done = done + 1
276 }
277 } }
278 }
279 }
280 i = e + 1
281 }
282
283 // ★RELEASE THE LEASE (same defect fixed in nx_adoptsweep -- acquire-without-release turns the guard
284 // into a 7200s lockout after three completed runs; it fails looking exactly like the guard working).
285 // Safe to try all three: nx_lease release is OWNER-CHECKED (wrong owner -> LS-REFUSED not-holder).
286 if gotlease == 1 {
287 let rout: *u8 = sys_mmap(AN_MAGIC_4096)
288 let rlen: *i64 = sys_mmap(16) as *i64
289 let rav: *i64 = sys_mmap(64) as *i64
290 let r1: *u8 = "gatesweep_1"
291 let r2: *u8 = "gatesweep_2"
292 let r3: *u8 = "gatesweep_3"
293 var rs: i64 = 1
294 while rs <= 3 {
295 var rname: *u8 = r1
296 if rs == 2 { rname = r2 }
297 if rs == 3 { rname = r3 }
298 rout[0] = 0 as u8; rlen[0] = 0
299 rav[0] = lelf as i64; rav[1] = "release" as *u8 as i64; rav[2] = rname as i64
300 rav[3] = candp as i64; rav[4] = 0
301 tr_run_capture_to(lelf, rav, rout, AN_MAGIC_4095, rlen, AN_MAGIC_20000)
302 if rlen[0] > 0 { if an_has(rout, rlen[0], "LS-RELEASED" as *u8) == 1 {
303 an_puts(" lease released: " as *u8); an_puts(rname); an_puts("\n" as *u8)
304 } }
305 rs = rs + 1
306 }
307 }
308
309 // empty-worklist refusal (fix 2)
310 if seen == 0 {
311 an_puts("\n ★EMPTY WORKLIST -- no SKIP-NOANCHOR rows in the newest census generation.\n" as *u8)
312 an_puts(" REFUSING to report a clean run over zero gates. verdict=NO-CONCLUSION\n" as *u8)
313 sys_exit(3); return 3
314 }
315 // ★ATTEMPTED NOTHING IS NOT A CLEAN RUN (same defect fixed in nx_adoptsweep): skip beyond the
316 // population slips past the seen==0 guard and yields zero work plus a NEGATIVE deferred, reported
317 // GREEN. Refuse before printing a summary that reads as a result.
318 if done == 0 {
319 an_puts("\n ★ATTEMPTED NOTHING -- skip is at or beyond the population (" as *u8); an_n(1, seen)
320 an_puts(" NOANCHOR rows in the newest census generation).\n" as *u8)
321 an_puts(" REFUSING to report a verdict over zero attempted gates. verdict=NO-CONCLUSION\n" as *u8)
322 sys_exit(3); return 3
323 }
324 let sum: i64 = anch + refu + alrdy + errn
325 an_puts("\n noanchor_in_census=" as *u8); an_n(1, seen)
326 an_puts(" attempted=" as *u8); an_n(1, done)
327 an_puts("\n ANCHORED=" as *u8); an_n(1, anch)
328 an_puts(" REFUSED=" as *u8); an_n(1, refu)
329 an_puts(" ALREADY-ANCHORED=" as *u8); an_n(1, alrdy)
330 an_puts(" ERROR=" as *u8); an_n(1, errn)
331 let genuine: i64 = anch + refu
332 an_puts("\n genuine_attempts=" as *u8); an_n(1, genuine)
333 if genuine > 0 { an_puts(" anchor_permil=" as *u8); an_n(1, (anch * 1000) / genuine) }
334 an_puts(" partition: " as *u8); an_n(1, sum); an_puts(" of " as *u8); an_n(1, done)
335 if sum == done { an_puts(" -- SUMS\n" as *u8) }
336 if sum != done { an_puts(" -- ⚠DOES NOT SUM\n" as *u8) }
337 var deferred: i64 = seen - skipn - done
338 if deferred < 0 { deferred = 0 }
339 if deferred > 0 {
340 an_puts(" ⚠DEFERRED " as *u8); an_n(1, deferred)
341 an_puts(" gate(s) -- BOUNDED BATCH, NOT THE CLASS. resume with skip=" as *u8); an_n(1, skipn + done); an_puts("\n" as *u8)
342 }
343 if lf >= 0 {
344 an_w(lf, "ANCHORSWEEP-TOTAL noanchor=" as *u8); an_n(lf, seen)
345 an_w(lf, " attempted=" as *u8); an_n(lf, done)
346 an_w(lf, " anchored=" as *u8); an_n(lf, anch)
347 an_w(lf, " refused=" as *u8); an_n(lf, refu)
348 an_w(lf, " already=" as *u8); an_n(lf, alrdy)
349 an_w(lf, " genuine=" as *u8); an_n(lf, genuine)
350 an_w(lf, " error=" as *u8); an_n(lf, errn)
351 an_w(lf, " deferred=" as *u8); an_n(lf, deferred)
352 an_w(lf, " verdict=" as *u8)
353 if refu + errn == 0 { an_w(lf, "GREEN\n" as *u8) } else { an_w(lf, "RED\n" as *u8) }
354 sys_close(lf)
355 }
356 if refu + errn > 0 { sys_exit(1); return 1 }
357 sys_exit(0); return 0
358}