Install
openclaw skills install apm-agent-progressive-memoryAPM Protocol (Agent Progressive Memory): Progressive disclosure protocol for group chat AND DM (main session) memory.
openclaw skills install apm-agent-progressive-memoryAPM supports both group chat and private (main session DM) memory management. The two structures are completely independent and do not interfere with each other.
| Aspect | Group Chat | DM (Main Session) |
|---|---|---|
| Memory path | memory/groups/{group_name}/ | memory/main/ |
| Loading | 5-step progressive (index → P0 → P1 → P2 → P3) | 3-layer progressive (index → attention → longterm) |
| Index file | memory/groups/{group_name}.md | memory/main/index.md |
| Priority files | attention.md, project.md, experience.md, people.md | attention.md, longterm.md |
| Entry rule | Must read index first, no subdirectory bypass | Must read index first |
| Flush trigger | Per-group flush on /remem | Full-session flush on /remem |
Key differences:
Agent must follow the layered disclosure protocol when accessing memory in group chats: read the index first, then load layers on demand.
memory/groups/{group_name}.md (index file)memory/groups/{group_name}/memory_search subdirectoriesmemory/group_names.json to a friendly name {group_name} before use| Step | Action | Output |
|---|---|---|
| 0. Group name mapping | Check memory/group_names.json, convert room ID to {group_name} | Friendly name |
| 1. Route to index | memory_get("memory/groups/{group_name}.md") | Hard Rules + routing table |
| 2. Intent matching | Match current message to trigger scenario | File to load |
| 3. Explicit load | memory_get("memory/groups/{group_name}/{file}.md") | Actual memory content |
| 4. Sub-layer control | Load only if Step 3 file references conventions/ | 1 sub-file max |
| 5. Budget circuit-breaker | Stop when cumulative tokens exceed memory_budget | Stop loading |
Only one best-matching file is loaded per session (highest priority wins).
conventions/ files: only 1 at a timeexperience.mdattention.md[DEPRECATED] instead of removing)| Trigger | Condition | Action |
|---|---|---|
/remem | User manual trigger | Full flush |
| Pre-compact | Context near limit | Auto-flush before loss |
| Idle timeout | 30min inactive, no flush | One-time auto-flush |
When a flush is triggered for a session whose memory system has not yet been initialized, the Agent must initialize it based on available information.
| Scenario | Action |
|---|---|
| Group index missing | Create from group_names.json + context |
| DM index missing | Create from MEMORY.md content |
Initialization is not overwriting: existing files are never overwritten — only created when completely absent.
memory/groups/
├── {group_name}.md # L0: Entry gate (mandatory read)
└── {group_name}/ # Group memory (direct access forbidden)
├── attention.md # P0: Current focus
├── project.md # P1: Project static info
├── experience.md # P2: Experience / decision log
├── people.md # P3: People profiles
└── conventions/ # L3: Detailed specifications
├── api.md
└── ...
memory/main/ # DM progressive disclosure
├── index.md # L0: DM entry index
├── attention.md # P0: Current tasks, blockers
├── longterm.md # P1: MEMORY.md distilled summary
├── daily-synced.md # P2: Daily notes summary
└── projects/ # P3: Project context
└── {name}.md
| Priority | File | Content | When to Load |
|---|---|---|---|
| P0 | attention.md | Active tasks, blockers | Any work conversation |
| P1 | project.md | Tech stack, architecture | Technical decisions |
| P2 | experience.md | Lessons learned | Search hit + append |
| P3 | people.md | Team roles, contacts | Need to find someone |
## Every Session
1. Read `SOUL.md` → USER.md → MEMORY.md
2. **If in MAIN SESSION** (DM):
- Read `memory/main/index.md` — DM progressive index
- Based on routing, load up to 2 files
- Report `上次 flush: YYYY-MM-DD HH:mm` (from `flush-state.json`)
3. Read `memory/YYYY-MM-DD.md` (today + yesterday)
memory/flush-state.json:
{
"groups": { "last_flush_time": "..." },
"main_session": { "last_flush_time": "..." },
"pending_items": []
}
❌ Load all at once → ✅ Load only one at a time
❌ Skip index → ✅ Read index first
❌ Load two groups → ✅ Clear old, reload from Step 1
/remem + Pre-compact + Idle