Skip to main content

Validate and refactor Markdown documentation against source code using heuristics + LLM

Project description

docval

Python License: Apache-2.0 Tests

AI Cost Tracking

PyPI Version Python License AI Cost Human Time Model

  • ๐Ÿค– 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.

docval_architecture.svg

How it works

docs/  โ”€โ”€โ†’  chunk by heading  โ”€โ”€โ†’  heuristic checks  โ”€โ”€โ†’  cross-ref with code  โ”€โ”€โ†’  (optional) LLM  โ”€โ”€โ†’  report/fix

Three validation layers, each progressively deeper:

  1. 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
  2. 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
  3. LLM validator (optional, paid) โ€” semantic validation via litellm for 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

docval-0.1.1.tar.gz (34.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

docval-0.1.1-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

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

Hashes for docval-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3026aa5aac6b524f6cd9101ed9597121d09c9621a691dce3294556ac8b2494bd
MD5 21229ca76ac6c4295aaaa6102059c14a
BLAKE2b-256 368dffc4b9f087f939e12af03ce52ebd6d5b19ac5a2c02f90e1803917aafc000

See more details on using hashes here.

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

Hashes for docval-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dff7bb2579127fd0d6fd1591a4085603bf678a9fcbac15dc34c1fff6d78ae6a8
MD5 1d9d93ac65c3c11174d2cc8933e87491
BLAKE2b-256 38999e86f780a2483e27b788fdf9013e2de6075ec4160825e24755f2d3f34315

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page