code wiki / _hdl_build / nx_mgmt_upload_gate.nx
nx_mgmt_upload_gate.nx
buildroot/runtime/_hdl_build/nx_mgmt_upload_gate.nx
about
nx_mgmt_upload_gate.nx -- SOVEREIGN in-process referee for the /api/upload keystone (chunked artifact publish).
NO socket, NO curl, NO shell: it chdir's to /tmp (so every staging file lands there, NOT in the real build/NAS
dir), then feeds crafted HTTP request BYTES straight into the PURE handler ma_do_upload and asserts BOTH the
response bytes AND the on-disk result. Proves the reassembly + monotonic-seq gate + allowlist + sha256 + the
atomic .upload->.new stage, all fail-closed. Because ma_do_upload composes the shipped mu_stage_chunk write
primitive, this end-to-end gate also transitively covers it (retiring the old isolated primitive-only gate).
The target names are the REAL allowlisted basenames (exercising md_upload_target_ok for real), rooted in /tmp
so nothing live is ever touched.
T1 multi-chunk happy path: seq0(final=0)+seq1(final=1) -> <t>.new == chunkA ++ chunkB, BYTE-EXACT
T2 NEG unknown target -> 400, nothing written
T3 NEG seq gap (seq0 then seq2) -> 400, .new NOT produced
T4 NEG final without a prior seq0 (fresh target) -> 400 (bad seq), .new NOT produced
T5 sha256 mismatch on final -> 400 + staging (.upload) DELETED, .new NOT produced
T6 sha256 MATCH on final -> 200 + .new produced BYTE-EXACT (positive control for the hash path)
T7 VIDEO content namespace (2026-07-11): sites/nishifamily/video/*.js uploads + stages; html/wasm/ver.txt validate
T8 video namespace fail-closed: .elf ext, ".." traversal, dot-file, prefix-miss ALL refused (validator + handler)
GREEN iff T1..T8 hold. Sovereign: nx_mgmt_api (-> ma_do_upload -> mu_stage_chunk) + nx_sha256 + nx_fio + nx_syscalls.
license_tier: ORIGINAL expect_exit: 0
dependencies 4 imports · 0 importers
imports: nx_mgmt_api.nxnx_sha256.nxnx_fio.nxnx_syscalls.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
| none |
functions
| 24 | func u_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 25 | func u_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 26 | func u_row(name: *u8, ok: i64) -> i64 |
| 31 | func u_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o + i] = s[i]; i = i + 1 } return o + i } |
| 32 | func u_catn(d: *u8, o: i64, v: i64) -> i64 |
| 40 | func u_starts(buf: *u8, n: i64, s: *u8) -> i64 |
| 47 | func u_contains(hay: *u8, n: i64, needle: *u8) -> i64 |
| 62 | func u_build(req: *u8, qs: *u8, chunk: *u8, clen: i64) -> i64 |
| 75 | func u_read_file(path: *u8, out: *u8, cap: i64) -> i64 |
| 91 | func u_bytes_eq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 called by 1: main |
| 99 | func u_sha256_hex(bytes: *u8, n: i64, out: *u8) -> i64 |
| 114 | func main() -> i64 |