Skill: biociao/apm-agent-progressive-memory (version 1.5.0)

--- name: APM-agent-progressive-memory description: "APM Protocol (Agent Progressive Memory): Progressive disclosure protocol for group chat AND DM (main session) 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 | 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_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 | 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) ```markdown ## 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`: ```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


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)