code wiki / (root) / nx_write_run.nx

nx_write_run.nx source

↩ module page · 238 lines · 10494 B

1// nx_write_run.nx -- WRITING arc: the FILE-DRIVEN RUNNER (the tool the operator 2// runs on a real story). It reads everything from knowledge/staging/write/: 3// story.txt the work (operator/lane content -- Claude never authors it) 4// roster.txt character bible, one name per line 5// descriptors.txt descriptor lexicon, one term per line (setting/outfit/mood/...) 6// register.txt "term weight" per line (intensity lexicon; optional) 7// gov.txt "threshold age consent locale" ints (optional; default 5 1 1 1) 8// and emits, per scene, the IMAGE-GEN prompt + COMPANION context, plus the register 9// route -> stdout AND knowledge/staging/write/out.txt. 10// 11// This keeps the seam intact: the operator drops their content + lexicons here and 12// runs the tool; the engine (all gated organs) does the structuring. Build+run: 13// ./_offc/nx_sov_build_run.elf nx_write_run 14// 15// license_tier: ORIGINAL 16// module: nishi-core.write.run 17// depends: nishi-core.write.parselex, nishi-core.write.emit, nishi-core.write.register 18// capability: WRITE_RUN_TOOL 19import "nx_syscalls_x86_64.nx" 20import "nx_parse_lex.nx" 21import "nx_emit.nx" 22import "nx_register.nx" 23import "nx_conflict.nx" 24 25const WR_MAXSC: i64 = 128 26 27// write a null-terminated string to stdout AND the out file 28func wstr(outfd: i64, s: *u8) -> i64 { 29 var n: i64 = 0 30 while s[n] != (0 as u8) { n = n + 1 } 31 sys_write(1, s, n) 32 if outfd > 0 { sys_write(outfd, s, n) } 33 return 0 34} 35// write a signed integer to stdout AND the out file 36func wnum(outfd: i64, v: i64) -> i64 { 37 var m: i64 = v 38 if m < 0 { wstr(outfd, "-\x00" as *u8); m = 0 - m } 39 let bb: *u8 = sys_mmap(32) 40 let t: *u8 = sys_mmap(32) 41 var k: i64 = 0 42 if m == 0 { t[0] = 48 as u8; k = 1 } 43 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 44 var i: i64 = 0 45 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 46 bb[k] = 0 as u8 47 wstr(outfd, bb) 48 return 0 49} 50// write a packed term (by index) to stdout + out file 51func wterm(outfd: i64, terms: *u8, idx: i64) -> i64 { 52 let off: i64 = ig_name_off(terms, idx) 53 var n: i64 = 0 54 while terms[off + n] != (0 as u8) { n = n + 1 } 55 sys_write(1, (terms as i64 + off) as *u8, n) 56 if outfd > 0 { sys_write(outfd, (terms as i64 + off) as *u8, n) } 57 return 0 58} 59// parse up to maxk whitespace-separated ints from raw[0..n) into out 60func parse_ints(raw: *u8, n: i64, out: *i64, maxk: i64) -> i64 { 61 var count: i64 = 0 62 var i: i64 = 0 63 while i < n { 64 var g: i64 = 1 65 while g == 1 { 66 if i < n { let c: i64 = raw[i] as i64; if c >= 48 { if c <= 57 { g = 0 } else { i = i + 1 } } else { i = i + 1 } } else { g = 0 } 67 } 68 if i < n { 69 var val: i64 = 0 70 var g2: i64 = 1 71 while g2 == 1 { 72 if i < n { let c: i64 = raw[i] as i64; if c >= 48 { if c <= 57 { val = val * 10 + (c - 48); i = i + 1 } else { g2 = 0 } } else { g2 = 0 } } else { g2 = 0 } 73 } 74 if count < maxk { out[count] = val; count = count + 1 } 75 } 76 } 77 return count 78} 79// null-terminate a buffer at the first newline; return the resulting length 80func first_line(buf: *u8, n: i64) -> i64 { 81 var i: i64 = 0 82 var done: i64 = 0 83 while i < n { 84 if done == 0 { 85 if buf[i] == (10 as u8) { buf[i] = 0 as u8; done = 1 } 86 else { if buf[i] == (13 as u8) { buf[i] = 0 as u8; done = 1 } else { i = i + 1 } } 87 } else { i = n } 88 } 89 if done == 0 { buf[n] = 0 as u8 } 90 var ln: i64 = 0 91 while buf[ln] != (0 as u8) { ln = ln + 1 } 92 return ln 93} 94 95func main() -> i64 { 96 let lenp: *i64 = sys_mmap(16) as *i64 97 let story: *u8 = sys_read_file_x86_64("knowledge/staging/write/story.txt\x00" as *u8, lenp) 98 if story == (0 as *u8) { 99 wstr(0, "no story.txt -- drop story.txt + roster.txt + descriptors.txt into knowledge/staging/write/\n\x00" as *u8) 100 sys_exit(0) 101 return 0 102 } 103 let n: i64 = lenp[0] 104 105 // roster (optional) 106 let roster: *u8 = sys_mmap(4096) 107 var nnames: i64 = 0 108 let rraw: *u8 = sys_read_file_x86_64("knowledge/staging/write/roster.txt\x00" as *u8, lenp) 109 if rraw != (0 as *u8) { nnames = px_pack_lines(rraw, lenp[0], roster, 4096) } 110 111 // descriptors (optional) 112 let dterms: *u8 = sys_mmap(8192) 113 var ndterms: i64 = 0 114 let draw: *u8 = sys_read_file_x86_64("knowledge/staging/write/descriptors.txt\x00" as *u8, lenp) 115 if draw != (0 as *u8) { ndterms = px_pack_lines(draw, lenp[0], dterms, 8192) } 116 117 // register lexicon (optional) 118 let rterms: *u8 = sys_mmap(8192) 119 let rweights: *i64 = sys_mmap(2048) as *i64 120 var nrt: i64 = 0 121 let rgraw: *u8 = sys_read_file_x86_64("knowledge/staging/write/register.txt\x00" as *u8, lenp) 122 if rgraw != (0 as *u8) { nrt = px_pack_weighted(rgraw, lenp[0], rterms, 8192, rweights) } 123 124 // conflict axes lexicon (optional): "term axis" per line (same axis = mutually exclusive) 125 let cfterms: *u8 = sys_mmap(8192) 126 let cfaxes: *i64 = sys_mmap(2048) as *i64 127 var ncf: i64 = 0 128 var naxes: i64 = 0 129 let craw: *u8 = sys_read_file_x86_64("knowledge/staging/write/conflicts.txt\x00" as *u8, lenp) 130 if craw != (0 as *u8) { 131 ncf = px_pack_weighted(craw, lenp[0], cfterms, 8192, cfaxes) 132 var ci0: i64 = 0 133 while ci0 < ncf { if cfaxes[ci0] + 1 > naxes { naxes = cfaxes[ci0] + 1 } ci0 = ci0 + 1 } 134 } 135 let cfout: *i64 = sys_mmap(8192) as *i64 136 137 // persistent attributes (cross-scene continuity): "term axis" per line 138 let pterms: *u8 = sys_mmap(8192) 139 let paxes: *i64 = sys_mmap(2048) as *i64 140 var npt: i64 = 0 141 var pnaxes: i64 = 0 142 let praw: *u8 = sys_read_file_x86_64("knowledge/staging/write/persistent.txt\x00" as *u8, lenp) 143 if praw != (0 as *u8) { 144 npt = px_pack_weighted(praw, lenp[0], pterms, 8192, paxes) 145 var pi0: i64 = 0 146 while pi0 < npt { if paxes[pi0] + 1 > pnaxes { pnaxes = paxes[pi0] + 1 } pi0 = pi0 + 1 } 147 } 148 149 // governance (optional): threshold age consent locale ; defaults 5 1 1 1 150 var thr: i64 = 5 151 var age: i64 = 1 152 var consent: i64 = 1 153 var locale: i64 = 1 154 let gv: *i64 = sys_mmap(64) as *i64 155 let graw: *u8 = sys_read_file_x86_64("knowledge/staging/write/gov.txt\x00" as *u8, lenp) 156 if graw != (0 as *u8) { 157 let gc: i64 = parse_ints(graw, lenp[0], gv, 4) 158 if gc >= 1 { thr = gv[0] } 159 if gc >= 2 { age = gv[1] } 160 if gc >= 3 { consent = gv[2] } 161 if gc >= 4 { locale = gv[3] } 162 } 163 164 // style suffix + negative prompt (optional, single line each, operator DATA) 165 let styleb: *u8 = sys_read_file_x86_64("knowledge/staging/write/style.txt\x00" as *u8, lenp) 166 var has_style: i64 = 0 167 if styleb != (0 as *u8) { if first_line(styleb, lenp[0]) > 0 { has_style = 1 } } 168 let negb: *u8 = sys_read_file_x86_64("knowledge/staging/write/negative.txt\x00" as *u8, lenp) 169 var has_neg: i64 = 0 170 if negb != (0 as *u8) { if first_line(negb, lenp[0]) > 0 { has_neg = 1 } } 171 172 let stride: i64 = 5 + nnames 173 let scenes: *i64 = sys_mmap(WR_MAXSC * stride * 8) as *i64 174 let nsc: i64 = ig_extract(story, n, roster, nnames, scenes, WR_MAXSC) 175 176 let outfd: i64 = sys_openat_wr("knowledge/staging/write/out.txt\x00" as *u8, 0x1a4) 177 178 wstr(outfd, "== nishi-write analysis ==\n\x00" as *u8) 179 wstr(outfd, "scenes: \x00" as *u8); wnum(outfd, nsc); wstr(outfd, "\n\x00" as *u8) 180 var rscore: i64 = 0 181 if nrt > 0 { rscore = rg_score(story, 0, n, rterms, rweights, nrt) } 182 let route: i64 = rg_decision(rscore, thr, age, consent, locale) 183 wstr(outfd, "register score: \x00" as *u8); wnum(outfd, rscore) 184 wstr(outfd, " threshold: \x00" as *u8); wnum(outfd, thr) 185 wstr(outfd, " route: \x00" as *u8); wnum(outfd, route) 186 wstr(outfd, " (0=SFW-lane 1=EXPLICIT-lane 2=REFUSE)\n\n\x00" as *u8) 187 188 let dst: *u8 = sys_mmap(2048) 189 var k: i64 = 0 190 while k < nsc { 191 let base: i64 = k * stride 192 let a: i64 = scenes[base] 193 let b: i64 = scenes[base + 1] 194 let focus: i64 = scenes[base + 3] 195 wstr(outfd, "SCENE \x00" as *u8); wnum(outfd, k); wstr(outfd, "\n\x00" as *u8) 196 em_image_prompt_focus(story, a, b, roster, nnames, focus, dterms, ndterms, dst) 197 wstr(outfd, " IMG: \x00" as *u8); wstr(outfd, dst) 198 if has_style == 1 { wstr(outfd, ", \x00" as *u8); wstr(outfd, styleb) } 199 wstr(outfd, "\n\x00" as *u8) 200 if has_neg == 1 { wstr(outfd, " NEG: \x00" as *u8); wstr(outfd, negb); wstr(outfd, "\n\x00" as *u8) } 201 em_companion_ctx(story, a, b, roster, nnames, dterms, ndterms, dst) 202 wstr(outfd, " CTX: \x00" as *u8); wstr(outfd, dst); wstr(outfd, "\n\x00" as *u8) 203 if naxes > 0 { 204 let nc: i64 = cf_detect_owned(story, scenes[base], scenes[base + 1], roster, nnames, cfterms, cfaxes, ncf, naxes, cfout) 205 var ci: i64 = 0 206 while ci < nc { 207 wstr(outfd, " CONFLICT [\x00" as *u8); wterm(outfd, roster, cfout[ci * 4 + 0]) 208 wstr(outfd, ", axis \x00" as *u8); wnum(outfd, cfout[ci * 4 + 1]); wstr(outfd, "]: \x00" as *u8) 209 wterm(outfd, cfterms, cfout[ci * 4 + 2]); wstr(outfd, " <-> \x00" as *u8); wterm(outfd, cfterms, cfout[ci * 4 + 3]) 210 wstr(outfd, "\n\x00" as *u8) 211 ci = ci + 1 212 } 213 if nc == 0 { wstr(outfd, " conflicts: none\n\x00" as *u8) } 214 } 215 wstr(outfd, "\n\x00" as *u8) 216 k = k + 1 217 } 218 219 if pnaxes > 0 { 220 wstr(outfd, "-- continuity (whole-story persistent attributes, per character) --\n\x00" as *u8) 221 let pc: i64 = cf_detect_owned(story, 0, n, roster, nnames, pterms, paxes, npt, pnaxes, cfout) 222 var pj: i64 = 0 223 while pj < pc { 224 wstr(outfd, " CONTINUITY [\x00" as *u8); wterm(outfd, roster, cfout[pj * 4 + 0]) 225 wstr(outfd, ", axis \x00" as *u8); wnum(outfd, cfout[pj * 4 + 1]); wstr(outfd, "]: \x00" as *u8) 226 wterm(outfd, pterms, cfout[pj * 4 + 2]); wstr(outfd, " <-> \x00" as *u8); wterm(outfd, pterms, cfout[pj * 4 + 3]) 227 wstr(outfd, " (changes across story)\n\x00" as *u8) 228 pj = pj + 1 229 } 230 if pc == 0 { wstr(outfd, " continuity: consistent\n\x00" as *u8) } 231 wstr(outfd, "\n\x00" as *u8) 232 } 233 234 wstr(outfd, "-- end (also written to knowledge/staging/write/out.txt) --\n\x00" as *u8) 235 if outfd > 0 { sys_close(outfd) } 236 sys_exit(0) 237 return 0 238}