From 7f03876e2698d8080ee884411b801a7723e416a0 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Sat, 1 Aug 2026 08:38:51 -0500 Subject: [PATCH] self-review 2026-08-01: fix double-encode score mangling; expose similarity probe; presence-aware defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - route_create_node passed already-boxed Floats through el_from_float a second time, reinterpreting boxed bits as raw doubles — every HTTP-created node silently stored default salience/importance/confidence regardless of input (verified live: 0.9/0.25/0.6 in -> 0.5/0.5/1.0 stored). Floats now passed bare, matching the route_emit_ise pattern that always worked. - Presence-aware defaults via json_get_raw: absent key != explicit value; confidence now honored from payload instead of hardcoded 1.0. - GET /api/similarity?a=&b= wires engram_cosine_sim (built 2026-07-24, zero callers until now) into the introspection API. - /health reports live node/edge counts instead of a hardcoded literal. --- engram/src/server.el | 63 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/engram/src/server.el b/engram/src/server.el index 6689ed8..ace3047 100644 --- a/engram/src/server.el +++ b/engram/src/server.el @@ -111,22 +111,39 @@ fn persist_canonical() -> Int { // Observed live: the soul's boot-counter write-back landed with // label="soul:boot_count:99" (content), importance 0.5, no tags. Honor the // full field set via engram_node_full when any of them is supplied. +// PRESENCE-AWARE DEFAULTS (2026-08-01 self-review): the old pattern +// `if x == 0.0 { default }` made a legitimate 0.0 unrepresentable — a caller +// setting salience/importance/weight to zero silently got 0.5. json_get_raw +// returns "" when the key is ABSENT and the raw token when present, so +// absence and zero are now distinguishable. Also: confidence was hardcoded +// to 1.0 regardless of input — every HTTP-created node claimed full +// epistemic confidence. Now honored from the payload (default 1.0). fn route_create_node(method: String, path: String, body: String) -> String { let content: String = json_get_string(body, "content") let nt_raw: String = json_get_string(body, "node_type") let node_type: String = if str_eq(nt_raw, "") { "Memory" } else { nt_raw } - let sal_raw: Float = json_get_float(body, "salience") - let salience: Float = if sal_raw == 0.0 { 0.5 } else { sal_raw } + let sal_present: String = json_get_raw(body, "salience") + let salience: Float = if str_eq(sal_present, "") { 0.5 } else { json_get_float(body, "salience") } let label_raw: String = json_get_string(body, "label") let label: String = if str_eq(label_raw, "") { content } else { label_raw } - let imp_raw: Float = json_get_float(body, "importance") - let importance: Float = if imp_raw == 0.0 { 0.5 } else { imp_raw } + let imp_present: String = json_get_raw(body, "importance") + let importance: Float = if str_eq(imp_present, "") { 0.5 } else { json_get_float(body, "importance") } + let conf_present: String = json_get_raw(body, "confidence") + let confidence: Float = if str_eq(conf_present, "") { 1.0 } else { json_get_float(body, "confidence") } let tier_raw: String = json_get_string(body, "tier") let tier: String = if str_eq(tier_raw, "") { "Working" } else { tier_raw } let tags: String = json_get_string(body, "tags") + // NO el_from_float WRAPPER (2026-08-01 self-review): salience/importance/ + // confidence are already Float (el_val_t) values — json_get_float and + // Float literals both encode. Wrapping them in el_from_float AGAIN + // reinterpreted the boxed bits as a raw double, producing garbage that + // failed engram_decode_score's range check and clamped every HTTP-created + // node to defaults (salience 0.9 in → 0.5 stored; confidence 0.6 in → 1.0 + // stored — verified live). route_emit_ise always passed Floats bare and + // its 0.3/0.3/0.8 stored correctly; this call now does the same. let id: String = engram_node_full( content, node_type, label, - el_from_float(salience), el_from_float(importance), el_from_float(1.0), + salience, importance, confidence, tier, tags ) let saved: Int = persist_canonical() @@ -194,8 +211,10 @@ fn route_create_edge(method: String, path: String, body: String) -> String { let to_id: String = json_get_string(body, "to_id") let rel_raw: String = json_get_string(body, "relation") let relation: String = if str_eq(rel_raw, "") { "associates" } else { rel_raw } - let w_raw: Float = json_get_float(body, "weight") - let weight: Float = if w_raw == 0.0 { 0.5 } else { w_raw } + // Presence-aware (2026-08-01): weight 0.0 is a legitimate edge weight + // (dormant association); only default when the key is absent. + let w_present: String = json_get_raw(body, "weight") + let weight: Float = if str_eq(w_present, "") { 0.5 } else { json_get_float(body, "weight") } engram_connect(from_id, to_id, weight, relation) let saved: Int = persist_canonical() "{\"ok\":true,\"from_id\":\"" + from_id + "\",\"to_id\":\"" + to_id + "\",\"relation\":\"" + relation + "\"}" @@ -242,8 +261,12 @@ fn route_load(method: String, path: String, body: String) -> String { ok_json() } +// (2026-08-01 self-review) Health previously returned a hardcoded literal — +// it reported "ok" even when the snapshot failed to load and the store was +// empty. Now reports live counts so a monitor can distinguish "up and +// loaded" from "up and hollow" (node_count=0 after boot = failed load). fn route_health(method: String, path: String, body: String) -> String { - "{\"status\":\"ok\",\"engine\":\"engram-runtime-native\"}" + "{\"status\":\"ok\",\"engine\":\"engram-runtime-native\",\"node_count\":" + int_to_str(engram_node_count()) + ",\"edge_count\":" + int_to_str(engram_edge_count()) + "}" } // route_embed_backfill — GET/POST /api/embed-backfill?n=48 @@ -410,6 +433,25 @@ fn route_capture_knowledge(method: String, path: String, body: String) -> String "{\"ok\":true,\"id\":\"" + id + "\"}" } +// route_similarity — GET /api/similarity?a=&b= +// +// (2026-08-01 self-review) engram_cosine_sim was added 2026-07-24 +// (bl-b2d1c944) with the stated purpose of exposing semantic distance to +// "EL code and the introspection API" — but it had ZERO callers anywhere: +// no route, no soul-daemon use. The activation path uses embeddings +// internally (semantic seeding, Pass-2 additive term), but there was no way +// to probe pairwise node similarity from outside. This closes that: cosine +// in [-1,1], or -2 when either node is missing or not yet embedded (so +// "not comparable" is distinguishable from "genuinely orthogonal" 0.0). +fn route_similarity(method: String, path: String, body: String) -> String { + let a: String = query_param(path, "a") + let b: String = query_param(path, "b") + if str_eq(a, "") { return err_json("missing a") } + if str_eq(b, "") { return err_json("missing b") } + let sim: Float = engram_cosine_sim(a, b) + "{\"a\":\"" + a + "\",\"b\":\"" + b + "\",\"cosine\":" + float_to_str(sim) + "}" +} + // ── Auth ────────────────────────────────────────────────────────────────────── fn check_auth_ok(method: String, body: String) -> Bool { @@ -522,6 +564,11 @@ fn handle_request(method: String, path: String, body: String) -> String { return route_embed_backfill(method, path, body) } + // Semantic similarity probe (2026-08-01) + if str_eq(method, "GET") && str_starts_with(clean, "/api/similarity") { + return route_similarity(method, path, body) + } + "{\"error\":\"not found\",\"path\":\"" + clean + "\"}" }