code wiki / _hdl_build / nx_rebuild_drain.nx
nx_rebuild_drain.nx source
↩ module page · 1307 lines · 79056 B
1// nx_rebuild_drain.nx -- THE ACTING HALF of dependency-aware staleness (debt 1785447998).
2//
3// nx_rebuild_plan DIAGNOSES: 662 of 696 deployed organs run binaries predating their own dependencies,
4// 638 of them traceable to just two shared runtimes carrying real behavioural root-fixes (SIGPIPE in
5// nx_syscalls.nx, the ss_get O(whole-store) fix in nx_seg_store.nx). But a census nobody is OBLIGED to
6// read is the same shape of defect as a fix nobody is OBLIGED to rebuild against -- both are capability
7// that exists and does not reach the place it matters. This organ is the obligation.
8//
9// ★★★WHY AN ORGAN AND NOT THE SHELL SCRIPT IT REPLACES: a shell batch is something a human remembers to
10// run. An organ can be SUPERVISED -- put on a beat, it turns "someone should rebuild the dependents"
11// into a property of the system. That is the whole difference between a workaround and a fix.
12//
13// GUARDS, every one of them learned by being bitten today:
14// • _cli/STUB TRAP: a fresh build far SMALLER than the deployed elf means the same-basename .nx is a
15// smoke stub and the real tool came from another source. nx_https_get rebuilds 443KB vs 633KB
16// deployed -- installing that BREAKS a working tool. REFUSED, never installed.
17// • ETXTBSY: cp over a RUNNING elf fails; the daemon holds that inode. Install is write-to-.new then
18// RENAME, which swaps the directory entry and leaves the live inode alone.
19// • BUILD FAILURE IS NOT INSTALLABLE: a non-zero build rc or a missing artifact skips the target.
20// • BOUNDED + SERIAL: today's saturation incident (load 63, mgmt+tools+sshd dead) came from wide
21// fan-out. This drains a batch at a time, one build at a time, and stops. Idempotent: re-running
22// simply picks up whatever is still stale, so a partial drain is always safe to resume.
23// • IDENTICAL-BYTES IS A NO-OP: if the fresh build matches what is deployed, nothing is written.
24//
25// nx_rebuild_drain beat [batch] [buildroot] [elfdir] SELF-CONTAINED for a clock row: regenerates the list, then drains a bounded batch
26// nx_rebuild_drain classify <listfile> [buildroot] [elfdir] PARTITION ONLY, spends no compile: buildable vs lib-basename vs no-elf
27// nx_rebuild_drain <listfile> [batch] [buildroot] [elfdir]
28// listfile = output of `nx_rebuild_plan list` (one target name per line)
29// -> per-target rows + summary. Exit 0 always; a drain reports, it does not refuse.
30// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
31import "nx_syscalls.nx"
32import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
33
34const RD_AT_FDCWD: i64 = 0 - 100
35const RD_SYS_NEWFSTATAT: i64 = 262
36const RD_STATBUF: i64 = 256
37const RD_OFF_SIZE: i64 = 48
38const RD_PATHCAP: i64 = 512
39const RD_LISTCAP: i64 = 262144
40// derived: measured 8 serial targets ran clean with zero saturation; 8 is the proven-safe default and is
41// overridable per invocation rather than baked in.
42const RD_DEFAULT_BATCH: i64 = 8
43// the stub-trap ratio: a fresh build under HALF the deployed size is a wrong-source signal, not a
44// shrink. Same discriminator nx_stale_check documents.
45const RD_STUB_NUM: i64 = 2
46// ⚠NO BUILD TIMEOUT IS ENFORCED HERE. A wedged nx_sov_build_run will block this drain indefinitely.
47// Stating it rather than declaring an unused RD_BUILD_TIMEOUT_S const -- a threshold nothing reads is
48// a guard that exists only in the reader's imagination, which is worse than an honestly absent one.
49// Mitigated for now by BOUNDED batches: a hang stalls one batch, never an unattended sweep.
50const RD_COPYBUF: i64 = 1048576
51
52func rd_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
53// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
54// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
55// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
56// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
57func rd_n(v: i64) -> i64 { nxi_out(v); return 0 }
58func rd_len(a: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { i = i + 1 } return i }
59func rd_cpy(dst: *u8, src: *u8) -> i64 { var i: i64 = 0; while src[i] != (0 as u8) { dst[i] = src[i]; i = i + 1 } dst[i] = 0 as u8; return i }
60func rd_cat(dst: *u8, o: i64, src: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while src[i] != (0 as u8) { dst[p] = src[i]; p = p + 1; i = i + 1 } dst[p] = 0 as u8; return p }
61
62// ALIAS RESOLUTION (2026-08-15). Some deployed artifacts carry a basename that is NOT their build
63// target -- nx_opaque_login.elf is byte-identical to the nx_opaque_login_daemon build. Without this the
64// row resolves to a LIBRARY, never links, and blocks the queue forever.
65// ★DATA, NOT CODE: the mapping lives in a conf so a new case is a row, not a rebuild of this organ.
66// ⚠ONLY `proven` ROWS RESOLVE. An `unresolved` row keeps its recorded evidence and is NOT built under a
67// guessed target -- installing a different program under a live service's name is worse than the stale
68// binary it would replace. ★WRONG IN THE DIRECTION OF DOING NOTHING.
69const RD_ALIAS_CONF: *u8 = "knowledge/registry/elf_source_alias.conf"
70const RD_TAB_C: i64 = 9
71const RD_HASH_C: i64 = 35
72// Writes the resolved build target for `name` into out; returns 1 if a PROVEN alias applied, else 0
73// (and out is left holding `name` unchanged).
74func rd_alias(name: *u8, out: *u8) -> i64 {
75 rd_cpy(out, name)
76 let lenp: *i64 = sys_mmap(8)
77 let b: *u8 = sys_read_file(RD_ALIAS_CONF, lenp)
78 let n: i64 = lenp[0]
79 sys_munmap(lenp as *u8, 8)
80 if n <= 0 { return 0 }
81 var applied: i64 = 0
82 var i: i64 = 0
83 while i < n {
84 var le: i64 = i
85 var sc: i64 = 1
86 while sc == 1 { if le >= n { sc = 0 } else { if b[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
87 if le > i {
88 if (b[i] as i64) != RD_HASH_C {
89 let e1: i64 = rd_find_byte(b, i, le, RD_TAB_C)
90 if e1 >= 0 {
91 let nlen: i64 = e1 - i
92 var k: i64 = 0
93 var same: i64 = 1
94 var cmp: i64 = 1
95 while cmp == 1 {
96 if k >= nlen { cmp = 0 } else {
97 if name[k] != b[i+k] { same = 0; cmp = 0 } else { k = k + 1 }
98 }
99 }
100 if same == 1 { if name[nlen] == (0 as u8) {
101 let f2s: i64 = e1 + 1
102 let t2: i64 = rd_find_byte(b, f2s, le, RD_TAB_C)
103 if t2 >= 0 {
104 // ★WIDENED 2026-08-17 to accept `equivalent` as well as `proven`, and the scope is
105 // ONE ROW: of the three equivalent aliases, two are DECLARED DAEMONS that the
106 // portmap guard defers regardless, so only nx_project -> nx_project_gate becomes
107 // buildable. Its evidence is the STRICT oracle (nx_contentdiff runs_scanned=470
108 // lost_from_live=0 verdict=GREEN 3/3), and four independent guards still stand
109 // between this and the serving root: the daemon deferral, the content-loss
110 // threshold, the .prev rollback, and the install ledger.
111 // ⚠`unresolved` is STILL refused. A guessed alias installs a different program
112 // under a deployed name, which is worse than the stale binary it replaces.
113 var okstat: i64 = 0
114 if rd_starts_at(b, t2 + 1, le, "proven" as *u8) == 1 { okstat = 1 }
115 if rd_starts_at(b, t2 + 1, le, "equivalent" as *u8) == 1 { okstat = 1 }
116 if okstat == 1 {
117 var w: i64 = 0
118 while f2s + w < t2 { out[w] = b[f2s + w]; w = w + 1 }
119 out[w] = 0 as u8
120 applied = 1
121 }
122 }
123 } }
124 }
125 }
126 }
127 i = le + 1
128 }
129 sys_munmap(b, n)
130 return applied
131}
132
133// ★★★★★★THE CALLABLE HOME FOR "WHERE IS THIS BYTE". I wrote the cursor-clobber exit THREE TIMES in
134// one session -- mb_loop_allocs, rd_has_main, and rd_alias -- each time AFTER banking the law that
135// forbids it. A rule I have to remember is a rule I will skip; the only thing that stops it is a
136// function that cannot express the defect. Returns the index of `c` in [s,e), or -1. The scan cursor
137// and the ANSWER are separate variables, so the exit can never destroy the position.
138func rd_find_byte(b: *u8, s: i64, e: i64, c: i64) -> i64 {
139 var i: i64 = s
140 var at: i64 = 0 - 1
141 var scanning: i64 = 1
142 while scanning == 1 {
143 if i >= e { scanning = 0 } else {
144 if (b[i] as i64) == c { at = i; scanning = 0 } else { i = i + 1 }
145 }
146 }
147 return at
148}
149
150func rd_starts_at(b: *u8, s: i64, e: i64, pre: *u8) -> i64 {
151 var k: i64 = 0
152 while pre[k] != (0 as u8) {
153 if s + k >= e { return 0 }
154 if b[s+k] != pre[k] { return 0 }
155 k = k + 1
156 }
157 return 1
158}
159
160func rd_streq(a: *u8, b: *u8) -> i64 {
161 var i: i64 = 0
162 var r: i64 = 2
163 while r == 2 {
164 if a[i] != b[i] { r = 0 } else {
165 if a[i] == (0 as u8) { r = 1 } else { i = i + 1 }
166 }
167 }
168 return r
169}
170
171func rd_size(path: *u8) -> i64 {
172 let sb: *u8 = sys_mmap(RD_STATBUF)
173 if __syscall(RD_SYS_NEWFSTATAT, RD_AT_FDCWD, path as i64, sb as i64, 0, 0, 0) != 0 { return 0 - 1 }
174 let sp: *i64 = ((sb as i64) + RD_OFF_SIZE) as *i64
175 return sp[0]
176}
177
178// name must be [A-Za-z0-9_] -- this string is handed to execve, so anything else is refused outright
179// rather than sanitised. A target name is not user prose; if it does not look like one, it is not one.
180func rd_safe(name: *u8) -> i64 {
181 var i: i64 = 0
182 while name[i] != (0 as u8) {
183 let c: i64 = name[i] as i64
184 var ok: i64 = 0
185 if c >= 48 { if c <= 57 { ok = 1 } }
186 if c >= 65 { if c <= 90 { ok = 1 } }
187 if c >= 97 { if c <= 122 { ok = 1 } }
188 if c == 95 { ok = 1 }
189 if ok == 0 { return 0 }
190 i = i + 1
191 if i >= 64 { return 0 }
192 }
193 if i == 0 { return 0 }
194 return 1
195}
196
197// byte-identical? 1 = same, 0 = differ/unreadable
198func rd_same(a: *u8, b: *u8) -> i64 {
199 let sa: i64 = rd_size(a)
200 let sb2: i64 = rd_size(b)
201 if sa < 0 { return 0 }
202 if sa != sb2 { return 0 }
203 let fa: i64 = sys_openat_rd(a)
204 if fa < 0 { return 0 }
205 let fb: i64 = sys_openat_rd(b)
206 if fb < 0 { sys_close(fa); return 0 }
207 let ba: *u8 = sys_mmap(RD_COPYBUF)
208 let bb: *u8 = sys_mmap(RD_COPYBUF)
209 var same: i64 = 1
210 var go: i64 = 1
211 while go == 1 {
212 let ra: i64 = sys_read(fa, ba, RD_COPYBUF)
213 let rb: i64 = sys_read(fb, bb, RD_COPYBUF)
214 if ra != rb { same = 0; go = 0 } else {
215 if ra <= 0 { go = 0 } else {
216 var k: i64 = 0
217 while k < ra { if ba[k] != bb[k] { same = 0; k = ra; go = 0 } else { k = k + 1 } }
218 }
219 }
220 }
221 sys_close(fa)
222 sys_close(fb)
223 return same
224}
225
226// copy src -> dst (truncating). 1 ok, 0 fail.
227func rd_copy(src: *u8, dst: *u8) -> i64 {
228 let fs: i64 = sys_openat_rd(src)
229 if fs < 0 { return 0 }
230 let fd: i64 = sys_openat_wr(dst, 493)
231 if fd < 0 { sys_close(fs); return 0 }
232 let buf: *u8 = sys_mmap(RD_COPYBUF)
233 var ok: i64 = 1
234 var go: i64 = 1
235 while go == 1 {
236 let r: i64 = sys_read(fs, buf, RD_COPYBUF)
237 if r < 0 { ok = 0; go = 0 } else {
238 if r == 0 { go = 0 } else {
239 let wn: i64 = sys_write(fd, buf, r)
240 if wn != r { ok = 0; go = 0 }
241 }
242 }
243 }
244 sys_fsync(fd)
245 sys_close(fd)
246 sys_close(fs)
247 return ok
248}
249
250// ---- CONTENT CONTAINMENT (root fix 2026-07-30, ws=sev-eater) ---------------------------------
251// THE SIZE RATIO ABOVE CANNOT SEE THE DIFFERENCE BETWEEN THE TWO THINGS IT MUST SEPARATE.
252// MEASURED TODAY, both directions, which is why this exists:
253// * A BETTER TOOLCHAIN SHRINKS A BINARY WITHOUT LOSING ANYTHING. Rebuilding nx_fin_serve /
254// nx_mp_serve / nx_torrent_mkinfo produced 12-22pc SMALLER elfs whose printable-string sets were
255// IDENTICAL to the deployed ones (only_in_deployed=0 AND only_in_fresh=0). seq1464 restored 11712
256// bytes of optimiser passes, so EVERY organ built by an older compiler now looks suspicious to a
257// size ruler. Judged by size alone the whole 700-organ queue is unreachable.
258// * REAL SOURCE LOSS ALSO SHRINKS A BINARY -- and by LESS. A supervised drain of 40 found 9 organs
259// whose fresh build was missing runs the deployed binary had (nx_warden -48, nx_conductor -46,
260// nx_https_get -12, +6 more). Every one of them PASSED the 50pc stub ratio; refused_stub_source
261// was 0. The ratio would have installed all nine.
262// So size correlates with the thing we fear and does not measure it. CONTENT does: a run of printable
263// bytes in the deployed binary is something that binary can emit, and if the fresh build cannot emit
264// it, capability was lost. An optimiser cannot trip this -- it changes instruction encoding, not the
265// strings the program can print.
266// LAW: A GUARD MUST MEASURE THE PROPERTY YOU CARE ABOUT (capability retained), NOT A PROXY THAT
267// CORRELATES WITH IT (size). Same shape as nx_srcguard v2's symbol-set containment for SOURCE.
268// THE MEASUREMENT ITSELF IS NOT MADE HERE. This organ carried its own printable-run differ until
269// 2026-08-16; see the rd_lost_runs tombstone below for why a second one was a defect rather than an
270// optimisation. The reasoning above is retained because it is WHY the guard exists at all -- it is the
271// case for measuring content instead of size, and that case is unchanged by which organ does the counting.
272
273// ⛔rd_slurp DELETED 2026-08-16 -- a hand-rolled CAPPED whole-file reader that sat beside the estate's
274// proven cap-free `sys_read_file`, which sizes its buffer from the file (lseek END) and cannot
275// short-read. Its own source records DEBT-EATEN 2026-07-15 for precisely this class: "the old fixed cap
276// SILENTLY TRUNCATED bigger files ... the worst failure class". I reproduced that eaten debt here as
277// three guessed ceilings (65536 alias conf / 65536 live-service table / 8388608 elf compare), one of
278// them feeding a SAFETY GUARD that fails OPEN on truncation and one feeding the content-loss verdict
279// that can corrupt in BOTH directions.
280// ★★★★★★A DUPLICATE RULER WEARING A CONSTANT IS STILL A DUPLICATE RULER, AND ITS CONSTANT IS THE PART
281// THAT ROTS. Compose the proven reader; never re-implement it.
282
283
284// ⛔rd_lost_runs DELETED 2026-08-16, with its private rd_runs / rd_h_ins / rd_h_has hash set and the six
285// constants that tuned it (RD_RUNMIN RD_HSLOTS RD_HMASK RD_HBYTES RD_FNVP RD_LENMIX RD_PROBE_CAP).
286// It was a SECOND printable-run differ living beside nx_contentdiff, and the two disagreed on a SAFETY
287// verdict: 267 vs 334 on identical inputs, because this one's RD_RUNMIN was 8 and the incumbent's minlen
288// is 6. The count now comes from rd_cdiff_lost, which forks the incumbent and parses its report, so the
289// drain and /api/promote decide on the SAME number and the calibrated 10-run floor finally means what it
290// was calibrated to mean. ★★★★★★DELETING THE DUPLICATE IS THE FIX; RETUNING 8 TO 6 WOULD HAVE LEFT TWO
291// RULERS THAT AGREE TODAY AND DRIFT TOMORROW.
292
293// run the sovereign builder for <target> under buildroot; returns its exit code, or -1 on spawn failure.
294// REBUILD LIKE FOR LIKE (2026-08-19): does the DEPLOYED elf carry a .debug_line section? If it does,
295// the drain must rebuild with --debug, or the content ruler reads the disappearance of the debug NAME
296// TABLE as capability loss and the row is refused forever. MEASURED on the two rows that sat at the
297// head of every regenerated list: nx_conductor "lost 52 runs" / nx_warden "lost 55" -- every single
298// lost run was a FUNCTION NAME (sys_socket, sys_recvfrom, w_is_build_artifact...) from .debug_line/
299// .debug_info of an 08-15 dbgflag-era debug build; rebuilt with --debug the loss collapses to the
300// names of functions the compiler's whole-program DCE genuinely removed (dead code, not capability).
301// The probe is the section-name STRING in the elf bytes -- the same channel the section header table
302// uses, present exactly when nxasm emitted the section, and absent from a stripped build. Fail-open:
303// an unreadable elf probes 0 and the row builds exactly as before.
304const RD_DEBUG_MARK: *u8 = ".debug_line"
305func rd_live_has_debug(dep: *u8) -> i64 {
306 let lenp: *i64 = sys_mmap(16) as *i64
307 let b: *u8 = sys_read_file(dep, lenp)
308 if (b as i64) == 0 { return 0 }
309 let n: i64 = lenp[0]
310 var m: i64 = 0
311 while RD_DEBUG_MARK[m] != (0 as u8) { m = m + 1 }
312 var i: i64 = 0
313 var hit: i64 = 0
314 while i + m <= n {
315 var k: i64 = 0
316 var ok: i64 = 1
317 while k < m { if b[i+k] != RD_DEBUG_MARK[k] { ok = 0; k = m } else { k = k + 1 } }
318 if ok == 1 { hit = 1; i = n }
319 i = i + 1
320 }
321 if n > 0 { sys_munmap(b, n + 16) }
322 sys_munmap(lenp as *u8, 16)
323 return hit
324}
325func rd_build(broot: *u8, target: *u8, want_debug: i64) -> i64 {
326 let pid: i64 = sys_fork()
327 if pid < 0 { return 0 - 1 }
328 if pid == 0 {
329 sys_chdir(broot)
330 let devnull: i64 = sys_openat_wr("/dev/null" as *u8, 420)
331 if devnull >= 0 { sys_dup3(devnull, 1, 0); sys_dup3(devnull, 2, 0) }
332 let av: *i64 = sys_mmap(64) as *i64
333 av[0] = "./_offc/nx_sov_build_run.elf" as i64
334 av[1] = target as i64
335 av[2] = "--build-only" as i64
336 var na: i64 = 3
337 if want_debug == 1 { av[na] = "--debug" as i64; na = na + 1 }
338 av[na] = 0
339 let ev: *i64 = sys_mmap(16) as *i64
340 ev[0] = 0
341 sys_execve("./_offc/nx_sov_build_run.elf" as *u8, av, ev)
342 sys_exit(127)
343 }
344 let st: *i64 = sys_mmap(16) as *i64
345 sys_wait4(pid, st, 0)
346 return wait_exit_code(st[0])
347}
348
349// ★★★★★★THE BEAT VERB IS THE WHOLE POINT OF THIS ORGAN, AND IT WAS THE ONE THING MISSING. This
350// file's own header says it: "an organ can be SUPERVISED -- put on a beat, it turns 'someone should
351// rebuild the dependents' into a property of the system. That is the whole difference between a
352// workaround and a fix." It shipped without one, so it stayed a tool somebody had to remember to run --
353// which is the same adoption defect it exists to cure, one level up.
354// A clock row forks ONE command, but the pipeline is plan-list THEN drain, and the drain's own note says
355// the list must be regenerated first because installing changes who is stale. So the loop closes HERE,
356// inside the incumbent, rather than in a new beat organ that would be a second thing to keep correct.
357// ★EXTEND THE INCUMBENT, NEVER ADD A SECOND RULER.
358// ⚠BOUNDED BY CONSTRUCTION: the batch is an argument with a small default, the drain is serial, every
359// install is content-loss-refused and rollback-snapshotted, and identical bytes are a no-op. The header
360// records why that matters -- "today's saturation incident (load 63, mgmt+tools+sshd dead) came from
361// wide fan-out."
362// Deliberately SMALL. A beat is unattended, so its blast radius per firing is the thing that must be
363// bounded, not its throughput -- 1,849 rows drain over many quiet firings rather than one wide one.
364// ★★★★★★THE BATCH IS A SAFETY CEILING, NOT THE OPERATING POINT. A guessed count is a defect
365// generator in both directions -- too small is a trickle (at 4/day, 1,834 rows is ~458 days), too large
366// saturates the host. The real limit is HEADROOM, and the estate already measures it: nx_build_admit
367// reads /proc live and nx_sov_build_run turns a denial into SBR_ADMIT_REFUSED(6). So the drain runs
368// until the BOX says stop, and this number only bounds the worst case for one unattended firing.
369// ★COMPOSE THE INCUMBENT'S MEASUREMENT INSTEAD OF INVENTING A SECOND ONE: reading /proc here would be a
370// duplicate ruler that drifts from the admitter the builds actually obey.
371// ★★★★★★A COUNT WITHOUT A WORKLIST IS NOT ACTIONABLE, AND `lost_runs=2` IS A COUNT. A refusal that
372// says only HOW MANY capabilities the fresh build drops leaves the reader with no way to decide whether
373// the loss is a real regression or a deliberate reword -- so the row is re-attempted and re-refused on
374// every firing, forever. That is the head-of-line block again, one level down.
375// The estate already has the differ that NAMES them (nx_contentdiff prints `LOST: <run>`), so this forks
376// it ON REFUSAL ONLY rather than teaching rd_lost_runs to print. ★COMPOSE THE RULER, NEVER RE-IMPLEMENT
377// IT -- and the fork cost is paid only on the rare refusal, never on the common path.
378// ⚠Output goes to a DURABLE log, not stdout: this organ emits a JSON row stream, and interleaving the
379// differ's prose would corrupt it for every consumer. The JSON keeps the count; the log keeps the names.
380const RD_INSTALLLOG: *u8 = "knowledge/status/rebuild_installs.log"
381// ⛔THE LEDGER OF WHAT THIS ORGAN ACTUALLY SWAPPED. The trend journal records `installed=3` and NOT
382// WHICH -- so after the beat ran unattended, "did it replace a declared daemon?" was UNANSWERABLE, and I
383// hit exactly that wall auditing my own runs. ★★★★★★A COUNT WITHOUT A WORKLIST IS NOT ACTIONABLE, AND
384// FOR AN ORGAN THAT MUTATES THE SERVING ROOT THE WORKLIST IS THE AUDIT TRAIL. An unattended installer
385// whose actions cannot be enumerated afterwards is asking to be trusted rather than checked.
386// Append-only; the rollback path rides on the row so a reversal needs no archaeology.
387func rd_install_log(organ: *u8, was: i64, now: i64, prevn: *u8) -> i64 {
388 let fd: i64 = sys_openat_append(RD_INSTALLLOG, MODE_0644)
389 if fd < 0 {
390 rd_w("{\"organ\":\"nx_rebuild_drain\",\"install_ledger\":\"UNWRITABLE\"}\n" as *u8)
391 return 0 - 1
392 }
393 let b: *u8 = sys_mmap(RD_PATHCAP)
394 var o: i64 = 0
395 o = rd_catn(b, o, sys_now_realtime_sec())
396 o = rd_cat(b, o, "\t" as *u8); o = rd_cat(b, o, organ)
397 o = rd_cat(b, o, "\twas=" as *u8); o = rd_catn(b, o, was)
398 o = rd_cat(b, o, "\tnow=" as *u8); o = rd_catn(b, o, now)
399 o = rd_cat(b, o, "\trollback=" as *u8); o = rd_cat(b, o, prevn)
400 b[o] = 10 as u8
401 o = o + 1
402 sys_write(fd, b, o)
403 sys_close(fd)
404 sys_munmap(b, RD_PATHCAP)
405 return 0
406}
407const RD_FAILLOG: *u8 = "knowledge/status/rebuild_buildfail.log"
408// ⛔THE OTHER PERMANENTLY-STUCK CLASS, AND IT BURNS A BUILD SLOT EVERY FIRING. MEASURED on the live beat
409// series: `failed=2` on EVERY scheduled firing since 1786932213 -- the SAME two organs re-attempted and
410// re-failing, consuming half a batch of 4 for ever. That is the head-of-line block already fixed for LIB
411// rows, in a new costume: a row that cannot compile is retried by an unattended beat until someone
412// notices, and `failed=2` is a COUNT WITH NO WORKLIST so nobody can.
413// ★★★★★A COUNTER TELLS YOU A CLASS EXISTS; ONLY A LEDGER TELLS YOU IT IS THE SAME ROW EVERY TIME.
414// ⚠DELIBERATELY NOT AN AUTO-SKIP: a BUILDFAIL can be TRANSIENT (a sibling mid-edit, headroom, a lease),
415// so refusing the row for ever would be wrong in the destructive direction. Recording it makes the
416// repeat offender VISIBLE and adjudicable; suppressing it would hide a defect that may have healed.
417func rd_fail_log(organ: *u8, tgt: *u8, rc: i64) -> i64 {
418 let fd: i64 = sys_openat_append(RD_FAILLOG, MODE_0644)
419 if fd < 0 { rd_w("{\"organ\":\"nx_rebuild_drain\",\"buildfail_ledger\":\"UNWRITABLE\"}\n" as *u8); return 0 - 1 }
420 let b: *u8 = sys_mmap(RD_PATHCAP)
421 var o: i64 = 0
422 o = rd_catn(b, o, sys_now_realtime_sec())
423 o = rd_cat(b, o, "\t" as *u8); o = rd_cat(b, o, organ)
424 o = rd_cat(b, o, "\tbuilt_target=" as *u8); o = rd_cat(b, o, tgt)
425 o = rd_cat(b, o, "\trc=" as *u8); o = rd_catn(b, o, rc)
426 b[o] = 10 as u8
427 o = o + 1
428 sys_write(fd, b, o)
429 sys_close(fd)
430 sys_munmap(b, RD_PATHCAP)
431 return 0
432}
433const RD_LOSSLOG: *u8 = "knowledge/status/rebuild_contentloss.log"
434const RD_CDIFF_ELF: *u8 = "./_offc/nx_contentdiff.elf"
435const RD_CDIFF_TMPA: *u8 = "/tmp/nx_rd_cdiff_"
436const RD_CDIFF_TMPB: *u8 = ".txt"
437const RD_STATLINE: *u8 = "runs_scanned="
438const RD_LOSTFIELD: *u8 = "lost_from_live="
439// ⛔THE ONE CONTENT RULER. This organ used to CARRY ITS OWN printable-run differ (rd_runs + an FNV hash
440// set) whose shortest counted run was RD_RUNMIN=8, while nx_contentdiff -- the ruler /api/promote's guard
441// shares arithmetic with -- uses minlen=6. MEASURED 2026-08-16 on nx_clean_serve_daemon, identical inputs
442// (deployed 1255501 B, fresh 715779 B): mine said 267 lost, the incumbent said 334 of 592 scanned. FOUR
443// of the six runs it NAMED as lost were shorter than 8 (`default` `delete` `typeof` `finally`) and were
444// structurally invisible to mine. ★★★★★★I ADOPTED PROMOTE'S CALIBRATED FLOOR (10 runs / 49 permil) AND
445// APPLIED IT TO A DIFFERENT MEASURE WITH A DIFFERENT DENOMINATOR -- A THRESHOLD CALIBRATED ON ONE RULER
446// IS MEANINGLESS ON ANOTHER, and the drift is toward UNDER-reporting loss, i.e. toward installing a
447// regression. The comment directly below already forbade exactly this and I built it anyway.
448// Returns lost_from_live, or -1 when the report cannot be read or parsed -- and an unverifiable compare
449// is refused by the caller, because a guard that cannot answer must never wave through.
450func rd_cdiff_lost(organ: *u8, dep: *u8, fresh: *u8, logit: i64) -> i64 {
451 // ⚠Per-organ temp path: a single shared scratch file would make two concurrent drains read each
452 // other's report. Concurrency on the SAME organ is already excluded by the per-target lease.
453 let tp: *u8 = sys_mmap(RD_PATHCAP)
454 var tc: i64 = rd_cpy(tp, RD_CDIFF_TMPA)
455 tc = rd_cat(tp, tc, organ)
456 tc = rd_cat(tp, tc, RD_CDIFF_TMPB)
457 sys_unlinkat(tp)
458 let of: i64 = sys_openat_wr(tp, MODE_0644)
459 if of < 0 { sys_munmap(tp, RD_PATHCAP); return 0 - 1 }
460 let pid: i64 = sys_fork()
461 if pid < 0 { sys_close(of); sys_munmap(tp, RD_PATHCAP); return 0 - 1 }
462 if pid == 0 {
463 sys_dup3(of, 1, 0)
464 sys_dup3(of, 2, 0)
465 let av: *i64 = sys_mmap(64) as *i64
466 av[0] = RD_CDIFF_ELF as i64
467 av[1] = dep as i64
468 av[2] = fresh as i64
469 av[3] = 0
470 let ev: *i64 = sys_mmap(16) as *i64
471 ev[0] = 0
472 sys_execve(RD_CDIFF_ELF, av, ev)
473 sys_exit(127)
474 }
475 let st: *i64 = sys_mmap(16) as *i64
476 sys_wait4(pid, st, 0)
477 sys_close(of)
478 sys_munmap(st as *u8, 16)
479 let lenp: *i64 = sys_mmap(8)
480 let b: *u8 = sys_read_file(tp, lenp)
481 let n: i64 = lenp[0]
482 sys_munmap(lenp as *u8, 8)
483 sys_munmap(tp, RD_PATHCAP)
484 if n <= 0 { return 0 - 1 }
485 if logit == 1 {
486 let fd: i64 = sys_openat_append(RD_LOSSLOG, MODE_0644)
487 if fd >= 0 {
488 let hb: *u8 = sys_mmap(RD_PATHCAP)
489 var o: i64 = rd_cpy(hb, "\n=== " as *u8)
490 o = rd_cat(hb, o, organ)
491 o = rd_cat(hb, o, " epoch=" as *u8)
492 o = rd_catn(hb, o, sys_now_realtime_sec())
493 o = rd_cat(hb, o, " (capabilities the DEPLOYED binary has and the FRESH build does not)\n" as *u8)
494 sys_write(fd, hb, o)
495 sys_write(fd, b, n)
496 sys_munmap(hb, RD_PATHCAP)
497 sys_close(fd)
498 }
499 }
500 // ★ANCHOR BY POSITION, NEVER BY TEXT. `lost_from_live=` is itself a printable run inside any binary
501 // that embeds nx_contentdiff's strings, so it can appear on a `LOST:` line -- an unanchored search
502 // would read the DATA as the ANSWER. Only the stats line STARTS with `runs_scanned=`.
503 var flen: i64 = 0
504 while RD_LOSTFIELD[flen] != (0 as u8) { flen = flen + 1 }
505 var out: i64 = 0 - 1
506 var i: i64 = 0
507 var walking: i64 = 1
508 while walking == 1 {
509 if i >= n { walking = 0 } else {
510 var le: i64 = i
511 var sc: i64 = 1
512 while sc == 1 { if le >= n { sc = 0 } else { if b[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
513 if rd_starts_at(b, i, le, RD_STATLINE) == 1 {
514 var k: i64 = i
515 var fnd: i64 = 0 - 1
516 var scan: i64 = 1
517 while scan == 1 {
518 if k >= le { scan = 0 } else {
519 if rd_starts_at(b, k, le, RD_LOSTFIELD) == 1 { fnd = k; scan = 0 } else { k = k + 1 }
520 }
521 }
522 if fnd >= 0 {
523 var p: i64 = fnd + flen
524 var v: i64 = 0
525 var any: i64 = 0
526 var dig: i64 = 1
527 while dig == 1 {
528 if p >= le { dig = 0 } else {
529 let c: i64 = b[p] as i64
530 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; p = p + 1 } else { dig = 0 } } else { dig = 0 }
531 }
532 }
533 if any == 1 { out = v }
534 }
535 walking = 0
536 } else { i = le + 1 }
537 }
538 }
539 sys_munmap(b, n)
540 return out
541}
542func rd_name_losses(organ: *u8, dep: *u8, fresh: *u8) -> i64 {
543 let fd: i64 = sys_openat_append(RD_LOSSLOG, MODE_0644)
544 if fd < 0 { return 0 - 1 }
545 let hb: *u8 = sys_mmap(RD_PATHCAP)
546 var o: i64 = rd_cpy(hb, "\n=== " as *u8)
547 o = rd_cat(hb, o, organ)
548 o = rd_cat(hb, o, " epoch=" as *u8)
549 o = rd_catn(hb, o, sys_now_realtime_sec())
550 o = rd_cat(hb, o, " (capabilities the DEPLOYED binary has and the FRESH build does not)\n" as *u8)
551 sys_write(fd, hb, o)
552 sys_munmap(hb, RD_PATHCAP)
553 let pid: i64 = sys_fork()
554 if pid < 0 { sys_close(fd); return 0 - 1 }
555 if pid == 0 {
556 sys_dup3(fd, 1, 0)
557 sys_dup3(fd, 2, 0)
558 let av: *i64 = sys_mmap(64) as *i64
559 av[0] = RD_CDIFF_ELF as i64
560 av[1] = dep as i64
561 av[2] = fresh as i64
562 av[3] = 0
563 let ev: *i64 = sys_mmap(16) as *i64
564 ev[0] = 0
565 sys_execve(RD_CDIFF_ELF, av, ev)
566 sys_exit(127)
567 }
568 let st: *i64 = sys_mmap(16) as *i64
569 sys_wait4(pid, st, 0)
570 sys_close(fd)
571 return wait_exit_code(st[0])
572}
573// ★★★★★★A GUARD THAT MEASURES ONLY LOSS WILL BLOCK EVERY UPGRADE THAT RENAMES ANYTHING. MEASURED
574// 2026-08-15 on nx_archive_daemon: the fresh build LOSES 2 runs (an old `User-Agent: NishiReader/2.0` +
575// its Accept twin, replaced by the Chrome header set nx_polite_browser now emits) and GAINS 139 --
576// including ARENA-OVERRUN, ring_sizes and the fail-loud ENOMEM messages, i.e. the arena safety work the
577// deployed binary predates. Refusing that install keeps the OLDER, LESS SAFE binary in production, and
578// re-refuses it on every firing forever.
579// ★A ONE-DIRECTION DIFF CANNOT TELL A REGRESSION FROM A REWORD -- the gain is half the evidence and the
580// guard was reading neither.
581// THE THRESHOLD IS NOT INVENTED HERE. /api/promote's calibrated guard already permits 1-2 absent runs:
582// ordinary edits measure 8-38 permil, and EVERY real regression cleared 49+ permil / 10+ runs. This
583// adopts that measured floor in the unit available (run count), so the drain DECIDES LIKE PROMOTE
584// DECIDES -- ★TWO GUARDS FOR ONE INVARIANT WITH DIFFERENT THRESHOLDS IS THE DUPLICATE-RULER DEFECT.
585// ⚠A loss below the floor is never silent: it is still NAMED in the loss log and reported in the row.
586// ★★★★★★A DRAIN THAT CANNOT TELL A LIVE SERVICE FROM A ONE-SHOT WILL EVENTUALLY DEPLOY ONE WITHOUT
587// A HEALTH CHECK. Every install so far landed on a NON-running binary -- verified against the live table,
588// not assumed -- but that was the luck of the queue order, not a property of this organ. The backlog
589// holds nx_opaque_login, nx_gallery_serve and nx_mgmt_api among its 1,828 rows, and this organ's guards
590// are all STATIC (content, size, rollback): none of them asks "does it still serve after the swap?".
591// The estate already states the rule -- /api/promote REFUSES daemons with "A DAEMON must use the
592// health-checked /api/deploy (validate -> promote -> http-health -> auto-rollback), not /api/promote --
593// that is the correct path, not a workaround." This organ was bypassing that lane entirely.
594// ★READ THE LIVE TABLE, NEVER HARDCODE A SERVICE LIST: the supervisor writes mgmt_snap.json every poll,
595// so the set is DATA that stays current on its own. A baked-in list would rot into a guard that waves
596// through whatever was added after it was written.
597// ⚠Refusing is the SAFE direction: a deferred upgrade leaves the estate exactly as it is, while an
598// unchecked daemon swap can take a service down and only the NEXT restart would reveal it (the rename
599// leaves the running inode alone, so the damage is silent until then -- the worst shape a failure can
600// have).
601const RD_SNAP: *u8 = "mgmt_snap.json"
602// ⛔NO CAP HERE, AND THE REASON IS THE GUARD'S OWN SAFETY. This read used a hand-picked 65536 ceiling.
603// mgmt_snap.json measures 662 B today -- 99x headroom, which is exactly why the defect was invisible --
604// but a capped read TRUNCATES IN SILENCE, and a truncated live-service table reads as `not live` for
605// every service past the cut. The guard would then wave an unchecked daemon swap through, and the rename
606// leaves the running inode alone so nothing would surface until the next restart.
607// ★★★★★★A SAFETY GUARD WHOSE INPUT CAN TRUNCATE SILENTLY FAILS OPEN, AND ITS HEADROOM TODAY IS NOT A
608// PROPERTY OF TOMORROW'S DATA. sys_read_file sizes from the file and cannot short-read.
609func rd_is_live_service(name: *u8) -> i64 {
610 let lenp: *i64 = sys_mmap(8)
611 let b: *u8 = sys_read_file(RD_SNAP, lenp)
612 let n: i64 = lenp[0]
613 sys_munmap(lenp as *u8, 8)
614 if n <= 0 {
615 // ★A GUARD THAT CANNOT MEASURE MUST REFUSE, NEVER WAVE THROUGH. No snapshot means we cannot tell
616 // whether this target is live, and installing on that basis is exactly the gamble to avoid.
617 return 0 - 1
618 }
619 let pat: *u8 = sys_mmap(RD_PATHCAP)
620 var p: i64 = rd_cpy(pat, "SVC " as *u8)
621 p = rd_cat(pat, p, name)
622 p = rd_cat(pat, p, ".elf " as *u8)
623 var found: i64 = 0
624 var i: i64 = 0
625 while i < n {
626 var le: i64 = i
627 var sc: i64 = 1
628 while sc == 1 { if le >= n { sc = 0 } else { if b[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
629 if rd_starts_at(b, i, le, pat) == 1 { found = 1; i = n } else { i = le + 1 }
630 }
631 sys_munmap(pat, RD_PATHCAP)
632 sys_munmap(b, n)
633 return found
634}
635const RD_PORTMAP: *u8 = "knowledge/status/portmap.conf"
636// ⛔A DAEMON THAT HAPPENS TO BE DOWN IS STILL A DAEMON. rd_is_live_service reads mgmt_snap, which lists
637// only what is RUNNING -- so a declared service that is currently stopped sails past it and gets its
638// binary swapped by a rename, bypassing the health-checked /api/deploy lane. ★★★★★A GUARD KEYED ON
639// CURRENT STATE MISSES EVERY SUBJECT THAT IS BETWEEN STATES, AND `stopped` IS EXACTLY WHEN A BAD BINARY
640// LANDS UNNOTICED: nothing fails until the next start. portmap.conf is the CANONICAL port registry and
641// its own header states the rule -- "A listener absent here is UNDECLARED." Owning a port IS the
642// declaration. 1 = declared owner, 0 = not, -1 = unreadable (caller refuses, never waves through).
643func rd_owns_port(name: *u8) -> i64 {
644 let lenp: *i64 = sys_mmap(8)
645 let b: *u8 = sys_read_file(RD_PORTMAP, lenp)
646 let n: i64 = lenp[0]
647 sys_munmap(lenp as *u8, 8)
648 if n <= 0 { return 0 - 1 }
649 let pat: *u8 = sys_mmap(RD_PATHCAP)
650 var p: i64 = rd_cpy(pat, name)
651 p = rd_cat(pat, p, ".elf" as *u8)
652 var found: i64 = 0
653 var i: i64 = 0
654 var walking: i64 = 1
655 while walking == 1 {
656 if i >= n { walking = 0 } else {
657 var le: i64 = i
658 var sc: i64 = 1
659 while sc == 1 { if le >= n { sc = 0 } else { if b[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
660 if le > i { if b[i] != (35 as u8) {
661 let t: i64 = rd_find_byte(b, i, le, RD_TAB_C)
662 if t >= 0 { if rd_starts_at(b, t + 1, le, pat) == 1 {
663 // ★rd_starts_at IS A PREFIX TEST, so the field must also END here or `nx_foo.elf`
664 // matches a row owning `nx_foo.elf.bak`. A PREFIX TEST STANDING IN FOR AN EXACT ONE.
665 if t + 1 + p >= le { found = 1; walking = 0 }
666 } }
667 } }
668 if walking == 1 { i = le + 1 }
669 }
670 }
671 sys_munmap(pat, RD_PATHCAP)
672 sys_munmap(b, n)
673 return found
674}
675const RD_LOSS_REGRESSION_RUNS: i64 = 10
676const RD_ADMIT_REFUSED: i64 = 6
677// BUILD SLOTS PER FIRING -- not rows per firing; rows we decline to build cost no slot (see the
678// work-done-not-work-offered note in the drain loop). ★A CONSTANT MUST CARRY THE ARITHMETIC THAT CHOSE
679// IT, OR THE NEXT READER CAN ONLY GUESS WHETHER RAISING IT IS SAFE. MEASURED 2026-08-16 from this
680// organ's own elapsed_s column: fixed cost per firing ~9 s (plan regeneration + lib skips), marginal
681// cost ~10 s per build, so 4 slots = ~48 s. Against the 1800 s period adopted from the estate's
682// established queue-drain beat (ddqbeat, nx_dedup_migrate queue 2) that is a 2.7% duty cycle.
683// ⚠The REAL governor is not this number: nx_sov_build_run's admission controller refuses per-build
684// when the box lacks headroom and the drain STOPS on SBR_ADMIT_REFUSED, so a loaded box drains slower
685// by measurement rather than by anything guessed here. Raise this only with a fresh elapsed_s reading.
686const RD_BEAT_BATCH: i64 = 4
687// The durable series. Append-only, TAB-separated, one line per run of the `beat` VERB -- which is NOT
688// the same as one line per SCHEDULED firing, and conflating the two is what made this series unreadable:
689// read `src=scheduled` rows for cadence and backlog trend, `src=manual` rows for operator-driven drains.
690// The schedule itself is NEVER inferable from this file; the clocksched- plane is its only authority. nx_sizeguard already exists
691// to watch a status journal's growth and its sibling calibration is knowledge/status/procchurn.jrnl at
692// 1048576 B / 20000 lines -- REUSE THAT BUDGET rather than inventing one when this is wired to a guard.
693const RD_TREND: *u8 = "knowledge/status/rebuild_drain.jrnl"
694func rd_trend(backlog: i64, attempted: i64, installed: i64, notprog: i64, failed: i64, src: *u8, elapsed: i64, ddaemon: i64, dlive: i64, current: i64, hstop: i64) -> i64 {
695 let fd: i64 = sys_openat_append(RD_TREND, MODE_0644)
696 if fd < 0 {
697 // ★AN UNWRITABLE TREND MUST ANNOUNCE, NOT VANISH: a silently missing row reads later as "the
698 // beat did not fire", which is the exact confusion this series exists to remove.
699 rd_w("{\"organ\":\"nx_rebuild_drain\",\"trend\":\"UNWRITABLE\",\"path\":\"" as *u8)
700 rd_w(RD_TREND); rd_w("\"}\n" as *u8)
701 return 0 - 1
702 }
703 let b: *u8 = sys_mmap(RD_PATHCAP)
704 var o: i64 = 0
705 o = rd_catn(b, o, sys_now_realtime_sec())
706 o = rd_cat(b, o, "\tbacklog=" as *u8); o = rd_catn(b, o, backlog)
707 o = rd_cat(b, o, "\tattempted=" as *u8); o = rd_catn(b, o, attempted)
708 o = rd_cat(b, o, "\tinstalled=" as *u8); o = rd_catn(b, o, installed)
709 o = rd_cat(b, o, "\tnot_a_program=" as *u8); o = rd_catn(b, o, notprog)
710 o = rd_cat(b, o, "\tfailed=" as *u8); o = rd_catn(b, o, failed)
711 o = rd_cat(b, o, "\tsrc=" as *u8); o = rd_cat(b, o, src)
712 // ★★★★★A BEAT THAT DOES NOT REPORT ITS OWN DURATION CANNOT BE SCHEDULED FROM EVIDENCE -- the period is
713 // then chosen by taste, and the only feedback is a queue that visibly never drains. With elapsed in
714 // the series the duty cycle (elapsed/period) is arithmetic any later reader can redo.
715 o = rd_cat(b, o, "\telapsed_s=" as *u8); o = rd_catn(b, o, elapsed)
716 // REASON TRAVELS WITH THE COUNT (2026-08-29): these buckets were COMPUTED on every beat and then
717 // thrown away by this row, so `backlog=2301 installed=0` read for 15 hours as a broken drain when
718 // it is mostly DAEMONS this organ CORRECTLY defers to the health-checked /api/deploy lane, plus a
719 // program tail starved by build admission on a loaded box. Additive columns, appended LAST.
720 o = rd_cat(b, o, "\tdeferred_daemon=" as *u8); o = rd_catn(b, o, ddaemon)
721 o = rd_cat(b, o, "\tdeferred_live=" as *u8); o = rd_catn(b, o, dlive)
722 o = rd_cat(b, o, "\talready_current=" as *u8); o = rd_catn(b, o, current)
723 o = rd_cat(b, o, "\theadroom_stopped=" as *u8); o = rd_catn(b, o, hstop)
724 b[o] = 10 as u8
725 o = o + 1
726 sys_write(fd, b, o)
727 sys_close(fd)
728 sys_munmap(b, RD_PATHCAP)
729 return 0
730}
731// decimal append into dst at o, returns new offset (MSB-first, no allocation)
732func rd_catn(dst: *u8, o: i64, v: i64) -> i64 {
733 var m: i64 = v
734 if m < 0 { dst[o] = 45 as u8; return rd_catn(dst, o + 1, 0 - m) }
735 if m == 0 { dst[o] = 48 as u8; return o + 1 }
736 let t: *u8 = sys_mmap(32)
737 var k: i64 = 0
738 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
739 var p: i64 = o
740 while k > 0 { k = k - 1; dst[p] = t[k]; p = p + 1 }
741 sys_munmap(t, 32)
742 return p
743}
744const RD_PLAN_ELF: *u8 = "./_offc/nx_rebuild_plan.elf"
745const RD_BEAT_LIST: *u8 = "/tmp/nx_rebuild_beat.list"
746func rd_plan_list(elfdir: *u8, srcroot: *u8, outpath: *u8) -> i64 {
747 let pid: i64 = sys_fork()
748 if pid < 0 { return 0 - 1 }
749 if pid == 0 {
750 let ofd: i64 = sys_openat_wr(outpath, MODE_0644)
751 if ofd < 0 { sys_exit(126) }
752 sys_dup3(ofd, 1, 0)
753 let av: *i64 = sys_mmap(64) as *i64
754 av[0] = RD_PLAN_ELF as i64
755 av[1] = "list" as i64
756 av[2] = elfdir as i64
757 av[3] = srcroot as i64
758 av[4] = 0
759 let ev: *i64 = sys_mmap(16) as *i64
760 ev[0] = 0
761 sys_execve(RD_PLAN_ELF, av, ev)
762 sys_exit(127)
763 }
764 let st: *i64 = sys_mmap(16) as *i64
765 sys_wait4(pid, st, 0)
766 return wait_exit_code(st[0])
767}
768
769// 1 iff <broot>/runtime/**/<name>.nx declares a main(). A source without one is a LIBRARY and can never
770// link standalone -- `nxasm_x86: UNDEFINED label: main` is the toolchain saying "not a program", not
771// "broken code". Checked BEFORE spending a compile, because the compile is the expensive part and its
772// failure is indistinguishable from a real one once you only have an rc.
773// ⚠Both source roots are probed in the builder's own order (_hdl_build first, then runtime), so this
774// reports on the file that actually compiles rather than the first one that happens to exist.
775const RD_MAINDECL: *u8 = "func main("
776// ⚠⚠READS THE WHOLE SOURCE, NOT A HEAD WINDOW. In this corpus main() is conventionally the LAST
777// function in the file, so a head-capped read would have found it in almost nothing and reported every
778// program as NOT-A-PROGRAM -- vacuous by construction, and it would have silently emptied the drain's
779// work queue while looking like a clean classification. ★A HEAD READ CANNOT ANSWER A QUESTION ABOUT THE
780// TAIL. rd_slurp is the organ's existing whole-file reader; composing it keeps one reader, not two.
781func rd_has_main(broot: *u8, name: *u8) -> i64 {
782 let p: *u8 = sys_mmap(RD_PATHCAP)
783 let lenp: *i64 = sys_mmap(8)
784 var c: i64 = rd_cpy(p, broot)
785 c = rd_cat(p, c, "/runtime/_hdl_build/" as *u8)
786 c = rd_cat(p, c, name)
787 c = rd_cat(p, c, ".nx" as *u8)
788 var buf: *u8 = sys_read_file(p, lenp)
789 var n: i64 = lenp[0]
790 if n <= 0 {
791 c = rd_cpy(p, broot)
792 c = rd_cat(p, c, "/runtime/" as *u8)
793 c = rd_cat(p, c, name)
794 c = rd_cat(p, c, ".nx" as *u8)
795 buf = sys_read_file(p, lenp)
796 n = lenp[0]
797 }
798 var found: i64 = 0
799 if n > 0 {
800 var i: i64 = 0
801 while i < n {
802 // ⚠⚠EXIT BY FLAG, NEVER BY CLOBBERING THE CURSOR. The first cut of this wrote `k = 9` to
803 // break out -- but the needle is 10 bytes, so RD_MAINDECL[9] is '(' and NOT the terminator:
804 // on a mismatch it reset k to 9 and span forever at 100% CPU. ★★★★★★A LOOP THAT BREAKS BY
805 // CLOBBERING ITS OWN CURSOR IS THE DEFECT THIS ESTATE HAS ALREADY PAID FOR FOUR TIMES IN A
806 // DAY, AND I WROTE IT AGAIN -- the fix is a separate flag, which cannot be off-by-one.
807 var k: i64 = 0
808 var ok: i64 = 1
809 var scanning: i64 = 1
810 while scanning == 1 {
811 if RD_MAINDECL[k] == (0 as u8) { scanning = 0 } else {
812 if i + k >= n { ok = 0; scanning = 0 } else {
813 if buf[i+k] != RD_MAINDECL[k] { ok = 0; scanning = 0 } else { k = k + 1 }
814 }
815 }
816 }
817 if ok == 1 { found = 1; i = n } else { i = i + 1 }
818 }
819 }
820 if n > 0 { sys_munmap(buf, n) }
821 sys_munmap(lenp as *u8, 8)
822 sys_munmap(p, RD_PATHCAP)
823 return found
824}
825
826// ★★★★★★DEDUPE TO SUBJECTS, THEN SPLIT BY REMEDY, BEFORE PUBLISHING ANY BACKLOG NUMBER. `1,852
827// stale organs` is a MIXED POPULATION, not a work queue: some rows are libraries whose basename happens
828// to match a deployed elf and can NEVER be built, some have no deployed elf at all, and only the
829// remainder is work. Reporting the total as a backlog sends the next reader on a campaign that cannot
830// finish. This verb answers the partition WITHOUT SPENDING A SINGLE COMPILE -- the classification is a
831// file read per row, and the compile is the expensive part -- so the honest number is cheap to have and
832// there is no excuse for quoting the mixed one.
833// ⚠Walks the WHOLE list, never a batch: a partition measured over a prefix is a sample wearing a
834// population's name.
835func rd_classify(listp: *u8, broot: *u8, elfdir: *u8) -> i64 {
836 let lb: *u8 = sys_mmap(RD_LISTCAP)
837 let lfd: i64 = sys_openat_rd(listp)
838 if lfd < 0 { rd_w("{\"organ\":\"nx_rebuild_drain\",\"refused\":\"listfile unreadable\"}\n" as *u8); return 2 }
839 let ln: i64 = sys_read(lfd, lb, RD_LISTCAP - 1)
840 sys_close(lfd)
841 if ln <= 0 { rd_w("{\"organ\":\"nx_rebuild_drain\",\"refused\":\"list EMPTY\"}\n" as *u8); return 2 }
842 lb[ln] = 0 as u8
843 let name: *u8 = sys_mmap(RD_PATHCAP)
844 let dep: *u8 = sys_mmap(RD_PATHCAP)
845 var rows: i64 = 0
846 var notprog: i64 = 0
847 var noelf: i64 = 0
848 var daemonrow: i64 = 0
849 var unsafe_name: i64 = 0
850 var buildable: i64 = 0
851 var i: i64 = 0
852 while i < ln {
853 var le: i64 = i
854 var sc: i64 = 1
855 while sc == 1 { if le >= ln { sc = 0 } else { if lb[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
856 if le > i {
857 var o: i64 = 0
858 var k: i64 = i
859 while k < le { if o < RD_PATHCAP - 1 { name[o] = lb[k]; o = o + 1 } k = k + 1 }
860 name[o] = 0 as u8
861 rows = rows + 1
862 if rd_safe(name) == 0 { unsafe_name = unsafe_name + 1 } else {
863 var c: i64 = rd_cpy(dep, elfdir)
864 c = rd_cat(dep, c, "/" as *u8)
865 c = rd_cat(dep, c, name)
866 c = rd_cat(dep, c, ".elf" as *u8)
867 if rd_size(dep) < 0 { noelf = noelf + 1 } else {
868 let tgt: *u8 = sys_mmap(RD_PATHCAP)
869 let aliased: i64 = rd_alias(name, tgt)
870 // ★★★★★SPLIT BY REMEDY BEFORE PUBLISHING A BACKLOG NUMBER. A DECLARED DAEMON belongs to the
871 // health-checked /api/deploy lane and can NEVER be drained by this one, so counting it
872 // as `buildable` makes the work queue permanently unreachable -- a backlog that cannot
873 // reach zero reads as failure when it is actually correct. Checked FIRST because it is
874 // the most specific fact: nx_project_serve is BOTH a declared daemon and a lib basename,
875 // and `daemon` is the one that names its remedy.
876 if rd_owns_port(name) == 1 {
877 daemonrow = daemonrow + 1
878 rd_w("DECLARED-DAEMON " as *u8); rd_w(name); rd_w(" -- /api/deploy lane, not this one\n" as *u8)
879 } else {
880 if rd_has_main(broot, tgt) == 0 {
881 notprog = notprog + 1
882 rd_w("LIB-BASENAME " as *u8); rd_w(name); rd_w("\n" as *u8)
883 } else {
884 buildable = buildable + 1
885 if aliased == 1 { rd_w("ALIASED " as *u8); rd_w(name); rd_w(" -> " as *u8); rd_w(tgt); rd_w("\n" as *u8) }
886 }
887 }
888 sys_munmap(tgt, RD_PATHCAP)
889 }
890 }
891 }
892 i = le + 1
893 }
894 rd_w("{\"organ\":\"nx_rebuild_drain\",\"verb\":\"classify\",\"rows\":" as *u8); rd_n(rows)
895 rd_w(",\"buildable\":" as *u8); rd_n(buildable)
896 rd_w(",\"lib_basename_never_buildable\":" as *u8); rd_n(notprog)
897 rd_w(",\"no_deployed_elf\":" as *u8); rd_n(noelf)
898 rd_w(",\"declared_daemon_other_lane\":" as *u8); rd_n(daemonrow)
899 rd_w(",\"unsafe_name\":" as *u8); rd_n(unsafe_name)
900 let sum: i64 = buildable + notprog + noelf + unsafe_name + daemonrow
901 rd_w(",\"partition_sum\":" as *u8); rd_n(sum)
902 if sum == rows { rd_w(",\"reconciles\":1" as *u8) } else { rd_w(",\"reconciles\":0" as *u8) }
903 rd_w(",\"note\":\"buildable is the ONLY row count that is a work queue; the rest need adjudication, not compiles\"}\n" as *u8)
904 return 0
905}
906
907func main(argc: i64, argv: *i64) -> i64 {
908 if argc < 2 { rd_w("usage: nx_rebuild_drain <listfile> [batch] [buildroot] [elfdir]\n nx_rebuild_drain classify <listfile> [buildroot] [elfdir]\n" as *u8); sys_exit(2); return 2 }
909 // beat sets these and falls through into the ONE drain body below -- a second copy of the drain
910 // loop would be a second thing to keep correct, and the two would silently disagree the first time
911 // either changed.
912 var is_beat: i64 = 0
913 let t_start: i64 = sys_now_realtime_sec()
914 var beat_list: *u8 = "" as *u8
915 var beat_batch: i64 = 0
916 // ★★★★★★A GUARD THAT KEYS ON THE VERB CANNOT SEE WHO TYPED IT. `is_beat` was meant to keep hand-runs
917 // out of the durable series, and it could not: invoking the `beat` verb by hand mints rows that are
918 // byte-identical to the scheduler's. I then read three of my OWN rows as evidence of a 5-minute
919 // cadence and published a 6-day drain estimate for a job that fires DAILY. Only the CLOCK ROW passes
920 // `scheduled`, so an operator can never mint a scheduled row by accident.
921 var beat_src: *u8 = "manual" as *u8
922 var beat_broot: *u8 = "buildroot" as *u8
923 var beat_elfdir: *u8 = "." as *u8
924 if rd_streq(argv[1] as *u8, "beat" as *u8) == 1 {
925 var bb: i64 = RD_BEAT_BATCH
926 var bbr: *u8 = "buildroot" as *u8
927 var bed: *u8 = "." as *u8
928 if argc >= 3 {
929 let bs: *u8 = argv[2] as *u8
930 var v: i64 = 0
931 var q: i64 = 0
932 while bs[q] != (0 as u8) { let c: i64 = bs[q] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } q = q + 1 }
933 if v > 0 { bb = v }
934 }
935 if argc >= 4 { bbr = argv[3] as *u8 }
936 if argc >= 5 { bed = argv[4] as *u8 }
937 // ★A FLAG THAT ACCEPTS ANY SPELLING CANNOT REPORT A TYPO -- exact token or refuse, so a clock row
938 // with a mistyped marker fails LOUDLY instead of silently logging every scheduled firing as manual.
939 var bsrc: *u8 = "manual" as *u8
940 if argc >= 6 {
941 if rd_streq(argv[5] as *u8, "scheduled" as *u8) == 1 { bsrc = "scheduled" as *u8 } else {
942 rd_w("{\"organ\":\"nx_rebuild_drain\",\"verb\":\"beat\",\"refused\":\"unrecognised source marker -- the only accepted token is `scheduled`, and only the clock row passes it\"}\n" as *u8)
943 sys_exit(2)
944 return 2
945 }
946 }
947 // ★REGENERATE FIRST. Installing changes who is stale, so a beat that reuses yesterday's list
948 // re-attempts work already done and misses work newly created.
949 let prc: i64 = rd_plan_list(bed, "buildroot/runtime" as *u8, RD_BEAT_LIST)
950 if prc != 0 {
951 rd_w("{\"organ\":\"nx_rebuild_drain\",\"verb\":\"beat\",\"refused\":\"plan list failed\",\"rc\":" as *u8)
952 rd_n(prc); rd_w("}\n" as *u8)
953 sys_exit(0)
954 return 0
955 }
956 rd_w("{\"organ\":\"nx_rebuild_drain\",\"verb\":\"beat\",\"list\":\"" as *u8)
957 rd_w(RD_BEAT_LIST); rd_w("\",\"batch\":" as *u8); rd_n(bb); rd_w(",\"src\":\"" as *u8); rd_w(bsrc); rd_w("\"}\n" as *u8)
958 beat_list = RD_BEAT_LIST
959 beat_batch = bb
960 beat_src = bsrc
961 beat_broot = bbr
962 beat_elfdir = bed
963 is_beat = 1
964 }
965 if rd_streq(argv[1] as *u8, "classify" as *u8) == 1 {
966 if argc < 3 { rd_w("usage: nx_rebuild_drain classify <listfile> [buildroot] [elfdir]\n" as *u8); sys_exit(2); return 2 }
967 var cb: *u8 = "buildroot" as *u8
968 var ce: *u8 = "." as *u8
969 if argc >= 4 { cb = argv[3] as *u8 }
970 if argc >= 5 { ce = argv[4] as *u8 }
971 let rcc: i64 = rd_classify(argv[2] as *u8, cb, ce)
972 sys_exit(rcc)
973 return rcc
974 }
975 var listp: *u8 = argv[1] as *u8
976 var batch: i64 = RD_DEFAULT_BATCH
977 var broot: *u8 = "buildroot" as *u8
978 var elfdir: *u8 = "." as *u8
979 if argc >= 3 {
980 let bs: *u8 = argv[2] as *u8
981 var v: i64 = 0
982 var i: i64 = 0
983 while bs[i] != (0 as u8) { let c: i64 = bs[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 }
984 if v > 0 { batch = v }
985 }
986 if argc >= 4 { broot = argv[3] as *u8 }
987 if argc >= 5 { elfdir = argv[4] as *u8 }
988 if is_beat == 1 { listp = beat_list; batch = beat_batch; broot = beat_broot; elfdir = beat_elfdir }
989
990 let lb: *u8 = sys_mmap(RD_LISTCAP)
991 let lfd: i64 = sys_openat_rd(listp)
992 if lfd < 0 { rd_w("{\"organ\":\"nx_rebuild_drain\",\"refused\":\"listfile unreadable\"}\n" as *u8); sys_exit(2); return 2 }
993 let ln: i64 = sys_read(lfd, lb, RD_LISTCAP - 1)
994 sys_close(lfd)
995 if ln <= 0 { rd_w("{\"organ\":\"nx_rebuild_drain\",\"drained\":0,\"note\":\"list EMPTY -- nothing stale, or the plan was never run\"}\n" as *u8); return 0 }
996 lb[ln] = 0 as u8
997
998 let name: *u8 = sys_mmap(RD_PATHCAP)
999 let fresh: *u8 = sys_mmap(RD_PATHCAP)
1000 let dep: *u8 = sys_mmap(RD_PATHCAP)
1001 let tmpn: *u8 = sys_mmap(RD_PATHCAP)
1002 let prevn: *u8 = sys_mmap(RD_PATHCAP)
1003 var installed: i64 = 0
1004 var notprog: i64 = 0
1005 // ★★★★★★COUNTED BEFORE THE BATCH BOUND, NOT INSIDE IT. The first cut incremented this in the drain
1006 // loop -- which stops after `batch` rows -- so the trend recorded `backlog=2` for a 1,852-row queue:
1007 // A COUNTER INSIDE A BOUNDED LOOP MEASURES THE BOUND, NOT THE POPULATION. Worse, the line carried a
1008 // comment asserting it counted every row, so the wrong number arrived CERTIFIED.
1009 // ★A COMMENT THAT STATES AN INTENT THE CODE DOES NOT IMPLEMENT IS WORSE THAN NO COMMENT.
1010 var total_rows: i64 = 0
1011 var stopped_headroom: i64 = 0
1012 var livedefer: i64 = 0
1013 var tr_i: i64 = 0
1014 while tr_i < ln {
1015 var tr_e: i64 = tr_i
1016 var tr_s: i64 = 1
1017 while tr_s == 1 { if tr_e >= ln { tr_s = 0 } else { if lb[tr_e] == (10 as u8) { tr_s = 0 } else { tr_e = tr_e + 1 } } }
1018 if tr_e > tr_i { total_rows = total_rows + 1 }
1019 tr_i = tr_e + 1
1020 }
1021 var nochange: i64 = 0
1022 var refused: i64 = 0
1023 var refusedc: i64 = 0
1024 var failed: i64 = 0
1025 // ★SPLIT OUT OF `failed` 2026-08-17: no-deployed-elf spends NO build slot, a BUILDFAIL spends one, and
1026 // the partition identity needs only the former. `failed` is KEPT as the union so the existing summary
1027 // field does not change meaning for any consumer (rule 19: add, never repurpose).
1028 var skipped_no_elf: i64 = 0
1029 var portdefer: i64 = 0
1030 // `done` = build slots SPENT (the batch bound). `examined` = rows the loop looked at, which is
1031 // larger whenever a row is declined without a compile. ★PUBLISH BOTH OR THE PARTITION CANNOT BE
1032 // CHECKED: examined == done + not_a_program + deferred_live_service + no-deployed-elf, and a
1033 // residual there is a row class nobody named.
1034 var done: i64 = 0
1035 var examined: i64 = 0
1036
1037 rd_w("{\"organ\":\"nx_rebuild_drain\",\"rows\":[" as *u8)
1038 var first: i64 = 1
1039 var i: i64 = 0
1040 while i < ln {
1041 if done >= batch { i = ln } else {
1042 var le: i64 = i
1043 var sc: i64 = 1
1044 while sc == 1 { if le >= ln { sc = 0 } else { if lb[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
1045 if le > i {
1046 var o: i64 = 0
1047 var k: i64 = i
1048 while k < le { if o < RD_PATHCAP - 1 { name[o] = lb[k]; o = o + 1 } k = k + 1 }
1049 name[o] = 0 as u8
1050 if rd_safe(name) == 1 {
1051 // ★★★★★★A LIMIT MUST COUNT WORK DONE, NOT WORK OFFERED. This counter used to advance HERE,
1052 // before the outcome was known, so a row we DECLINE to build spent a build slot.
1053 // MEASURED 2026-08-16: three permanently-unbuildable lib sources sit at the head of
1054 // every regenerated list, so a batch of 4 performed ONE build per firing and the
1055 // other three slots re-derived the same three refusals for ever. The comment forty
1056 // lines below already named this head-of-line block and cited the banked remedy --
1057 // the diagnosis was written and the arithmetic was never changed to match it.
1058 // ★A DIAGNOSIS IN A COMMENT IS NOT A FIX; THE QUEUE OBEYS THE COUNTER, NOT THE PROSE.
1059 examined = examined + 1
1060 var c: i64 = rd_cpy(dep, elfdir)
1061 c = rd_cat(dep, c, "/" as *u8)
1062 c = rd_cat(dep, c, name)
1063 c = rd_cat(dep, c, ".elf" as *u8)
1064 let ds: i64 = rd_size(dep)
1065 var f: i64 = rd_cpy(fresh, broot)
1066 f = rd_cat(fresh, f, "/_build/" as *u8)
1067 f = rd_cat(fresh, f, name)
1068 f = rd_cat(fresh, f, ".sov.elf" as *u8)
1069 if first == 0 { rd_w("," as *u8) }
1070 first = 0
1071 rd_w("{\"organ\":\"" as *u8); rd_w(name); rd_w("\",\"result\":\"" as *u8)
1072 // ★★★★★★"IT DOES NOT COMPILE" AND "IT IS NOT A PROGRAM" ARE DIFFERENT FACTS WITH
1073 // OPPOSITE REMEDIES. MEASURED 2026-08-15: the first two rows of the backlog reported
1074 // BUILDFAIL rc=4, and the real error is `nxasm_x86: UNDEFINED label: main` --
1075 // nx_gen_gateway.nx is a LIBRARY (its runnable twin is nx_gen_gateway_daemon.nx, which
1076 // has its own built elf). A lib can NEVER link standalone, so this row fails on every
1077 // run, never stops being stale, and sits at the head of every regenerated list.
1078 // ★★★★★★A PERMANENTLY-FAILING ROW AT THE HEAD OF AN ALWAYS-RE-SORTED QUEUE IS A
1079 // HEAD-OF-LINE BLOCK THAT NEVER CLEARS, and the estate already banked the remedy:
1080 // HIDING AN UNBUILDABLE SET INSIDE A BUILD QUEUE GUARANTEES THE QUEUE NEVER FINISHES --
1081 // dedupe to SUBJECTS, then SPLIT BY REMEDY, before publishing any backlog number.
1082 // Detected the only way that is not a guess: the source either declares main or it does
1083 // not. Reported as its own row so the two never share a counter -- a lib here needs
1084 // ADJUDICATION (whose elf is that, really?), never a compile fix.
1085 let livesvc: i64 = rd_is_live_service(name)
1086 if ds < 0 { rd_w("SKIP-NO-DEPLOYED-ELF\"}" as *u8); failed = failed + 1; skipped_no_elf = skipped_no_elf + 1 } else {
1087 // ★ONE DECISION, ONE BRANCH -- the brace shape here is UNCHANGED on purpose. A nested
1088 // else would mean hand-balancing a 13-deep cascade, and a mis-closed brace in a live
1089 // installer is a worse defect than the one being fixed.
1090 // ★NAME WHICH REASON: a RUNNING service and a DECLARED-but-stopped one take the same
1091 // remedy but are not the same fact, and two skip-causes sharing one counter is how a
1092 // population stops being adjudicable.
1093 let portown: i64 = rd_owns_port(name)
1094 var deferany: i64 = 0
1095 if livesvc != 0 { deferany = 1 }
1096 if portown != 0 { deferany = 1 }
1097 if deferany != 0 {
1098 if livesvc < 0 { rd_w("REFUSED-CANNOT-READ-LIVE-TABLE\"}" as *u8) } else {
1099 if livesvc != 0 { rd_w("DEFERRED-LIVE-SERVICE-USE-API-DEPLOY\"}" as *u8) } else {
1100 if portown < 0 { rd_w("REFUSED-CANNOT-READ-PORTMAP\"}" as *u8) } else { rd_w("DEFERRED-DECLARED-DAEMON-USE-API-DEPLOY\"}" as *u8) } } }
1101 if livesvc != 0 { livedefer = livedefer + 1 } else { portdefer = portdefer + 1 }
1102 } else {
1103 // ⛔RESOLVE THE ALIAS BEFORE THE GATE THAT REJECTS ON IT. The first wiring put this
1104 // AFTER rd_has_main, which tests the DEPLOYED BASENAME -- so an aliased row was
1105 // rejected as a library before the alias was ever consulted, and the change was a
1106 // no-op that still compiled and still passed neutrality.
1107 // ★★★★★A LOOKUP PLACED AFTER THE TEST IT EXISTS TO SATISFY CANNOT CHANGE ANY OUTCOME,
1108 // AND NOTHING IN THE BUILD OR THE TEST SUITE SAYS SO -- only running the aliased row
1109 // and seeing the OLD verdict does. rd_classify already had this order right; the
1110 // drain path did not, which is exactly how the two halves drifted.
1111 let btgt: *u8 = sys_mmap(RD_PATHCAP)
1112 let usedalias: i64 = rd_alias(name, btgt)
1113 if rd_has_main(broot, btgt) == 0 {
1114 rd_w("NOT-A-PROGRAM-LIB-SOURCE\"}" as *u8)
1115 notprog = notprog + 1
1116 sys_munmap(btgt, RD_PATHCAP)
1117 } else {
1118 // The slot is spent HERE -- at the first action that costs the box a compile.
1119 // STOPPED-NO-HEADROOM counts too: the box was asked, and asking is the work.
1120 done = done + 1
1121 // ⛔THE ALIAS WAS RESOLVED FOR THE CLASSIFIER AND NEVER FOR THE BUILDER. rd_alias had
1122 // exactly two call sites -- its definition and rd_classify -- so the conf could
1123 // REPORT a resolved provenance while the drain still compiled the deployed basename,
1124 // which for an aliased row is a LIBRARY that can never link.
1125 // ★★★★★★A REGISTRY WIRED INTO THE REPORT BUT NOT INTO THE ACTION IS BUILT+UNWIRED
1126 // WEARING THE COSTUME OF A FEATURE: every reader sees the mapping and nothing obeys it.
1127 // BUILD the alias target and read ITS artifact; COMPARE against the DEPLOYED basename.
1128 // Non-aliased rows are unaffected BY CONSTRUCTION -- rd_alias copies `name` through
1129 // unchanged when no proven/equivalent row matches.
1130 if usedalias == 1 {
1131 var af: i64 = rd_cpy(fresh, broot)
1132 af = rd_cat(fresh, af, "/_build/" as *u8)
1133 af = rd_cat(fresh, af, btgt)
1134 af = rd_cat(fresh, af, ".sov.elf" as *u8)
1135 }
1136 let rc: i64 = rd_build(broot, btgt, rd_live_has_debug(dep))
1137 // ⛔LOG BEFORE THE FREE. The first cut called rd_fail_log(name, btgt, rc) at the JSON
1138 // emit site far below -- AFTER this munmap -- a USE-AFTER-FREE that SIGSEGV'd the live
1139 // drain on its very first BUILDFAIL. The ledger file was created at 0 bytes, so the
1140 // open succeeded and the crash landed writing the freed pointer.
1141 // ★★★★★★A LEDGER ADDED TO RECORD FAILURES BECAME THE FAILURE: I extended the LIFETIME of
1142 // a borrowed buffer by adding a reader, and nothing in the build or the neutrality
1143 // test could see it -- only running the exact row that fails.
1144 // ★AN ARGUMENT THAT OUTLIVES ITS OWNER'S munmap IS A DANGLING POINTER NO MATTER HOW
1145 // OBVIOUSLY CORRECT THE CALL LOOKS AT THE CALL SITE.
1146 let fs: i64 = rd_size(fresh)
1147 // ⛔BACKPRESSURE IS NOT A FAILURE, AND AN APPEND-ONLY LEDGER MUST NOT SAY IT IS.
1148 // rc == RD_ADMIT_REFUSED is the BOX saying "stop", not the TARGET saying "broken".
1149 // The emit logic below already earned that exclusion (see its note); the ledger I
1150 // added would have bypassed it and permanently recorded healthy organs as failures --
1151 // the exact regression that note exists to prevent, re-entered through a new door.
1152 // ★★★★★★A NEW RECORDER MUST INHERIT EVERY EXCLUSION THE EXISTING REPORTER ALREADY
1153 // EARNED; ADDING AN OUTPUT IS NOT NEUTRAL JUST BECAUSE IT ONLY WRITES.
1154 // ⚠Both calls sit BEFORE the munmap so btgt is still owned -- fs is hoisted above the
1155 // free for the same reason, which also lets NO-ARTIFACT record the real built target
1156 // instead of the deployed basename.
1157 if rc != 0 { if rc != RD_ADMIT_REFUSED { rd_fail_log(name, btgt, rc) } }
1158 if rc == 0 { if fs < 0 { rd_fail_log(name, btgt, 0 - 1) } }
1159 sys_munmap(btgt, RD_PATHCAP)
1160 // ★★★★★★BACKPRESSURE IS NOT A FAILURE. nx_sov_build_run returns SBR_ADMIT_REFUSED(6)
1161 // for all three admission denials -- DENY-MEM, QUEUE, CANNOT-MEASURE -- and its
1162 // source says why that code is distinct: the NAS branch once returned the raw
1163 // 3/4/5 which COLLIDE with COMPILE_FAIL/ASM_FAIL, so "a wait-and-retry signal
1164 // decoded as a broken build". My drain counted every rc!=0 as BUILDFAIL and would
1165 // have reproduced that regression from the other side -- recording a HEALTHY
1166 // target as broken, permanently, in an append-only trend.
1167 // ★A WAIT-AND-RETRY SIGNAL RECORDED AS A FAILURE TEACHES THE OPERATOR THAT HEALTHY
1168 // TARGETS ARE BROKEN. It STOPS the batch instead: the box is telling us to stop,
1169 // and the drain is idempotent so the remainder is simply the next firing's work.
1170 if rc == RD_ADMIT_REFUSED {
1171 rd_w("STOPPED-NO-HEADROOM\"}" as *u8)
1172 // The FLAG is what stops the loop (read at the loop tail). The old `i = ln`
1173 // written here was OVERWRITTEN by the tail's `i = le + 1` one screen down, so
1174 // "STOPS the batch" was true in prose and false in code: MEASURED 2026-08-18,
1175 // a 16-slot round printed STOPPED-NO-HEADROOM at slot 4 and went on to spend
1176 // the other 12 -- a loop-exit sentinel written into the cursor and erased, the
1177 // estate's own banked gotcha. A stop is a flag; the cursor is not a flag.
1178 stopped_headroom = 1
1179 } else {
1180 if rc != 0 { rd_w("BUILDFAIL\",\"rc\":" as *u8); rd_n(rc); rd_w("}" as *u8); failed = failed + 1 } else {
1181 if fs < 0 { rd_w("BUILDFAIL-NO-ARTIFACT\"}" as *u8); failed = failed + 1 } else {
1182 // ONE RULER: the count now comes from nx_contentdiff itself, so the drain
1183 // decides on the SAME number /api/promote's guard was calibrated against.
1184 // THE RULER SPEAKS BEFORE THE SIZE SCREEN (2026-08-18). The stub trap below
1185 // ("fresh under HALF the deployed size is a wrong-source signal") used to fire
1186 // FIRST and alone, so the content ruler never got to vouch for a small build.
1187 // Then nx_cc gained whole-program DCE and every honest rebuild became 24-72%
1188 // smaller: MEASURED on the live beat -- 11 of 16 slots per round went to
1189 // REFUSED-AMBIGUOUS-STUB-SOURCE for binaries that had lost NOTHING, the drain
1190 // tapered from 12 installs a round to 0-2, and the same 11 rows re-occupied
1191 // the head of every regenerated list. A stub source (main returns 0) is still
1192 // refused: it loses every printable run, so lostr>0 and the trap fires as
1193 // before -- but now on EVIDENCE, and an unverifiable ruler (-1) refuses too.
1194 // Same shape as the promote guard's SHRINK fix the same day: size alone
1195 // escalates only when the ruler could not vouch.
1196 let lostr: i64 = rd_cdiff_lost(name, dep, fresh, 0)
1197 var stubref: i64 = 0
1198 if fs * RD_STUB_NUM < ds { if lostr != 0 { stubref = 1 } }
1199 if stubref == 1 {
1200 rd_w("REFUSED-AMBIGUOUS-STUB-SOURCE\",\"lost_runs\":" as *u8); rd_n(lostr)
1201 rd_w(",\"fresh\":" as *u8); rd_n(fs)
1202 rd_w(",\"deployed\":" as *u8); rd_n(ds); rd_w("}" as *u8)
1203 refused = refused + 1
1204 } else {
1205 // The OTHER half of the evidence: what the fresh build adds. A rename shows
1206 // as a small loss beside a large gain; a true regression does not.
1207 var gained: i64 = 0
1208 if lostr > 0 { gained = rd_cdiff_lost(name, fresh, dep, 0) }
1209 var block: i64 = 0
1210 if lostr < 0 { block = 1 }
1211 if lostr >= RD_LOSS_REGRESSION_RUNS { block = 1 }
1212 if block == 0 { if lostr > 0 {
1213 // Below the measured regression floor: PROCEED, but never silently.
1214 rd_cdiff_lost(name, dep, fresh, 1)
1215 } }
1216 if block == 1 {
1217 // Capability the deployed binary can express and the fresh one cannot.
1218 // -1 means we could not read one of them: refuse that too, because a
1219 // guard that cannot answer must not wave things through.
1220 if lostr < 0 { rd_w("REFUSED-UNVERIFIABLE-CONTENT\",\"fresh\":" as *u8) } else { rd_w("REFUSED-CONTENT-LOSS\",\"lost_runs\":" as *u8) }
1221 if lostr > 0 { rd_n(lostr); rd_w(",\"gained_runs\":" as *u8); rd_n(gained); rd_w(",\"fresh\":" as *u8) }
1222 rd_n(fs); rd_w(",\"deployed\":" as *u8); rd_n(ds)
1223 // Name them, so the refusal is adjudicable instead of merely counted.
1224 if lostr > 0 { rd_cdiff_lost(name, dep, fresh, 1); rd_w(",\"named_in\":\"" as *u8); rd_w(RD_LOSSLOG); rd_w("\"" as *u8) }
1225 rd_w("}" as *u8)
1226 refusedc = refusedc + 1
1227 } else {
1228 if rd_same(fresh, dep) == 1 {
1229 rd_w("ALREADY-CURRENT\",\"bytes\":" as *u8); rd_n(fs); rd_w("}" as *u8)
1230 nochange = nochange + 1
1231 } else {
1232 // ★★★KEEP A WAY BACK BEFORE YOU NEED ONE. The first real drain installed 9
1233 // binaries that had SHRUNK 24-42%; the 50% stub ratio passed them and only
1234 // post-hoc probing proved they were sound. They were -- but that was LUCK,
1235 // and luck is not a guard. Rename is atomic and therefore IRREVERSIBLE: the
1236 // previous inode has no name left and cannot be rebuilt, because it came
1237 // from an older toolchain that no longer exists. So snapshot the deployed
1238 // elf to .prev FIRST; if the snapshot cannot be taken, DO NOT INSTALL.
1239 // Rule 26's shape applied to software: reversible BY CONSTRUCTION, never by
1240 // the hope that the new artifact is fine.
1241 var pv: i64 = rd_cpy(prevn, dep)
1242 pv = rd_cat(prevn, pv, ".prev" as *u8)
1243 if rd_copy(dep, prevn) == 0 { rd_w("REFUSED-NO-ROLLBACK-SNAPSHOT\"}" as *u8); failed = failed + 1 } else {
1244 var t: i64 = rd_cpy(tmpn, dep)
1245 t = rd_cat(tmpn, t, ".new" as *u8)
1246 if rd_copy(fresh, tmpn) == 0 { rd_w("COPYFAIL\"}" as *u8); failed = failed + 1 } else {
1247 nx_chmod(tmpn, 493)
1248 if sys_renameat(tmpn, dep) != 0 {
1249 rd_w("RENAMEFAIL\"}" as *u8); failed = failed + 1
1250 } else {
1251 rd_w("INSTALLED\",\"was\":" as *u8); rd_n(ds)
1252 rd_w(",\"now\":" as *u8); rd_n(rd_size(dep))
1253 rd_w(",\"rollback\":\"" as *u8); rd_w(prevn); rd_w("\"}" as *u8)
1254 installed = installed + 1
1255 rd_install_log(name, ds, fs, prevn)
1256 }
1257 }
1258 }
1259 }
1260 }
1261 }
1262 }
1263 }
1264 }
1265 }
1266 }
1267 }
1268 }
1269 }
1270 if stopped_headroom == 1 { i = ln } else { i = le + 1 }
1271 }
1272 }
1273 rd_w("],\"attempted\":" as *u8); rd_n(done)
1274 rd_w(",\"installed\":" as *u8); rd_n(installed)
1275 rd_w(",\"already_current\":" as *u8); rd_n(nochange)
1276 rd_w(",\"refused_stub_source\":" as *u8); rd_n(refused)
1277 rd_w(",\"refused_content_loss\":" as *u8); rd_n(refusedc)
1278 rd_w(",\"not_a_program\":" as *u8); rd_n(notprog)
1279 rd_w(",\"failed\":" as *u8); rd_n(failed)
1280 rd_w(",\"skipped_no_deployed_elf\":" as *u8); rd_n(skipped_no_elf)
1281 rd_w(",\"buildfail\":" as *u8); rd_n(failed - skipped_no_elf)
1282 rd_w(",\"batch\":" as *u8); rd_n(batch)
1283 rd_w(",\"examined\":" as *u8); rd_n(examined)
1284 rd_w(",\"partition_reconciles\":" as *u8)
1285 // 🔴FIXED 2026-08-17, AND MY OWN CHECK IS WHAT CAUGHT IT. This read `+ failed`, which DOUBLE-COUNTS:
1286 // a BUILDFAIL row already spent a build slot, so it is inside `done`. It reconciled in every earlier
1287 // test only because those runs contained no real build failures -- the first run that hit two
1288 // printed `partition_reconciles:0` and named the defect for me.
1289 // ★★★★★★`failed` IS A BUCKET NAMED FOR HOW THE READER FAILED, HOLDING TWO FACTS WITH OPPOSITE SLOT
1290 // ACCOUNTING: SKIP-NO-DEPLOYED-ELF spends NO slot, BUILDFAIL spends one. Only the no-elf class is an
1291 // addend here. ★A PARTITION CHECK EARNS ITS KEEP THE FIRST TIME THE POPULATION CHANGES SHAPE.
1292 if examined == done + notprog + livedefer + portdefer + skipped_no_elf { rd_n(1) } else { rd_n(0) }
1293 rd_w(",\"deferred_live_service\":" as *u8); rd_n(livedefer)
1294 rd_w(",\"deferred_declared_daemon\":" as *u8); rd_n(portdefer)
1295 rd_w(",\"stopped_for_headroom\":" as *u8); rd_n(stopped_headroom)
1296 rd_w(",\"note\":\"IDEMPOTENT: re-run to continue draining -- regenerate the list with `nx_rebuild_plan list` first, since installing changes who is stale. VERIFY BY RE-RUNNING THE CENSUS, not by trusting this summary.\"}\n" as *u8)
1297 // ★★★★★★A BEAT THAT LEAVES NO TREND IS INDISTINGUISHABLE FROM ONE THAT NEVER FIRED. The summary
1298 // above goes to a job artifact nobody keeps; unattended firings need a DURABLE series or the only
1299 // answerable question is "did it run just now", never "is the backlog shrinking".
1300 // The load-bearing column is `backlog` -- the row count of the list the beat REGENERATED this
1301 // firing. A LEVEL CANNOT EXPRESS PROGRESS: one row says nothing, two rows say whether the drain is
1302 // outpacing the staleness that shared runtimes keep creating. Append-only, one line per firing.
1303 // ⚠Written only for the `beat` VERB -- but the verb is typeable by hand, so the row carries `src=`
1304 // to say which. This comment previously claimed the two could not mix; they did, on the same day.
1305 if is_beat == 1 { rd_trend(total_rows, done, installed, notprog, failed, beat_src, sys_now_realtime_sec() - t_start, portdefer, livedefer, nochange, stopped_headroom) }
1306 return 0
1307}