code wiki / _hdl_build / nx_readmany.nx
nx_readmany.nx
buildroot/runtime/_hdl_build/nx_readmany.nx
about
nx_readmany.nx -- ONE CALL, N FILES (Lane I common-task hardening, 2026-08-20).
MINED, NOT GUESSED. nx_wfcost measured the full 309-transcript / 2,006,669,677 B action record and
the read cluster is the largest BUILD candidate in it: nx_fs:read >> nx_fs:read 5,675 episodes,
nx_shelltool:grep >> nx_fs:read 1,683, nx_fs:lines >> nx_fs:lines 1,233, nx_fs:lines >> nx_fs_write:edit
904 -- ~9,495 consecutive-read episodes, each one a seat turn spent re-issuing the same verb.
(The larger mgmt:POST cluster is deliberately NOT addressed here: nx_organ_ship already collapses it,
so that one is an ADOPTION gap, not a build gap -- building a second would be the duplicate ruler.)
WHY A BATCH READ AND NOT A BIGGER CAP: the measured unit is the SEAT TURN (1 turn ~= 133,658
input-token-equivalents, measured, not estimated). N reads cost N turns regardless of how many bytes
each returns, so the win comes from collapsing TURNS, never from raising a limit.
TWO LAWS THIS ORGAN EXISTS TO NOT BREAK:
1. THE ENVELOPE IS PER ITEM, NEVER GLOBAL. A single global "truncated=1" cannot say WHICH file was
cut, so the caller re-reads all of them and the batch saves nothing. Every item carries its own
status + bytes= + of= (its TRUE full size, always known because the read is sized from the file).
This lane already found `nx_actlog harden` computing a truncation envelope and then dropping it
at the next hop -- an envelope dropped at the next hop is an envelope that was never published.
2. ONE BAD TARGET MUST NOT POISON THE BATCH. Every item gets its own third state
(OK | EMPTY | ABSENT | UNREADABLE | BUDGET-EXHAUSTED), so an absent path costs exactly one row
and the other N-1 files still come back. A batch that fails whole is worse than N single reads.
PARTITION: ok + empty + absent + unreadable + budget_exhausted == items, and the footer PRINTS the
sum so it can be reconciled. TRUNCATED is a SEPARATE AXIS, never a partition member -- a truncated
item is ALSO an OK item, and folding it in would silently break the reconciliation.
read <per_item_max> <budget> <path> [path...] 0 = unlimited for either bound
selftest gv verdict gate, runtime fixtures, neg-controls
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_gate_verdict.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 37 | const RM_BUDGET_DEF: i64 = 262144 |
| 38 | const RM_ITEM_DEF: i64 = 65536 |
| 39 | const RM_ITEMS_MAX: i64 = 256 |
| 40 | const RM_PATH_BUF: i64 = 4096 |
| 41 | const RM_MODE_644: i64 = 420 |
| 42 | const RM_MODE_755: i64 = 493 |
| 43 | const RM_STDOUT: i64 = 1 |
| 45 | const RM_S_OK: i64 = 0 |
| 46 | const RM_S_EMPTY: i64 = 1 |
| 47 | const RM_S_ABSENT: i64 = 2 |
| 48 | const RM_S_UNREADABLE: i64 = 3 |
| 49 | const RM_S_BUDGET: i64 = 4 |
| 50 | const RM_NSTAT: i64 = 5 |
functions
| 52 | func rm_len(s: *u8) -> i64 |
| 57 | func rm_eq(a: *u8, b: *u8) -> i64 called by 1: main |
| 68 | func rm_atoi(s: *u8) -> i64 called by 1: main |
| 78 | func rm_status_name(st: i64) -> *u8 called by 1: rm_one |
| 88 | func rm_one(path: *u8, idx: i64, item_max: i64, remaining: i64, tally: *i64, axis: *i64) -> i64 called by 2: rm_readrm_selftest calls 6: sys_read_filegv_putsgv_numrm_status_namesys_writesys_free_file |
| 125 | func rm_read(argc: i64, argv: *i64, first: i64, item_max: i64, budget: i64) -> i64 |
| 175 | func rm_selftest() -> i64 |
| 293 | func main(argc: i64, argv: *i64) -> i64 |