code wiki / _hdl_build / nx_seat_drive.nx
nx_seat_drive.nx source
↩ module page · 188 lines · 8152 B
1// nx_seat_drive.nx -- S2 SEAT-PROTOCOL DRIVER (agent-seat system, 2026-07-20).
2// Runs the seat lifecycle around a lane-configured work step so a NON-CLAUDE seat
3// (local maker ensemble, cron, any executor) closes rungs through the same protocol
4// and gates as a Claude seat: CHECKIN -> WORK -> VERIFY(gate) -> CHECKOUT, with an
5// append-only journal (fa_appendz, torn-proof) as the resume/standup surface.
6// Single responsibility: the PROTOCOL. The work itself, its success gate, and the
7// hub verbs are all LANE CONFIG DATA (no magic behavior, rule 11/22).
8//
9// argv: <lanefile>
10// lanefile = KEY=VALUE lines (LF). Required: ws= actor= journal= workelf= workartifact= gateelf=
11// Optional: workarg1..workarg3, gatearg1..gatearg2, checkinelf= checkinarg1=, checkoutelf= checkoutarg1=
12// Hub-verb convention: checkin/checkout elfs are invoked as <elf> [argN] <ws> <actor>
13// so a live wrapper (nx_seat checkin over tools/call) and a fixture both fit.
14//
15// ARTIFACT-TRUTH (banked law): the work step is judged by its DECLARED artifact
16// (workartifact unlinked before the run, must exist non-empty after), not only by
17// wait4 status. A work step that "succeeds" without producing its artifact is REFUSED.
18//
19// exit: 0 OK | 2 config | 3 checkin-refused (fail-closed) | 4 work-fail | 5 gate-RED
20// 6 artifact-missing | 7 checkout-fail
21// license_tier: ORIGINAL No hw writes (Rule 26).
22import "nx_seat_drive_lib.nx"
23import "nx_seg_store.nx"
24import "nx_deploy_lib.nx"
25import "nx_framed_append.nx"
26import "nx_syscalls.nx"
27const SD_MAGIC_1048576: i64 = 1048576
28
29const SD_CONF_CAP: i64 = 65536
30const SD_REC_CAP: i64 = 2048
31
32// journal one frame: "SEATD <ws> <actor> <tag>[ rc=<rc>]" (rc skipped when rcflag==0)
33func sd_frame(journal: *u8, ws: *u8, actor: *u8, tag: *u8, rcflag: i64, rc: i64) -> i64 {
34 let rec: *u8 = sys_mmap(SD_REC_CAP)
35 var o: i64 = 0
36 o = sd_cat(rec, o, "SEATD " as *u8)
37 o = sd_cat(rec, o, ws)
38 o = sd_cat(rec, o, " " as *u8)
39 o = sd_cat(rec, o, actor)
40 o = sd_cat(rec, o, " " as *u8)
41 o = sd_cat(rec, o, tag)
42 if rcflag == 1 {
43 o = sd_cat(rec, o, " rc=" as *u8)
44 o = sd_num(rec, o, rc)
45 }
46 let arc: i64 = fa_appendz(journal, rec, SD_REC_CAP)
47 sys_write(1, rec, o)
48 sys_write(1, "\n" as *u8, 1)
49 return arc
50}
51
52func main(argc: i64, argv: *i64) -> i64 {
53 if argc < 2 { sd_w("usage: nx_seat_drive <lanefile>\n" as *u8); sys_exit(2); return 2 }
54 let lanep: *u8 = argv[1] as *u8
55 let conf: *u8 = sys_mmap(SD_CONF_CAP)
56 let cn: i64 = dp_read(lanep, conf, SD_CONF_CAP)
57 if cn <= 0 { sd_w("SEATD-CONFIG-MISSING\n" as *u8); sys_exit(2); return 2 }
58
59 let ws: *u8 = sd_val(conf, cn, "ws=" as *u8)
60 let actor: *u8 = sd_val(conf, cn, "actor=" as *u8)
61 let journal: *u8 = sd_val(conf, cn, "journal=" as *u8)
62 let workelf: *u8 = sd_val(conf, cn, "workelf=" as *u8)
63 let workart: *u8 = sd_val(conf, cn, "workartifact=" as *u8)
64 let gateelf: *u8 = sd_val(conf, cn, "gateelf=" as *u8)
65 if (ws as i64) == 0 { sd_w("SEATD-CONFIG-BAD missing=ws\n" as *u8); sys_exit(2); return 2 }
66 if (actor as i64) == 0 { sd_w("SEATD-CONFIG-BAD missing=actor\n" as *u8); sys_exit(2); return 2 }
67 if (journal as i64) == 0 { sd_w("SEATD-CONFIG-BAD missing=journal\n" as *u8); sys_exit(2); return 2 }
68 if (workelf as i64) == 0 { sd_w("SEATD-CONFIG-BAD missing=workelf\n" as *u8); sys_exit(2); return 2 }
69 if (workart as i64) == 0 { sd_w("SEATD-CONFIG-BAD missing=workartifact\n" as *u8); sys_exit(2); return 2 }
70 if (gateelf as i64) == 0 { sd_w("SEATD-CONFIG-BAD missing=gateelf\n" as *u8); sys_exit(2); return 2 }
71
72 let wa1: *u8 = sd_val(conf, cn, "workarg1=" as *u8)
73 let wa2: *u8 = sd_val(conf, cn, "workarg2=" as *u8)
74 let wa3: *u8 = sd_val(conf, cn, "workarg3=" as *u8)
75 let ga1: *u8 = sd_val(conf, cn, "gatearg1=" as *u8)
76 let ga2: *u8 = sd_val(conf, cn, "gatearg2=" as *u8)
77 let cielf: *u8 = sd_val(conf, cn, "checkinelf=" as *u8)
78 let cia1: *u8 = sd_val(conf, cn, "checkinarg1=" as *u8)
79 let coelf: *u8 = sd_val(conf, cn, "checkoutelf=" as *u8)
80 let coa1: *u8 = sd_val(conf, cn, "checkoutarg1=" as *u8)
81
82 // capture files ride next to the journal (declared, not hidden /tmp state)
83 let wout: *u8 = sys_mmap(SD_VAL_CAP)
84 var wo: i64 = 0
85 wo = sd_cat(wout, 0, journal)
86 wo = sd_cat(wout, wo, ".work.out" as *u8)
87 let gout: *u8 = sys_mmap(SD_VAL_CAP)
88 var go: i64 = 0
89 go = sd_cat(gout, 0, journal)
90 go = sd_cat(gout, go, ".gate.out" as *u8)
91 let hout: *u8 = sys_mmap(SD_VAL_CAP)
92 var ho: i64 = 0
93 ho = sd_cat(hout, 0, journal)
94 ho = sd_cat(hout, ho, ".hub.out" as *u8)
95
96 let arc0: i64 = sd_frame(journal, ws, actor, "KICKOFF" as *u8, 0, 0)
97 if arc0 < 0 { sd_w("SEATD-JOURNAL-FAIL\n" as *u8); sys_exit(2); return 2 }
98
99 // CHECKIN (optional, fail-closed: a refused claim means DO NOT WORK)
100 if (cielf as i64) != 0 {
101 let cav: *i64 = sys_mmap(64) as *i64
102 var cn2: i64 = 0
103 if (cia1 as i64) != 0 { cav[cn2] = cia1 as i64; cn2 = cn2 + 1 }
104 cav[cn2] = ws as i64
105 cn2 = cn2 + 1
106 cav[cn2] = actor as i64
107 cn2 = cn2 + 1
108 let rci: i64 = dep_run_capture(cielf, cav, cn2, hout)
109 if rci != 0 {
110 sd_frame(journal, ws, actor, "CHECKIN-REFUSED" as *u8, 1, rci)
111 sys_exit(3)
112 return 3
113 }
114 sd_frame(journal, ws, actor, "CHECKIN" as *u8, 1, rci)
115 }
116
117 // WORK -- artifact-truth: unlink the declared artifact first, require it after
118 sys_unlinkat(workart)
119 let wav: *i64 = sys_mmap(64) as *i64
120 var wn: i64 = 0
121 if (wa1 as i64) != 0 { wav[wn] = wa1 as i64; wn = wn + 1 }
122 if (wa2 as i64) != 0 { wav[wn] = wa2 as i64; wn = wn + 1 }
123 if (wa3 as i64) != 0 { wav[wn] = wa3 as i64; wn = wn + 1 }
124 let rcw: i64 = dep_run_capture(workelf, wav, wn, wout)
125 if rcw != 0 {
126 sd_frame(journal, ws, actor, "WORKFAIL" as *u8, 1, rcw)
127 sys_exit(4)
128 return 4
129 }
130 let abuf: *u8 = sys_mmap(64)
131 let an: i64 = dp_read(workart, abuf, 32)
132 if an <= 0 {
133 sd_frame(journal, ws, actor, "NOARTIFACT" as *u8, 0, 0)
134 sys_exit(6)
135 return 6
136 }
137 // EVIDENCE ARCHIVE (operator 2026-07-20 "needs evidence + a feedback loop keeping it honest"):
138 // the declared artifact may live in a VOLATILE home (/tmp wiped 6x today) -- copy it to a
139 // durable sibling of the journal BEFORE gating, so the lane gate/attestor and any later
140 // auditor read evidence that cannot vanish. Fail LOUD if the archive cannot be written.
141 let arcp: *u8 = sys_mmap(SD_VAL_CAP)
142 var ao: i64 = 0
143 ao = sd_cat(arcp, 0, journal)
144 ao = sd_cat(arcp, ao, ".artifact" as *u8)
145 let full: *u8 = sys_mmap(SD_MAGIC_1048576)
146 let fn2: i64 = dp_read(workart, full, SD_MAGIC_1048576)
147 var arc_rc: i64 = 0 - 1
148 if fn2 > 0 { arc_rc = ss_writefile(arcp, full, fn2) }
149 if arc_rc != 0 {
150 sd_frame(journal, ws, actor, "ARCHIVE-FAIL" as *u8, 1, arc_rc)
151 sys_exit(6)
152 return 6
153 }
154
155 // VERIFY -- the lane's own gate must be GREEN (exit 0)
156 let gav: *i64 = sys_mmap(64) as *i64
157 var gn: i64 = 0
158 if (ga1 as i64) != 0 { gav[gn] = ga1 as i64; gn = gn + 1 }
159 if (ga2 as i64) != 0 { gav[gn] = ga2 as i64; gn = gn + 1 }
160 let rcg: i64 = dep_run_capture(gateelf, gav, gn, gout)
161 if rcg != 0 {
162 sd_frame(journal, ws, actor, "GATERED" as *u8, 1, rcg)
163 sys_exit(5)
164 return 5
165 }
166
167 // CHECKOUT (optional; a failed release is LOUD, not swallowed)
168 if (coelf as i64) != 0 {
169 let oav: *i64 = sys_mmap(64) as *i64
170 var on: i64 = 0
171 if (coa1 as i64) != 0 { oav[on] = coa1 as i64; on = on + 1 }
172 oav[on] = ws as i64
173 on = on + 1
174 oav[on] = actor as i64
175 on = on + 1
176 let rco: i64 = dep_run_capture(coelf, oav, on, hout)
177 if rco != 0 {
178 sd_frame(journal, ws, actor, "CHECKOUT-FAIL" as *u8, 1, rco)
179 sys_exit(7)
180 return 7
181 }
182 }
183
184 sd_frame(journal, ws, actor, "DONE work_rc=0 gate_rc=0" as *u8, 0, 0)
185 sd_w("NX-SEAT-DRIVE OK\n" as *u8)
186 sys_exit(0)
187 return 0
188}