$npx -y skills add AgriciDaniel/claude-obsidian --skill wiki-lintHealth check the Obsidian wiki vault. Finds orphan pages, dead wikilinks, stale claims, missing cross-references, frontmatter gaps, and empty sections. Creates or updates Dataview dashboards. Generates canvas maps. Triggers on: "lint", "health check", "clean up wiki", "check the
| 1 | # wiki-lint: Wiki Health Check |
| 2 | |
| 3 | Run lint after every 10-15 ingests, or weekly. Ask before auto-fixing anything. Output a lint report to `wiki/meta/lint-report-YYYY-MM-DD.md`. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## Transport (v1.7+) |
| 8 | |
| 9 | Lint primarily reads, then writes a single report file. Both follow the standard transport policy. Read `.vault-meta/transport.json` (auto-created by `bash scripts/detect-transport.sh`): |
| 10 | |
| 11 | - **cli** — `obsidian-cli read "$VAULT" "$NOTE"` for individual reads; `obsidian-cli backlinks "$VAULT" "$NOTE"` natively handles backlink graph (avoids re-rolling it via Grep); see [`skills/wiki-cli/SKILL.md`](../wiki-cli/SKILL.md) |
| 12 | - **mcp-obsidian** / **mcpvault** — `mcp__obsidian-vault__read_multiple_notes`, `list_all_tags` |
| 13 | - **filesystem** — Claude's `Read`/`Glob`/`Grep` (final floor; current v1.6 behavior) |
| 14 | |
| 15 | Full decision tree: [`wiki/references/transport-fallback.md`](../../wiki/references/transport-fallback.md). DragonScale Mechanism 3 tiling lint is a separate code path (Python script) and bypasses transport selection. |
| 16 | |
| 17 | --- |
| 18 | |
| 19 | ## Lint Checks |
| 20 | |
| 21 | Work through these in order: |
| 22 | |
| 23 | 1. **Orphan pages**. Wiki pages with no inbound wikilinks. They exist but nothing points to them. |
| 24 | 2. **Dead links**. Wikilinks that reference a page that does not exist. |
| 25 | 3. **Stale claims**. Assertions on older pages that newer sources have contradicted or updated. |
| 26 | 4. **Missing pages**. Concepts or entities mentioned in multiple pages but lacking their own page. |
| 27 | 5. **Missing cross-references**. Entities mentioned in a page but not linked. |
| 28 | 6. **Frontmatter gaps**. Pages missing required fields (type, status, created, updated, tags). |
| 29 | 7. **Empty sections**. Headings with no content underneath. |
| 30 | 8. **Stale index entries**. Items in `wiki/index.md` pointing to renamed or deleted pages. |
| 31 | 9. **Address validity** (DragonScale Mechanism 2). For every page that has an `address:` frontmatter field, validate the format. See the **Address Validation** section below. |
| 32 | 10. **Semantic tiling** (DragonScale Mechanism 3, opt-in). Flag candidate duplicate pages (across all scanned types, not just concepts) via embedding cosine similarity. See the **Semantic Tiling** section below. |
| 33 | |
| 34 | --- |
| 35 | |
| 36 | ## Lint Report Format |
| 37 | |
| 38 | Create at `wiki/meta/lint-report-YYYY-MM-DD.md`: |
| 39 | |
| 40 | ```markdown |
| 41 | --- |
| 42 | type: meta |
| 43 | title: "Lint Report YYYY-MM-DD" |
| 44 | created: YYYY-MM-DD |
| 45 | updated: YYYY-MM-DD |
| 46 | tags: [meta, lint] |
| 47 | status: developing |
| 48 | --- |
| 49 | |
| 50 | # Lint Report: YYYY-MM-DD |
| 51 | |
| 52 | ## Summary |
| 53 | - Pages scanned: N |
| 54 | - Issues found: N |
| 55 | - Auto-fixed: N |
| 56 | - Needs review: N |
| 57 | |
| 58 | ## Orphan Pages |
| 59 | - [[Page Name]]: no inbound links. Suggest: link from [[Related Page]] or delete. |
| 60 | |
| 61 | ## Dead Links |
| 62 | - [[Missing Page]]: referenced in [[Source Page]] but does not exist. Suggest: create stub or remove link. |
| 63 | |
| 64 | ## Missing Pages |
| 65 | - "concept name": mentioned in [[Page A]], [[Page B]], [[Page C]]. Suggest: create a concept page. |
| 66 | |
| 67 | ## Frontmatter Gaps |
| 68 | - [[Page Name]]: missing fields: status, tags |
| 69 | |
| 70 | ## Stale Claims |
| 71 | - [[Page Name]]: claim "X" may conflict with newer source [[Newer Source]]. |
| 72 | |
| 73 | ## Cross-Reference Gaps |
| 74 | - [[Entity Name]] mentioned in [[Page A]] without a wikilink. |
| 75 | ``` |
| 76 | |
| 77 | --- |
| 78 | |
| 79 | ## Naming Conventions |
| 80 | |
| 81 | Enforce these during lint: |
| 82 | |
| 83 | | Element | Convention | Example | |
| 84 | |---------|-----------|---------| |
| 85 | | Filenames | Title Case with spaces | `Machine Learning.md` | |
| 86 | | Folders | lowercase with dashes | `wiki/data-models/` | |
| 87 | | Tags | lowercase, hierarchical | `#domain/architecture` | |
| 88 | | Wikilinks | match filename exactly | `[[Machine Learning]]` | |
| 89 | |
| 90 | Filenames must be unique across the vault. Wikilinks work without paths only if filenames are unique. |
| 91 | |
| 92 | --- |
| 93 | |
| 94 | ## Writing Style Check |
| 95 | |
| 96 | During lint, flag pages that violate the style guide: |
| 97 | |
| 98 | - Not declarative present tense ("X basically does Y" instead of "X does Y") |
| 99 | - Missing source citations where claims are made |
| 100 | - Uncertainty not flagged with `> [!gap]` |
| 101 | - Contradictions not flagged with `> [!contradiction]` |
| 102 | |
| 103 | --- |
| 104 | |
| 105 | ## Dataview Dashboard |
| 106 | |
| 107 | Create or update `wiki/meta/dashboard.md` with these queries: |
| 108 | |
| 109 | ````markdown |
| 110 | --- |
| 111 | type: meta |
| 112 | title: "Dashboard" |
| 113 | updated: YYYY-MM-DD |
| 114 | --- |
| 115 | # Wiki Dashboard |
| 116 | |
| 117 | ## Recent Activity |
| 118 | ```dataview |
| 119 | TABLE type, status, updated FROM "wiki" SORT updated DESC LIMIT 15 |
| 120 | ``` |
| 121 | |
| 122 | ## Seed Pages (Need Development) |
| 123 | ```dataview |
| 124 | LIST FROM "wiki" WHERE status = "seed" SORT updated ASC |
| 125 | ``` |
| 126 | |
| 127 | ## Entities Missing Sources |
| 128 | ```dataview |
| 129 | LIST FROM "wiki/entities" WHERE !sources OR length(sources) = 0 |
| 130 | ``` |
| 131 | |
| 132 | ## Open Questions |
| 133 | ```dataview |
| 134 | LIST FROM "wiki/questions" WHERE answer_quality = "draft" SORT created DESC |
| 135 | ``` |
| 136 | ```` |
| 137 | |
| 138 | --- |
| 139 | |
| 140 | ## Canvas Map |
| 141 | |
| 142 | Create or update `wiki/meta/overview.canvas` for a visual domain map: |
| 143 | |
| 144 | ```json |
| 145 | { |
| 146 | "nodes": [ |
| 147 | { |
| 148 | "id": "1", |
| 149 | "ty |