What Issues Does the Claude-Obsidian Lint Workflow Detect?
The lint workflow in claude-obsidian performs deterministic, read-only analysis of Obsidian vaults to detect 11 distinct categories of structural defects—including dead links, ambiguous targets, orphan pages, and missing frontmatter—outputting detailed JSON or Markdown reports.
The claude-obsidian repository (AgriciDaniel/claude-obsidian) provides a comprehensive validation engine for knowledge-base maintenance. Implemented primarily in claude_obsidian/lint_engine.py, the lint workflow systematically identifies link resolution failures, metadata inconsistencies, and configuration problems that compromise vault navigability and integrity.
Link Resolution and Integrity Issues
The workflow validates all internal wiki-links against the vault's actual file structure and naming conventions.
Dead Links
Dead links represent references pointing to non-existent files, headings, or block identifiers. During the resolution phase in claude_obsidian/lint_engine.py, when the resolver finds zero candidate targets for a link and the reference is not present in the allow-list, the issue is recorded in the dead_links category at lines [777‑789]. These entries include the source file, line number, target path, and specific failure reason.
Ambiguous Targets
Ambiguous targets occur when a single wiki-link resolves to multiple possible destinations, such as files sharing identical basenames or aliases. The detection logic populates this category when resolver.resolve(link) returns more than one candidate, as implemented at lines [664‑672]. This prevents editors from accidentally linking to incorrect documents when naming collisions exist.
Duplicate Basenames
The linter identifies duplicate basenames—markdown files sharing the same filename stem outside the intentional _index.md pattern—which can confuse automated link resolution. This check iterates through the basename_groups mapping at lines [290‑308] to flag naming collisions that might cause ambiguous target errors.
Allow-Listed Dangling Links
Links explicitly exempted from dead-link reporting via an allow-list file are tracked separately as allow-listed dangling links. The _is_allowlisted(link, patterns) function evaluates exemption status at lines [779‑789] and [1004‑1009], recording these entries in the allowlisted category for audit purposes rather than treating them as errors.
Content Structure Quality Checks
Beyond link validation, the workflow inspects document metadata and structural completeness.
Orphan Pages
Orphan pages are documents within the wiki/ folder that receive no inbound links from other vault pages, effectively isolating them from the knowledge graph. The linter filters these into the orphans category when a page is absent from the incoming link map, as seen at lines [511‑516].
Missing Frontmatter
The engine enforces standardized metadata by detecting missing frontmatter fields. It compares each page’s frontmatter.fields against REQUIRED_FRONTMATTER_FIELDS—including title, type, status, created, updated, and tags—at lines [560‑566]. Any required field absent from a markdown file generates a report entry specifying the missing keys.
Empty Sections
Empty sections refer to headings that contain no visible content, text, or non-comment code blocks. The _empty_sections(page) function walks heading ranges and validates stripped content at lines [970‑986], flagging structural placeholders that lack substantive information.
Index and Navigation Maintenance
The workflow includes specialized checks for navigation hub integrity.
Stale Index Entries
Index pages (index.md or _index.md) containing dead links or ambiguous targets are flagged as stale index entries, indicating outdated navigation hubs that misdirect users. This detection triggers at lines [674‑678] and [998‑1002] when resolution failures occur specifically on index-designated paths.
System and Configuration Health
The linter validates external dependencies and file accessibility.
Read Errors
Read errors capture I/O failures, permission denials, or Unicode decoding errors encountered while scanning vault files. The workflow collects these filesystem-level exceptions in read_errors during markdown file opening operations at lines [531‑537], ensuring visibility into access problems without crashing the analysis.
Configuration Errors
When the lint allow-list fails to load due to invalid JSON syntax, unreadable file permissions, or directory misconfiguration, the workflow generates configuration errors. The _load_allowlist function produces these diagnostics at lines [607‑629], distinguishing between file-not-found scenarios and parse failures.
Provenance Errors
The linter validates vault provenance ledgers—tracking content sources and claims—for structural integrity. Provenance errors encompass missing source ledgers, malformed entries, and validation failures against the schema defined in claude_obsidian/ledgers.py. These are gathered via _provenance_errors at lines [823‑848], utilizing strict JSON loading utilities from claude_obsidian/json_utils.py and low-level file reading from claude_obsidian/transaction.py.
Running the Lint Workflow
Execute the linter from the command line to analyze a vault directory:
# Generate a JSON report for programmatic processing
python -m claude_obsidian.lint_engine /path/to/vault --format json > report.json
# Generate a human-readable Markdown report
python -m claude_obsidian.lint_engine /path/to/vault --format markdown > report.md
For programmatic integration, import the core functions directly:
from claude_obsidian.lint_engine import lint_vault, render_markdown
# Analyze vault structure
report = lint_vault("path/to/vault")
# Access specific issue categories programmatically
dead_links = report["dead_links"]
for entry in dead_links:
print(f"{entry['source']}:{entry['line']} → {entry['target']} ({entry['reason']})")
# Render formatted output
print(render_markdown(report))
All findings are accumulated into a deterministic categories dictionary at lines [1086‑1098] of the engine, then rendered by render_markdown at lines [1137‑1245].
Summary
- The lint workflow claude-obsidian detects 11 distinct issue categories spanning link integrity, content structure, and system configuration.
- Core link validation—including dead links, ambiguous targets, and duplicate basenames—resolves in
claude_obsidian/lint_engine.pywithin the 290‑789 line range. - Content quality checks for orphans, frontmatter, and empty sections operate between lines 511‑986.
- System health monitoring for configuration and provenance errors utilizes auxiliary modules
json_utils.py,ledgers.py, andtransaction.py. - Results aggregate into a structured
categoriesobject and render viarender_markdownfor both JSON and Markdown output formats.
Frequently Asked Questions
What file contains the core lint workflow implementation?
The primary implementation resides in claude_obsidian/lint_engine.py, which orchestrates vault parsing, link resolution, issue detection, and report generation. Supporting utilities for strict JSON parsing and ledger validation live in claude_obsidian/json_utils.py and claude_obsidian/ledgers.py, respectively, while claude_obsidian/transaction.py provides low-level file reading capabilities.
How does the linter distinguish between dead links and allow-listed dangling links?
Before recording a dead link, the workflow invokes _is_allowlisted(link, patterns) at lines [779‑789] to check the exemption configuration. If the link matches an allow-list pattern, it is routed to the allowlisted category at lines [1004‑1009] rather than being reported as a resolution error, enabling intentional dangling references for external or future content.
What output formats does the Claude-Obsidian lint workflow support?
The workflow generates deterministic reports in both JSON and Markdown formats. The render_markdown function (lines [1137‑1245]) produces human-readable output with categorized sections, while the raw categories dictionary (lines [1086‑1098]) provides structured JSON suitable for CI/CD pipelines and programmatic processing.
Which pages are classified as orphans by the lint workflow?
Pages located within the wiki/ folder that have zero inbound links from other vault documents are classified as orphans. The detection logic checks the incoming link map at lines [511‑516]; if a page does not appear as a target in any other document's links, it is flagged as isolated content.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →