Post-change documentation sweep. Captures non-obvious knowledge into the right docs, trims bloat, and keeps the repo's documentation surfaces aligned after changes that likely introduced drift.
When to use
After infrastructure, configuration, architecture, or operational changes
After a merged PR, release cut, feature shipment, or version bump when those changes likely caused doc drift
When asked to refresh docs, instruction files, runbooks, changelogs, API docs, roadmaps, or README content
When a session uncovered new gotchas, changed setup steps, changed external behavior, or added services
When an API contract, feature surface, migration path, or release/install path changed
When the repo's docs surface is obviously underspecified and it is worth suggesting a minimal docs bootstrap to the user
When NOT to use
Writing a full documentation set from scratch without user approval
Code correctness or security review - use code-review or security-audit
Code quality, slop, or maintainability cleanup - use anti-slop
Prompt authoring or reusable skill-file maintenance - use prompt-generator or skill-creator
Full codebase audit across multiple domains - use full-review (it invokes update-docs as one pass)
Git commit messages, PR descriptions, release announcement copy, or tag operations - use git
Roadmap prioritisation and backlog shaping belongs to the roadmap skill; factual drift (stated version, shipped highlights, items mistakenly listed as planned) belongs here
AI Self-Check
Before presenting documentation updates, verify:
Only documenting gotchas, decisions, and failure modes - not defaults readable from config
No stale counts introduced (used "N" or kept count accurate)
Internal links verified (no broken references after renames or moves)
Companion instruction files still aligned (AGENTS.md synced if CLAUDE.md changed)
Existing doc surface checked first before creating a new markdown file
Release, API, roadmap, and feature docs updated only if the change actually affected them
No orphaned gotchas for already-fixed issues
Deprecated entries marked with [DEPRECATED] prefix and date, not silently removed
.env.example updated if env vars or runtime config changed
If repo docs are too thin, a minimal docs bootstrap was offered to the user as a suggestion, not forced
Size check run (wc -c) - instruction files under 40,000 chars
README / quality-evidence sections checked for stale dates, stale counts, and old run references
All roadmap files (committed AND gitignored) checked - their stated version/date matches current HEAD or latest tag
[planned] / [exploring] items that actually shipped have moved to Shipped Highlights, not left in the in-progress list
When private and public roadmaps both exist, both are updated, with the public one carrying user-visible highlights only and the private one carrying internal detail
Docs match code: commands, flags, config names, screenshots, and API examples are checked against the changed implementation
Audience path checked: README, changelog, API docs, runbooks, and migration notes are updated only where users need them
Cross-cutting agent hygiene applied - see references/agent-hygiene.md
Core Principle
Document what you can't grep, in the file readers will actually check. If it's in the source code, config files, or manifests, it usually doesn't belong in docs. Document: gotchas, decisions, failure modes, workarounds, implicit dependencies, release-facing deltas, and "the thing that took 30 minutes to figure out."
Performance
Diff the code first, then update affected docs; avoid broad rewrites unrelated to the change.
Prefer generated API/schema docs where the project already has generation tooling.
Keep examples minimal but runnable so future verification is cheap.
Best Practices
Document behavior changes, deprecations, migration steps, and rollback notes in the place users will look.
Remove stale instructions instead of appending contradictory notes.
Keep changelog entries user-facing and avoid internal implementation noise.
Workflow
Audit-only mode: When invoked by full-review or when the user asks to "just report" or "check docs," run Steps 1-6 and report findings without making changes or committing. Skip Steps 7-8.
Check whether the repo's docs surface is missing or too thin
Update affected docs (or report what needs updating in audit-only mode)
Verify internal links
Audit instruction-file bloat
Sync companion instruction files
Commit doc changes
1. Identify What Changed
Check git diff and conversation context to understand what was modified:
# Uncommitted changes
git diff --name-only
# Compare against the roadmap's stated version, falling back to last tag, falling back to last 10
ROADMAP_VER=$(grep -hoE 'Current:?\s*v?[0-9]+\.[0-9]+\.[0-9]+' ROADMAP.md docs/ROADMAP.md 2>/dev/null | head -1 | grep -oE 'v?[0-9]+\.[0-9]+\.[0-9]+')
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
RANGE="${ROADMAP_VER:-${LAST_TAG}}..HEAD"
git log --oneline "$RANGE" 2>/dev/null || git log --oneline -10
Scan for changes in: configuration, infrastructure, service deployments, scripts, CI workflows, network/IP assignments, service versions, and anything operational.
1.5. Roadmap Freshness Check
Roadmaps drift the hardest because they restate facts the code, tags, and commit history already prove. Run this check whenever the repo has a roadmap - committed OR gitignored. If no roadmap is found, the step is silent and you move on; absence of ROADMAP.md is not an error.
# Discover all roadmap files (tracked AND gitignored). Normalize the leading ./ from find
# so it doesn't duplicate paths returned by git ls-files.
ROADMAPS=$(
{ git ls-files '*ROADMAP*' '*roadmap*' 2>/dev/null
find . -maxdepth 4 -iname 'ROADMAP*' -not -path '*/node_modules/*' -not -path '*/.git/*' 2>/dev/null \
| sed 's|^\./||'
} | sort -u
)
if [[ -n "$ROADMAPS" ]]; then
# Resolve the source-of-truth version (try common manifests in order)
REPO_VER=""
[[ -f package.json ]] && REPO_VER=$(node -p "require('./package.json').version" 2>/dev/null)
[[ -z "$REPO_VER" && -f Cargo.toml ]] && REPO_VER=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
[[ -z "$REPO_VER" && -f pyproject.toml ]] && REPO_VER=$(grep -m1 '^version' pyproject.toml | sed -E 's/.*"([^"]+)".*/\1/')
[[ -z "$REPO_VER" && -f setup.py ]] && REPO_VER=$(grep -oE "version=['\"][^'\"]+" setup.py | sed -E "s/.*['\"]//")
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
HEAD_DATE=$(git log -1 --format=%cs HEAD 2>/dev/null)
# For each roadmap, parse the stated Current/Updated/Version header and compare
while read -r rm; do
[[ -f "$rm" ]] || continue
STATED=$(grep -hE '^>.*(Current|Updated|Version)' "$rm" 2>/dev/null | head -3)
RM_VER=$(printf '%s' "$STATED" | grep -oE 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -1)
RM_DATE=$(printf '%s' "$STATED" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)
[[ -z "$RM_VER$RM_DATE" ]] && continue # no parseable header, skip silently
# Informational counts (used in the drift output, not as triggers - commit count is a
# bad proxy for staleness when an agentic /loop session can ship 5 commits in 20 min).
COMMITS=0; TAGS=0
if [[ -n "$RM_VER" ]]; then
COMMITS=$(git rev-list --count "${RM_VER}..HEAD" 2>/dev/null || echo 0)
TAGS=$(git tag --sort=v:refname 2>/dev/null | awk -v r="$RM_VER" 'found{c++} $0==r{found=1} END{print c+0}')
fi
# Tags cut AFTER the roadmap's stated date - the cleanest "you shipped, roadmap is
# behind" signal. Releases are deliberate punctuation; arbitrary commits are not.
NEWER_TAGS=$(git for-each-ref --sort=-creatordate \
--format='%(creatordate:short) %(refname:short)' refs/tags 2>/dev/null \
| awk -v d="${RM_DATE:-9999-99-99}" '$1 > d {print $2}')
NEW_TAG_COUNT=$(printf '%s\n' "$NEWER_TAGS" | grep -c .)
# Calendar-day staleness fallback for projects that do not tag releases. Portable across
# GNU date (Linux) and BSD date (macOS).
DAYS_BEHIND=0
if [[ -n "$RM_DATE" && -n "$HEAD_DATE" ]]; then
H=$(date -d "$HEAD_DATE" +%s 2>/dev/null || date -j -f %Y-%m-%d "$HEAD_DATE" +%s 2>/dev/null)
R=$(date -d "$RM_DATE" +%s 2>/dev/null || date -j -f %Y-%m-%d "$RM_DATE" +%s 2>/dev/null)
[[ -n "$H" && -n "$R" ]] && DAYS_BEHIND=$(( (H - R) / 86400 ))
fi
# Drift if ANY of: stated version older than latest tag; one or more releases cut since
# the header date; or >14 calendar days since the header date with no release activity.
DRIFT=0
[[ -n "$RM_VER" && -n "$LAST_TAG" && "$(printf '%s\n' "$RM_VER" "$LAST_TAG" | sort -V | tail -1)" != "$RM_VER" ]] && DRIFT=1
[[ "$NEW_TAG_COUNT" -gt 0 ]] && DRIFT=1
[[ "$DAYS_BEHIND" -gt 14 ]] && DRIFT=1
if [[ "$DRIFT" -eq 1 ]]; then
echo "ROADMAP DRIFT: $rm states ${RM_VER:-?} / ${RM_DATE:-?}; HEAD is ${LAST_TAG:-v$REPO_VER} / $HEAD_DATE; $COMMITS commits, $TAGS tags between, $NEW_TAG_COUNT releases since header date, ${DAYS_BEHIND}d calendar gap."
# Feed the drift range into Step 2 - widens the diff window beyond `git log -10`
[[ -n "$RM_VER" ]] && RANGE="${RM_VER}..HEAD"
fi
done <<< "$ROADMAPS"
fi
Why tags-and-days, not commit-count: commit count was the obvious proxy for staleness in pre-agentic days. It is unusable now - a /loop or agentic refactor session can ship 5+ commits in under an hour without touching anything the roadmap should track. Tags and calendar days are velocity-independent: a release tag is a deliberate event the roadmap should reflect, and 14 calendar days without an updated header is real staleness regardless of how many commits passed through. Commit count survives only as informational context in the drift output.
Side-channel staleness: the header check is structural - it flags drift in stated metadata, not the substance of the roadmap. Roadmaps often contain time-stamped sections like Scanned 2026-04-10, Last refreshed 2026-04-10, as of 2026-04-10, or Weekly refresh covers .... Surface those as separate observations when the date is older than HEAD by more than a week:
Do NOT fabricate refreshed content. The user wants staleness called out so they can decide whether to refresh manually, not invented data.
1.6. Evidence Freshness Check
README files often contain "quality evidence" paragraphs that rot quietly: old benchmark dates,
old run IDs, stale skill counts, stale test counts, old release versions, or claims like
"latest run" that no longer match repository state. Run this check whenever touching README,
CHANGELOG, release docs, project status docs, or any doc with evidence/quality/status wording.
# Find brittle evidence claims in tracked docs.
DOCS=$(git ls-files '*.md' 'docs/**/*.md' 2>/dev/null)
if [[ -n "$DOCS" ]]; then
printf '%s\n' "$DOCS" | while IFS= read -r doc; do
git grep -n -E '([0-9]{4}-[0-9]{2}-[0-9]{2}|[0-9]+/[0-9]+|quality evidence|refiner run|refiner-runs|benchmark|latest (run|score|evidence|benchmark)|current (run|score|evidence|gates|version)|score[: ]|passed (for|in|on))' -- "$doc" 2>/dev/null || true
done
fi
# Compare public skill count claims against the actual tracked collection.
ACTUAL_SKILLS=$(git ls-files 'skills/*/SKILL.md' 2>/dev/null | wc -l | tr -d ' ')
if [[ "$ACTUAL_SKILLS" -eq 0 ]]; then
ACTUAL_SKILLS=$(find skills -mindepth 2 -maxdepth 2 -name SKILL.md -not -path '*/_*/*' | wc -l | tr -d ' ')
fi
if [[ -n "$DOCS" ]]; then
printf '%s\n' "$DOCS" | while IFS= read -r doc; do
git grep -n -E '[0-9]+ public skills|[0-9]+ skills|[0-9]+/[0-9]+' -- "$doc" 2>/dev/null || true
done
fi
printf 'Actual tracked public skills: %s\n' "$ACTUAL_SKILLS"
# If .refiner-runs.json exists, identify the latest recorded run before restating it.
python3 - <<'PY' 2>/dev/null
import json
from pathlib import Path
p = Path(".refiner-runs.json")
if p.exists():
data = json.loads(p.read_text())
run = data[-1] if isinstance(data, list) and data else data
print(json.dumps(run, indent=2)[:2000])
PY
When a stale evidence claim is found, either update it from the source artifact or rewrite it to
avoid brittle counts. Good: "Current repository gates pass for the public skill collection."
Risky: "Current gates pass for all 42 skills" unless you verified the count in the same run.
2. Categorize Doc Impact
Map changes to documentation targets. Common instruction file names: CLAUDE.md, AGENTS.md, GEMINI.md, CODEX.md. Adapt to the project's doc structure:
Change Type
Likely Docs to Update
New/changed infrastructure specs
Project instruction file (AGENTS.md or equivalent), inventory docs
New service or app deployed
Project instruction file, deployment docs
IP/port/endpoint changes
Project instruction file, network inventory
Version bumps (runtimes, deps, images)
Project instruction file
New gotcha discovered
Project instruction file
Operational procedure performed
Runbooks or deployment checklists (include when in the deploy cycle the procedure runs)
Gitignored private roadmap AND committed public roadmap both present
Update both - private gets the deeper internal detail, public gets the user-visible summary
Strategy or sequencing changes
ROADMAP.md, status docs, milestone docs
When to write an ADR: If the decision affects multiple components, constrains future options, or reverses a previous decision, it's worth a dedicated Architecture Decision Record. If it's a one-liner ("switched from X to Y because Z"), a short bullet in the project's instruction file is enough.
Gotcha placement heuristic:
One-liner gotcha (e.g., "VIP refuses k8s traffic - use direct IP") -> CLAUDE.md bullet.
Multi-step procedure (e.g., "rotating a cert requires drain, replace, reload in order") -> dedicated runbook section.
Time-critical pre/post-deploy action (e.g., "Redis FLUSHALL must run after deploy but before traffic is routed back") -> checklist at the top of the runbook, not buried in a section.
3. Check Whether the Repo's Docs Surface Is Missing or Too Thin
If the repo has no meaningful documentation surface, or only a minimal README.md, treat that as a separate observation before editing anything.
Examples of "too thin":
No docs/ directory and no durable markdown files beyond a stub README.md
A README.md that only names the project and gives no setup, usage, API, or feature overview
Repeated change-driven doc drift with nowhere sensible to record it
What to do:
Suggest a minimal docs bootstrap to the user as a dismissable recommendation
Keep the suggestion small and concrete, for example: README.md, CHANGELOG.md, API.md, ROADMAP.md, or docs/adr/
Tailor the suggestion to the repo type; don't propose a generic docs tree mechanically
If the user declines, continue with the best available existing doc surface and note the limitation
What NOT to do:
Don't automatically create a full new docs set
Don't block routine doc maintenance on the bootstrap suggestion
4. Update Affected Docs
For each affected doc, read it first, then make targeted edits.
What to ADD:
Gotchas that aren't obvious from code (e.g., "VIP refuses k8s traffic - use direct IP")
Implicit dependencies between components (e.g., "must restart pod after SealedSecret update")
Failure modes and their symptoms (e.g., "PLEG unhealthy = container runtime frozen")
Workarounds for known issues
Operational constraints (e.g., "serial: 1 required - removing it updates all nodes simultaneously")
Operational timing - when a procedure must run relative to a deployment step, say so explicitly (e.g., "Redis FLUSHALL must run after the new image is deployed but before traffic is routed back")
Connection strings and service endpoints when IPs, ports, or hostnames change
Decisions and their rationale
User-visible feature additions, removals, and caveats in the doc where readers expect them
API behavior changes in API.md, endpoint docs, or the repo's canonical API surface
When no docs exist yet:
Don't create a full documentation set from scratch unless the user explicitly asks
DO offer a minimal docs bootstrap suggestion if the repo is under-documented
DO add a minimal entry to the project instruction file (CLAUDE.md, AGENTS.md, or equivalent) with the gotcha or operational note that prompted this
If the project has no instruction file at all, note this to the user and suggest creating one with the essential gotcha. Don't block on it.
What NOT to add:
Default values readable from config files or manifests
Standard framework/platform behavior
Information already in upstream docs
Temporary state (in-progress work, one-time migration steps already completed)
Verbose explanations - one line per gotcha, expand only if the fix is non-obvious
5. Verify Internal Links
After editing docs, check that internal references still resolve:
# Check tracked and new markdown files
{ git ls-files '*.md'; git ls-files --others --exclude-standard -- '*.md'; } 2>/dev/null | sort -u | while read -r file; do
grep -oEh '\[[^]]*\]\([^)#]+' "$file"
done | sed 's/.*](//' | grep -v '^https\?://' | sort -u | while read -r path; do
[[ -e "$path" ]] || echo "BROKEN LINK: $path"
done
This catches [text](path) and  links, strips anchors (#section),
and skips external URLs. Works on both GNU and BSD grep (no -P flag needed).
If files were renamed or moved, update all references.
6. Audit Project Instruction Files for Bloat
After updates, review the project's shared instruction file critically:
Remove or condense if:
A gotcha was fixed and no longer applies (mark as resolved, then delete next session)
Information is now in a runbook (replace with pointer)
A section restates what's in the source (e.g., listing every container image tag)
Multiple bullet points say the same thing differently
A migration or one-time procedure is fully complete and won't recur
Version numbers that Renovate/CI keeps current automatically
Keep if:
You'd waste 15+ minutes rediscovering it without the doc
It's a cross-component interaction not visible in any single file
It contradicts what you'd expect from reading the code
It's a "don't do X" warning born from actual breakage
Size targets:
Shared instruction files: aim for under 40,000 characters and under 500 lines even if the tool allows more. If over, move detailed sections to docs/ and link.
Individual sections: if a section exceeds 30 lines, consider splitting into a dedicated doc.
Check size after edits: wc -c CLAUDE.md AGENTS.md 2>/dev/null
7. Sync Companion Instruction Files
If the project keeps multiple instruction files (AGENTS.md plus tool-specific variants, for example), keep them aligned after updates.
# Example: sync AGENTS.md into a tool-specific companion
test -f AGENTS.md && test -f CLAUDE.md && cp AGENTS.md CLAUDE.md
Review the copied file after syncing and remove any tool-specific commands or behavior that do not apply to that target.
Default: instruction files are usually gitignored unless the project intentionally tracks them. Check .gitignore and existing history before committing them.
8. Commit Documentation Changes
Only commit changes to tracked docs (inventory, runbooks, ADRs, changelogs, feature docs, API docs, roadmaps, and instruction files if the project commits them).
Severity scale:P0 | P1 | P2 | P3 | info (see shared contract).
Related Skills
full-review - orchestrates code-review, anti-slop, security-audit, and update-docs in
parallel. Update-docs is one of the four passes.
git - for commit message conventions and PR descriptions. Update-docs covers project
documentation files; git covers version control operations.
Common Mistakes
Documenting everything: If it's in config files, don't repeat the default value in the instruction file. Document the gotcha around it.
Stale counts: "13 dashboards" becomes wrong when you add one. Use "N dashboards" or keep the count accurate.
Stale quality evidence: README claims like "latest run", "current score", or "39/39 skills" must be checked against the source artifact in the same session.
Orphaned gotchas: A gotcha about a bug that was fixed 3 months ago is noise. Prune regularly.
Assuming every merge needs docs: A merged PR is a strong hint, not an automatic docs task. Check for actual drift.
Forgetting non-README surfaces: API changes belong in API.md; release deltas belong in CHANGELOG.md; feature drift belongs in feature docs.
Missing the companion sync: If the project keeps multiple instruction files, keep them aligned after changes.
Over-documenting migrations: Once a migration is complete and verified, condense to a one-liner and remove the step-by-step procedure.
Dangling links: Renaming a doc without updating references elsewhere creates dead links that erode trust in documentation.
Bootstrapping without consent: If the repo lacks docs, suggest a minimal docs surface; don't silently create a documentation tree the user did not ask for.
Deleting deprecated docs too early: Keep deprecated entries visible for at least one release cycle so people find the migration path.
Skipping the roadmap header check: A roadmap with Current: v0.27 while HEAD is on v0.43 is the loudest possible drift signal. Always parse and compare the header before deciding whether the roadmap needs updates.
Treating a gitignored roadmap as out of scope: Private roadmaps drift hardest because nobody complains about them publicly. Run the freshness check against ALL roadmaps the find command surfaces, not just tracked ones.
Rules
Document deltas, not defaults. Capture what changed, what broke, and what future sessions need to know.
Treat merged PRs and releases as doc-drift signals, not guarantees. Verify likely impact before editing.
Prefer the right existing doc over the nearest convenient one. Put API changes in API docs, release deltas in changelogs, and planning changes in roadmap/status docs.
Do not rewrite healthy docs for style alone. Keep edits tied to real operational value.
Offer docs bootstrap suggestions when the repo is under-documented, but keep them dismissable.
Keep companion instruction files aligned. If the repo maintains more than one instruction surface, update the others or note the drift explicitly.
Prefer stable wording over brittle counts. Avoid numbers and one-off migration prose that will rot immediately.
1---2name: update-docs3description: · Sweep docs after changes: README, changelog, API, runbooks. Triggers: 'update docs', 'refresh docs', 'sync docs', 'docs drift', 'merged PR', 'release cut', 'version bump', 'update changelog'. Not for PR text (use git).4license: MIT5---67# Update Docs89Post-change documentation sweep. Captures non-obvious knowledge into the right docs, trims bloat, and keeps the repo's documentation surfaces aligned after changes that likely introduced drift.1011## When to use1213- After infrastructure, configuration, architecture, or operational changes14- After a merged PR, release cut, feature shipment, or version bump when those changes likely caused doc drift15- When asked to refresh docs, instruction files, runbooks, changelogs, API docs, roadmaps, or README content16- When a session uncovered new gotchas, changed setup steps, changed external behavior, or added services17- When an API contract, feature surface, migration path, or release/install path changed18- When the repo's docs surface is obviously underspecified and it is worth suggesting a minimal docs bootstrap to the user1920## When NOT to use2122- Writing a full documentation set from scratch without user approval23- Code correctness or security review - use **code-review** or **security-audit**24- Code quality, slop, or maintainability cleanup - use **anti-slop**25- Prompt authoring or reusable skill-file maintenance - use **prompt-generator** or **skill-creator**26- Full codebase audit across multiple domains - use **full-review** (it invokes update-docs as one pass)27- Git commit messages, PR descriptions, release announcement copy, or tag operations - use **git**28- Roadmap prioritisation and backlog shaping belongs to the **roadmap** skill; factual drift (stated version, shipped highlights, items mistakenly listed as planned) belongs here2930---3132## AI Self-Check3334Before presenting documentation updates, verify:3536- [ ] Only documenting gotchas, decisions, and failure modes - not defaults readable from config37- [ ] No stale counts introduced (used "N" or kept count accurate)38- [ ] Internal links verified (no broken references after renames or moves)39- [ ] Companion instruction files still aligned (AGENTS.md synced if CLAUDE.md changed)40- [ ] Existing doc surface checked first before creating a new markdown file41- [ ] Release, API, roadmap, and feature docs updated only if the change actually affected them42- [ ] No orphaned gotchas for already-fixed issues43- [ ] Deprecated entries marked with `[DEPRECATED]` prefix and date, not silently removed44- [ ] `.env.example` updated if env vars or runtime config changed45- [ ] If repo docs are too thin, a minimal docs bootstrap was offered to the user as a suggestion, not forced46- [ ] Size check run (`wc -c`) - instruction files under 40,000 chars47- [ ] README / quality-evidence sections checked for stale dates, stale counts, and old run references48- [ ] All roadmap files (committed AND gitignored) checked - their stated version/date matches current HEAD or latest tag49- [ ] `[planned]` / `[exploring]` items that actually shipped have moved to Shipped Highlights, not left in the in-progress list50- [ ] When private and public roadmaps both exist, both are updated, with the public one carrying user-visible highlights only and the private one carrying internal detail51- [ ] **Docs match code**: commands, flags, config names, screenshots, and API examples are checked against the changed implementation52- [ ] **Audience path checked**: README, changelog, API docs, runbooks, and migration notes are updated only where users need them53- [ ] Cross-cutting agent hygiene applied - see `references/agent-hygiene.md`5455## Core Principle5657**Document what you can't grep, in the file readers will actually check.** If it's in the source code, config files, or manifests, it usually doesn't belong in docs. Document: gotchas, decisions, failure modes, workarounds, implicit dependencies, release-facing deltas, and "the thing that took 30 minutes to figure out."5859---6061## Performance6263- Diff the code first, then update affected docs; avoid broad rewrites unrelated to the change.64- Prefer generated API/schema docs where the project already has generation tooling.65- Keep examples minimal but runnable so future verification is cheap.666768---6970## Best Practices7172- Document behavior changes, deprecations, migration steps, and rollback notes in the place users will look.73- Remove stale instructions instead of appending contradictory notes.74- Keep changelog entries user-facing and avoid internal implementation noise.757677## Workflow7879**Audit-only mode:** When invoked by full-review or when the user asks to "just report" or "check docs," run Steps 1-6 and report findings without making changes or committing. Skip Steps 7-8.80811. Identify changes821.5. Roadmap freshness check831.6. Evidence freshness check842. Categorize doc impact853. Check whether the repo's docs surface is missing or too thin864. Update affected docs (or report what needs updating in audit-only mode)875. Verify internal links886. Audit instruction-file bloat897. Sync companion instruction files908. Commit doc changes9192### 1. Identify What Changed9394Check git diff and conversation context to understand what was modified:9596```bash97# Uncommitted changes98git diff --name-only99100# Compare against the roadmap's stated version, falling back to last tag, falling back to last 10101ROADMAP_VER=$(grep -hoE 'Current:?\s*v?[0-9]+\.[0-9]+\.[0-9]+' ROADMAP.md docs/ROADMAP.md 2>/dev/null | head -1 | grep -oE 'v?[0-9]+\.[0-9]+\.[0-9]+')102LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)103RANGE="${ROADMAP_VER:-${LAST_TAG}}..HEAD"104git log --oneline "$RANGE" 2>/dev/null || git log --oneline -10105```106107Scan for changes in: configuration, infrastructure, service deployments, scripts, CI workflows, network/IP assignments, service versions, and anything operational.108109### 1.5. Roadmap Freshness Check110111Roadmaps drift the hardest because they restate facts the code, tags, and commit history already prove. Run this check whenever the repo has a roadmap - committed OR gitignored. If no roadmap is found, the step is silent and you move on; absence of `ROADMAP.md` is not an error.112113```bash114# Discover all roadmap files (tracked AND gitignored). Normalize the leading ./ from find115# so it doesn't duplicate paths returned by git ls-files.116ROADMAPS=$(117 { git ls-files '*ROADMAP*' '*roadmap*' 2>/dev/null118 find . -maxdepth 4 -iname 'ROADMAP*' -not -path '*/node_modules/*' -not -path '*/.git/*' 2>/dev/null \119 | sed 's|^\./||'120 } | sort -u121)122123if [[ -n "$ROADMAPS" ]]; then124 # Resolve the source-of-truth version (try common manifests in order)125 REPO_VER=""126 [[ -f package.json ]] && REPO_VER=$(node -p "require('./package.json').version" 2>/dev/null)127 [[ -z "$REPO_VER" && -f Cargo.toml ]] && REPO_VER=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')128 [[ -z "$REPO_VER" && -f pyproject.toml ]] && REPO_VER=$(grep -m1 '^version' pyproject.toml | sed -E 's/.*"([^"]+)".*/\1/')129 [[ -z "$REPO_VER" && -f setup.py ]] && REPO_VER=$(grep -oE "version=['\"][^'\"]+" setup.py | sed -E "s/.*['\"]//")130 LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)131 HEAD_DATE=$(git log -1 --format=%cs HEAD 2>/dev/null)132133 # For each roadmap, parse the stated Current/Updated/Version header and compare134 while read -r rm; do135 [[ -f "$rm" ]] || continue136 STATED=$(grep -hE '^>.*(Current|Updated|Version)' "$rm" 2>/dev/null | head -3)137 RM_VER=$(printf '%s' "$STATED" | grep -oE 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -1)138 RM_DATE=$(printf '%s' "$STATED" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)139 [[ -z "$RM_VER$RM_DATE" ]] && continue # no parseable header, skip silently140141 # Informational counts (used in the drift output, not as triggers - commit count is a142 # bad proxy for staleness when an agentic /loop session can ship 5 commits in 20 min).143 COMMITS=0; TAGS=0144 if [[ -n "$RM_VER" ]]; then145 COMMITS=$(git rev-list --count "${RM_VER}..HEAD" 2>/dev/null || echo 0)146 TAGS=$(git tag --sort=v:refname 2>/dev/null | awk -v r="$RM_VER" 'found{c++} $0==r{found=1} END{print c+0}')147 fi148149 # Tags cut AFTER the roadmap's stated date - the cleanest "you shipped, roadmap is150 # behind" signal. Releases are deliberate punctuation; arbitrary commits are not.151 NEWER_TAGS=$(git for-each-ref --sort=-creatordate \152 --format='%(creatordate:short) %(refname:short)' refs/tags 2>/dev/null \153 | awk -v d="${RM_DATE:-9999-99-99}" '$1 > d {print $2}')154 NEW_TAG_COUNT=$(printf '%s\n' "$NEWER_TAGS" | grep -c .)155156 # Calendar-day staleness fallback for projects that do not tag releases. Portable across157 # GNU date (Linux) and BSD date (macOS).158 DAYS_BEHIND=0159 if [[ -n "$RM_DATE" && -n "$HEAD_DATE" ]]; then160 H=$(date -d "$HEAD_DATE" +%s 2>/dev/null || date -j -f %Y-%m-%d "$HEAD_DATE" +%s 2>/dev/null)161 R=$(date -d "$RM_DATE" +%s 2>/dev/null || date -j -f %Y-%m-%d "$RM_DATE" +%s 2>/dev/null)162 [[ -n "$H" && -n "$R" ]] && DAYS_BEHIND=$(( (H - R) / 86400 ))163 fi164165 # Drift if ANY of: stated version older than latest tag; one or more releases cut since166 # the header date; or >14 calendar days since the header date with no release activity.167 DRIFT=0168 [[ -n "$RM_VER" && -n "$LAST_TAG" && "$(printf '%s\n' "$RM_VER" "$LAST_TAG" | sort -V | tail -1)" != "$RM_VER" ]] && DRIFT=1169 [[ "$NEW_TAG_COUNT" -gt 0 ]] && DRIFT=1170 [[ "$DAYS_BEHIND" -gt 14 ]] && DRIFT=1171172 if [[ "$DRIFT" -eq 1 ]]; then173 echo "ROADMAP DRIFT: $rm states ${RM_VER:-?} / ${RM_DATE:-?}; HEAD is ${LAST_TAG:-v$REPO_VER} / $HEAD_DATE; $COMMITS commits, $TAGS tags between, $NEW_TAG_COUNT releases since header date, ${DAYS_BEHIND}d calendar gap."174 # Feed the drift range into Step 2 - widens the diff window beyond `git log -10`175 [[ -n "$RM_VER" ]] && RANGE="${RM_VER}..HEAD"176 fi177 done <<< "$ROADMAPS"178fi179```180181**Why tags-and-days, not commit-count:** commit count was the obvious proxy for staleness in pre-agentic days. It is unusable now - a `/loop` or agentic refactor session can ship 5+ commits in under an hour without touching anything the roadmap should track. Tags and calendar days are velocity-independent: a release tag is a deliberate event the roadmap should reflect, and 14 calendar days without an updated header is real staleness regardless of how many commits passed through. Commit count survives only as informational context in the drift output.182183**Side-channel staleness:** the header check is structural - it flags drift in stated metadata, not the *substance* of the roadmap. Roadmaps often contain time-stamped sections like `Scanned 2026-04-10`, `Last refreshed 2026-04-10`, `as of 2026-04-10`, or `Weekly refresh covers ...`. Surface those as **separate observations** when the date is older than HEAD by more than a week:184185```bash186echo "$ROADMAPS" | while read -r rm; do187 [[ -f "$rm" ]] || continue188 grep -nE '([Ss]canned|[Ll]ast [Rr]efreshed|[Aa]s of|[Ww]eekly refresh)[^0-9]*[0-9]{4}-[0-9]{2}-[0-9]{2}' "$rm" 2>/dev/null189done190```191192Do NOT fabricate refreshed content. The user wants staleness called out so they can decide whether to refresh manually, not invented data.193194### 1.6. Evidence Freshness Check195196README files often contain "quality evidence" paragraphs that rot quietly: old benchmark dates,197old run IDs, stale skill counts, stale test counts, old release versions, or claims like198"latest run" that no longer match repository state. Run this check whenever touching README,199CHANGELOG, release docs, project status docs, or any doc with evidence/quality/status wording.200201```bash202# Find brittle evidence claims in tracked docs.203DOCS=$(git ls-files '*.md' 'docs/**/*.md' 2>/dev/null)204if [[ -n "$DOCS" ]]; then205 printf '%s\n' "$DOCS" | while IFS= read -r doc; do206 git grep -n -E '([0-9]{4}-[0-9]{2}-[0-9]{2}|[0-9]+/[0-9]+|quality evidence|refiner run|refiner-runs|benchmark|latest (run|score|evidence|benchmark)|current (run|score|evidence|gates|version)|score[: ]|passed (for|in|on))' -- "$doc" 2>/dev/null || true207 done208fi209210# Compare public skill count claims against the actual tracked collection.211ACTUAL_SKILLS=$(git ls-files 'skills/*/SKILL.md' 2>/dev/null | wc -l | tr -d ' ')212if [[ "$ACTUAL_SKILLS" -eq 0 ]]; then213 ACTUAL_SKILLS=$(find skills -mindepth 2 -maxdepth 2 -name SKILL.md -not -path '*/_*/*' | wc -l | tr -d ' ')214fi215if [[ -n "$DOCS" ]]; then216 printf '%s\n' "$DOCS" | while IFS= read -r doc; do217 git grep -n -E '[0-9]+ public skills|[0-9]+ skills|[0-9]+/[0-9]+' -- "$doc" 2>/dev/null || true218 done219fi220printf 'Actual tracked public skills: %s\n' "$ACTUAL_SKILLS"221222# If .refiner-runs.json exists, identify the latest recorded run before restating it.223python3 - <<'PY' 2>/dev/null224import json225from pathlib import Path226p = Path(".refiner-runs.json")227if p.exists():228 data = json.loads(p.read_text())229 run = data[-1] if isinstance(data, list) and data else data230 print(json.dumps(run, indent=2)[:2000])231PY232```233234When a stale evidence claim is found, either update it from the source artifact or rewrite it to235avoid brittle counts. Good: "Current repository gates pass for the public skill collection."236Risky: "Current gates pass for all 42 skills" unless you verified the count in the same run.237238### 2. Categorize Doc Impact239240Map changes to documentation targets. Common instruction file names: `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `CODEX.md`. Adapt to the project's doc structure:241242| Change Type | Likely Docs to Update |243|-------------|----------------------|244| New/changed infrastructure specs | Project instruction file (`AGENTS.md` or equivalent), inventory docs |245| New service or app deployed | Project instruction file, deployment docs |246| IP/port/endpoint changes | Project instruction file, network inventory |247| Version bumps (runtimes, deps, images) | Project instruction file |248| New gotcha discovered | Project instruction file |249| Operational procedure performed | Runbooks or deployment checklists (include when in the deploy cycle the procedure runs) |250| New secret or credential | Secrets inventory |251| CI/CD workflow changes | Project instruction file, pipeline docs |252| Docker/Compose changes | Project instruction file, deployment docs |253| Proxmox/LXC changes | Project instruction file, inventory docs |254| Rust crate/toolchain changes | Project instruction file, `README.md` (build prereqs) |255| Architecture decision | ADR if significant (see below), otherwise a short bullet in the instruction file |256| New or changed env vars, config keys, or runtime config | `.env.example`, `README.md` (setup section) |257| New dependencies or setup steps | `README.md` (getting started / prerequisites) |258| API endpoint or contract changes | `API.md`, `README.md` (API section), endpoint docs, OpenAPI spec if applicable |259| Feature added, removed, or materially changed | `README.md`, feature docs (`FEATURES.md`, `FEATURESET.md`, `docs/features/*.md`), changelog |260| Merged PR with user-visible impact | Changelog, roadmap/status docs, release notes, affected feature/API/setup docs |261| Version bumps / new release cut | `CHANGELOG.md`, release notes, `README.md`, install/upgrade docs, badges, package manager instructions |262| Release cut or version bump (roadmap-side) | `ROADMAP.md` header (`Current` / `Updated`), Shipped Highlights section, status docs |263| Multiple shipped features since last roadmap update | `ROADMAP.md` Shipped Highlights, Where-We-Are summary, `[planned]` / `[exploring]` items that actually shipped |264| Gitignored private roadmap AND committed public roadmap both present | Update both - private gets the deeper internal detail, public gets the user-visible summary |265| Strategy or sequencing changes | `ROADMAP.md`, status docs, milestone docs |266267**When to write an ADR:** If the decision affects multiple components, constrains future options, or reverses a previous decision, it's worth a dedicated Architecture Decision Record. If it's a one-liner ("switched from X to Y because Z"), a short bullet in the project's instruction file is enough.268269**Gotcha placement heuristic:**270- One-liner gotcha (e.g., "VIP refuses k8s traffic - use direct IP") -> `CLAUDE.md` bullet.271- Multi-step procedure (e.g., "rotating a cert requires drain, replace, reload in order") -> dedicated runbook section.272- Time-critical pre/post-deploy action (e.g., "Redis FLUSHALL must run after deploy but before traffic is routed back") -> checklist at the top of the runbook, not buried in a section.273274### 3. Check Whether the Repo's Docs Surface Is Missing or Too Thin275276If the repo has no meaningful documentation surface, or only a minimal `README.md`, treat that as a separate observation before editing anything.277278**Examples of "too thin":**279- No `docs/` directory and no durable markdown files beyond a stub `README.md`280- A `README.md` that only names the project and gives no setup, usage, API, or feature overview281- Repeated change-driven doc drift with nowhere sensible to record it282283**What to do:**284- Suggest a minimal docs bootstrap to the user as a dismissable recommendation285- Keep the suggestion small and concrete, for example: `README.md`, `CHANGELOG.md`, `API.md`, `ROADMAP.md`, or `docs/adr/`286- Tailor the suggestion to the repo type; don't propose a generic docs tree mechanically287- If the user declines, continue with the best available existing doc surface and note the limitation288289**What NOT to do:**290- Don't automatically create a full new docs set291- Don't block routine doc maintenance on the bootstrap suggestion292293### 4. Update Affected Docs294295**For each affected doc, read it first, then make targeted edits.**296297#### What to ADD:298- Gotchas that aren't obvious from code (e.g., "VIP refuses k8s traffic - use direct IP")299- Implicit dependencies between components (e.g., "must restart pod after SealedSecret update")300- Failure modes and their symptoms (e.g., "PLEG unhealthy = container runtime frozen")301- Workarounds for known issues302- Operational constraints (e.g., "serial: 1 required - removing it updates all nodes simultaneously")303- Operational timing - when a procedure must run relative to a deployment step, say so explicitly (e.g., "Redis FLUSHALL must run after the new image is deployed but before traffic is routed back")304- Connection strings and service endpoints when IPs, ports, or hostnames change305- Decisions and their rationale306- User-visible feature additions, removals, and caveats in the doc where readers expect them307- Release-facing deltas: upgraded versions, upgrade notes, breaking changes, and migration pointers308- API behavior changes in `API.md`, endpoint docs, or the repo's canonical API surface309310#### When no docs exist yet:311- Don't create a full documentation set from scratch unless the user explicitly asks312- DO offer a minimal docs bootstrap suggestion if the repo is under-documented313- DO add a minimal entry to the project instruction file (CLAUDE.md, AGENTS.md, or equivalent) with the gotcha or operational note that prompted this314- If the project has no instruction file at all, note this to the user and suggest creating one with the essential gotcha. Don't block on it.315316#### What NOT to add:317- Default values readable from config files or manifests318- Standard framework/platform behavior319- Information already in upstream docs320- Temporary state (in-progress work, one-time migration steps already completed)321- Verbose explanations - one line per gotcha, expand only if the fix is non-obvious322323### 5. Verify Internal Links324325After editing docs, check that internal references still resolve:326327```bash328# Check tracked and new markdown files329{ git ls-files '*.md'; git ls-files --others --exclude-standard -- '*.md'; } 2>/dev/null | sort -u | while read -r file; do330 grep -oEh '\[[^]]*\]\([^)#]+' "$file"331done | sed 's/.*](//' | grep -v '^https\?://' | sort -u | while read -r path; do332 [[ -e "$path" ]] || echo "BROKEN LINK: $path"333done334```335336This catches `[text](path)` and `` links, strips anchors (`#section`),337and skips external URLs. Works on both GNU and BSD grep (no `-P` flag needed).338If files were renamed or moved, update all references.339340### 6. Audit Project Instruction Files for Bloat341342After updates, review the project's shared instruction file critically:343344**Remove or condense if:**345- A gotcha was fixed and no longer applies (mark as resolved, then delete next session)346- Information is now in a runbook (replace with pointer)347- A section restates what's in the source (e.g., listing every container image tag)348- Multiple bullet points say the same thing differently349- A migration or one-time procedure is fully complete and won't recur350- Version numbers that Renovate/CI keeps current automatically351352**Keep if:**353- You'd waste 15+ minutes rediscovering it without the doc354- It's a cross-component interaction not visible in any single file355- It contradicts what you'd expect from reading the code356- It's a "don't do X" warning born from actual breakage357358**Size targets:**359- Shared instruction files: aim for **under 40,000 characters** and under 500 lines even if the tool allows more. If over, move detailed sections to `docs/` and link.360- Individual sections: if a section exceeds 30 lines, consider splitting into a dedicated doc.361- Check size after edits: `wc -c CLAUDE.md AGENTS.md 2>/dev/null`362363### 7. Sync Companion Instruction Files364365If the project keeps multiple instruction files (`AGENTS.md` plus tool-specific variants, for example), keep them aligned after updates.366367```bash368# Example: sync AGENTS.md into a tool-specific companion369test -f AGENTS.md && test -f CLAUDE.md && cp AGENTS.md CLAUDE.md370```371372Review the copied file after syncing and remove any tool-specific commands or behavior that do not apply to that target.373374**Default: instruction files are usually gitignored unless the project intentionally tracks them.** Check `.gitignore` and existing history before committing them.375376### 8. Commit Documentation Changes377378Only commit changes to tracked docs (inventory, runbooks, ADRs, changelogs, feature docs, API docs, roadmaps, and instruction files if the project commits them).379380```bash381# Stage specific changed docs (don't blindly add everything)382{ git diff --name-only -- '*.md' '.env.example'; git ls-files --others --exclude-standard -- '*.md' '.env.example'; } 2>/dev/null | sort -u | \383 while read -r path; do384 [[ -n "$path" ]] && git add -- "$path"385 done386# Only if docs changed:387git diff --cached --quiet || git commit -m "docs: update [target] after [what changed]"388```389390## Quick Reference: File Locations391392| File | Purpose | Committed? |393|------|---------|-----------|394| `README.md` | Repo overview, setup, install, usage | Yes |395| `CHANGELOG.md` | Release-facing history and breaking changes | Usually yes |396| `API.md` | Human-readable API surface and contract notes | Usually yes |397| `ROADMAP.md` | Public or private plan/status surface | Depends on project |398| `FEATURES.md` / `FEATURESET.md` | User-visible capability inventory | Depends on project |399| Other `*.md` docs | Release notes, status docs, migration notes, architecture docs | Depends on project |400| `AGENTS.md` | Cross-tool project instructions | Depends on project (check .gitignore) |401| Tool-specific instruction file | Companion instructions for a specific agent/tool when a project keeps one | Depends on project (check .gitignore) |402| `docs/` | Project documentation (inventory, runbooks, ADRs, migration notes, release docs) | Yes |403404## Handling Deprecated Features405406When a feature, service, or API is deprecated during a session:407- **Keep the doc entry** with a `[DEPRECATED]` prefix and the date - don't delete immediately408- **Add the replacement** in the same section so readers find both409- **Remove deprecated entries** after 2 release cycles or when confirmed no longer referenced anywhere410- **Breaking changes** deserve their own bullet: what broke, what replaces it, any migration steps411412## Output Contract413414See `references/output-contract.md` for the full contract.415416- **Skill name:** UPDATE-DOCS417- **Deliverable bucket:** `audits`418- **Mode:** always-on. Every invocation emits the full contract - monospace inline header, severity-grouped inline summary, linked Markdown deliverable, and concise monospace conclusion.419- **Deliverable path:** `docs/local/audits/update-docs/<YYYY-MM-DD>-<slug>.md`420- **Severity scale:** `P0 | P1 | P2 | P3 | info` (see shared contract).421422## Related Skills423424- **full-review** - orchestrates code-review, anti-slop, security-audit, and update-docs in425 parallel. Update-docs is one of the four passes.426- **git** - for commit message conventions and PR descriptions. Update-docs covers project427 documentation files; git covers version control operations.428429---430431## Common Mistakes432433- **Documenting everything**: If it's in config files, don't repeat the default value in the instruction file. Document the gotcha around it.434- **Stale counts**: "13 dashboards" becomes wrong when you add one. Use "N dashboards" or keep the count accurate.435- **Stale quality evidence**: README claims like "latest run", "current score", or "39/39 skills" must be checked against the source artifact in the same session.436- **Orphaned gotchas**: A gotcha about a bug that was fixed 3 months ago is noise. Prune regularly.437- **Assuming every merge needs docs**: A merged PR is a strong hint, not an automatic docs task. Check for actual drift.438- **Forgetting non-README surfaces**: API changes belong in `API.md`; release deltas belong in `CHANGELOG.md`; feature drift belongs in feature docs.439- **Missing the companion sync**: If the project keeps multiple instruction files, keep them aligned after changes.440- **Over-documenting migrations**: Once a migration is complete and verified, condense to a one-liner and remove the step-by-step procedure.441- **Dangling links**: Renaming a doc without updating references elsewhere creates dead links that erode trust in documentation.442- **Bootstrapping without consent**: If the repo lacks docs, suggest a minimal docs surface; don't silently create a documentation tree the user did not ask for.443- **Deleting deprecated docs too early**: Keep deprecated entries visible for at least one release cycle so people find the migration path.444- **Skipping the roadmap header check**: A roadmap with `Current: v0.27` while HEAD is on `v0.43` is the loudest possible drift signal. Always parse and compare the header before deciding whether the roadmap needs updates.445- **Treating a gitignored roadmap as out of scope**: Private roadmaps drift hardest because nobody complains about them publicly. Run the freshness check against ALL roadmaps the `find` command surfaces, not just tracked ones.446447---448449## Rules450451- **Document deltas, not defaults.** Capture what changed, what broke, and what future sessions need to know.452- **Treat merged PRs and releases as doc-drift signals, not guarantees.** Verify likely impact before editing.453- **Prefer the right existing doc over the nearest convenient one.** Put API changes in API docs, release deltas in changelogs, and planning changes in roadmap/status docs.454- **Do not rewrite healthy docs for style alone.** Keep edits tied to real operational value.455- **Offer docs bootstrap suggestions when the repo is under-documented, but keep them dismissable.**456- **Keep companion instruction files aligned.** If the repo maintains more than one instruction surface, update the others or note the drift explicitly.457- **Prefer stable wording over brittle counts.** Avoid numbers and one-off migration prose that will rot immediately.
Run npx skillmds@latest add iuliandita/update-docs in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
· Sweep docs after changes: README, changelog, API, runbooks. Triggers: 'update docs', 'refresh docs', 'sync docs', 'docs drift', 'merged PR', 'release cut', 'version bump', 'update changelog'. Not for PR text (use git). It is listed under Integrations & APIs on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: reads secrets. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
iuliandita (@iuliandita) published this skill. Their other Agent Skills are listed on their SkillMD profile.