lore doctor
Diagnose and repair your documentation corpus.
Synopsis
lore doctor [flags]
What Does This Do?
lore doctor runs a health checkup on your documentation corpus. It scans for problems — corrupted files, broken references, outdated caches — and fixes most of them automatically.
Analogy: Just as a doctor checks your vitals and prescribes treatment,
lore doctorassesses corpus health and prescribes--fix.
Real World Scenario
After merging 3 feature branches, something feels off —
lore showreturns stale results. Time for a checkup:lore doctor # ✗ stale-index (out of sync) lore doctor --fix # ✓ Fixed: rebuilt indexLike running
npm auditorgo vet— a habit that prevents surprises.

Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--fix |
bool | false |
Automatically repair fixable issues |
--config |
bool | false |
Only check .lorerc configuration (skip corpus) |
--rebuild-store |
bool | false |
Reconstruct store.db from scratch |
--prune |
bool | false |
Run garbage collection on generated artifacts (polish backups, polish.log, corrupt-state quarantine). Mutually exclusive with --fix, --rebuild-store, --config. |
--dry-run |
bool | false |
With --prune: report what would be removed without touching the filesystem |
--quiet |
bool | false |
Output only the issue count (or tab-separated feature\tremoved\tkept\tbytes with --prune) |
Diagnostic Checks
| Check | What it detects | Auto-fixable? |
|---|---|---|
| orphan-tmp | Leftover .tmp files from interrupted writes |
✅ Yes — deletes them |
| stale-index | Index file doesn't match actual documents | ✅ Yes — rebuilds index |
| stale-cache | Angela review cache is outdated | ✅ Yes — clears cache |
| broken-ref | A document references another that doesn't exist | ❌ No — manual fix |
| invalid-frontmatter | YAML metadata can't be parsed | ⚠ Depends on subkind — see below |
| config | Typos or invalid values in .lorerc |
❌ No — manual fix |
Invalid frontmatter — subkinds
For invalid-frontmatter issues, doctor distinguishes two sub-cases and treats them differently:
| Subkind | What it detects | Auto-fixable? |
|---|---|---|
missing |
No --- delimiter at all |
✅ Yes — synthesizes a safe frontmatter block (type inferred from filename, status: draft, today's date) |
malformed |
--- delimiter present but YAML is unparseable (unclosed quote, broken indent, duplicate keys, BOM + cassé, CRLF + cassé, etc.) |
❌ No — the authentic content may still be recoverable, auto-fix would destroy it |
On malformed, doctor emits a suggestion block so you know what to do:
✗ invalid-frontmatter decision-auth.md (malformed: YAML parse error: ...)
Suggested actions:
- Restore from a polish backup:
lore angela polish --restore 'decision-auth.md'
- Edit the file manually to repair the YAML block.
The --restore hint appears only when a polish-backup for the filename actually exists; filenames containing shell metacharacters (spaces, ;, backticks) are single-quoted so copy-paste into a shell is injection-safe.
This protection is invariant I31 — doctor never rewrites a frontmatter block when a --- delimiter is present. It guards against a single manual YAML typo destroying authentic content.
Output
lore doctor
Docs Check:
✓ orphan-tmp (none found)
✗ stale-index .lore/docs/index.md (last updated 2026-01-01)
✓ broken-ref (none found)
✓ stale-cache (none found)
✓ invalid-frontmatter (none found)
Config Check:
✓ .lorerc (valid)
✓ .lorerc.local (valid, mode 0600)
1 issue found. Run: lore doctor --fix
lore doctor --fix
✓ Fixed: stale-index (rebuilt from 12 documents)
All issues resolved.
Config Validation (--config)
Catches common .lorerc mistakes:
lore doctor --config
Config Check:
✗ .lorerc line 3: unknown key "ai.providr"
→ Did you mean "ai.provider"? (Levenshtein distance: 1)
✗ .lorerc line 7: "hooks.post_commit" expects boolean, got "yes"
→ Use true/false (YAML boolean), not "yes"/"no"
2 issues found.
How it suggests corrections: Lore uses Levenshtein distance — a measure of how similar two words are. If you type
providr, it knows you probably meantprovider(1 character away).
Prune Generated Artifacts
lore doctor --prune runs garbage collection across every family of growing artifacts Lore produces — bounded disk footprint in one command.
| Family | Pattern | Policy |
|---|---|---|
polish-backups |
polish-backups/*.bak |
Delete backups older than angela.polish.backup.retention_days (default 30) |
polish-log |
polish.log |
Two-pass: drop entries older than angela.polish.log.retention_days (default 30), then trim oldest until under angela.polish.log.max_size_mb (default 10 MB) |
corrupt-quarantine |
*.corrupt-<stamp> |
Delete quarantined state files older than angela.gc.corrupt_quarantine.retention_days (default 14). Symlinks and non-regular files are skipped. |
# Preview what would be removed — no files touched
lore doctor --prune --dry-run
Pruning generated artifacts:
✓ polish-backups removed 12 / kept 3 (14.2 KB)
✓ polish-log removed 87 / kept 412 (68.1 KB)
✓ corrupt-quarantine removed 2 / kept 0 (2.4 KB)
84.7 KB total
(dry-run: no files changed)
# Actually prune
lore doctor --prune
# Same layout, no (dry-run) footer
# Machine output for CI
lore doctor --prune --quiet
# polish-backups<TAB>12<TAB>3<TAB>14540
# polish-log<TAB>87<TAB>412<TAB>69734
# corrupt-quarantine<TAB>2<TAB>0<TAB>2457
Invariant I32 ensures every file family Lore can produce has a registered Pruner. A future growing artifact added without a matching pruner fails the I32 regression test — so --prune is future-proof by construction.
Concurrency-safe
The polish-log pruner acquires the same advisory flock as the writer (AppendLogEntry), and re-stats size + mtime just before the rewrite. If a writer bypasses the lock and appends during the prune, the drift is detected and the prune aborts without data loss.
Rebuild Store (--rebuild-store)
The store.db file is a SQLite database that indexes your documents for fast search. It is always reconstructible from your Markdown files — they are the source of truth.
# If store.db gets corrupted or you want a fresh start
lore doctor --rebuild-store
# → Rebuilt store.db from 12 documents and 47 commits
Safe to run anytime. The store is a cache, not a source of truth. Rebuilding it loses nothing.
Process Flow
graph TD
A[lore doctor] --> B{Mode?}
B -->|--config| C[Validate .lorerc + .lorerc.local]
B -->|--prune| P[Run all registered Pruners]
B -->|default| D[Run all diagnostic checks]
D --> E{Issues found?}
E -->|No| F[✓ All good]
E -->|Yes| G{--fix flag?}
G -->|Yes| H[Auto-fix what's safe]
H --> I[Report fixed + manual items]
G -->|No| J[Report issues + suggest --fix]
C --> K[Report config issues with suggestions]
P --> Q{--dry-run?}
Q -->|Yes| R[Report would-remove counts + bytes]
Q -->|No| S[Delete + report actual counts]
Examples
# Full checkup
lore doctor
# Fix everything fixable
lore doctor --fix
# Just check config
lore doctor --config
# Preview prune (no filesystem change)
lore doctor --prune --dry-run
# Actually prune growing artifacts
lore doctor --prune
# Nuclear option: rebuild everything
lore doctor --fix --rebuild-store
# CI gate: fail if unhealthy
[ $(lore doctor --quiet) -eq 0 ] || exit 1
When to Run
| Situation | Run |
|---|---|
| After pulling from remote | lore doctor — other people's changes may cause inconsistencies |
| After deleting documents | lore doctor — check for broken references |
After editing .lorerc |
lore doctor --config — catch typos |
| After migration/upgrade | lore doctor --fix --rebuild-store — full reset |
| Something feels wrong | lore doctor --fix — let Lore figure it out |
.lore/ disk footprint growing |
lore doctor --prune — garbage-collect backups, logs, quarantine |
| Before committing a large polish batch | lore doctor --prune --dry-run — preview cleanup |
Tips & Tricks
- Make it a habit: Run
lore doctorweekly, like you'd runnpm auditorgo vet. - CI integration:
lore doctor --quietreturns the issue count — perfect for CI gates. - After team merges: Pull →
lore doctor --fix→ done. Keeps everyone in sync. - Config typos: The Levenshtein suggestions catch 90% of typos. Trust them.
Exit Codes
| Code | Meaning |
|---|---|
0 |
No issues (or all fixed with --fix) |
1 |
Issues found (need --fix or manual intervention) |
4 |
Configuration error |
Common Questions
"Is --rebuild-store safe?"
Yes. store.db is a cache reconstructed from your Markdown files. Rebuilding loses nothing — it re-indexes everything from the source of truth.
"Doctor says 'manual fix required'"
Broken references and malformed frontmatter cannot be auto-fixed because Lore cannot infer the correct value without risking loss of authentic content (invariant I31). Open the flagged file, fix it manually — or run lore angela polish --restore <file> if a backup exists — then re-run lore doctor.
"What does --prune actually delete?"
Only three families: polish-backups/*.bak (polish atomic backups), polish.log entries older than retention (or over the size cap), and *.corrupt-<ts> quarantined state files. Symlinks and non-regular files are skipped. Your source markdown, .lorerc, and store.db are never touched by --prune.
"Should I run doctor after every merge?"
Good habit. lore doctor --fix takes under a second and catches stale indexes caused by teammates' changes.
See Also
- lore status — Quick health overview
- Configuration — Fix config issues