nx_mvault_record.nx source
↩ module page · 97 lines · 3948 B
1// nx_mvault_record.nx -- vault item as a CANONICAL CID RECORD on the seg-store.
2//
3// THE SOTA STORAGE FIX (operator 2026-07-17: "get our data on the nishi
4// information management state of the art plane so we stop dicking around with
5// bad formats and bad storage"): every vault item becomes a byte-deterministic
6// NXR1 record {class, type, source, mls, ref} (nx_canon_cid), CID-addressed
7// (nxc1-sha256, dedup by construction), written ADDITIVELY to the seg-store
8// with an atomic id-index (nx_registry). No TSV, no flat galx_vid_*.tsv.
9//
10// Composes ONLY proven, gated organs:
11// nx_canon_cid.nx -- canon_encode (key-sorted framed record), cid_of
12// nx_registry.nx -- reg_put (additive, atomic index), reg_get
13// nx_mvault_ingest -- mv_class_str / mv_type_str / mv_level_str (field values)
14//
15// The record is MLS-classified (mls field) so the librarian's per-level index
16// can shelve it at TS -- private content never enters the public U index.
17// license_tier: ORIGINAL
18
19import "nx_syscalls.nx"
20import "nx_canon_cid.nx"
21import "nx_registry.nx"
22import "nx_mvault_ingest.nx"
23
24// Build a canonical NXR1 record {class,type,source,mls,ref} into out; ret len.
25func mv_record_build(out: *u8, class_code: i64, type_code: i64, mls_code: i64,
26 source: *u8, ref: *u8) -> i64 {
27 let keys: *i64 = sys_mmap(8 * 5) as *i64
28 let vals: *i64 = sys_mmap(8 * 5) as *i64
29 let k_class: *u8 = "class" as *u8
30 let k_type: *u8 = "type" as *u8
31 let k_source: *u8 = "source" as *u8
32 let k_mls: *u8 = "mls" as *u8
33 let k_ref: *u8 = "ref" as *u8
34 keys[0] = k_class as i64; vals[0] = (mv_class_str(class_code)) as i64
35 keys[1] = k_type as i64; vals[1] = (mv_type_str(type_code)) as i64
36 keys[2] = k_source as i64; vals[2] = source as i64
37 keys[3] = k_mls as i64; vals[3] = (mv_level_str(mls_code)) as i64
38 keys[4] = k_ref as i64; vals[4] = ref as i64
39 let rl: i64 = canon_encode(keys, vals, 5, out)
40 // bulk drivers call this once per file -- free the tiny scratch or it
41 // compounds to GBs of touched pages across a full-corpus walk
42 sys_munmap(keys as *u8, 8 * 5)
43 sys_munmap(vals as *u8, 8 * 5)
44 return rl
45}
46
47func mvr_r32(p: *u8, off: i64) -> i64 {
48 let a: i64 = p[off]
49 let b: i64 = p[off + 1]
50 let c: i64 = p[off + 2]
51 let d: i64 = p[off + 3]
52 return (((((a << 8) | b) << 8) | c) << 8) | d
53}
54
55// Find field `key` in an NXR1 record: outp[0]=value addr, outl[0]=vlen; 1=found.
56func mv_rec_field(rec: *u8, reclen: i64, key: *u8, klen: i64,
57 outp: *i64, outl: *i64) -> i64 {
58 if reclen < 8 { return 0 }
59 if rec[0] != (78 as u8) { return 0 } // N
60 if rec[1] != (88 as u8) { return 0 } // X
61 if rec[2] != (82 as u8) { return 0 } // R
62 if rec[3] != (49 as u8) { return 0 } // 1
63 let n: i64 = mvr_r32(rec, 4)
64 var off: i64 = 8
65 var i: i64 = 0
66 while i < n {
67 let kl: i64 = mvr_r32(rec, off); off = off + 4
68 let kp: i64 = off; off = off + kl
69 let vl: i64 = mvr_r32(rec, off); off = off + 4
70 let vp: i64 = off; off = off + vl
71 if kl == klen {
72 var m: i64 = 1
73 var c: i64 = 0
74 while c < kl { if rec[kp + c] != key[c] { m = 0 } c = c + 1 }
75 if m == 1 {
76 outp[0] = (rec as i64) + vp
77 outl[0] = vl
78 return 1
79 }
80 }
81 i = i + 1
82 }
83 return 0
84}
85
86// Store a record CID-keyed on the seg-store (additive; atomic id-index).
87func mv_store_put(prefix: *u8, id: *u8, rec: *u8, reclen: i64) -> i64 {
88 let kp: *u8 = "mv:" as *u8
89 let idx: *u8 = "mv:ids" as *u8
90 return reg_put(prefix, kp, idx, id, rec, reclen)
91}
92
93// Read the current record for CID `id`: outp[0]/outl[0]; 1=found 0=tomb -1=absent.
94func mv_store_get(prefix: *u8, id: *u8, outp: *i64, outl: *i64) -> i64 {
95 let kp: *u8 = "mv:" as *u8
96 return reg_get(prefix, kp, id, outp, outl)
97}