runtime: resume the learned stance in think (#146)
El SDK CI - dev / build-and-test (push) Failing after 3m54s

This commit was merged in pull request #146.
This commit is contained in:
2026-08-16 16:44:15 +00:00
+41 -3
View File
@@ -13937,7 +13937,40 @@ static int eg_cog_is_keystone_seeds(const char* csv) {
el_val_t engram_think_json(el_val_t seeds, el_val_t faculty) {
GeoDescriptor* g = eg_geo_build_desc(EL_CSTR(seeds));
if (!g) return eg_geo_err("geometry unavailable");
CogStance st; cog_stance_init(&st, NULL, EL_CSTR(faculty), g->hub_id, NULL, g);
/* RESUME THE LEARNED STANCE (2026-08-16 self-review). This built a NEUTRAL
* stance every call all axis_gain 1.0, bias_dir NULL, reliability 0.5
* and never loaded the one the correspondence-beat had been persisting.
*
* That mattered because the faculty enters engram_think ONLY through the
* stance: `gain = stance->axis_gain[k]` warps the per-axis extents, and
* `stance->bias_dir` seeds the steering direction. cog_stance_init stores
* the faculty NAME but nothing reads it. So with a neutral stance,
* reason / abduce / induce / plan / analogize are the same function with
* different labels measured, byte-identical output across all five
* and `confidence` is pinned to the 0.5 uninformed prior, because
* GeoGradient.confidence is just stance->reliability.
*
* The machinery already existed and only this call site ignored it:
* engram_correspondence_beat_json resumes via cog_stance_from_node and
* persists via cog_stance_to_node under the id "stance-<faculty>-<hub>".
* Every beat's calibration was being written and then thrown away on the
* next read. Same defect as the NULL anchor directly above: a neutral
* argument collapsing a capability to a constant.
*
* Resume the same id the beat writes, so learning compounds across beats
* and cold boot. Fall back to neutral only when no stance exists yet
* which is a genuine uninformed prior, not a discarded informed one. */
char sid[256];
snprintf(sid, sizeof sid, "stance-%s-%s",
EL_CSTR(faculty) ? EL_CSTR(faculty) : "reason",
g->hub_id ? g->hub_id : "region");
CogStance st; StoreNode prev; int resumed = 0;
if (g_engram_store && store_get_node(g_engram_store, sid, &prev) == 1) {
if (cog_stance_from_node(&prev, &st) == 0) resumed = 1;
store_node_free(&prev);
}
if (!resumed) cog_stance_init(&st, sid, EL_CSTR(faculty), g->hub_id, NULL, g);
else { free(st.id); st.id = strdup(sid); }
GeoGradient grad;
/* ANCHOR THE READ (2026-08-16 self-review). This passed NULL, and NULL is
@@ -13999,8 +14032,13 @@ el_val_t engram_think_json(el_val_t seeds, el_val_t faculty) {
if (engram_think(g, anchor, &st, &grad) != 0) { free(anchor); cog_stance_free(&st); engram_geo_free(g); return eg_geo_err("think failed"); }
free(anchor);
JsonBuf b; jb_init(&b); char t[256];
snprintf(t, sizeof t, "{\"faculty\":\"%s\",\"n_support\":%d,\"magnitude\":%.6g,\"spread\":%.6g,\"confidence\":%.6g,\"dim\":%d",
EL_CSTR(faculty), grad.n_support, grad.magnitude, grad.spread, grad.confidence, grad.dim);
/* stance_resumed distinguishes an INFORMED read from an uninformed one.
* Without it, confidence 0.5 from a learned-but-unreliable stance and
* confidence 0.5 from "no stance exists" are indistinguishable the same
* reporting gap that let the NULL anchor and the neutral stance hide. */
snprintf(t, sizeof t, "{\"faculty\":\"%s\",\"n_support\":%d,\"magnitude\":%.6g,\"spread\":%.6g,\"confidence\":%.6g,\"stance_resumed\":%s,\"dim\":%d",
EL_CSTR(faculty), grad.n_support, grad.magnitude, grad.spread, grad.confidence,
resumed ? "true" : "false", grad.dim);
jb_puts(&b, t);
int emit = grad.dim < 8 ? grad.dim : 8;
jb_puts(&b, ",\"direction\":"); eg_geo_emit_vec(&b, grad.direction, emit);