Validate and refactor Markdown documentation against source code using heuristics + LLM
Project description
docval
AI Cost Tracking
- ๐ค LLM usage: $0.1500 (1 commits)
- ๐ค Human dev: ~$100 (1.0h @ $100/h, 30min dedup)
Generated on 2026-04-13 using openrouter/qwen/qwen3-coder-next
Validate and refactor Markdown documentation against source code โ detect outdated, orphaned, duplicate, and invalid docs using heuristics + optional LLM.
How it works
docs/ โโโ chunk by heading โโโ heuristic checks โโโ cross-ref with code โโโ (optional) LLM โโโ report/fix
Three validation layers, each progressively deeper:
- Heuristic validator (fast, free) โ empty sections, broken internal links, TODO/FIXME markers, duplicate detection via
difflib, stale version references, archive path detection, explicit deprecation markers - Cross-reference validator (fast, free) โ checks that backtick-quoted symbols (
ClassName,function_name), import paths in code blocks, and CLI commands actually exist in the project source - LLM validator (optional, paid) โ semantic validation via
litellmfor chunks that heuristics couldn't resolve with high confidence
Installation
pip install docval
With LLM support:
pip install docval[llm]
From source:
git clone https://github.com/wronai/docval.git
cd docval
pip install -e ".[dev]"
CLI Usage
Scan and report issues
docval scan docs/
docval scan docs/ --project /path/to/repo -v
docval scan docs/ -o report.md
docval scan docs/ -o report.json
Fix documentation (dry-run by default)
docval fix docs/ # preview changes
docval fix docs/ --no-dry-run # apply fixes
docval fix docs/ --no-dry-run --llm # with LLM validation
Generate a patch file
docval patch docs/ -o fixes.txt
docval patch docs/ --llm --model gpt-4o -o fixes.txt
View documentation statistics
docval stats docs/
LLM validation
export OPENAI_API_KEY=sk-...
docval scan docs/ --llm --model gpt-4o-mini
docval scan docs/ --llm --model anthropic/claude-sonnet-4-20250514
docval scan docs/ --llm --model groq/llama-3.3-70b-versatile
Any model supported by litellm works.
Python API
from pathlib import Path
from docval.pipeline import scan
from docval.reporters import ConsoleReporter, MarkdownReporter
# Run validation
result = scan(
docs_dir=Path("docs/"),
project_root=Path("."),
use_llm=False,
)
# Print to console
ConsoleReporter(verbose=True).report(result)
# Write markdown report
MarkdownReporter().report(result, Path("validation-report.md"))
Using individual validators
from docval.chunker import chunk_directory
from docval.context import build_context
from docval.validators import HeuristicValidator, CrossRefValidator
# Chunk docs
doc_files = chunk_directory(Path("docs/"))
# Build project context
ctx = build_context(Path("."))
# Run heuristics
heuristic = HeuristicValidator(ctx=ctx)
heuristic.validate(doc_files)
# Cross-reference check
crossref = CrossRefValidator(ctx=ctx)
crossref.validate(doc_files)
# Inspect results
for f in doc_files:
for chunk in f.chunks:
if chunk.issues:
print(f"{f.relative_path}:{chunk.line_start} [{chunk.status.value}] {chunk.heading}")
for issue in chunk.issues:
print(f" {issue.severity.value}: {issue.message}")
What it detects
| Check | Layer | Example |
|---|---|---|
| Empty sections | Heuristic | Heading with no body text |
| Broken internal links | Heuristic | [guide](./deleted-file.md) |
| Deprecated markers | Heuristic | DEPRECATED, OBSOLETE, DO NOT USE |
| Archive path | Heuristic | Files in docs/archive/ directories |
| Stale versions | Heuristic | References to v1.x when project is v3.x |
| Duplicates | Heuristic | >80% similar content across files |
| TODO/FIXME | Heuristic | Unfinished documentation markers |
| Orphaned code refs | CrossRef | `NonExistentClass` in backticks |
| Broken imports | CrossRef | from mypackage.deleted import X in code blocks |
| Semantic accuracy | LLM | Content that doesn't match actual project behavior |
Architecture
src/docval/
โโโ cli.py # Click CLI: scan, fix, patch, stats
โโโ pipeline.py # Orchestrates: discover โ chunk โ validate โ report
โโโ models.py # Data models: DocChunk, DocFile, ValidationResult
โโโ chunker.py # MD โ heading-based semantic chunks
โโโ context.py # Build project context (AST, git, .toon files)
โโโ validators/
โ โโโ heuristic.py # Rule-based checks (free, fast)
โ โโโ crossref.py # Code โ docs cross-reference
โ โโโ llm_validator.py # Semantic validation via litellm
โโโ actions/
โ โโโ executor.py # Apply fixes: delete, archive, patch
โโโ reporters/
โโโ console.py # Rich CLI output
โโโ markdown_report.py # .md report
โโโ json_report.py # .json for CI/CD
Integration with .toon files
docval understands .toon.yaml files from the code2llm ecosystem. When present, it extracts module names, class names, and exported functions for cross-referencing, giving more accurate orphaned-reference detection.
License
Licensed under Apache-2.0.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docval-0.1.1.tar.gz.
File metadata
- Download URL: docval-0.1.1.tar.gz
- Upload date:
- Size: 34.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3026aa5aac6b524f6cd9101ed9597121d09c9621a691dce3294556ac8b2494bd
|
|
| MD5 |
21229ca76ac6c4295aaaa6102059c14a
|
|
| BLAKE2b-256 |
368dffc4b9f087f939e12af03ce52ebd6d5b19ac5a2c02f90e1803917aafc000
|
File details
Details for the file docval-0.1.1-py3-none-any.whl.
File metadata
- Download URL: docval-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dff7bb2579127fd0d6fd1591a4085603bf678a9fcbac15dc34c1fff6d78ae6a8
|
|
| MD5 |
1d9d93ac65c3c11174d2cc8933e87491
|
|
| BLAKE2b-256 |
38999e86f780a2483e27b788fdf9013e2de6075ec4160825e24755f2d3f34315
|