code wiki / _hdl_build / nx_spore_germ_gate.nx

nx_spore_germ_gate.nx source

↩ module page · 206 lines · 10019 B

1// nx_spore_germ_gate.nx -- V-SPORE-1 PROOF (X-SEED-002): germinate ONE ecosystem piece 2// from its content-addressed manifest entry and prove it by BEHAVIOR (KAT exit code). 3// A tampered piece is rejected on the INTEGRITY gate and is NEVER built or run. 4// 5// Per NISHI_SPORE_SEED_PORTABILITY_CHARTER germination loop (1:1 PROOF, KAT-as-oracle): 6// 1. PACK -- manifest entry = FNV-1a(canonical piece bytes) + kat_expect exit code. 7// 2. INTEGRITY -- received bytes FNV-1a == manifest hash, else REJECT (never run). 8// 3. MATERIALIZE-- write the VERIFIED bytes to runtime/_germ_scratch_<piece>.nx so the 9// piece's imports resolve via the normal runtime/ tree exactly as the 10// canonical organ's do. Fully isolated-dir germination needs explicit 11// import closures (charter [F2]) = the named follow-on V-SPORE-1b. 12// 4. REBUILD -- the SOVEREIGN toolchain rebuilds the materialized bytes via 13// _offc/nx_sov_build_run.elf (nx_cc_sovereign + nxasm, empty-.s guard). 14// 5. BEHAVIOR -- fork/exec the rebuilt ELF; exit code == manifest kat_expect = 1:1 proof. 15// ADMIT iff INTEGRITY-clean AND rebuild rc==0 AND kat_exit==kat_expect. 16// 17// Controls: POSITIVE = intact nx_exit42 piece -> ADMITTED (kat_exit 42). 18// NEGATIVE = same piece, one byte flipped -> INTEGRITY mismatch -> REJECTED, 19// build+run NEVER reached (admitted count must remain exactly 1). 20// 21// RUN FROM the nxc2 cwd (relative _offc/ runtime/ knowledge/ paths). 22// Build: _offc/nx_sov_build_run.elf nx_spore_germ_gate -> /tmp/nx_spore_germ_gate.sov.elf 23// Verdict line is appended to knowledge/status/spore_germ.log. 24// 25// genealogy_id: nishi_spore_seed_portability_charter_2026-05-28 (X-SEED-002 / V-SPORE-1) 26// lineage_id: spore_germ_proof_v1 27 28import "nx_syscalls.nx" 29import "nx_gate_verdict.nx" 30 31// ---- FNV-1a over a byte buffer (inlined; matches nx_germinate_test, compiles clean) ---- 32const GERM_FNV_OFFSET: i64 = 0 - 3750763034362895579 // 0xcbf29ce484222325 33const GERM_FNV_PRIME: i64 = 1099511628211 // 0x100000001b3 34 35func germ_hash(buf: *u8, len: i64) -> i64 { 36 var h: i64 = GERM_FNV_OFFSET 37 var i: i64 = 0 38 while i < len { 39 h = h ^ (buf[i] as i64) 40 h = h * GERM_FNV_PRIME 41 i = i + 1 42 } 43 return h 44} 45 46func germ_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 47func germ_puts(s: *u8) -> i64 { sys_write(1, s, germ_slen(s)); return 0 } 48func germ_puts_fd(fd: i64, s: *u8) -> i64 { sys_write(fd, s, germ_slen(s)); return 0 } 49 50// decimal print to fd (matches sbr_putn spine) 51func germ_putn_fd(fd: i64, v: i64) -> i64 { 52 let bb: *u8 = sys_mmap(28) 53 var m: i64 = v 54 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 55 let t: *u8 = sys_mmap(28) 56 var k: i64 = 0 57 if m == 0 { t[0] = 48; k = 1 } 58 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 } 59 var i: i64 = 0 60 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 61 sys_write(fd, bb, k) 62 return 0 63} 64 65// hex print of an i64 (16 nibbles, MSB first) -- the content address, measured 66func germ_puthex_fd(fd: i64, v: i64) -> i64 { 67 let hx: *u8 = sys_mmap(20) 68 let digits: *u8 = "0123456789abcdef" as *u8 69 var i: i64 = 0 70 while i < 16 { 71 let shift: i64 = 60 - (i * 4) 72 let nib: i64 = (v >> shift) & 0xf 73 hx[i] = digits[nib] 74 i = i + 1 75 } 76 sys_write(fd, hx, 16) 77 return 0 78} 79 80// fork + optional stdout/stderr redirect + execve; parent waits; returns child's WEXITSTATUS, 81// OR 128+signal if the child died to a signal -- NO silent fake-success on a segfaulted tool 82// (replicates the nx_sov_build_run sbr_run evidence-driven runner spine). 83func germ_run(path: *u8, argv: *i64, envp: *i64, redir_out: i64, redir_err: i64) -> i64 { 84 let pid: i64 = sys_fork() 85 if pid == 0 { 86 if redir_out >= 0 { sys_dup3(redir_out, 1, 0) } 87 if redir_err >= 0 { sys_dup3(redir_err, 2, 0) } 88 sys_execve(path, argv, envp) 89 sys_exit(127) 90 } 91 let st: *i64 = sys_mmap(16) as *i64 92 sys_wait4(pid, st, 0) 93 let sig: i64 = st[0] & 0x7f 94 if sig != 0 { return 128 + sig } 95 return (st[0] >> 8) & 0xff 96} 97 98func main() -> i64 { 99 germ_puts("================================================================\n" as *u8) 100 germ_puts(" V-SPORE-1 GERMINATION PROOF -- one piece, content-addressed,\n" as *u8) 101 germ_puts(" rebuilt by the sovereign toolchain, proven by KAT (exit code).\n" as *u8) 102 germ_puts("================================================================\n" as *u8) 103 104 // ---- PACK: manifest entry computed from the canonical piece bytes ---- 105 let src_path: *u8 = "runtime/nx_exit42.nx" as *u8 106 let lenp: *i64 = sys_mmap(8) as *i64 107 let bytes: *u8 = sys_read_file(src_path, lenp) 108 let n: i64 = *lenp 109 if (bytes as i64) == 0 { germ_puts(" FAIL: canary source unreadable\n" as *u8); sys_exit(10); return 10 } 110 if n <= 0 { germ_puts(" FAIL: canary source empty\n" as *u8); sys_exit(10); return 10 } 111 let expect_hash: i64 = germ_hash(bytes, n) 112 let kat_expect: i64 = 42 113 114 germ_puts(" piece=nx_exit42 bytes=" as *u8); germ_putn_fd(1, n) 115 germ_puts(" expect_hash=" as *u8); germ_puthex_fd(1, expect_hash); germ_puts("\n" as *u8) 116 117 var admitted: i64 = 0 118 var neg_reject: i64 = 0 119 var build_rc: i64 = 0 - 1 120 var kat_exit: i64 = 0 - 1 121 122 // ---- POSITIVE control: intact piece -> integrity ok -> materialize -> rebuild -> KAT ---- 123 germ_puts("\n [+] POSITIVE: intact piece\n" as *u8) 124 let recv_hash: i64 = germ_hash(bytes, n) 125 if recv_hash != expect_hash { 126 germ_puts(" INTEGRITY mismatch on intact piece -- impossible; abort\n" as *u8) 127 sys_exit(11); return 11 128 } 129 germ_puts(" integrity: hash MATCH -> materialize\n" as *u8) 130 131 // MATERIALIZE the verified bytes into runtime/ (imports resolve via the normal tree) 132 let scratch_src: *u8 = "runtime/_germ_scratch_exit42.nx" as *u8 133 let wfd: i64 = sys_openat_wr(scratch_src, 0x1a4) 134 if wfd < 0 { germ_puts(" FAIL: cannot materialize scratch source\n" as *u8); sys_exit(12); return 12 } 135 sys_write(wfd, bytes, n) 136 sys_close(wfd) 137 germ_puts(" materialized -> runtime/_germ_scratch_exit42.nx\n" as *u8) 138 139 // REBUILD + BEHAVIOR via the sovereign build/run lane in ONE step: nx_sov_build_run 140 // compiles the materialized source (nx_cc -> nxasm, with the empty-.s nondeterminism 141 // guard) AND runs the result, propagating the program's run-exit as its own exit code. 142 // The canary's KAT exit (42) is deliberately distinct from the lane's build-fail codes 143 // (2/3/4), exec-fail (127), and signal deaths (128+sig) -- so germ_rc==42 unambiguously 144 // means: rebuilt clean AND KAT proven (1:1 PROOF, KAT-as-oracle). Reusing the proven 145 // lane (DRY) beats re-implementing cc->asm->run + its nondeterminism handling. 146 let builder: *u8 = "_offc/nx_sov_build_run.elf" as *u8 147 let b1: *u8 = "_germ_scratch_exit42" as *u8 148 let bargv: *i64 = sys_mmap(32) as *i64 149 bargv[0] = builder as i64 150 bargv[1] = b1 as i64 151 bargv[2] = 0 152 build_rc = germ_run(builder, bargv, 0 as *i64, 0 - 1, 0 - 1) 153 kat_exit = build_rc 154 germ_puts(" rebuild+run: germ_rc=" as *u8); germ_putn_fd(1, build_rc) 155 germ_puts(" (kat_expect=" as *u8); germ_putn_fd(1, kat_expect); germ_puts(")\n" as *u8) 156 if kat_exit == kat_expect { 157 admitted = admitted + 1 158 germ_puts(" -> ADMITTED (integrity-clean, rebuilt by sovereign toolchain, KAT proven)\n" as *u8) 159 } else { 160 germ_puts(" -> REJECT: build-fail or KAT mismatch (liar caught)\n" as *u8) 161 } 162 163 // ---- NEGATIVE control: tampered piece -> integrity mismatch -> NEVER built/run ---- 164 germ_puts("\n [-] NEGATIVE: one byte flipped in transit\n" as *u8) 165 let cor: *u8 = sys_mmap(n + 16) 166 var c: i64 = 0 167 while c < n { cor[c] = bytes[c]; c = c + 1 } 168 cor[0] = (cor[0] ^ 1) as u8 169 let cor_hash: i64 = germ_hash(cor, n) 170 if cor_hash != expect_hash { 171 neg_reject = neg_reject + 1 172 germ_puts(" integrity: hash MISMATCH -> REJECTED, build+run never reached\n" as *u8) 173 } else { 174 germ_puts(" integrity: collision?! tampered piece passed -- gate broken\n" as *u8) 175 } 176 177 // ---- VERDICT (sealed): GREEN iff exactly the known answer ---- 178 var green: i64 = 1 179 if admitted != 1 { green = 0 } 180 if neg_reject != 1 { green = 0 } 181 if kat_exit != kat_expect { green = 0 } 182 183 let lfd: i64 = sys_openat_append("knowledge/status/spore_germ.log" as *u8, 0x1a4) 184 if lfd >= 0 { 185 germ_puts_fd(lfd, "SPOREGERM-GATE epoch=" as *u8); germ_putn_fd(lfd, sys_now_realtime_sec()) 186 germ_puts_fd(lfd, " piece=nx_exit42 bytes=" as *u8); germ_putn_fd(lfd, n) 187 germ_puts_fd(lfd, " expect_hash=" as *u8); germ_puthex_fd(lfd, expect_hash) 188 germ_puts_fd(lfd, " pos_integrity=1 germ_rc=" as *u8); germ_putn_fd(lfd, build_rc) 189 germ_puts_fd(lfd, " kat_expect=" as *u8); germ_putn_fd(lfd, kat_expect) 190 germ_puts_fd(lfd, " admitted=" as *u8); germ_putn_fd(lfd, admitted) 191 germ_puts_fd(lfd, " neg_integrity_reject=" as *u8); germ_putn_fd(lfd, neg_reject) 192 if green == 1 { germ_puts_fd(lfd, " verdict=GREEN\n" as *u8) } else { germ_puts_fd(lfd, " verdict=RED\n" as *u8) } 193 sys_close(lfd) 194 } 195 196 germ_puts("----------------------------------------------------------------\n" as *u8) 197 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 198 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 199 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 200 let ctr__dry: *i64 = gv_ctr() 201 ctr__dry[0] = green 202 ctr__dry[1] = 1 203 let rc__dry: i64 = gv_verdict("SPORE-GERM-GATE" as *u8, ctr__dry, "a content-addressed piece germinated and proved out;" as *u8) 204 sys_exit(rc__dry) 205 return rc__dry 206}