Skip to main content

A lint for Claude Code memory directories — catches frontmatter rot, oversized files, and stop-word noise before it pollutes Claude's context.

Project description

claude-memory-lint

Disclaimer: This is an independent third-party tool. It is not affiliated with, endorsed by, or sponsored by Anthropic. "Claude" and "Claude Code" are trademarks of Anthropic and are used here nominatively to identify the official CLI/product this tool integrates with.

A static lint for Claude Code memory directories. Catches the file-quality problems that lead to context pollution before they reach the prompt — stop generic-keyword noise at the source instead of chasing it at runtime.

cml check  ~/.claude/projects/<id>/memory/   # exits 1 on ERROR
cml fix    ~/.claude/projects/<id>/memory/   # auto-add missing aliases
cml stats  ~/.claude/projects/<id>/memory/   # counts only, no contents

Why

Claude Code memory directories grow quickly. Once frontmatter is inconsistent and a meaningful fraction of files only carry generic keywords (api, github, claude, task, agent, …), runtime routing degrades into "every common word matches every file": context gets stuffed with unrelated memory and the model's attention drifts.

Runtime routers can patch the symptom. The cause is on the write side: missing frontmatter, empty aliases:, oversized files, stale copies. claude-memory-lint raises those defects to ERROR / WARN / INFO at write-time so they never reach the auto-load path.

Privacy posture

This is the privacy-conscious choice in the memory-tooling space:

  • No LLM calls. Period. Heuristics only.
  • No file body in stdout. stats and check --format json print filenames, rule IDs, and counts — never the file content.
  • Auto-fix writes a .bak next to the original and never sends anything off-machine.
  • A separate hook (claude-memory-router) handles runtime routing with the same posture; this lint is its compile-time companion.

Install

pip install claude-memory-lint
# or for development:
pip install -e .[dev]

Python 3.10+. No required runtime dependencies.

Rules

ID Severity What it catches
R001 ERROR frontmatter missing or unterminated
R002 ERROR both aliases: and triggers: are empty / absent
R003 WARN at 25 KiB / ERROR at 30 KiB file size threshold (lowered from 50 KiB in v0.1.2)
R004 WARN filename stem is not kebab-case ASCII
R005 INFO inbound: file is not referenced by any other memory file (orphan)
R006 WARN stop-word density in name + description ≥ 40 %
R007 INFO duplicate normalised stem (likely stale copy)
R008 INFO mtime older than 180 days
R009 ERROR secret literal pattern (GitHub PAT / AWS / Anthropic / OpenAI / Google / Slack / Stripe) — match is never echoed in the lint output
R010 WARN (opt-in) outbound: dangling markdown link ](*.md) — target not found in tree or archive/ (enable via --dangling-links). Complementary to R005: R005 catches a file no one points at; R010 catches a link that points at nothing
R011 WARN (opt-in) stale backup file *.bak / .backup / .orig / trailing ~ older than 7 days in the active directory (enable via --stale-backup)

Thresholds are tunable in code; runtime config file support is on the roadmap.

R009 (added in v0.2.0) is the response to a real-world incident where a GitHub PAT literal sat in a memory file for days under .gitignore "protection" while still being one filesystem-read away from the LLM context. The rule deliberately reports only the pattern type and the line — the matched substring is never written to stdout, JSON, SARIF, or any error path — because a lint that leaks the secret it caught is worse than no lint.

Use as a pre-commit hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/hinanohart/claude-memory-lint
    rev: v0.2.1
    hooks:
      - id: claude-memory-lint
        args: [check, --rule, R001, --rule, R002]

This blocks commits that introduce a memory file without proper frontmatter or aliases.

Use in CI

- name: lint memory directory
  run: |
    pip install claude-memory-lint
    cml check --format sarif path/to/memory > cml.sarif
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: cml.sarif

Companion: claude-memory-router

This lint pairs with claude-memory-router:

  • The lint enforces write-time quality (aliases, size, freshness).
  • The router consumes that quality at read-time and only injects the most relevant memory files into the prompt.

Garbage-in, garbage-out is real for routers as for any other engine. The lint exists so the router can do its best work.

Output formats

text   default — human-readable, one finding per line + summary
json   machine-readable; convenient for CI gates
sarif  SARIF 2.1.0 — uploadable to GitHub code scanning

Testing

pip install -e .[dev]
pytest -v

Aim for 45+ passing tests covering parser edge cases (no frontmatter / unterminated frontmatter / inline lists / multi-line lists), per-rule positive and negative cases, the corpus rule, and the CLI front-end including JSON / SARIF reporters.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_memory_lint-0.2.1.tar.gz (51.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_memory_lint-0.2.1-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

Details for the file claude_memory_lint-0.2.1.tar.gz.

File metadata

  • Download URL: claude_memory_lint-0.2.1.tar.gz
  • Upload date:
  • Size: 51.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claude_memory_lint-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8f4b9c8c268162ef521341877ed87f7106e6616dd4a44b6506bdd4f5ca28b296
MD5 117d8e7f1daf080aeb0aad96cc159818
BLAKE2b-256 a4baefdf3a04d52e9343a7c09a9fa4320978c506ac95fcd650f87c09b2c59539

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_memory_lint-0.2.1.tar.gz:

Publisher: publish.yml on hinanohart/claude-memory-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claude_memory_lint-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for claude_memory_lint-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 68e522773f49a2263c632b36810835c9b20a9f60980786ca7d070f9a043efd1f
MD5 ab9f0c4b8ad5ca6d77e4d3b5e7dbf44b
BLAKE2b-256 a3b77846a1dc6f81020c0ed901e463b2f795aeded7ca91b193268085173ed172

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_memory_lint-0.2.1-py3-none-any.whl:

Publisher: publish.yml on hinanohart/claude-memory-lint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page