code wiki / _hdl_build / nx_doc_vault_gate.nx
nx_doc_vault_gate.nx source
↩ module page · 130 lines · 5940 B
1// nx_doc_vault_gate.nx -- GATE for LEGAL D1 (nx_doc_vault).
2//
3// Drives the REAL vault and asserts the retention invariants:
4// ADDITIVE+VERSIONED : 3 versions of doc A -> version_count(A)=3, current is
5// version 3 (older versions retained, not overwritten).
6// SINGLE-AUTHORITATIVE: exactly one is_current per doc (UETA 16).
7// CHAIN TAMPER-EVIDENT: verify_chain(A)=OK; corrupt a non-final version's
8// hash -> CHAIN_BROKEN; restore -> OK (UETA 12).
9// SOFT-DELETE KEEPS HISTORY: soft_delete(A) -> no current, but
10// version_count(A) still 3 (Rule 13 additive-only).
11// SEAL ATTACH : a D5 seal attaches to the CURRENT version only.
12// TENANT ISOLATION : valid tid accepted; '.'/'/'/empty rejected (no
13// cross-tenant traversal -- MRPC 1.6 confidentiality).
14// MULTI-DOC : adding doc B leaves doc A's history untouched.
15//
16// Evidence -> knowledge/status/doc_vault.log
17// license_tier: ORIGINAL
18import "nx_doc_vault.nx"
19import "nx_syscalls.nx"
20
21const DV_LOG: *u8 = "knowledge/status/doc_vault.log"
22
23func 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 }
24func ewn(fd: i64, v: i64) -> i64 {
25 let bb: *u8 = sys_mmap(28); var m: i64 = v
26 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
27 let t: *u8 = sys_mmap(28); var k: i64 = 0
28 if m == 0 { t[0] = 48; k = 1 }
29 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
30 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
31 sys_write(fd, bb, k); return 0
32}
33
34func main() -> i64 {
35 var ok: i64 = 1
36 let cap: i64 = 64
37 let flat: *i64 = sys_mmap(cap * VF_STRIDE * 8) as *i64
38 var count: i64 = 0
39
40 let docA: i64 = 7001
41 let docB: i64 = 7002
42
43 // ---- ADDITIVE + VERSIONED: 3 chained versions of A ----
44 var add_ok: i64 = 1
45 count = nx_vault_add(flat, count, cap, docA, 1001, 500, 100)
46 if count != 1 { add_ok = 0 }
47 count = nx_vault_add(flat, count, cap, docA, 1002, 510, 200)
48 if count != 2 { add_ok = 0 }
49 count = nx_vault_add(flat, count, cap, docA, 1003, 520, 300)
50 if count != 3 { add_ok = 0 }
51 if nx_vault_version_count(flat, count, docA) != 3 { add_ok = 0 }
52 // current is version 3
53 let cur: i64 = nx_vault_current_idx(flat, count, docA)
54 if cur < 0 { add_ok = 0 }
55 if flat[cur * VF_STRIDE + VF_VER] != 3 { add_ok = 0 }
56 if add_ok != 1 { ok = 0 }
57
58 // ---- SINGLE AUTHORITATIVE COPY ----
59 var single_ok: i64 = 1
60 if nx_vault_current_count(flat, count, docA) != 1 { single_ok = 0 }
61 if single_ok != 1 { ok = 0 }
62
63 // ---- CHAIN: ok, then tamper a non-final version, then restore ----
64 var chain_ok: i64 = 1
65 if nx_vault_verify_chain(flat, count, docA) != VAULT_OK { chain_ok = 0 }
66 // corrupt version 2's content hash (record index 1) -> version 3's prev no longer links
67 let save_h: i64 = flat[1 * VF_STRIDE + VF_HASH]
68 flat[1 * VF_STRIDE + VF_HASH] = 9999
69 if nx_vault_verify_chain(flat, count, docA) != VAULT_CHAIN_BROKEN { chain_ok = 0 }
70 flat[1 * VF_STRIDE + VF_HASH] = save_h
71 if nx_vault_verify_chain(flat, count, docA) != VAULT_OK { chain_ok = 0 }
72 if chain_ok != 1 { ok = 0 }
73
74 // ---- SEAL attaches to the CURRENT version only ----
75 var seal_ok: i64 = 1
76 if nx_vault_attach_seal(flat, count, docA) != VAULT_OK { seal_ok = 0 }
77 if flat[2 * VF_STRIDE + VF_SEAL] != 1 { seal_ok = 0 } // v3 (current) sealed
78 if flat[0 * VF_STRIDE + VF_SEAL] != 0 { seal_ok = 0 } // v1 not
79 if flat[1 * VF_STRIDE + VF_SEAL] != 0 { seal_ok = 0 } // v2 not
80 if seal_ok != 1 { ok = 0 }
81
82 // ---- MULTI-DOC isolation: add B, A untouched ----
83 var multi_ok: i64 = 1
84 count = nx_vault_add(flat, count, cap, docB, 2001, 700, 400)
85 if count != 4 { multi_ok = 0 }
86 if nx_vault_version_count(flat, count, docA) != 3 { multi_ok = 0 }
87 if nx_vault_version_count(flat, count, docB) != 1 { multi_ok = 0 }
88 if nx_vault_verify_chain(flat, count, docB) != VAULT_OK { multi_ok = 0 }
89 if multi_ok != 1 { ok = 0 }
90
91 // ---- SOFT-DELETE keeps history (Rule 13) ----
92 var del_ok: i64 = 1
93 if nx_vault_soft_delete(flat, count, docA) != VAULT_OK { del_ok = 0 }
94 if nx_vault_current_idx(flat, count, docA) != (0 - 1) { del_ok = 0 } // no current
95 if nx_vault_current_count(flat, count, docA) != 0 { del_ok = 0 }
96 if nx_vault_version_count(flat, count, docA) != 3 { del_ok = 0 } // history retained
97 if del_ok != 1 { ok = 0 }
98
99 // ---- TENANT-ID isolation ----
100 var tid_ok: i64 = 1
101 if nx_vault_valid_tid("client_andelinwest" as *u8) != 1 { tid_ok = 0 }
102 if nx_vault_valid_tid("andelin-west-2026" as *u8) != 1 { tid_ok = 0 }
103 if nx_vault_valid_tid("../secret" as *u8) != 0 { tid_ok = 0 }
104 if nx_vault_valid_tid("a/b" as *u8) != 0 { tid_ok = 0 }
105 if nx_vault_valid_tid("dot.tid" as *u8) != 0 { tid_ok = 0 }
106 if nx_vault_valid_tid("" as *u8) != 0 { tid_ok = 0 }
107 if tid_ok != 1 { ok = 0 }
108
109 // ---- evidence ----
110 var fd: i64 = 1
111 while fd >= 1 {
112 ew(fd, "DOCVAULTGATE authored=organ additive_versioned=" as *u8); ewn(fd, add_ok)
113 ew(fd, " single_authoritative=" as *u8); ewn(fd, single_ok)
114 ew(fd, " chain_tamper_evident=" as *u8); ewn(fd, chain_ok)
115 ew(fd, " seal_current_only=" as *u8); ewn(fd, seal_ok)
116 ew(fd, " multidoc_isolated=" as *u8); ewn(fd, multi_ok)
117 ew(fd, " softdelete_keeps_history=" as *u8); ewn(fd, del_ok)
118 ew(fd, " tenant_id_no_traversal=" as *u8); ewn(fd, tid_ok)
119 if ok == 1 { ew(fd, " verdict=GREEN\n" as *u8) } else { ew(fd, " verdict=RED\n" as *u8) }
120 if fd == 1 {
121 let lf: i64 = sys_openat_append(DV_LOG, 420)
122 if lf >= 1 { fd = lf } else { fd = 0 }
123 } else {
124 sys_close(fd); fd = 0
125 }
126 }
127
128 if ok == 1 { return 0 }
129 return 1
130}