code wiki / _hdl_build / nx_pkg.nx
nx_pkg.nx
buildroot/runtime/_hdl_build/nx_pkg.nx
about
nx_pkg.nx -- THE SOVEREIGN CONTENT-ADDRESSED PACKAGE LANE (LR3 of /compare/lang), carrying the original
dependency-resolution self-test it grew from (verb `selftest`, still the NO-ARG DEFAULT so no existing
caller loses behaviour).
WHY THIS EXISTS. The 2025 registry worms self-replicated across 500+ npm packages by exploiting exactly
two assumptions: install-time code execution, and blind trust that a NAME resolves to whatever `latest`
happens to be. Go answered with a module proxy, a signed transparency log (sumdb), and no install
scripts. This lane does not GUARD that attack surface, it REMOVES it: THE IDENTITY OF A MODULE IS THE
HASH OF ITS BYTES. There is no version negotiation, so there is no `latest` to poison. The resolve
primitive takes a digest, not a name, so there is nothing to squat. And resolution never interprets,
forks or executes one byte of module content -- it reads, verifies, and writes.
THE ONE LAW: THE STORE PATH IS A HINT, THE HASH IS THE IDENTITY.
A blob at <store>/<digest> is RE-HASHED on every resolve and REFUSED if it does not hash to the digest
that was asked for. An attacker who can write the store cannot make it serve different bytes; the most
they achieve is a named, loud refusal.
EXTENDS THE ESTATE'S EXISTING CONTENT-ADDRESSING, DOES NOT ADD A SECOND ONE:
sha256_digest (nx_sha256.nx) -- the same digest nx_filehash / nx_closurehash / nx_content_put use
sys_read_file (nx_syscalls.nx) -- sizes its buffer from the file, so a module CANNOT short-read
lcf_* (nx_lineconf_lib.nx) -- line-anchored conf, LCF_MISS -> REFUSE, never a silent default
There is no new hash, no new store format, no second ruler.
VERBS (every path and policy value comes from a conf file; an absent key REFUSES, it never defaults):
nx_pkg cas_put <file> [conf] -> address a file by content; prints its digest
nx_pkg cas_resolve <digest64> <dest> [conf] -> THE CONTRACT PRIMITIVE (pkg_cas_resolve)
nx_pkg pin <name> <digest64> [conf] -> bind a logical name to a digest (THE TRUST BOUNDARY)
nx_pkg resolve <name> <dest> [conf] -> exact-match pinned name -> digest -> cas_resolve
nx_pkg logverify [conf] -> walk the hash-chained transparency journal
nx_pkg selftest -> the original dep-resolution teeth (T1..T4)
An UNRECOGNISED verb prints usage and exits 3. It never falls through to a permissive default -- the
route-mode defect (an unknown token silently selecting the permissive branch) is live in this estate
today and this is the one place it must not be repeated.
WHAT THE TRANSPARENCY JOURNAL PROVES, STATED HONESTLY. Every put/resolve appends
<seq>|<op>|<digest>|<bytes>|<prev_chain>|<chain> with chain = sha256(prev|digest|bytes)
so a retroactive edit to any past row breaks every chain link after it, and an append REFUSES on a
broken chain rather than extending it. That is TAMPER-EVIDENCE against an editor who does not rewrite
the whole file. It is NOT Go's sumdb: there is one writer, no signature, no gossiped tree head and no
inclusion proofs, so an attacker holding write access to the entire journal can recompute it from
dependencies 5 imports · 0 importers
imports: nx_syscalls.nxnx_itoa_lib.nxnx_g_puts_lib.nxnx_sha256.nxnx_lineconf_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 435 | struct PkConf { store: *u8, lock: *u8, log: *u8, ok: i64 } |
consts
| 66 | const PK_DIGEST_BYTES: i64 = 32 // SHA-256 output width, fixed by the algorithm |
| 67 | const PK_SHAHEX: i64 = 64 // = PK_DIGEST_BYTES * 2, asserted at runtime below |
| 68 | const PK_I64_DIGITS: i64 = 20 // widest decimal i64 incl sign, fixed by the type |
| 69 | const PK_BAR: i64 = 124 // '|' field separator |
| 70 | const PK_NL: i64 = 10 |
| 71 | const PK_SLASH: i64 = 47 |
| 72 | const PK_DOT: i64 = 46 |
| 73 | const PK_ASCII_0: i64 = 48 |
| 74 | const PK_ASCII_9: i64 = 57 |
| 75 | const PK_ASCII_a: i64 = 97 |
| 76 | const PK_ASCII_f: i64 = 102 |
| 77 | const PK_FD_OUT: i64 = 1 |
| 78 | const PK_FD_ERR: i64 = 2 |
| 79 | const PK_NFIELDS: i64 = 6 |
| 80 | const PK_F_SEQ: i64 = 0 |
| 81 | const PK_F_OP: i64 = 1 |
| 82 | const PK_F_DIG: i64 = 2 |
| 83 | const PK_F_BYTES: i64 = 3 |
| 84 | const PK_F_PREV: i64 = 4 |
| 85 | const PK_F_CHAIN: i64 = 5 |
| 86 | const PK_CONF_DEFAULT: *u8 = "knowledge/pkg_cas.conf" as *u8 |
| 90 | const PK_OK: i64 = 0 |
| 91 | const PK_R_MALFORMED: i64 = 1 |
| 92 | const PK_R_ABSENT: i64 = 2 |
| 93 | const PK_R_MISMATCH: i64 = 3 |
| 94 | const PK_R_DEST: i64 = 4 |
| 95 | const PK_R_IO: i64 = 5 |
| 96 | const PK_R_CHAIN: i64 = 6 |
| 97 | const PK_R_NOTPINNED: i64 = 7 |
| 98 | const PK_R_PINCONFLICT: i64 = 8 |
| 99 | const PK_R_PINAMBIG: i64 = 9 |
| 100 | const PK_R_CONF: i64 = 10 |
| 102 | const PK_EXIT_USAGE: i64 = 3 |
| 103 | const PK_EXIT_CONF: i64 = 4 |
| 104 | const PK_EXIT_MALFORMED: i64 = 5 |
| 105 | const PK_EXIT_ABSENT: i64 = 6 |
| 106 | const PK_EXIT_MISMATCH: i64 = 7 |
| 107 | const PK_EXIT_DEST: i64 = 8 |
| 108 | const PK_EXIT_NOTPINNED: i64 = 9 |
| 109 | const PK_EXIT_PINCONFLICT: i64 = 10 |
| 110 | const PK_EXIT_CHAIN: i64 = 11 |
| 111 | const PK_EXIT_IO: i64 = 12 |
| 112 | const PK_EXIT_PINAMBIG: i64 = 13 |
| 461 | const MAXD: i64 = 4 |
functions
| 114 | func pk_rule(code: i64) -> *u8 |
| 127 | func pk_exit_for(code: i64) -> i64 |
| 143 | func pk_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 144 | func pk_eputs(s: *u8) -> i64 { sys_write(PK_FD_ERR, s, pk_slen(s)); return 0 } |
| 145 | func pk_num(v: i64) -> i64 { nxi_out(v); return 0 } |
| 146 | func pk_cat(d: *u8, o: i64, s: *u8) -> i64 { var p: i64 = o; var i: i64 = 0; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } d[p] = 0 as u8; return p } |
| 147 | func pk_streq(a: *u8, b: *u8) -> i64 |
| 153 | func pk_starts(p: *u8, pre: *u8) -> i64 { var i: i64 = 0; while pre[i] != (0 as u8) { if p[i] != pre[i] { return 0 } i = i + 1 } return 1 } called by 1: pk_dest_ok |
| 154 | func pk_dotdot(p: *u8) -> i64 { var i: i64 = 0; while p[i] != (0 as u8) { if (p[i] as i64) == PK_DOT { if (p[i+1] as i64) == PK_DOT { return 1 } } i = i + 1 } return 0 } called by 1: pk_dest_ok |
| 155 | func pk_atoi(s: *u8) -> i64 called by 1: pk_log_verify |
| 170 | func pk_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } |
| 173 | func pk_mkdir(path: *u8) -> i64 |
| 180 | func pk_hex_into(dig: *u8, out: *u8) -> i64 called by 1: pk_sha_hex |
| 192 | func pk_sha_hex(buf: *u8, n: i64, outhex: *u8) -> i64 called by 4: pk_chain_steppkg_cas_resolvepk_selftestmain calls 4: sys_mmapsha256_digestpk_hex_intosys_munmap |
| 201 | func pk_is_hex64(s: *u8) -> i64 |
| 215 | func pk_dest_ok(p: *u8) -> i64 |
| 224 | func pk_blob_path(store: *u8, dighex: *u8) -> *u8 |
| 232 | func pk_write_atomic(finalpath: *u8, buf: *u8, n: i64) -> i64 |
| 253 | func pk_genesis(out: *u8) -> i64 { var i: i64 = 0; while i < PK_SHAHEX { out[i] = PK_ASCII_0 as u8; i = i + 1 } out[PK_SHAHEX] = 0 as u8; return PK_SHAHEX } called by 1: pk_log_verify |
| 255 | func pk_chain_step(prevhex: *u8, dighex: *u8, nbytes: i64, outhex: *u8) -> i64 |
| 268 | func pk_field(buf: *u8, st: i64, ln: i64, idx: i64, out: *u8, cap: i64) -> i64 called by 1: pk_log_verify |
| 288 | func pk_log_verify(logpath: *u8, entries: *i64, head: *u8) -> i64 |
| 339 | func pk_log_append(logpath: *u8, op: *u8, dighex: *u8, nbytes: i64) -> i64 |
| 381 | func pkg_cas_resolve(store: *u8, dighex: *u8, dest: *u8, outbytes: *i64) -> i64 |
| 405 | func pk_lock_lookup(buf: *u8, n: i64, name: *u8, outdig: *u8) -> i64 |
| 436 | func pk_conf_load(confpath: *u8) -> *PkConf |
| 456 | func g_pn(v: i64) -> i64 { nxi_out(v); return 0 } |
| 457 | func ck(name: *u8, c: i64) -> i64 { if c==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) } g_puts(name); g_puts("\n" as *u8); return c } |
| 458 | func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } |
| 459 | func psum(s: *u8) -> i64 { var acc: i64=0; var i: i64=0; while s[i]!=(0 as u8){ acc=acc+(s[i] as i64); i=i+1 } return acc } |
| 463 | func pkg_needed(target: i64, ndep: *i64, dep: *i64, N: i64, needed: *i64) -> i64 called by 1: pk_selftest |
| 469 | func pkg_topo(ndep: *i64, dep: *i64, N: i64, order: *i64) -> i64 |
| 480 | func pkg_verify(content: *u8, expected: i64) -> i64 { if psum(content)==expected { return 1 } return 0 } |
| 482 | func pk_selftest() -> i64 |
| 536 | func pk_usage() -> i64 |
| 553 | func pk_refuse(prefix: *u8, code: i64) -> i64 |
| 558 | func main(argc: i64, argv: *i64) -> i64 |