memory-consolidation
Skill5 starsChanged 43 days agoMITView on GitHub
Consolidation of recent Claude Code conversation logs into hub memory files. Extracts patterns, preferences, decisions. Updates patterns.md, conversation-log.md, CONTEXT.md. Archives entries older than 14 days. Adds wikilinks for hub-tracked projects. Audits frontmatter compliance. Surfaces stale projects (>30 days silent). Does NOT touch Claude Code's own built-in auto-memory. Invoke directly ("run memory consolidation") or wire up the opt-in scheduler in references/scheduling.md.
5 other projects use a version of this.
Adopted by
Most recently taken up by
- ArttuAn/agent-memory-skillstheir own version, first seen Oct 25, 2026
- modimihir07/agentic-ostheir own version, first seen Oct 25, 2026
- NVIDIA/nemoclaw-communitytheir own version, first seen Oct 13, 2026
- NITISH-R-G/agent-memory-protocoltheir own version, first seen Aug 1, 2026
- zwjbendn/weight-loss-skilltheir own version, first seen Mar 16, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- modimihir07/agentic-os★ 209same name
- NVIDIA/nemoclaw-community★ 142same name
- ArttuAn/agent-memory-skills★ 2same name
- NITISH-R-G/agent-memory-protocol★ 1same name
- zwjbendn/weight-loss-skill★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository12 other files it gives its agents.
- AGENTS.mdAGENTS.md
- councilSkill
- defuddleSkill
- doneSkill
- eli5Skill
- grill-meSkill
- learnSkill
- media-genSkill
- qmdSkill
- research-notebookSkill
- setup-for-meSkill
- wiki-articleSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
31 rules. 0 are common, 18 are distinctive, and 13 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
18
Distinctive
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 37
Only when no cutoff is supplied does the default apply: files modified in the last 24h (find ...
- Very specific: line 45
All three files live directly under the hub (resolved from JARVIS_HUB env, then ~/.jarvis-hub-path, then ~/jarvis-hub — same resolution …
- Distinctive: line 55
If a pattern you see in this window's data already exists in the file, increment its count and add the new evidence.
- Distinctive: line 57
Only surface patterns with 3+ total occurrences.
- Very specific: line 59
After writing this run's dated section to patterns.md, run the rotation script so the file doesn't grow unbounded:
- Very specific: line 65
If patterns.md doesn't exist yet, create it with the three curated section headers (empty) before appending this run's dated section — …
- Distinctive: line 79
If today's entry already exists (re-run same day), UPDATE it with the full day's data.
- Distinctive: line 85
Update only the "Last Session" and "Active Projects" sections based on most recent activity:
- Distinctive: line 90
Do this through the script rather than by hand, so it stays idempotent and no model ever loads the files:
- Distinctive: line 117
If the window is sparse or low-signal, write a minimal update and say so.
- Distinctive: line 122
Keep entries tight — a paragraph each, not an essay.
- Very specific: line 123
Never write memory content directly into MEMORY.md (the hub's hand-curated index) or into any user_*/project_*/feedback_*/reference_*-style …
- Very specific: line 129
Commit or push (that's /done's job, on the user's explicit signal)
- Distinctive: line 130
Run broader queries (git log, codebase search) — work from conversation logs only
- Very specific: line 137
If the window's total user-message count is below the scaled floor: write a one-line note to conversation-log.md ("Quiet stretch — no …
- Very specific: line 153
If you are about to write to any path under ~/.claude/projects/, stop immediately and abort that write — you should only ever be *reading* …
- Distinctive: line 167
Only emit for names that genuinely appear in the content — don't inject artificially.
- Distinctive: line 168
Do NOT emit wikilinks inside code blocks, JSON, or file paths.
- Very specific: line 174
After all three memory files have been updated, scan <hub>/*.md (top-level only, not subdirs) for files missing required frontmatter fields.
- Very specific: line 179
Read each top-level .md file in <hub>/.
- Distinctive: line 181
If any file is missing one or more fields, record a warning line per file.
- Very specific: line 182
If warnings exist, write them to <hub>/audit/frontmatter-warnings-YYYY-MM-DD.md (use today's date).
- Distinctive: line 186
If all files pass, skip creating the audit file (no empty files).
- Very specific: line 192
After updating CONTEXT.md, for each project listed in its "Active Projects" section, check git activity — only if that project directory is …
- Distinctive: line 199
If the command returns no output (directory doesn't exist, isn't a git repo, or has no commits), skip silently.
- Distinctive: line 201
If the last commit date is >30 days ago, append a warning line to the consolidation output (not to any memory file — surface in this …
- Distinctive: line 219
Delete the entry from its prior section — it must not be re-surfaced as a pending suggestion.
- Distinctive: line 220
If only part of a compound entry was confirmed, split it: move the confirmed clause to Applied Suggestions, leave the rest in place.
- Very specific: line 221
Do this before running the trim-patterns.py rotation step in section 1 — the rotation script only rotates dated sections and doesn't know …
- Distinctive: line 225
After computing this run's counts in section 1 above, for any Observed Pattern whose count newly reaches or crosses 3 (was <3 before this …
- Distinctive: line 229
Before adding, check for an existing Open Threads line naming that pattern — do not duplicate.
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Memory Consolidation
You are a memory-consolidation agent. Left to a manual trigger, you consolidate the window the invoking prompt gives you. If the user has wired up the opt-in scheduler (scripts/memory-tick.mjs, see references/scheduling.md), that scheduler runs on a tick that fires at most once per calendar day, whenever the machine is on and online, and derives the window from the last successful run — which may span several days if runs were missed.
Hard caps (DO NOT EXCEED)
- Max 40K input tokens total (after filtering)
- Max 5K output tokens across all 3 file updates
- Skip run entirely if fewer than 10 user messages in the window (scale this floor if the window covers more than one day — see Scope below)
- Total budget: stop and write partial if exceeded
Conversation log location
~/.claude/projects/*/*.jsonlClaude Code writes session logs into per-cwd project directories under ~/.claude/projects/. This skill scans all of them — every project the user has worked in with Claude Code, not just one — because there's no reliable way to guess which single directory is "the" projects root on someone else's machine. If the user wants to scope this to a subset, they can set JARVIS_CONSOLIDATION_SCOPE to a narrower glob before invoking; absent that, scan everything.
Each .jsonl file is one conversation session. Lines are JSON objects with type, message, etc.
Assert before proceeding: count the matched files. If the count is 0, do NOT take the sparse-window path — that means the glob itself is broken (wrong home directory, no Claude Code history yet), which is a different problem than "a quiet stretch." Report it plainly and exit non-zero rather than writing a misleadingly cheerful "quiet day" note.
Filter: only keep messages where type === "user" or type === "assistant" AND message.content is text (not tool use). Drop all tool_use and tool_result rows to save budget. Also drop system reminders.
Also drop injected skill/system text from "user" rows. A type: "user" row is not necessarily something the user typed — the harness injects skill bodies, hook output and command output as user turns. Discard any user-turn content that starts with Base directory for this skill:, <command-name>, <local-command-, <system-reminder>, or Caveat:. Without this filter one session's apparent volume inflates ~10x and the pattern counts become meaningless.
Scope
The window is whatever the invoking prompt says it is. If you were launched by scripts/memory-tick.mjs, it derives the window from the last SUCCESSFUL run, not from the clock, and passes an explicit ISO cutoff. Honour that cutoff: select files by modification time covering the whole span, then filter individual exchanges by their own timestamps.
Only when no cutoff is supplied does the default apply: files modified in the last 24h (find ... -mtime -1), exchanges from the last 24h.
Why this is not a detail: a scheduled job gets skipped on every tick the machine is off or offline. A hardcoded 24h window means each skipped tick is lost permanently — the next run can't see back far enough to recover it. A stamp-derived window (which memory-tick.mjs provides) makes the gap close itself.
Scale the sparse-window floor to the window. The "fewer than 10 user messages" rule above is written per day; across an N-day window the floor is N×10. Applying the one-day floor to a five-day window would discard a genuinely busy stretch as a quiet one.
Output targets
All three files live directly under the hub (resolved from JARVIS_HUB env, then ~/.jarvis-hub-path, then ~/jarvis-hub — same resolution every other skill in this plugin uses).
1. <hub>/patterns.md
Record recurring behaviors detected. Sections:
- ## Observed Patterns (3+ occurrences) — pattern + count + evidence
- ## Applied Suggestions — patterns the user confirmed, now behavior
- ## Dismissed — patterns the user rejected, don't suggest again
If a pattern you see in this window's data already exists in the file, increment its count and add the new evidence. If new, add to Observed Patterns with count=1 (or higher if multiple occurrences appear in this window).
Only surface patterns with 3+ total occurrences.
After writing this run's dated section to patterns.md, run the rotation script so the file doesn't grow unbounded:
python3 "${CLAUDE_PLUGIN_ROOT}/skills/memory-consolidation/scripts/trim-patterns.py"It keeps frontmatter + curated sections (Observed/Applied/Tracking/Dismissed) + dated sections from the last 14 days, merges any duplicate same-date headers, and archives older dated sections to <hub>/archive/patterns-YYYY-MM.md. Idempotent — safe even if this skill runs twice in a day. Non-zero exit means it refused to write (accounting mismatch or unexpected file shape) — leave patterns.md as-is and report the failure rather than retrying blindly.
If patterns.md doesn't exist yet, create it with the three curated section headers (empty) before appending this run's dated section — unlike /done, which never creates this file, consolidation is the thing that owns it.
2. <hub>/conversation-log.md
Rolling 7-day log. Today's entry format:
## YYYY-MM-DD
**Topics:** comma-separated list of main topics (projects, features, concerns)
**Decisions:** bullet list of concrete decisions made ("We decided to X because Y")
**Action items:** tasks assigned or taken on, with owner if clear
**Notable quotes:** 1-3 direct quotes that capture the user's intent or a new preferenceIf today's entry already exists (re-run same day), UPDATE it with the full day's data.
Archive entries older than 7 days to <hub>/archive/YYYY-MM.md (append). Keep the main conversation-log.md lean.
3. <hub>/CONTEXT.md
Update only the "Last Session" and "Active Projects" sections based on most recent activity:
- Last Session: today's date + topics + open threads
- Active Projects (index, not a log): this section holds exactly ONE status line per project and nothing else. The history of each project lives in
<hub>/projects/<name>.md, where<name>is the lowercase project name with non-alphanumerics turned into hyphens. For each project mentioned in this window: (1) add a dated entry to<hub>/projects/<name>.md, newest first (create the file if absent, with small frontmatter:name,description); (2) REPLACE that project's one status line inCONTEXT.mdwith a summary of the new state, 360 characters at most. Never add a second line for a project. Do not read whole project files.
Do this through the script rather than by hand, so it stays idempotent and no model ever loads the files:
python3 "${CLAUDE_PLUGIN_ROOT}/skills/done/scripts/update-context.py" \
--project "<name>" --status "<one line, current state>" --history "<dated detail>"It replaces or inserts the single status line, adds the history entry to <hub>/projects/<name>.md (skipping an identical entry that is already there), and moves any stray extra lines for the same project into that file verbatim. Re-running it with the same arguments changes nothing. Exit 2 means invalid input (nothing written); exit 1 means a write failed and CONTEXT.md was left as it was, so report it instead of retrying blindly.
An existing hub whose Active Projects section already has many dated lines per project: run the one-time migration python3 "${CLAUDE_PLUGIN_ROOT}/skills/memory-consolidation/scripts/split-context.py" (dry run), then again with --apply. It backs CONTEXT.md up to <hub>/archive/CONTEXT-YYYY-MM-DD-pre-split.md first and moves every original entry verbatim into the project files.
Open Threads stay short. When this run sees that a thread is resolved or stale, do not delete it and do not leave it to pile up: move the line verbatim to <hub>/archive/open-threads-archived-YYYY-MM-DD.md (create it with a one-line note on why each was moved, appending if the file exists for today), and leave a single pointer line at the top of the section. Archive only what you can show is resolved or stale; when unsure, keep it.
Do NOT wipe the file. Only update those two sections. Exception: section F below (Pattern Threshold Forcing Function) may also append a line to ## Open Threads when an Observed Pattern crosses the count >=3 threshold, and the stale-thread archiving above removes lines from it. If CONTEXT.md doesn't exist yet, create it with the minimal scaffold the done skill's update-context.py uses (frontmatter + Active Projects / Open Threads / Recent Decisions / Recent Sessions headers) rather than skipping the update; the script does this itself. Consolidation and /done share ownership of this file, so either one may be the first to create it.
Pattern detection heuristics
Look for:
- Tasks that got rescheduled 3+ times → flag as stale
- Time-of-day preferences (consistent hours when the user is most active)
- Meeting types that get cancelled/rescheduled repeatedly
- Projects that stall for >1 week
- Repeated feedback phrases ("don't do X", "always do Y")
- Task types that follow predictable sequences
Be honest about signal
If the window is sparse or low-signal, write a minimal update and say so. Don't invent patterns from 2 data points. Memory degrades when padded with noise.
Write rules
- Match the language of the original content when quoting the user directly; keep schema/structure labels in English.
- Keep entries tight — a paragraph each, not an essay.
- Never write memory content directly into
MEMORY.md(the hub's hand-curated index) or into anyuser_*/project_*/feedback_*/reference_*-style memory file — those are a separate, user-curated system. Only touch the three files this skill owns:patterns.md,conversation-log.md,CONTEXT.md.
Do NOT
- Modify
MEMORY.mdor any hand-curated hub memory file - Modify any project's own
CLAUDE.mdfile - Commit or push (that's
/done's job, on the user's explicit signal) - Run broader queries (
git log, codebase search) — work from conversation logs only - Interpret silence as rejection ("the user didn't reply" ≠ "the user disagrees")
- Repeat patterns already in Applied Suggestions as new observations
- Send anything to a chat bridge, Telegram, email, or any other notification channel — this skill reports into its own text output only. If the user wants an alert on failure, that's their scheduler's job (see
references/scheduling.md), not this skill's.
Sparse window fallback
If the window's total user-message count is below the scaled floor: write a one-line note to conversation-log.md ("Quiet stretch — no consolidation triggered") and exit without touching patterns.md or CONTEXT.md.
A. Claude Code's own auto-memory — DO NOT CROSS
Claude Code has a native auto-memory system, keyed to the current project's git root, that's separate from this plugin's hub. It owns its own rotation and dedupe.
This skill MUST NOT edit:
- Anything under
~/.claude/projects/*/memory/(Claude Code's own per-project auto-memory)
This skill operates exclusively on the hub's own consolidation files:
<hub>/CONTEXT.md<hub>/patterns.md<hub>/conversation-log.md
If you are about to write to any path under ~/.claude/projects/, stop immediately and abort that write — you should only ever be reading .jsonl files from there, never writing into it.
B. Wikilink emission (derived from the hub, not hardcoded)
When writing new content to any of this skill's three files, emit [[ProjectName]] wikilinks whenever a project name appears in the text — but only for projects the hub actually knows about. There is no fixed project roster shipped with this plugin (a stranger's machine has different projects than the one this skill was originally built for); derive it instead:
- List the hub's own top-level project directories (the same set
wiki-check.shin thedoneskill treats as "hub-tracked projects" — i.e. real directories under<hub>/, excluding infrastructure dirs likesessions,wiki,daily-notes,archive). - For each directory name that appears as a bare word in the text you're about to write, wrap it as
[[DirectoryName]](match the directory's actual casing).
There is no equivalent "people" roster shipped with this plugin (the original had one seeded from a personal contacts file; that file has no generic analog and isn't part of the hub format this plugin ships). Skip person-name wikilinking entirely rather than inventing a roster — if the user wants that back, it would need its own hub convention (e.g. <hub>/people/) they define themselves.
Rules:
- Only emit for names that genuinely appear in the content — don't inject artificially.
- Do NOT emit wikilinks inside code blocks, JSON, or file paths.
C. Frontmatter Compliance Audit
After all three memory files have been updated, scan <hub>/*.md (top-level only, not subdirs) for files missing required frontmatter fields.
Required fields: name, description
Steps:
- Read each top-level
.mdfile in<hub>/. - For each file, check whether its frontmatter block (
---...---) contains both required fields. - If any file is missing one or more fields, record a warning line per file.
- If warnings exist, write them to
<hub>/audit/frontmatter-warnings-YYYY-MM-DD.md(use today's date). Create theaudit/directory if it doesn't exist. - Warning format per file:
- <filename>: missing fields: <field1>, <field2> - Do NOT auto-fix. Surface only — the user fixes manually.
If all files pass, skip creating the audit file (no empty files).
D. Stale Project Surfacing
After updating CONTEXT.md, for each project listed in its "Active Projects" section, check git activity — only if that project directory is actually a git repo; skip silently otherwise.
For each project <name> under the hub:
git -C "<hub>/<name>" log -1 --format=%ci 2>/dev/nullIf the command returns no output (directory doesn't exist, isn't a git repo, or has no commits), skip silently.
If the last commit date is >30 days ago, append a warning line to the consolidation output (not to any memory file — surface in this skill's own text output to the user):
Project <name> has been silent for N days; consider moving to dormant.Calculate N as: today's date minus the last commit date (integer days).
Collect all stale warnings and emit them together at the end of the skill's output, under a heading ## Stale Project Warnings.
E. Confirmation → Applied Promotion
While reading the window's conversation logs (per the Scope step above), if a message shows the user explicitly confirming a suggestion this skill (or the assistant generally) previously surfaced — direct confirmations like "yes", "do it", "go ahead", "save that" replying to a stated pattern/suggestion:
- Locate the confirmed suggestion in
patterns.md— under## Observed Patterns (3+ occurrences)or## Tracking (<3 occurrences). - Move that entry into
## Applied Suggestions, formatted- **<short name> (applied YYYY-MM-DD):** <what changed, one line>using today's date. - Delete the entry from its prior section — it must not be re-surfaced as a pending suggestion.
- If only part of a compound entry was confirmed, split it: move the confirmed clause to Applied Suggestions, leave the rest in place.
- Do this before running the
trim-patterns.pyrotation step in section 1 — the rotation script only rotates dated sections and doesn't know about promotions.
F. Pattern Threshold Forcing Function
After computing this run's counts in section 1 above, for any Observed Pattern whose count newly reaches or crosses 3 (was <3 before this update, or is ≥3 but has no prior threshold flag recorded):
- Add a prominent line to this run's digest output:
PATTERN THRESHOLD: <pattern name> reached count <N> — <one-line action recommendation>. This is text output only — the point of the digest is for whoever reads this skill's output (interactively, or in the scheduler's log file) to see it; this skill does not push it anywhere itself. - Append a new numbered line under
## Open Threadsin<hub>/CONTEXT.md(next available number), formatted:N. **PATTERN THRESHOLD (YYYY-MM-DD):** <pattern name> at count <count> — <one-line action recommendation>. - Before adding, check for an existing Open Threads line naming that pattern — do not duplicate; a pattern gets one Open Thread line, not one per run.
Scheduling (fully optional)
This skill can be invoked directly ("run memory consolidation") or wired up
to run automatically. See references/scheduling.md for launchd (macOS) and
cron snippets, plus scripts/memory-tick.mjs and scripts/run-agent.mjs,
which implement the catch-up-window scheduler and a TCC-safe job runner. None
of this installs itself — it's there for you to opt into, not something this
plugin sets up on your behalf.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

