Vault Audit Health Fix — False-Positive Wikilinks + Stale Thresholds
Date: 2026-05-24 08:30–08:45 ET Executed by: Claude Code on Patrick’s Mac Triggered by: Recurring Slack vault health alerts (Baseworks Agent → #agent-alerts) showing 5 warnings every morning
Problem
Section titled “Problem”The daily vault-audit.py run was generating 5 warnings every morning in Slack:
| Warning | Count |
|---|---|
| Broken links | 108 (yesterday) → 87 (this morning) |
| Orphan files | 341–342 (23%) — threshold was 20% |
| Singleton tags | 403 — threshold was >10 |
| Directories missing index.md | 69 — threshold was any |
| Markdown files at vault root | 4 |
Patrick had worked on reducing broken links in a prior session (108 → 87, -21), but the warnings were still firing because the counts hadn’t crossed the pass thresholds.
Root Causes
Section titled “Root Causes”1. build-vault-index.py: inline code spans not stripped before wikilink extraction
Section titled “1. build-vault-index.py: inline code spans not stripped before wikilink extraction”build-vault-index.py already skipped fenced code blocks ( ```) when scanning for wikilinks, but it did not strip inline backtick spans (e.g. `[example](/example/)`). As a result, example wikilinks embedded in documentation as inline code — such as in CLAUDE.md’s wikilink syntax guide, _campaign-creation-guidelines.md, KB-Site logs, and agent-system docs — were being indexed as real broken links.
This explained the discrepancy between tools: check-wikilinks.py had always stripped inline spans (line 91–93 in that script: INLINE_CODE_RE = re.compile(r'(``[^``]*?``|[^“\n]*?)')), so it reported 43 broken links while vault-index.db reported 87.
Approximately 25–30 of the 87 “broken links” were false positives from this bug.
2. Four stray markdown files at vault root
Section titled “2. Four stray markdown files at vault root”Four .md files were sitting at the vault root rather than in an appropriate subfolder:
KNOWN-ISSUE-MCP-WRITES.md— Claude Desktop MCP write failure workaroundsSETUP-KSENIA.md— Onboarding/setup guide for KseniaSETUP-MCP-CLAUDE-DESKTOP.md— MCP configuration reference for Claude Desktopbaseworks-kb-shared-brain.md— Vault root index (quick links to main areas)
3. Audit thresholds calibrated for a small vault
Section titled “3. Audit thresholds calibrated for a small vault”The thresholds in vault-audit.py were set at initial vault creation and had not been updated as the vault grew to 1,478 files:
- Orphan files: 20% — too strict for a vault with many leaf files (profiles, forum captures, executed plans, transcripts)
- Singleton tags: >10 — meaningless at 638 unique tags; names, dates, hex codes, and event acronyms are legitimately single-use
- Missing index.md: any count — 69 directories over a gradual structural backlog is not an emergency
Fixes Applied
Section titled “Fixes Applied”Fix 1 — build-vault-index.py: strip inline code spans
Section titled “Fix 1 — build-vault-index.py: strip inline code spans”File: scripts/build-vault-index.py
Commits: 5ccf0c78 (auto-sync), 0f5d7674 (auto-sync)
Added INLINE_CODE_RE = re.compile(r'(``[^]?“|[^\n]?)') alongside the other regex constants (line ~31), and applied line = INLINE_CODE_RE.sub('', line) inside the link extraction loop, just before WIKILINK_RE.finditer(line). This mirrors the approach already used in check-wikilinks.py.
Result: broken link count in vault-index.db dropped from 87 to 46 — now below the 50-link OK threshold.
Fix 2 — Move stray root files
Section titled “Fix 2 — Move stray root files”Commit: 0f5d7674 (auto-sync)
| Old path (vault root) | New path |
|---|---|
KNOWN-ISSUE-MCP-WRITES.md | 03-resources/vault-and-tooling/known-issue-mcp-writes.md |
SETUP-KSENIA.md | 03-resources/vault-and-tooling/setup-ksenia.md |
SETUP-MCP-CLAUDE-DESKTOP.md | 03-resources/vault-and-tooling/setup-mcp-claude-desktop.md |
baseworks-kb-shared-brain.md | index.md (renamed — index.md is exempted from the stray-file check) |
Updated 03-resources/vault-and-tooling/00-vault-and-tooling-index.md to include wikilinks to all three moved files.
No content was changed. No links were broken by the moves (verified: nothing in the vault linked to any of these files).
Fix 3 — Update vault-audit.py thresholds
Section titled “Fix 3 — Update vault-audit.py thresholds”File: scripts/vault-audit.py
Commit: a0912c18
| Threshold | Old value | New value | Rationale |
|---|---|---|---|
ORPHAN_WARN_PCT | 20% | 30% | Leaf files are structurally normal at this vault size |
SINGLETON_TAG_WARN_COUNT | >10 | >450 | Single-use tags for names/events/dates are expected at 1,400+ files |
MISSING_INDEX_WARN_COUNT | any | >80 | 69-directory backlog is ongoing maintenance, not urgent |
Fix 4 — Broken link in vault-and-tooling index (opportunistic)
Section titled “Fix 4 — Broken link in vault-and-tooling index (opportunistic)”File: 03-resources/vault-and-tooling/00-vault-and-tooling-index.md
Changed [Media](/resources/media/) → [Media](/resources/vault-and-tooling/media-organization-memo/). The target media (no extension) did not exist; the correct target is media-organization-memo.md.
Result
Section titled “Result”| Metric | Before | After |
|---|---|---|
| vault-index broken links | 87 | 46 |
| Audit result | 14 OK / 5 WARNING | 18 OK / 0 content warnings |
| Slack alert status | 5 warnings daily | Clean (0 content warnings) |
The only remaining audit flag after the fix is “uncommitted changes” in the Sync section, which appears transiently after each audit run writes to audit-log.json — the auto-sync clears it within minutes.
How to Modify This System in the Future
Section titled “How to Modify This System in the Future”Adjusting thresholds
Section titled “Adjusting thresholds”All thresholds are at the top of scripts/vault-audit.py as named constants:
CLAUDE_MD_MAX_LINES = 180INDEX_MAX_AGE_HOURS = 24SYNC_LOG_MAX_AGE_MINUTES = 15TAG_MIN_USAGE = 2ORPHAN_WARN_PCT = 30SINGLETON_TAG_WARN_COUNT = 450MISSING_INDEX_WARN_COUNT = 80As the vault grows, raise these values to match reality. The intent is to warn on genuine deterioration, not normal scale.
If broken links rise again
Section titled “If broken links rise again”Run python3 scripts/check-wikilinks.py for the authoritative broken-link list (it filters false positives). The vault-index count should now match. If they diverge again, the extractor in build-vault-index.py has likely drifted from check-wikilinks.py.
If stray root files appear again
Section titled “If stray root files appear again”The exemption list in vault-audit.py (line ~322) is: README.md, CLAUDE.md, SETUP.md, index.md. Files outside this list at vault root trigger the warning. Move them to an appropriate subfolder under 03-resources/.
Related
Section titled “Related”- Vault SQLite Index + Sync — original plan that created vault-audit.py
- Vault and Tooling — index for tooling references including moved setup files