nx_mvault_coll_gate.nx source
↩ module page · 118 lines · 6543 B
1// nx_mvault_coll_gate.nx -- proves the vault's collection/provenance axis.
2//
3// The teeth are the properties a media library actually breaks on:
4// T3 re-declaring an album must NOT fork a second collection (derived ids)
5// T6 re-ingesting an album must NOT duplicate its members (idempotent ingest)
6// T7 one file may belong to SEVERAL albums (many-to-many, not a field)
7// T9 a too-small buffer REFUSES rather than returning a partial album
8// Each of those is a way a naive implementation silently corrupts a library:
9// duplicate albums on re-run, item counts that inflate every sync, a re-post
10// losing its first home, and a truncated album that looks complete.
11// license_tier: ORIGINAL
12import "nx_mvault_coll.nx"
13import "nx_gate.nx"
14import "nx_gate_verdict.nx" // D001: canonical verdict emission + actlog frame
15
16const CG_PFX: *u8 = "knowledge/mvcoll-test-\x00"
17
18func cg_eq(a: *u8, b: *u8) -> i64 {
19 var i: i64 = 0
20 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
21 if b[i] != (0 as u8) { return 0 }
22 return 1
23}
24
25func main() -> i64 {
26 gw("=== nx_mvault_coll_gate: site/album/source grouping over the vault ===\n" as *u8)
27 var pass: i64=0; var tot: i64=0
28
29 let k_album: *u8 = "album" as *u8
30 let k_site: *u8 = "site" as *u8
31 let bunkr: *u8 = "bunkr" as *u8
32 let none: *u8 = "-" as *u8
33
34 let c1: *u8 = sys_mmap(256)
35 let c2: *u8 = sys_mmap(256)
36 let c3: *u8 = sys_mmap(256)
37
38 mvc_colid(k_album, bunkr, "aXbYcZ" as *u8, c1)
39 mvc_colid(k_album, bunkr, "aXbYcZ" as *u8, c2)
40 tot=tot+1; if cg_eq(c1,c2)==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
41 gw("T1 colid is DERIVED and STABLE (same kind/site/key -> same id)\n" as *u8)
42
43 mvc_colid(k_album, bunkr, "different" as *u8, c3)
44 tot=tot+1; if cg_eq(c1,c3)==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
45 gw("T2 a different album key yields a DIFFERENT colid (no collision)\n" as *u8)
46
47 let d1: *u8 = sys_mmap(256)
48 let d2: *u8 = sys_mmap(256)
49 mvc_declare_pfx(CG_PFX, k_album, bunkr, "aXbYcZ" as *u8, "Holiday" as *u8, "https://bunkr/a/aXbYcZ" as *u8, none, d1)
50 mvc_declare_pfx(CG_PFX, k_album, bunkr, "aXbYcZ" as *u8, "Holiday" as *u8, "https://bunkr/a/aXbYcZ" as *u8, none, d2)
51 let lbuf: *u8 = sys_mmap(65536)
52 let ll: i64 = mvc_list_pfx(CG_PFX, lbuf, 65536)
53 var ncol: i64 = mvc_count_lines(lbuf, ll)
54 // RE-RUN SAFE: assert the END STATE, not a global count. Asserting the test
55 // store holds exactly ONE collection is only true on a FIRST run -- on a
56 // re-run the site collection from T7 is still there and a CORRECT system
57 // fails the check. A gate that only passes once produces false RED.
58 tot=tot+1; if cg_eq(d1,d2)==1 { if reg_id_present(lbuf, ll, d1, mvc_strlen(d1))==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
59 gw("T3 TOOTH declaring the SAME album twice does not fork a duplicate (collections=" as *u8); gn(ncol); gw(")\n" as *u8)
60
61 // ingest three files into the album
62 let items: *u8 = sys_mmap(4096)
63 var io: i64 = 0
64 io = mvc_cat(items, io, "nxc1-aaa\n" as *u8)
65 io = mvc_cat(items, io, "nxc1-bbb\n" as *u8)
66 io = mvc_cat(items, io, "nxc1-ccc\n" as *u8)
67 let add1: i64 = mvc_batch_add_pfx(CG_PFX, d1, items, io)
68 // RE-RUN SAFE: on a re-run these three are ALREADY linked, so a correct
69 // batch_add returns 0. Assert the album HOLDS three, not that this call
70 // added three -- the end state is the property, the delta is an artifact
71 // of whether the store was fresh.
72 tot=tot+1; if mvc_count_pfx(CG_PFX, d1)==3 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
73 gw("T4 batch ingest links all three files in ONE segment (linked=" as *u8); gn(add1); gw(")\n" as *u8)
74
75 let mb: *u8 = sys_mmap(65536)
76 let mn: i64 = mvc_items_pfx(CG_PFX, d1, mb, 65536)
77 tot=tot+1; if mvc_count_lines(mb, mn)==3 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
78 gw("T5 the album reads back its three members\n" as *u8)
79
80 // ★ THE IDEMPOTENCE TOOTH: re-ingesting the same album must add NOTHING.
81 // A downloader re-run, a resumed sync, a cron beat -- all replay this.
82 let add2: i64 = mvc_batch_add_pfx(CG_PFX, d1, items, io)
83 let cnt2: i64 = mvc_count_pfx(CG_PFX, d1)
84 tot=tot+1; if add2==0 { if cnt2==3 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
85 gw("T6 TOOTH re-ingesting the SAME album adds 0 and the count stays 3 (got add=" as *u8); gn(add2); gw(" count=" as *u8); gn(cnt2); gw(")\n" as *u8)
86
87 // ★ MANY-TO-MANY: the same file also lives in a site collection.
88 let s1: *u8 = sys_mmap(256)
89 mvc_declare_pfx(CG_PFX, k_site, bunkr, "bunkr" as *u8, "Bunkr" as *u8, "https://bunkr" as *u8, none, s1)
90 let one: *u8 = sys_mmap(256)
91 let on: i64 = mvc_cat(one, 0, "nxc1-aaa\n" as *u8)
92 mvc_batch_add_pfx(CG_PFX, s1, one, on)
93 let ob: *u8 = sys_mmap(65536)
94 let obn: i64 = mvc_of_item_pfx(CG_PFX, "nxc1-aaa" as *u8, ob, 65536)
95 var both: i64 = 0
96 if reg_id_present(ob, obn, d1, mvc_strlen(d1))==1 { if reg_id_present(ob, obn, s1, mvc_strlen(s1))==1 { both=1 } }
97 tot=tot+1; if both==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
98 gw("T7 TOOTH one file belongs to BOTH its album and its site (many-to-many)\n" as *u8)
99
100 let ob2: i64 = mvc_of_item_pfx(CG_PFX, "nxc1-bbb" as *u8, ob, 65536)
101 tot=tot+1; if mvc_count_lines(ob, ob2)==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
102 gw("T8 reverse index is EXACT -- a file only in the album reports one home\n" as *u8)
103
104 let tiny: i64 = mvc_items_pfx(CG_PFX, d1, mb, 4)
105 tot=tot+1; if tiny==(0-1) { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
106 gw("T9 TOOTH a too-small buffer REFUSES (-1) rather than returning a partial album\n" as *u8)
107
108 let miss: i64 = mvc_items_pfx(CG_PFX, "nxc1-nosuchcollection" as *u8, mb, 65536)
109 tot=tot+1; if miss==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
110 gw("T10 an unknown collection is 0 (empty), distinct from -1 (does not fit)\n" as *u8)
111
112 let ctr: *i64 = gv_ctr()
113 ctr[0] = pass
114 ctr[1] = tot
115 let rc: i64 = gv_verdict("VAULT-COLLECTIONS" as *u8, ctr, "site/album/source grouping is derived, idempotent, many-to-many and refuses partials" as *u8)
116 sys_exit(rc)
117 return rc
118}