nx_chat_demo_api.nx
buildroot/runtime/nx_chat_demo_api.nx
about
nx_chat_demo_api.nx -- the SAFE public front for a testable persistent-chat UI backed by C1's store.
v2 (2026-08-16): does the append/fetch IN-PROCESS on the seg-store, NOT by forking nx_chat_store.
WHY: MEASURED via curl to /mcp -- a list (read) returned in 44ms, but a post that FORKED nx_chat_store
to write hung to the tools-daemon exec deadline (~14s) and returned empty (exit -5), because the
write-path grandchild orphaned under the daemon's capture. A read fork was fine; a write fork was not.
In-process removes the fork entirely: this organ takes the plane lock, appends, and releases in its own
process -- the exact code path nx_chat_store's gate proves, just linked instead of exec'd. Fast + no orphan.
SECURITY BOUNDARY unchanged: only post/list, rooms forced into demo_, inputs sanitized + capped, budgets
from C1's conf refuse loudly. Destructive verbs do not exist here. REFEREE: nx_chat_demo_api_gate.
DEBT (named, not a silent twin): the append/fetch logic is duplicated from nx_chat_store; the consolidation
is to extract nx_chat_store_lib that BOTH this front and the CLI import (comms.plan chatstore-lib-extract).
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 4 imports · 1 importers
imports: nx_syscalls.nxnx_itoa_lib.nxnx_store_seed_lib.nxnx_seg_store.nx
imported by: nx_chat_unicode_probe_t58.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 18 | const CDA_EXIT_OK: i64 = 0 |
| 19 | const CDA_EXIT_USAGE: i64 = 2 |
| 20 | const CDA_EXIT_REFUSED: i64 = 3 |
| 21 | const CDA_ROOM_MAX: i64 = 24 |
| 22 | const CDA_NAME_MAX: i64 = 24 |
| 23 | const CDA_TEXT_MAX: i64 = 280 |
| 24 | const CDA_FETCH_MAX: i64 = 200 |
| 25 | const CDA_PFX_CAP: i64 = 256 |
| 26 | const CDA_ROW_OVH: i64 = 128 |
| 27 | const CDA_WSLACK: i64 = 65536 |
| 28 | const CDA_CONF_CAP: i64 = 192 |
| 29 | const CDA_OUTCAP: i64 = 262144 |
| 30 | const CDA_NL: i64 = 10 |
| 31 | const CDA_PIPE: i64 = 124 |
| 32 | const CDA_KIND_TEXT: i64 = 1 |
| 33 | const CDA_KIND_SYS: i64 = 4 |
| 34 | const CHATCONF: *u8 = "knowledge/comms/chatstore.conf" |
| 35 | const CSA_ERR_CONF: i64 = 0 - 3 |
| 36 | const CSA_ERR_BODY: i64 = 0 - 10 |
| 37 | const CSA_ERR_LOCK: i64 = 0 - 4 |
| 38 | const CSA_ERR_MSGS: i64 = 0 - 11 |
| 39 | const CSA_ERR_BYTES: i64 = 0 - 12 |
| 40 | const CSA_ERR_CORRUPT: i64 = 0 - 5 |
functions
| 42 | func cda_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 43 | func cda_wn(s: *u8, n: i64) -> i64 { sys_write(1, s, n); return 0 } |
| 44 | func cda_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 45 | func cda_eq(a: *u8, b: *u8) -> i64 |
| 51 | func cda_ident(src: *u8, dst: *u8, cap: i64) -> i64 |
| 66 | func cda_text(src: *u8, dst: *u8, cap: i64) -> i64 |
| 78 | func cda_demoroom(clean: *u8, out: *u8) -> i64 |
| 87 | func cda_jesc(out: *u8, o: i64, s: *u8, n: i64) -> i64 called by 1: cda_list |
| 100 | func cda_hexe(src: *u8, n: i64, dst: *u8) -> i64 called by 1: cda_rowbuild |
| 112 | func cda_hexv(c: i64) -> i64 called by 1: cda_list |
| 117 | func cda_catn(d: *u8, o: i64, v: i64) -> i64 |
| 127 | func cda_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } return o } |
| 128 | func cda_confs(key: *u8, out: *u8, cap: i64) -> i64 |
| 157 | func cda_confn(key: *u8) -> i64 |
| 163 | func cda_prefix(room: *u8, out: *u8) -> i64 |
| 173 | func cda_rowbuild(seq: i64, kind: i64, sender: *u8, body: *u8, blen: i64, out: *u8) -> i64 |
| 187 | func cda_delkey(seq: i64, out: *u8) -> i64 |
| 193 | func cda_put_key(prefix: *u8, key: *u8, val: *u8, vlen: i64) -> i64 |
| 199 | func csa_append(room: *u8, sender: *u8, body: *u8, blen: i64) -> i64 |
| 264 | func csa_fetch(room: *u8, since: i64, maxn: i64, outbuf: *u8, outcap: i64) -> i64 |
| 300 | func cda_post(room_in: *u8, name_in: *u8, text_in: *u8) -> i64 |
| 328 | func cda_atoi(b: *u8, n: i64) -> i64 { var v: i64 = 0; var i: i64 = 0; while i < n { let c: i64 = b[i] as i64; if c < 48 { break } if c > 57 { break } v = v * 10 + (c - 48); i = i + 1 } return v } called by 1: cda_list |
| 329 | func cda_list(room_in: *u8, since_in: *u8) -> i64 |
| 406 | func cda_usage() -> i64 |
| 410 | func main(argc: i64, argv: *i64) -> i64 |