Created
January 30, 2026 23:03
-
-
Save jalehman/d7c7405f36877550d4def157174cfed5 to your computer and use it in GitHub Desktop.
Three-Layer Memory System - Agent Skill Architecture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Three-Layer Memory System — Architecture Reference</title> | |
| <style> | |
| :root { | |
| --bg: #0d1117; | |
| --bg-secondary: #161b22; | |
| --text: #c9d1d9; | |
| --text-muted: #8b949e; | |
| --accent: #58a6ff; | |
| --accent-secondary: #1f6feb; | |
| --border: #30363d; | |
| --code-bg: #1c2128; | |
| --success: #3fb950; | |
| --warning: #d29922; | |
| } | |
| * { box-sizing: border-box; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| line-height: 1.6; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| .container { | |
| max-width: 900px; | |
| margin: 0 auto; | |
| padding: 2rem; | |
| } | |
| header { | |
| border-bottom: 1px solid var(--border); | |
| padding-bottom: 1.5rem; | |
| margin-bottom: 2rem; | |
| } | |
| h1 { | |
| color: var(--text); | |
| font-size: 2rem; | |
| margin: 0 0 0.5rem 0; | |
| font-weight: 600; | |
| } | |
| .meta { | |
| color: var(--text-muted); | |
| font-size: 0.9rem; | |
| } | |
| .meta a { | |
| color: var(--accent); | |
| text-decoration: none; | |
| } | |
| h2 { | |
| color: var(--text); | |
| font-size: 1.5rem; | |
| border-bottom: 1px solid var(--border); | |
| padding-bottom: 0.5rem; | |
| margin-top: 2.5rem; | |
| font-weight: 600; | |
| } | |
| h3 { | |
| color: var(--text); | |
| font-size: 1.2rem; | |
| margin-top: 2rem; | |
| font-weight: 600; | |
| } | |
| h4 { | |
| color: var(--text-muted); | |
| font-size: 1rem; | |
| margin-top: 1.5rem; | |
| font-weight: 600; | |
| } | |
| p { margin: 1rem 0; } | |
| .highlight { | |
| background: var(--bg-secondary); | |
| border: 1px solid var(--border); | |
| border-left: 4px solid var(--accent); | |
| padding: 1rem; | |
| border-radius: 6px; | |
| margin: 1.5rem 0; | |
| } | |
| .highlight strong { | |
| color: var(--accent); | |
| } | |
| code { | |
| background: var(--code-bg); | |
| padding: 0.2rem 0.4rem; | |
| border-radius: 4px; | |
| font-family: 'SF Mono', 'Fira Code', monospace; | |
| font-size: 0.9em; | |
| color: #f0883e; | |
| } | |
| pre { | |
| background: var(--code-bg); | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| padding: 1rem; | |
| overflow-x: auto; | |
| margin: 1rem 0; | |
| } | |
| pre code { | |
| background: none; | |
| padding: 0; | |
| color: var(--text); | |
| } | |
| .layer-card { | |
| background: var(--bg-secondary); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| padding: 1.5rem; | |
| margin: 1rem 0; | |
| } | |
| .layer-card h3 { | |
| margin-top: 0; | |
| color: var(--accent); | |
| } | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin: 1rem 0; | |
| font-size: 0.9rem; | |
| } | |
| th, td { | |
| border: 1px solid var(--border); | |
| padding: 0.75rem; | |
| text-align: left; | |
| } | |
| th { | |
| background: var(--bg-secondary); | |
| color: var(--text); | |
| font-weight: 600; | |
| } | |
| td { | |
| color: var(--text-muted); | |
| } | |
| ul, ol { | |
| padding-left: 1.5rem; | |
| } | |
| li { | |
| margin: 0.5rem 0; | |
| } | |
| .formula { | |
| background: var(--code-bg); | |
| border: 1px solid var(--border); | |
| border-radius: 6px; | |
| padding: 1rem; | |
| text-align: center; | |
| font-family: 'SF Mono', monospace; | |
| font-size: 1.1rem; | |
| margin: 1rem 0; | |
| } | |
| footer { | |
| margin-top: 3rem; | |
| padding-top: 1.5rem; | |
| border-top: 1px solid var(--border); | |
| color: var(--text-muted); | |
| font-size: 0.85rem; | |
| } | |
| footer a { | |
| color: var(--accent); | |
| text-decoration: none; | |
| } | |
| .badge { | |
| display: inline-block; | |
| background: var(--accent-secondary); | |
| color: white; | |
| padding: 0.25rem 0.5rem; | |
| border-radius: 4px; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| margin-left: 0.5rem; | |
| } | |
| @media (max-width: 600px) { | |
| .container { padding: 1rem; } | |
| h1 { font-size: 1.5rem; } | |
| h2 { font-size: 1.25rem; } | |
| pre { font-size: 0.8rem; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <h1>🧠 Three-Layer Memory System <span class="badge">Agent Skill</span></h1> | |
| <p class="meta"> | |
| Persistent, evolving memory for AI agents<br> | |
| Origin: <a href="https://x.com/rohit4verse/status/2012925228159295810">@rohit4verse's thread</a> (Jan 2026) | |
| </p> | |
| </header> | |
| <div class="highlight"> | |
| <strong>Key insight:</strong> Memory is infrastructure, not a feature. Embeddings measure similarity, not truth. You need structure, timestamps, and maintenance. | |
| </div> | |
| <h2>Overview</h2> | |
| <p>The Three-Layer Memory System gives agents persistent, evolving memory that compounds over time. Unlike static context files, this system automatically extracts facts, resolves contradictions, and keeps summaries current.</p> | |
| <h2>The Three Layers</h2> | |
| <div class="layer-card"> | |
| <h3>Layer 1: Knowledge Graph</h3> | |
| <p><code>memory/entities/</code></p> | |
| <p>Entity-based storage. Every important person, company, or project gets a folder with atomic facts (<code>items.json</code>) and a weekly-rewritten snapshot (<code>summary.md</code>).</p> | |
| <pre><code>memory/entities/ | |
| alice/ | |
| items.json ← atomic facts (timestamped) | |
| summary.md ← weekly snapshot | |
| acme-corp/ | |
| items.json | |
| summary.md</code></pre> | |
| <p><strong>Key principles:</strong></p> | |
| <ul> | |
| <li>Nothing is ever deleted — facts are marked <code>historical</code> when superseded</li> | |
| <li>Full history is preserved for traceability</li> | |
| <li>Summaries are regenerated weekly from raw facts</li> | |
| </ul> | |
| </div> | |
| <div class="layer-card"> | |
| <h3>Layer 2: Daily Notes</h3> | |
| <p><code>memory/YYYY-MM-DD.md</code></p> | |
| <p>The raw timeline. Written continuously throughout the day. Contains session notes, decisions, and context that might become durable facts.</p> | |
| <p>Durable facts are extracted into Layer 1 by the automated pipeline.</p> | |
| </div> | |
| <div class="layer-card"> | |
| <h3>Layer 3: Tacit Knowledge</h3> | |
| <p><code>MEMORY.md</code></p> | |
| <p>How your human operates — not facts about the world, but facts about <em>them</em>: communication preferences, work patterns, tool preferences, relationship context.</p> | |
| <p>Updated manually or by weekly synthesis when patterns emerge.</p> | |
| </div> | |
| <h2>The Compounding Engine</h2> | |
| <p>Two automated cron jobs maintain the system:</p> | |
| <h3>Fact Extraction (every 30 minutes)</h3> | |
| <p>Scans data sources (conversation logs, meeting notes, transcripts) for durable facts about people, companies, and projects. Extracts facts and adds them via a validated wrapper that handles deduplication and contradictions automatically.</p> | |
| <h3>Weekly Synthesis (configurable)</h3> | |
| <p>For each entity:</p> | |
| <ol> | |
| <li>Reviews all facts in <code>items.json</code></li> | |
| <li>Rewrites <code>summary.md</code> with current state</li> | |
| <li>Marks contradicting facts as historical</li> | |
| <li>Prunes very old historical facts</li> | |
| <li>Updates <code>MEMORY.md</code> if new patterns emerge</li> | |
| </ol> | |
| <h2>Retrieval</h2> | |
| <h3>Tiered Retrieval Tool</h3> | |
| <pre><code>bash memory/pipelines/retrieve-memory.sh "<user query>"</code></pre> | |
| <p><strong>Retrieval stages (cascading):</strong></p> | |
| <ol> | |
| <li><strong>Entity matching</strong> — Searches index for matching entities</li> | |
| <li><strong>Summary loading</strong> — Loads summaries for matched entities (up to 5)</li> | |
| <li><strong>Fact search</strong> — Searches all facts if insufficient (up to 10)</li> | |
| <li><strong>Daily notes fallback</strong> — Searches recent daily notes (last 7 days)</li> | |
| </ol> | |
| <h3>Recency Scoring</h3> | |
| <p>Results are scored using exponential time decay:</p> | |
| <div class="formula">score = e<sup>−λ × days_old</sup></div> | |
| <p>Where λ = ln(2) / half_life (default 30 days)</p> | |
| <table> | |
| <tr><th>Age</th><th>Score</th></tr> | |
| <tr><td>Today</td><td>1.000</td></tr> | |
| <tr><td>1 day</td><td>0.977</td></tr> | |
| <tr><td>1 week</td><td>0.871</td></tr> | |
| <tr><td>30 days (half-life)</td><td>0.500</td></tr> | |
| <tr><td>60 days</td><td>0.250</td></tr> | |
| <tr><td>90 days</td><td>0.125</td></tr> | |
| </table> | |
| <h2>Atomic Fact Schema</h2> | |
| <pre><code>{ | |
| "id": "uuid", | |
| "content": "Alice started her new job at Acme Corp", | |
| "source": "conversation|meeting|transcript|manual", | |
| "sourceRef": "meeting-id or session-key", | |
| "entityType": "person|company|project", | |
| "createdAt": "2026-01-28T23:00:00Z", | |
| "status": "active|historical", | |
| "supersedes": "uuid-of-old-fact or null", | |
| "edge": null // optional structured relationship | |
| }</code></pre> | |
| <h3>Optional Structured Edges</h3> | |
| <pre><code>{ | |
| "content": "Alice works at Acme Corp", | |
| "edge": { | |
| "subject": "alice", | |
| "predicate": "works_at", | |
| "object": "acme-corp" | |
| } | |
| }</code></pre> | |
| <h2>Time Decay</h2> | |
| <p>The system implements <strong>two complementary decay mechanisms:</strong></p> | |
| <h3>1. Semantic Decay (Synthesis Time)</h3> | |
| <ul> | |
| <li>New facts contradicting old ones mark the older fact <code>historical</code></li> | |
| <li>Weekly synthesis rewrites summaries focusing on <code>active</code> facts</li> | |
| <li>Historical facts get brief mentions</li> | |
| <li>Facts older than 6 months with <code>historical</code> status get truncated</li> | |
| </ul> | |
| <h3>2. Recency Scoring (Retrieval Time)</h3> | |
| <p>The tiered retrieval tool applies exponential time decay to rank results, ensuring newer facts surface first.</p> | |
| <h2>File Structure</h2> | |
| <pre><code>workspace/ | |
| MEMORY.md ← Layer 3: Tacit knowledge | |
| memory/ | |
| ARCHITECTURE.md ← Reference documentation | |
| YYYY-MM-DD.md ← Layer 2: Daily notes | |
| entities/ | |
| index.json ← Entity metadata index | |
| <entity-slug>/ | |
| items.json ← Layer 1: Atomic facts | |
| summary.md ← Layer 1: Weekly snapshot | |
| checkpoints/ ← Short-term session snapshots | |
| metrics/ ← Access frequency tracking | |
| logs/ ← Maintenance logs | |
| status.json ← Maintenance status | |
| pipelines/ | |
| add-fact-validated.sh ← Add facts with validation | |
| retrieve-memory.sh ← Tiered retrieval CLI | |
| build-entity-index.sh ← Rebuild index.json | |
| checkpoint-save.sh ← Save session state | |
| checkpoint-load.sh ← Load session state | |
| extract-facts.md ← Extraction pipeline docs | |
| weekly-synthesis.md ← Synthesis pipeline docs</code></pre> | |
| <h2>Getting Started</h2> | |
| <ol> | |
| <li>Install the skill to your workspace</li> | |
| <li>Run the bootstrap script to create the directory structure</li> | |
| <li>Configure extraction sources (conversation logs, meeting notes, etc.)</li> | |
| <li>Set up cron jobs for extraction and synthesis</li> | |
| <li>Start using <code>retrieve-memory.sh</code> for context-aware memory loading</li> | |
| </ol> | |
| <footer> | |
| <p> | |
| <strong>References:</strong><br> | |
| <a href="https://x.com/rohit4verse/status/2012925228159295810">Original architecture by @rohit4verse</a> | |
| </p> | |
| </footer> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment