Recall Maintain
Scannednpx machina-cli add skill davegoldblatt/total-recall/recall-maintain --openclawRun maintenance on the memory system. Primary function: pressure-based demotion when working memory exceeds the word budget. Secondary: stale entry verification, contradiction checks, open loop review.
What To Do
0. Preconditions
Check for IDs first. Scan all managed files (CLAUDE.local.md, memory/registers/.md, memory/archive/**/.md) for single-line list item entries (lines starting with - , not inside code blocks, not placeholders).
-
If ANY managed entry lacks an ID (no
^tr[0-9a-f]{10}at end of line): refuse to run.Cannot run maintain: [N] entries are missing IDs. Run /recall-init-ids first to tag all entries. -
If ANY duplicate IDs are found across entries: refuse to run.
Cannot run maintain: duplicate ID found. ID: ^tr8f2a1c3d7e 1. CLAUDE.local.md line 15 2. registers/preferences.md line 8 Resolve manually before running maintain.
If preconditions pass, proceed.
1. Load and Reconcile
Parse entries from all managed files. For each entry, extract:
- The entry text (everything between
-and^tr...) - The ID (the
^tr[0-9a-f]{10}token) - The file path and line number
- The tier (derived from file location):
CLAUDE.local.md->workingmemory/registers/*->registermemory/archive/*->archive
Load metadata from memory/.recall/metadata.json:
- If file doesn't exist, create it as empty
{} - For each inline ID missing from metadata, create a metadata entry with
created_at=now,last_reviewed_at=now,pinned=false,snoozed_until=null,status=active, tier from file - For each metadata entry, recompute
tierfrom file location (file location is authoritative - overwrite metadata tier if it differs)
2. Compute Working Memory Pressure
Count words in working memory entries only (tier=working):
- For each working entry, count whitespace-separated tokens in the entry text
- Exclude the leading
-and trailing^tr...from word count - Sum all working entry word counts =
working_words - Target = 1500 words
Report:
Working memory: [working_words] words (target: 1500)
3. Select Candidates
A. Pressure Candidates (only if working_words > 1500)
From working entries, exclude:
- Entries with
pinned: truein metadata - Entries with
snoozed_untilin the future
Score remaining working entries:
score = 1.0 * word_count(entry) + 0.1 * days_since(last_reviewed_at)
(If last_reviewed_at is missing, treat as 365 days.)
Sort by score descending. Take the top candidates until the sum of their word counts >= (working_words - 1500). This is the minimum set needed to bring working memory under budget.
B. Superseded Cleanup (always, regardless of pressure)
Find any entry across all tiers where metadata has status: "superseded" and tier is NOT archive. These should be archived.
4. Present Candidates
If no candidates (under budget and no superseded entries):
recall-maintain — all clear
━━━━━━━━━━━━━━━━━━━━━━━━━━
Working memory: [N] words (target: 1500) - under budget
No superseded entries pending cleanup.
No action needed.
Otherwise, present each candidate with its reason:
recall-maintain — [N] candidates
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Working memory: [working_words] words (target: 1500, over by [N])
Pressure candidates (need to free [N] words):
1. [CLAUDE.local.md] 23 words, last reviewed 45 days ago
"Dave prefers concise error messages and no unnecessary logging"
→ [k]eep / [p]in / [s]nooze / [d]emote / [a]rchive / [m]ark superseded
2. [CLAUDE.local.md] 18 words, last reviewed 30 days ago
"Current deployment target is AWS us-east-1 with fallback to us-west-2"
→ [k]eep / [p]in / [s]nooze / [d]emote / [a]rchive / [m]ark superseded
Superseded cleanup:
3. [registers/tech-stack.md] status: superseded
"Using Node 16 in production"
→ [a]rchive (recommended) / [k]eep
Apply all / decide individually?
5. Execute Actions
For each candidate, apply the chosen action:
keep: Update last_reviewed_at to now in metadata. No file changes.
pin: Set pinned: true and update last_reviewed_at in metadata. No file changes. Entry will be excluded from future pressure candidates.
snooze: Set snoozed_until to now + 30 days (or user-specified duration) and update last_reviewed_at in metadata. No file changes. Entry will be excluded from pressure candidates until the snooze expires.
demote (working -> register):
- Remove the entry line from CLAUDE.local.md
- Append the entry line (with ID) to
memory/registers/_inbox.md- Create
_inbox.mdwith header if it doesn't exist:# Inbox > Entries demoted from working memory. Review and file into appropriate registers.
- Create
- Update metadata tier to
registerandlast_reviewed_atto now
archive (working or register -> archive):
- Remove the entry line from its current file
- Append the entry line (with ID) to
memory/archive/ARCHIVE.md- Create ARCHIVE.md with header if it doesn't exist:
# Archive > Archived memory entries. Searchable but never auto-loaded.
- Create ARCHIVE.md with header if it doesn't exist:
- Update metadata: set
status: "archived",tier: "archive",last_reviewed_atto now
mark_superseded: Set status: "superseded" and last_reviewed_at to now in metadata. No file changes. Entry will appear in superseded cleanup on next maintain run.
File Editing Rules
When moving entries between files:
- Remove the ENTIRE line (including the
-prefix and^tr...suffix) - Do NOT reflow, reformat, or modify any other lines in the source file
- Append the ENTIRE line to the destination file
- Preserve exact formatting of the entry text
6. Write Metadata
After all actions are applied, write memory/.recall/metadata.json:
- Sort keys alphabetically for readable diffs
- Use 2-space indentation
- Write deterministically (same input = same output)
7. Secondary Checks
After the pressure-based flow, run these additional checks (same as before):
Stale entries: Search registers for entries where metadata last_reviewed_at is older than 30 days. Present them:
Stale entries (not reviewed in 30+ days):
1. [registers/tech-stack.md] Last reviewed: 2025-12-01
"Using Postgres 15 in production" ^tra1b2c3d4e5
→ [v]erify (update last_reviewed_at) / [u]pdate / [a]rchive
Contradictions: Scan across tiers for conflicting claims on the same topic. Flag any found.
Open loop review: Check memory/registers/open-loops.md for items that are past due or resolved.
Daily log archival: If daily logs older than 30 days exist, suggest archiving to memory/archive/daily/.
8. Summary
recall-maintain — complete
━━━━━━━━━━━━━━━━━━━━━━━━━━
Working memory: [before] -> [after] words (target: 1500)
Actions taken:
Kept (reviewed): [N]
Pinned: [N]
Snoozed: [N] (until [date])
Demoted to _inbox.md: [N]
Archived: [N]
Marked superseded: [N]
Secondary checks:
Stale entries verified: [N]
Contradictions found: [N]
Open loops reviewed: [N]
Daily logs to archive: [N]
Metadata: [N] entries in memory/.recall/metadata.json
Source
git clone https://github.com/davegoldblatt/total-recall/blob/main/skills/recall-maintain/SKILL.mdView on GitHub Overview
Recall Maintain performs pressure-based cleanup on the memory system. Its primary job is to demote, archive, or pin entries when working memory exceeds the word budget, with secondary checks like stale entry verification and contradiction detection to keep recall fast and relevant.
How This Skill Works
It scans CLAUDE.local.md, memory/registers/*.md, and memory/archive/*.md for IDs and tiers, then loads metadata from memory/.recall/metadata.json (creating it if missing). It counts words in working-tier entries to compute working_words, and if this exceeds 1500, it scores candidates by word_count + 0.1 * days_since_last_reviewed_at, selecting enough entries to bring the total under budget. It also performs superseded cleanup by archiving non-archive entries with status: superseded.
When to Use It
- Working memory exceeds the 1500-word target
- You’ve added or edited many entries and risk overflowing memory
- You need to prune unpinned, non-snoozed entries to reclaim space
- A scheduled maintenance pass is due to keep memory tidy
- There are entries labeled as superseded that should be archived
Quick Start
- Step 1: Run recall-maintain to begin the pressure-based cleanup
- Step 2: Review the generated candidate list and actions (keep, pin, snooze, demote, archive, supersede)
- Step 3: Apply decisions and re-run if needed until Working memory is under budget
Best Practices
- Always verify IDs and duplicates prior to running recall-maintain
- Respect pinned and snoozed flags when scoring candidates
- Prioritize archiving superseded entries first when cleaning up
- Consider last_reviewed_at; treat missing dates as 365 days for scoring
- Log actions and rationale to enable audit trails
Example Use Cases
- CLAUDE.local.md — 23 words, last reviewed 45 days ago; "Dave prefers concise error messages and no unnecessary logging"
- CLAUDE.local.md — 18 words, last reviewed 30 days ago; "Current deployment target is AWS us-east-1 with fallback to us-west-2"
- registers/tech-stack.md — 42 words, last reviewed 12 days ago; "Tech stack includes React, Node.js, and Kubernetes"
- CLAUDE.local.md — 10 words, last reviewed 8 days ago; "Caching policy adjusted for memory budget"
- memory/archive/old-logs.md — 55 words, last reviewed 60 days ago; "Archived older logs to reduce lookup times"