code wiki / (root) / nx_companion_mind.nx

nx_companion_mind.nx source

↩ module page · 258 lines · 11965 B

1// nx_companion_mind.nx -- THE MIND CONTEXT (companionchat CC0, 2026-08-30): ONE composer that puts the companion's 2// LONG-TERM MEMORY (nx_elara_memory recall), RELATIONSHIP STATE (nx_charmem ctx) and TYPED PRESENT-TENSE STATE 3// (nx_elara_state context) into the chat turn's system prompt. 4// FOUND BY IMPORT-LIST MEASUREMENT: nx_gen_orchestrator carried persona, wardrobe and the affect vector and NEVER 5// consulted these three PROMOTED organs, so the intelligence was built and dark. This lib COMPOSES them by forking 6// the serving-root binaries (the nx_companion_sota idiom) -- it re-implements none of them -- and it FABRICATES 7// NOTHING: an empty store contributes zero bytes, an unset present is never narrated as a fact, a wedged organ costs 8// the turn at most MIND_FORK_TIMEOUT_MS and then contributes nothing. 9// Contract symbol: go_mind_context (the companionchat.matrix CC0 watch), measured in the orchestrator that calls it. 10// Gate: nx_gen_mind_gate (fixture sessions under /tmp, positive + neg-control-empty-session teeth). 11// CC3 (2026-08-30): the LOREBOOK plane rides the same composer -- em_lorebook (nx_lorebook.nx, in-process, no fork) injects 12// keyed world facts only when the turn touches a trigger; a budget refusal is logged to stderr and contributes ZERO bytes. 13// license_tier: ORIGINAL 14import "nx_syscalls.nx" 15import "nx_tool_run.nx" 16import "nx_lorebook.nx" 17 18const MIND_ELF_MEM: *u8 = "/volume1/homes/elderwesto/nishihost/nx_elara_memory.elf" as *u8 19const MIND_ELF_CHAR: *u8 = "/volume1/homes/elderwesto/nishihost/nx_charmem.elf" as *u8 20const MIND_ELF_STATE: *u8 = "/volume1/homes/elderwesto/nishihost/nx_elara_state.elf" as *u8 21// one organ's stdout: cm_ctx bounds itself to CM_BUF and em_recall to 64 KiB, so 64 KiB is the organs' own ceiling, not a guess 22const MIND_CAP: i64 = 65536 23// a wedged organ may cost the turn at most this. The chat dispatch budget is 180 s; three forks at 4 s stay under 7 percent of it. 24const MIND_FORK_TIMEOUT_MS: i64 = 4000 25// top-k salience hits per turn -- em_recall's own default, passed explicitly so the contract is visible here 26const MIND_RECALL_MAX: *u8 = "5" as *u8 27// DATA: which session/char key the daemon speaks for (first [a-z0-9_] run of the file); default when absent 28const MIND_SESSION_FILE: *u8 = "elara_session.txt" as *u8 29const MIND_SESSION_DEFAULT: *u8 = "elara" as *u8 30// nx_charmem refuses names over 32 [a-z0-9_]; the same bound here so a refusal never surprises the caller 31const MIND_SESSION_CAP: i64 = 32 32// the user turn is passed to recall/remember as ONE argv element; bounded so a pasted novel cannot exceed an argv limit 33const MIND_QUERY_CAP: i64 = 512 34const MIND_BLOCK_CAP: i64 = 4096 35const MIND_CH_QUOTE: i64 = 34 36const MIND_CH_BSLASH: i64 = 92 37const MIND_CH_NL: i64 = 10 38const MIND_CH_SPACE: i64 = 32 39const MIND_CH_LOWER_N: i64 = 110 40const MIND_FD_STDERR: i64 = 2 41const MIND_I64_BYTES: i64 = 8 42 43func mind_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 44func mind_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } 45 46// first index of needle in buf[from..n) or -1. Uses a flag to exit, never the cursor (nx_srclint idiom). 47func mind_find(buf: *u8, n: i64, from: i64, needle: *u8) -> i64 { 48 let nl: i64 = mind_len(needle) 49 if nl <= 0 { return 0 - 1 } 50 var i: i64 = from 51 if i < 0 { i = 0 } 52 while i + nl <= n { 53 var j: i64 = 0 54 var same: i64 = 1 55 var scan: i64 = 1 56 while scan == 1 { 57 if j >= nl { scan = 0 } else { 58 if buf[i + j] != needle[j] { same = 0; scan = 0 } else { j = j + 1 } 59 } 60 } 61 if same == 1 { return i } 62 i = i + 1 63 } 64 return 0 - 1 65} 66 67// fork one serving-root organ with up to 4 args, bounded capture, bounded time. Returns bytes captured (0 on any failure). 68func mind_run(elf: *u8, nargs: i64, a1: *u8, a2: *u8, a3: *u8, a4: *u8, out: *u8) -> i64 { 69 let argv: *i64 = sys_mmap(64) as *i64 70 argv[0] = elf as i64 71 if nargs >= 1 { argv[1] = a1 as i64 } 72 if nargs >= 2 { argv[2] = a2 as i64 } 73 if nargs >= 3 { argv[3] = a3 as i64 } 74 if nargs >= 4 { argv[4] = a4 as i64 } 75 argv[nargs + 1] = 0 76 let olen: *i64 = sys_mmap(16) as *i64 77 olen[0] = 0 78 tr_run_capture_to(elf, argv, out, MIND_CAP - 1, olen, MIND_FORK_TIMEOUT_MS) 79 var n: i64 = olen[0] 80 if n < 0 { n = 0 } 81 if n > MIND_CAP - 1 { n = MIND_CAP - 1 } 82 out[n] = 0 as u8 83 return n 84} 85 86// the session key: first [a-z0-9_] run of MIND_SESSION_FILE (relative to the daemon's cwd), else the default. 87func mind_session(out: *u8) -> i64 { 88 let lp: *i64 = sys_mmap(16) as *i64 89 lp[0] = 0 90 let b: *u8 = sys_read_file(MIND_SESSION_FILE, lp) 91 var o: i64 = 0 92 if (b as i64) != 0 { 93 var i: i64 = 0 94 var scan: i64 = 1 95 while scan == 1 { 96 if i >= lp[0] { scan = 0 } else { if o >= MIND_SESSION_CAP { scan = 0 } else { 97 let c: i64 = b[i] as i64 98 var ok: i64 = 0 99 if c >= 97 { if c <= 122 { ok = 1 } } 100 if c >= 48 { if c <= 57 { ok = 1 } } 101 if c == 95 { ok = 1 } 102 if ok == 1 { out[o] = c as u8; o = o + 1; i = i + 1 } else { scan = 0 } 103 } } 104 } 105 } 106 if o == 0 { o = mind_cat(out, 0, MIND_SESSION_DEFAULT) } 107 out[o] = 0 as u8 108 return o 109} 110 111// bounded, control-char-free copy of the user turn for argv use 112func mind_query(umsg: *u8, umlen: i64, q: *u8) -> i64 { 113 var n: i64 = umlen 114 if n > MIND_QUERY_CAP { n = MIND_QUERY_CAP } 115 var i: i64 = 0 116 while i < n { let c: i64 = umsg[i] as i64; if c < MIND_CH_SPACE { q[i] = MIND_CH_SPACE as u8 } else { q[i] = c as u8 } i = i + 1 } 117 q[n] = 0 as u8 118 return n 119} 120 121// copy the JSON string value that follows `key` (the full lead-in, e.g. "narrative":") from body[from..n). 122// Returns chars copied; endpos[0] = index just past the closing quote for iteration, or -1 when the key is absent. 123func mind_jstr(body: *u8, blen: i64, from: i64, key: *u8, out: *u8, cap: i64, endpos: *i64) -> i64 { 124 endpos[0] = 0 - 1 125 let p: i64 = mind_find(body, blen, from, key) 126 if p < 0 { out[0] = 0 as u8; return 0 } 127 var i: i64 = p + mind_len(key) 128 var o: i64 = 0 129 var scan: i64 = 1 130 while scan == 1 { 131 if i >= blen { scan = 0 } else { 132 let c: i64 = body[i] as i64 133 if c == MIND_CH_QUOTE { scan = 0 } else { 134 if c == MIND_CH_BSLASH { 135 i = i + 1 136 if i < blen { 137 let e: i64 = body[i] as i64 138 if o < cap - 1 { if e == MIND_CH_LOWER_N { out[o] = MIND_CH_SPACE as u8 } else { out[o] = e as u8 } o = o + 1 } 139 } 140 } else { 141 if o < cap - 1 { out[o] = c as u8; o = o + 1 } 142 } 143 i = i + 1 144 } 145 } 146 } 147 endpos[0] = i + 1 148 out[o] = 0 as u8 149 return o 150} 151 152// [PRESENT] -- the typed present-tense narrative from nx_elara_state. An UNSET present is not a present: defaults are 153// never narrated as facts (the neg-control-empty-session tooth pins this). 154func mind_state_block(session: *u8, out: *u8, cap: i64) -> i64 { 155 let buf: *u8 = sys_mmap(MIND_CAP) 156 let n: i64 = mind_run(MIND_ELF_STATE, 2, "context" as *u8, session, 0 as *u8, 0 as *u8, buf) 157 if n <= 0 { return 0 } 158 let nar: *u8 = sys_mmap(MIND_BLOCK_CAP) 159 let ep: *i64 = sys_mmap(16) as *i64 160 let nl: i64 = mind_jstr(buf, n, 0, "\"narrative\":\"" as *u8, nar, MIND_BLOCK_CAP, ep) 161 if nl <= 0 { return 0 } 162 if mind_find(nar, nl, 0, "unset" as *u8) >= 0 { return 0 } 163 if nl + 128 >= cap { return 0 } 164 var o: i64 = 0 165 o = mind_cat(out, o, "[PRESENT -- your body, place and mood right now; stay consistent with it]\n" as *u8) 166 o = mind_cat(out, o, nar) 167 o = mind_cat(out, o, "\n" as *u8) 168 return o 169} 170 171// [RELATIONSHIP STATE] + facts + shared memories, verbatim from nx_charmem ctx (it already speaks prompt). 172func mind_rel_block(session: *u8, out: *u8, cap: i64) -> i64 { 173 let buf: *u8 = sys_mmap(MIND_CAP) 174 let n: i64 = mind_run(MIND_ELF_CHAR, 2, "ctx" as *u8, session, 0 as *u8, 0 as *u8, buf) 175 if n <= 0 { return 0 } 176 if mind_find(buf, n, 0, "[RELATIONSHIP STATE]" as *u8) != 0 { return 0 } 177 if n + 2 >= cap { return 0 } 178 var o: i64 = 0 179 var i: i64 = 0 180 while i < n { out[o] = buf[i]; o = o + 1; i = i + 1 } 181 if out[o - 1] != (MIND_CH_NL as u8) { out[o] = MIND_CH_NL as u8; o = o + 1 } 182 return o 183} 184 185// [REMEMBERED] -- salience-ranked recall of what they told her before, keyed on THIS turn's words. Zero hits = zero bytes. 186func mind_mem_block(session: *u8, umsg: *u8, umlen: i64, out: *u8, cap: i64) -> i64 { 187 if umlen <= 0 { return 0 } 188 let q: *u8 = sys_mmap(MIND_QUERY_CAP + 8) 189 mind_query(umsg, umlen, q) 190 let buf: *u8 = sys_mmap(MIND_CAP) 191 let n: i64 = mind_run(MIND_ELF_MEM, 4, "recall" as *u8, session, q, MIND_RECALL_MAX, buf) 192 if n <= 0 { return 0 } 193 if mind_find(buf, n, 0, "\"hits\":0," as *u8) >= 0 { return 0 } 194 let txt: *u8 = sys_mmap(MIND_BLOCK_CAP) 195 let ep: *i64 = sys_mmap(16) as *i64 196 var o: i64 = 0 197 var emitted: i64 = 0 198 var from: i64 = 0 199 var scan: i64 = 1 200 while scan == 1 { 201 let tl: i64 = mind_jstr(buf, n, from, "\"text\":\"" as *u8, txt, MIND_BLOCK_CAP, ep) 202 if ep[0] < 0 { scan = 0 } else { 203 from = ep[0] 204 if tl > 0 { 205 if o + tl + 128 >= cap { scan = 0 } else { 206 if emitted == 0 { o = mind_cat(out, o, "[REMEMBERED -- things they told you before; use the exact detail, never an invented variant]\n" as *u8) } 207 o = mind_cat(out, o, "- " as *u8) 208 o = mind_cat(out, o, txt) 209 o = mind_cat(out, o, "\n" as *u8) 210 emitted = emitted + 1 211 } 212 } 213 } 214 } 215 return o 216} 217 218// [WORLD] -- lorebook entries this turn touched (CC3, em_lorebook). A budget refusal is written to stderr and contributes 219// zero bytes: the model never reads half a fact, and the daemon log says why nothing was injected. 220func mind_world_block(umsg: *u8, umlen: i64, out: *u8, cap: i64) -> i64 { 221 if umlen <= 0 { return 0 } 222 let stats: *i64 = sys_mmap(LB_STATS_N * MIND_I64_BYTES) as *i64 223 let n: i64 = em_lorebook(umsg, umlen, out, cap, stats) 224 if stats[LB_ST_REFUSED] == 1 { 225 if n > 0 { sys_write(MIND_FD_STDERR, out, n) } 226 out[0] = 0 as u8 227 return 0 228 } 229 return n 230} 231 232// THE CONTRACT. Composes present + relationship + world + remembered into out (NUL-terminated), returns bytes written. 233// Order is deliberate: what she IS now, who they ARE to each other, what the WORLD they touched holds, then what they SAID before. 234func go_mind_context(umsg: *u8, umlen: i64, out: *u8, cap: i64) -> i64 { 235 if cap < 256 { out[0] = 0 as u8; return 0 } 236 let session: *u8 = sys_mmap(64) 237 mind_session(session) 238 var o: i64 = 0 239 o = o + mind_state_block(session, ((out as i64) + o) as *u8, cap - o - 1) 240 o = o + mind_rel_block(session, ((out as i64) + o) as *u8, cap - o - 1) 241 o = o + mind_world_block(umsg, umlen, ((out as i64) + o) as *u8, cap - o - 1) 242 o = o + mind_mem_block(session, umsg, umlen, ((out as i64) + o) as *u8, cap - o - 1) 243 out[o] = 0 as u8 244 return o 245} 246 247// the write half: the user's turn enters long-term memory as an event; em_salience decides what surfaces later. 248// Called AFTER the reply, so a turn never recalls itself. 249func go_mind_remember(umsg: *u8, umlen: i64) -> i64 { 250 if umlen <= 0 { return 0 } 251 let session: *u8 = sys_mmap(64) 252 mind_session(session) 253 let q: *u8 = sys_mmap(MIND_QUERY_CAP + 8) 254 mind_query(umsg, umlen, q) 255 let buf: *u8 = sys_mmap(MIND_CAP) 256 mind_run(MIND_ELF_MEM, 4, "remember" as *u8, session, q, "event" as *u8, buf) 257 return 0 258}