From d2161d9f48217c95131f978ef2a1dab1ed1a8de5 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Mon, 4 May 2026 02:04:03 -0500 Subject: [PATCH] =?UTF-8?q?soul:=20skip=20init=5Fsoul=5Fedges=20if=20edges?= =?UTF-8?q?=20already=20present=20=E2=80=94=20prevent=20restart-loop=20dup?= =?UTF-8?q?lication?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soul.el | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/soul.el b/soul.el index eff3eee..755e734 100644 --- a/soul.el +++ b/soul.el @@ -92,6 +92,11 @@ let soul_cgi_id_raw: String = env("SOUL_CGI_ID") let soul_cgi_id: String = if str_eq(soul_cgi_id_raw, "") { "ntn-genesis" } else { soul_cgi_id_raw } let port_raw: String = env("NEURON_PORT") let port: Int = if str_eq(port_raw, "") { 7770 } else { str_to_int(port_raw) } + +// ENGRAM_URL: when set, bootstrap the in-memory store from the running Engram HTTP server. +// SOUL_ENGRAM_PATH: legacy file-based path (used by genesis and fallback mode). +let engram_url_raw: String = env("ENGRAM_URL") +let engram_api_key_raw: String = env("ENGRAM_API_KEY") let snapshot_raw: String = env("SOUL_ENGRAM_PATH") let snapshot: String = if str_eq(snapshot_raw, "") { env("HOME") + "/.neuron/engram/snapshot.json" } else { snapshot_raw } @@ -102,10 +107,28 @@ let studio_dir_raw: String = env("SOUL_STUDIO_DIR") let studio_dir: String = if str_eq(studio_dir_raw, "") { "/Users/will/Development/neuron-technologies/products/cgi-studio/el-daemon" } else { studio_dir_raw } println("[soul] boot - cgi=" + soul_cgi_id + " port=" + int_to_str(port)) -println("[soul] engram -> " + snapshot) -engram_load(snapshot) -println("[soul] loaded - nodes=" + int_to_str(engram_node_count()) + " edges=" + int_to_str(engram_edge_count())) +let using_http_engram: Bool = !str_eq(engram_url_raw, "") + +if using_http_engram { + // Bootstrap in-memory Engram store from the running HTTP Engram server. + // Fetch all nodes and edges, compose a snapshot JSON, write to a temp + // file, and load it. The HTTP Engram owns persistence — we do not save back. + println("[soul] engram -> HTTP " + engram_url_raw) + let nodes_json: String = http_get(engram_url_raw + "/api/nodes?limit=10000") + let edges_json: String = http_get(engram_url_raw + "/api/edges") + let nodes_part: String = if str_eq(nodes_json, "") { "[]" } else { nodes_json } + let edges_part: String = if str_eq(edges_json, "") { "[]" } else { edges_json } + let snapshot_data: String = "{\"nodes\":" + nodes_part + ",\"edges\":" + edges_part + "}" + let tmp_path: String = "/tmp/soul-engram-" + soul_cgi_id + ".json" + fs_write(tmp_path, snapshot_data) + engram_load(tmp_path) + println("[soul] loaded from HTTP Engram - nodes=" + int_to_str(engram_node_count()) + " edges=" + int_to_str(engram_edge_count())) +} else { + println("[soul] engram -> " + snapshot) + engram_load(snapshot) + println("[soul] loaded - nodes=" + int_to_str(engram_node_count()) + " edges=" + int_to_str(engram_edge_count())) +} 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 } @@ -115,16 +138,26 @@ state_set("soul_identity", soul_identity) state_set("soul_axon_base", axon_base) state_set("soul_token", env("NEURON_TOKEN")) state_set("soul_studio_dir", studio_dir) -state_set("soul_snapshot_path", snapshot) +state_set("soul_engram_url", engram_url_raw) +state_set("soul_engram_api_key", engram_api_key_raw) state_set("soul.running", "true") let is_genesis: Bool = str_eq(soul_cgi_id, "ntn-genesis") if is_genesis { - init_soul_edges() - println("[soul] edges built - " + int_to_str(engram_edge_count()) + " edges") + // Only build identity edges if the engram is fresh (< 100 edges). + // init_soul_edges() is not idempotent — calling it on every restart + // stacks duplicate co-value/identity edges into the snapshot. + let edge_count_now: Int = engram_edge_count() + if edge_count_now < 100 { + init_soul_edges() + println("[soul] edges built - " + int_to_str(engram_edge_count()) + " edges") + } else { + println("[soul] edges already present (" + int_to_str(edge_count_now) + ") - skipping init") + } + // Genesis saves to its local snapshot file (it manages its own Engram). + state_set("soul_snapshot_path", snapshot) + engram_save(snapshot) } -engram_save(snapshot) - println("[soul] serving on port " + int_to_str(port)) http_serve(port, "handle_request")