vaultlint
Consistency and staleness linter for Markdown vaults used as AI agent memory — Obsidian vaults, CLAUDE.md/AGENTS.md setups, memory banks, agent knowledge bases.
Agents read these files and act on what they say. A duplicate "next action" marker, a broken cross-reference, or a status line that's quietly gone stale can make an agent act on the wrong thing — silently. vaultlint catches that class of bug before it does.
Why this exists
Existing tools cover adjacent ground but not this gap:
stalebrainandAgentLinteraudit a single instruction file (CLAUDE.md/AGENTS.md) against the repo.- Generic Obsidian checkers (broken-link plugins, vault inspectors) target human PKM use, not the action-marker/state-consistency issues that specifically break an agent reading the vault.
vaultlint targets multi-file vaults with a history of decisions (the Obsidian/JARVIS pattern), checking for the exact class of bug that made this project necessary in the first place — see Proof it works below.
Install
pip install vaultlint
(Not yet published — see status note at the bottom of this README.)
Usage
vaultlint /path/to/your/vault
vaultlint report — 75 files scanned, 40 findings
BROKEN_LINK: 37
DUPLICATE_ACTION_MARKER: 2
STALE_STATUS_CANDIDATE: 1
[WARNING] BROKEN_LINK — 03 - Automato/Opportunities/OPP-002-Autonomous-Digital-Business-Scan.md:12
reference to 'OPPORTUNITY_HUNTER.md' does not resolve to an existing file in the vault
...
Options:
vaultlint /path/to/vault --json # machine-readable output
vaultlint /path/to/vault --stale-threshold-days 14 # tune staleness window (default: 30)
vaultlint /path/to/vault --fail-on error # exit 1 if any error-level finding exists (CI-friendly)
Or without installing, straight from a checkout:
python3 -m vaultlint /path/to/vault
What it checks (v0.1 — 3 rules, zero dependencies, fully static)
- BROKEN_LINK — a Markdown
[text](path.md)link or a backtick`path.md`reference that doesn't resolve to a real file in the vault. - DUPLICATE_ACTION_MARKER — a single file contains more than one "next action" marker (e.g.
## Next Action/NEXT ACTION:). An agent reading the file may act on the wrong one. - STALE_STATUS_CANDIDATE — a
Status: ...line reads as in-progress/pending in a file that hasn't been touched in N days. This is a heuristic (file mtime + keyword match), not a certainty — always flagged asinfo, meant for human review, not auto-action.
No LLM calls. No writes to your vault — read-only, always.
Proof it works
Run read-only against the real, actively-growing JARVIS Obsidian vault this tool was built inside of: 40 real findings across 75 files as of the latest run (up from 18/59 a few hours earlier in this same project's history — the count grows naturally as the vault grows, which is itself evidence the tool stays useful over time, not a regression). The bulk are genuinely broken cross-references left behind after renames/reorganizations and short-name backtick references across subfolders (the documented v0.1 limitation below — some of these are true positives, some are the known false-positive class), plus 2 files that accumulated a duplicate Next Action marker — the exact failure mode that motivated this tool, since it happened for real, more than once, in this same project's history. Full raw output: dogfood-report.json.
What v0.1 deliberately does NOT do
- No LLM-based semantic staleness judgment — only mtime + keyword heuristics. Cheaper, faster, more predictable. A v2 semantic mode is a possible future addition, not a v0.1 promise.
- Doesn't resolve short/ambiguous filename references (e.g. a backtick reference to
`SCOPE.md`when it lives in a subfolder) — known limitation, see dogfood report. - No git integration — uses file mtime as a universal proxy, since not every vault is a git repo.
- No auto-fix.
vaultlintonly reports; it never edits your vault.
License
MIT — see LICENSE.
Status
v0.1.0, locally built and tested (7/7 unit tests, dogfood-verified against a real 59-file vault). Not yet published to PyPI or GitHub — this repository/package is staged for release, pending publication approval.
Metadata
Release files for vaultlint 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vaultlint-0.1.0.tar.gz | 10.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vaultlint-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.3 kB
Release files / vaultlint-0.1.0.tar.gz
| Download URL | vaultlint-0.1.0.tar.gz |
|---|---|
| Size | 10.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
90dc30270aaa3e25c49ad0b6f49dabc79046b8139f7f192b085c6456dd927328
|
|
BLAKE2b-256 checksum How to use checksums |
b96489b22987416a2eb37a03f6f5132320c26ce99ec4139a4cdfa669e23c4f8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / vaultlint-0.1.0-py3-none-any.whl
| Download URL | vaultlint-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c6728e4998ddbf2446f9043e45fba669d76c7478c3bdf4ec38d2feb9f4b2a9b
|
|
BLAKE2b-256 checksum How to use checksums |
78ffa9fab37f3b13ab9daafaca5cea104cfd132835819b6b6381cd13ecf8d3dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|