A structured memory architecture for AI agents running on OpenClaw.
Gives your AI assistant persistent memory, identity, and proactive behaviour across sessions.
Author: Tomasz Przybylski
License: MIT
When you run an AI assistant, each session starts fresh — no memory of yesterday's decisions, your preferences, or ongoing projects. This memory system solves that by giving your agent a set of structured markdown files it reads at the start of every session.
The result: an assistant that remembers who you are, what projects you're running, and what needs to happen next — every single time.
workspace/
├── AGENTS.md # How the agent should behave (conventions, rules, workflow)
├── SOUL.md # Personality & tone (who the agent "is")
├── IDENTITY.md # Name, emoji, vibe
├── USER.md # About the human (name, timezone, focus)
├── TOOLS.md # Local notes: CLI paths, credentials hints, model routing
├── HEARTBEAT.md # Periodic check schedule + proactive task routing rules
├── MEMORY.md # Long-term curated memory (like a human's long-term memory)
├── MEMORY-INDEX.md # Compact index of MEMORY.md (faster to load, ~70% smaller)
│
├── memory/
│ ├── YYYY-MM-DD.md # Daily session notes (raw log of what happened)
│ └── heartbeat-state.json # Timestamps of last checks (email, calendar, todos...)
│
└── projects/
└── PROJECT-NAME/
└── MEMORY.md # Per-project memory (todos, context, credentials, next steps)
The main instruction file. Tells the agent:
- How to load memory at session start
- When and how to write memory
- How to handle group chats vs. direct messages
- Autonomy level (e.g. "never ask for permission")
- Sub-agent spawning protocol
- Heartbeat vs. cron: when to use each
Defines the agent's character. Not just "be helpful" — actual opinions, communication style, what to avoid (sycophancy, asking unnecessary questions), and the core philosophy.
Name, creature type, emoji. Minimal but gives the agent a consistent "self".
Who you're helping. Name, timezone, what to call them, current focus, communication channels. The agent reads this every session.
Not system-level config — this is the agent's personal cheat sheet. CLI paths, API keys format, model routing rules, platform-specific formatting rules.
The most complex file. Defines:
- Task routing rules: which channels map to which sub-agents
- Periodic checks: email every 4h, calendar every 6h, todos every 30min
- Cooldown tracking: prevents spam checking
- Reporting conventions: how/where to post results
- Status dashboard: live
STATUS.jsonupdates
Curated facts the agent should always know. Think of it as a human's long-term memory — distilled from daily notes, not raw logs. Updated periodically.
A lightweight index of MEMORY.md with line references ([MEMORY.md#L10-25]). Loaded instead of the full file to save context tokens (~70% smaller). Auto-synced by cron.
Raw session logs. What happened, decisions made, things to remember. The agent writes here during the session. Periodically reviewed and distilled into MEMORY.md.
Tracks Unix timestamps of the last time each periodic check was performed. Prevents duplicate checks across sessions.
{
"lastChecks": {
"email": 1234567890,
"calendar": 1234567890,
"projects": 1234567890,
"memory": 1234567890,
"todo_inbox": 1234567890,
"channel_sync": 1234567890
},
"lastHeartbeat": 1234567890
}Every project gets its own memory file. Contains:
- What the project is
- Credentials and access details
- Current todos (with priority)
- Next steps (written on pause/stop so any new session can continue)
- Log of what was done
The agent follows this sequence at the start of every session:
1. Read SOUL.md → who am I?
2. Read USER.md → who am I helping?
3. Read memory/YYYY-MM-DD.md (today + yesterday) → recent context
4. Read MEMORY-INDEX.md → compact long-term memory overview
5. (on-demand) memory_get("MEMORY.md", from=LINE) → specific sections
This keeps context usage low while ensuring the agent always has the right context.
OpenClaw can send periodic "heartbeat" messages to the agent. The agent uses HEARTBEAT.md as a checklist:
- Load
memory/heartbeat-state.json - Compare each check's last timestamp vs. its cooldown
- Run only the checks that are due (max 1-2 per heartbeat)
- Update the state file
- Post findings to the relevant Slack channel
Cooldowns (example):
| Check | Cooldown |
|---|---|
| 4h | |
| Calendar | 6h |
| TODO inbox | 30min |
| Projects | 8h |
| Memory maintenance | 24h |
A key pattern in this system: tasks given in a project channel should be delegated to a project-specific sub-agent, not handled inline.
Task in #project-channel
→ Spawn sub-agent for that project
→ Sub-agent works and reports in #project-channel
→ Main agent confirms delegation ("✅ Übergeben an Project-Agent")
Direct DM tasks (without channel context), quick info questions, and system tasks are handled inline.
The system maintains a projects/STATUS.json file synced to a live dashboard (via Supabase/GitHub Gist). Every agent updates it on task start and finish:
{
"current": "projectname — what I'm doing right now",
"last_updated": "2026-02-24T14:30:00+07:00",
"today": ["project: task done ✅"],
"projects": {
"project-name": { "status": "active", "last": "what was last done" }
}
}- Copy this repo into your OpenClaw workspace directory
- Fill in
USER.mdwith your details - Customise
SOUL.mdto your preferred personality - Edit
HEARTBEAT.md— add your project channels and check schedule - Create
projects/YOUR-PROJECT/MEMORY.mdfor each project - Configure OpenClaw heartbeat interval (e.g. 30 minutes)
"Each session, you wake up fresh. These files are your memory. Read them. Update them. They're how you persist."
The agent is not a stateless tool. It's a collaborator that grows with your projects. The memory system is what makes that possible.