nx_mod_manifest_lib.nx
buildroot/runtime/nx_mod_manifest_lib.nx
about
nx_mod_manifest_lib.nx -- THE SOVEREIGN MOD PACKAGE MANIFEST (/compare/modding MD18 mod_manifest_emit, 2026-09-06).
One manifest carries the package name, version, game targets, dependencies, the licence ROW read from the ONE rights table
(nx_licgate_lib: id, redistribution right after the unverified cap, verified flag), one content row per member (relative
path, bytes, sha256), the provenance verdict per member from the ONE asset journal (nx_asset_prov_lib, MD9) and an AUDIT
HEAD: the nx_sign_envelope_lib hash chain h0 = genesis, h = sha256(h || canonical(record)) over the header record and
every content record, canonicalised by nx_canon_cid so field order cannot change the bytes. Any edit to a member's bytes,
to a content row, or to the header changes the head, and the verifier REFUSES BY NAME (missing, tampered, head). There is
exactly ONE chain function, mm_chain, and both the emitter and the verifier call it, so they cannot disagree by drift.
The manifest is the estate's own line format (record|field|field), deterministic (no timestamps), so two emits of the
same package are byte-identical. Transport is the content-put door's job; this lib only writes and reads the bytes.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 3 imports · 3 importers
imports: nx_syscalls.nxnx_sign_envelope_lib.nxnx_asset_prov_lib.nx
imported by: nx_mod_manifest.nxnx_mod_manifest_gate.nxnx_pushback_lib.nx
structs
| none |
consts
| 16 | const MM_MAGIC: *u8 = "nxmod" |
| 17 | const MM_FORMAT_VERSION: i64 = 1 |
| 18 | const MM_SEP: i64 = 124 // '|' |
| 19 | const MM_NL: i64 = 10 |
| 20 | const MM_TAB: i64 = 9 |
| 21 | const MM_COMMA: i64 = 44 |
| 22 | const MM_AT: i64 = 64 |
| 23 | const MM_SLASH: i64 = 47 |
| 24 | const MM_DOT: i64 = 46 |
| 25 | const MM_FILE_MODE: i64 = 420 |
| 26 | const MM_PATH_CAP: i64 = 1024 |
| 27 | const MM_FIELD_CAP: i64 = 4096 |
| 28 | const MM_SHA_HEX: i64 = 64 |
| 29 | const MM_DIGEST: i64 = 32 |
| 30 | const MM_REC_CAP: i64 = 8192 |
| 31 | const MM_MAX_FIELDS: i64 = 8 |
| 33 | const MM_OK: i64 = 0 |
| 34 | const MM_ERR_LICENCE_UNKNOWN: i64 = 0 - 1 |
| 35 | const MM_ERR_TABLE_UNREADABLE: i64 = 0 - 2 |
| 36 | const MM_ERR_BAD_PATH: i64 = 0 - 3 |
| 37 | const MM_ERR_UNREADABLE_FILE: i64 = 0 - 4 |
| 38 | const MM_ERR_BAD_FIELD: i64 = 0 - 5 |
| 39 | const MM_ERR_NOT_MANIFEST: i64 = 0 - 6 |
| 40 | const MM_ERR_MALFORMED: i64 = 0 - 7 |
| 41 | const MM_ERR_NO_FILES: i64 = 0 - 8 |
| 42 | const MM_ERR_OUT_UNWRITABLE: i64 = 0 - 9 |
| 43 | const MM_ERR_CAPACITY: i64 = 0 - 10 |
| 45 | const MM_V_ACCEPT: i64 = 0 |
| 46 | const MM_V_MISSING: i64 = 1 |
| 47 | const MM_V_TAMPERED: i64 = 2 |
| 48 | const MM_V_HEAD: i64 = 3 |
| 50 | const MM_S_OK: i64 = 0 |
| 51 | const MM_S_TAMPERED: i64 = 1 |
| 52 | const MM_S_MISSING: i64 = 2 |
| 54 | const MM_M_BUF: i64 = 0 |
| 55 | const MM_M_N: i64 = 1 |
| 56 | const MM_M_NAME: i64 = 2 // NUL-terminated copies in scratch |
| 57 | const MM_M_VERSION: i64 = 3 |
| 58 | const MM_M_GAMES: i64 = 4 // csv joined |
| 59 | const MM_M_DEPS: i64 = 5 // csv joined name@version |
| 60 | const MM_M_LIC: i64 = 6 |
| 61 | const MM_M_LIC_REDIST: i64 = 7 |
| 62 | const MM_M_LIC_VERIFIED: i64 = 8 |
| 63 | const MM_M_NCONTENT: i64 = 9 |
| 64 | const MM_M_PATHS: i64 = 10 // *i64 -> *u8 strings |
| 65 | const MM_M_BYTES: i64 = 11 // *i64 |
| 66 | const MM_M_SHAS: i64 = 12 // *i64 -> *u8 65-byte strings |
| 67 | const MM_M_HEAD: i64 = 13 // *u8 65 |
| 68 | const MM_M_AUDIT_ROWS: i64 = 14 |
| 69 | const MM_M_NGAMES: i64 = 15 |
| 70 | const MM_M_NDEPS: i64 = 16 |
| 71 | const MM_M_NPROV: i64 = 17 |
| 72 | const MM_M_ERR: i64 = 18 |
| 73 | const MM_M_FORMAT: i64 = 19 |
| 74 | const MM_M_N_SLOTS: i64 = 24 |
| 76 | const MM_R_VERDICT: i64 = 0 |
| 77 | const MM_R_OK: i64 = 1 |
| 78 | const MM_R_TAMPERED: i64 = 2 |
| 79 | const MM_R_MISSING: i64 = 3 |
| 80 | const MM_R_HEAD_DECLARED: i64 = 4 // *u8 65 |
| 81 | const MM_R_HEAD_RECOMPUTED: i64 = 5 // *u8 65 -- from the DECLARED rows |
| 82 | const MM_R_HEAD_OF_FILES: i64 = 6 // *u8 65 -- from the files as they ARE |
| 83 | const MM_R_STATES: i64 = 7 // *i64 per member |
| 84 | const MM_R_N: i64 = 8 |
functions
| 86 | func mm_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 87 | func mm_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 } |
| 88 | func mm_catn(d: *u8, o: i64, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { d[o + i] = s[i]; i = i + 1 } return o + n } |
| 89 | func mm_putd(d: *u8, o: i64, v: i64) -> i64 { return lg_putd(d, o, v) } |
| 90 | func mm_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 } |
| 91 | func mm_dup(s: *u8, n: i64) -> *u8 { let d: *u8 = sys_mmap(n + 1); var i: i64 = 0; while i < n { d[i] = s[i]; i = i + 1 } d[n] = 0 as u8; return d } |
| 92 | func mm_atoi(s: *u8, n: i64) -> i64 { var v: i64 = 0; var i: i64 = 0; while i < n { let c: i64 = s[i] as i64; if c < 48 { return 0 - 1 } if c > 57 { return 0 - 1 } v = v * 10 + (c - 48); i = i + 1 } if n == 0 { return 0 - 1 } return v } |
| 94 | func mm_field_ok(s: *u8) -> i64 |
| 106 | func mm_path_ok(p: *u8) -> i64 |
| 124 | func mm_join_path(root: *u8, rel: *u8, out: *u8) -> i64 |
| 135 | func mm_chain(name: *u8, version: *u8, games: *u8, deps: *u8, lic: *u8, paths: *i64, bytes: *i64, shas: *i64, n: i64, out32: *u8) -> i64 |
| 170 | func mm_split_csv(csv: *u8, parts: *i64, cap: i64) -> i64 |
| 189 | func mm_join(parts: *i64, n: i64, out: *u8) -> i64 |
| 199 | func mm_emit(outpath: *u8, name: *u8, version: *u8, games_csv: *u8, deps_csv: *u8, lic: *u8, jrnl: *u8, root: *u8, paths: *i64, n: i64, head65: *u8, info: *i64) -> i64 called by 1: mod_manifest_emit calls 23: mm_field_oklg_ctxlg_find_licenselg_lic_redistlg_lic_verifiedsys_mmap+17 |
| 298 | func mod_manifest_emit(outpath: *u8, name: *u8, version: *u8, games_csv: *u8, deps_csv: *u8, lic: *u8, jrnl: *u8, root: *u8, paths: *i64, n: i64, head65: *u8, info: *i64) -> i64 |
| 302 | func mm_fields(b: *u8, s: i64, e: i64, offs: *i64, lens: *i64) -> i64 |
| 314 | func mm_is(b: *u8, off: i64, len: i64, s: *u8) -> i64 { if mm_len(s) != len { return 0 } var i: i64 = 0; while i < len { if b[off + i] != s[i] { return 0 } i = i + 1 } return 1 } |
| 315 | func mm_parse(b: *u8, n: i64, m: *i64) -> i64 |
| 407 | func mm_verify(m: *i64, root: *u8, r: *i64) -> i64 |
| 457 | func mm_err_name(e: i64) -> *u8 called by 1: main |
| 470 | func mm_verdict_name(v: i64) -> *u8 |
| 477 | func mm_state_name(s: i64) -> *u8 called by 1: main |