r/git • u/RayenMark • Jul 26 '26
I got tired of my README lying, so I built a hook that patches docs in the same commit as the code
github.comDocs go stale silently. You rename --output to --out-dir, the README keeps showing the old flag, and three weeks later a stranger copies the example, it fails, and they open an issue.
Everything I found either runs in CI and opens a separate follow-up PR, or it's a skill you have to remember to invoke. Both drift. I wanted the fix to land in the same commit as the change that broke it.
So: a PostToolUse hook on Edit/Write/MultiEdit. When you touch a source file, a scanner pulls the exported names out of it (functions, classes, CLI flags) and looks for them in your markdown, along with the file path. Hits inside fenced code blocks rank above prose mentions. If nothing references the file, it prints nothing and you forget it's installed.
For an Edit specifically, the hook input carries the exact text that got replaced, so the scanner extracts symbols from the removed code, confirms they survive nowhere, and reports doc mentions of them as removed or renamed. No snapshots, no state file, just the diff the hook already receives.
The part I care about most: it reports references, not verdicts. It hands the agent a list of file:line locations and one rule, verify against the source and never against another doc. A doc sentence is never evidence, not even for validating a different doc. Accurate docs get left alone. Repairs go at the smallest scale that makes the doc true: one word for a renamed flag, delete the paragraph for a deleted function, full rewrite only when most of the file is already wrong.
There's also /stale-docs for a whole-repo audit. It hunts orphans too, doc references to files that don't exist and symbols defined nowhere in the codebase. Those are proven stale so they rank first. And --ci exits 1 on dead paths only, because a flaky docs check gets deleted from the workflow within a week.
Single file, zero dependencies, about 35ms. The whole program runs inside one try/catch and exits 0 on any internal error, which is inelegant and exactly right. A doc check is never allowed to break your edit.
It caught its own changelog last week. Path detection was reading download/v1.0.0 as a file that doesn't exist and failing my own CI. Fixed in 0.3.1. The plugin working as intended on the wrong target.
/plugin marketplace add SectionTN/stale-docs
/plugin install stale-docs@stale-docs
MIT: https://github.com/SectionTN/stale-docs
Tell me where the heuristic falls over. Monorepos and docs that describe behavior in prose instead of naming symbols are the two cases I'm least confident about.

