nx_self_build_test.nx source
↩ module page · 186 lines · 9039 B
1// nx_self_build_test.nx -- THE NET, PROVEN BEFORE THE TRAPEZE.
2//
3// PROOF #0 (the headline): a DELIBERATE FAILED WRITE. Snapshot a temp file,
4// overwrite it with content that FAILS its gate, run the rollback, and ASSERT
5// the restored bytes are BYTE-IDENTICAL to the snapshot (reread + rehash +
6// nx_blob_hash_eq). The safety net works on a deliberate failure -> the
7// reversible-modify tier is safe to point at real source files.
8//
9// Also asserts (the 3-tier policy):
10// - a DESTRUCTIVE op (W_DELETE, and W_OVERWRITE_SRC with NO backup) is DENIED
11// - an ADDITIVE op (W_ADDITIVE) is ALLOWED
12// - the PASS path: a gated-GREEN reversible modify COMMITS (new bytes stand)
13//
14// FAIL-LOUD known-answer: every assertion has a known expected value; any
15// mismatch prints WHAT failed and exits NONZERO. Exit 0 = ALL PROVEN.
16//
17// The re-gate verdict is injected by the caller (two-phase begin/finish):
18// here it is a deterministic known-answer (1 = fail, 0 = pass) -- in-process,
19// and free of the gate-runner's hardcoded /tmp scratch paths (so concurrent
20// ticks cannot collide on it). This exercises the SAME
21// snapshot -> write -> re-gate -> rollback flow the production path uses.
22//
23// license_tier: ORIGINAL
24
25import "nx_syscalls.nx"
26import "nx_blob_store.nx"
27import "nx_self_build.nx"
28
29func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
30func t_putn(n: i64) -> i64 {
31 if n == 0 { sys_write(1, "0" as *u8, 1); return 0 }
32 var m: i64 = n; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
33 let d: *u8 = sys_mmap(24); var k: i64 = 0
34 while m > 0 { d[k] = (0x30 + (m % 10)) as u8; m = m / 10; k = k + 1 }
35 var j: i64 = k - 1
36 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 }
37 return 0
38}
39
40// FAIL-LOUD: print label + got vs want, exit nonzero on mismatch.
41func t_assert_eq(label: *u8, got: i64, want: i64) -> i64 {
42 t_puts(" "); t_puts(label)
43 if got == want {
44 t_puts(" = "); t_putn(got); t_puts(" [OK]\n")
45 return 1
46 }
47 t_puts(" [FAIL got="); t_putn(got); t_puts(" want="); t_putn(want); t_puts("]\n")
48 sys_exit(2)
49 return 0
50}
51
52// gate verdict convention (the value the caller would get from running the
53// gate on the just-written file): 0 = PROVEN (pass), nonzero = FAILED.
54const GATE_FAIL: i64 = 1
55const GATE_PASS: i64 = 0
56
57// seed a known buffer to a path (plain create+write -- fine for test setup).
58func t_seed_file(path: *u8, buf: *u8, len: i64) -> i64 {
59 let fd: i64 = sys_openat_wr(path, 420)
60 if fd < 0 { return -1 }
61 var total: i64 = 0
62 while total < len {
63 let base: i64 = buf as i64
64 let tail: *u8 = (base + total) as *u8
65 let n: i64 = sys_write(fd, tail, len - total)
66 if n <= 0 { sys_close(fd); return -1 }
67 total = total + n
68 }
69 sys_close(fd)
70 return total
71}
72
73// hash the current on-disk bytes of `path` into out_hash via a scratch store.
74func t_hash_file(store: *NxBlobStore, path: *u8, out_hash: *NxBlobHash) -> i64 {
75 let ln: *i64 = (sys_mmap(8)) as *i64
76 let bytes: *u8 = sys_read_file(path, ln)
77 if (bytes as i64) == 0 { return -1 }
78 if nx_blob_store_put(store, bytes, ln[0], out_hash) != NX_BLOB_OK { return -1 }
79 return ln[0]
80}
81
82func main() -> i64 {
83 t_puts("NISHI SELF-BUILD -- safety-net proof (the net before the trapeze)\n")
84 t_puts("================================================================\n")
85
86 // ---- [A] 3-TIER POLICY ASSERTIONS ------------------------------------
87 t_puts("[A] 3-tier policy classifier (additive over warden):\n")
88 let tgt: *u8 = "/tmp/_sbld_policy_target" as *u8
89
90 // ADDITIVE -> ALLOW (W_ALLOW = 1)
91 t_assert_eq("ADDITIVE authorized (W_ALLOW=1)" as *u8,
92 nx_self_build_authorize(W_ADDITIVE, tgt, 0, 0), W_ALLOW)
93 t_assert_eq("ADDITIVE classified TIER_ADDITIVE(1)" as *u8,
94 nx_sb_classify(W_ADDITIVE, tgt, 0, 0), SB_TIER_ADDITIVE)
95
96 // DESTRUCTIVE: delete -> DENY (W_DENY = 0)
97 t_assert_eq("DELETE denied (W_DENY=0)" as *u8,
98 nx_self_build_authorize(W_DELETE, tgt, 1, 1), W_DENY)
99 t_assert_eq("DELETE classified TIER_DESTRUCTIVE(3)" as *u8,
100 nx_sb_classify(W_DELETE, tgt, 1, 1), SB_TIER_DESTRUCTIVE)
101
102 // DESTRUCTIVE: overwrite source WITHOUT backup -> DENY
103 t_assert_eq("OVERWRITE-no-backup denied (W_DENY=0)" as *u8,
104 nx_self_build_authorize(W_OVERWRITE_SRC, tgt, 0, 1), W_DENY)
105 t_assert_eq("OVERWRITE-no-backup classified TIER_DESTRUCTIVE(3)" as *u8,
106 nx_sb_classify(W_OVERWRITE_SRC, tgt, 0, 1), SB_TIER_DESTRUCTIVE)
107
108 // REVERSIBLE: overwrite WITH backup + gate -> classified reversible, ALLOW
109 t_assert_eq("OVERWRITE+backup+gate classified TIER_REVERSIBLE(2)" as *u8,
110 nx_sb_classify(W_OVERWRITE_SRC, tgt, 1, 1), SB_TIER_REVERSIBLE)
111 t_assert_eq("REVERSIBLE authorized (W_ALLOW=1)" as *u8,
112 nx_self_build_authorize(W_OVERWRITE_SRC, tgt, 1, 1), W_ALLOW)
113
114 // ---- [B] PROOF #0: DELIBERATE FAILED WRITE -> ROLLBACK BYTE-IDENTICAL --
115 t_puts("[B] PROOF #0 -- deliberate failed write -> rollback byte-identical:\n")
116 let ctx: *NxSelfBuild = nx_self_build_new()
117 t_assert_eq("ctx valid" as *u8, nx_self_build_is_valid(ctx), 1)
118 let fpath: *u8 = "/tmp/_sbld_reversible_target.nx" as *u8
119
120 // original known-answer content (this is the byte-identity oracle)
121 let orig: *u8 = "ORIGINAL-GOOD-SOURCE-v1\nfunc main() { return 0 }\n" as *u8
122 let orig_len: i64 = sb_slen(orig)
123 t_assert_eq("seed original bytes" as *u8, t_seed_file(fpath, orig, orig_len), orig_len)
124
125 // capture the snapshot hash via an INDEPENDENT scratch store (oracle).
126 let oracle: *NxBlobStore = nx_blob_store_new()
127 let orig_hash: *NxBlobHash = nx_blob_hash_new()
128 t_assert_eq("snapshot oracle hash captured (len)" as *u8,
129 t_hash_file(oracle, fpath, orig_hash), orig_len)
130
131 // garbage that "fails its gate".
132 let garbage: *u8 = "GARBAGE-THAT-FAILS-THE-GATE !!! corrupt $#@\n" as *u8
133 let garbage_len: i64 = sb_slen(garbage)
134
135 // PHASE 1: begin -> snapshot (durable) + atomic-write garbage.
136 let txn: *NxSbTxn = nx_sb_txn_new(ctx, fpath)
137 t_assert_eq("begin(garbage) -> SB_OK(0)" as *u8,
138 nx_self_build_begin(txn, garbage, garbage_len), SB_OK)
139
140 // sanity: the garbage really did land on disk before the gate runs.
141 let mid_hash: *NxBlobHash = nx_blob_hash_new()
142 t_hash_file(oracle, fpath, mid_hash)
143 let garbage_hash: *NxBlobHash = nx_blob_hash_new()
144 nx_blob_store_put(oracle, garbage, garbage_len, garbage_hash)
145 t_assert_eq("post-begin disk == garbage (write happened, nx_blob_hash_eq=1)" as *u8,
146 nx_blob_hash_eq(mid_hash, garbage_hash), 1)
147
148 // PHASE 2: finish with a FAILING gate verdict -> expect SB_ROLLED_BACK.
149 t_assert_eq("finish(GATE_FAIL) -> SB_ROLLED_BACK(1)" as *u8,
150 nx_self_build_finish(txn, GATE_FAIL), SB_ROLLED_BACK)
151
152 // THE ASSERTION: restored on-disk bytes rehash BYTE-IDENTICAL to snapshot.
153 let restored_hash: *NxBlobHash = nx_blob_hash_new()
154 let restored_len: i64 = t_hash_file(oracle, fpath, restored_hash)
155 t_assert_eq("restored bytes length == snapshot length" as *u8, restored_len, orig_len)
156 t_assert_eq("restored hash BYTE-IDENTICAL to snapshot (nx_blob_hash_eq=1)" as *u8,
157 nx_blob_hash_eq(restored_hash, orig_hash), 1)
158 t_assert_eq("restored hash != garbage hash (0)" as *u8,
159 nx_blob_hash_eq(restored_hash, garbage_hash), 0)
160
161 // ---- [C] PASS PATH: gated-GREEN reversible modify COMMITS -------------
162 t_puts("[C] PASS path -- gated-green reversible modify commits:\n")
163 let good_new: *u8 = "ORIGINAL-GOOD-SOURCE-v2\nfunc main() { return 0 }\n" as *u8
164 let good_new_len: i64 = sb_slen(good_new)
165 let txn2: *NxSbTxn = nx_sb_txn_new(ctx, fpath)
166 t_assert_eq("begin(good v2) -> SB_OK(0)" as *u8,
167 nx_self_build_begin(txn2, good_new, good_new_len), SB_OK)
168 t_assert_eq("finish(GATE_PASS) -> SB_OK(0)" as *u8,
169 nx_self_build_finish(txn2, GATE_PASS), SB_OK)
170
171 // the new bytes must now stand on disk (hash == new content hash).
172 let new_disk_hash: *NxBlobHash = nx_blob_hash_new()
173 let new_disk_len: i64 = t_hash_file(oracle, fpath, new_disk_hash)
174 t_assert_eq("committed bytes length == new length" as *u8, new_disk_len, good_new_len)
175 let good_new_hash: *NxBlobHash = nx_blob_hash_new()
176 nx_blob_store_put(oracle, good_new, good_new_len, good_new_hash)
177 t_assert_eq("committed disk bytes == new content (nx_blob_hash_eq=1)" as *u8,
178 nx_blob_hash_eq(new_disk_hash, good_new_hash), 1)
179
180 t_puts("================================================================\n")
181 t_puts("ALL PROVEN: 3-tier policy enforced + rollback byte-identical on a\n")
182 t_puts(" deliberate failed write. The net exists before the\n")
183 t_puts(" capability. exit 0.\n")
184 sys_exit(0)
185 return 0
186}