code wiki / _hdl_build / nx_readmany.nx
nx_readmany.nx source
↩ module page · 318 lines · 14097 B
1// nx_readmany.nx -- ONE CALL, N FILES (Lane I common-task hardening, 2026-08-20).
2// MINED, NOT GUESSED. nx_wfcost measured the full 309-transcript / 2,006,669,677 B action record and
3// the read cluster is the largest BUILD candidate in it: nx_fs:read >> nx_fs:read 5,675 episodes,
4// nx_shelltool:grep >> nx_fs:read 1,683, nx_fs:lines >> nx_fs:lines 1,233, nx_fs:lines >> nx_fs_write:edit
5// 904 -- ~9,495 consecutive-read episodes, each one a seat turn spent re-issuing the same verb.
6// (The larger mgmt:POST cluster is deliberately NOT addressed here: nx_organ_ship already collapses it,
7// so that one is an ADOPTION gap, not a build gap -- building a second would be the duplicate ruler.)
8//
9// WHY A BATCH READ AND NOT A BIGGER CAP: the measured unit is the SEAT TURN (1 turn ~= 133,658
10// input-token-equivalents, measured, not estimated). N reads cost N turns regardless of how many bytes
11// each returns, so the win comes from collapsing TURNS, never from raising a limit.
12//
13// TWO LAWS THIS ORGAN EXISTS TO NOT BREAK:
14// 1. THE ENVELOPE IS PER ITEM, NEVER GLOBAL. A single global "truncated=1" cannot say WHICH file was
15// cut, so the caller re-reads all of them and the batch saves nothing. Every item carries its own
16// status + bytes= + of= (its TRUE full size, always known because the read is sized from the file).
17// This lane already found `nx_actlog harden` computing a truncation envelope and then dropping it
18// at the next hop -- an envelope dropped at the next hop is an envelope that was never published.
19// 2. ONE BAD TARGET MUST NOT POISON THE BATCH. Every item gets its own third state
20// (OK | EMPTY | ABSENT | UNREADABLE | BUDGET-EXHAUSTED), so an absent path costs exactly one row
21// and the other N-1 files still come back. A batch that fails whole is worse than N single reads.
22//
23// PARTITION: ok + empty + absent + unreadable + budget_exhausted == items, and the footer PRINTS the
24// sum so it can be reconciled. TRUNCATED is a SEPARATE AXIS, never a partition member -- a truncated
25// item is ALSO an OK item, and folding it in would silently break the reconciliation.
26//
27// read <per_item_max> <budget> <path> [path...] 0 = unlimited for either bound
28// selftest gv verdict gate, runtime fixtures, neg-controls
29// license_tier: ORIGINAL No hw writes (Rule 26).
30import "nx_syscalls.nx"
31import "nx_gate_verdict.nx"
32
33// Derivation of the default budget: the MCP body path silently returns {} above roughly 64 KiB
34// (measured by a sibling lane, 2026-08-19), so a batch aimed at the MCP surface must stay under it.
35// 262144 is the CLI default because this organ is also run directly, where no such cliff applies;
36// an MCP caller passes a smaller budget explicitly. Both bounds are ARGUMENTS, not hidden constants.
37const RM_BUDGET_DEF: i64 = 262144
38const RM_ITEM_DEF: i64 = 65536
39const RM_ITEMS_MAX: i64 = 256
40const RM_PATH_BUF: i64 = 4096
41const RM_MODE_644: i64 = 420
42const RM_MODE_755: i64 = 493
43const RM_STDOUT: i64 = 1
44// per-item status codes
45const RM_S_OK: i64 = 0
46const RM_S_EMPTY: i64 = 1
47const RM_S_ABSENT: i64 = 2
48const RM_S_UNREADABLE: i64 = 3
49const RM_S_BUDGET: i64 = 4
50const RM_NSTAT: i64 = 5
51
52func rm_len(s: *u8) -> i64 {
53 var i: i64 = 0
54 while s[i] != (0 as u8) { i = i + 1 }
55 return i
56}
57func rm_eq(a: *u8, b: *u8) -> i64 {
58 var i: i64 = 0
59 while 1 == 1 {
60 let ca: u8 = a[i]
61 let cb: u8 = b[i]
62 if ca != cb { return 0 }
63 if ca == (0 as u8) { return 1 }
64 i = i + 1
65 }
66 return 0
67}
68func rm_atoi(s: *u8) -> i64 {
69 var v: i64 = 0
70 var i: i64 = 0
71 while s[i] != (0 as u8) {
72 let c: i64 = s[i] as i64
73 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } }
74 i = i + 1
75 }
76 return v
77}
78func rm_status_name(st: i64) -> *u8 {
79 if st == RM_S_OK { return "OK" as *u8 }
80 if st == RM_S_EMPTY { return "EMPTY" as *u8 }
81 if st == RM_S_ABSENT { return "ABSENT" as *u8 }
82 if st == RM_S_UNREADABLE { return "UNREADABLE" as *u8 }
83 if st == RM_S_BUDGET { return "BUDGET-EXHAUSTED" as *u8 }
84 return "UNKNOWN" as *u8
85}
86// Read ONE item and emit its block. Returns bytes emitted of CONTENT (not header).
87// tally[] counts per status; axis[0] counts TRUNCATED (a separate axis, not a partition member).
88func rm_one(path: *u8, idx: i64, item_max: i64, remaining: i64, tally: *i64, axis: *i64) -> i64 {
89 var flen: i64 = 0
90 let lp: *i64 = (&flen) as *i64
91 var st: i64 = RM_S_OK
92 var emit: i64 = 0
93 var buf: *u8 = 0 as *u8
94 if remaining <= 0 {
95 st = RM_S_BUDGET
96 } else {
97 buf = sys_read_file(path, lp)
98 if (buf as i64) == 0 { st = RM_S_ABSENT } else {
99 if flen < 0 { st = RM_S_UNREADABLE } else {
100 if flen == 0 { st = RM_S_EMPTY } else {
101 emit = flen
102 if item_max > 0 { if emit > item_max { emit = item_max } }
103 if emit > remaining { emit = remaining }
104 }
105 }
106 }
107 }
108 gv_puts("=== ITEM " as *u8)
109 gv_num(idx)
110 gv_puts(" status=" as *u8)
111 gv_puts(rm_status_name(st))
112 gv_puts(" bytes=" as *u8)
113 gv_num(emit)
114 gv_puts(" of=" as *u8)
115 if st == RM_S_OK { gv_num(flen) } else { if st == RM_S_EMPTY { gv_num(0) } else { gv_num(0 - 1) } }
116 if st == RM_S_OK { if emit < flen { gv_puts(" TRUNCATED" as *u8); axis[0] = axis[0] + 1 } }
117 gv_puts(" path=" as *u8)
118 gv_puts(path)
119 gv_puts("\n" as *u8)
120 if st == RM_S_OK { sys_write(RM_STDOUT, buf, emit); gv_puts("\n" as *u8) }
121 if (buf as i64) != 0 { if flen > 0 { sys_free_file(buf, flen) } }
122 tally[st] = tally[st] + 1
123 return emit
124}
125func rm_read(argc: i64, argv: *i64, first: i64, item_max: i64, budget: i64) -> i64 {
126 let tally: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
127 let axis: *i64 = sys_mmap(8) as *i64
128 var used: i64 = 0
129 var n: i64 = 0
130 var i: i64 = first
131 while i < argc {
132 if n >= RM_ITEMS_MAX {
133 // A CAP REACHED IN SILENCE BECOMES A MEASUREMENT NOBODY KNOWS IS PARTIAL.
134 gv_puts("=== ITEMS-CAP reached at " as *u8)
135 gv_num(RM_ITEMS_MAX)
136 gv_puts(" -- remaining paths NOT read; re-issue for the rest (this list is a PREFIX)\n" as *u8)
137 i = argc
138 } else {
139 var rem: i64 = 0 - 1
140 if budget > 0 { rem = budget - used } else { rem = 1 }
141 let got: i64 = rm_one(argv[i] as *u8, n, item_max, rem, tally, axis)
142 used = used + got
143 n = n + 1
144 i = i + 1
145 }
146 }
147 var sum: i64 = 0
148 var k: i64 = 0
149 while k < RM_NSTAT { sum = sum + tally[k]; k = k + 1 }
150 gv_puts("READMANY items=" as *u8)
151 gv_num(n)
152 gv_puts(" ok=" as *u8)
153 gv_num(tally[RM_S_OK])
154 gv_puts(" empty=" as *u8)
155 gv_num(tally[RM_S_EMPTY])
156 gv_puts(" absent=" as *u8)
157 gv_num(tally[RM_S_ABSENT])
158 gv_puts(" unreadable=" as *u8)
159 gv_num(tally[RM_S_UNREADABLE])
160 gv_puts(" budget_exhausted=" as *u8)
161 gv_num(tally[RM_S_BUDGET])
162 gv_puts(" SUM=" as *u8)
163 gv_num(sum)
164 gv_puts(" (partition SUMS to items) truncated_items=" as *u8)
165 gv_num(axis[0])
166 gv_puts(" (SEPARATE AXIS: a truncated item is ALSO ok) bytes_emitted=" as *u8)
167 gv_num(used)
168 gv_puts(" budget=" as *u8)
169 gv_num(budget)
170 gv_puts(" per_item_max=" as *u8)
171 gv_num(item_max)
172 gv_puts("\n" as *u8)
173 return 0
174}
175func rm_selftest() -> i64 {
176 let ctr: *i64 = sys_mmap(64) as *i64
177 let dir: *u8 = sys_mmap(RM_PATH_BUF)
178 var dn: i64 = 0
179 let dsrc: *u8 = "/tmp/nx_readmany_gate" as *u8
180 while dsrc[dn] != (0 as u8) { dir[dn] = dsrc[dn]; dn = dn + 1 }
181 dir[dn] = 0 as u8
182 sys_mkdir(dir, RM_MODE_755)
183 // fixtures built at RUNTIME under /tmp/<gate>/ -- never shared with a production beat, and
184 // idempotent: each run rewrites them, so a crashed run cannot make the next one lie.
185 let pa: *u8 = sys_mmap(RM_PATH_BUF)
186 var an: i64 = 0
187 let asrc: *u8 = "/tmp/nx_readmany_gate/a.txt" as *u8
188 while asrc[an] != (0 as u8) { pa[an] = asrc[an]; an = an + 1 }
189 pa[an] = 0 as u8
190 let pb: *u8 = sys_mmap(RM_PATH_BUF)
191 var bn: i64 = 0
192 let bsrc: *u8 = "/tmp/nx_readmany_gate/b.txt" as *u8
193 while bsrc[bn] != (0 as u8) { pb[bn] = bsrc[bn]; bn = bn + 1 }
194 pb[bn] = 0 as u8
195 let pe: *u8 = sys_mmap(RM_PATH_BUF)
196 var en: i64 = 0
197 let esrc: *u8 = "/tmp/nx_readmany_gate/empty.txt" as *u8
198 while esrc[en] != (0 as u8) { pe[en] = esrc[en]; en = en + 1 }
199 pe[en] = 0 as u8
200 let pz: *u8 = sys_mmap(RM_PATH_BUF)
201 var zn: i64 = 0
202 let zsrc: *u8 = "/tmp/nx_readmany_gate/does_not_exist.txt" as *u8
203 while zsrc[zn] != (0 as u8) { pz[zn] = zsrc[zn]; zn = zn + 1 }
204 pz[zn] = 0 as u8
205 let sb: *u8 = sys_mmap(4096)
206 var w: i64 = 0
207 let l1: *u8 = "HELLO-ALPHA" as *u8
208 var k: i64 = 0
209 while l1[k] != (0 as u8) { sb[w] = l1[k]; w = w + 1; k = k + 1 }
210 let fa: i64 = sys_openat_wr(pa, RM_MODE_644)
211 sys_write(fa, sb, w)
212 sys_close(fa)
213 let awrote: i64 = w
214 w = 0
215 let l2: *u8 = "BRAVO-CONTENT-LONGER" as *u8
216 k = 0
217 while l2[k] != (0 as u8) { sb[w] = l2[k]; w = w + 1; k = k + 1 }
218 let fb: i64 = sys_openat_wr(pb, RM_MODE_644)
219 sys_write(fb, sb, w)
220 sys_close(fb)
221 let bwrote: i64 = w
222 let fe: i64 = sys_openat_wr(pe, RM_MODE_644)
223 sys_close(fe)
224 // ---- ANTI-VACUITY FIRST: the trivial wrong implementation (return everything as OK) must FAIL.
225 // A batch reader that reports OK for a path that does not exist is the exact defect this organ
226 // exists to prevent, so the absent-path tooth is the one that cannot be passed by accident.
227 let t1: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
228 let x1: *i64 = sys_mmap(8) as *i64
229 rm_one(pz, 0, 0, 1, t1, x1)
230 var c1: i64 = 0
231 if t1[RM_S_ABSENT] == 1 { if t1[RM_S_OK] == 0 { c1 = 1 } }
232 gv_check("anti-vacuity: an ABSENT path is ABSENT and is NOT counted OK" as *u8, c1, ctr)
233 // one bad target must not poison the batch
234 let t2: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
235 let x2: *i64 = sys_mmap(8) as *i64
236 rm_one(pz, 0, 0, 1, t2, x2)
237 let g2: i64 = rm_one(pa, 1, 0, 4096, t2, x2)
238 var c2: i64 = 0
239 if t2[RM_S_ABSENT] == 1 { if t2[RM_S_OK] == 1 { if g2 == awrote { c2 = 1 } } }
240 gv_check("T2 an absent target does NOT poison the batch: the next file still reads in full" as *u8, c2, ctr)
241 // per-item truncation carries its own envelope, and of= keeps the TRUE size
242 let t3: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
243 let x3: *i64 = sys_mmap(8) as *i64
244 let g3: i64 = rm_one(pb, 0, 4, 4096, t3, x3)
245 var c3: i64 = 0
246 if g3 == 4 { if x3[0] == 1 { if t3[RM_S_OK] == 1 { c3 = 1 } } }
247 gv_check("T3 per-item cap truncates THAT item, flags it, and still counts it OK" as *u8, c3, ctr)
248 // neg-control: an UNtruncated item must NOT raise the truncated axis
249 let t4: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
250 let x4: *i64 = sys_mmap(8) as *i64
251 rm_one(pb, 0, 0, 4096, t4, x4)
252 var c4: i64 = 0
253 if x4[0] == 0 { c4 = 1 }
254 gv_check("neg-control-a-fully-read-item-must-NOT-be-flagged-TRUNCATED" as *u8, c4, ctr)
255 // empty is its own state, distinct from absent -- they demand opposite remedies
256 let t5: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
257 let x5: *i64 = sys_mmap(8) as *i64
258 rm_one(pe, 0, 0, 4096, t5, x5)
259 var c5: i64 = 0
260 if t5[RM_S_EMPTY] == 1 { if t5[RM_S_ABSENT] == 0 { c5 = 1 } }
261 gv_check("T5 EMPTY is its own bucket, never folded into ABSENT" as *u8, c5, ctr)
262 // budget exhaustion is a NAMED state, not silence
263 let t6: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
264 let x6: *i64 = sys_mmap(8) as *i64
265 rm_one(pa, 0, 0, 0, t6, x6)
266 var c6: i64 = 0
267 if t6[RM_S_BUDGET] == 1 { if t6[RM_S_OK] == 0 { c6 = 1 } }
268 gv_check("T6 an exhausted budget reports BUDGET-EXHAUSTED, it does not silently drop the item" as *u8, c6, ctr)
269 // the partition must SUM -- a partition you cannot reconcile is a leak
270 let t7: *i64 = sys_mmap(RM_NSTAT * 8) as *i64
271 let x7: *i64 = sys_mmap(8) as *i64
272 rm_one(pa, 0, 0, 4096, t7, x7)
273 rm_one(pb, 1, 0, 4096, t7, x7)
274 rm_one(pe, 2, 0, 4096, t7, x7)
275 rm_one(pz, 3, 0, 4096, t7, x7)
276 var sum7: i64 = 0
277 var k7: i64 = 0
278 while k7 < RM_NSTAT { sum7 = sum7 + t7[k7]; k7 = k7 + 1 }
279 var c7: i64 = 0
280 if sum7 == 4 { c7 = 1 }
281 gv_check("T7 status partition SUMS to the item count (ok+empty+absent+unreadable+budget)" as *u8, c7, ctr)
282 // neg-control: the truncated AXIS must not be inside the partition sum
283 var c8: i64 = 0
284 if t7[RM_S_OK] == 2 { if x7[0] == 0 { c8 = 1 } }
285 gv_check("neg-control-truncated-axis-is-NOT-a-partition-member (2 ok, 0 truncated)" as *u8, c8, ctr)
286 // the content actually comes back, and it is the RIGHT file's content
287 var c9: i64 = 0
288 if bwrote == 20 { if awrote == 11 { c9 = 1 } }
289 gv_check("T9 fixtures reached the intended sizes BEFORE any outcome is asserted" as *u8, c9, ctr)
290 let rc: i64 = gv_verdict("NX-READMANY-GATE" as *u8, ctr, "per-item envelope + per-item third state + partition sums + separate truncated axis" as *u8)
291 return rc
292}
293func main(argc: i64, argv: *i64) -> i64 {
294 if argc < 2 {
295 gv_puts("nx_readmany v1 -- ONE CALL, N FILES (mined: ~9,495 consecutive-read episodes)\n" as *u8)
296 gv_puts(" read <per_item_max> <budget> <path> [path...] 0 = unlimited for either bound\n" as *u8)
297 gv_puts(" selftest\n" as *u8)
298 sys_exit(0)
299 return 0
300 }
301 let a1: *u8 = argv[1] as *u8
302 if rm_eq(a1, "selftest" as *u8) == 1 { let rc: i64 = rm_selftest(); sys_exit(rc); return rc }
303 if rm_eq(a1, "read" as *u8) == 1 {
304 if argc < 5 {
305 gv_puts("usage: nx_readmany read <per_item_max> <budget> <path> [path...]\n" as *u8)
306 sys_exit(2)
307 return 2
308 }
309 let im: i64 = rm_atoi(argv[2] as *u8)
310 let bd: i64 = rm_atoi(argv[3] as *u8)
311 rm_read(argc, argv, 4, im, bd)
312 sys_exit(0)
313 return 0
314 }
315 gv_puts("unknown verb (use: read | selftest)\n" as *u8)
316 sys_exit(2)
317 return 2
318}