Auto-syncs stale docstrings and README when function signatures change. Detects documentation drift after refactors, parameter additions, or return type changes. Dry-run by default — proposes before writing.
87
100%
Does it follow best practices?
Impact
86%
1.59xAverage score across 17 eval scenarios
Passed
No known issues
Surgical documentation updater. Patches docs when a documented symbol's caller-visible contract changes. Conservative by design: flag more, change less.
If get_diff.sh reports no contract changes AND Step 2.5 finds no body-only drift: output exactly this and stop:
Mode: dry-run
✓ No contract changes detected in tracked files. Documentation is current.
Do NOT create new documentation. Do NOT write README files. Do NOT summarize commits. Stop here.
/doc-sync or /doc-sync --dry-run — detect and report, no file writes/doc-sync --apply — detect, report, and write patches/doc-sync --apply HEAD~3..HEAD — specify commit rangeArguments are available as $ARGUMENTS. Default to dry-run when empty.
Arguments: [--dry-run | --apply] [commit-range]
Load timing: After Step 1 completes and returns results, load references/workflow-steps.md before proceeding to Step 2. Do not load at startup — only when actively executing the workflow.
get_diff.sh to detect changes (default: all uncommitted):
SCRIPT=$(find "$(git rev-parse --show-toplevel)" -maxdepth 6 \-name "get_diff.sh" -path "/scripts/" 2>/dev/null | head -1) bash "$SCRIPT" $ARGUMENTS
2. Check existing doc coverage for every changed symbol (Step 2.5 in workflow-steps.md)
3. Check for README candidate sections via symbol-name grep (Step 2.5 Check 2)
4. Classify with two-factor + ownership test (Step 2 in workflow-steps.md)
Example (decorator-only contract change):
Before: a documented `fetch_user(id)` has no deprecation signal; signature unchanged.
After: add `@deprecated("Use get_user")` to the same function.
Expected: update the `fetch_user` docstring to surface deprecation; if README mentions it, flag `[NEEDS HUMAN REVIEW]` and propose-first (only apply markdown edits with explicit user approval).
5. If `--apply`: auto-write docstrings; propose README updates (only apply markdown edits with explicit user approval)
6. Verify every edit with `references/verify-steps.md`
7. Report in unified format: Updated / Proposed / Flagged / Missing Coverage / Skipped
## Scope — The Two-Factor Rule
A symbol is in scope when **both** conditions are true:
1. It already has a docstring or README mention (previously documented)
2. Its code changed
This skill handles Python, TypeScript, JavaScript, Go, Rust, Ruby, Java, and Kotlin. Docstring formats vary by language — match the existing style exactly.
**Write boundary**: In non-markdown source files, the only permitted edit is to docstring/JSDoc comment content. Function bodies, imports, logic, and all other code are never modified.
**The binding vote principle**: past documentation is a vote on importance.
A trivial 1-line body change in a documented function is in scope.
A trivial 1-line change in an undocumented function is not.
Visibility (public/private/internal) is irrelevant — only prior documentation is.
Example (binding vote, body-only semantic drift):
Before: docstring says "validates three conditions"; signature unchanged.
After: body changes to validate four conditions.
Expected: update only the stale docstring sentence to "four conditions"; do not touch unrelated docs.
## Ownership Rule (canonical — other files reference this)Docstring in source file → auto-write always Markdown code span match → propose-first; only apply with explicit user approval Prose mention without code span → skip (low confidence) No coverage found → report-only
Docstrings are symbol-local and unambiguous — safe to auto-write.
README content is human-authored territory — always require explicit user approval before applying edits.
Protected files (CHANGELOG, ADRs, legal docs) are excluded from candidate section search entirely — not proposed, not flagged, not mentioned.
See `references/scope-bounds.md` and `references/workflow-steps.md` Step 2.5.
## When Uncertain
Flag as `[NEEDS HUMAN REVIEW]`, explain, stop. Never guess.evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17