nx_content_get.nx
buildroot/runtime/nx_content_get.nx
about
nx_content_get.nx -- CHUNKED CONTENT DOWNLOAD SOURCE: the sovereign door for NAS->laptop bytes.
WHY THIS EXISTS (operator standing order 2026-09-03: "dont build python ... build nishi and nishi estate
should have this capability and if it doesnt lets build from the first byte up these capabilities").
nx_content_put calls itself "the sovereign door for laptop->NAS bytes" and there was NO MIRROR. Measured
the same day: a NAS-side source that had legitimately diverged from its laptop twin could not be brought
back without a seat retyping 38,414 bytes through a chat transcript -- which is the hand-transcription
defect this estate builds organs to avoid. The absence was named as a gap before it was built; this is it.
nx_content_get begin <src> -> CG-BEGIN src= total_bytes= sha256= chunk_raw= nchunks=
nx_content_get chunk <src> <index> -> CG-CHUNK OK ... chunk_sha256= b64=<data>
nx_content_get probe -> the derived chunk size and every term of its derivation
IT IS A MIRROR, NOT A COPY, AND THE ASYMMETRIES ARE THE DESIGN:
1. STATELESS BY CONSTRUCTION. nx_content_put needs staging, an index and a stale-reaper because the
bytes ACCUMULATE ON THE RECEIVER. In a get they accumulate on the CLIENT, so there is no server-side
transfer state to stage, index, resume or reap. Half of the incumbent machinery is therefore
deliberately ABSENT rather than mirrored -- carrying it would be complexity with no invariant to
protect, and a reaper with nothing to reap is a beat that can only ever be wrong.
2. THE GENERATION CHECK REPLACES CAS. The incumbent refuses a DIFFERENT body for an index that already
landed, so a blind retry can never corrupt. A get has the opposite exposure: the SOURCE can change
under a multi-call read, and reassembling chunks from two generations yields a franken-file that is
byte-valid and semantically nonsense. So begin declares the WHOLE-FILE sha256 and the client MUST
verify its reassembly against it. A file edited mid-transfer fails that check loudly.
Per-chunk sha is carried too, and here is exactly what each can and cannot do: the per-chunk digest
detects a CORRUPTED chunk, and it CANNOT detect a consistent read of a CHANGED file. Only the
whole-file digest can, which is why begin pays one full read to compute it.
A SIZE COMPARISON WOULD NOT DO: a same-size rewrite passes it, and "size is never an identity" is a
law this estate has been bitten by three separate times.
3. THE CHUNK SIZE IS DERIVED FROM THE *RESPONSE* CAP, NOT THE REQUEST CAP. This is the term a symmetric
copy would get wrong. The incumbent sizes its chunk against the 65,536-byte request-body cap it
measured at the edge; a get rides the RESPONSE path, whose observed capture cap is 163,840 -- the
bound nx_fs prints as capture_cap when it truncates. Reserve = the receipt skeleton MEASURED FROM THE
LITERAL AT RUNTIME, never hand-counted, plus a full path, plus the digits and hex digest it carries.
The raw size is floored to a multiple of 3 so base64 never emits interior padding.
MEASURED 2026-09-03: reserve=1249 (66+1024+95+64), chunk_raw=121941, exactly divisible by 3.
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_base64.nxnx_sha256.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
| 62 | const CG_RESP_CAP: i64 = 163840 |
| 63 | const CG_DIGEST: i64 = 32 |
| 64 | const CG_SHAHEX: i64 = 64 |
| 65 | const CG_PATHCAP: i64 = 1024 |
| 66 | const CG_I64_DIGITS: i64 = 19 |
| 67 | const CG_RECEIPT_FIELDS: i64 = 5 |
| 68 | const CG_SEEK_SET: i64 = 0 |
| 69 | const CG_SEEK_END: i64 = 2 |
| 70 | const CG_READBUF: i64 = 65536 |
| 72 | const CG_SKEL: *u8 = "CG-CHUNK OK src= index= off= raw= total_bytes= chunk_sha256= b64=\n" as *u8 |
functions
| 74 | func cg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 75 | func cg_out(s: *u8) -> i64 { sys_write(1, s, cg_slen(s)); return 0 } |
| 76 | func cg_eo(s: *u8) -> i64 { sys_write(2, s, cg_slen(s)); return 0 } |
| 77 | func cg_num(v: i64) -> i64 |
| 86 | func cg_hex_into(d: *u8, out: *u8) -> i64 |
| 99 | func cg_sha_hex_of(buf: *u8, n: i64, outhex: *u8) -> i64 |
| 105 | func cg_starts(p: *u8, pre: *u8) -> i64 called by 1: cg_src_ok |
| 113 | func cg_has(p: *u8, needle: *u8) -> i64 |
| 131 | func cg_src_ok(p: *u8) -> i64 |
| 147 | func cg_reserve() -> i64 |
| 150 | func cg_chunk_raw() -> i64 |
| 158 | func cg_fsize(path: *u8) -> i64 |
| 167 | func cg_file_sha(path: *u8, outhex: *u8) -> i64 |
| 189 | func cg_do_begin(src: *u8) -> i64 |
| 207 | func cg_do_chunk(src: *u8, index: i64) -> i64 |
| 247 | func cg_do_probe() -> i64 |
| 259 | func cg_atoi(s: *u8) -> i64 called by 1: main |
| 272 | func cg_streq(a: *u8, b: *u8) -> i64 called by 1: main |
| 279 | func main(argc: i64, argv: *i64) -> i64 |