Memory lint
Periodic health check of the file-based LLM Wiki memory (the `~/.claude/.../memory/` bundle) — the "lint" operation of the Karpathy LLM-Wiki pattern. Invoke every week or two, or after a batch of memory-ingest writes, or when the memory "feels stale". Finds contradictions, stale/superseded claims, orphan pages, broken `[[wikilinks]]`, index drift (file↔MEMORY.md mismatch), unquoted-`#` frontmatter truncation, and redundant clusters worth merging — then records findings in log.md. Read-only proposals for anything destructive; the user confirms merges/deletions.From its SKILL.md
npx -y skills add bentleypark/aiwatch --skill memory-lintAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
4.1 KB, as published. Nobody here has run it
memory-lint — keep the LLM Wiki healthy
The file memory (~/.claude/projects/-Users-bentley-Desktop-bentely-aiwatch-aiwatch/memory/) compounds over
time; without periodic linting it drifts. This is the lint operation of the LLM-Wiki pattern (#891).
When to run
- Every 1–2 weeks, after a batch of
memory-ingestwrites, or when recall feels noisy/stale.
Checks
-
Index drift — every
memory/*.md(except MEMORY.md) has exactly one MEMORY.md line, and every MEMORY.md link resolves to a file. ReportNOT INDEXED/MISSING FILE. -
Broken wikilinks — every
[[stem]]resolves to an existingmemory/stem.md(wikilinks target thetype_-prefixed filename stem, not the frontmattername; or a deliberate forward-marker). Report danglers. -
Frontmatter integrity — every page has
name+type; nodescription/titletruncated by an unquoted bare#(grep for descriptions containing#without surrounding quotes). -
Contradictions / stale claims — two pages that assert opposite things, or a page whose claim a later session invalidated (e.g. a file/flag it names no longer exists — verify against current code before flagging).
-
Redundant clusters — near-duplicate pages on one topic (e.g. the #891 Phase 1 review/close/verify clusters) that should be merged into one, preserving each original's Why.
-
Decision-graph structure (#967) — run
npm run lint:graph -- --github. The--is required:npm run lint:graph --githubsilently swallows the flag and runs the offline subset, which then passes while skipping every liveness check. (node scripts/lint-decision-graph.mjs --githubworks too.) It checks what is mechanical and refuses to guess at what is not:- edge grammar —
bounds::only on aconstraint_*page and only ever targeting a decision page;constrains::only ondecision_*;advances::only oninitiative_*(rule 1b);blocks::never a wiki edge. - dead edges (
--github) — everyadvances:: #Nresolves to an OPEN issue that is not a PR. - duplicate claims — no issue is a slice of two initiatives.
- dangling
[[wikilinks]]— over the WHOLE bundle, not just the graph pages: this is the only mechanical version of check 2 (which is otherwise a prose instruction), so a broken link anywhere is a hard finding here. - unclaimed candidates (
--github) — openarea:biz/area:marketingissues that no initiative claims. A report, never a finding, and exit code 0. Whether an issue advances an initiative is a judgement; a lint that decides it manufactures false confidence. Read the list, decide, edit the page.
Structural findings exit non-zero. The lint cannot run in CI — the memory bundle is harness-global, so Actions has nothing to check out — but its pure functions are CI-gated via
npm run test:scripts. - edge grammar —
Output
- Write a
YYYY-MM-DD lint: <n> findings (<summary>)line tomemory/log.md. - Auto-fix only the safe, mechanical issues (repoint a broken wikilink to its renamed target, add a missing
index line, quote a
#-truncated description). - Propose — do NOT auto-apply — anything lossy (merging pages, deleting stale claims). Present the plan and wait for user confirmation (user feedback is never deleted unilaterally; merge preserves the Why).
Relationship
Pairs with memory-ingest (the write side). Neither touches the repo — the memory dir is harness-global.