fix/test: PR #21 review — guard, safety Bell, api write-back, temp paths
Neuron Soul CI / build (pull_request) Failing after 13m22s
Neuron Soul CI / build (pull_request) Failing after 13m22s
fix(soul): add HTTP-engram guard to safe_to_seed — when ENGRAM_URL is set the HTTP Engram owns persistence; genesis must never save to local snapshot regardless of node counts (was: guard_disk forced to empty string, making the ratio check vacuously true and allowing init_soul_edges+engram_save). fix(soul): use multiplication form for ratio guard — node_count * 16000 < disk_len avoids floor-division truncation that underestimated boundary files (250KB / 16000 = 15.6, floors to 15; a 15-node graph wrongly passed old guard). fix(chat): add safety_augment_system to handle_chat_as_soul, handle_dharma_room_turn, and handle_dharma_room_turn_agentic — all three called the LLM without Hard Bell evaluation, leaving users in dharma rooms without crisis resource routing. fix(neuron-api): add api_persisted read-back to handle_api_define_process — was the only write handler that returned ok:true without verifying the node was actually written to engram. fix(routes): unique temp file path in connectd_post — replaces fixed /tmp/neuron-connectors-req.json with a timestamped path to prevent collision if concurrency is added or two soul instances share a machine. test: add tests/test_bell_safety.el — covers safety_detect_bell_level (none/soft/hard), safety_classify_hard_bell (abuse/self_harm routing), safety_normalize (smart-quote), safety_augment_system, and handle_safety_contact_post (validation + read-back). test: add tests/test_soul_guard.el — pure-function logic tests for the safe_to_seed predicate: 200KB boundary, 47MB/63-node clobber scenario, HTTP-engram mode, multiplication vs division truncation at 250KB. test: add tests/test_api_define_process.el — verifies the define_process write is read-back verified after the fix.
This commit is contained in:
@@ -368,12 +368,19 @@ let is_genesis: Bool = str_eq(soul_cgi_id, "ntn-genesis")
|
||||
// sparse but the on-disk snapshot file is large, the load FAILED — seeding+saving now would
|
||||
// clobber the user's real memory (this is exactly how the 06-14 clobber happened). Read the
|
||||
// on-disk file (local mode only) and refuse the destructive seed+save when it looks populated.
|
||||
//
|
||||
// HTTP-engram guard (2026-06-17): when ENGRAM_URL is set the HTTP Engram owns persistence —
|
||||
// the soul must NEVER write to the local snapshot regardless of node counts. safe_to_seed is
|
||||
// unconditionally false in HTTP mode (not the persistence owner).
|
||||
let guard_disk: String = if str_eq(engram_url_raw, "") { fs_read(snapshot) } else { "" }
|
||||
let guard_disk_len: Int = str_len(guard_disk)
|
||||
// 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)
|
||||
// Multiplication form (2026-06-17): node_count * 16000 < disk_len avoids floor-division truncation
|
||||
// (e.g., 250KB / 16000 = 15.6, floors to 15 — a 15-node graph wrongly passes the old guard).
|
||||
// HTTP-engram guard: when using_http_engram the soul is not the persistence owner; never seed.
|
||||
let safe_to_seed: Bool = !using_http_engram && !(guard_disk_len > 200000 && engram_node_count() * 16000 < guard_disk_len)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user