Crowi Docs Refresh (site ドキュメントの追随 + 陳腐化掃除)
SkillDocs & knowledgeA periodic maintenance skill that updates the documentation (content/docs/{ja,en}) in apps/crowi-site/ based on recent changes to main (integrated features and fixes), and investigates and fixes outdated descriptions on existing pages by checking against the actual code. Run it when several integrat
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Crowi Docs Refresh (site ドキュメントの追随 + 陳腐化掃除) skill
What this skill tells your AI
The instructions your AI receives, as published by crowi/crowi in .claude/skills/crowi-docs-refresh/SKILL.md and read by ahel’s review.
標準の呼び出し元: 手動の
/crowi-docs-refreshに加えて、integrate-worktree の Step 10 が統合完了時の drain point(他に READY_TO_INTEGRATE が残っていない時)に 自動で呼ぶ。どちらの経路でも本 skill の動作は同一(watermark 駆動)。
apps/crowi-site/(crowi.wiki の LP + docs・Fumadocs)を main の実装に追随させる。
2 つの仕事を 1 回で行う: ①未文書化の user-visible 変更を書き足す(前回実行以降の
delta 駆動)、②既存ページの陳腐化を実コード照合で見つけて直す(claim 検証)。
site は push で Cloudflare Pages に deploy されるため、main に merge 済みの機能は
文書化してよい(未 merge・未実装は書かない)。
対象 / 非対象
- 対象:
apps/crowi-site/content/docs/{ja,en}/(読者別の 3 タブ =guide/利用者 /operations/管理者・運用者 /develop/開発者・コントリビュータ)+ 必要なら LP 側の feature 記述。 - 非対象: wiki(
/crowi/spec/...)— spec の publish は crowi-design の領分。docs/rfcs/— RFC は設計文書であり user docs ではない。README 群。
ワークフロー
Step 0: scope 解決(1 回だけ確定)
- 引数に git range(
abc..def)があればそれ。 - なければ
.feature-state/docs-sync-state.jsonのlastDocsSyncSha..HEAD。 - state が無い初回は self-bootstrap:
git log -1 --format=%H -- apps/crowi-site/content(site docs を最後に触った commit)を起点にする。docs はそこまでは同期して いたはず、という近似 — 実行後は state が引き継ぐ。
Step 1: delta 抽出(何が user-visible に変わったか)
range 内から docs 影響候補を集める:
# 主信号: user-visible 変更は changeset として積まれている(CLAUDE.md の運用)
git diff --name-only --diff-filter=A <range> -- .changeset | grep -v README
# 副信号: feat/fix commit と merge summary
git log --oneline --no-merges <range> | grep -E "^[0-9a-f]+ (feat|fix)"
git log --merges --format="%h %s%n%b" <range>
各候補を仕分ける:
- docs 済み: range 内で対応する
content/docs変更が既に入っている (git log <range> -- apps/crowi-site/contentと突き合わせ)→ skip。 feature pipeline は docs 同梱が多いので、これが最頻ケース。 - docs 必要: 新しい記法 / config / env / UI 挙動 / 運用手順の変化 → Step 2 へ。
- docs 不要: 内部 refactor・test・CI のみ → skip(判断を 1 行残す)。
モデル割り当て(Codex/Claude の分担 — 2026-07-18 user 合意)
制御・glue・ゲート・commit は Claude(本 session)、分析・批評・長文は Codex。
Codex は必ず .claude/scripts/codex-run.sh 経由(exec + strict schema。
--tier sol|terra|luna — sol=最難関/terra=標準/luna=軽作業)。再実行前に
stale 成果物を掃除する(codex-runs の invocation 跨ぎ再利用に注意)。
| 仕事 | 担当 |
|---|---|
| scope 解決・delta 抽出・parity/build ゲート・commit | Claude(session) |
| 陳腐化 sweep(docs↔code の敵対照合) | Codex terra |
| 難所の挙動解明(cache 意味論・並行・security — 誤記述が実害になる箇所) | Codex sol(単発・難所限定) |
| en ページの draft(長文) | Codex terra |
| ja ページの draft(既存 docs の文体との一貫性) | Claude |
| 最終照合 | 書き手と逆のモデル(Claude 執筆分は Codex が事実照合、Codex 執筆分は Claude が照合) |
Step 2: 書き足し(実コードから書く)
- commit message や changeset の文面だけから書かない。該当の実コード (handler / plugin / component)と、あればテストの AC を読んでから書く — message は意図であり、docs は挙動の記述。spec ファイルは integrate 後に 消えているのが正常なので、頼らない。挙動が非自明な難所(上表)は先に Codex sol へ「file:line 根拠付きで正確な挙動を説明せよ」を単発で投げ、 その出力を下敷きにする。
- en は Codex terra に draft させ、ja は Claude が書く(en の翻訳ではなく 既存 ja docs の文体で書き直す)。書き上がったら逆モデルで事実照合。
- 置き場所は 2 段階で決める。まず読者(利用者 →
guide/、管理者・運用者 →operations/、開発者・コントリビュータ →develop/、全員 →reference/)、次に文書タイプ(導入 / 手順 / 参照 / 解説)。1 ページには 1 タイプだけを書く。新ページより既存ページへの追記を優先。 - 4 つのフォルダは Fumadocs の root フォルダ(= サイドバーのタブ)。ページを足したら該当
meta.jsonのpagesに登録する(未登録ページはサイドバーに出ない)。タブ内のグループはセパレータ("---名前---")で分ける。 - 新しい環境変数・設定キー・CLI オプションは
reference/の該当表に行を足すのが第一。reference/は参照タイプだけを置く場所で、表と 1 行の説明だけを書く。手順ページには「なぜ・いつ使うか」だけを書き、表はreference/の該当ページへリンクする(表を 2 か所に置かない)。 reference/にも SDK の識別子(register*/CrowiPlugin/PluginContext/configSchema/adminPlacement/StateCell/modelAccessなど)は書かない。これらはdevelop/plugin-apiに置く。- 版固有の移行手順は
operations/upgradeの該当バージョン節に書く。トポロジや設定の説明ページには書かない。 - 利用者・運用者向けページ(
guide/operations/reference/)に RFC 番号・spec id(feature-*)・ファイルパス・関数名・ミドルウェア名・CSS トークン・モデルのフィールド名を書かない。書けるのはdevelop/のみ。 - 概念の呼び名は
reference/glossaryに登録した語を使い、リンク文言はリンク先ページのtitleに揃える。呼び名を増やす・変えるときはscripts/docs-glossary.jsonを先に直す(用語 lint はこのファイルからルールを起こす)。 - 経緯を書かない(「以前は」「旧バージョンでは」)。例外は
operations/upgrading-from-v1の v1 との差分説明。 - ページを移動・改名したら
public/_redirectsに 301 を足し、リンク元の相対リンクを張り替える(検知は Step 4 のcheck:links)。 - ja / en を同時に書く。片方だけの commit を作らない。
Step 3: 陳腐化調査(claim 検証)
2 層で行う。大きい範囲なら層 b は subagent に fan-out してよい:
a. delta 隣接ページの精読: Step 1 の変更が触れた領域の既存ページを読み、
今回の変更で古くなった記述(挙動・制限・既定値)を直す。
b. 機械照合 sweep(Codex terra へ offload): 「以下の docs の claim 群を
実コードに当てて反証せよ」を codex-run.sh --sandbox read-only --tier terra
に exec + strict FINDINGS schema(crowi-review と同形)で投げる。照合先の正:
- env 変数 →
.env.example+packages/api/src/util/env-schema.ts - config キー →
apps/crowi-runner/crowi.config.json+ 各 plugin の config schema - 記法・embed tag → renderer 登録(
addEmbedTag/addCodeBlockRenderer等の呼び出し) - コマンド・scripts → 各
package.json/crowi-admin/@crowi/cli - ポート・URL →
scripts/dev-ports.mjs/Caddyfilefindings は Claude が verification-on-action で裁く(直すものだけ実コードで 裏取り)— fix or drop(修正するか、誤検出として 1 行報告)。terra の指摘の うち確信が持てず裏取りも難しい claim だけ sol にエスカレーションして正否を 確定する(sweep 全体を sol で回すのは過剰)。codex 不可(exit 2)なら Claude subagent で代替し、報告に明記。 なお「docs が正しく code が退行」の可能性が残る claim は直さず報告して ユーザー判断(docs 側を勝手に実装へ合わせない)。
Step 4: ゲート
# ja/en parity: 変更した docs ページに ja/en の対応があるか(片翼更新の検知)。
# sed は 2 式で書く — BSD sed の BRE は \| 非対応で、1 式のグループ交替だと
# 正常ペアまで PARITY MISS に化ける(実測済み)。
git diff --name-only HEAD -- apps/crowi-site/content \
| sed -e 's|/docs/ja/|/docs/*/|' -e 's|/docs/en/|/docs/*/|' \
| sort | uniq -c | awk '$1 == 1 {print "PARITY MISS:", $2}'
pnpm --filter @crowi/site build # Fumadocs は壊れた mdx でビルドが落ちる(壊れたリンクは落ちない)
# ページ間の相対リンクと、JSX の href 属性 (`<Card href="/ja/docs/...">`) が
# 解決するか(静的エクスポートは壊れたリンクを素のアンカーとして出力するので、
# ビルドでは検知できない)。JSX の href は locale 込みの絶対パスでなければ
# 落ちる — Card は href をそのままリンクコンポーネントへ渡すため、相対パスや
# locale 落ちのパスは 404 になる。リポジトリルートの pnpm lint と pre-push、
# それに docs.yml (ci.yml が docs だけの push を skip するため) からも走る。
pnpm --filter @crowi/site check:links
# 2 種類の禁止語を見る。(1) 内部識別子 (RFC 番号・spec id・リポジトリのパス・
# 関数名・CSS トークン・モデルのフィールド名) — guide/ operations/ reference/ のみ。
# (2) canonical 用語の揺れ — develop/ と locale 直下の index も含む全ページ。
# (2) のルールは scripts/docs-glossary.json から起こされる。呼び名を増やす・
# 変えるときはこのファイルを先に直す(canonical 語が reference/glossary.mdx に
# 現れることは pnpm test:scripts のテストが assert する)。
# 正当な出現は scripts/docs-vocabulary-allow.json に {path, pattern, why} を足す。
node scripts/check-docs-vocabulary.mjs
# チェッカ自身のテスト。Card の href 検証 (locale 落ち / 別 locale / 存在しない
# ページ) と、用語集とデータの乖離を見る。
pnpm test:scripts
pnpm --filter @crowi/site lint && pnpm --filter @crowi/site type-check
parity 検知は構造が対称なページのみの近似(LP 等の片側限定ファイルは除外して 判断)。build が通らない mdx は commit しない。
Step 5: commit + watermark
docs(site): ...(英語)。main-direct なら main write lock を取得して commit 後に解放(CLAUDE.md「main write lock」)。changeset は不要(docs のみ)。 push しない(ユーザー指示待ち)。- watermark を atomic に更新:
printf '{ "lastDocsSyncSha": "%s", "at": "%s" }\n' "$(git rev-parse HEAD)" \
"$(date -u +%FT%TZ)" > .feature-state/docs-sync-state.json.tmp \
&& mv .feature-state/docs-sync-state.json.tmp .feature-state/docs-sync-state.json
- 報告: 書き足したページ / 直した stale 記述 / drop した候補(各 1 行)。
鉄則
- 実コードを読まずに docs を書かない(commit message は意図、docs は挙動)。
- main に merge されていないものを書かない(worktree 進行中の機能は次回)。
- ja / en の片翼更新をしない。
- 見つけた stale は fix or drop — 退避先は存在しない(全 skill 共通)。
- push しない。site の deploy は push に紐づくので、公開タイミングはユーザーが握る。
guide/operations/reference/に RFC 番号・spec id (feature-*)・ファイルパス・関数名・ミドルウェア名・CSS トークン・モデルのフィールド名を書かない。書けるのはdevelop/のみ(検知は Step 4 の禁止語 lint)。reference/は 参照タイプだけ。表と 1 行の説明で構成し、手順と理由は元の手順・解説ページに残す。SDK の識別子はreference/にも書かずdevelop/plugin-apiに置く。- 同じ一覧表を 2 か所に置かない。実体は
reference/の 1 ページに置き、手順ページは該当ページへのリンクだけを持つ。 - 経緯を書かない。「以前は」「旧バージョンでは」「この変更は意図的な整理です」は削る。例外は
operations/upgrading-from-v1の v1 との差分説明。 - 未リリースの機能・「進行中」「予定」を書かない。予定は LP と GitHub Releases に任せる。
- alpha 注意書きをページごとに書かない(グローバルバナーが担う)。
- Callout は Fumadocs
<Callout>に統一し 1 ページ 3 個まで。6 行を超える注記は節に昇格する。 - 手順ページの本文が 6,000 字を超えたら分割を検討する。
- リンク文言はリンク先ページのタイトルと一致させる。概念の呼び名は
reference/glossaryに登録した語を使う。この統一はdevelop/にも効く — 内部識別子と違って呼び名の揺れに例外フォルダは無い。lint のルールはscripts/docs-glossary.jsonから起こされるので、呼び名を増やす・変えるときはそのファイルとreference/glossaryの両方を直す(片方だけだとpnpm test:scriptsが落ちる)。 - RFC 索引 (
develop/rfcs) は repodocs/rfcs/の全ファイルを載せる。guide/とoperations/からは RFC へ直リンクしない(RFC は設計文書であって利用者・運用者向けではない)。develop/内からの直リンクは許可する — 読者がコントリビュータで、RFC 本文そのものが目的地だから。 - 索引に RFC の実装状況を書かない。 23 本の進捗を docs 側で維持すると必ず陳腐化する。状態は各 RFC 自身のメタデータブロックが持つ。
エッジケース
| ケース | 挙動 |
|---|---|
| range 内の docs 影響変更がゼロ | 陳腐化 sweep(Step 3b)だけ回して watermark を進める |
| docs が正しく code が退行して見える | docs を触らず報告(修正は crowi-fix の領分) |
| 大型 feature で docs が丸ごと新章になる規模 | 本 skill で書かず、planner への docs spec 依頼を提案(1 ページ超の新章は設計判断を含む) |
pnpm --filter @crowi/site build が既存ページ起因で落ちる | 自分の変更と切り分け、既存起因なら別 fix として報告(黙って直してよいのは自明な壊れリンク程度) |
Signals
- GitHub stars
- 1k
- Forks
- 164
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
crowi-docs-refresh- Source
- github.com/crowi/crowi