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}