code wiki / (root) / nx_charmem.nx

nx_charmem.nx

buildroot/runtime/nx_charmem.nx

19378 B490 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_charmem.nx -- SOVEREIGN CHARACTER MEMORY (the Nomi/Replika-class relationship state, in Nishi). Operator 2026-08-05: "SQLite-backed character memory (affection/trust/drift/learned user preferences), we want in nishi sota." DESIGN: EVENT-SOURCED, APPEND-ONLY (rule 13 -- history is sacred). The Python original mutates SQLite rows; this organ never mutates anything: every interaction APPENDS one line to knowledge/status/charmem_<char>.jrnl and current state is a FOLD over the journal at read time. That buys what the mutable version cannot: full audit (why is affection 72? read the lines), time-travel debugging, and no lost-update races between writers. event <char> <kind> <args...> append one event. kinds: aff|trust|intim|excit <+/-N> relationship metric delta (fold clamps to 0..100) mood <word> current mood (latest wins) pref <key>=<value> learned user preference (latest value per key wins) mem <imp 1-9> <text...> an important memory with importance weight state <char> fold -> metrics, mood, counts (machine-parseable line) ctx <char> fold -> the LLM-ready system-prompt block (top prefs+memories) selftest <char> hermetic assertions on a throwaway fixture journal Char names sanitize to [a-z0-9_] max 32 (boundary defense: the name builds a path). license_tier: ORIGINAL module: nishi-core.companion.charmem

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_lane_conf.nx nx_charmem.nx

imports: nx_syscalls.nxnx_lane_conf.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main cm_w sys_write cm_len sys_mmap cm_sane cm_eq cm_event cm_kind cm_eq ↻ cm_w ↻ sys_mmap ↻ cm_path cm_cat cm_u cm_u ↻ sys_mmap ↻ cm_now sys_mmap ↻ sys_clock_gettime_real cm_cat ↻ sys_openat_append sys_write ↻ sys_close cm_state sys_mmap ↻ cm_fold cm_def lc_write_lane lc_geti sys_mmap ↻ lc_read lc_slen sys_mmap ↻ cm_path ↻ sys_openat_rd sys_read sys_close ↻ cm_int cm_kind ↻

structs

none

consts

25const CM_BUF: i64 = 1048576
26const CM_LINE: i64 = 4096
27const CM_PREF_MAX: i64 = 64
28const CM_MEM_MAX: i64 = 256
30const CM_CTX_PREFS: i64 = 6
31const CM_CTX_MEMS: i64 = 6
32const CM_DEF_AFF: i64 = 50
33const CM_DEF_TRUST: i64 = 50
34const CM_DEF_INTIM: i64 = 30
35const CM_DEF_EXCIT: i64 = 50

functions

37func cm_def(slot: i64) -> i64
called by 2: cm_foldcm_selftest calls 1: lc_write_lane
44func cm_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
called by 1: cm_w
45func cm_w(s: *u8) -> i64 { sys_write(1, s, cm_len(s)); return 0 }
46func cm_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i }
47func cm_u(dst: *u8, off: i64, v: i64) -> i64
57func cm_eq(a: *u8, b: *u8) -> i64
67func cm_int(s: *u8, pi: *i64) -> i64
called by 2: cm_foldcm_ctx
83func cm_clamp(v: i64) -> i64 { if v<0 { return 0 } if v>100 { return 100 } return v }
called by 2: cm_foldcm_selftest
88func cm_eol(buf: *u8, idx: i64) -> i64
called by 2: cm_foldcm_ctx
99func cm_line_copy(buf: *u8, idx: i64, dst: *u8, cap: i64) -> i64
called by 2: cm_foldcm_ctx
116func cm_sane(s: *u8, out: *u8) -> i64
called by 2: cm_selftestmain
133func cm_path(char: *u8, out: *u8) -> i64
called by 3: cm_eventcm_foldcm_selftest calls 1: cm_cat
141func cm_now() -> i64 { let ts: *i64=sys_mmap(16) as *i64; ts[0]=0; sys_clock_gettime_real(ts); return ts[0] }
144func cm_kind(k: *u8) -> i64
called by 2: cm_eventcm_fold calls 1: cm_eq
156func cm_event(char: *u8, argc: i64, argv: *i64) -> i64
194func cm_fold(char: *u8, m: *i64, moodbuf: *u8, buf: *u8) -> i64
253func cm_state(char: *u8) -> i64
276func cm_ctx(char: *u8) -> i64
400func cm_file_size(path: *u8) -> i64
408func cm_selftest(char: *u8) -> i64
471func main(argc: i64, argv: *i64) -> i64