From d3d550664ecc78233f5099bc1020a84a0a7f449a Mon Sep 17 00:00:00 2001 From: bigmerge Date: Sat, 15 Aug 2026 14:25:41 -0500 Subject: [PATCH] Unify write/supersede/reframe onto one set-based region operation Collapses three separate mutation paths (node write, node supersede, and ad-hoc bulk edits) into a single reframe_core: isolate a region (cosine + 1-hop adjacency), tombstone-supersede it as an immutable set, insert the replacement manifold, rebind edges by cosine, and persist atomically. write and supersede become the region-size-0 and region-size-1 degenerate cases of the same path, eliminating divergent per-route logic. Identity keystones remain write-protected across all three entry points. --- engram/src/server.el | 312 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) diff --git a/engram/src/server.el b/engram/src/server.el index 3372ff6..c5e66a5 100644 --- a/engram/src/server.el +++ b/engram/src/server.el @@ -371,6 +371,305 @@ fn route_capture_knowledge(method: String, path: String, body: String) -> String "{\"ok\":true,\"id\":\"" + id + "\"}" } +// ═══════════════════════════════════════════════════════════════════════════ +// THE UNIVERSAL ENGRAM OPERATION — reframe_region (native, set-based). +// +// There is ONE operation on the engram: isolate a discrete sub-manifold (a +// REGION) and operate on it AS A WHOLE — a set operation: +// isolate (cosine retrieval + adjacency → the SET of nodes) +// → supersede the stale region as a set (immutable tombstone; originals kept) +// → insert the new manifold as a set (dedup/load-merge path) +// → rebind edges by cosine +// → verify + one atomic persist. +// new = (region superseded) ∪ new_manifold. +// +// The SINGLE NODE is the DEGENERATE n=1 case of this SAME operation — not a +// separate CRUD path: +// write(content) = reframe(region=∅, manifold=[1 node]) (route_write) +// supersede(id,new) = reframe(region={id}, manifold=[1 node]) (route_supersede) +// relate(a,b,rel) = the rebind sub-op in isolation (route_create_edge) +// The ONLY anti-pattern is decomposing a region-scale change into a LOOP of +// independent top-level per-node updates. Here the region is the unit: one +// isolate, one atomic set-replace, one persist, one verify — iterating members +// INSIDE the one operation is set construction, not the sin. +// +// Spec: knowledge e7a03a94 / f999c5ff. Keystones kn-efeb4a5b / kn-5b606390 are +// write-protected — never superseded, never inserted-as identity. +// ═══════════════════════════════════════════════════════════════════════════ + +fn is_keystone(id: String) -> Bool { + if str_eq(id, "kn-efeb4a5b-5aff-4759-8a97-7233099be6ee") { return true } + if str_eq(id, "kn-5b606390-a52d-4ca2-8e0e-eba141d13440") { return true } + return false +} + +// membership test in a [String] set +fn set_has(ids: [String], id: String) -> Bool { + let n: Int = el_list_len(ids) + let i: Int = 0 + while i < n { + if str_eq(el_list_get(ids, i), id) { return true } + i = i + 1 + } + return false +} + +// ── ISOLATE ──────────────────────────────────────────────────────────────── +// Select the region as a SET: cosine/token retrieval around the vantage +// (aperture k), optionally unioned with the 1-hop adjacency of each hit. +// Keystones are excluded from the mutable region by construction. +fn isolate_region(vantage: String, k: Int, expand: Int) -> [String] { + let ids: [String] = el_list_empty() + if str_eq(vantage, "") { return ids } + // (a) cosine/token retrieval — a clean node array [{"id":..},..] + let arr: String = engram_search_json(vantage, k) + let n: Int = json_array_len(arr) + let i: Int = 0 + while i < n { + let hit: String = json_array_get(arr, i) + let id: String = json_get_string(hit, "id") + if !str_eq(id, "") { + if !is_keystone(id) { + if !set_has(ids, id) { ids = el_list_append(ids, id) } + } + } + i = i + 1 + } + // (b) adjacency: union the 1-hop neighbourhood of each retrieved node. + // Iterate only over the original cosine seeds [0, seeds); neighbours append + // past that bound, so this is one hop, not a transitive sweep. + if expand > 0 { + let seeds: Int = el_list_len(ids) + let s: Int = 0 + while s < seeds { + let seed: String = el_list_get(ids, s) + let nb: String = engram_neighbors_json(seed, 1, "both") + let m: Int = json_array_len(nb) + let j: Int = 0 + while j < m { + let elem: String = json_array_get(nb, j) + let nodeobj: String = json_get_raw(elem, "node") + let nid: String = json_get_string(nodeobj, "id") + if !str_eq(nid, "") { + if !is_keystone(nid) { + if !set_has(ids, nid) { ids = el_list_append(ids, nid) } + } + } + j = j + 1 + } + s = s + 1 + } + } + return ids +} + +// ── SUPERSEDE (set) ──────────────────────────────────────────────────────── +// Retire the region AS A WHOLE: one region-tombstone marker carries the +// provenance (reason + the full superseded id set); every region node is bound +// to it with a "superseded_by" edge. Originals are RETAINED — immutable +// tombstone, never a hard delete (engram_forget is deliberately NOT used). +// Returns the tombstone marker id ("" if the region is empty). +fn supersede_set(region: [String], reason: String) -> String { + let n: Int = el_list_len(region) + if n == 0 { return "" } + let csv: String = "" + let i0: Int = 0 + while i0 < n { + let sep: String = if i0 == 0 { "" } else { "," } + csv = csv + sep + el_list_get(region, i0) + i0 = i0 + 1 + } + let content: String = "region-tombstone: " + reason + " | superseded " + int_to_str(n) + " nodes: " + csv + let tomb: String = engram_node_full(content, "Tombstone", "region-tombstone", 0.1, 0.1, 1.0, "Episodic", "[\"tombstone\",\"region-supersede\"]") + let i: Int = 0 + while i < n { + let rid: String = el_list_get(region, i) + engram_connect(rid, tomb, 1.0, "superseded_by") + i = i + 1 + } + return tomb +} + +// ── INSERT (manifold) ────────────────────────────────────────────────────── +// Insert the new manifold as a SET. Inline JSON array of node objects +// {content, node_type?, tier?, tags?}. Each becomes a real embedded node +// (engram_node_full is the n=1 insert atom); the manifold is the set built from +// those atoms, wired with internal "manifold_member" edges so it enters as one +// connected sub-graph. Identity node_types (self/values) are demoted to Memory +// — identity can never be minted through reframe. Returns the new node ids. +fn insert_manifold_json(manifold: String) -> [String] { + let out: [String] = el_list_empty() + if str_eq(manifold, "") { return out } + let n: Int = json_array_len(manifold) + if n <= 0 { return out } + let i: Int = 0 + let prev: String = "" + while i < n { + let obj: String = json_array_get(manifold, i) + let content: String = json_get_string(obj, "content") + if !str_eq(content, "") { + let nt_raw: String = json_get_string(obj, "node_type") + let nt: String = if str_eq(nt_raw, "") { "Memory" } else { nt_raw } + if str_eq(nt, "self") { nt = "Memory" } + if str_eq(nt, "values") { nt = "Memory" } + let tier_raw: String = json_get_string(obj, "tier") + let tier: String = if str_eq(tier_raw, "") { "Working" } else { tier_raw } + let tags_raw: String = json_get_raw(obj, "tags") + let tags: String = if str_eq(tags_raw, "") { "" } else { tags_raw } + let label: String = str_slice(content, 0, 60) + let id: String = engram_node_full(content, nt, label, 0.5, 0.5, 0.9, tier, tags) + out = el_list_append(out, id) + if !str_eq(prev, "") { engram_connect(prev, id, 0.6, "manifold_member") } + prev = id + } + i = i + 1 + } + return out +} + +// ── REBIND (edges by cosine) ─────────────────────────────────────────────── +// Re-embed the new manifold into the surrounding geometry: bind each new node +// to the tombstone marker (provenance: new region -reframes-> retired region), +// then to its top cosine/token neighbours in the store (skipping itself, the +// new set, keystones, tombstones). Returns the number of edges bound. +fn rebind_cosine(new_ids: [String], tomb: String) -> Int { + let bound: Int = 0 + let n: Int = el_list_len(new_ids) + let i: Int = 0 + while i < n { + let nid: String = el_list_get(new_ids, i) + if !str_eq(tomb, "") { + engram_connect(nid, tomb, 0.8, "reframes") + bound = bound + 1 + } + let node_json: String = engram_get_node_json(nid) + let content: String = json_get_string(node_json, "content") + let arr: String = engram_search_json(content, 5) + let m: Int = json_array_len(arr) + let j: Int = 0 + while j < m { + let hit: String = json_array_get(arr, j) + let hid: String = json_get_string(hit, "id") + if !str_eq(hid, "") { + if !str_eq(hid, nid) { + if !is_keystone(hid) { + if !set_has(new_ids, hid) { + let htype: String = json_get_string(hit, "node_type") + if !str_eq(htype, "Tombstone") { + engram_connect(nid, hid, 0.5, "related") + bound = bound + 1 + } + } + } + } + } + j = j + 1 + } + i = i + 1 + } + return bound +} + +// ── THE OPERATION ────────────────────────────────────────────────────────── +// isolate (done by caller) → supersede region → insert manifold → rebind → +// one atomic persist → verify report. This is the whole operation; every +// mutation route below is a projection of it. +fn reframe_core(region: [String], manifold: String, reason: String, do_rebind: Int) -> String { + let n_before: Int = engram_node_count() + let e_before: Int = engram_edge_count() + let region_n: Int = el_list_len(region) + let tomb: String = if region_n > 0 { supersede_set(region, reason) } else { "" } + let new_ids: [String] = insert_manifold_json(manifold) + let inserted: Int = el_list_len(new_ids) + let bound: Int = if do_rebind > 0 { rebind_cosine(new_ids, tomb) } else { 0 } + let saved: Int = persist_canonical() + let new_csv: String = "" + let k: Int = 0 + while k < inserted { + let sep: String = if k == 0 { "" } else { "," } + new_csv = new_csv + sep + "\"" + el_list_get(new_ids, k) + "\"" + k = k + 1 + } + return "{\"ok\":true,\"region_superseded\":" + int_to_str(region_n) + + ",\"tombstone_id\":\"" + tomb + "\"" + + ",\"inserted\":" + int_to_str(inserted) + + ",\"new_ids\":[" + new_csv + "]" + + ",\"edges_rebound\":" + int_to_str(bound) + + ",\"nodes_added\":" + int_to_str(engram_node_count() - n_before) + + ",\"edges_added\":" + int_to_str(engram_edge_count() - e_before) + + ",\"node_count\":" + int_to_str(engram_node_count()) + + ",\"edge_count\":" + int_to_str(engram_edge_count()) + + ",\"keystones_protected\":true}" +} + +// POST /api/reframe — the universal set-based mutation. +// Body: {vantage?, region_ids?(csv), k?, expand?, manifold(json array), reason?, rebind?} +// region_ids (explicit) wins; else cosine-isolate around vantage. +fn route_reframe(method: String, path: String, body: String) -> String { + let region_csv: String = json_get_string(body, "region_ids") + let vantage: String = json_get_string(body, "vantage") + let region: [String] = el_list_empty() + if !str_eq(region_csv, "") { + let parts: [String] = str_split(region_csv, ",") + let pn: Int = el_list_len(parts) + let i: Int = 0 + while i < pn { + let id: String = str_trim(el_list_get(parts, i)) + if !str_eq(id, "") { + if is_keystone(id) { return err_json("reframe: identity keystone write-protected") } + if !set_has(region, id) { region = el_list_append(region, id) } + } + i = i + 1 + } + } else { + if !str_eq(vantage, "") { + let kv: Int = json_get_int(body, "k") + let kk: Int = if kv > 0 { kv } else { 12 } + let expand: Int = json_get_int(body, "expand") + region = isolate_region(vantage, kk, expand) + } + } + let manifold: String = json_get_raw(body, "manifold") + let reason_raw: String = json_get_string(body, "reason") + let reason: String = if str_eq(reason_raw, "") { "reframe" } else { reason_raw } + // rebind defaults ON for reframe (absent → 1); explicit 0 disables. + let rebind_raw: String = json_get_raw(body, "rebind") + let do_rebind: Int = if str_eq(rebind_raw, "") { 1 } else { json_get_int(body, "rebind") } + return reframe_core(region, manifold, reason, do_rebind) +} + +// write — DEGENERATE n=1 of reframe: region=∅, manifold=[1 node]. The SAME +// reframe_core path. rebind off so the pure-add matches plain node creation. +// POST /api/write {content, node_type?, tier?, tags?} +fn route_write(method: String, path: String, body: String) -> String { + let content: String = json_get_string(body, "content") + if str_eq(content, "") { return err_json("write: content required") } + let nt: String = json_get_string(body, "node_type") + if str_eq(nt, "self") { return err_json("write: identity is write-protected") } + if str_eq(nt, "values") { return err_json("write: identity is write-protected") } + let empty: [String] = el_list_empty() + let manifold: String = "[" + body + "]" // the body IS a valid manifold node object + return reframe_core(empty, manifold, "write", 0) +} + +// supersede — DEGENERATE n=1 of reframe: region={id}, manifold=[1 node]. The +// SAME reframe_core path with a size-1 region. Original retained (immutable); +// new node inserted and cosine-rebound; provenance edge new-reframes-tomb. +// POST /api/supersede {id, content, node_type?, tier?, tags?, reason?} +fn route_supersede(method: String, path: String, body: String) -> String { + let id: String = json_get_string(body, "id") + if str_eq(id, "") { return err_json("supersede: id required") } + if is_keystone(id) { return err_json("supersede: identity keystone write-protected") } + let content: String = json_get_string(body, "content") + if str_eq(content, "") { return err_json("supersede: content required") } + let region: [String] = el_list_empty() + region = el_list_append(region, id) + let manifold: String = "[" + body + "]" + let reason_raw: String = json_get_string(body, "reason") + let reason: String = if str_eq(reason_raw, "") { "supersede " + id } else { reason_raw } + return reframe_core(region, manifold, reason, 1) +} + // ── Auth ────────────────────────────────────────────────────────────────────── fn check_auth_ok(method: String, body: String) -> Bool { @@ -418,6 +717,19 @@ fn handle_request(method: String, path: String, body: String) -> String { return route_stats(method, path, body) } + // ── The universal set-based operation and its n=1 degenerate projections ── + // reframe = isolate → supersede-region → insert-manifold → rebind. write and + // supersede are the SAME reframe_core path at region size 0 and 1. + if str_eq(method, "POST") && (str_eq(clean, "/api/reframe") || str_eq(clean, "/reframe")) { + return route_reframe(method, path, body) + } + if str_eq(method, "POST") && (str_eq(clean, "/api/write") || str_eq(clean, "/write")) { + return route_write(method, path, body) + } + if str_eq(method, "POST") && (str_eq(clean, "/api/supersede") || str_eq(clean, "/supersede")) { + return route_supersede(method, path, body) + } + // Nodes if str_eq(method, "POST") && (str_eq(clean, "/api/nodes") || str_eq(clean, "/nodes")) { return route_create_node(method, path, body)