Grounding is the edge's weight, and the weight is a vector
El SDK CI - dev / build-and-test (pull_request) Failing after 3m59s
El SDK CI - dev / build-and-test (pull_request) Failing after 3m59s
A relation that keeps holding up strengthens; one that stops corresponding
decays. That is not analogous to grounding, it IS grounding — so it belongs on
the edge, not in a subsystem beside it. The graph was already the grounding
structure; this stops modelling it as something else.
Deleted, not refactored:
- cog_ground_edge and the `grounded-by` relation type. A grounded-by edge
models grounding as a relation BETWEEN nodes when it is a property OF a
relation. #147 fixed which endpoints that edge landed on and left the wrong
idea intact. Measured on the live store: the old path scored two nodes with
ZERO edges between them at 0.925237 and wrote an edge for it.
- ground() writing. It was a read that wrote — the eg_vindex_sync defect.
Three identical calls produced three writes to the same edge id.
- keystone_write_blocked. Its measured cost was 0.00% brier reduction over
n_trials 0 on the keystone: the loop never ran, so the self was never
calibrated and never falsifiable. Nothing replaces it — non-circularity of
the reference frame is temporal, not a permission.
- a graph predicate for "evidence downstream of itself", built and then
withdrawn. Reachability from the self region covers 89.2% of the live graph
(10,580 of 11,861 nodes), so any topological predicate marks nearly all
evidence tainted and degenerates into the total block censorship began as.
The vector, carried in a GRD1 block on the edge's own metadata:
factual, relational, associative (the existing hebb), polarity (SIGNED — near
zero is "no support", negative is "actively contradicts"; `inhibitory` is that
distinction crushed to one bit), provenance class, and a timestamp. Confidence,
recency, staleness and volatility are DERIVED at read and never serialized.
Decay is one model, not two: cog_decay_factor is the single implementation and
engram_temporal_decay now delegates to it — proven bit-identical over 24
(age, reinforcement) points.
Values reference: thirteen regions, aggregate MIN, binding value named. Measured
— the 13 have pairwise centroid cosine min 0.1525 / mean 0.5199 / max 0.9278, so
they demonstrably are not one region, and a mean would let agreement with twelve
mask a violation of the thirteenth.
Supersession versions the whole vector jointly, gated by consequence and
salience with no epsilon anywhere: floor crossings and sign changes only.
Polarity flips and provenance-class changes are inherently significant and
bypass the salience gate.
Also fixed: the frame contract. Descriptors are built over L2-normalized member
embeddings; think() and the grounding path were fitting RAW vectors against them.
Measured on the self region, same data, same 106 members:
magnitude 0.00283443 -> 0.536134, spread 18.7565 -> 0.930163.
Every fit score sat three decimal places below the 0.5 floors that gate on them.
assert() gates on both floors and computes still_held instead of returning a
hardcoded `true` — the old build reported still_held for a node that does not
exist.
This commit is contained in:
+269
-17
@@ -23,7 +23,7 @@
|
||||
* and a region, and grounded-for-whom.
|
||||
*
|
||||
* PURE + (mostly) READ-ONLY, stdlib + libm only. think() and the warp are pure
|
||||
* over their inputs. Persistence (Stance <-> StoreNode, grounded-by edges) is the
|
||||
* over their inputs. Persistence (Stance <-> StoreNode, edge grounding vectors) is the
|
||||
* only part that touches the store, and it is additive / supersede / tombstone —
|
||||
* never mutate-in-place, never delete. It NEVER touches the live daemon: all
|
||||
* offline against a scratch store, per the design's rails.
|
||||
@@ -152,30 +152,25 @@ int engram_express(const GeoGradient* g, const float* anchor, float* out_point);
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
* §5 HOLD vs GROUND vs ASSERT. Holding is unconditional (the store gates nothing).
|
||||
* Grounding is a RELATION — a "grounded-by" edge, probabilistic, grounded-for-whom.
|
||||
* The honesty floor is checked only at ASSERTION.
|
||||
* Grounding is an ATTRIBUTE OF a relation — carried on the edge itself, as a
|
||||
* vector (§7). The honesty floor is checked only at ASSERTION, on both axes.
|
||||
* ═══════════════════════════════════════════════════════════════════════════ */
|
||||
#define COG_GROUNDED_BY_RELATION "grounded-by"
|
||||
/* DELETED 2026-08-16: COG_GROUNDED_BY_RELATION and cog_ground_edge.
|
||||
*
|
||||
* A "grounded-by" edge models grounding as a relation BETWEEN two nodes. It is a
|
||||
* property OF a relation — and it is that relation's weight. Minting a new edge
|
||||
* to carry a score was the error; #147 corrected which endpoints the edge landed
|
||||
* on and left the wrong idea standing. There is nothing to ground a claim
|
||||
* "against" that is not already an edge, and if no edge exists the honest answer
|
||||
* is that the two are not related — not a freshly minted one scoring 0.98.
|
||||
* See §7 for what replaced it. */
|
||||
#define COG_SALIENT_TO_RELATION "salient-to"
|
||||
|
||||
/* Write a grounded-by edge (additive). weight = grounding ∈(0,1] from the verifier;
|
||||
* for_whom recorded in edge metadata (grounding is relational). Never a node flag. */
|
||||
int cog_ground_edge(EngramPagedStore* s, const char* claim_id,
|
||||
const char* evidence_id, double grounding, const char* for_whom);
|
||||
|
||||
/* Write/refresh a salient-to edge: salience is RELATIONAL (grounded-for-whom),
|
||||
* carried on the edge to the observer — not baked into the node scalar (§2.1). */
|
||||
int cog_salient_edge(EngramPagedStore* s, const char* node_id,
|
||||
const char* observer_id, double salience);
|
||||
|
||||
/* The honesty floor — a QUERY at assertion time, NOT a schema constraint. Reads the
|
||||
* claim's stored grounded-by edges (for the given observer) and returns:
|
||||
* 1 = may assert (best grounding >= floor),
|
||||
* 0 = REFUSE assertion (holds unconditionally; only asserting is gated),
|
||||
* <0 = error. The content remains held either way. */
|
||||
int cog_assert_gate(EngramPagedStore* s, const char* claim_id,
|
||||
const char* for_whom, double floor);
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
* §4 THE REFLEXIVE CORRESPONDENCE-LOOP — the learning engine. think scores its
|
||||
* OWN gradient against outcome, refines the stance on the error, and (optionally)
|
||||
@@ -209,8 +204,265 @@ int engram_correspondence_beat(const GeoDescriptor* region, const float* anchor,
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
* §6 METASTABILITY. Keystones (self/values) are read-mostly: the loop reads but
|
||||
* never writes them. Mark by stance flag or by a keystone-id set the loop consults.
|
||||
*
|
||||
* SUPERSEDED BY §7's PROVENANCE CONSTRAINT (2026-08-16). The keystone flag is a
|
||||
* PERMISSION: it asks who the target is, not where the evidence came from. That
|
||||
* is censorship, and it costs the ability to ever ground the self (spec
|
||||
* correspondence-and-censorship.md §0/§2). The constraint that actually protects
|
||||
* a reference frame is cog_grounding_downstream: a region may not be calibrated
|
||||
* by evidence downstream of itself. These declarations remain only so existing
|
||||
* call sites keep compiling; nothing in the grounding path consults them.
|
||||
* ═══════════════════════════════════════════════════════════════════════════ */
|
||||
typedef struct { const char** ids; int n; } CogKeystoneSet;
|
||||
int cog_is_keystone(const CogKeystoneSet* ks, const CogStance* s);
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
* §7 GROUNDING IS THE EDGE'S WEIGHT, AND THE WEIGHT IS A VECTOR
|
||||
* (2026-08-16; spec correspondence-and-censorship.md §2–§6 @ 2b7e4ba.)
|
||||
*
|
||||
* THE MODEL. Grounding is not a subsystem, a score, or a relation BETWEEN nodes.
|
||||
* It is an attribute OF a relation. The graph already IS the grounding structure:
|
||||
* every edge is a grounded relation, and what that relation is worth is carried
|
||||
* on the edge itself. Three things follow, and each DELETES rather than adds:
|
||||
*
|
||||
* 1. `grounded-by` as a relation type does not exist, and cog_ground_edge is
|
||||
* gone. Minting an edge to hold a score models grounding as a relation
|
||||
* between nodes when it is a property of a relation. #147 corrected which
|
||||
* endpoints that edge landed on and left the wrong idea standing.
|
||||
* 2. There is no observer, and no sampling rate. Change is not a consequence of
|
||||
* use — it IS use, the way potentiation is the firing rather than something
|
||||
* that reads the firing and writes a weight. So no supervisor compares a
|
||||
* value to a threshold and decides to persist.
|
||||
* 3. Between two recorded versions the trajectory is not unknown. Decay is a
|
||||
* pure function of the last recorded point and elapsed time, so it is
|
||||
* ANALYTIC: store the point, read the curve.
|
||||
*
|
||||
* WHAT IS *NOT* HERE, DELIBERATELY. An earlier draft of the spec posed "a graph
|
||||
* predicate for evidence downstream of itself" as the hard problem, and this file
|
||||
* briefly contained one. It is withdrawn. Non-circularity is TEMPORAL, not
|
||||
* topological: you cannot recalibrate the ruler while measuring with it, so you
|
||||
* do it when you are not using the frame to act. Reachability could never have
|
||||
* worked — measured on the live store, reachability from the self region over
|
||||
* all relations reaches 89.2% of the graph (10,580 of 11,861 nodes) and 16.0%
|
||||
* over hebbian/semantic relations alone, so the predicate marks essentially all
|
||||
* evidence tainted and the constraint degenerates into the total block that
|
||||
* censorship started as. Nothing replaces it here; the independence is a fact
|
||||
* about engagement, owned by the dreamer, not a fact about the graph.
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════════════════
|
||||
* §7.1 THE VECTOR
|
||||
*
|
||||
* The test for a real dimension is whether it can move independently of the
|
||||
* others. Five can, and each maps onto substrate that already exists:
|
||||
*
|
||||
* factual correspondence with evidence. [GRD1]
|
||||
* relational correspondence with values — min over THIRTEEN
|
||||
* value regions, carrying the binding value's NAME. [GRD1]
|
||||
* associative co-activation frequency. This is the edge's `hebb`
|
||||
* field with its existing dynamics — NOT a new one.
|
||||
* Independent by construction: every superstition is
|
||||
* a strong association with no factual grounding.
|
||||
* polarity SIGNED. Near zero means "no support"; NEGATIVE means
|
||||
* "this actively contradicts". The edge's `inhibitory`
|
||||
* bit is exactly this distinction crushed to one bit,
|
||||
* and is carried forward as the seed value. [GRD1]
|
||||
* provenance observed / inferred / told / imprinted. Categorical,
|
||||
* and load-bearing: it governs what the relation is
|
||||
* entitled to. [GRD1]
|
||||
*
|
||||
* Plus a TIMESTAMP, which is what turns the supersession chain into a time
|
||||
* series of vectors rather than a series of numbers.
|
||||
*
|
||||
* DERIVED, THEREFORE NEVER STORED. Confidence (high grounding AND low
|
||||
* volatility), recency (decay read off the curve), staleness (grounding fallen
|
||||
* below its floor), volatility (the derivative of a series nothing destroyed).
|
||||
* Storing confidence separately is how `confidence: 0.5` ends up sitting beside
|
||||
* a zero direction vector, asserting something nothing computed. Every field in
|
||||
* CogGrounding below is marked STORED or DERIVED, and the serializer writes
|
||||
* only the STORED ones.
|
||||
*
|
||||
* THE VALUES REFERENCE IS THIRTEEN REGIONS AND THE AGGREGATE IS MIN.
|
||||
* Measured on the live store: the values root kn-5b606390 `contains` exactly 13
|
||||
* value nodes; pairwise centroid cosine among their regions is min 0.1525,
|
||||
* mean 0.5199, median 0.5282, max 0.9278 — they demonstrably do not form one
|
||||
* region. Against a single union region the individual values sit at cosine
|
||||
* 0.38..0.89, with constraints-as-freedom at 0.3812 and change-is-the-signal at
|
||||
* 0.4677, so a union centroid under-represents precisely the values a claim is
|
||||
* most likely to be measured against. MIN rather than MEAN because a mean lets
|
||||
* strong agreement with twelve values mask a violation of the thirteenth, which
|
||||
* is the mechanism of rationalization; min yields a binding constraint with a
|
||||
* NAME attached rather than a score.
|
||||
*
|
||||
* TRAVERSAL CONDUCTS ON FACTUAL; ASSERTION REQUIRES BOTH. If activation
|
||||
* conducted on relational weight, Neuron could not follow a chain of reasoning
|
||||
* to a conclusion he then rejects — censorship arriving through the spreading
|
||||
* rule. The gap between reachable and assertable is where the wide
|
||||
* factual/relational angles live, and that gap is the interesting part.
|
||||
* ═══════════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* ── The one decay model (moved here from el_runtime.c so that node decay and
|
||||
* edge-grounding decay are a single implementation with a single set of
|
||||
* constants, rather than a model and a parallel copy of it). Half-life scales
|
||||
* with how established the thing is: T_eff = T_HALF · (1 + ln(1 + reinforcements)).
|
||||
* The floor is a preference, not a cliff — max penalty for age alone is 4x.
|
||||
* `lambda_override` > 0 replaces the default rate; 0 means use the default. */
|
||||
#define COG_T_HALF_HOURS 168.0
|
||||
#define COG_DECAY_LAMBDA 0.693147
|
||||
#define COG_DECAY_FLOOR 0.25
|
||||
double cog_decay_factor(int64_t age_ms, double reinforcements, double lambda_override);
|
||||
|
||||
/* The compact vector block carried in the edge's own metadata. Line schema, same
|
||||
* precedent as STNC1 / GEO1. Metadata the edge already carried is preserved
|
||||
* verbatim ahead of the magic line. */
|
||||
#define COG_GROUNDING_META_MAGIC "GRD1"
|
||||
|
||||
/* Provenance class — categorical, and it governs what the relation is entitled
|
||||
* to. A change of class is inherently significant and needs no threshold,
|
||||
* because told → observed is a categorical upgrade, not a drift. */
|
||||
typedef enum {
|
||||
COG_PROV_UNSET = 0,
|
||||
COG_PROV_OBSERVED = 1,
|
||||
COG_PROV_INFERRED = 2,
|
||||
COG_PROV_TOLD = 3,
|
||||
COG_PROV_IMPRINTED = 4
|
||||
} CogProvClass;
|
||||
const char* cog_prov_name(CogProvClass p);
|
||||
CogProvClass cog_prov_parse(const char* s);
|
||||
|
||||
typedef struct {
|
||||
int present; /* 1 iff the edge carries a GRD1 block */
|
||||
|
||||
/* ── STORED: the vector, as it stood at `ts` ─────────────────────────────── */
|
||||
double factual; /* correspondence with evidence */
|
||||
double relational; /* min over the thirteen value regions */
|
||||
double associative; /* co-activation frequency — mirrors edge->hebb */
|
||||
double polarity; /* SIGNED support; <0 = actively contradicts */
|
||||
CogProvClass prov; /* observed / inferred / told / imprinted */
|
||||
int64_t ts; /* when this version was recorded (ms) */
|
||||
int64_t seq; /* supersession sequence number */
|
||||
double reinforcements; /* uses folded into this version */
|
||||
char binding_value[128]; /* the argmin value — the conflict's NAME */
|
||||
/* the two gradients as frame-independent signed projections, plus the angle
|
||||
* between them in full R^dim. These are part of the JOINT STATE a decision
|
||||
* saw, not a convenience: near +1 evidence and values push the same way; at
|
||||
* or below 0 the relation is factually supported and relationally wrong. */
|
||||
double fac_proj, rel_proj, cos_angle;
|
||||
int agreement; /* sign(cos_angle): +1 / 0 / −1 */
|
||||
double floor_at_record, rel_floor_at_record;
|
||||
char prev_edge[192]; /* the version this superseded ("" if first) */
|
||||
|
||||
/* ── DERIVED at read time. NEVER serialized. ─────────────────────────────── */
|
||||
int64_t age_ms; /* recency: now − ts */
|
||||
double decay; /* cog_decay_factor over that age */
|
||||
double factual_now; /* factual · decay */
|
||||
double relational_now;
|
||||
double associative_now;
|
||||
int stale; /* grounding fallen below its floor */
|
||||
} CogGrounding;
|
||||
|
||||
/* Read an edge's vector as of `now_ms`. Pure — never writes. An edge with no
|
||||
* GRD1 block still has an associative strength (its accrued hebb) and a polarity
|
||||
* (its signed authored weight); `present` says whether the grounding dimensions
|
||||
* have ever been established, and an unestablished dimension is reported as such
|
||||
* rather than defaulted to a passing value. */
|
||||
int cog_grounding_parse(const StoreEdge* e, int64_t now_ms, CogGrounding* out);
|
||||
|
||||
/* Serialize the STORED half of the vector, preserving pre-existing non-GRD1
|
||||
* metadata. Returns an owned string. Derived fields are not written. */
|
||||
char* cog_grounding_metadata(const char* base_meta, const CogGrounding* g);
|
||||
|
||||
/* ── §7.2 CONSOLIDATION-GATED SUPERSESSION ──────────────────────────────────
|
||||
*
|
||||
* Supersession is not recording — it is CONSOLIDATION, gated by salience, which
|
||||
* is why you remember the argument and not the commute. Significance is
|
||||
* evaluated PER-DIMENSION but the record is the WHOLE VECTOR: any dimension
|
||||
* moving enough to matter triggers a supersession, and the new version captures
|
||||
* every dimension as it stood at that instant. Versioning axes independently
|
||||
* would make the joint state unreconstructable, and the joint state is the point
|
||||
* — it is what makes "stayed true, became wrong" visible as an event (factual
|
||||
* holding steady across versions while relational degrades).
|
||||
*
|
||||
* There is deliberately no epsilon in this enum or in the function that computes
|
||||
* it. Every test is a floor crossing or a sign change, both exact. Two of them
|
||||
* are INHERENTLY significant because they are discrete state changes rather than
|
||||
* drift, and those bypass the salience gate entirely. */
|
||||
typedef enum {
|
||||
COG_SIG_NONE = 0, /* nothing decision-relevant moved — DO NOT RECORD */
|
||||
COG_SIG_FIRST_RECORD = 1, /* no prior version exists */
|
||||
COG_SIG_POLARITY_FLIP = 2, /* INHERENT: support ↔ contradiction, or ignorance
|
||||
* ↔ either. A discrete change of state. */
|
||||
COG_SIG_PROVENANCE_CHANGE = 3, /* INHERENT: told → observed is a categorical
|
||||
* upgrade in what the relation is entitled to. */
|
||||
COG_SIG_FACTUAL_FLOOR = 4, /* crossed the assert floor, factual axis */
|
||||
COG_SIG_RELATIONAL_FLOOR = 5, /* crossed the assert floor, relational axis */
|
||||
COG_SIG_AGREEMENT_FLIP = 6, /* factual/relational agreement changed sign */
|
||||
COG_SIG_DIRECTION_REVERSAL = 7 /* a gradient reversed direction */
|
||||
} CogSignificance;
|
||||
|
||||
CogSignificance cog_grounding_significant(const CogGrounding* prev,
|
||||
const CogGrounding* now,
|
||||
double floor, double rel_floor);
|
||||
const char* cog_significance_name(CogSignificance s);
|
||||
/* 1 iff this reason is a discrete state change that consolidates regardless of
|
||||
* salience (polarity flip, provenance change, first record). */
|
||||
int cog_significance_inherent(CogSignificance s);
|
||||
|
||||
/* ── §7.3 RECORDING: supersession of the EDGE, never an overwrite ────────────
|
||||
* Writes version seq+1 as a NEW edge record with the same endpoints and relation
|
||||
* and id "<root>#<seq+1>", carrying a GRD1 `p` pointer to its predecessor. The
|
||||
* predecessor is never touched. The chain IS the trajectory: not only what the
|
||||
* grounding is but which way it has been moving and how fast — a derivative
|
||||
* obtained for free from immutability, because the points were never destroyed.
|
||||
* Returns the version written (>=1), or <0 on error. */
|
||||
int cog_grounding_record(EngramPagedStore* s, const StoreEdge* base,
|
||||
const CogGrounding* g, char* out_id, size_t out_id_cap);
|
||||
|
||||
/* Walk forward from a base edge id to its newest recorded version. Point reads
|
||||
* only; consolidation is gated, so the chain is short. Returns the highest
|
||||
* version found (0 = the base record is the only one). */
|
||||
int cog_grounding_head(EngramPagedStore* s, const char* base_id,
|
||||
StoreEdge* out, int max_versions);
|
||||
|
||||
/* VOLATILITY — derived, never stored: the mean absolute per-version change of a
|
||||
* dimension across the recorded chain. Feeds the equally-derived `confidence`
|
||||
* (high grounding AND low volatility), which is likewise never stored. */
|
||||
typedef struct {
|
||||
int n_versions;
|
||||
double factual_volatility;
|
||||
double relational_volatility;
|
||||
double factual_drift; /* signed: newest − oldest */
|
||||
double relational_drift;
|
||||
int stayed_true_became_wrong; /* factual steady while relational degraded */
|
||||
} CogTrajectory;
|
||||
int cog_grounding_trajectory(EngramPagedStore* s, const char* base_id,
|
||||
int64_t now_ms, CogTrajectory* out);
|
||||
|
||||
/* ── §7.4 ASSERTION GATES ON BOTH FLOORS ────────────────────────────────────
|
||||
* A well-evidenced claim must not earn the right to be asserted regardless of
|
||||
* whether it means the right thing. `may_assert` requires the decayed factual
|
||||
* grounding to clear `floor` AND the decayed relational grounding to clear
|
||||
* `rel_floor`. A relation whose relational axis has never been established does
|
||||
* not pass by default — it is reported unestablished and refused, because
|
||||
* defaulting it to passing is exactly the exemption §0 forbids. Traversal is
|
||||
* untouched: activation still conducts on the factual/associative side, so a
|
||||
* relation can remain thinkable while ceasing to be assertable. */
|
||||
typedef struct {
|
||||
int may_assert;
|
||||
int found; /* any relation at all on this claim */
|
||||
int relational_established;
|
||||
int still_held; /* DERIVED: node present and not tombstoned */
|
||||
double factual; /* best decayed factual grounding */
|
||||
double relational; /* the SAME edge's relational axis, not a max */
|
||||
double polarity;
|
||||
double cos_angle;
|
||||
int agreement;
|
||||
CogProvClass prov;
|
||||
char best_edge[192];
|
||||
char binding_value[128];
|
||||
int n_edges;
|
||||
} CogAssertion;
|
||||
int cog_assert_two_axis(EngramPagedStore* s, const char* claim_id,
|
||||
double floor, double rel_floor, int64_t now_ms,
|
||||
CogAssertion* out);
|
||||
|
||||
#endif /* ENGRAM_COGNITION_H */
|
||||
|
||||
Reference in New Issue
Block a user