a4fc26eed360357640501540f0059014ecab58ea
1
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a2ba1ccb05 |
feat(dynamics): Hebbian potentiation + Ebbinghaus decay for halls + tunnels
Adds the L7 living-connection dynamics layer for the hallway primitive (PR #1558) and the tunnel primitive (PR #1565). Connections now carry strength, stability, last_activated, and access_count fields; pure-math helpers in a new ``mempalace.dynamics`` module update these via Hebbian potentiation (Hebb 1949) on co-access and Ebbinghaus exponential decay (Ebbinghaus 1885) on time-since-use, with the Cepeda spacing effect (Cepeda et al. 2006) growing stability when reinforcement is distributed rather than massed. Existing palaces continue to work unchanged — the new fields populate via safe defaults (strength=1.0, stability=1.0, last_activated=created_at, access_count=0) lazily on any potentiate/decay call. No migration step required. No schema break. Old records work; new records ship with full L7 state from creation. ## What this commit does 1. New module ``mempalace/dynamics.py`` — pure math, no I/O, no chromadb. Three public helpers: - ``initialize_dynamics_fields(connection, *, now=None)`` Backfill helper. Populates missing strength / stability / last_activated / access_count fields. Existing fields are NOT overwritten. Safe for pre-L7 records. - ``potentiate(connection, *, increment=POTENTIATION_INCREMENT, now=None)`` Hebbian strengthening on a co-access event. Increments strength (capped at MAX_STRENGTH), updates last_activated, increments access_count. Grows stability by STABILITY_INCREMENT ONLY when the gap since the prior activation is at least SPACED_INTERVAL_HOURS — implements the Cepeda spacing effect (rapid bursts don't build durability; distributed practice does). - ``apply_decay(connection, *, now=None)`` Ebbinghaus exponential decay. New strength = old * exp(-days_since / stability), floored at STRENGTH_FLOOR (0.05) so connections never reach zero — only become dim. Idempotent at the same instant. Higher stability = slower decay. 2. Integration in ``mempalace/hallways.py:compute_hallways_for_wing`` — before persisting the new hallway list for a wing, looks up the existing wing's hallways and builds a (entity_a, entity_b) → dynamics lookup. Each new record gets the preserved dynamics if the entity pair existed before, OR default dynamics via ``initialize_dynamics_fields`` if it's a brand-new pair. Without this preservation, every mine would wipe accumulated connection weights — defeating the whole L7 layer. 3. Integration in ``mempalace/palace_graph.py:create_tunnel`` — the existing dedup-on-canonical-id path now also preserves the four dynamics fields from the existing record onto the recreated tunnel (in addition to the already-preserved ``created_at``). Brand-new tunnels and legacy records (created before L7) get default dynamics via ``initialize_dynamics_fields``. ## Tests (RED-first) Twenty-five new tests in ``tests/test_dynamics.py`` covering the pure math: field initialization defaults, potentiation strength increment + cap, last_activated update, access_count increment, spaced vs. rapid reinforcement (Cepeda spacing effect), decay rate (exp(-days/stability)), floor clamping, idempotency at same instant, higher-stability slower-decay behavior, no-time-passed no-op, backfill on missing fields, mutate-and- return-same-dict chaining. Plus integration scenarios: potentiation restoring decayed strength, repeated spaced reinforcement growing stability monotonically, burst reinforcement not growing stability. Six new integration tests: test_new_hallway_record_carries_all_dynamics_fields test_recompute_preserves_accumulated_strength test_recompute_initializes_dynamics_for_brand_new_pairs test_new_tunnel_carries_all_dynamics_fields test_recreate_tunnel_preserves_accumulated_dynamics test_recreate_tunnel_initializes_dynamics_for_legacy_records All RED-first (KeyError: 'strength' before the integration commits). All GREEN after. ## Backward compatibility Pre-existing palaces work unchanged: - Old hallway records with no dynamics fields are still readable; the next ``compute_hallways_for_wing`` recompute populates the missing fields via ``initialize_dynamics_fields``. - Old tunnel records similarly; the next ``create_tunnel`` recreate (or any future call passing the record through ``initialize_dynamics_fields``) populates the missing fields. - A ``test_recreate_tunnel_initializes_dynamics_for_legacy_records`` test pins this contract explicitly. No forced migration. No schema break. Old records work; new behavior kicks in on first touch. ## What this does NOT do (intentionally scoped out) - Spreading activation at search time — that's a search-layer change; bigger PR; separate work. - Lazy decay-on-read in ``list_hallways`` / ``list_tunnels`` — the math is here; wiring it into the read path is a follow-up. - Config exposure of the tunable constants — STRENGTH_FLOOR, MAX_STRENGTH, POTENTIATION_INCREMENT etc. are hardcoded module-level for v1. If empirical palace data shows the defaults need tuning, expose via MempalaceConfig in a follow-up. - Decay-aware ranking in search — the strength field is now there; the search ranker doesn't yet use it. Follow-up. ## Verification pytest tests/test_dynamics.py → 25 passed (RED before this commit; GREEN after) pytest tests/test_hallways.py::TestHallwayDynamicsIntegration → 3 passed (RED before; GREEN after) pytest tests/test_palace_graph_tunnels.py::TestTunnelDynamicsIntegration → 3 passed (RED before; GREEN after) pytest -q (full mempalace suite) → 2111 passed, 3 skipped, 0 regressions ruff check mempalace/dynamics.py mempalace/hallways.py mempalace/palace_graph.py tests/ → All checks passed! ruff format --check ... → 6 files already formatted (pinned 0.15.9) ## Research grounding - Hebb, D. O. (1949). The Organization of Behavior. Wiley. → "Neurons that fire together, wire together" → potentiate() - Ebbinghaus, H. (1885). Über das Gedächtnis. → Exponential forgetting curve → apply_decay() - Cepeda, N. J., Pashler, H., Vul, E., Wixted, J. T., & Rohrer, D. (2006). Distributed practice in verbal recall tasks: A review and quantitative synthesis. Psychological Bulletin, 132(3), 354-380. → Spacing effect → stability growth on spaced reinforcement |