--- name: reflect-logs description: > Process session logs into structured memory. Reads unprocessed logs from memory/log/, extracts lessons into topic memory files (gotchas, process-lessons, decisions, etc.), updates MEMORY.md index, and flags stale entries. Run periodically or after several sessions. allowed-tools: Read, Edit, Write, Glob, Grep, Bash(md5sum *), Bash(ls *), Bash(cat *), Bash(date *), Bash(find *), Bash(git log *), Bash(git diff *), Bash(head *) --- # Reflect Logs Skill You are processing session logs into structured, topic-based memory files. ## Pre-gathered context ### Reflection state !`cat .reflection-state.json 2>/dev/null || echo "{}"` ### Available log files !`ls -1t memory/log/ 2>/dev/null || echo "No logs found"` ### Current MEMORY.md index !`cat MEMORY.md 2>/dev/null || echo "No MEMORY.md found"` ### Existing memory topic files !`ls -1 memory/ 2>/dev/null || echo "No memory directory"` ### Settings (Read `~/dev/claude/projects/claude-foundations/settings.yaml` using the Read tool. If not found, use defaults: max_logs_per_run=10, retention_days=7, warn_unreflected_days=14) ### Recent git log (for staleness detection) !`git log --oneline -30 2>/dev/null || echo "Not a git repo"` ## Instructions ### Step 1: Identify unprocessed logs Compare `memory/log/` contents against `.reflection-state.json`: - A log is **new** if its filename is not in the `processed` map - A log is **changed** if its filename exists but the md5sum differs from the stored hash - Respect `max_logs_per_run` from settings (default: 10) — process oldest first To compute hashes, run `md5sum memory/log/` for each file and compare against the stored values. If there are no unprocessed logs, say so and stop. ### Step 2: Read and categorise Read each unprocessed log file. Group the extracted content by destination: **Routing rules:** - Gotchas tagged `[topic]` → `memory/gotchas-.md` (e.g., `[k8s]` → `memory/gotchas-k8s.md`) - Decisions → `memory/decisions.md` - Process Notes → `memory/process-lessons.md` - Key Context that represents a stable pattern → `memory/process-lessons.md` or a new topic file - Open Questions that were resolved across sessions → note the resolution, don't carry forward If a `[topic]` tag doesn't match any existing gotchas file, create a new `memory/gotchas-.md` file following the format of existing ones (title heading, individual gotcha subheadings with 2-4 line explanations). ### Step 3: Update memory files For each destination file: 1. **Read** the existing content using the Read tool 2. **Deduplicate**: Do NOT add entries that already exist in substance, even if worded differently. Check for semantic overlap, not just string matching. 3. **Append** new entries in the same style as existing content: - Gotcha files: `## Heading` with 2-4 lines of explanation including symptom and fix - Process lessons: Imperative rule format ("Always X before Y", "Never assume Z") - Decisions: `## Heading` with rationale paragraph 4. If creating a new topic file, include a top-level `# Gotchas` heading and make it self-contained ### Step 4: Staleness detection Scan existing entries in the memory topic files you touched (not all files — only the ones relevant to this run): - **Version-based**: If an entry mentions a specific version (e.g., "Cilium 1.19.1", "chart v39.x"), check `git log` for version bumps past that number. If found, add `` as a comment after the entry. - **Fix-based**: If an entry describes a workaround for a bug, grep recent log files and git commits for keywords suggesting the bug was fixed upstream. If found, flag it. - **Automation-based**: If a process lesson describes a manual sequence, check if a script in `scripts/` now handles it. If so, flag or update the entry. Print all flagged items in the summary so the user can confirm removal. ### Step 5: Update MEMORY.md index If any new topic files were created: - Add a one-line entry to the appropriate section of MEMORY.md - Follow the existing format: `- [Title](memory/filename.md) -- Description` - Make the description specific and searchable — it's used to decide what to read ### Step 6: Update reflection state Write `.reflection-state.json` with updated hashes: ```json { "version": 1, "last_run": "", "processed": { "log/YYYY-MM-DD.HHMMSS.md": "", ...existing entries... } } ``` Preserve existing entries. Add new ones for the logs just processed. Use `date -u +%Y-%m-%dT%H:%M:%SZ` for the timestamp. ### Step 7: Summary Print: - Number of logs processed - New entries added (listed by destination file) - Stale entries flagged (with the reason) - Any new topic files created - Any open questions resolved ## Quality checks - Every new entry must be **actionable or informative** — no filler - Gotchas include **symptom AND fix**, not just "X was tricky" - Process lessons are phrased as **rules** ("Always X before Y") - New entries match the **formatting style** of existing entries in the target file - Deduplication is by **substance**, not exact string match