feat(harness): add memoize sub-action for memory hygiene#8
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new memoize sub-action to the harness skill so users can run a deterministic memory-hygiene pass over Claude Code memory and optionally wire a weekly remote review workflow around it. It extends the existing harness surfaces (snapshot, audit, doctor, etc.) with a maintenance path for keeping memory indexes, frontmatter, and stale references from drifting over time.
Changes:
- Adds
skills/harness/scripts/memoize.sh, a new report-generating script that checks memory index sync, frontmatter hygiene, stale citations, and possible duplicates. - Adds
skills/harness/scripts/memoize-prompt.md, a/scheduleprompt template for a weekly remote memory-review routine. - Updates
skills/harness/SKILL.mdto advertise, route, and document the newmemoizeaction and its related files.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 14 comments.
| File | Description |
|---|---|
skills/harness/scripts/memoize.sh |
Implements the new memory-hygiene scan and report generation logic. |
skills/harness/scripts/memoize-prompt.md |
Defines the weekly remote workflow for reviewing memory and opening a PR with findings. |
skills/harness/SKILL.md |
Documents the new memoize action, routing keywords, and supporting files. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- CLAUDE_DIR override now cascades to default search roots - MEMOIZE_SEARCH_ROOTS uses PATH-style colon separator (paths with spaces) - ./ and ../ tokens resolve under search roots, not CWD - prune .git, node_modules, vendor, etc. during fallback walk - drop unread SUMMARY stderr emission - prompt drops the local-script branch (snapshot has no scripts) - prompt index-check explicitly skips MEMORY.md and _*.md - prompt clarifies stale-citation is local-only - SKILL.md clarifies report-vs-memory contract
This was referenced May 2, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5.
Issue
Memory under
~/.claude/projects/<slug>/memory/is reactive — entries get written when the agent notices something worth saving, but nothing prunes or consolidates. Over time, project memories cite renamed files, feedback memories accumulate near-duplicates, andMEMORY.mddrifts out of sync with the actual files. The current "verify before recommending from memory" rule inCLAUDE.mdis a read-time check, not a maintenance pass.Effect on the user
Stale memory leaks into responses. The agent recalls a function that no longer exists, or repeats the same feedback rule three different ways because nobody noticed the duplicate. Trust in memory erodes, and the user ends up suppressing the system rather than maintaining it.
Root cause
There's no maintenance surface. The harness has
install/update/doctorfor hooks and commands,snapshot+auditfor the broader setup, but nothing that touches memory. The only existing safeguard runs at read-time, per-recall, and can't fix structural drift like a missing index entry or a frontmatter typo.The fix
A new
memoizesub-action — deterministic, idempotent, report-only.skills/harness/scripts/memoize.shruns four checks against~/.claude/projects/<slug>/memory/:memory/*.mdis listed inMEMORY.md; every entry points at a real file.name,description,type.~/,/Users/,./, or ending in a known source extension) that resolve nowhere across~/.claude/projects/and~/Projects/. Conservative on purpose — false positives cost more than misses; slash-commands, brace expansions, and regex-shaped strings are filtered out.typewhosenameordescriptionare lexically similar (Jaccard ≥ 0.5). Flag, don't merge.Output goes to
<memory>/_memoize-report.md(leading underscore so it's never indexed byMEMORY.md). The report is byte-stable on equal runs — running twice produces an identical file. Flags:--dry-run,--target=PATH. Env knobs mirrorsnapshot.sh:CLAUDE_DIR,USER_PROJECT_KEY,MEMOIZE_SEARCH_ROOTS.skills/harness/scripts/memoize-prompt.mdis the/schedulerecipe for a weekly remote routine that runs the script, layers in the semantic checks the lexical pass can't catch (conceptual duplicates, outdated facts, conflicting guidance), and PRsaudits/memory/YYYY-MM-DD.mdagainst the snapshot repo. Suggested cron0 6 * * 0(Sunday 06:00 UTC), modelclaude-opus-4-7. The remote agent never modifies memory directly — the user reviews and applies.skills/harness/SKILL.mdpicks upmemoizein the frontmatterdescription(so the skill auto-routes on "memoize" / "consolidate memory" / "prune memory"), a row in the dispatch table, a new## memoizesection, and an entry in the Files-in-this-skill table.Validation
./scripts/harness-check.shpasses — shellcheck clean (resolved three SC2005 stylistic warnings onecho $(dim …)patterns), ruff, mypy, pytest.bash skills/harness/scripts/memoize.sh --dry-runagainst the real~/.claude/projects/-Users-marlinf/memory/reports zero findings.memoizeruns produce a byte-identical report (diffempty) — idempotency confirmed./grade,/harness-check, brace expansionstacks/{typescript,python,go,laravel}, regex/MFC/class-based). Restricting to hard path prefixes + known source extensions dropped the noise to zero against the same input.