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
| 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:
- 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_searchsubdirectories - Group name mapping rule: group chat room IDs must first be resolved via
memory/group_names.jsonto a friendly name{group_name}before use
2. Five-Step Loading Flow
| 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).
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
| 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 |
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.
| 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.
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
| 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 |
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
- Entry gate — index is the only entry
- Five-step loading — name mapping → index → intent → load → sub-layer → budget
- Loading discipline — 2+1 file limit, clear on switch
- Write-back — immediately update on decisions
- Memory Flush —
/remem+ Pre-compact + Idle - Auto-Flush — precompact hook before compaction
- DM Progressive — independent layout, survives uninstall
- Auto-Initialization — init missing memory from known info
微信扫一扫