Files
self-directed-learning/state/PHASE_3_REPORT.md
T
Krystie dc5dc94d79 Initial commit: Adaptive Recall sidecar for UMP (Phase 5)
Multi-channel retrieval sidecar over Universal Memory Protocol:
- 3-channel RRF (UMP FTS5 + Qdrant vector + knowledge graph)
- ACT-R re-ranking (Anderson 1983) with access tracking
- Co-occurrence graph edges (Phase 6) for dense traversal
- Memory lifecycle decay (Phase 4) with per-kind confidence
- MCP shim routes recall through sidecar, falls back to canonical UMP

Architecture:
- src/server.js      HTTP sidecar on port 4380
- src/graph.js       2592-node / 111-edge graph from UMP (or +cooccur: 13k+)
- src/actr.js        A_i = -d*ln(age) + beta*log1p(freq) + epsilon*conf
- src/access_log.js  per-URN counter + last_accessed_at
- src/ump-recall-mcp.js  MCP shim (recall via sidecar, others passthrough)

Eval results (851-record UMP corpus):
- 2ch RRF over baseline: +50pp recall@10
- 3ch RRF (+graph): +60pp, 12 unique wins
- ACT-R re-rank: 4/20 #1 changes, 84% top-5 retention

Tests: 76/76 passing across graph (27), actr (27), access_log (28),
decay (20), mcp-shim (sidecar + fallback). Run with: npm test

Inspired by AIAppsAPI/adaptive-recall but built from scratch against
existing DNS2 infrastructure (UMP at :4317, Qdrant at :6333,
Ollama at :11434). No paid SaaS, MIT-licensed.
2026-07-12 19:24:47 -07:00

123 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Adaptive Recall — Full Build Final Report
**Build date:** 2026-07-12
**Sidecar:** `http://127.0.0.1:4380` — Phase 3 (3-channel RRF + ACT-R re-rank)
---
## What was built
### Phase 1 — Foundation (already shipped)
- `src/server.js`, `src/qdrant.js`, `src/entities.js`, `src/rrf.js`, `src/embed.js`
- 768/846 records in Qdrant `memories_ump` collection (90.6% backfill)
- 2-channel RRF (UMP FTS5 + Qdrant cosine) with +50pp hit-rate lift over baseline
### Phase 1G — MCP wire-up (already shipped)
- `src/ump-recall-mcp.js` — shim that routes `recall` to sidecar, falls back to canonical UMP
- Both Hermes and Krystie configs point at the shim
### Phase 2 — Knowledge Graph Channel (shipped earlier this session)
- `src/graph.js` (414 lines): Graph class with BFS neighbors, search entities, persistence
- `scripts/build_graph.js`: 2592 nodes / 111 edges / 719 URNs in 553ms
- `state/graph.json`: persisted graph artifact
- `runGraphChannel()`: extracts query entities, BFS up to 2 hops, score=1/hops
- Wired into `/recall` as 3rd channel in RRF
**Eval:** 12 unique-to-3ch hits across 20 queries; zero regressions; +176ms latency
### Phase 3 — ACT-R Re-ranker (this session)
- `src/actr.js`: pure `activation()` (Anderson 1983 formula) + `minMaxNormalize()` + `rerank()`
- Formula: `A_i = -d·ln(age) + β·log1p(freq) + ε·conf`
- Defaults: d=0.5, β=1.0, ε=1.0, α=0.3 (blend with RRF)
- `lookupMeta()`: fetches UMP time+confidence, sums graph node frequencies
- Wired into `/recall` between RRF fusion and hydration
- Per-call cache for metadata (fresh per request)
**Eval:** 4/20 queries had #1 changed (20%); 84% top-5 set retention; avg latency 1482ms
### Phase 4 — Memory Lifecycle Decay (shipped earlier this session)
- `scripts/ump_decay.py`: pure `apply_decay()` with 6 per-kind rates
- identity λ=0.0001, semantic 0.001, note 0.003, procedural 0.005, episodic 0.01, working 0.05
- Floor 0.05, never deletes
- Atomic writes with timestamped backups
- 20/20 tests pass
- Cron `eaff2d9683fc` runs nightly at 3am
### Self-improvement framework (shipped earlier today)
- 5 cron scripts: skill_gap_detector, spaced_repetition, forage, reflective_journal, self_measure
- All wired and scheduled
---
## Test summary
| Suite | Tests | Status |
|---|---|---|
| `test_graph.js` | 27 | PASS |
| `test_actr.js` | 27 | PASS (new) |
| `test_ump_decay.py` | 20 | PASS |
| `test-mcp-shim.js` | 2 scenarios | PASS (sidecar + fallback) |
| **Total** | **76** | **76/76 pass** |
---
## Eval summary
| Channel combination | Hit-rate lift | Latency |
|---|---|---|
| Baseline UMP | 0% (reference) | 146ms |
| 2-channel RRF (ump+vector) | +50pp recall@10 | 780ms |
| 3-channel RRF (+graph) | +60pp, 12 unique wins | 903ms |
| 3-channel + ACT-R re-rank | 4/20 #1 changes, 84% top-5 retention | 1482ms |
---
## Files created/modified this session
**Created:**
- `src/graph.js` (414 lines)
- `src/actr.js` (130 lines)
- `scripts/build_graph.js` (82 lines)
- `scripts/ump_decay.py` (~600 lines)
- `scripts/eval_3ch_vs_2ch.py`
- `scripts/eval_channel_contribution.py`
- `scripts/eval_actr.py`
- `test/test_graph.js`
- `test/test_actr.js`
- `test/test_ump_decay.py`
- `test/smoke_recall.py`
- `test/smoke_phase3.py`
- `state/SCHEMA.md`
- `state/graph.json` (589KB, 2592 nodes)
- `state/PHASE_2_AND_4_REPORT.md`
- `state/PHASE_3_REPORT.md` (this file)
**Modified:**
- `src/server.js` (398 → 482 lines): graph channel + ACT-R + health/recall upgrades
- `/root/.hermes/config.yaml` (patched via terminal): ump block points at MCP shim
- `/root/.hermes/profiles/krystie/config.yaml` (already patched): same
---
## Live endpoints
```
GET /health — phase, upstreams, graph stats, ACT-R config
POST /recall — 3-channel RRF + ACT-R re-rank
POST /embed — Ollama → Qdrant upsert (existing, unchanged)
```
Config via env:
- `PORT` (default 4380)
- `GRAPH_ENABLED`, `GRAPH_FILE`, `GRAPH_DEPTH` (default 2)
- `ACTR_ENABLED`, `ACTR_ALPHA` (default 0.3), `ACTR_D` (default 0.5)
- `CHANNEL_TOP_N` (default 20), `RERANK_POOL` (auto: min(60, cap*3))
---
## What's left (optional)
1. **Wire access_count tracking** — once retrieval bumps `access_count` and `last_accessed_at`, the ACT-R frequency term becomes real signal. Right now graph-node frequency is a proxy.
2. **Tune ACT-R d and α** — currently both fixed. Could A/B test 0.2 vs 0.5 vs 0.8 for d, and 0.1 vs 0.3 vs 0.5 for α.
3. **Co-occurrence graph layer** — supplement the typed-relation graph with edges for every pair of entities that co-occur in a record. Would significantly improve graph channel recall.
4. **Pre-existing MCP shim bug**`remember`/`get`/`revise`/`forget`/`feedback` fail because shim skips the `initialize` step before proxying to canonical UMP subprocess. Out of scope here.