code wiki / _hdl_build / _drv_f2_gate.nx
_drv_f2_gate.nx source
↩ module page · 211 lines · 13069 B
1// _drv_f2_gate.nx -- gate for the FEDERATED DRIVER REGISTRY (X-DRV-F2). NO mocks.
2//
3// Proves the NETWORK EFFECT with real measurement + real signatures:
4// (0) MEASURE -- emit+run the two candidate configs (lean, verbose) on the sovereign emu and
5// read their REAL emu-steps (lean < verbose). No fabricated perf -- the reports carry these.
6// (1) SIGN -- build TWO nodes' signed reports (node A: verbose; node B: lean), each ed25519-signed
7// with that node's own identity key (genuine, 2 distinct nodes).
8// (2) NETWORK EFFECT -- run nx_fed_registry on node A ALONE -> winner = verbose (its only data);
9// run on A+B -> winner = lean. Assert two_node_winner_steps < one_node_winner_steps: the
10// registry is MEASURABLY improved by the SECOND node's data (the winner flows back).
11// (3) FLOW-BACK -- the 2-node winner config, re-run on the emu, achieves the registry's claimed
12// steps (the recommendation really delivers; report perf == reality).
13// (4) POISON-REJECTION -- a report with a BAD signature claiming steps=1 (would win if accepted)
14// is REJECTED -> the winner stays lean, NOT the poison. Only consenting, authentic data
15// refines the registry (you cannot poison it with unsigned reports).
16//
17// Evidence -> knowledge/status/fed_registry.log (DRVF2GATE row). Sovereign. license_tier: ORIGINAL
18import "nx_syscalls.nx"
19import "nx_ed25519_signature.nx"
20
21const F_EMIT: *u8 = "_offc/nx_drv_proto_emit.elf"
22const F_SOV: *u8 = "_offc/nx_boot_run_sov.elf"
23const F_FED: *u8 = "_offc/nx_fed_registry.elf"
24const F_FEDOUT: *u8 = "knowledge/registry/driver_registry_federated.tsv"
25const LEAN_SPEC: *u8 = "knowledge/specs/drv_proto_nndp_lean.spec"
26const VERB_SPEC: *u8 = "knowledge/specs/drv_proto_nndp_verbose.spec"
27const LEAN_BIN: *u8 = "runtime/_hdl_build/_drv_proto_nndp_lean.bin"
28const VERB_BIN: *u8 = "runtime/_hdl_build/_drv_proto_nndp_verbose.bin"
29
30func g_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
31func g_fp(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 }
32func g_fn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 }
33
34func g_run1(prog: *u8, a1: *u8, outpath: *u8) -> i64 {
35 let pid: i64 = sys_fork()
36 if pid == 0 {
37 if outpath != (0 as *u8) { let ofd: i64 = sys_openat_wr(outpath, 0x1a4); if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } }
38 let argv: *i64 = sys_mmap(32) as *i64
39 argv[0] = prog as i64
40 var k: i64 = 1
41 if a1 != (0 as *u8) { argv[k] = a1 as i64; k = k + 1 }
42 argv[k] = 0
43 let envp: *i64 = sys_mmap(16) as *i64
44 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0
45 sys_execve(prog, argv, envp)
46 sys_exit(127)
47 }
48 let st: *i64 = sys_mmap(16) as *i64
49 sys_wait4(pid, st, 0)
50 let sg: i64 = st[0] & 0x7f
51 if sg != 0 { return 128 + sg }
52 return (st[0] >> 8) & 0xff
53}
54
55func g_read(path: *u8, buf: *u8, cap: i64) -> i64 {
56 let fd: i64 = sys_openat_rd(path)
57 if fd < 0 { return 0 }
58 var n: i64 = 0
59 var go: i64 = 1
60 while go == 1 { let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - 1 - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap - 1 { go = 0 } }
61 sys_close(fd)
62 return n
63}
64
65// parse integer after the first "steps=" in buf; -1 if absent.
66func g_parse_steps(buf: *u8, n: i64) -> i64 {
67 var i: i64 = 0
68 while i + 6 <= n {
69 if buf[i]==(115 as u8) { if buf[i+1]==(116 as u8) { if buf[i+2]==(101 as u8) { if buf[i+3]==(112 as u8) { if buf[i+4]==(115 as u8) { if buf[i+5]==(61 as u8) {
70 var p: i64 = i + 6; var v: i64 = 0; var any: i64 = 0
71 while p < n { let c: i64 = buf[p] as i64; if c>=48 { if c<=57 { v=v*10+(c-48); any=1; p=p+1 } else { p=n } } else { p=n } }
72 if any == 1 { return v }
73 return 0 - 1
74 }}}}}}
75 i = i + 1
76 }
77 return 0 - 1
78}
79
80// emit a config spec + run on emu; return steps (-1 on fail).
81func g_measure(spec: *u8, bin: *u8, serial: *u8) -> i64 {
82 if g_run1(F_EMIT, spec, "/tmp/_f2_emit.out" as *u8) != 0 { return 0 - 1 }
83 g_run1(F_SOV, bin, serial)
84 let sb: *u8 = sys_mmap(65536)
85 let sn: i64 = g_read(serial, sb, 65536)
86 return g_parse_steps(sb, sn)
87}
88
89func g_hex(src: *u8, n: i64, dst: *u8) -> i64 {
90 var i: i64 = 0
91 while i < n { let b: i64 = src[i] as i64; let hi: i64 = (b>>4)&0xf; let lo: i64 = b&0xf; if hi<10 { dst[i*2]=(48+hi) as u8 } else { dst[i*2]=(87+hi) as u8 } if lo<10 { dst[i*2+1]=(48+lo) as u8 } else { dst[i*2+1]=(87+lo) as u8 } i=i+1 }
92 dst[n*2] = 0 as u8
93 return n*2
94}
95func g_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i }
96func g_catn(dst: *u8, off: i64, v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{dst[off+i]=t[k-1-i];i=i+1}; return off+k }
97
98// build a signed report line into out: "deviceid\tconfig\tsteps\tpubhex\tsighex\n"; return length.
99// payload signed = "fedreport deviceid=<id> config=<cfg> steps=<n>". corrupt!=0 flips a sig char.
100func g_report(out: *u8, did: i64, cfg: *u8, steps: i64, priv: *u8, pub: *u8, corrupt: i64) -> i64 {
101 let payload: *u8 = sys_mmap(2048)
102 var po: i64 = 0
103 po = g_cat(payload, po, "fedreport deviceid=" as *u8); po = g_catn(payload, po, did)
104 po = g_cat(payload, po, " config=" as *u8); po = g_cat(payload, po, cfg)
105 po = g_cat(payload, po, " steps=" as *u8); po = g_catn(payload, po, steps)
106 let sig: *u8 = sys_mmap(64)
107 ed25519_sign_full(priv, payload, po, sig)
108 let sighex: *u8 = sys_mmap(160); g_hex(sig, 64, sighex)
109 if corrupt != 0 { if sighex[0] == (97 as u8) { sighex[0] = 98 as u8 } else { sighex[0] = 97 as u8 } } // flip first sig hex char
110 let pubhex: *u8 = sys_mmap(80); g_hex(pub, 32, pubhex)
111 var o: i64 = 0
112 o = g_catn(out, o, did); out[o]=9 as u8; o=o+1
113 o = g_cat(out, o, cfg); out[o]=9 as u8; o=o+1
114 o = g_catn(out, o, steps); out[o]=9 as u8; o=o+1
115 o = g_cat(out, o, pubhex); out[o]=9 as u8; o=o+1
116 o = g_cat(out, o, sighex); out[o]=10 as u8; o=o+1
117 return o
118}
119
120func g_write(path: *u8, buf: *u8, n: i64) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd<0 { return 0-1 } sys_write(fd, buf, n); sys_close(fd); return 0 }
121
122// run fed_registry on inbox; parse winner steps for deviceid 2 from the federated registry (field 2 of the "2\t..." line).
123func g_fed_winner(inbox: *u8) -> i64 {
124 g_run1(F_FED, inbox, "/tmp/_f2_fed.out" as *u8)
125 let fb: *u8 = sys_mmap(65536)
126 let fn: i64 = g_read(F_FEDOUT, fb, 65536)
127 // find a line starting with "2\t", parse the 3rd tab-field (steps).
128 var i: i64 = 0
129 while i < fn {
130 var at_line: i64 = 0
131 if i == 0 { at_line = 1 } else { if fb[i-1] == (10 as u8) { at_line = 1 } }
132 if at_line == 1 { if i+2 <= fn { if fb[i] == (50 as u8) { if fb[i+1] == (9 as u8) {
133 // field0 = "2", advance past 2 tabs to field2
134 var p: i64 = i; var tabs: i64 = 0
135 while p < fn { if fb[p] == (10 as u8) { p = fn } else { if fb[p] == (9 as u8) { tabs = tabs + 1; if tabs == 2 { p = p + 1; var v: i64 = 0; var any: i64 = 0; while p < fn { let c: i64 = fb[p] as i64; if c>=48 { if c<=57 { v=v*10+(c-48); any=1; p=p+1 } else { p=fn } } else { p=fn } } if any==1 { return v } return 0-1 } else { p = p + 1 } } else { p = p + 1 } } }
136 }}}}
137 i = i + 1
138 }
139 return 0 - 1
140}
141
142func g_count(buf: *u8, n: i64, pat: *u8) -> i64 { var pl: i64=0; while pat[pl]!=(0 as u8){pl=pl+1} var c: i64=0; var i: i64=0; while i+pl<=n { var k: i64=0; var hit: i64=1; while k<pl { if buf[i+k]!=pat[k]{hit=0;k=pl}else{k=k+1} } if hit==1 {c=c+1;i=i+pl} else {i=i+1} } return c }
143
144func main() -> i64 {
145 g_p("=== federated driver registry gate (X-DRV-F2: network-effect, signed, poison-rejecting) ===\n" as *u8)
146 let lfd: i64 = sys_openat_append("knowledge/status/fed_registry.log" as *u8, 0x1a4)
147
148 // (0) MEASURE both configs' real emu steps.
149 let lean_steps: i64 = g_measure(LEAN_SPEC, LEAN_BIN, "/tmp/_f2_lean.txt" as *u8)
150 let verb_steps: i64 = g_measure(VERB_SPEC, VERB_BIN, "/tmp/_f2_verb.txt" as *u8)
151 var measured_ok: i64 = 0
152 if lean_steps > 0 { if verb_steps > lean_steps { measured_ok = 1 } }
153
154 // node identity keys (2 distinct nodes); derive pubs.
155 let privA: *u8 = sys_mmap(32); let privB: *u8 = sys_mmap(32)
156 let sA: *u8 = "NISHI-NODE-IDENTITY-TEST-SEED-01" as *u8
157 let sB: *u8 = "NISHI-NODE-IDENTITY-TEST-SEED-02" as *u8
158 var i: i64 = 0; while i < 32 { privA[i] = sA[i]; privB[i] = sB[i]; i = i + 1 }
159 let pubA: *u8 = sys_mmap(32); let pubB: *u8 = sys_mmap(32)
160 ed25519_pub_from_priv(privA, pubA); ed25519_pub_from_priv(privB, pubB)
161
162 // (1) SIGN node reports.
163 let lineA: *u8 = sys_mmap(1024); let la: i64 = g_report(lineA, 2, VERB_SPEC, verb_steps, privA, pubA, 0) // node A: verbose
164 let lineB: *u8 = sys_mmap(1024); let lb: i64 = g_report(lineB, 2, LEAN_SPEC, lean_steps, privB, pubB, 0) // node B: lean
165 let lineP: *u8 = sys_mmap(1024); let lp: i64 = g_report(lineP, 2, "knowledge/specs/POISON.spec" as *u8, 1, privA, pubA, 1) // BAD sig, steps=1
166
167 // (2) NETWORK EFFECT: 1-node (A only) vs 2-node (A+B).
168 let inbox: *u8 = sys_mmap(4096)
169 var o: i64 = 0
170 o = 0; var k: i64=0; while k<la { inbox[o]=lineA[k]; o=o+1; k=k+1 }
171 g_write("/tmp/_f2_inbox1.tsv" as *u8, inbox, o)
172 let winner_1: i64 = g_fed_winner("/tmp/_f2_inbox1.tsv" as *u8)
173
174 o = 0; k=0; while k<la { inbox[o]=lineA[k]; o=o+1; k=k+1 } k=0; while k<lb { inbox[o]=lineB[k]; o=o+1; k=k+1 }
175 g_write("/tmp/_f2_inbox2.tsv" as *u8, inbox, o)
176 let winner_2: i64 = g_fed_winner("/tmp/_f2_inbox2.tsv" as *u8)
177
178 var network_effect: i64 = 0
179 if winner_1 == verb_steps { if winner_2 == lean_steps { if winner_2 < winner_1 { network_effect = 1 } } }
180
181 // (3) FLOW-BACK: the winner (lean) re-run achieves the registry's claimed steps.
182 let flowback: i64 = g_measure(LEAN_SPEC, LEAN_BIN, "/tmp/_f2_flow.txt" as *u8)
183 var flowback_ok: i64 = 0
184 if flowback == winner_2 { flowback_ok = 1 }
185
186 // (4) POISON-REJECTION: A + B + poison(bad sig, steps=1). Poison must be rejected; winner stays lean.
187 o = 0; k=0; while k<la { inbox[o]=lineA[k]; o=o+1; k=k+1 } k=0; while k<lb { inbox[o]=lineB[k]; o=o+1; k=k+1 } k=0; while k<lp { inbox[o]=lineP[k]; o=o+1; k=k+1 }
188 g_write("/tmp/_f2_inbox3.tsv" as *u8, inbox, o)
189 let winner_p: i64 = g_fed_winner("/tmp/_f2_inbox3.tsv" as *u8)
190 let fedout: *u8 = sys_mmap(8192); let fn: i64 = g_read("/tmp/_f2_fed.out" as *u8, fedout, 8192)
191 let rejected_seen: i64 = g_count(fedout, fn, "REJECTED" as *u8)
192 var poison_rejected: i64 = 0
193 if winner_p == lean_steps { if rejected_seen >= 1 { poison_rejected = 1 } } // poison(1) NOT selected, was rejected
194
195 g_p(" measured: lean=" as *u8); g_fn(1, lean_steps); g_p(" verbose=" as *u8); g_fn(1, verb_steps)
196 g_p(" | winner_1node=" as *u8); g_fn(1, winner_1); g_p(" winner_2node=" as *u8); g_fn(1, winner_2)
197 g_p(" | network_effect=" as *u8); g_fn(1, network_effect); g_p(" flowback=" as *u8); g_fn(1, flowback_ok); g_p(" poison_rejected=" as *u8); g_fn(1, poison_rejected); g_p("\n" as *u8)
198
199 var pass: i64 = 0
200 if measured_ok == 1 { if network_effect == 1 { if flowback_ok == 1 { if poison_rejected == 1 { pass = 1 } } } }
201
202 if pass == 1 {
203 g_p("DRVF2GATE verdict=GREEN (federated registry: node A alone -> winner verbose " as *u8); g_fn(1, winner_1); g_p(" steps; A+B -> winner lean " as *u8); g_fn(1, winner_2); g_p(" steps = MEASURABLY improved by the 2nd node's data [network effect]; winner re-run delivers the claimed steps [flow-back]; a BAD-signature poison report claiming steps=1 is REJECTED [only consenting authentic data refines the registry])\n" as *u8)
204 if lfd >= 0 { g_fp(lfd, "DRVF2GATE verdict=GREEN keystone=federated-registry-network-effect winner_1node=" as *u8); g_fn(lfd, winner_1); g_fp(lfd, " winner_2node=" as *u8); g_fn(lfd, winner_2); g_fp(lfd, " improved-by-2nd-node=yes flowback=verified poison-rejected=yes epoch=" as *u8); g_fn(lfd, sys_now_realtime_sec()); g_fp(lfd, "\n" as *u8); sys_close(lfd) }
205 sys_exit(0); return 0
206 }
207 g_p("DRVF2GATE verdict=RED (measured/network-effect/flowback/poison not all green)\n" as *u8)
208 if lfd >= 0 { g_fp(lfd, "DRVF2GATE verdict=RED measured=" as *u8); g_fn(lfd, measured_ok); g_fp(lfd, " net=" as *u8); g_fn(lfd, network_effect); g_fp(lfd, " flow=" as *u8); g_fn(lfd, flowback_ok); g_fp(lfd, " poison=" as *u8); g_fn(lfd, poison_rejected); g_fp(lfd, " w1=" as *u8); g_fn(lfd, winner_1); g_fp(lfd, " w2=" as *u8); g_fn(lfd, winner_2); g_fp(lfd, "\n" as *u8); sys_close(lfd) }
209 sys_exit(1)
210 return 1
211}