feat(soul): add safety module, expand connectors API, memory-recall bug notes

- safety.el/.elh: new safety module
- neuron-api.el, routes.el, soul.el, chat.el: connectors API expansion
- regenerated dist/ C artifacts
- MEMORY_RECALL_BUG.md: investigation notes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tim Lingo
2026-06-15 11:10:33 -05:00
parent 6c57d4fe1b
commit 3bb17a5296
22 changed files with 1013 additions and 109 deletions
Vendored
+37 -2
View File
@@ -46,13 +46,38 @@ el_val_t handle_see(el_val_t body);
el_val_t studio_tools_json(void);
el_val_t agentic_api_key(void);
el_val_t agentic_tools_literal(void);
el_val_t agentic_tools_with_web(void);
el_val_t dispatch_tool(el_val_t tool_name, el_val_t tool_input);
el_val_t json_array_append(el_val_t arr, el_val_t item);
el_val_t append_tool_log(el_val_t log, el_val_t name);
el_val_t exec_tool_block(el_val_t block);
el_val_t agentic_blob(el_val_t model, el_val_t system, el_val_t tools_json, el_val_t messages, el_val_t origin, el_val_t approval, el_val_t iteration, el_val_t tools_log, el_val_t content, el_val_t queue, el_val_t results, el_val_t next);
el_val_t extract_all_text(el_val_t s);
el_val_t strip_citations(el_val_t s);
el_val_t agentic_api_turn(el_val_t model, el_val_t safe_sys, el_val_t tools_json, el_val_t messages);
el_val_t agentic_engine(el_val_t session_id, el_val_t blob);
el_val_t handle_chat_agentic(el_val_t body);
el_val_t handle_session_approve(el_val_t session_id, el_val_t body);
el_val_t handle_chat_as_soul(el_val_t body);
el_val_t handle_dharma_room_turn(el_val_t body);
el_val_t handle_dharma_room_turn_agentic(el_val_t body);
el_val_t auto_persist(el_val_t req, el_val_t resp);
el_val_t strengthen_chat_nodes(el_val_t activation_nodes);
el_val_t safety_self_harm_phrases(void);
el_val_t safety_abuse_phrases(void);
el_val_t safety_general_hard_phrases(void);
el_val_t safety_soft_phrases(void);
el_val_t safety_normalize(el_val_t message);
el_val_t safety_any_match(el_val_t text, el_val_t phrases_json);
el_val_t safety_count_match(el_val_t text, el_val_t phrases_json);
el_val_t safety_detect_bell_level(el_val_t message);
el_val_t safety_classify_hard_bell(el_val_t message);
el_val_t safety_soft_directive(void);
el_val_t safety_hard_directive(el_val_t hard_type);
el_val_t safety_augment_system(el_val_t system, el_val_t user_msg);
el_val_t safety_contact_path(void);
el_val_t handle_safety_contact_get(void);
el_val_t handle_safety_contact_post(el_val_t body);
el_val_t auth_headers(el_val_t tok);
el_val_t axon_get(el_val_t path);
el_val_t axon_post(el_val_t path, el_val_t body);
@@ -69,6 +94,7 @@ el_val_t elp_detect_predicate(el_val_t msg);
el_val_t elp_parse(el_val_t msg);
el_val_t handle_elp_chat(el_val_t body);
el_val_t strip_query(el_val_t path);
el_val_t flag_true(el_val_t body, el_val_t key);
el_val_t err_404(el_val_t path);
el_val_t err_405(el_val_t method, el_val_t path);
el_val_t route_health(void);
@@ -100,6 +126,9 @@ el_val_t boot_num;
el_val_t identity_raw;
el_val_t soul_identity;
el_val_t is_genesis;
el_val_t guard_disk;
el_val_t guard_disk_len;
el_val_t safe_to_seed;
el_val_t init_soul_edges(void) {
el_val_t self_root = EL_STR("015644f5-8194-4af0-800d-dd4a0cd71396");
@@ -267,7 +296,13 @@ 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"));
if (is_genesis) {
guard_disk = ({ el_val_t _if_result_25 = 0; if (str_eq(engram_url_raw, EL_STR(""))) { _if_result_25 = (fs_read(snapshot)); } else { _if_result_25 = (EL_STR("")); } _if_result_25; });
guard_disk_len = str_len(guard_disk);
safe_to_seed = !((engram_node_count() < 50) && (guard_disk_len > 200000));
if (is_genesis && !safe_to_seed) {
println(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("[soul] GUARD: loaded "), int_to_str(engram_node_count())), EL_STR(" nodes but snapshot file is ")), int_to_str(guard_disk_len)), EL_STR(" bytes \xe2\x80\x94 refusing to seed/save over a real graph")));
}
if (is_genesis && safe_to_seed) {
el_val_t edge_count_now = engram_edge_count();
if (edge_count_now < 100) {
init_soul_edges();
@@ -278,7 +313,7 @@ int main(int _argc, char** _argv) {
state_set(EL_STR("soul_snapshot_path"), snapshot);
engram_save(snapshot);
}
if (is_genesis) {
if (is_genesis && safe_to_seed) {
el_val_t snap = state_get(EL_STR("soul_snapshot_path"));
if (!str_eq(snap, EL_STR(""))) {
engram_save(snap);