Files
custom-claude-skills/skills/reflect-logs/SKILL.md
Paul O'Reilly 5a59d463de Fix skill frontmatter and simplify distill skill instructions
Replace non-ASCII characters in log and distill-best-practices
frontmatter that silently prevented skill loading. Simplify distill
skill instructions. Update install.sh for new skills.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:15:45 +13:00

5.1 KiB

name, description, allowed-tools
name description allowed-tools
reflect-logs 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. 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/<filename> 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-<topic>.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-<topic>.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 # <Topic> 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 <!-- STALE? Project has upgraded past <version> --> 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:

{
  "version": 1,
  "last_run": "<ISO-8601 timestamp>",
  "processed": {
    "log/YYYY-MM-DD.HHMMSS.md": "<md5hash>",
    ...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