VA.2026.005 · Floor 01 · hall 08
“intelligence without memory is only improvisation — this is the room where the persona learns to remember, and admits when it cannot.”
VA-Memory is a library, not a service — deliberately. No mandatory framework, no HTTP surface, no registry publish in v1. You import MemoryService, call capture('{persona}', ...) and recall('{persona}', ...), and the persona starts accumulating a past. Persistence to Postgres arrives through VA-ORM; in-memory store covers dev and test. A seeded persona lives in local Postgres for live verification — identity withheld from every label in this hall.
Its anatomy is two tables and one promise. MemoryUtterance keeps raw speech per session with deterministic ids (personaId:sessionId:seq); MemoryAtom keeps facts, preferences, decisions, instructions, events, and notes across sessions with salience 0–100. Every query is scoped by an explicit personaId — there is no cross-persona leakage by construction, and cross-probe tests confirm it empirically rather than by assertion.
Recall is hybrid without a vector vendor: trigram (pg_trgm) first, token-overlap fallback, scored with salience, recency, and since Rev. B a pheromone trail that rewards repeatedly recalled atoms — then link-expanded. The ACO layer closes the loop: a frequently recalled atom carries τ = 1 − e^(−n/6) into the score, while graph edges idle beyond seven days evaporate by ρ = 0.97 down to a floor of 0.05. Trails fade; they do not calcify. Since Phase 09 the library grows a single brain: one property-graph partition per persona where memory, place, and ledger share nodes and edges. Spatial and economic bridges plug in optionally; without them the engine behaves exactly as v1.
Phase 17 added the room within the room: what happens when recall returns nothing. A twelve-particle swarm walks the persona's graph while a human says bentar, inget-inget lagi — four hops per particle, inertia 0.5, cognitive and social pulls 1.2 each, twenty percent reseeded every round, seeded by fnv1a over the input so the same question always produces the same forgetting. Confidence is 0.7·fit + 0.3·consensus, and the swarm is graded rather than trusted: above 0.7 a memory is inserted plainly, between 0.4 and 0.7 it enters the prompt flagged [type ~guess 0.60] under its own header, and below that the engine returns nothing at all. A guess is allowed. A guess wearing a fact's clothes is not. Everything is default-off; a live hit short-circuits the swarm entirely, so the fallback only runs when the honest path has already failed.
VA.2026.005
VA-Memory
AI Memory Engine · Persona Persistence · Hybrid Recall · ACO + PSO · Property Graph · TypeScript Library
Pure domain: utterance, atom, capture, recall with link-expand, persona snapshot. Patterns distilled from three refcode implementations.
Postgres store via VA-ORM with MEMORY_STORE switch. MemoryUtterance and MemoryAtom models land in va.schema; a seeded persona verifies locally.
Packaged as importable library (va-memory/memory): framework-free core guarded by isolation spec, external smoke test. HTTP surface cancelled.
LLM async extraction (flushExtract) layered over bilingual rule extractor — 6 types, salience scoring. LLM failure keeps rule atoms; uncovered atoms are reported, never silently deleted.
FTS + hybrid ranking without vector vendor, then prompt contract: append persona, prepend budgeted recall. Consumption documented as internal clone.
Content-hash dedup, utterance retention (atoms never swept), dry-run GC, hardening. v1 boundaries declared: no ACL, no compaction, no HTTP, no registry.
Single-brain graph bridge plus causal relation edges — memory stops being a pile of atoms and starts being a neighborhood.
Place-and-route and agent-asset-transfer bridges land, then recallBrain unifies memory, spatial, and economic recall under one cross-slot budget with world filters.
Pheromone on atoms (τ = 1 − e^(−n/6), 10% of the score) and evaporation on idle edges (ρ = 0.97 past seven days, floor 0.05, cap 0.95). Stochastic expansion was cut and its work handed to Phase 17.
Four atom fields move from text blobs to native JSONB with GIN indexes; trigram search reads array elements instead of bracket syntax, and tag/keyword filters become exact while matching stays fuzzy.
A twelve-particle swarm explores the persona graph when live recall comes back empty — deterministic seed, confidence bands, 15-minute sessions that carry a clue from one turn to the next. Two pre-existing bugs found and fixed on the way: an FTS path querying the wrong persona, and a search floor so low the fallback could never fire.
The single facade splits into a recall engine, a flush engine, and graph helpers — same behaviour, narrower surfaces, easier to test in isolation.
A person extractor adds relationship atoms to the graph and recall gains a top-N budget, so a rich persona no longer spends its whole prompt on its own past.
A capture that collides with an existing id but carries different text is no longer dropped silently: it is reassigned a sequence and logged, because disappearing speech is the one failure a memory engine cannot afford.
concepts — kept & discarded
kept — store ↔ extract as swappable axes; memory and postgres, rule and llm
kept — graded recall: yakin, duality, nihil — a confidence band is a promise to the reader
rejected — HTTP service and registry publish for v1; clone-internal instead
held — no vector DB; trigram plus overlap plus trails is enough to remember well
discarded — stochastic ACO expansion; superseded by the PSO backup path, one swarm instead of two
archive ref — VA.2026.005/CON
cross ref — timeline fig. 01
curator annotations
never make capture wait for understanding — store first, extract later.
one personaId per query. memory that leaks between minds is gossip, not recall.
utterances may be swept; atoms never are. the diary thins, the character remains.
a guess is a legitimate output; an unlabelled guess is a lie. the swarm is graded, and only certainty feeds the pheromone.
| materials | capture pipeline · rule + LLM extract · postgres store via VA-ORM · hybrid recall · prompt context builder · dedup + retention hygiene · single brain property graph · ACO pheromone + edge evaporation · PSO backup swarm · JSONB native atoms | dimensions | phases — 17 done · 14 planned · atom types — 6 · recall weights — 0.55 · 0.25 · 0.10 · 0.10 · swarm — 12 particles · 4 hops · confidence bands — ≥0.7 yakin · ≥0.4 dugaan · vector DB — 0 · suite — 369 tests · 18 files |
|---|---|---|---|
| condition | v1 · library, un-published · ACO live · PSO default-off · jsonb native · 356 pass / 13 skip · capture self-heal | acquired | 2026 |
| revision | Rev. D | archive location | DWG-005 · floor Floor 01 |
| internal reference | VA.2026.005/M | origin | distilled from three refcode memories, 2026 |
failed experiments
phase 03 briefly planned an HTTP surface. cancelled — a memory library should not dictate transport.
early flushExtract deleted rule atoms the LLM didn't cover. now uncovered atoms are reported and rule atoms retained on failure.
small talk briefly became permanent memory. drop patterns now discard greetings before extraction.
broad queries returned the wrong place and the wrong number. fixed with verbatim grounding, scope guards, and negative-memory demotion.
the FTS helper received the query text where the persona id belonged. recallBrain returned zero candidates in Postgres while recall worked fine, and unit tests never saw it because the in-memory store has no searchText. caught by an isolation probe, locked with regression specs, and confirmed safe — it never leaked, it only forgot.
the first swarm runs surfaced confident guesses with no text evidence at all — particles agreeing, and agreement mistaken for proof. now a hit must share a single token with the question or clues, or the round returns nothing.
confidence divided particle count by a fixed twelve, so on a 91-atom graph a three-node cluster could never clear the guess threshold. reweighted against uniform expectation, the band became reachable — the bug was in the denominator, not the swarm.
draft concepts
research notes
— synchronous rule extraction plus async LLM flush is the only schedule that keeps chat latency flat.
— pg_trgm plus token-overlap reaches useful recall without operating a vector database.
— a library beats a service here: the host app owns its singleton, its framework, its deploy.
— one graph partition per persona beats three stores — memory, place, and ledger recall better together.
— native JSONB beats stringified arrays — filters turn exact while trigram stays fuzzy.
— seeding a stochastic search from the input hash makes forgetting reproducible — the same hesitation always forgets the same way.
— consensus measured against uniform expectation scales; consensus measured against a fixed denominator collapses on wide graphs.
Capture writes the utterance and extracts rule atoms synchronously; deeper LLM understanding arrives asynchronously. A memory that slows down conversation to think is not a memory — it is an interruption.
Every atom and utterance carries its personaId, and every query filters by it. Isolation is not a feature flag or an ACL table in v1 — it is the shape of the data itself, verified by cross-probing one persona's vocabulary against another's memory.
When hybrid recall finds nothing, the swarm may still find something — but it must declare itself. Certainty is inserted plainly, suspicion is fenced behind a guess marker, and below the floor the honest answer is silence. A wrong memory costs more than a missing one.
within the collection
future vision
VA-Memory stays a library on purpose. Phase 14's coherence and compaction waits in the wings while the swarm's thresholds earn their keep on more real personas, and live metrics for swarm rounds and bands are the next honest measurement. The contract has not moved since Rev. A and will not now: capture without waiting, recall with weight, context under budget — and a guess that always says so.