⚠️ READ-ONLY SKILL: This skill is a reference implementation. Do not edit files directly.
When installing, copy scripts to your workspace folder:
```bash
# Scripts → workspace scripts/
cp skills/engram/scripts/*.js scripts/
```
Templates and assets remain in the skill folder. Specify the path via env:
```bash
export ENGRAM_SKILL_DIR=skills/engram # or absolute path
bun scripts/init.js
```
WithoutENGRAM_SKILL_DIR, scripts look for assets relative to../from their location.
Memory System
Three-layer memory architecture for OpenClaw agents: curated long-term memory (MEMORY.md), structured knowledge graph (life/), and session-isolated daily notes (memory/).
Quick Start
# 1. Install QMD (if not installed)
bun skills/engram/scripts/install-qmd.js
# 2. Initialize everything
bun skills/engram/scripts/init.js
# Add a group session
bun skills/engram/scripts/add-session.js --platform telegram --id 3382546134
# Validate integrity
bun skills/engram/scripts/validate.js
# Migrate to v2 schema
bun skills/engram/scripts/migrate-v2.js --dry-run
Architecture Overview
┌─────────────────────────────────────────────┐
║ Layer 3: MEMORY.md (Curated Wisdom) ║
║ Long-term personal insights, decisions ║
├─────────────────────────────────────────────┤
║ Layer 2: Knowledge Graph (life/) ║
║ PARA entities with atomic facts ║
├─────────────────────────────────────────────┤
║ Layer 1: Daily Notes (memory/) ║
║ Raw session notes, per-session isolation ║
└─────────────────────────────────────────────┘
Data flows upward: Daily notes → extracted to Knowledge Graph → distilled to MEMORY.md
For full architecture details, see [references/architecture.md](references/architecture.md).
Memory Rules
Session Isolation
Golden Rule: Memory is isolated by session.
| Session Type | Memory Path | QMD Collection | Access | |-------------|-------------|----------------|--------| | Main (personal) | memory/agent-{id}/main/ | openclaw-memory-agent-{id}-main | Full: MEMORY.md + life/ | | Telegram group | memory/agent-{id}/telegram-{gid}/ | openclaw-memory-agent-{id}-telegram-{gid} | Own daily notes ONLY | | Discord channel | memory/agent-{id}/discord-{cid}/ | openclaw-memory-agent-{id}-discord-{cid} | Own daily notes ONLY |
Rules:
- NEVER cross-reference memory between sessions
- Group chats CANNOT see MEMORY.md or life/
- Always specify
-c <collection>in QMD queries
Every Session Startup (Fast/Full Init)
First, detect init mode based on the incoming message:
- If the message matches the heartbeat prompt → Fast Init
- Otherwise → Full Init
Fast Init (Heartbeat)
Heartbeats need speed, not full context. SOUL.md and USER.md are typically already in project context (OpenClaw loads them automatically).
- Determine session
- Create today's daily note if not exists
- Read
memory/heartbeat-state.json - Proceed to HEARTBEAT.md
Skipped: SOUL.md, USER.md, yesterday's daily note, MEMORY.md, life/index.md, QMD query — none needed for heartbeat flow.
Full Init (Interactive)
- Read SOUL.md, USER.md
- Determine session (main, telegram group, discord channel, etc.)
- Create today's daily note if not exists:
memory/agent-{id}/{session}/YYYY-MM-DD.md - Read session memory:
- Main: today + yesterday daily notes +
MEMORY.md+life/index.md - Group: today + yesterday daily notes only
- Knowledge Graph (main session only): run
qmd query "<topic of first user message>" -c life - Extract the main topic/entity from the user's first request and query it
- If message is a greeting or vague → defer to QMD Query Triggers below
QMD Query Triggers
Apply during a session (after Full Init). Run qmd query whenever a trigger fires.
Main session only — group chats do not have access to the Knowledge Graph (life/).
🔴 Mandatory Triggers (always run)
| Trigger | Condition | Query | |---------|-----------|-------| | First substantive request | User's first non-greeting message in a session | qmd query "<topic>" -c life | | Named entity appears | Project, person, or system mentioned for the first time in this session | qmd query "<entity name>" -c life | | Decision requested | User asks for advice, recommendation, or "what should I do" | qmd query "<topic>" -c life + check memory/domains/ if relevant |
🟡 Situational Triggers (use judgment)
| Trigger | Condition | |---------|-----------| | Topic shift | Conversation moves to a clearly different domain (e.g. dev → infra → marketing) | | Long session + new subject | >20 messages in session and a new subject appears | | "We did this before" | Request that could have history in prior sessions/notes | | Contradiction detected | Something the user says conflicts with what you believe you know |
How to run
# Combined KG + session memory (recommended)
qmd query "topic" -c life -c openclaw-memory-agent-{id}-main
# KG only (when session memory not relevant)
qmd query "topic" -c life
Use the most specific term you can extract. If multiple entities are relevant, run separate queries.
Daily Notes
- Path:
memory/agent-{id}/{session}/YYYY-MM-DD.md - Header:
# YYYY-MM-DD - Three-Layer Rotation (>1000 lines during heartbeat):
- Archive — full file moved to
archives/YYYY-MM/(nothing lost) - Stub — auto-summary (10-20 lines) with line refs to archive and KG links
- QMD index — archive indexed for granular search via
qmd query - Run rotation AFTER KG Extraction to minimize stub duplication
Knowledge Graph (PARA)
Structured memory in life/ using Projects/Areas/Resources/Archives:
life/
├── projects/<name>/ # Active work (summary.md + items.json)
├── areas/people/<name>/ # People (summary.md + items.json)
├── areas/groups/<name>/ # Groups
├── resources/<topic>/ # Reference material
├── archives/ # Inactive entities
└── index.md # Master entity index
Tiered retrieval:
qmd query "topic" -c life— search first- Read
summary.md— quick context (~90% sufficient) - Read
items.json— only for granular detail
Entity creation rules:
- Mentioned 3+ times across conversations
- Has a direct relationship to the user
- Is a significant project, person, or company
For the atomic fact schema (v2), see [references/fact-schema.md](references/fact-schema.md).
Writing Memory
| Type | Destination | |------|-------------| | Operational lesson | TOOLS.md or AGENTS.md | | Personal insight | MEMORY.md (main session only) | | Event/fact | Today's daily note | | Durable knowledge | Knowledge Graph (life/) |
When someone says "remember this":
- Determine the type
- Write to the appropriate file
- Run
qmd update
QMD Search
# Hybrid search (BM25 + vectors + rerank)
qmd query "search text" -c <collection>
# Multi-collection search (searches across multiple collections)
qmd query "search text" -c life -c openclaw-memory-agent-main-main
# BM25-only search (no GPU required, faster)
qmd search "search text" -c <collection>
# Update index after changes
qmd update # BM25 (instant)
qmd embed # Vectors (heartbeat only)
Strategy:
- Always use
-cflag for session isolation - Multi-collection (
-c col1 -c col2) for cross-cutting searches (e.g., KG + daily notes) - Use
qmd search(BM25-only) when GPU is busy or unavailable - Top 2-3 results usually sufficient
- Run
qmd updateafter writing memory - Do NOT run
qmd embedmanually (heartbeat handles it)
For QMD installation and configuration, see [references/qmd-setup.md](references/qmd-setup.md).
Heartbeat Integration
Add to your HEARTBEAT.md:
## Heartbeat Flow (every 30 minutes)
0. Create today's daily note + Three-Layer Rotation check
1. Monday? → Weekly Syn