/doc-refresh skill — contract¶
Project-local Claude Code skill at .claude/skills/doc-refresh/SKILL.md. Invoked
as /doc-refresh [release <version> | adr <number> | milestone | manual <note>].
Why this exists¶
Documentation drifts silently: nobody edits README.md when a feature ships
elsewhere, and docs/deployment.md's "After the tag" release step-down —
advance the milestone in mvp-scope.md §1, log it in §10 — is a manual step
with no enforcement. The first time it was skipped
(PR #265, 2026-08-19), MVP-1
had been released for six days while every session still opened with "Now
building MVP-1 against a 2026-08-13 deadline," and the stale contract was
actively misdirecting /next and /spec, which gate off mvp-scope.md §1.
This skill formalizes that cleanup pass so it recurs on a trigger (a release, an ADR, a milestone amendment) rather than being rediscovered from scratch each time the drift becomes visible enough to notice.
Shape¶
Five steps, all detailed in the SKILL.md itself:
- Find the delta — diff from the last entry in
docs/product/doc-refresh-log.md, never guess what changed. - Scan — up to 3 parallel read-only Explore agents (product/decision layer, official docs tree + README, repo-wide grep for hardcoded facts in contracts/skills), mirroring PR #265's three-agent split.
- Ask — four recurring judgment calls via
AskUserQuestion, each with a stated recommended default, rather than an agent silently deciding scope-affecting questions. - Execute — six workstreams (A: the contract, B: root context, C: official docs tree, D: archive moves, E: contracts minimal-flip, F: ledger + roadmap inputs), one branch, one commit per workstream.
- Verify and land — full test suite (not
test-fast— this is low-frequency), strictmkdocs build, a targeted grep gate for the exact stale strings Step 1 found, then the PR.
Two process fixes baked in after the first run¶
The archive blast-radius grep. PR #265's Workstream D (git mv of stale run
artifacts into docs/_archive/) shipped without checking for inbound references
to the moved paths. Codex's /pr-loop review round 1 caught it — three broken
links across CHANGELOG.md, an ADR, and a design note. Step 3-D now runs
git grep -l <basename> for every moved file before the PR opens, so this
class of finding no longer costs a paid review round.
The shared-worktree merge hazard. Landing PR #265's conflict resolution
against main hit a real hazard: this machine runs several Claude Code sessions
against this repo concurrently, and the primary checkout carries per-session
untracked state (.claude/launch.json diverges by design — each session adds
its own preview-server entries). A plain git merge in that shared directory
was correctly rejected once, and a naive retry could have silently collided
with another session's local files. Step 5 now mandates resolving conflicts in
an isolated git worktree add --detach, verifying there, and pushing the merge
commit directly (git push origin <sha>:<branch>) rather than fast-forwarding
the shared checkout.
Boundaries¶
- Does not write new milestone content — a
milestone-triggered pass documents that a redefinition happened and produces the reading-list bridge to it (roadmap-inputs-<date>.md); the actual gate sentence is a founder call. - Does not touch qa/product-manager gate semantics in
.agents/roles/— only de-duplicates hardcoded dates/counts to referencemvp-scope.md §1. - Does not create Linear tickets —
roadmap-inputs-<date>.mdis the handoff artifact for whatever session does that.
Ledger¶
docs/product/doc-refresh-log.md — one row per invocation, append-only, never
edited retroactively. Read its last row before starting Step 0 of the next run.