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}