runtime: anchor the think read, so Neuron can think at all #142
Reference in New Issue
Block a user
Delete Branch "fix/think-anchor"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
engram_think_jsonpassedNULLas the anchor. NULL is not "no opinion" —engram_thinkre-origins atanchor ? anchor : region->centroid, so NULL means read from the centroid, and the centroid is the one point where the gradient is zero by construction:r = x - centroid = 0→ every axis projection 0 →grad0 → the "at rest" branch atengram_cognition.c:137.Measured consequence. Every faculty returned an identical null result, differing only in its label:
magnitude 1is membership evaluated at the centroid,spread 0is its distance to itself,confidence 0.5is the stance fallback. Every observed number is explained by the NULL.The geometry was never at fault.
/api/driftcomputes real values (centroid_sep 0.104,core_disp 0.045) over the very same 87 members. Neuron could not think because the read was always taken from the region’s own centre.Fix. The seeds choose which region; they must also supply the vantage. Anchor at the first resolvable embedded seed — the same seed
eg_geo_build_descinfersdimfrom, so the two can never disagree. A single seed still yields a real gradient, because the descriptor expands to that seed’s neighbourhood and the seed’s own position is distinct from the neighbourhood centroid. The vector is copied, not borrowed:g->nodesis realloc’d in place on append, so a borrowedEngramNode*dangles across a concurrent write.Verified against a clone of the production store (13,616 nodes / 37,865 edges):
with distinct unit direction vectors. Previously both returned the zero vector, magnitude 1, spread 0.
Still open, and isolated by this fix: all five faculties still return identical numbers and
confidencestays 0.5, becausecog_stance_initis passed NULL for the stance and the faculty enters the computation only through the stance’saxis_gain[]andbias_dir. The faculty label is inert until a stance is loaded — which is exactly whatlearn()’s correspondence-beat calibrates. Same shape as this bug: a neutral parameter collapsing a capability to a constant.engram_think_json passed NULL as the anchor. NULL is not "no opinion": engram_think re-origins at `anchor ? anchor : region->centroid`, so NULL means "read from the centroid" — and the centroid is the one point where the gradient is zero by construction. r = x - centroid = 0, so every axis projection is 0, grad is 0, and direction takes the "at rest" branch at engram_cognition.c:137. Measured consequence: EVERY faculty returned an identical null result, differing only in its label — {"direction":[0,0,0,0,0,0,0,0],"spread":0,"magnitude":1,"confidence":0.5} magnitude 1 is membership evaluated at the centroid, spread 0 is its distance to itself, confidence 0.5 is the stance fallback. The geometry was never at fault: /api/drift computes real values (centroid_sep 0.104, core_disp 0.045) over the very same 87 members. Neuron could not think because the read was always taken from the region's own centre. The seeds choose WHICH region; they must also supply the VANTAGE. Anchor at the first resolvable embedded seed — the same seed eg_geo_build_desc infers dim from, so the two can never disagree. One seed still yields a real gradient because the descriptor expands to that seed's neighbourhood, so the seed's position is distinct from the neighbourhood centroid. The vector is COPIED, never borrowed: g->nodes is realloc'd in place on append, so a borrowed EngramNode* dangles across any concurrent write. Verified against a clone of the production store (13,616 nodes / 37,865 edges): self anchor n_support 87 magnitude 0.00282 spread 18.79 values hub n_support 28 magnitude 0.00318 spread 17.72 with distinct unit direction vectors. Previously both returned the zero vector with magnitude 1 and spread 0. STILL OPEN, now isolated by this fix: all five faculties return identical numbers and confidence stays 0.5, because cog_stance_init is passed NULL for the stance and the faculty enters the computation only through the stance's axis_gain[] and bias_dir. The faculty label is inert until a stance is loaded — which is what learn()'s correspondence-beat calibrates. Same shape as this bug: a neutral parameter collapsing a capability to a constant.will.anderson referenced this pull request2026-08-16 17:20:41 +00:00