Skip to content

/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:

  1. Find the delta — diff from the last entry in docs/product/doc-refresh-log.md, never guess what changed.
  2. 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.
  3. Ask — four recurring judgment calls via AskUserQuestion, each with a stated recommended default, rather than an agent silently deciding scope-affecting questions.
  4. 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.
  5. Verify and land — full test suite (not test-fast — this is low-frequency), strict mkdocs 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 reference mvp-scope.md §1.
  • Does not create Linear tickets — roadmap-inputs-<date>.md is 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.