nx_writer_run.nx source
↩ module page · 234 lines · 11619 B
1// nx_writer_run.nx -- WRITING arc, rung W-RUN-2: the UNIFYING file-driven runner.
2// One tool, every mode. Reads the chosen mode + the mode registry, ENFORCES the
3// seam (refuses if the registry routes an explicit mode off the local lane),
4// resolves register/lane/structure, and dispatches to the right organ -- emitting
5// the structured artifact the generation SEAT then expands (SFW=tutor seat,
6// explicit=operator local-LLM seat; this tool authors no prose, per the seam).
7//
8// Does NOT touch the existing nx_write_run (its scene-ingestion path is unchanged).
9// Staging: knowledge/staging/writer/{mode,scenario,manga,voice,draft}.txt ;
10// registry SSOT: knowledge/registry/write_modes.tsv . Build+run:
11// ./_offc/nx_sov_build_run.elf nx_writer_run
12//
13// license_tier: ORIGINAL
14// module: nishi-core.write.writerrun
15// depends: nishi-core.write.mode/scenario/manga/tone
16// capability: WRITE_RUN_UNIFIED
17import "nx_syscalls_x86_64.nx"
18import "nx_mode.nx"
19import "nx_scenario.nx"
20import "nx_manga.nx"
21import "nx_tone.nx"
22import "nx_campaign.nx"
23const K_MAGIC_1024: i64 = 1024
24
25func wstr(outfd: i64, s: *u8) -> i64 {
26 var n: i64 = 0
27 while s[n] != (0 as u8) { n = n + 1 }
28 sys_write(1, s, n)
29 if outfd > 0 { sys_write(outfd, s, n) }
30 return 0
31}
32func wnum(outfd: i64, v: i64) -> i64 {
33 var m: i64 = v
34 if m < 0 { wstr(outfd, "-\x00" as *u8); m = 0 - m }
35 let bb: *u8 = sys_mmap(32)
36 let t: *u8 = sys_mmap(32)
37 var k: i64 = 0
38 if m == 0 { t[0] = 48 as u8; k = 1 }
39 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
40 var i: i64 = 0
41 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
42 bb[k] = 0 as u8
43 wstr(outfd, bb)
44 return 0
45}
46// null-terminate buf at the first newline; return length
47func wr_firstline(buf: *u8, n: i64) -> i64 {
48 var i: i64 = 0
49 var done: i64 = 0
50 while i < n {
51 if done == 0 {
52 if buf[i] == (10 as u8) { buf[i] = 0 as u8; done = 1 }
53 else { if buf[i] == (13 as u8) { buf[i] = 0 as u8; done = 1 } else { i = i + 1 } }
54 } else { i = n }
55 }
56 if done == 0 { buf[n] = 0 as u8 }
57 var ln: i64 = 0
58 while buf[ln] != (0 as u8) { ln = ln + 1 }
59 return ln
60}
61
62func wr_do_scenario(outfd: i64, lanb: *u8) -> i64 {
63 let lenp: *i64 = sys_mmap(16) as *i64
64 let sb: *u8 = sys_read_file("knowledge/staging/writer/scenario.txt\x00" as *u8, lenp)
65 if sb == (0 as *u8) { wstr(outfd, " (provide scenario.txt: kind/setting/roles/goal lines)\n\x00" as *u8); return 0 }
66 let sn: i64 = lenp[0]
67 let miss: i64 = sc_validate(sb, sn)
68 if miss > 0 { wstr(outfd, " REJECT incomplete scenario; required fields missing: \x00" as *u8); wnum(outfd, miss); wstr(outfd, "\n\x00" as *u8); return 0 }
69 let brief: *u8 = sys_mmap(K_MAGIC_1024)
70 sc_emit_brief(sb, sn, brief, K_MAGIC_1024)
71 wstr(outfd, " BRIEF: \x00" as *u8); wstr(outfd, brief)
72 wstr(outfd, "\n -> hand to the \x00" as *u8); wstr(outfd, lanb); wstr(outfd, " seat to expand into prose.\n\x00" as *u8)
73 return 0
74}
75
76func wr_do_convo(outfd: i64, lanb: *u8) -> i64 {
77 let lenp: *i64 = sys_mmap(16) as *i64
78 let sb: *u8 = sys_read_file("knowledge/staging/writer/scenario.txt\x00" as *u8, lenp)
79 if sb == (0 as *u8) { wstr(outfd, " (provide scenario.txt as the situation to practise)\n\x00" as *u8); return 0 }
80 let sn: i64 = lenp[0]
81 if sc_validate(sb, sn) > 0 { wstr(outfd, " REJECT incomplete situation\n\x00" as *u8); return 0 }
82 let brief: *u8 = sys_mmap(K_MAGIC_1024)
83 sc_emit_brief(sb, sn, brief, K_MAGIC_1024)
84 wstr(outfd, " SITUATION: \x00" as *u8); wstr(outfd, brief)
85 wstr(outfd, "\n -> \x00" as *u8); wstr(outfd, lanb)
86 wstr(outfd, " seat keeps topics going (nx_convo cv_next_topic) + scores attempts respect-gated (cv_rubric).\n\x00" as *u8)
87 return 0
88}
89
90func wr_do_manga(outfd: i64, lanb: *u8) -> i64 {
91 let lenp: *i64 = sys_mmap(16) as *i64
92 let mb: *u8 = sys_read_file("knowledge/staging/writer/manga.txt\x00" as *u8, lenp)
93 if mb == (0 as *u8) { wstr(outfd, " (provide manga.txt: PAGE/PANEL + shot/char/say/sfx/caption)\n\x00" as *u8); return 0 }
94 let mn: i64 = lenp[0]
95 wstr(outfd, " pages: \x00" as *u8); wnum(outfd, mg_count_pages(mb, mn))
96 wstr(outfd, " panels: \x00" as *u8); wnum(outfd, mg_count_panels(mb, mn))
97 wstr(outfd, " missing-shot: \x00" as *u8); wnum(outfd, mg_validate(mb, mn)); wstr(outfd, "\n\x00" as *u8)
98 let pr: *u8 = sys_mmap(512)
99 mg_emit_panel_prompt(mb, mn, 0, pr, 512)
100 wstr(outfd, " panel-0 img: \x00" as *u8); wstr(outfd, pr)
101 wstr(outfd, "\n -> image-gen + \x00" as *u8); wstr(outfd, lanb); wstr(outfd, " seat for dialogue.\n\x00" as *u8)
102 return 0
103}
104
105func wr_do_campaign(outfd: i64, lanb: *u8) -> i64 {
106 let lenp: *i64 = sys_mmap(16) as *i64
107 let cb: *u8 = sys_read_file("knowledge/staging/writer/campaign.txt\x00" as *u8, lenp)
108 if cb == (0 as *u8) { wstr(outfd, " (provide campaign.txt: setting/party/quest header, then SESSION / ENCOUNTER blocks)\n\x00" as *u8); return 0 }
109 let cn: i64 = lenp[0]
110 let miss: i64 = cg_validate(cb, cn)
111 wstr(outfd, " sessions: \x00" as *u8); wnum(outfd, cg_count_sessions(cb, cn))
112 wstr(outfd, " encounters: \x00" as *u8); wnum(outfd, cg_count_encounters(cb, cn))
113 wstr(outfd, " missing-required: \x00" as *u8); wnum(outfd, miss); wstr(outfd, "\n\x00" as *u8)
114 if miss > 0 { wstr(outfd, " REJECT: a GM cannot run an encounter without kind+goal (and the header needs setting/party/quest)\n\x00" as *u8); return 0 }
115 let sa: *u8 = sys_mmap(512)
116 let sb2: *u8 = sys_mmap(512)
117 wstr(outfd, " CONTINUITY time-regressions: \x00" as *u8); wnum(outfd, cg_time_check(cb, cn))
118 wstr(outfd, " teleports: \x00" as *u8); wnum(outfd, cg_transit_check(cb, cn, sa, sb2, 512)); wstr(outfd, "\n\x00" as *u8)
119 let bufb: *u8 = sys_mmap(K_MAGIC_1024)
120 let ne: i64 = cg_count_encounters(cb, cn)
121 var k: i64 = 0
122 while k < ne {
123 cg_emit_brief(cb, cn, k, bufb, K_MAGIC_1024)
124 wstr(outfd, " [\x00" as *u8); wnum(outfd, k); wstr(outfd, "] \x00" as *u8); wstr(outfd, bufb); wstr(outfd, "\n\x00" as *u8)
125 cg_emit_img(cb, cn, k, bufb, K_MAGIC_1024)
126 wstr(outfd, " IMG: \x00" as *u8); wstr(outfd, bufb); wstr(outfd, "\n\x00" as *u8)
127 k = k + 1
128 }
129 wstr(outfd, " -> hand each brief to the \x00" as *u8); wstr(outfd, lanb)
130 wstr(outfd, " seat to run at the table; IMG lines feed the same image-gen path.\n\x00" as *u8)
131 return 0
132}
133
134func wr_do_tone(outfd: i64, lanb: *u8) -> i64 {
135 let lenp: *i64 = sys_mmap(16) as *i64
136 let vb: *u8 = sys_read_file("knowledge/staging/writer/voice.txt\x00" as *u8, lenp)
137 if vb == (0 as *u8) { wstr(outfd, " (provide voice.txt: a sample of your own writing)\n\x00" as *u8); return 0 }
138 let vn: i64 = lenp[0]
139 let sc: *i64 = sys_mmap(64) as *i64
140 let tfV: *i64 = sys_mmap(128) as *i64
141 tn_fingerprint(vb, vn, tfV, sc)
142 wstr(outfd, " voice fingerprinted (cadence dim0=\x00" as *u8); wnum(outfd, tfV[0]); wstr(outfd, ")\n\x00" as *u8)
143 let lenp2: *i64 = sys_mmap(16) as *i64
144 let db: *u8 = sys_read_file("knowledge/staging/writer/draft.txt\x00" as *u8, lenp2)
145 if db == (0 as *u8) { wstr(outfd, " (add draft.txt to score a draft against your voice)\n\x00" as *u8); return 0 }
146 let dn: i64 = lenp2[0]
147 let tfD: *i64 = sys_mmap(128) as *i64
148 tn_fingerprint(db, dn, tfD, sc)
149 let wun: *i64 = sys_mmap(128) as *i64
150 var wi: i64 = 0
151 while wi < TN_DIMS { wun[wi] = 1000; wi = wi + 1 }
152 let drf: *i64 = sys_mmap(128) as *i64
153 let dist: i64 = tn_drift(tfD, tfV, wun, TN_DIMS, drf)
154 wstr(outfd, " draft voice-distance: \x00" as *u8); wnum(outfd, dist); wstr(outfd, "\n\x00" as *u8)
155 var bi: i64 = 0
156 var bv: i64 = 0
157 var di: i64 = 0
158 while di < TN_DIMS {
159 var a: i64 = drf[di]
160 if a < 0 { a = 0 - a }
161 if a > bv { bv = a; bi = di }
162 di = di + 1
163 }
164 wstr(outfd, " largest drift on dim \x00" as *u8); wnum(outfd, bi)
165 wstr(outfd, " (signed \x00" as *u8); wnum(outfd, drf[bi]); wstr(outfd, ")\n -> \x00" as *u8); wstr(outfd, lanb)
166 wstr(outfd, " seat: steer that dim toward 0 to match your voice.\n\x00" as *u8)
167 return 0
168}
169
170func main() -> i64 {
171 let lenp: *i64 = sys_mmap(16) as *i64
172 let modeb: *u8 = sys_read_file("knowledge/staging/writer/mode.txt\x00" as *u8, lenp)
173 if modeb == (0 as *u8) {
174 wstr(0, "no mode.txt -- put one of correspondence/manga/erotica/paper/scenario/language/social in knowledge/staging/writer/mode.txt\n\x00" as *u8)
175 sys_exit(0); return 0
176 }
177 wr_firstline(modeb, lenp[0])
178
179 let regb: *u8 = sys_read_file("knowledge/registry/write_modes.tsv\x00" as *u8, lenp)
180 if regb == (0 as *u8) { wstr(0, "no write_modes.tsv registry\n\x00" as *u8); sys_exit(1); return 1 }
181 let rn: i64 = lenp[0]
182
183 let outfd: i64 = sys_openat_wr("knowledge/staging/writer/out.txt\x00" as *u8, 0x1a4)
184 let scratch: *u8 = sys_mmap(256)
185
186 wstr(outfd, "== nishi-writer ==\nmode: \x00" as *u8); wstr(outfd, modeb); wstr(outfd, "\n\x00" as *u8)
187
188 // GOVERNANCE: the seam audit is a HARD gate
189 let viol: i64 = md_seam_audit(regb, rn, scratch, 256)
190 wstr(outfd, "seam-audit violations: \x00" as *u8); wnum(outfd, viol); wstr(outfd, "\n\x00" as *u8)
191 if viol > 0 {
192 wstr(outfd, "REFUSE: registry routes an explicit mode to a non-local lane (seam violation)\n\x00" as *u8)
193 if outfd > 0 { sys_close(outfd) }
194 sys_exit(2); return 2
195 }
196
197 let lanb: *u8 = sys_mmap(64)
198 let rgb: *u8 = sys_mmap(64)
199 let stb: *u8 = sys_mmap(64)
200 if md_lane(regb, rn, modeb, lanb, 64) < 0 {
201 wstr(outfd, "unknown mode (not in write_modes.tsv)\n\x00" as *u8)
202 if outfd > 0 { sys_close(outfd) }
203 sys_exit(0); return 0
204 }
205 md_register(regb, rn, modeb, rgb, 64)
206 md_structure(regb, rn, modeb, stb, 64)
207 wstr(outfd, "register: \x00" as *u8); wstr(outfd, rgb)
208 wstr(outfd, " lane: \x00" as *u8); wstr(outfd, lanb)
209 wstr(outfd, " structure: \x00" as *u8); wstr(outfd, stb); wstr(outfd, "\n\x00" as *u8)
210
211 var handled: i64 = 0
212 if md_streq(stb, "scenario\x00" as *u8) == 1 { wr_do_scenario(outfd, lanb); handled = 1 }
213 if md_streq(stb, "convo\x00" as *u8) == 1 { wr_do_convo(outfd, lanb); handled = 1 }
214 if md_streq(stb, "panel\x00" as *u8) == 1 { wr_do_manga(outfd, lanb); handled = 1 }
215 if md_streq(stb, "tone\x00" as *u8) == 1 { wr_do_tone(outfd, lanb); handled = 1 }
216 if md_streq(stb, "campaign\x00" as *u8) == 1 { wr_do_campaign(outfd, lanb); handled = 1 }
217 if md_streq(stb, "dialogue\x00" as *u8) == 1 {
218 wstr(outfd, " turn-resolved roleplay -> nx_dialogue: per-turn intensity, four-cell tally, unprompted-explicit\n\x00" as *u8)
219 wstr(outfd, " and honoured-decline rates, first-explicit-turn index and escalation slope. Lexicon stays operator DATA.\n\x00" as *u8)
220 handled = 1
221 }
222 if md_streq(stb, "scene\x00" as *u8) == 1 {
223 wstr(outfd, " register=explicit -> routed to the LOCAL seat (operator hardware). Engine structures via nx_ingest/nx_register (nx_write_run); Claude authors no explicit prose.\n\x00" as *u8)
224 handled = 1
225 }
226 if md_streq(stb, "imrad\x00" as *u8) == 1 {
227 wstr(outfd, " paper structure -> use nx_cite for references; hand the outline to the \x00" as *u8); wstr(outfd, lanb); wstr(outfd, " seat.\n\x00" as *u8)
228 handled = 1
229 }
230 if handled == 0 { wstr(outfd, " structure not yet dispatched; hand the DATA to the seat.\n\x00" as *u8) }
231
232 if outfd > 0 { sys_close(outfd) }
233 sys_exit(0); return 0
234}