fix(soul): restore the soul_identity producer — the chat system prompt has been empty for three months (#137)
Five sites in chat.el read state_get("soul_identity") and splice the result into
the system prompt, beside the voice, security and capability rules:
chat.el:737, 1745, 2620, 3425, 3480
Nothing has written that key since b163fa6. The producer was added 2026-05-02 in
601e0fe and deleted by the awareness refactor days later. Every chat turn since has
built its system prompt with an EMPTY identity section, and nothing reported it.
Found by the #132 state-key gate, which treats a read with no producer as a build
error rather than a silence. That is the entire argument for that gate.
RESTORED VERBATIM, NOT IMPROVED. soul_identity is an env-configurable persona LINE.
It is not soul_identity_context — the graph-derived
[INTELLECTUAL-DNA]/[VALUES]/[MEMORY-PHILOSOPHY] block written at soul.el:184.
Repointing the five reads at that block would have substituted different content and
called it a repair. Whether the chat prompt should ALSO carry the graph-derived block
is a real question and a separate one; it is not smuggled in here.
Verified by the gate that found it: dead reads 6 -> 1, and it now reports the
chat.el baseline entry as STALE — 'entries that no longer match anything; delete
them'. The remaining one is studio.el's soul_principal, untouched by this change.
Rung: BUILT, gate-verified, boots. NOT end-to-end chat-verified — proving the
prompt now carries the line needs a live provider call, which I have not run.
Refs #137, #132
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+8
-3
@@ -1274,6 +1274,8 @@ el_val_t axon_raw;
|
||||
el_val_t axon_base;
|
||||
el_val_t studio_dir_raw;
|
||||
el_val_t studio_dir;
|
||||
el_val_t identity_raw;
|
||||
el_val_t soul_identity;
|
||||
el_val_t using_http_engram;
|
||||
el_val_t local_node_count;
|
||||
el_val_t snapshot_usable;
|
||||
@@ -31948,6 +31950,9 @@ int main(int _argc, char** _argv) {
|
||||
axon_base = ({ el_val_t _if_result_824 = 0; if (str_eq(axon_raw, EL_STR(""))) { _if_result_824 = (EL_STR("http://localhost:7771")); } else { _if_result_824 = (axon_raw); } _if_result_824; });
|
||||
studio_dir_raw = env(EL_STR("SOUL_STUDIO_DIR"));
|
||||
studio_dir = ({ el_val_t _if_result_825 = 0; if (str_eq(studio_dir_raw, EL_STR(""))) { _if_result_825 = (el_str_concat(env(EL_STR("HOME")), EL_STR("/Development/neuron-technologies/products/cgi-studio/el-daemon"))); } else { _if_result_825 = (studio_dir_raw); } _if_result_825; });
|
||||
identity_raw = env(EL_STR("SOUL_IDENTITY"));
|
||||
soul_identity = ({ el_val_t _if_result_826 = 0; if (str_eq(identity_raw, EL_STR(""))) { _if_result_826 = (el_str_concat(el_str_concat(EL_STR("You are "), soul_cgi_id), EL_STR(", a CGI."))); } else { _if_result_826 = (identity_raw); } _if_result_826; });
|
||||
state_set(EL_STR("soul_identity"), soul_identity);
|
||||
println(el_str_concat(el_str_concat(el_str_concat(EL_STR("[soul] boot - cgi="), soul_cgi_id), EL_STR(" port=")), int_to_str(port)));
|
||||
using_http_engram = !str_eq(engram_url_raw, EL_STR(""));
|
||||
engram_load(snapshot);
|
||||
@@ -31957,8 +31962,8 @@ int main(int _argc, char** _argv) {
|
||||
println(el_str_concat(el_str_concat(EL_STR("[soul] engram -> HTTP "), engram_url_raw), EL_STR(" (no local snapshot, first boot)")));
|
||||
el_val_t nodes_json = http_get(el_str_concat(engram_url_raw, EL_STR("/api/nodes?limit=10000")));
|
||||
el_val_t edges_json = http_get(el_str_concat(engram_url_raw, EL_STR("/api/edges")));
|
||||
el_val_t nodes_part = ({ el_val_t _if_result_826 = 0; if (str_eq(nodes_json, EL_STR(""))) { _if_result_826 = (EL_STR("[]")); } else { _if_result_826 = (nodes_json); } _if_result_826; });
|
||||
el_val_t edges_part = ({ el_val_t _if_result_827 = 0; if (str_eq(edges_json, EL_STR(""))) { _if_result_827 = (EL_STR("[]")); } else { _if_result_827 = (edges_json); } _if_result_827; });
|
||||
el_val_t nodes_part = ({ el_val_t _if_result_827 = 0; if (str_eq(nodes_json, EL_STR(""))) { _if_result_827 = (EL_STR("[]")); } else { _if_result_827 = (nodes_json); } _if_result_827; });
|
||||
el_val_t edges_part = ({ el_val_t _if_result_828 = 0; if (str_eq(edges_json, EL_STR(""))) { _if_result_828 = (EL_STR("[]")); } else { _if_result_828 = (edges_json); } _if_result_828; });
|
||||
el_val_t snapshot_data = el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"nodes\":"), nodes_part), EL_STR(",\"edges\":")), edges_part), EL_STR("}"));
|
||||
el_val_t tmp_path = el_str_concat(el_str_concat(EL_STR("/tmp/soul-engram-"), soul_cgi_id), EL_STR(".json"));
|
||||
fs_write(tmp_path, snapshot_data);
|
||||
@@ -31982,7 +31987,7 @@ int main(int _argc, char** _argv) {
|
||||
state_set(EL_STR("soul_engram_api_key"), engram_api_key_raw);
|
||||
state_set(EL_STR("soul.running"), EL_STR("true"));
|
||||
is_genesis = str_eq(soul_cgi_id, EL_STR("ntn-genesis"));
|
||||
guard_disk = ({ el_val_t _if_result_828 = 0; if (str_eq(engram_url_raw, EL_STR(""))) { _if_result_828 = (fs_read(snapshot)); } else { _if_result_828 = (EL_STR("")); } _if_result_828; });
|
||||
guard_disk = ({ el_val_t _if_result_829 = 0; if (str_eq(engram_url_raw, EL_STR(""))) { _if_result_829 = (fs_read(snapshot)); } else { _if_result_829 = (EL_STR("")); } _if_result_829; });
|
||||
guard_disk_len = str_len(guard_disk);
|
||||
safe_to_seed = (!using_http_engram && !((guard_disk_len > 200000) && ((engram_node_count() * 16000) < guard_disk_len)));
|
||||
if (is_genesis && !safe_to_seed) {
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
# soul.c.stamp — fingerprint of the .el sources dist/soul.c was generated from.
|
||||
# Written by tools/soulc-stamp.sh --write. Do not hand-edit.
|
||||
# generated_amalgam_sha256 63e30030bee5e87fa082a84cda5c1226896f49da6076101fcd6b9530ea7caf49
|
||||
# generated_amalgam_bytes 1204442
|
||||
# generated_amalgam_sha256 ee09798ad93ddd047136577cf324483e5956984d60d06596d34662f315ee0df4
|
||||
# generated_amalgam_bytes 1204845
|
||||
f8597e10546654bce3fbbe40461b2da59d0e06dbf1b038d1d362d24f949e3911 awareness.el
|
||||
b6f3d14ca0c26017a2d617399a6d3754dabb0905e4d5f52eb75d25c4ad18d3c5 chat.el
|
||||
42288c212cbf72fb1e8ecbd4d9900e4e9ee1cfa475b7974295c7637f1bf2939f elp-input.el
|
||||
@@ -13,6 +13,6 @@ fba8ffdb9ba72bca5b09ca1c93a520edc52f3f4d8aec2c7585fe9b17e06420b2 manifest.el
|
||||
a6d69f3fc55233d9d3300160fd46a1551f2064bcd0fb84e2c9e432f636a72476 routes.el
|
||||
c28e36952ec56525963a0bdf29455ab097d3b0c5653d19c25fbb005e1069a1f7 safety.el
|
||||
fd3ab91d0ae0ea26639e21bef2f8f94054dc4b02eae68b19e3fe689d2769aad4 sessions.el
|
||||
0f1cf43904a98a5a646cce5a07e0e96162ced662692fbc13357d9b67d9a8ac3d soul.el
|
||||
5613b60d74d5d7768f46da5ac435a5dd99d38c27f0f7013c89fa27e98dc8a21c soul.el
|
||||
30337940905171a9645b0929f0a412ce6b3dccb1246495070c553bca0bbae6cd stewardship.el
|
||||
e105dc5990e6adbf39db9dc0462cd8bcf6e6c3dfd03709059227ecfad2bbab29 studio.el
|
||||
|
||||
@@ -559,6 +559,27 @@ let axon_base: String = if str_eq(axon_raw, "") { "http://localhost:7771" } else
|
||||
let studio_dir_raw: String = env("SOUL_STUDIO_DIR")
|
||||
let studio_dir: String = if str_eq(studio_dir_raw, "") { env("HOME") + "/Development/neuron-technologies/products/cgi-studio/el-daemon" } else { studio_dir_raw }
|
||||
|
||||
// RESTORED 2026-08-09 — this producer was added 2026-05-02 in 601e0fe and deleted
|
||||
// by the awareness refactor b163fa6 a few days later. Nothing has written
|
||||
// soul_identity since, while FIVE sites in chat.el kept reading it:
|
||||
// chat.el:737, 1745, 2620, 3425, 3480 — each doing state_get("soul_identity")
|
||||
// and splicing the result into the system prompt beside the voice, security and
|
||||
// capability rules. They have been splicing an EMPTY STRING for roughly three
|
||||
// months. The identity section of every chat turn was blank and nothing said so.
|
||||
//
|
||||
// Found by the #132 state-key gate, which reports a read with no producer as a
|
||||
// build error rather than a silence — the whole reason that gate exists.
|
||||
//
|
||||
// Restored verbatim rather than improved: this key is an env-configurable persona
|
||||
// LINE, which is NOT the same thing as soul_identity_context (the graph-derived
|
||||
// [INTELLECTUAL-DNA]/[VALUES]/[MEMORY-PHILOSOPHY] block written at soul.el:184).
|
||||
// Pointing these five reads at that block instead would have substituted different
|
||||
// content and called it a fix. Whether the chat system prompt should ALSO carry the
|
||||
// graph-derived block is a real question, and a separate one.
|
||||
let identity_raw: String = env("SOUL_IDENTITY")
|
||||
let soul_identity: String = if str_eq(identity_raw, "") { "You are " + soul_cgi_id + ", a CGI." } else { identity_raw }
|
||||
state_set("soul_identity", soul_identity)
|
||||
|
||||
println("[soul] boot - cgi=" + soul_cgi_id + " port=" + int_to_str(port))
|
||||
|
||||
let using_http_engram: Bool = !str_eq(engram_url_raw, "")
|
||||
|
||||
Reference in New Issue
Block a user