SKILL.md still narrated the 2026-06-01-and-earlier additive-only stance. With the policy change captured in feedback_memory_sync_destructive_ok.md and sync-memory.sh now in mirror mode, the framing needed updating. Behavior of the tool itself is unchanged (--apply-safe still only does the low-risk index appends + profile->repo copies; merges/dedups still land in PROPOSED for a human). The reasons given for that are now: they're judgment calls, not "we might wipe useful data." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.1 KiB
name, description
| name | description |
|---|---|
| memory-dream | Memory lint + consolidation analyzer for the ClaudeTools REPO memory store (.claude/memory/). Audits the index, backlinks, referenced file paths, duplicate/overlap clusters, stale dated facts, and drift against the machine-local harness profile memory store. Default run is read-only. --apply-safe performs the low-risk fixes (append missing index lines, copy any profile-only files into the repo for indexing). Cluster merges, dedup deletes, and stale-fact removal are surfaced as PROPOSED actions for a human to apply -- they're judgment calls, not automation candidates. (Repo is the source of truth as of 2026-06-02; sync-memory.sh mirrors repo to profile, so PROFILE-side cleanup is handled by that script, not here. See feedback_memory_sync_destructive_ok.md.) Invoke for: "memory dream", "consolidate memory", "memory lint", "clean up memory", "memory errors", "dedupe memory". |
Memory Dream
A read-only-by-default analyzer that flags issues in the shared memory store.
Mutating ops are gated behind --apply-safe (for low-risk fixes) or the
PROPOSED section (for judgment calls a human resolves by hand).
The two-store model (important)
There are TWO separate memory stores on every machine:
- REPO store --
.claude/memory/(88+*.mdfiles +MEMORY.mdindex). Tracked in git, syncs to all machines via Gitea. This is the source of truth.CLAUDE.mdmandates writing here. - HARNESS PROFILE store --
$HOME/.claude/projects/<slug>/memory/. Machine local, NOT in git, NOT synced. This is the store the Claude Code harness auto-injects into the system prompt at session start.
The two drift over time. memory-dream reports that drift in its report
section. The companion script .claude/scripts/sync-memory.sh is what
actually reconciles them: it runs in mirror mode (since 2026-06-02) —
repo is authoritative, profile is synced to match (deletions propagate;
repo content wins on conflict). PROFILE-side hygiene lives in
sync-memory.sh, not here.
What it checks
scripts/memory_dream.py runs six READ-ONLY analyses over the REPO store:
- INDEX RECONCILE -- orphan files (no
MEMORY.mdline), index lines whose target file is missing, and frontmattername:vs filename signals. - BACKLINKS --
[[name]]references in bodies whose target slug has no file. - REFERENCED-ARTIFACT VALIDITY -- conservatively extracts repo-relative file paths / script names from each body (backtick-wrapped single tokens only) and flags ones not found in the repo. Reported as verify, never delete (many are legitimately server-side or in sibling repos).
- DUPLICATE / OVERLAP CLUSTERS -- groups memories by type + token-overlap /
shared slug-prefix and lists candidate mergeable clusters (e.g. the many
feedback_syncro_*files). Proposes merges; never performs them. - STALE DATED FACTS -- flags
project-type memories with an "as of " style claim older than ~6 months for re-verification. - DRIFT vs PROFILE STORE -- locates the harness profile memory dir for this project and reports profile-only files (candidates to migrate INTO the repo) and repo-only files (candidates to push OUT to profile). Report only.
The report ends with a ## PROPOSED (needs human approval) section that is
NEVER auto-applied.
Modes
- Default (no flag) -- REPORT ONLY. Mutates nothing. Writes a timestamped
report to
.claude/memory/_reports/YYYY-MM-DD-HHMM-dream.md(created if missing) and prints it to stdout. --apply-safe-- performs ONLY additive, non-destructive fixes and prints each action:- (a) append missing index lines to
MEMORY.mdfor orphan files, under the correct## <Type>header, never reordering or removing existing lines; - (b) copy profile-only memory files INTO the repo store (additive migration). If a same-named repo file already exists it is SKIPPED and the conflict is reported -- it is never overwritten.
- (a) append missing index lines to
--no-file-- print to stdout only; skip writing the_reports/file.--report-file <path>-- write the report to an explicit path.
What dream does NOT auto-do
memory-dream does NOT, even with --apply-safe:
- delete a repo memory file (cluster dedup is a judgment call — pick which file becomes canonical, fold the others' content, retire the originals deliberately);
- remove or reorder index lines (index cleanups are also surfaced as proposals);
- overwrite a file whose content differs;
- perform a proposed merge.
These stay in the report's ## PROPOSED section. The rationale isn't "never delete" any more (the fleet-wide additive safety net was dropped 2026-06-02; see feedback_memory_sync_destructive_ok.md) — it's that merges and dedups require human judgment about which file is canonical and how to combine content. Profile-side deletion DOES happen automatically — but in sync-memory.sh, not here.
Running it
This machine's Python launcher is py (per identity.json); the script also
runs under python / python3. Stdlib only -- no pip deps.
# REPORT ONLY (default) -- writes _reports/<stamp>-dream.md and prints it
py "$CLAUDETOOLS_ROOT/.claude/skills/memory-dream/scripts/memory_dream.py"
# report to stdout only, write nothing
py "$CLAUDETOOLS_ROOT/.claude/skills/memory-dream/scripts/memory_dream.py" --no-file
# additive-only fixes (append orphan index lines, migrate profile-only files)
py "$CLAUDETOOLS_ROOT/.claude/skills/memory-dream/scripts/memory_dream.py" --apply-safe
CLAUDETOOLS_ROOT resolves from the env var, else claudetools_root in
.claude/identity.json, else the repo root derived from the script's own
location -- no hardcoded drive letters.
Cleanup / approve workflow
- Run with no flag. Read the report (stdout or
_reports/<stamp>-dream.md). - Run
--apply-safeto take the safe additive wins: orphan index lines get added, profile-only memories get migrated into the repo (conflicts skipped and reported). - Work the
## PROPOSEDsection by hand:[MERGE?]-- decide whether to consolidate a cluster. If yes, author a new combined memory (or set of files for a rule/history split), retire the originals viagit rm, updateMEMORY.md. Deletions are now first-class —sync-memory.shmirror mode will propagate them to every profile store on the next run.[REVERIFY?]-- confirm the dated fact still holds; update the body and its date if it changed.[STALE-REF?]-- confirm the referenced path moved/renamed; repoint or annotate. Many are legitimately server-side (.serviceunits,/opt/...).[INDEX-CLEANUP?]/[DRIFT-RESOLVE?]-- human picks the winner.
- Commit the repo store changes so they sync to the fleet via Gitea.
Self-test
scripts/selftest.py runs the analyzer against a synthetic fixture memory
store in a temp dir and asserts each detector fires (orphan, missing target,
broken backlink, stale path, cluster, profile drift) and that --apply-safe
only touches the things it's supposed to (index appends + profile→repo copy
of new files; no deletions, no merges, no overwrites of differing content).
Run:
py "$CLAUDETOOLS_ROOT/.claude/skills/memory-dream/scripts/selftest.py"