self-review 2026-07-31: strip emb from consumer API JSON; cumulative eviction/breakthrough counters
Every node object on consumer read routes (/api/nodes, /api/search, activation results, neighbors, compiled context) carried the full ~5.7KB emb vector — responses 10-50x oversized, blowing MCP token limits. engram_emit_node_json now takes include_emb; only engram_save passes 1, so persistence and the /api/sync//api/edges replication paths (which serve engram_save output) keep embeddings intact. _eg_act_wm_evicted/_eg_act_breakthroughs were reset at the top of every engram_activate, so act_stats reported only the last call and the 60s heartbeat missed nearly all events (curiosity runs 2 activates per 30s). Both are now monotonic process-lifetime totals; consumers diff readings.
This commit is contained in:
Vendored
BIN
Binary file not shown.
@@ -6022,10 +6022,17 @@ static int64_t _eg_embed_breaker_until = 0;
|
|||||||
* The executive-filter pathologies this system has repeatedly debugged by
|
* The executive-filter pathologies this system has repeatedly debugged by
|
||||||
* inference (WM flooded with breakthrough-floor nodes, silent cap evictions,
|
* inference (WM flooded with breakthrough-floor nodes, silent cap evictions,
|
||||||
* embedder wedged behind the breaker) were all invisible: no ISE, no stats
|
* embedder wedged behind the breaker) were all invisible: no ISE, no stats
|
||||||
* field. These per-call counters record what the LAST engram_activate did;
|
* field. engram_act_stats_json() exposes them so the soul heartbeat can emit
|
||||||
* engram_act_stats_json() exposes them so the soul heartbeat can emit them. */
|
* them.
|
||||||
static int64_t _eg_act_breakthroughs = 0; /* forced promotions at the floor */
|
*
|
||||||
static int64_t _eg_act_wm_evicted = 0; /* Pass 4 over-cap evictions */
|
* CUMULATIVE CONTRACT (2026-07-31 self-review): these are monotonic totals
|
||||||
|
* for the process lifetime, like pulse/sync_added_total — NOT per-call. The
|
||||||
|
* original per-call reset meant engram_act_stats_json only reported the LAST
|
||||||
|
* activate call, and the 60s heartbeat (2 curiosity activates per 30s in
|
||||||
|
* between) missed nearly every eviction/breakthrough event. Consumers wanting
|
||||||
|
* rates keep the previous reading and diff. Restart legitimately resets to 0. */
|
||||||
|
static int64_t _eg_act_breakthroughs = 0; /* forced promotions at the floor, cumulative */
|
||||||
|
static int64_t _eg_act_wm_evicted = 0; /* Pass 4 over-cap evictions, cumulative */
|
||||||
|
|
||||||
static int64_t engram_now_ms(void); /* defined in the store section below */
|
static int64_t engram_now_ms(void); /* defined in the store section below */
|
||||||
|
|
||||||
@@ -6724,7 +6731,7 @@ static el_val_t engram_node_to_map(const EngramNode* n) {
|
|||||||
|
|
||||||
/* (Node JSON serialization is provided by `engram_emit_node_json` further
|
/* (Node JSON serialization is provided by `engram_emit_node_json` further
|
||||||
* down in the persistence section — reused by the *_json builtins below.) */
|
* down in the persistence section — reused by the *_json builtins below.) */
|
||||||
static void engram_emit_node_json(JsonBuf* b, const EngramNode* n);
|
static void engram_emit_node_json(JsonBuf* b, const EngramNode* n, int include_emb);
|
||||||
static void engram_emit_edge_json(JsonBuf* b, const EngramEdge* e);
|
static void engram_emit_edge_json(JsonBuf* b, const EngramEdge* e);
|
||||||
|
|
||||||
/* Salience may arrive either as a float bit-pattern or as a small integer
|
/* Salience may arrive either as a float bit-pattern or as a small integer
|
||||||
@@ -7659,9 +7666,11 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
|||||||
|
|
||||||
int64_t now_ms = engram_now_ms();
|
int64_t now_ms = engram_now_ms();
|
||||||
|
|
||||||
/* Reset per-call observability counters (2026-07-27). */
|
/* Observability counters: _eg_act_breakthroughs/_eg_act_wm_evicted are
|
||||||
_eg_act_breakthroughs = 0;
|
* CUMULATIVE for the process lifetime and intentionally NOT reset here
|
||||||
_eg_act_wm_evicted = 0;
|
* (2026-07-31 self-review — the old per-call reset made the 60s heartbeat
|
||||||
|
* miss nearly all events between beats; see the definition site).
|
||||||
|
* ctx_cos stays per-call: it is a gauge of THIS query vs the centroid. */
|
||||||
_eg_act_ctx_cos = -2.0;
|
_eg_act_ctx_cos = -2.0;
|
||||||
|
|
||||||
/* ── Embedding backfill + query embedding (2026-07-24, bl-b2d1c944) ──
|
/* ── Embedding backfill + query embedding (2026-07-24, bl-b2d1c944) ──
|
||||||
@@ -8411,7 +8420,13 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
|
|||||||
|
|
||||||
/* ── Engram persistence (JSON snapshot) ─────────────────────────────────── */
|
/* ── Engram persistence (JSON snapshot) ─────────────────────────────────── */
|
||||||
|
|
||||||
static void engram_emit_node_json(JsonBuf* b, const EngramNode* n) {
|
/* include_emb (2026-07-31 self-review): the ~5.7KB "emb" vector belongs ONLY
|
||||||
|
* in persistence/replication output (engram_save → snapshot.json, which also
|
||||||
|
* backs /api/sync and /api/edges via scratch exports). Consumer read routes
|
||||||
|
* (/api/nodes, /api/search, activation results, neighbors, compiled context)
|
||||||
|
* were shipping it on every node — responses 10-50x oversized, blowing MCP
|
||||||
|
* token limits. Pass include_emb=1 only from engram_save. */
|
||||||
|
static void engram_emit_node_json(JsonBuf* b, const EngramNode* n, int include_emb) {
|
||||||
jb_putc(b, '{');
|
jb_putc(b, '{');
|
||||||
jb_puts(b, "\"id\":"); jb_emit_escaped(b, n->id ? n->id : "");
|
jb_puts(b, "\"id\":"); jb_emit_escaped(b, n->id ? n->id : "");
|
||||||
jb_puts(b, ",\"content\":"); jb_emit_escaped(b, n->content ? n->content : "");
|
jb_puts(b, ",\"content\":"); jb_emit_escaped(b, n->content ? n->content : "");
|
||||||
@@ -8454,7 +8469,7 @@ static void engram_emit_node_json(JsonBuf* b, const EngramNode* n) {
|
|||||||
* insensitive to 4-sig-fig rounding, and this keeps snapshot bloat to
|
* insensitive to 4-sig-fig rounding, and this keeps snapshot bloat to
|
||||||
* ~5KB per embedded node without a base64 codec. Absent field = not
|
* ~5KB per embedded node without a base64 codec. Absent field = not
|
||||||
* embedded; the lazy backfill re-embeds eventually if dropped. */
|
* embedded; the lazy backfill re-embeds eventually if dropped. */
|
||||||
if (n->emb && n->emb_dim > 0) {
|
if (include_emb && n->emb && n->emb_dim > 0) {
|
||||||
jb_puts(b, ",\"emb\":\"");
|
jb_puts(b, ",\"emb\":\"");
|
||||||
for (int32_t j = 0; j < n->emb_dim; j++) {
|
for (int32_t j = 0; j < n->emb_dim; j++) {
|
||||||
snprintf(tmp, sizeof(tmp), "%s%.4g", j ? "," : "",
|
snprintf(tmp, sizeof(tmp), "%s%.4g", j ? "," : "",
|
||||||
@@ -8492,7 +8507,7 @@ el_val_t engram_save(el_val_t path) {
|
|||||||
jb_puts(&b, "{\"nodes\":[");
|
jb_puts(&b, "{\"nodes\":[");
|
||||||
for (int64_t i = 0; i < g->node_count; i++) {
|
for (int64_t i = 0; i < g->node_count; i++) {
|
||||||
if (i > 0) jb_putc(&b, ',');
|
if (i > 0) jb_putc(&b, ',');
|
||||||
engram_emit_node_json(&b, &g->nodes[i]);
|
engram_emit_node_json(&b, &g->nodes[i], 1);
|
||||||
}
|
}
|
||||||
jb_puts(&b, "],\"edges\":[");
|
jb_puts(&b, "],\"edges\":[");
|
||||||
for (int64_t i = 0; i < g->edge_count; i++) {
|
for (int64_t i = 0; i < g->edge_count; i++) {
|
||||||
@@ -9025,7 +9040,7 @@ el_val_t engram_get_node_json(el_val_t id) {
|
|||||||
EngramNode* n = engram_find_node(sid);
|
EngramNode* n = engram_find_node(sid);
|
||||||
if (!n) return el_wrap_str(el_strdup("{}"));
|
if (!n) return el_wrap_str(el_strdup("{}"));
|
||||||
JsonBuf b; jb_init(&b);
|
JsonBuf b; jb_init(&b);
|
||||||
engram_emit_node_json(&b, n);
|
engram_emit_node_json(&b, n, 0);
|
||||||
return el_wrap_str(b.buf);
|
return el_wrap_str(b.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9050,7 +9065,7 @@ el_val_t engram_get_node_by_label(el_val_t label) {
|
|||||||
EngramNode* n = &g->nodes[i];
|
EngramNode* n = &g->nodes[i];
|
||||||
if (n->label && strcmp(n->label, lbl) == 0) {
|
if (n->label && strcmp(n->label, lbl) == 0) {
|
||||||
JsonBuf b; jb_init(&b);
|
JsonBuf b; jb_init(&b);
|
||||||
engram_emit_node_json(&b, n);
|
engram_emit_node_json(&b, n, 0);
|
||||||
return el_wrap_str(b.buf);
|
return el_wrap_str(b.buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9091,7 +9106,7 @@ el_val_t engram_search_json(el_val_t query, el_val_t limit) {
|
|||||||
int64_t end = nhits < lim ? nhits : lim;
|
int64_t end = nhits < lim ? nhits : lim;
|
||||||
for (int64_t k = 0; k < end; k++) {
|
for (int64_t k = 0; k < end; k++) {
|
||||||
if (!first) jb_putc(&b, ',');
|
if (!first) jb_putc(&b, ',');
|
||||||
engram_emit_node_json(&b, &g->nodes[hits[k].idx]);
|
engram_emit_node_json(&b, &g->nodes[hits[k].idx], 0);
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
free(hits);
|
free(hits);
|
||||||
@@ -9123,7 +9138,7 @@ el_val_t engram_scan_nodes_json(el_val_t limit, el_val_t offset) {
|
|||||||
int first = 1;
|
int first = 1;
|
||||||
for (int64_t i = off; i < end; i++) {
|
for (int64_t i = off; i < end; i++) {
|
||||||
if (!first) jb_putc(&b, ',');
|
if (!first) jb_putc(&b, ',');
|
||||||
engram_emit_node_json(&b, &g->nodes[idx[i]]);
|
engram_emit_node_json(&b, &g->nodes[idx[i]], 0);
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
free(idx);
|
free(idx);
|
||||||
@@ -9160,7 +9175,7 @@ el_val_t engram_scan_nodes_by_type_json(el_val_t type_v, el_val_t limit, el_val_
|
|||||||
int first = 1;
|
int first = 1;
|
||||||
for (int64_t i = off; i < end; i++) {
|
for (int64_t i = off; i < end; i++) {
|
||||||
if (!first) jb_putc(&b, ',');
|
if (!first) jb_putc(&b, ',');
|
||||||
engram_emit_node_json(&b, &g->nodes[idx[i]]);
|
engram_emit_node_json(&b, &g->nodes[idx[i]], 0);
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
free(idx);
|
free(idx);
|
||||||
@@ -9224,7 +9239,7 @@ el_val_t engram_neighbors_json(el_val_t node_id, el_val_t max_depth, el_val_t di
|
|||||||
if (!n) continue;
|
if (!n) continue;
|
||||||
if (!first) jb_putc(&b, ',');
|
if (!first) jb_putc(&b, ',');
|
||||||
jb_puts(&b, "{\"node\":");
|
jb_puts(&b, "{\"node\":");
|
||||||
engram_emit_node_json(&b, n);
|
engram_emit_node_json(&b, n, 0);
|
||||||
jb_puts(&b, ",\"edge\":");
|
jb_puts(&b, ",\"edge\":");
|
||||||
engram_emit_edge_json(&b, e);
|
engram_emit_edge_json(&b, e);
|
||||||
char tmp[64]; snprintf(tmp, sizeof(tmp), ",\"hops\":%lld}", (long long)(h + 1));
|
char tmp[64]; snprintf(tmp, sizeof(tmp), ",\"hops\":%lld}", (long long)(h + 1));
|
||||||
@@ -9267,7 +9282,7 @@ el_val_t engram_activate_json(el_val_t query, el_val_t depth) {
|
|||||||
if (i > 0) jb_putc(&b, ',');
|
if (i > 0) jb_putc(&b, ',');
|
||||||
jb_puts(&b, "{\"node\":");
|
jb_puts(&b, "{\"node\":");
|
||||||
if (n) {
|
if (n) {
|
||||||
engram_emit_node_json(&b, n);
|
engram_emit_node_json(&b, n, 0);
|
||||||
} else {
|
} else {
|
||||||
jb_puts(&b, "{}");
|
jb_puts(&b, "{}");
|
||||||
}
|
}
|
||||||
@@ -9404,9 +9419,11 @@ el_val_t engram_stats_json(void) {
|
|||||||
return el_wrap_str(el_strdup(buf));
|
return el_wrap_str(el_strdup(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* engram_act_stats_json — per-call activation observability + embedder
|
/* engram_act_stats_json — activation observability + embedder breaker state.
|
||||||
* breaker state. (2026-07-27 self-review.) wm_evicted/breakthroughs describe
|
* (2026-07-27 self-review; counters made cumulative 2026-07-31.)
|
||||||
* the LAST engram_activate call on this store; embed_breaker_open=1 means
|
* wm_evicted/breakthroughs are monotonic process-lifetime totals across ALL
|
||||||
|
* engram_activate calls on this store (diff successive readings for rates;
|
||||||
|
* they reset to 0 only on restart); embed_breaker_open=1 means
|
||||||
* eg_embed_fetch is currently refusing calls (semantic activation silently
|
* eg_embed_fetch is currently refusing calls (semantic activation silently
|
||||||
* degraded to lexical until the cooldown expires). The soul heartbeat folds
|
* degraded to lexical until the cooldown expires). The soul heartbeat folds
|
||||||
* this into its ISE so the pathologies are diagnosable from telemetry
|
* this into its ISE so the pathologies are diagnosable from telemetry
|
||||||
@@ -9593,7 +9610,7 @@ el_val_t engram_compile_layered_json(el_val_t intent, el_val_t depth) {
|
|||||||
jb_puts(&b, "[LAYER 0 — STRUCTURAL]\n");
|
jb_puts(&b, "[LAYER 0 — STRUCTURAL]\n");
|
||||||
wrote_layer0 = 1;
|
wrote_layer0 = 1;
|
||||||
}
|
}
|
||||||
engram_emit_node_json(&b, n);
|
engram_emit_node_json(&b, n, 0);
|
||||||
jb_putc(&b, '\n');
|
jb_putc(&b, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9606,7 +9623,7 @@ el_val_t engram_compile_layered_json(el_val_t intent, el_val_t depth) {
|
|||||||
jb_puts(&b, "[ENGRAM CONTEXT]\n");
|
jb_puts(&b, "[ENGRAM CONTEXT]\n");
|
||||||
wrote_normal = 1;
|
wrote_normal = 1;
|
||||||
}
|
}
|
||||||
engram_emit_node_json(&b, n);
|
engram_emit_node_json(&b, n, 0);
|
||||||
jb_putc(&b, '\n');
|
jb_putc(&b, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9656,7 +9673,7 @@ el_val_t engram_query_range(el_val_t start_ms_v, el_val_t end_ms_v) {
|
|||||||
jb_putc(&b, '[');
|
jb_putc(&b, '[');
|
||||||
for (int64_t i = 0; i < mc; i++) {
|
for (int64_t i = 0; i < mc; i++) {
|
||||||
if (i > 0) jb_putc(&b, ',');
|
if (i > 0) jb_putc(&b, ',');
|
||||||
engram_emit_node_json(&b, &g->nodes[idx[i]]);
|
engram_emit_node_json(&b, &g->nodes[idx[i]], 0);
|
||||||
}
|
}
|
||||||
jb_putc(&b, ']');
|
jb_putc(&b, ']');
|
||||||
free(idx);
|
free(idx);
|
||||||
|
|||||||
Reference in New Issue
Block a user