AgentSkillsCN

hierarchical_memory

管理一套以Markdown文件存储的简易层级化记忆系统。当用户希望保存笔记、回溯过往情境、回顾先前讨论内容,或随时间累积学习心得时,此技能将是您的理想之选。但请勿将其用于特定于代码的文档编写(建议改用CLAUDE.md或AGENTS.md)。

SKILL.md
--- frontmatter
name: hierarchical_memory
description: >
  Manage a simple hierarchical memory system stored as markdown files.
  Use when the user wants to save a note, recall past context, review
  what was discussed previously, or aggregate learnings over time.
  Do NOT use for code-specific documentation (use CLAUDE.md or AGENTS.md instead).
allowed-tools: Bash(uv run *), Bash(git *), Read, Write, Glob

Manage notes in hierarchical memory at $CLAUDE_OBSIDIAN_DIR/memory/ (default: ~/claude/obsidian/memory/).

Set CLAUDE_OBSIDIAN_DIR to change the vault root. All paths derive from it.

Quick Reference

CommandWhat it does
note "text"Append timestamped line to today, report aggregation staleness
listList all memory files with type and date
read-day [YYYY-MM-DD]Output a day's content (default: today)
read-month [YYYY-MM]Output a month's summary (default: current)
read-overallOutput overall_memory.md
read-currentOutput overall + current month + today in one call
statusShow aggregation staleness

Commands

All commands:

bash
uv run --directory SKILL_DIR python scripts/memory.py <command> [args]

Where SKILL_DIR is the directory containing this skill.

Save a note

bash
uv run --directory SKILL_DIR python scripts/memory.py note "Your note text here"

Appends: - **TIMESTAMP** [hostname:reponame]: TEXT to today's daily file. Prints a staleness one-liner after saving — e.g. Aggregation stale: 2026-02 CREATE, overall UPDATE or Aggregation: up to date.

Readers

Three focused readers + one convenience shortcut:

bash
# Read a specific day (default: today)
uv run --directory SKILL_DIR python scripts/memory.py read-day 2026-02-10

# Read a monthly summary (default: current month)
uv run --directory SKILL_DIR python scripts/memory.py read-month 2026-02

# Read overall memory
uv run --directory SKILL_DIR python scripts/memory.py read-overall

# Read everything current (overall + month + today) in one call
uv run --directory SKILL_DIR python scripts/memory.py read-current

List files

bash
uv run --directory SKILL_DIR python scripts/memory.py list

Shows all memory files with type (daily/monthly/overall/unknown) and modification date. Warns on unknown files.

Check aggregation status

bash
uv run --directory SKILL_DIR python scripts/memory.py status

Shows which monthly summaries need creating or updating, overall memory staleness, and knowledge graph contents.

File Structure

code
$CLAUDE_OBSIDIAN_DIR/memory/
├── overall_memory.md    # Overall working memory (synthesized from monthly)
├── 2026-02.md           # Monthly summary (sortable YYYY-MM)
├── 2026-02-08.md        # Daily notes (append-only)
└── ...

Memory Hierarchy

LevelPurposeFreedom
LinesRaw capture. Append-only, no judgment.None
Daily (YYYY-MM-DD.md)Container for a day's notes.None
Monthly (YYYY-MM.md)Compress: what mattered this month?High
Overall (overall_memory.md)Synthesize: current state of the world.Highest

Memory Search Guidance

NeedSourceWhy
Big picture facts, preferences, contextoverall_memory.mdSynthesized, compressed — current state of the world
Time period contextYYYY-MM.mdThemed detail for a specific month
Specific detailsYYYY-MM-DD.mdRaw, unfiltered daily entries
Curated knowledge$CLAUDE_OBSIDIAN_DIR/knowledge_graph/Durable topic notes, personal knowledge base

For keyword search, use Grep/Glob directly on the memory directory:

bash
# Find memory files by name pattern
Glob("$CLAUDE_OBSIDIAN_DIR/memory/*.md")

# Search memory contents for a keyword
Grep(pattern="search term", path="$CLAUDE_OBSIDIAN_DIR/memory/")

Aggregation

Always run status first to see what needs work. Then launch sub-agents only for months that need CREATE or UPDATE.

Monthly summary

Launch a sub-agent for each month that needs CREATE or UPDATE:

Read all daily notes in $CLAUDE_OBSIDIAN_DIR/memory/ for YYYY-MM. Write a monthly summary to $CLAUDE_OBSIDIAN_DIR/memory/YYYY-MM.md. Include: key decisions, important events, learnings, and any facts that changed (new job, new tools, new preferences). Drop noise (test notes, trivial observations, routine operations). Organize by theme, not by date. More recent notes take priority over older ones. Tag each theme with #topic tags (e.g. #skills, #architecture, #debugging). Include [[obsidian links]] to related vault notes where appropriate. Keep it concise.

Overall working memory

Launch a sub-agent only if status shows overall needs CREATE or UPDATE:

Read all monthly summaries in $CLAUDE_OBSIDIAN_DIR/memory/ chronologically. Write $CLAUDE_OBSIDIAN_DIR/memory/overall_memory.md as a current-state working memory. Rules: (1) Facts use last-write-wins — if the user changed jobs, reflect only the current employer. (2) Key learnings and preferences persist across time. (3) Events compress — keep milestones, drop details. (4) The result should read like a living profile: big picture facts, preferences, context, and knowledge — "here is what I know about this user and their world right now." Not a changelog. Not granular details unless truly important. (5) Tag each section with #topic tags for obsidian graph discoverability. (6) Include [[obsidian links]] to related vault notes.

When to aggregate

The note command reports staleness after each save. Finish all your notes first, then aggregate any stale months/overall in one pass. The status command still exists for manual inspection with full detail.

Fact Freshness

Key facts in overall_memory.md can go stale — jobs change, preferences evolve, projects wind down. When relying on a fact from memory that seems like it could have changed (employment, location, active projects, tool preferences), consider asking the user to confirm it's still current rather than assuming. This is especially true for facts that are months old. Don't be annoying about it — just be aware that memory is a snapshot, not a live feed.

Git Integration

After saving notes or aggregating, commit and push. Use git -C to avoid cd (matches the Bash(git *) permission):

bash
git -C $CLAUDE_OBSIDIAN_DIR add -A && git -C $CLAUDE_OBSIDIAN_DIR commit -m "memory update" && git -C $CLAUDE_OBSIDIAN_DIR push

If no remote is configured, use the private_repo skill to set one up.