/* test_m3_parity.c — M3 JSON-parity gate for the ENGRAM_STORE wiring. * * This is a REAL el-level harness: it links the actual el_runtime.o (the soul's * native engram builtins) + engram_store.o and calls the engram_node family plus * engram_connect, engram_activate_json, engram_save, engram_store_boot directly. No EL interpreter * and no full soul build are needed — el_runtime.c compiles to a standalone .o * whose engram builtins operate on the process-global engram store, and the * string arena is inert unless el_request_start() is called, so the builtins are * callable straight from C (el_val_t is int64_t; EL_STR/EL_CSTR are pointer casts). * * Modes (argv[1]), data dir (argv[2]): * seed — ENGRAM_STORE unset: build a fixed seed graph, write snapshot.json + * off_graph.json (pristine, pre-activation), then activate → off_act.json. * on — ENGRAM_STORE=1: engram_store_boot(dir) imports snapshot.json ONCE into * neuron.egm and loads it resident; write on_graph.json, then activate → * on_act.json; checkpoint + close. * reboot — ENGRAM_STORE=1 with snapshot.json DELETED: boot must reload from * neuron.egm (WAL replay), never re-reading JSON; write reboot_graph.json. * offcheck — assert flag-off leaves the store untouched. * * The graph comparison (done by run_m3_parity.sh via python, modulo ordering) is * the deterministic gate; activation ids/promoted are compared as a robust set. */ #include "el_runtime.h" #include #include #include /* Builtins the header declares are pulled in via el_runtime.h. The M3 additions * are not in the header yet, so declare them here. */ extern int engram_store_enabled(void); extern el_val_t engram_store_boot(el_val_t data_dir); extern el_val_t engram_store_checkpoint(void); extern el_val_t engram_store_close(void); extern el_val_t engram_node_layered(el_val_t content, el_val_t node_type, el_val_t label, el_val_t salience, el_val_t certainty, el_val_t confidence, el_val_t status, el_val_t tags, el_val_t layer_id); static el_val_t S(const char* s){ return EL_STR(s); } static el_val_t F(double d){ return el_from_float(d); } /* Build a fixed, deterministic seed graph: 12 nodes across two layers + 9 edges. * Content is chosen so an activation query has real matches to rank. */ static void build_seed(void){ /* core-identity layer (1) via engram_node_full */ el_val_t n0 = engram_node_full(S("tiered storage engine design"), S("Concept"), S("storage-engine"), F(0.9), F(0.8), F(1.0), S("Semantic"), S("design,storage")); el_val_t n1 = engram_node_full(S("write-ahead log durability"), S("Concept"), S("wal"), F(0.85), F(0.75), F(1.0), S("Semantic"), S("wal,durability")); el_val_t n2 = engram_node_full(S("paged buffer pool with checkpointing"), S("Concept"), S("buffer-pool"), F(0.8), F(0.7), F(1.0), S("Semantic"), S("paging")); el_val_t n3 = engram_node_full(S("spreading activation over the graph"), S("Concept"), S("activation"), F(0.8), F(0.7), F(1.0), S("Semantic"), S("activation,graph")); el_val_t n4 = engram_node_full(S("hebbian co-activation potentiation"), S("Concept"), S("hebbian"), F(0.7), F(0.6), F(1.0), S("Semantic"), S("hebb")); el_val_t n5 = engram_node_full(S("crash recovery replays the log"), S("Concept"), S("recovery"), F(0.75), F(0.65), F(1.0), S("Semantic"), S("recovery,wal")); /* domain-knowledge layer (2) via engram_node_layered */ el_val_t n6 = engram_node_layered(S("b-tree primary index id to location"), S("Fact"), S("btree"), F(0.7), F(0.6), F(1.0), S(""), S("index"), (el_val_t)2); el_val_t n7 = engram_node_layered(S("adjacency index for edge lookup"), S("Fact"), S("adjacency"), F(0.7), F(0.6), F(1.0), S(""), S("index,graph"), (el_val_t)2); el_val_t n8 = engram_node_layered(S("slotted pages hold tlv records"), S("Fact"), S("slotted-page"), F(0.65), F(0.55), F(1.0), S(""), S("format"), (el_val_t)2); el_val_t n9 = engram_node_full(S("memory tiers working semantic episodic"), S("Concept"), S("tiers"), F(0.7), F(0.6), F(1.0), S("Semantic"), S("tiers,memory")); el_val_t n10 = engram_node_full(S("embeddings enable nearest neighbour search"), S("Concept"), S("embeddings"), F(0.65), F(0.55), F(1.0), S("Semantic"), S("embeddings")); el_val_t n11 = engram_node_full(S("the durable engram is the mind's memory"), S("Belief"), S("engram"), F(0.95), F(0.9), F(1.0), S("Semantic"), S("engram,memory")); engram_connect(n0, n1, F(0.8), S("depends-on")); engram_connect(n0, n2, F(0.8), S("depends-on")); engram_connect(n0, n3, F(0.7), S("enables")); engram_connect(n1, n5, F(0.9), S("enables")); engram_connect(n3, n4, F(0.6), S("triggers")); engram_connect(n2, n6, F(0.7), S("uses")); engram_connect(n3, n7, F(0.7), S("uses")); engram_connect(n0, n8, F(0.6), S("uses")); engram_connect(n11, n9, F(0.8), S("about")); engram_connect(n11, n10, F(0.5), S("about")); } static void write_file(const char* path, const char* content){ FILE* f = fopen(path, "wb"); if (!f){ fprintf(stderr, "cannot open %s\n", path); exit(2); } if (content) fwrite(content, 1, strlen(content), f); fclose(f); } static const char* QUERY = "storage engine activation and the durable log"; int main(int argc, char** argv){ if (argc < 3){ fprintf(stderr, "usage: %s \n", argv[0]); return 2; } const char* mode = argv[1]; const char* dir = argv[2]; char p[1024]; if (!strcmp(mode, "seed")){ if (engram_store_enabled()){ fprintf(stderr, "seed mode requires ENGRAM_STORE unset\n"); return 2; } build_seed(); snprintf(p, sizeof p, "%s/snapshot.json", dir); if (!engram_save(S(p))){ fprintf(stderr, "seed save failed\n"); return 2; } snprintf(p, sizeof p, "%s/off_graph.json", dir); engram_save(S(p)); /* pristine off-path graph */ el_val_t act = engram_activate_json(S(QUERY), (el_val_t)3); snprintf(p, sizeof p, "%s/off_act.json", dir); write_file(p, EL_CSTR(act)); printf("[seed] nodes=%lld edges=%lld\n", (long long)(int64_t)engram_node_count(), (long long)(int64_t)engram_edge_count()); return 0; } if (!strcmp(mode, "on")){ if (!engram_store_enabled()){ fprintf(stderr, "on mode requires ENGRAM_STORE=1\n"); return 2; } if (!engram_store_boot(S(dir))){ fprintf(stderr, "store boot failed\n"); return 2; } snprintf(p, sizeof p, "%s/on_graph.json", dir); engram_save(S(p)); /* export resident (== store) */ /* Checkpoint the freshly-imported (pristine) graph — this is the state * the reboot comparison expects to round-trip. Under M3.5 a checkpoint * persists the resident graph's CURRENT field state, so it must run * BEFORE activation mutates fields in place; activation itself is * exercised below only for the activation-result-set parity check. The * M3.5 gate (test_m35_hebb_persist) separately proves that a checkpoint * taken AFTER activation durably carries the learned hebb/WM state. */ engram_store_checkpoint(); el_val_t act = engram_activate_json(S(QUERY), (el_val_t)3); snprintf(p, sizeof p, "%s/on_act.json", dir); write_file(p, EL_CSTR(act)); printf("[on] nodes=%lld edges=%lld\n", (long long)(int64_t)engram_node_count(), (long long)(int64_t)engram_edge_count()); engram_store_close(); return 0; } if (!strcmp(mode, "reboot")){ if (!engram_store_enabled()){ fprintf(stderr, "reboot mode requires ENGRAM_STORE=1\n"); return 2; } /* snapshot.json has been deleted by the runner — boot MUST come from * neuron.egm (+ WAL replay), never re-reading JSON. */ if (!engram_store_boot(S(dir))){ fprintf(stderr, "reboot boot failed\n"); return 2; } snprintf(p, sizeof p, "%s/reboot_graph.json", dir); engram_save(S(p)); printf("[reboot] nodes=%lld edges=%lld\n", (long long)(int64_t)engram_node_count(), (long long)(int64_t)engram_edge_count()); engram_store_close(); return 0; } if (!strcmp(mode, "offcheck")){ /* ENGRAM_STORE unset: enabled()==0 and boot is a no-op returning 0. */ int en = engram_store_enabled(); el_val_t b = engram_store_boot(S(dir)); printf("[offcheck] enabled=%d boot_ret=%lld\n", en, (long long)(int64_t)b); return (en == 0 && (int64_t)b == 0) ? 0 : 1; } fprintf(stderr, "unknown mode %s\n", mode); return 2; }