A Biologically-Inspired Persistent Memory
for AI Agent Orchestration
01 — The Amnesia Problem
Valora orchestrates 11 specialised AI agents through multi-stage pipelines. Each is capable. But the moment a session ends, everything learned vanishes.
Repeated mistakes
An agent flags the same anti-pattern in sprint 1, sprint 5, sprint 12. Each time a fresh discovery.
Rediscovered patterns
Conventions emerge in the codebase. Agents reverse-engineer them on every run instead of building on accumulated knowledge.
Lost decisions
The team chooses an architectural direction. Agents propose already-rejected alternatives. The knowledge-base/ directory was empty.
02 — Neuroscience Inspiration
Without mental repetition, the newly formed connections in the brain are subject to a process of forgetting which, following a regular course, is most rapid immediately after learning.Hermann Ebbinghaus — Über das Gedächtnis, 1885
02 — Forgetting Curve
Each memory category has a half-life tuned to its nature. Observations fade fast. Patterns persist. Decisions outlive both.
strength = 0.5^(elapsed / halfLife)
Neuroscience
Ebbinghaus Forgetting Curve
Memory strength decays exponentially without reinforcement.
Spaced Repetition
Retrieving a memory strengthens it, pushing the decay curve into the future.
Error Amplification (Amygdala)
Mistakes are tagged with extra durability. We remember embarrassments longer than trivia.
Hippocampal Consolidation
Episodic memories compress into semantic knowledge during low-activity periods (sleep).
v1 — Valora equivalent
strength = 0.5^(t / halfLife)
The specification taken directly from Ebbinghaus. Pure maths, zero abstractions.
halfLife += accessCount × 2d
Each retrieval adds 2 days to the effective half-life. Frequently queried patterns persist.
isError → halfLife × 2
Error entries get double the base half-life. Hard lessons outlive routine observations.
valora consolidate
Jaccard tag-merge promotes episodic observations into durable semantic patterns.
03 — v1 Architecture
All memory lives under .valora/memory/ — gitignored by default, per-project, zero infrastructure required.
03 — The Decay Engine
export function computeStrength(referenceAt: string, halfLifeDays: number, now = Date.now()): number {
const elapsedDays = (now - new Date(referenceAt).getTime()) / MS_PER_DAY;
return Math.pow(0.5, elapsedDays / halfLifeDays); // injectable for deterministic tests
}
export function computeEffectiveHalfLife(
base: number, accessCount: number, isError: boolean,
retrievalBoostDays = 2, errorMultiplier = 2
): number {
const b = isError ? base * errorMultiplier : base; // amygdala effect
return b + accessCount * retrievalBoostDays; // spaced repetition
}
03 — Memory Entry
Every entry carries a confidence tier — unchanged across both v1 and v2. Agents weight memories accordingly.
type ConfidenceTier =
| 'verified' // ← highest trust
| 'observed'
| 'inferred'
| 'stale'; // ← never injected
// Injection: verified → observed → inferred
// Stale entries are always excluded.
relatedPaths intersect with files changed since last consolidation.04 — Where v1 Fell Short
v1 faithfully translated Ebbinghaus. But biology isn't a filing cabinet — the brain is a network, and the network is the memory.
Jaccard tag overlap is coarse
Synonyms never match. Antonyms might. Tag selection is arbitrary — two memories about the same concept with different labels will never consolidate. ADR-011 acknowledged this weakness explicitly.
Memories are isolated islands
No links between related entries. "Auth rewrite" (decisions.json) and "session-token format" (episodic.json) live in separate JSON arrays with no pointer between them. Every connection existed only in a developer's head.
No hippocampal index
Every recall loaded the full bucket, scored every entry, and sorted. O(n) per query with no structural way to skip irrelevant categories. The brain doesn't scan its entire cortex to recall breakfast.
05 — The Graph Insight
Donald Hebb's rule (1949) describes how synaptic strength grows with co-activation — the same mechanism behind long-term potentiation in the hippocampus.
Hebbian co-access
Every co-retrieved pair gets its co_access[otherId] count incremented in frontmatter. Frequently paired memories develop strong associative links.
Spreading activation
A query activates cosine-similar seeds. Activation then propagates outward over related and co_accessed edges, decaying by γ=0.6 per hop.
Synaptic consolidation
Cosine clustering (≥0.82) promotes episodic clusters to semantic memories — the cortical transfer that happens during biological sleep.
06 — v2 Architecture
Per-memory .md files with YAML frontmatter and [[id|kind]] wikilinks. The vault is openable in Obsidian — no extra tooling required.
.valora/memory/
├── version
├── meta.json
├── embeddings.bin ← packed Float32Array
├── embeddings.index.json ← id → offset map
├── episodic/
│ └── mem-abc123def456.md
├── semantic/
│ └── mem-xyz789pqr012.md
├── decisions/
│ └── mem-def456ghi789.md
└── .obsidian/ ← Obsidian compat
---
id: mem-abc123def456
category: episodic
created_at: "2026-04-28T10:23:00Z"
last_accessed_at: "2026-04-30T09:10:00Z"
agent_role: code-reviewer
confidence: observed
tags: ["typescript", "testing"]
half_life_days: 7
access_count: 3
is_error: false
co_access: {"mem-xyz789pqr012": 2}
---
Found a flaky test in the auth suite — timeout
too short for the CI environment.
[[mem-xyz789pqr012|related]]
06 — Recall
The vault recall pipeline replaces bucket scans with an embedding-seeded graph traversal — then wires co-retrieved pairs closer together.
nomic-embed-text. Graceful lexical fallback when no embedder is configured — zero code-path changes.embeddings.bin (packed Float32Array). Top k=12 seeds selected as activation starting points.related and co_accessed edges to depth 2. Activation decays by γ=0.6 per hop times edge weight.activation × decayStrength × confidenceWeight. Weights: verified=1.0 · observed=0.7 · inferred=0.4 · stale=0.1.co_access[otherId] in frontmatter for every co-retrieved pair — the synaptic weight update.07 — Synaptic Consolidation
valora consolidate — the hippocampal transfer that happens during biological sleep. Episodic observations cluster into durable semantic patterns.
related_paths intersect with files changed since the last consolidation are downgraded to stale. Code moves; memories must track it.semantic/*.md entry with confidence inferred. Each member gets a [[centroidId|decays_from]] wikilink.accessCount incremented and half-life extended — spaced repetition for patterns that proved durable.08 — Context Injection
Every pipeline invocation prepends the AGENT MEMORY block — built from vault recall, capped at 2 000 tokens, ordered by confidence tier.
AGENT MEMORY · vault recall · 2 000 tok budget
──────────────────────────────────────────────────
[VERIFIED · 0.97] Integration tests must use
Testcontainers; mock-based integration tests
are forbidden. (recalled 8×)
[OBSERVED · 0.72] Auth middleware rewritten for
compliance, not tech debt — session tokens
stored differently. (recalled 3×)
[INFERRED · 0.51] Pattern: no-console lint
suppression is consistently followed by an
eslint-disable comment explanation. (cluster)
09 — Design Decisions
Kept from v1
Rejected for v2
10 — Results
$ valora consolidate
Pruning entries below 0.05 strength...
✓ pruned 3 stale entries
Git-invalidating changed paths...
✓ downgraded 2 → stale
Embedding episodic entries...
✓ embedded 47 / 47
Cosine clustering (threshold 0.82)...
✓ merged 4 episodic clusters → 4 semantic
Strengthening survivors...
✓ strengthened 43 episodic entries
consolidation complete in 1.8s
Roadmap
Embedding-based similarity
Shipped in v2 — cosine ANN + spreading activation.
Pattern discovery
Cluster analysis to surface implicit conventions — agents discover architecture rules they never explicitly recorded.
valora memory reembed
Migrate embeddings when the model changes without touching memory content.
Kuzu graph export
Read-only analytics export for graph query and visualisation. Vault remains the write authority.