From 5ddb8602015cb552e29f8617a88337691026782f Mon Sep 17 00:00:00 2001 From: Tim Lingo <1timlingo@gmail.com> Date: Mon, 15 Jun 2026 18:21:59 -0500 Subject: [PATCH] fix(soul): ratio guard against genesis seeding over a populated engram Genesis boot previously seeded a fresh identity and saved it over snapshot.json whenever the in-memory graph looked empty. Replace the fixed node-count threshold with a ratio guard: refuse to seed when the on-disk snapshot is large (>200KB) but the loaded graph is sparse (< disk/16000 nodes). KNOWN LIMITATION: this gates only the seed/pre-serve-save path. The deeper cause is a non-atomic engram_save (fopen wb truncates to 0 before writing 47MB), which creates a window where a concurrent load reads an empty file -> genesis -> and if guard_disk is read in that same window the guard passes. The real fix is an atomic engram_save (temp + fsync + rename) in el_runtime.c, tracked separately. Co-Authored-By: Claude Opus 4.8 (1M context) --- dist/soul.c | 2 +- soul.el | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dist/soul.c b/dist/soul.c index d2542f3..a0ea366 100644 --- a/dist/soul.c +++ b/dist/soul.c @@ -28945,7 +28945,7 @@ int main(int _argc, char** _argv) { is_genesis = str_eq(soul_cgi_id, EL_STR("ntn-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)); + safe_to_seed = !((guard_disk_len > 200000) && (engram_node_count() < (guard_disk_len / 16000))); 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"))); } diff --git a/soul.el b/soul.el index 7e5281f..9f3b56a 100644 --- a/soul.el +++ b/soul.el @@ -370,7 +370,10 @@ let is_genesis: Bool = str_eq(soul_cgi_id, "ntn-genesis") // on-disk file (local mode only) and refuse the destructive seed+save when it looks populated. let guard_disk: String = if str_eq(engram_url_raw, "") { fs_read(snapshot) } else { "" } let guard_disk_len: Int = str_len(guard_disk) -let safe_to_seed: Bool = !(engram_node_count() < 50 && guard_disk_len > 200000) +// Ratio guard (2026-06-15 fix): refuse to seed/save whenever the in-memory load is FAR smaller than +// the on-disk file implies (~16KB/node) — catches partial loads of ANY size, not just <50. The old +// <50 threshold let a 63-node identity-only load clobber a 47MB/5000-node graph. +let safe_to_seed: Bool = !(guard_disk_len > 200000 && engram_node_count() < guard_disk_len / 16000) if is_genesis && !safe_to_seed { println("[soul] GUARD: loaded " + int_to_str(engram_node_count()) + " nodes but snapshot file is " + int_to_str(guard_disk_len)