code wiki / _hdl_build / nx_seat_drive_gate.nx
nx_seat_drive_gate.nx source
↩ module page · 217 lines · 9225 B
1// nx_seat_drive_gate.nx -- GATE for the S2 seat-protocol driver (6 teeth, 3 negative controls).
2// PREREQ: stage the elfs first (banked /tmp-wipe + fork-budget laws):
3// nx_sov_build_run nx_seat_drive / nx_fix_ok / nx_fix_fail -> cp /tmp/<n>.sov.elf _offc/<n>.elf
4// Run from nxc2 root. SELF-EXEC CHAIN (one driver fork per process, counters ride argv --
5// the proven WSL fork-budget pattern): argv = [self] [stage] [pass].
6// Teeth: T1 happy e2e (DONE frame + both artifacts) | T2 NEG work-fail refused | T3 NEG lane-gate
7// RED refused | T4 NEG checkin refused fail-closed (work never ran) | T5 NEG artifact-lie refused
8// (rc0 work without its declared artifact) | T6 journal is append-only across reruns (DONE x2).
9// Verdict: NX-SEAT-DRIVE-GATE pass=N/6 verdict=GREEN|RED (exit 0 iff 6/6).
10// license_tier: ORIGINAL No hw writes (Rule 26).
11import "nx_seg_store.nx"
12import "nx_deploy_lib.nx"
13import "nx_syscalls.nx"
14
15const SG_JCAP: i64 = 65536
16
17func sg_w(s: *u8) -> i64 {
18 var n: i64 = 0
19 while s[n] != (0 as u8) { n = n + 1 }
20 sys_write(1, s, n)
21 return 0
22}
23
24func sg_len(s: *u8) -> i64 {
25 var n: i64 = 0
26 while s[n] != (0 as u8) { n = n + 1 }
27 return n
28}
29
30func sg_atoi(s: *u8) -> i64 {
31 var v: i64 = 0
32 var i: i64 = 0
33 while s[i] != (0 as u8) {
34 let c: i64 = s[i] as i64
35 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } }
36 i = i + 1
37 }
38 return v
39}
40
41func sg_itoa(dst: *u8, v: i64) -> i64 {
42 var m: i64 = v
43 let t: *u8 = sys_mmap(24)
44 var k: i64 = 0
45 if m == 0 { t[0] = 48 as u8; k = 1 }
46 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
47 var i: i64 = 0
48 while i < k { dst[i] = t[k - 1 - i]; i = i + 1 }
49 dst[k] = 0 as u8
50 return k
51}
52
53func sg_count(buf: *u8, n: i64, needle: *u8) -> i64 {
54 var cnt: i64 = 0
55 var p: i64 = 0
56 while p < n {
57 var ki: i64 = 0
58 var hit: i64 = 1
59 var scanning: i64 = 1
60 while scanning == 1 {
61 let kc: i64 = needle[ki] as i64
62 if kc == 0 { scanning = 0 } else {
63 var bc: i64 = 0
64 if p + ki < n { bc = buf[p + ki] as i64 }
65 if bc == kc { ki = ki + 1 } else { hit = 0; scanning = 0 }
66 }
67 }
68 if hit == 1 { cnt = cnt + 1 }
69 p = p + 1
70 }
71 return cnt
72}
73
74// journal-frame count: reads path fresh each call, one fixed callee chain
75func sg_jcount(path: *u8, needle: *u8) -> i64 {
76 let buf: *u8 = sys_mmap(SG_JCAP)
77 let n: i64 = dp_read(path, buf, SG_JCAP)
78 return sg_count(buf, n, needle)
79}
80
81// non-empty file probe (artifact-truth): 1 iff path exists with >0 bytes
82func sg_nonempty(path: *u8) -> i64 {
83 let buf: *u8 = sys_mmap(64)
84 let n: i64 = dp_read(path, buf, 32)
85 if n > 0 { return 1 }
86 return 0
87}
88
89// run the driver on a lane file; returns driver exit code (-1 on signal death)
90func sg_drive(lanep: *u8, outp: *u8) -> i64 {
91 let av: *i64 = sys_mmap(32) as *i64
92 av[0] = lanep as i64
93 return dep_run_capture("_offc/nx_seat_drive.elf" as *u8, av, 1, outp)
94}
95
96func main(argc: i64, argv: *i64) -> i64 {
97 var stage: i64 = 1
98 var pass: i64 = 0
99 if argc >= 2 { let ss: *u8 = argv[1] as *u8; stage = sg_atoi(ss) }
100 if argc >= 3 { let ps: *u8 = argv[2] as *u8; pass = sg_atoi(ps) }
101 if stage < 1 { stage = 1 }
102
103 if stage == 1 {
104 sys_unlinkat("/tmp/sdg_t1.jrnl" as *u8)
105 sys_unlinkat("/tmp/sdg_t1.marker" as *u8)
106 sys_unlinkat("/tmp/sdg_t1.gmarker" as *u8)
107 let lane: *u8 = "ws=sdg-t1\nactor=gatefix\njournal=/tmp/sdg_t1.jrnl\nworkelf=_offc/nx_fix_ok.elf\nworkarg1=/tmp/sdg_t1.marker\nworkartifact=/tmp/sdg_t1.marker\ngateelf=_offc/nx_fix_ok.elf\ngatearg1=/tmp/sdg_t1.gmarker\n" as *u8
108 ss_writefile("/tmp/sdg_t1.lane" as *u8, lane, sg_len(lane))
109 let rc: i64 = sg_drive("/tmp/sdg_t1.lane" as *u8, "/tmp/sdg_t1.out" as *u8)
110 let done: i64 = sg_jcount("/tmp/sdg_t1.jrnl" as *u8, "DONE" as *u8)
111 let ma: i64 = sg_nonempty("/tmp/sdg_t1.marker" as *u8)
112 let ga: i64 = sg_nonempty("/tmp/sdg_t1.gmarker" as *u8)
113 var ok: i64 = 1
114 if rc != 0 { ok = 0 }
115 if done != 1 { ok = 0 }
116 if ma != 1 { ok = 0 }
117 if ga != 1 { ok = 0 }
118 if ok == 1 { sg_w("T1 happy-e2e PASS\n" as *u8); pass = pass + 1 } else { sg_w("T1 happy-e2e FAIL\n" as *u8) }
119 }
120 if stage == 2 {
121 sys_unlinkat("/tmp/sdg_t2.jrnl" as *u8)
122 sys_unlinkat("/tmp/sdg_t2.marker" as *u8)
123 let lane: *u8 = "ws=sdg-t2\nactor=gatefix\njournal=/tmp/sdg_t2.jrnl\nworkelf=_offc/nx_fix_fail.elf\nworkarg1=/tmp/sdg_t2.marker\nworkartifact=/tmp/sdg_t2.marker\ngateelf=_offc/nx_fix_ok.elf\n" as *u8
124 ss_writefile("/tmp/sdg_t2.lane" as *u8, lane, sg_len(lane))
125 let rc: i64 = sg_drive("/tmp/sdg_t2.lane" as *u8, "/tmp/sdg_t2.out" as *u8)
126 let wf: i64 = sg_jcount("/tmp/sdg_t2.jrnl" as *u8, "WORKFAIL" as *u8)
127 let done: i64 = sg_jcount("/tmp/sdg_t2.jrnl" as *u8, "DONE" as *u8)
128 var ok: i64 = 1
129 if rc != 4 { ok = 0 }
130 if wf != 1 { ok = 0 }
131 if done != 0 { ok = 0 }
132 if ok == 1 { sg_w("T2 neg-workfail PASS\n" as *u8); pass = pass + 1 } else { sg_w("T2 neg-workfail FAIL\n" as *u8) }
133 }
134 if stage == 3 {
135 sys_unlinkat("/tmp/sdg_t3.jrnl" as *u8)
136 sys_unlinkat("/tmp/sdg_t3.marker" as *u8)
137 let lane: *u8 = "ws=sdg-t3\nactor=gatefix\njournal=/tmp/sdg_t3.jrnl\nworkelf=_offc/nx_fix_ok.elf\nworkarg1=/tmp/sdg_t3.marker\nworkartifact=/tmp/sdg_t3.marker\ngateelf=_offc/nx_fix_fail.elf\n" as *u8
138 ss_writefile("/tmp/sdg_t3.lane" as *u8, lane, sg_len(lane))
139 let rc: i64 = sg_drive("/tmp/sdg_t3.lane" as *u8, "/tmp/sdg_t3.out" as *u8)
140 let gr: i64 = sg_jcount("/tmp/sdg_t3.jrnl" as *u8, "GATERED" as *u8)
141 let done: i64 = sg_jcount("/tmp/sdg_t3.jrnl" as *u8, "DONE" as *u8)
142 var ok: i64 = 1
143 if rc != 5 { ok = 0 }
144 if gr != 1 { ok = 0 }
145 if done != 0 { ok = 0 }
146 if ok == 1 { sg_w("T3 neg-gatered PASS\n" as *u8); pass = pass + 1 } else { sg_w("T3 neg-gatered FAIL\n" as *u8) }
147 }
148 if stage == 4 {
149 sys_unlinkat("/tmp/sdg_t4.jrnl" as *u8)
150 sys_unlinkat("/tmp/sdg_t4.marker" as *u8)
151 let lane: *u8 = "ws=sdg-t4\nactor=gatefix\njournal=/tmp/sdg_t4.jrnl\nworkelf=_offc/nx_fix_ok.elf\nworkarg1=/tmp/sdg_t4.marker\nworkartifact=/tmp/sdg_t4.marker\ngateelf=_offc/nx_fix_ok.elf\ncheckinelf=_offc/nx_fix_fail.elf\n" as *u8
152 ss_writefile("/tmp/sdg_t4.lane" as *u8, lane, sg_len(lane))
153 let rc: i64 = sg_drive("/tmp/sdg_t4.lane" as *u8, "/tmp/sdg_t4.out" as *u8)
154 let cr: i64 = sg_jcount("/tmp/sdg_t4.jrnl" as *u8, "CHECKIN-REFUSED" as *u8)
155 let ma: i64 = sg_nonempty("/tmp/sdg_t4.marker" as *u8)
156 var ok: i64 = 1
157 if rc != 3 { ok = 0 }
158 if cr != 1 { ok = 0 }
159 if ma != 0 { ok = 0 }
160 if ok == 1 { sg_w("T4 neg-checkin-failclosed PASS\n" as *u8); pass = pass + 1 } else { sg_w("T4 neg-checkin-failclosed FAIL\n" as *u8) }
161 }
162 if stage == 5 {
163 sys_unlinkat("/tmp/sdg_t5.jrnl" as *u8)
164 sys_unlinkat("/tmp/sdg_t5.marker" as *u8)
165 sys_unlinkat("/tmp/sdg_t5.other" as *u8)
166 let lane: *u8 = "ws=sdg-t5\nactor=gatefix\njournal=/tmp/sdg_t5.jrnl\nworkelf=_offc/nx_fix_ok.elf\nworkarg1=/tmp/sdg_t5.other\nworkartifact=/tmp/sdg_t5.marker\ngateelf=_offc/nx_fix_ok.elf\n" as *u8
167 ss_writefile("/tmp/sdg_t5.lane" as *u8, lane, sg_len(lane))
168 let rc: i64 = sg_drive("/tmp/sdg_t5.lane" as *u8, "/tmp/sdg_t5.out" as *u8)
169 let na: i64 = sg_jcount("/tmp/sdg_t5.jrnl" as *u8, "NOARTIFACT" as *u8)
170 var ok: i64 = 1
171 if rc != 6 { ok = 0 }
172 if na != 1 { ok = 0 }
173 if ok == 1 { sg_w("T5 neg-artifact-lie PASS\n" as *u8); pass = pass + 1 } else { sg_w("T5 neg-artifact-lie FAIL\n" as *u8) }
174 }
175 if stage == 6 {
176 // NO cleanup -- T6 proves the journal is append-only across reruns of the T1 lane
177 let rc: i64 = sg_drive("/tmp/sdg_t1.lane" as *u8, "/tmp/sdg_t6.out" as *u8)
178 let done: i64 = sg_jcount("/tmp/sdg_t1.jrnl" as *u8, "DONE" as *u8)
179 var ok: i64 = 1
180 if rc != 0 { ok = 0 }
181 if done != 2 { ok = 0 }
182 if ok == 1 { sg_w("T6 journal-append-only PASS\n" as *u8); pass = pass + 1 } else { sg_w("T6 journal-append-only FAIL\n" as *u8) }
183 }
184
185 if stage >= 6 {
186 sg_w("NX-SEAT-DRIVE-GATE pass=" as *u8)
187 let pb: *u8 = sys_mmap(24)
188 sg_itoa(pb, pass)
189 sg_w(pb)
190 if pass == 6 {
191 sg_w("/6 verdict=GREEN\n" as *u8)
192 sys_exit(0)
193 return 0
194 }
195 sg_w("/6 verdict=RED\n" as *u8)
196 sys_exit(1)
197 return 1
198 }
199
200 // SELF-EXEC CHAIN: one driver fork per process; counters ride argv
201 let self: *u8 = argv[0] as *u8
202 let sb: *u8 = sys_mmap(24)
203 sg_itoa(sb, stage + 1)
204 let pb2: *u8 = sys_mmap(24)
205 sg_itoa(pb2, pass)
206 let nav: *i64 = sys_mmap(40) as *i64
207 nav[0] = self as i64
208 nav[1] = sb as i64
209 nav[2] = pb2 as i64
210 nav[3] = 0
211 let envp: *i64 = sys_mmap(16) as *i64
212 envp[0] = 0
213 sys_execve(self, nav, envp)
214 sg_w("SDG-EXEC-FAIL\n" as *u8)
215 sys_exit(1)
216 return 1
217}