nx_legal_store.nx
buildroot/runtime/nx_legal_store.nx
about
nx_legal_store.nx -- LEGAL RUNG D7: durable persistence for the legal stores.
module: nishi-core.legal.store
capability: LEGAL_DOC_PERSIST
The logic cores (D1 vault / D2 envelope+recipients / D4 annotations) hold their
state in caller-allocated flat i64 record arrays -- correct, but lost on a
restart. This rung makes them DURABLE: serialize a flat array to a per-tenant
file with an integrity header, and load it back byte-identical so the portal
daemon survives a restart.
FORMAT : [magic i64][stride i64][count i64] then count*stride i64 records.
INTEGRITY: load verifies the magic AND that the stored stride matches the
caller's expected stride -- so a vault file can never be misread as
an envelope file (different stride) -> silent corruption refused.
PER-TENANT: the path is <base><tenant>.<name>, tenant validated [A-Za-z0-9_-]
(nx_vault_valid_tid, the proven discipline) -> no cross-tenant
traversal; one tenant can never load another's store.
HONEST scope: this proves the persistence CONTRACT (save/load/survive-restart/
tenant-isolated/integrity-checked) over a plain per-tenant file. The production
path composes nx_seg_store (the same durable, concurrent-safe segmented store
the email mailbox already persists to) -- a pattern-covered refinement, not a
new primitive.
Composes: nx_doc_vault (nx_vault_valid_tid tenant discipline). license_tier: ORIGINAL
lineage_id: nishi_legal_store_d7
dependencies 2 imports · 5 importers
imports: nx_syscalls.nxnx_doc_vault.nx
imported by: nx_legal_blob_gate.nxnx_legal_portal_boot.nxnx_legal_portal_boot_gate.nxnx_legal_portal_daemon.nxnx_legal_store_gate.nx
structs
| none |
consts
| 31 | const LS_MAGIC: i64 = 0x4E584C5331 // "NXLS1" -- recognizes a legal-store file |
| 32 | const LS_OK: i64 = 0 |
| 33 | const LS_ERR_TENANT: i64 = 1 |
| 34 | const LS_ERR_OPEN: i64 = 2 |
| 35 | const LS_ERR_MAGIC: i64 = 3 |
| 36 | const LS_ERR_STRIDE: i64 = 4 |
| 89 | const LS_BMAGIC: i64 = 0x4E584C42 // "NXLB" -- recognizes a legal-blob (raw document bytes) file |
functions
| 38 | func ls_cat(out: *u8, o: i64, s: *u8) -> i64 { var k: i64 = 0; while s[k] != (0 as u8) { out[o] = s[k]; o = o + 1; k = k + 1 } return o } called by 1: ls_path |
| 41 | func ls_path(out: *u8, base: *u8, tenant: *u8, name: *u8) -> i64 |
| 53 | func ls_save(flat: *i64, count: i64, stride: i64, path: *u8) -> i64 |
| 66 | func ls_load(flat: *i64, cap: i64, stride: i64, path: *u8) -> i64 |
| 93 | func ls_blob_save(bytes: *u8, len: i64, path: *u8) -> i64 |
| 106 | func ls_blob_load(out: *u8, cap: i64, path: *u8) -> i64 |