self-review 2026-06-10: fix ise_post JSON escaping + rebuild soul daemon

Two fixes:

1. ise_post was only escaping " in content strings. When wm_top contained
   node labels with \n (backslash-n escape sequences from jb_emit_escaped),
   the HTTP Engram server's JSON parser decoded \n as a literal newline in
   the stored content, making heartbeat ISEs unparseable. Fix: escape
   backslashes first, then quotes, then \n and \r — matching make_action's
   existing pattern. Result: heartbeat ISEs now parse cleanly.

2. Soul daemon (dist/neuron) was missing — the build command in the prompt
   was linking all 46 dist/*.c files together, causing 1092 duplicate symbol
   errors. EL compiles transitive imports inline so neuron.c is self-contained;
   correct build links ONLY neuron.c + el_runtime.c. Daemon now starts.
This commit is contained in:
2026-06-10 08:54:28 -05:00
parent c81f49d938
commit 297066c2d4
4 changed files with 20 additions and 6 deletions
+10 -2
View File
@@ -30,8 +30,16 @@ fn ise_post(content: String) -> Void {
)
return ""
}
let safe: String = str_replace(content, "\"", "\\\"")
let body: String = "{\"content\":\"" + safe + "\"}"
// Proper JSON string escaping: backslashes first, then quotes, then control chars.
// Previously only escaped " — this caused ise_post to produce malformed JSON when
// content contained \n (backslash-n) from wm_top label escaping: the HTTP Engram
// server would decode \n as a literal newline in the stored content field, making
// the heartbeat ISE unparseable as JSON. (2026-06-10 self-review)
let safe1: String = str_replace(content, "\\", "\\\\")
let safe2: String = str_replace(safe1, "\"", "\\\"")
let safe3: String = str_replace(safe2, "\n", "\\n")
let safe4: String = str_replace(safe3, "\r", "\\r")
let body: String = "{\"content\":\"" + safe4 + "\"}"
let discard: String = http_post_json(engram_url + "/api/neuron/state-events", body)
return ""
}
+5 -2
View File
@@ -174,8 +174,11 @@ el_val_t ise_post(el_val_t content) {
el_val_t discard = engram_node_full(content, EL_STR("InternalStateEvent"), EL_STR("state-event"), el_from_float(el_from_float(0.3)), el_from_float(el_from_float(0.3)), el_from_float(el_from_float(0.8)), EL_STR("Episodic"), EL_STR("[\"internal-state\",\"InternalStateEvent\"]"));
return EL_STR("");
}
el_val_t safe = str_replace(content, EL_STR("\""), EL_STR("\\\""));
el_val_t body = el_str_concat(el_str_concat(EL_STR("{\"content\":\""), safe), EL_STR("\"}"));
el_val_t safe1 = str_replace(content, EL_STR("\\"), EL_STR("\\\\"));
el_val_t safe2 = str_replace(safe1, EL_STR("\""), EL_STR("\\\""));
el_val_t safe3 = str_replace(safe2, EL_STR("\n"), EL_STR("\\n"));
el_val_t safe4 = str_replace(safe3, EL_STR("\r"), EL_STR("\\r"));
el_val_t body = el_str_concat(el_str_concat(EL_STR("{\"content\":\""), safe4), EL_STR("\"}"));
el_val_t discard = http_post_json(el_str_concat(engram_url, EL_STR("/api/neuron/state-events")), body);
return EL_STR("");
return 0;
Vendored
BIN
View File
Binary file not shown.
+5 -2
View File
@@ -25299,8 +25299,11 @@ el_val_t ise_post(el_val_t content) {
el_val_t discard = engram_node_full(content, EL_STR("InternalStateEvent"), EL_STR("state-event"), el_from_float(el_from_float(0.3)), el_from_float(el_from_float(0.3)), el_from_float(el_from_float(0.8)), EL_STR("Episodic"), EL_STR("[\"internal-state\",\"InternalStateEvent\"]"));
return EL_STR("");
}
el_val_t safe = str_replace(content, EL_STR("\""), EL_STR("\\\""));
el_val_t body = el_str_concat(el_str_concat(EL_STR("{\"content\":\""), safe), EL_STR("\"}"));
el_val_t safe1 = str_replace(content, EL_STR("\\"), EL_STR("\\\\"));
el_val_t safe2 = str_replace(safe1, EL_STR("\""), EL_STR("\\\""));
el_val_t safe3 = str_replace(safe2, EL_STR("\n"), EL_STR("\\n"));
el_val_t safe4 = str_replace(safe3, EL_STR("\r"), EL_STR("\\r"));
el_val_t body = el_str_concat(el_str_concat(EL_STR("{\"content\":\""), safe4), EL_STR("\"}"));
el_val_t discard = http_post_json(el_str_concat(engram_url, EL_STR("/api/neuron/state-events")), body);
return EL_STR("");
return 0;