code wiki / _hdl_build / nx_legal_store_gate.nx
nx_legal_store_gate.nx source
↩ module page · 144 lines · 6358 B
1// nx_legal_store_gate.nx -- GATE for LEGAL D7 (nx_legal_store), the ENGINEER verify.
2//
3// Composes a REAL D1 vault store + the persistence layer and asserts the durable-
4// state contract, each with a negative control:
5// T1 ROUND-TRIP : a 3-version vault saved + loaded into a FRESH array is
6// byte-identical (every record field), as after a restart.
7// T2 SURVIVES-RESTART: the reloaded array still satisfies the vault invariants
8// (version_count=3, chain OK, current=v3) -- real state, not bytes.
9// T3 TENANT ISOLATION: ls_path rejects '../x' / 'a/b' / '' (no traversal); a
10// different tenant's path is a different file -> can't load it.
11// T4 ABSENT + CORRUPT: load of a missing file -> -1; a wrong-magic file -> -MAGIC
12// (never silent garbage).
13// T5 STRIDE GUARD : a vault file (stride 8) loaded as stride 9 -> -STRIDE
14// (a vault can never be misread as an envelope).
15// T6 IDEMPOTENT : saving twice then loading yields the identical store (#10).
16//
17// Evidence -> knowledge/status/legal_store.log
18// license_tier: ORIGINAL
19import "nx_legal_store.nx"
20import "nx_doc_vault.nx"
21import "nx_syscalls.nx"
22
23const LST_LOG: *u8 = "knowledge/status/legal_store.log"
24const LST_BASE: *u8 = "/tmp/nx_ls_"
25
26func ew(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
27func ewn(fd: i64, v: i64) -> i64 {
28 let bb: *u8 = sys_mmap(28); var m: i64 = v
29 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
30 let t: *u8 = sys_mmap(28); var k: i64 = 0
31 if m == 0 { t[0] = 48; k = 1 }
32 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
33 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
34 sys_write(fd, bb, k); return 0
35}
36
37func main() -> i64 {
38 var ok: i64 = 1
39 let cap: i64 = 16
40 let flat1: *i64 = sys_mmap(cap * VF_STRIDE * 8) as *i64
41 let flat2: *i64 = sys_mmap(cap * VF_STRIDE * 8) as *i64
42 let path: *u8 = sys_mmap(512)
43 let pathB: *u8 = sys_mmap(512)
44
45 // ---- build a real 3-version vault store ----
46 var count: i64 = 0
47 count = nx_vault_add(flat1, count, cap, 7001, 1001, 500, 100)
48 count = nx_vault_add(flat1, count, cap, 7001, 1002, 510, 200)
49 count = nx_vault_add(flat1, count, cap, 7001, 1003, 520, 300)
50
51 // ---- T1: save + load into a FRESH array, byte-identical ----
52 var t1: i64 = 1
53 if ls_path(path, LST_BASE, "clientA" as *u8, "vault" as *u8) < 0 { t1 = 0 }
54 if ls_save(flat1, count, VF_STRIDE, path) != LS_OK { t1 = 0 }
55 let lc: i64 = ls_load(flat2, cap, VF_STRIDE, path)
56 if lc != count { t1 = 0 }
57 var i: i64 = 0
58 while i < count * VF_STRIDE {
59 if flat2[i] != flat1[i] { t1 = 0 }
60 i = i + 1
61 }
62 if t1 != 1 { ok = 0 }
63
64 // ---- T2: the reloaded store still satisfies the vault invariants ----
65 var t2: i64 = 1
66 if nx_vault_version_count(flat2, lc, 7001) != 3 { t2 = 0 }
67 if nx_vault_verify_chain(flat2, lc, 7001) != VAULT_OK { t2 = 0 }
68 let cur: i64 = nx_vault_current_idx(flat2, lc, 7001)
69 if cur < 0 { t2 = 0 }
70 if flat2[cur * VF_STRIDE + VF_VER] != 3 { t2 = 0 }
71 if t2 != 1 { ok = 0 }
72
73 // ---- T3: tenant isolation ----
74 // (a genuine zeroed empty string -- the bare "" literal can alias another
75 // literal in the string pool, so build the empty tenant explicitly.)
76 var t3: i64 = 1
77 let empty: *u8 = sys_mmap(8); empty[0] = 0 as u8
78 if ls_path(path, LST_BASE, "../etc" as *u8, "vault" as *u8) != (0 - 1) { t3 = 0 }
79 if ls_path(path, LST_BASE, "a/b" as *u8, "vault" as *u8) != (0 - 1) { t3 = 0 }
80 if ls_path(path, LST_BASE, empty, "vault" as *u8) != (0 - 1) { t3 = 0 }
81 // clientB's path is a DIFFERENT file -> loading it finds nothing (no cross-tenant)
82 if ls_path(pathB, LST_BASE, "clientB" as *u8, "vault" as *u8) < 0 { t3 = 0 }
83 if ls_load(flat2, cap, VF_STRIDE, pathB) != (0 - 1) { t3 = 0 }
84 if t3 != 1 { ok = 0 }
85
86 // ---- T4: absent + corrupt ----
87 var t4: i64 = 1
88 let pmiss: *u8 = sys_mmap(512)
89 if ls_path(pmiss, LST_BASE, "nobody" as *u8, "vault" as *u8) < 0 { t4 = 0 }
90 if ls_load(flat2, cap, VF_STRIDE, pmiss) != (0 - 1) { t4 = 0 }
91 // write a wrong-magic file, then load -> -LS_ERR_MAGIC
92 let pbad: *u8 = sys_mmap(512)
93 if ls_path(pbad, LST_BASE, "corrupt" as *u8, "vault" as *u8) < 0 { t4 = 0 }
94 let bfd: i64 = sys_openat_wr(pbad, 420)
95 if bfd < 0 { t4 = 0 } else {
96 let bh: *i64 = sys_mmap(32) as *i64
97 bh[0] = 0xDEADBEEF; bh[1] = VF_STRIDE; bh[2] = 0
98 sys_write(bfd, bh as *u8, 24)
99 sys_close(bfd)
100 }
101 if ls_load(flat2, cap, VF_STRIDE, pbad) != (0 - LS_ERR_MAGIC) { t4 = 0 }
102 if t4 != 1 { ok = 0 }
103
104 // ---- T5: stride guard (a vault file is not an envelope file) ----
105 var t5: i64 = 1
106 // path still points at clientA's saved vault (stride 8); load expecting stride 9 -> refused
107 if ls_path(path, LST_BASE, "clientA" as *u8, "vault" as *u8) < 0 { t5 = 0 }
108 if ls_load(flat2, cap, 9, path) != (0 - LS_ERR_STRIDE) { t5 = 0 }
109 if t5 != 1 { ok = 0 }
110
111 // ---- T6: idempotent re-save ----
112 var t6: i64 = 1
113 if ls_save(flat1, count, VF_STRIDE, path) != LS_OK { t6 = 0 }
114 if ls_save(flat1, count, VF_STRIDE, path) != LS_OK { t6 = 0 }
115 let lc2: i64 = ls_load(flat2, cap, VF_STRIDE, path)
116 if lc2 != count { t6 = 0 }
117 var j: i64 = 0
118 while j < count * VF_STRIDE {
119 if flat2[j] != flat1[j] { t6 = 0 }
120 j = j + 1
121 }
122 if t6 != 1 { ok = 0 }
123
124 // ---- evidence ----
125 var fd: i64 = 1
126 while fd >= 1 {
127 ew(fd, "LEGALSTOREGATE authored=organ composes=D1 roundtrip=" as *u8); ewn(fd, t1)
128 ew(fd, " survives_restart=" as *u8); ewn(fd, t2)
129 ew(fd, " tenant_isolation=" as *u8); ewn(fd, t3)
130 ew(fd, " absent_corrupt=" as *u8); ewn(fd, t4)
131 ew(fd, " stride_guard=" as *u8); ewn(fd, t5)
132 ew(fd, " idempotent_resave=" as *u8); ewn(fd, t6)
133 if ok == 1 { ew(fd, " verdict=GREEN\n" as *u8) } else { ew(fd, " verdict=RED\n" as *u8) }
134 if fd == 1 {
135 let lf: i64 = sys_openat_append(LST_LOG, 420)
136 if lf >= 1 { fd = lf } else { fd = 0 }
137 } else {
138 sys_close(fd); fd = 0
139 }
140 }
141
142 if ok == 1 { return 0 }
143 return 1
144}