Memory System
Three-layer architecture for an agent that wakes up fresh every session
flowchart TD
CONV["Conversations\nTelegram main session"]
HB["Heartbeats\nPeriodic background work"]
subgraph L2["Layer 2 — Daily Notes"]
DN["memory/YYYY-MM-DD.md\nRaw timeline of events"]
end
subgraph L1["Layer 1 — Knowledge Graph"]
direction TB
AREAS["life/areas/"]
PPL["people/"]
CMP["companies/"]
PRJ["projects/"]
ITEMS["items.json\nAtomic timestamped facts"]
SUMM["summary.md\nLiving snapshot"]
AREAS --- PPL
AREAS --- CMP
AREAS --- PRJ
PPL --> ITEMS
PPL --> SUMM
ITEMS -->|"weekly\nsynthesis"| SUMM
end
subgraph L3["Layer 3 — Tacit Knowledge"]
MEM["MEMORY.md\nPatterns, preferences,\nlessons learned"]
end
CONV -->|"writes events"| DN
HB -->|"extracts\ndurable facts"| ITEMS
DN -.->|"facts flow\nupward"| ITEMS
DN -.->|"periodic\nreview"| MEM
SUMM -.->|"context\nat session start"| CONV
MEM -.->|"loaded\nat session start"| CONV
DN -.->|"recent days\nloaded"| CONV
The Three Layers
Layer 1: Knowledge Graph
life/areas/{type}/{entity}/Entity-based storage that compounds forever. Each person, company, or project gets a folder containing:
— summary.md: living snapshot, rewritten weekly
— items.json: atomic timestamped facts
Never delete — supersede instead.
Layer 2: Daily Notes
memory/YYYY-MM-DD.mdRaw timeline — what happened, when. Written continuously during conversations and heartbeats. Durable facts are later extracted upward into Layer 1. The journal.
Layer 3: Tacit Knowledge
MEMORY.mdPatterns, preferences, lessons learned — facts about Echo, not the world. Curated wisdom distilled from daily notes. The index that points to topic-specific files.
The Compounding Engine
The flywheel: Conversation → Facts extracted → Graph grows → Weekly synthesis → Better context → Better responses → More conversation
Real-Time Extraction
During heartbeats: check conversations, extract durable facts (relationships, status changes, milestones), write to entity items.json. Skip casual chat and temporary info.
Weekly Synthesis (Sunday)
For each entity with new facts: load summary.md + active facts from items.json, rewrite summary.md for current state, mark contradicted facts as superseded.
Atomic Fact Schema
{
"id": "entity-001",
"fact": "The actual fact",
"category": "relationship | milestone | status | preference",
"timestamp": "YYYY-MM-DD",
"source": "conversation",
"status": "active | superseded",
"supersededBy": "entity-002"
} Core Principle: Echo wakes up blank every session. There is no hidden state, no persistent process, no background memory. The only thing that survives between sessions is what's written to disk. If you think it, write it. Text > brain.