diff --git a/lang/runtime/el_runtime.c b/lang/runtime/el_runtime.c index b8eff06..81829bd 100644 --- a/lang/runtime/el_runtime.c +++ b/lang/runtime/el_runtime.c @@ -14062,12 +14062,57 @@ el_val_t engram_ground_json(el_val_t claim, el_val_t evidence, el_val_t for_whom double grounding = (rc == 0) ? gr.grounding : 0.0; if (rc == 0) engram_verify_grounding_free(&gr); const char* fw = EL_CSTR(for_whom); if (fw && !*fw) fw = NULL; - const char* cid = C->hub_id ? C->hub_id : EL_CSTR(claim); - const char* eid = E->hub_id ? E->hub_id : EL_CSTR(evidence); - int wr = cog_ground_edge(g_engram_store, cid, eid, grounding, fw); - JsonBuf b; jb_init(&b); char t[256]; - snprintf(t, sizeof t, "{\"relation\":\"grounded-by\",\"claim\":\"%s\",\"evidence\":\"%s\",\"for_whom\":\"%s\",\"grounding\":%.6g,\"written\":%s}", - cid, eid, fw ? fw : "-", grounding, wr == 0 ? "true" : "false"); + + /* GROUND THE NODE ASKED ABOUT, AND SAY WHAT WAS RESOLVED (2026-08-16 + * self-review). This wrote the grounded-by edge between the two REGION + * HUBS and then echoed those hubs back in the "claim"/"evidence" fields + * as though they were the caller's input. Three consequences, all measured + * against the live store: + * + * 1. The edge landed on a node the caller never named. Asking to ground + * 3b9ced5d against 6edf8c79 wrote an edge on 6edf8c79 -> d0406dfd, + * because those were the hubs of the two regions. + * 2. When both seeds resolve into the same region, the hubs coincide and + * the call grounds a node against ITSELF, returning grounding = 1 — + * a perfect score with no evidence behind it. Two independent agents + * hit this and reported 0.885 / 0.909 self-groundings as confident. + * 3. The echo concealed both, because the response looked exactly like a + * successful grounding of the ids that were passed in. + * + * The region is HOW a claim is evaluated; it is not WHAT the claim is + * about. So the edge attaches to the requested ids, and the resolved hubs + * are reported separately under claim_region / evidence_region. When the + * two regions coincide, the grounding is degenerate by construction and is + * reported as such rather than as a confident 1.0. */ + const char* cid = EL_CSTR(claim); + const char* eid = EL_CSTR(evidence); + const char* chub = C->hub_id ? C->hub_id : cid; + const char* ehub = E->hub_id ? E->hub_id : eid; + /* Degeneracy is broader than chub == ehub. Three circular shapes, each of + * which yields a high score for structural reasons rather than evidential + * ones, and all three were previously invisible: + * same-region both seeds resolve to one region — grounding a thing + * against itself. + * claim-in-ev the claim's region hub IS the evidence node: the evidence + * sits at the centre of the claim's own neighbourhood. + * ev-in-claim the mirror case. + * Measured: grounding 3b9ced5d against 6edf8c79 scored 0.98883 purely + * because 6edf8c79 is the hub of 3b9ced5d's region. */ + const char* degenerate = NULL; + if (chub && ehub && strcmp(chub, ehub) == 0) degenerate = "same-region"; + else if (chub && eid && strcmp(chub, eid) == 0) degenerate = "claim-region-is-evidence"; + else if (ehub && cid && strcmp(ehub, cid) == 0) degenerate = "evidence-region-is-claim"; + if (degenerate) grounding = 0.0; /* circular support is not support */ + + /* Do not write an edge for a grounding that is degenerate by construction. */ + int wr = degenerate ? -1 : cog_ground_edge(g_engram_store, cid, eid, grounding, fw); + JsonBuf b; jb_init(&b); char t[512]; + snprintf(t, sizeof t, "{\"relation\":\"grounded-by\",\"claim\":\"%s\",\"evidence\":\"%s\"," + "\"claim_region\":\"%s\",\"evidence_region\":\"%s\",\"degenerate\":%s%s%s," + "\"for_whom\":\"%s\",\"grounding\":%.6g,\"written\":%s}", + cid ? cid : "", eid ? eid : "", chub ? chub : "", ehub ? ehub : "", + degenerate ? "\"" : "false", degenerate ? degenerate : "", degenerate ? "\"" : "", + fw ? fw : "-", grounding, wr == 0 ? "true" : "false"); jb_puts(&b, t); engram_geo_free(C); engram_geo_free(E); return el_wrap_str(b.buf);