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}