APM Agent Progressive Memory

APM Protocol (Agent Progressive Memory): Progressive disclosure protocol for group chat AND DM (main session) memory.

Audits

Pending

Install

openclaw skills install apm-agent-progressive-memory

APM — Progressive Disclosure Protocol

APM supports both group chat and private (main session DM) memory management. The two structures are completely independent and do not interfere with each other.

Group vs DM: Strategy Comparison

AspectGroup ChatDM (Main Session)
Memory pathmemory/groups/{group_name}/memory/main/
Loading5-step progressive (index → P0 → P1 → P2 → P3)3-layer progressive (index → attention → longterm)
Index filememory/groups/{group_name}.mdmemory/main/index.md
Priority filesattention.md, project.md, experience.md, people.mdattention.md, longterm.md
Entry ruleMust read index first, no subdirectory bypassMust read index first
Flush triggerPer-group flush on /rememFull-session flush on /remem

Key differences:

  • Group uses 5-step loading with budget controls; DM uses simpler 3-layer
  • Group has conventions/ sub-directory; DM does not
  • DM reuses existing MEMORY.md; Group uses dedicated files
  • Uninstaller: Group loses memory access; DM retains MEMORY.md

Agent must follow the layered disclosure protocol when accessing memory in group chats: read the index first, then load layers on demand.

Core Rules

1. Entry Gate

  • The only legal entry point for group chat memory is memory/groups/{group_name}.md (index file)
  • Forbidden: directly reading any sub-files under memory/groups/{group_name}/
  • Forbidden: bypassing the index to directly memory_search subdirectories
  • Group name mapping rule: group chat room IDs must first be resolved via memory/group_names.json to a friendly name {group_name} before use

2. Five-Step Loading Flow

StepActionOutput
0. Group name mappingCheck memory/group_names.json, convert room ID to {group_name}Friendly name
1. Route to indexmemory_get("memory/groups/{group_name}.md")Hard Rules + routing table
2. Intent matchingMatch current message to trigger scenarioFile to load
3. Explicit loadmemory_get("memory/groups/{group_name}/{file}.md")Actual memory content
4. Sub-layer controlLoad only if Step 3 file references conventions/1 sub-file max
5. Budget circuit-breakerStop when cumulative tokens exceed memory_budgetStop loading

Only one best-matching file is loaded per session (highest priority wins).

3. Loading Discipline

  • Maximum 2 P0-P2 files + 1 P3 file per session
  • conventions/ files: only 1 at a time
  • When switching group chats, clear old context first, then restart from Step 1

4. Write-Back on Updates

  • New decision → append to experience.md
  • Task status change → update attention.md
  • Index files: append-only (mark deleted entries [DEPRECATED] instead of removing)

5. Memory Flush

TriggerConditionAction
/rememUser manual triggerFull flush
Pre-compactContext near limitAuto-flush before loss
Idle timeout30min inactive, no flushOne-time auto-flush

6. Auto-Initialization on Missing Memory

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.

ScenarioAction
Group index missingCreate from group_names.json + context
DM index missingCreate from MEMORY.md content

Initialization is not overwriting: existing files are never overwritten — only created when completely absent.

File Structure

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 Definitions

PriorityFileContentWhen to Load
P0attention.mdActive tasks, blockersAny work conversation
P1project.mdTech stack, architectureTechnical decisions
P2experience.mdLessons learnedSearch hit + append
P3people.mdTeam roles, contactsNeed to find someone

DM Entry Loading (to add in AGENTS.md)

## 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)

Flush State File

memory/flush-state.json:

{
  "groups": { "last_flush_time": "..." },
  "main_session": { "last_flush_time": "..." },
  "pending_items": []
}

Anti-Pattern

❌ Load all at once        → ✅ Load only one at a time
❌ Skip index           → ✅ Read index first
❌ Load two groups      → ✅ Clear old, reload from Step 1

Complete Protocol Checklist

  1. Entry gate — index is the only entry
  2. Five-step loading — name mapping → index → intent → load → sub-layer → budget
  3. Loading discipline — 2+1 file limit, clear on switch
  4. Write-back — immediately update on decisions
  5. Memory Flush/remem + Pre-compact + Idle
  6. Auto-Flush — precompact hook before compaction
  7. DM Progressive — independent layout, survives uninstall
  8. Auto-Initialization — init missing memory from known info