| name | recap |
| description | Batch-promote recurring insights from session logs into memory/ files with frequency filtering. Use when the user wants to extract persistent lessons or patterns from recent sessions — 'recap my recent sessions', 'what have I been learning lately'. Do NOT use for: saving a single fact now (use learn), writing today's session log (use wrapup), or synthesizing a specific topic into a note (use distill). |
| schedulable | true |
Recap
Batch-promotes insights from session logs into memory/ files. Applies frequency filtering
to ensure only recurring insights are promoted. Does NOT write to MEMORY.md — Critical
Behaviors are promoted exclusively via /learn.
Session Log Discovery
Glob [logs_folder]/session/**/*-session-*.md (post-v2.4.0: session logs live under the dedicated session/ subfolder); filter to files WITHOUT recapped: frontmatter field.
Process only those (faster than scanning all logs).
If no unrecapped logs found → tell user "No unrecapped session logs found." and stop.
Run Threshold
Read recap.min_sessions from onebrain.yml (default: 6 if field absent).
Read recap.min_frequency from onebrain.yml (default: 2 if field absent).
1 unrecapped log:
→ warn: "Only 1 session log — promotion filter requires at least {min_frequency} sessions."
→ stop (nothing can pass frequency filter with only 1 log)
2 to (min_sessions - 1) unrecapped logs:
→ warn: "{N}/{min_sessions} sessions — below threshold. Recommended to wait for more sessions. Run recap now?"
→ AskUserQuestion: run-now / wait
→ if wait: stop without processing
≥ min_sessions unrecapped logs:
→ proceed immediately, no confirmation needed
Promotion Filter (always applied, regardless of log count)
After deciding to proceed, apply frequency filter to all extracted insights:
- Promote only insights whose topic appears in ≥ min_frequency of the session logs being processed
- Single-occurrence insights → skip; insight stays in session log (accessible later via /distill)
Why require recurrence: An insight seen once is an observation. Seen in multiple separate sessions, it becomes evidence of a genuine pattern worth long-term storage. The frequency filter prevents one-off thoughts from cluttering memory/ with noise that quickly becomes stale.
Example (min_frequency=2, 8 logs):
- Topic "recap" → appears in logs 1, 3, 5, 7 → ✅ promote
- Topic "dreaming" → appears in log 2 only → ⏭ skip
- Topic "worktree" → appears in logs 4, 6 → ✅ promote
Conflict Handling
When insights conflict with existing memory files, scan ONLY files with status: active
or status: needs-review — skip deprecated files.
Collect ALL conflicts first, then resolve sequentially:
──────────────────────────────────────────────────────────────
⚠️ {N} conflicts found — resolving one at a time
──────────────────────────────────────────────────────────────
[{n}/{N}] 💡 insight from session {YYYY-MM-DD}:
"{insight text}"
Conflicts with `memory/{filename}.md`
Then AskUserQuestion:
- question: "How should I handle this conflict?"
- header: "Conflict [{n}/{N}]"
- multiSelect: false
- options:
- label: "update", description: "Merge insight into existing file (old content still partially correct)"
- label: "supersede", description: "Create new file, deprecate old (old content fully outdated)"
- label: "separate", description: "Create new file separately (no conflict, keep both)"
- label: "skip", description: "Discard this insight, move on"
Options:
- update → merge insight into existing file in-place, bump
verified
- supersede → create new file; deprecate old; remove old row from MEMORY-INDEX.md;
set
supersedes: on new, superseded_by: on old
- separate → create new file, no changes to existing
- skip → discard this insight, move on
Memory Consolidation
After resolving conflicts, scan for files with overlapping topics.
Build a topic frequency map from all active+needs-review files.
Scan only files whose topics appear in 2+ files — skip deprecated.
Resolve sequentially [1/N]:
[{n}/{N}] 🔀 Overlapping topics — merge recommended
{file-a}.md (topics: {a}, {b})
{file-b}.md (topics: {a}, {b}, {c})
Then AskUserQuestion:
- question: "Merge these overlapping memory files?"
- header: "Consolidate [{n}/{N}]"
- multiSelect: false
- options:
- label: "merge", description: "Synthesize into one file (preserves all unique information)"
- label: "skip", description: "Leave both files as-is"
merge:
- Read both files
- Synthesize (do NOT concatenate) into one coherent document preserving all unique information
- Name new file after shared topics (e.g.
dev-workflow-worktree.md)
- Frontmatter: keep highest
conf; most recent verified; if either was needs-review
→ merged file inherits needs-review (caution wins); update total_needs_review accordingly
- Deprecate both old files + remove their rows from MEMORY-INDEX.md; for each deprecated file:
decrement
total_active if it was active, or total_needs_review if it was needs-review
- Add new file to MEMORY-INDEX.md; increment
total_active (or total_needs_review if inherited needs-review)
Contradiction during merge: if files contain contradicting facts, do NOT auto-pick.
AskUserQuestion showing both versions: keep version A / keep version B / cancel merge
skip → leave both files as-is, move to next opportunity
Order of Operations
- Read
recap.min_sessions and recap.min_frequency from onebrain.yml (apply defaults if absent)
- Apply run threshold check (warn / stop / proceed per rules above)
- Extract insights from all unrecapped session logs; apply promotion filter (
min_frequency)
- Collect and resolve all conflicts (sequential [1/N])
- Run memory consolidation (sequential [1/N])
- For EVERY processed session log (whether it produced insights or not):
- Set
recapped: YYYY-MM-DD in frontmatter
- Extract 2–4 keywords from log content → set
topics: [...] in frontmatter
auto-saved: true and synthesized_from_checkpoints: true logs processed same way
- Update
onebrain.yml stats.last_recap: YYYY-MM-DD
Writing Promoted Insights
Each insight that passes the frequency filter:
- Write to
memory/kebab-case-topic.md with frontmatter:
tags: [agent-memory], source: /recap, status: active, conf: medium, verified: today, updated: today, created: today, topics: [...]
- Filename collision: if target exists, suffix with
-NN automatically (no user prompt —
batch mode)
- Infer
type from content (same 5 categories as /learn): behavioral / context / dev / project / reference — pick silently, no prompt
- Add row to MEMORY-INDEX.md:
| [[memory/filename]] | topic1, topic2 | {inferred-type} | active | description |
- Update MEMORY-INDEX.md
updated: and total_active counter
Do NOT write to MEMORY.md. Critical Behaviors are promoted exclusively via /learn.
Write Log Entry
Follow ../_shared/audit-log-format.md (canonical frontmatter, append-per-day algorithm, run-section heading, failure mode) with:
- Filename:
YYYY-MM-DD-recap.md — one file per day.
- Tags:
[audit-log, recap]
- Skill:
/recap
Per-skill body template (replace the canonical ## Run HH:MM section's body with this):
## Run HH:MM
### Memory Changes
- **created** memory/feedback_X.md — "always do Y" (frequency: 3 sessions)
- **updated** memory/project_active.md — added Studio milestone
- **deprecated** memory/feedback_old_pattern.md — superseded by feedback_X
### Source Sessions
- 07-logs/session/2026/05/2026-05-08-session-02.md
- 07-logs/session/2026/05/2026-05-09-session-01.md
### Skipped (insufficient frequency)
- "use bun for everything" — only 1 occurrence
Output
No unrecapped logs
✅ No unrecapped session logs found.
Completion (after all conflicts + consolidations resolved)
──────────────────────────────────────────────────────────────
💡 Recap — {N} sessions processed
──────────────────────────────────────────────────────────────
Promoted {N} insights to memory/:
• `{filename}.md` — {topic}
{N} session logs marked recapped.
→ Run /distill to compress a completed thread into a knowledge note.
In-Skill Examples
Promotable vs. non-promotable insights (min_frequency=2, 3 logs):
| Topic | log-01 | log-02 | log-03 | Unique log count | Promoted? |
|---|
| "review-rounds" | ✓ | ✓ | ✓ | 3 | ✅ yes |
| "worktree" | ✓ ✓ ✓ ✓ | — | — | 1 | ❌ no — 4 occurrences in 1 log = frequency 1 |
| "checkpoint" | — | ✓ | — | 1 | ❌ no — below min_frequency |
Good promotable insight (generalizable, not session-specific):
Run minimum 3 independent review rounds before merging any PR.
Not promotable (open question, not yet a fact):
Should we use per-occurrence weighting instead of per-log frequency?
→ Comes from ## Open Questions — skip, don't promote.
Known Gotchas
-
Frequency is per unique session log, not per occurrence. A topic mentioned 3 times within a single session log still counts as frequency 1. Only occurrences across separate log files increment the frequency count.
-
Extract from findings sections only. Insights from ## Open Questions are unresolved and not promotable — they are not yet facts. Extract from ## Key Decisions, ## Insights & Learnings, and ## What Worked / Didn't Work sections only.
-
merged confidence on merge. When merging two memory files where one is conf: high and the other is conf: low, the merged file inherits the LOWER confidence. The conservative value wins — a low-confidence fact does not become high-confidence by being merged with one that is.
-
auto-saved: true logs. These are checkpoint-synthesized summaries. They may contain less detail than manually-written session logs. Weight them equally for frequency counting but be conservative about extracting nuanced insights from them.