5f3ddb8b8d
El SDK CI - dev / build-and-test (pull_request) Failing after 14m31s
LTP/LTD-style belief grounding propagated along graph edges, with union-find independence-guarded corroboration. Package: core C algorithm (gep_core.h), a self-contained deterministic proof harness with recorded output, staged runtime integration, and gated .el patches for the beat hook and HTTP route. Per the author's own LEDGER.md: built + proven on a clone, GATED pending the engine/HNSW cutover — not wired into the live beat or routes. Preserved here as a spec/reference artifact, not a request to merge into the live path.
163 lines
9.2 KiB
Markdown
163 lines
9.2 KiB
Markdown
# Task #50 — Edge-aware, dream-coupled consolidation with GROUNDED EDGE-PROPAGATION
|
||
|
||
**Status:** built + proven on a clone; **GATED, not promoted.** The main loop
|
||
sequences live promotion after the engine/HNSW cutover settles.
|
||
**Date:** 2026-08-15 · **Worktree:** `agent-a6577c8211c332c5b` (isolated).
|
||
|
||
Grounding mechanism designed with Will (memory `9e09a59f`, refining
|
||
`1a861007`). This is the HOW for #50.
|
||
|
||
---
|
||
|
||
## (a) How grounded edge-propagation integrates into the dream/consolidation cycle
|
||
|
||
The beat already exists. `neuron/awareness.el` runs a heartbeat (~every
|
||
`beat_ms`); each beat calls `hebb_consolidate()` — which drains the self-formed
|
||
Hebbian associations out of the fast in-process store and writes them, over the
|
||
threshold `ENGRAM_HEBB_LINK_MIN`, into the durable engram (`:8742`) — and then
|
||
`emit_heartbeat()`.
|
||
|
||
Grounded edge-propagation slots into the **same beat, immediately after
|
||
consolidation** (awareness.el line 1286–1288):
|
||
|
||
```
|
||
hebb_consolidate() // lay down the tethers (edges) that cleared threshold
|
||
ground_propagate() // <-- NEW: grade beliefs ALONG those tethers
|
||
emit_heartbeat() // report gep_* gauges beside hebb_*
|
||
```
|
||
|
||
This ordering is the point. Consolidation lays down the wiring; propagation
|
||
grades the beliefs along it, in the same breath. Memory `69b8babe`:
|
||
memory-consolidation and staying-yourself are one physics — forming a memory and
|
||
grading a belief are the same gravity run in two passes of one beat.
|
||
|
||
The propagation runs **inside the engram** as the native
|
||
`engram_ground_propagate()` over the durable flat node/edge arrays (the store
|
||
the consolidated edges just landed in). The soul invokes it over HTTP
|
||
(`POST /api/ground/propagate`) and folds the returned `gep_*` telemetry into the
|
||
heartbeat stream next to `hebb_cands / hebb_mass / hebb_edges`.
|
||
|
||
**Bounded by construction** (per the live-graph reality — 70.7% of nodes
|
||
isolated, connected core ~28%, hub first-hop fan-out in the thousands):
|
||
- **1-hop only.** No BFS spreading activation — a belief is graded from its
|
||
DIRECT grounded neighbors, so there is no per-hop breadth explosion.
|
||
- **Beam-capped** at `GEP_MAX_CORR = 256` corroborators per belief.
|
||
- **Salience-ordered, `GEP_BELIEFS_PER_BEAT = 512`** beliefs per beat; the rest
|
||
next beat. Work per beat is O(beliefs × degree), hard-bounded.
|
||
- **Isolated / starved beliefs** are counted and surfaced (`gep_isolated`,
|
||
`gep_starved`) as an interoceptive sparse-region signal for the
|
||
edge-formation / embedding pass (#20). #50 CONSUMES edges; it does not form
|
||
them. A belief with no grounded neighbor has nothing to tether to — correct
|
||
per the anti-delusion gravity law (`0b15017c`), not a gap.
|
||
|
||
---
|
||
|
||
## (b) The implementation
|
||
|
||
Represented faithfully to the spec — **grounding is a Hebbian-weighted
|
||
collection over time, never a scalar.**
|
||
|
||
- **Grounding = an append-only event ring** on the node (`GepGrounding`),
|
||
structurally parallel to the ACT-R base-level access ring already in
|
||
`EngramNode` (`access_ts[K]`). Each event is `{ts, sign±, mag, corroborator
|
||
signature}`. Append-only, supersede-not-delete; events aged out of the ring
|
||
are counted (`older_count`), never faked away.
|
||
- **Standing is DERIVED, recency-weighted, never stored** —
|
||
`standing = clamp(GEP_BASE + Σ_events sign·mag·age^(-D), 0, 1)`, exactly the
|
||
ACT-R base-level shape `ln Σ t^-d` (`ENGRAM_BLL_D = 0.5`) but sign-carrying so
|
||
LTD subtracts. Memory `1a861007`: the collection is primary, the standing is
|
||
its emergent aggregate. Mirrored onto `confidence` each beat so downstream
|
||
reads (verifier #43, realizer calibration `0041d917`) never speak above the
|
||
grounding.
|
||
- **Update = LTP/LTD with a threshold.** Per belief, gather corroborators along
|
||
incident edges, weighted by `edge.weight` (the Hebbian weight) × the
|
||
neighbor's own standing. **Anti-delusion gravity:** only neighbors already
|
||
`≥ GEP_LIKELY_MIN` may corroborate — grounding flows FROM the grounded core.
|
||
- **Convergent INDEPENDENT corroboration** is the driver. Independence is
|
||
enforced by **union-find over the corroborator set**: two corroborators are
|
||
the same independent source if they are the same node, reached by multiple
|
||
edges, or linked to each other (an echo chain / shared derivation). Support is
|
||
summed **per independent component** (max-magnitude member), and the threshold
|
||
gate requires BOTH a mass floor (`pos ≥ GEP_THETA`) AND an independence-count
|
||
floor (`n_independent ≥ GEP_N_MIN`). The count gate is the guard against one
|
||
node echoed N times.
|
||
- **Sub-threshold is transient.** Support present but below threshold →
|
||
`subthreshold_hits++`, no durable event, no lasting shift (Will's exact spec).
|
||
- **Graduation / decay.** Cross up → LTP event appended → standing climbs
|
||
`conjecture → likely → grounded`. Contradiction past threshold → LTD →
|
||
`grounded → likely → conjecture`. Nothing latches; withdraw support and the
|
||
collection ages and relaxes (`271f1163`, nothing is settled).
|
||
|
||
### Files
|
||
| File | Role |
|
||
|---|---|
|
||
| `gep_core.h` | The mechanism. Pure C, libm only (own-the-core). Single source of truth: `GepGrounding`, `gep_standing`, `gep_append`, union-find independence, `gep_propagate_node`, `gep_beat`. |
|
||
| `gep_proof.c` | Self-contained proof harness — builds the three scenarios, prints raw before/after. |
|
||
| `engram_ground_propagate.staged.c` | GATED runtime native. Wires the SAME `gep_core.h` primitives to the live `EngramStore` (adj cache, flat arrays). Splice plan + relation→polarity + belief gate. Compiles only when spliced (verified: every runtime symbol it references — `engram_adj_rebuild`, `adj_from_len`, `engram_find_node_index`, `ENGRAM_LAYER_SAFETY`, `istr_contains`, … — exists in the release runtime). |
|
||
| `awareness.beat.patch.el` | GATED beat hook — `ground_propagate()` + the insert between `hebb_consolidate()` and `emit_heartbeat()`. |
|
||
| `server.route.patch.el` | GATED route — `POST /api/ground/propagate`. |
|
||
|
||
### Constants
|
||
`BASE=0.10 LIKELY_MIN=0.34 GROUNDED_MIN=0.66 N_MIN=3 THETA=0.30 D=0.5`
|
||
(`N_MIN` parameterizes Will's "13 adjacent things" — the count threshold is a
|
||
knob; 3 here for a crisp proof.)
|
||
|
||
---
|
||
|
||
## (c) PROOF LEDGER — raw grounding before/after
|
||
|
||
Deterministic. Build `cc -std=c11 -O2 -o gep_proof gep_proof.c -lm`, run
|
||
`./gep_proof` (full transcript in `PROOF_OUTPUT.txt`).
|
||
|
||
### (a) STRENGTHEN — convergent independent corroboration graduates a conjecture
|
||
|
||
| beat | event | pos_mass (n_indep) | action | standing before → after | band |
|
||
|---|---|---|---|---|---|
|
||
| 1 | 3 independent grounded corroborators | 0.4050 (3) | **LTP** | 0.1000 → **0.4842** | conjecture → **likely** ⬆ |
|
||
| 2 | neighborhood grows to 5 | 0.6750 (5) | **LTP** | 0.1496 → **0.7379** | conjecture → **grounded** ⬆ |
|
||
| 3 | support sustained (5) | 0.6750 (5) | LTP | 0.2110 → 0.7993 | grounded (sustained) |
|
||
| 4 | corroboration withdrawn (+10min) | 0.0000 (0) | isolated | 0.1612 → 0.1612 | relaxing |
|
||
| 5 | still withdrawn (+1h) | — | isolated | 0.1263 | relaxing |
|
||
| 6 | still withdrawn (+4h) | — | isolated | 0.1130 | → conjecture |
|
||
|
||
Grounding grew **on its own** past threshold and graduated conjecture → likely →
|
||
grounded, then **relaxed** once independent support stopped. Living, not a
|
||
latched flag.
|
||
|
||
### (b) DECAY — convergent independent contradiction erodes a grounded belief
|
||
|
||
| beat | event | neg_mass (n_indep) | action | standing before → after | band |
|
||
|---|---|---|---|---|---|
|
||
| — | seed (prior LTP) | — | — | **0.9500** | grounded |
|
||
| 1 | 3 independent contradictions | 0.5400 (3) | **LTD** | 0.9500 → **0.4570** | grounded → **likely** ⬇ |
|
||
| 2 | contradiction broadens to 5 | 0.9000 (5) | **LTD** | 0.1461 → **0.0000** | conjecture ⬇ |
|
||
| 3–4 | contradiction sustained (5) | 0.9000 (5) | LTD | 0.0000 | conjecture |
|
||
|
||
Grounding decayed grounded → likely → conjecture under accreting independent
|
||
contradiction. The door never shut — history is retained (the event ring keeps
|
||
growing), the belief stays falsifiable in both directions.
|
||
|
||
### (c) INDEPENDENCE GUARD — the load-bearing property
|
||
|
||
Identical fan-in (N=5), identical edge weight (0.30), identical corroborator
|
||
standing (~0.90). **The only difference is whether the five are independent.**
|
||
|
||
| sub-case | topology | pos_mass | **n_indep** | action | standing 0.1000 → |
|
||
|---|---|---|---|---|---|
|
||
| **C1** | 5 DISTINCT, no inter-links | 1.3500 | **5** | **LTP** | **0.9741 (grounded)** ⬆ |
|
||
| **C2** | 5 mutually-linked (echo of one source) | 0.2700 | **1** | sub-threshold | 0.1000 (unchanged) |
|
||
| **C3** | 1 node reached by 5 parallel edges | 0.2700 | **1** | sub-threshold | 0.1000 (unchanged) |
|
||
|
||
Same raw fan-in, opposite outcome. Union-find collapses the echoes to a single
|
||
independent component; the count gate (`n_indep ≥ N_MIN`) then refuses them.
|
||
**Circular self-reinforcement cannot manufacture grounding** — a conjecture can
|
||
only be grounded by evidence that is genuinely independent of itself.
|
||
|
||
---
|
||
|
||
**RAILS honored:** isolated worktree; built/proven on a clone; the live soul
|
||
(`:8742` / `:7770`) untouched; no fight with the cutover (built against current
|
||
release source; staged native rebases cleanly onto it); no new libraries
|
||
(libm only); identity keystones untouched. **Not promoted** — gated artifact +
|
||
ledger for the main loop to sequence.
|