-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add docvet fix command for AST-based docstring scaffolding #305
Description
Summary
Add a docvet fix command that generates missing docstring sections using pure AST analysis — no LLM, no external dependencies. This is the natural complement to docvet check: check finds the gaps, fix scaffolds the skeletons.
Motivation
Every linter that ships an auto-fixer wins adoption. Ruff's --fix is why it displaced flake8. Users don't want to be told what's wrong — they want a path to fix it.
The user journey today:
docvet check --all → 200 findings → overwhelmed → abandon
The user journey with fix:
docvet check --all → 200 findings → docvet fix --all → skeletons generated → fill in blanks → done
Proposed behavior
docvet fix # Fix findings in git diff files
docvet fix --staged # Fix findings in staged files
docvet fix --all # Fix findings in entire codebase
docvet fix --dry-run # Show what would be changed without modifying filesExample output
Given a function with missing sections:
def transfer(source: Account, target: Account, amount: Decimal) -> Receipt:
"""Transfer funds between accounts."""
if amount <= 0:
raise ValueError("Amount must be positive")
if source.balance < amount:
raise InsufficientFundsError(source, amount)
...After docvet fix:
def transfer(source: Account, target: Account, amount: Decimal) -> Receipt:
"""Transfer funds between accounts.
Args:
source: [TODO: describe]
target: [TODO: describe]
amount: [TODO: describe]
Returns:
[TODO: describe]
Raises:
ValueError: [TODO: describe]
InsufficientFundsError: [TODO: describe]
"""Design constraints
- AST-only — no LLM, no network, no new dependencies. Uses the same AST parsing as enrichment checks.
- Deterministic — same input always produces same output
- Idempotent — running fix twice doesn't duplicate sections
- Non-destructive — preserves existing docstring content, only adds missing sections
--dry-run— required for safety, shows diff without modifying files
Scope
In scope
- Scaffold missing Args, Returns, Raises, Yields, Receives, Warns, Attributes sections
- Scaffold missing Examples section with
>>>placeholder - Preserve existing sections and descriptions
- Support all file discovery modes (diff, staged, all, positional args)
Out of scope
- AI-powered description generation (separate tool/plugin territory)
- Fixing formatting issues (ruff's domain)
- Adding docstrings to symbols that have none (interrogate's domain + presence check)
Technical approach
The enrichment check already identifies what's missing via AST analysis. The fix command reuses the same analysis but emits the skeleton instead of reporting the gap. Core data flow:
File → AST parse → enrichment analysis → missing sections identified → generate skeleton → write back
Testing considerations
- Roundtrip tests: original → fix → re-check produces zero findings for scaffolded sections
- Idempotency: running fix twice doesn't duplicate sections
- Edge cases: existing partial docstrings, decorated functions, async generators, nested classes
- Dry-run output matches actual changes
Context
Emerged from party-mode consensus (2026-03-06) with strong support from 5+ agents. Identified as the highest-conversion-impact feature for adoption.