M9: env-gated geometry priming in engram_activate (ENGRAM_GEOMETRY_PRIMING, default OFF)

Wire the centered relational-neighborhood geometry (engram_geometry.c) into
activation seed selection behind a reversible env flag that defaults OFF. Flag
unset => byte-identical to M8 (verified: identical result id sequence + order
across 15 queries vs the M8 baseline binary). When set, composes with M8's ANN
candidate generation: damp-only seed reweight by centered membership
(disambiguation) + sub-threshold neighborhood priming (warm floor below the WM
gate, capped, ISE-skipped). Safe because the BFS keeps the max, so priming only
raises a floor and can never cap a legitimate activation.

Descriptor + global mean run over the paged store; the resident-array vindex is
bridged with a vids[] map. Tunables via env (SEED_LO/PRIME_SCALE/PRIME_MAX).

Default-OFF binary is behavior-neutral and safe to deploy. Enabling the flag is
currently NO-GO on cost/benefit: 3.2x median / 13x p90 latency for no reliable
coherence/disambiguation gain (see perf profile). Not a defect - WM cap holds,
no crash, ASan/UBSan clean.
This commit is contained in:
2026-08-12 20:29:16 -05:00
parent 8cae0f94eb
commit 7946b98d3d
+154
View File
@@ -6540,6 +6540,9 @@ static int64_t _eg_act_wm_evicted = 0; /* ALL WM evictions, cumulative (see b
* candidate's content. Both cumulative for the process lifetime. */
static int64_t _eg_act_dup_seeds = 0;
static int64_t _eg_act_dup_wm = 0;
/* M9 geometry priming: sub-threshold neighborhood members primed by the centered
* geometry (ENGRAM_GEOMETRY_PRIMING). Cumulative; stays 0 when the flag is off. */
static int64_t _eg_act_geo_primed = 0;
/* Redundant WM residents evicted by the GLOBAL pass (2026-08-06). Counted
* separately from _eg_act_dup_wm on purpose: dup_wm measures duplicates caught
* among this call's candidates, dup_wm_global measures duplicates that reached
@@ -7433,6 +7436,7 @@ static char* engram_first_n_chars(const char* s, size_t n) {
* */
#include "engram_store.h"
#include "engram_vindex.h" /* M8: ANN (HNSW) index for activation seed selection */
#include "engram_geometry.h" /* M9: centered relational-neighborhood geometry (priming) */
static EngramPagedStore* g_engram_store = NULL;
@@ -9016,6 +9020,62 @@ static VIndex* eg_vindex_sync(EngramStore* g, int32_t dim) {
return _eg_vindex;
}
/* ── M9 GEOMETRY PRIMING (ENGRAM_GEOMETRY_PRIMING, default OFF) ──────────────
* Opt-in wiring of the centered relational-neighborhood geometry (engram_geometry.c)
* into activation seed selection. When the flag is UNSET or "0" every code path
* below is skipped and engram_activate is byte-identical to M8. When set, after
* M8 has produced its ANN seed set, the centered geometry of that neighborhood is
* used to (a) DAMP off-domain seeds by centered membership (disambiguation) and
* (b) PRIME nearby neighborhood members sub-threshold (warm floor). It COMPOSES
* with M8 it never removes an M8 seed nor changes ANN candidate discovery.
*
* The geometry descriptor + global-mean run over the PAGED store (g_engram_store)
* by string id; the runtime's resident-array VIndex is passed through with a
* vids[] map (vids[i] == g->nodes[i].id) so its ordinals resolve. This is the
* behaviour-changing M9 step gated behind a reversible flag see runbook
* 2026-08-12-geometry-priming-cutover-reversal.md. */
static int eg_geometry_priming_on(void) {
static int cached = -1;
if (cached < 0) {
const char* s = getenv("ENGRAM_GEOMETRY_PRIMING");
cached = (s && s[0] && s[0] != '0') ? 1 : 0;
}
return cached;
}
/* Runtime-owned centered-frame global mean over the paged store's embedded set.
* Built lazily on first priming call, recomputed only when the embedded count
* drifts >10% (engram_geo_mean_maybe_refresh). Process-lifetime, single-threaded,
* alongside _eg_vindex. Returns NULL if unavailable (no paged store / no embeds /
* dim mismatch) caller falls back to pure-M8 behaviour for that call. */
static GeoMeanCache* _eg_geo_mean = NULL;
static const float* eg_geo_mean_sync(int32_t dim) {
if (!g_engram_store || dim <= 0) return NULL;
if (!_eg_geo_mean) {
_eg_geo_mean = engram_geo_mean_build(g_engram_store);
if (!_eg_geo_mean) return NULL;
} else {
(void)engram_geo_mean_maybe_refresh(_eg_geo_mean, g_engram_store, 0.10);
}
if (engram_geo_mean_dim(_eg_geo_mean) != dim) return NULL; /* embedder dim moved */
return engram_geo_mean_vec(_eg_geo_mean);
}
/* Geometry-priming tunables (all bounded so the flag can only SHARPEN, never
* amplify or overflow WM). Overridable via env for the A/B without a rebuild. */
static double eg_geo_seed_lo(void) { /* seed damp floor: factor in [LO,1] */
const char* s = getenv("ENGRAM_GEO_SEED_LO"); double v = s ? atof(s) : 0.5;
if (!(v >= 0.0 && v <= 1.0)) v = 0.5; return v;
}
static double eg_geo_prime_scale(void){ /* primed warm act = membership*scale (< WM gate) */
const char* s = getenv("ENGRAM_GEO_PRIME_SCALE"); double v = s ? atof(s) : 0.08;
if (!(v > 0.0 && v < ENGRAM_WM_THRESHOLD)) v = 0.08; return v;
}
static int eg_geo_prime_max(void){ /* cap primed members added to the frontier */
const char* s = getenv("ENGRAM_GEO_PRIME_MAX"); int v = s ? atoi(s) : 32;
if (v < 0) v = 0; if (v > 256) v = 256; return v;
}
el_val_t engram_activate(el_val_t query, el_val_t depth) {
EngramStore* g = engram_get();
const char* q = EL_CSTR(query);
@@ -9308,6 +9368,100 @@ el_val_t engram_activate(el_val_t query, el_val_t depth) {
sel[nsel] = bi; selkey[nsel] = key; nsel++;
}
free(seed_dup);
/* ── M9 GEOMETRY PRIMING (ENGRAM_GEOMETRY_PRIMING, default OFF) ──────
* COMPOSES with the M8 seed set above: uses the CENTERED geometry of
* the seed neighborhood to (a) damp off-domain seeds by centered
* membership (disambiguation) and (b) prime nearby members sub-
* threshold (a warm floor). Flag OFF this whole block is skipped and
* the seed set/activation are exactly what M8 produced. Read-only over
* the graph except for the bounded, sub-threshold seed additions here. */
if (eg_geometry_priming_on() && g_engram_store && q_emb && q_dim > 0 && nsel > 0) {
const float* gmean = eg_geo_mean_sync(q_dim);
if (gmean) {
/* Seed ids = the M8-selected semantic seeds; vids maps the
* resident-array VIndex ordinals (== g->nodes[] index) to store
* ids so the descriptor's ANN expansion resolves to paged nodes. */
const char** seed_ids = malloc((size_t)nsel * sizeof(char*));
char** vids = malloc((size_t)g->node_count * sizeof(char*));
if (seed_ids && vids) {
for (int s = 0; s < nsel; s++) seed_ids[s] = g->nodes[sel[s]].id;
for (int64_t i = 0; i < g->node_count; i++) vids[i] = g->nodes[i].id;
GeoDescriptor* geo = engram_geometry_descriptor(
g_engram_store, _eg_vindex, vids, (int)g->node_count,
seed_ids, (size_t)nsel, NULL, gmean);
if (geo && geo->n_members > 0) {
const double lo = eg_geo_seed_lo();
const double pscl = eg_geo_prime_scale();
const int pmax = eg_geo_prime_max();
/* Centered membership per resident idx (-1 = not in the
* geometry left untouched by the reweight). */
double* geo_m = malloc((size_t)g->node_count * sizeof(double));
if (geo_m) {
for (int64_t i = 0; i < g->node_count; i++) geo_m[i] = -1.0;
for (int m = 0; m < geo->n_members; m++) {
int64_t ri = engram_find_node_index(geo->members[m].id);
if (ri >= 0 && ri < g->node_count) {
double mv = geo->members[m].membership;
if (mv < 0.0) mv = 0.0; else if (mv > 1.0) mv = 1.0;
geo_m[ri] = mv;
}
}
/* (a) DAMP-ONLY seed reweight: factor = lo+(1-lo)*memb
* [lo,1]. Off-domain seeds (low centered membership)
* lose weight; the neighborhood anchor (memb1) is
* unchanged. Never amplifies. Updates both the frontier
* act (drives propagation) and best_bg (drives this
* node's own WM weight). */
for (int64_t s = 0; s < seed_count; s++) {
int64_t si = seeds[s].idx;
if (si < 0 || si >= g->node_count) continue;
double mv = geo_m[si];
if (mv < 0.0) continue; /* not in geometry */
double factor = lo + (1.0 - lo) * mv;
seeds[s].act *= factor;
best_bg[si] *= factor;
}
/* (b) PRIME sub-threshold: descriptor members not
* already reached get a warm floor act=memb*pscl
* (pscl < WM gate cannot self-promote) and enter the
* frontier so a warm gradient spreads one hop then dies
* at the 0.02 BFS cutoff. Capped at pmax; ISE skipped.
* Safe: BFS keeps max, so this only RAISES a floor and
* never caps a stronger legitimate activation. */
int primed = 0;
for (int m = 0; m < geo->n_members && primed < pmax; m++) {
int64_t ri = engram_find_node_index(geo->members[m].id);
if (ri < 0 || ri >= g->node_count) continue;
if (reached[ri]) continue; /* already a seed */
EngramNode* pn = &g->nodes[ri];
if (pn->node_type &&
strcmp(pn->node_type, "InternalStateEvent") == 0)
continue;
double mv = geo->members[m].membership;
if (mv < 0.0) mv = 0.0; else if (mv > 1.0) mv = 1.0;
double pact = mv * pscl;
if (pact < 0.01) continue; /* too cold to matter */
seeds[seed_count].idx = ri;
seeds[seed_count].act = pact;
seeds[seed_count].created_at = pn->created_at;
seed_count++;
best_bg[ri] = pact;
best_hops[ri] = 0;
reached[ri] = 1;
primed++;
}
_eg_act_geo_primed += primed;
free(geo_m);
}
engram_geo_free(geo);
} else if (geo) {
engram_geo_free(geo);
}
}
free(seed_ids); free(vids);
}
}
}
free(e_eff); e_eff = NULL; /* M8: no longer needed past seed selection */
/* Compute mean seed created_at for temporal proximity bonus.