docs-nav-lint 運用ガイド (Jr 引き継ぎ可能版)
根拠 ADR: ADR-0051 — docs/_config.json nav 未登録の .md ファイル検出 lint を追加
1. このガイドが扱う問題
新規 .md を docs/ 配下に追加した際、docs/_config.json の nav 配列に登録し忘れると Cloudflare Pages 上で 404 状態のまま放置 される (PR #796/#827 で実際に 2 日間 404 発生)。
これを CI で機械的に検出するのが scripts/docs-nav-lint.mjs。3 ルールで lint:
| Rule | 種類 | 内容 |
|---|---|---|
| R1 | orphan-md | docs/**/*.md のうち _config.json の nav 配列に未登録 |
| R2 | broken-nav-entry | _config.json の file: が指す実体ファイルが存在しない |
| R3 | duplicate-nav-entry | 同一 file が複数 nav エントリに登録されている |
2. ローカル実行
# 通常実行 (R1=WARN, R2/R3=FAIL)
npm run docs:lint
# Grace period 終了後 (2 週間後): R1 も FAIL になるモード
node scripts/docs-nav-lint.mjs --strict
# 現存 orphan を allowlist に一括追加 (緊急時の current-state freeze)
node scripts/docs-nav-lint.mjs --add-current-orphans
Exit code: 0 = pass, 1 = fail, 2 = usage error。
3. CI 実行
.github/workflows/docs-nav-lint.yml で PR + main push 時に自動実行。
GitHub PR の status check 欄に docs-nav-lint が緑/黄/赤で表示される。
Grace period (移行期間 2 週間): env.STRICT: 'false' で R1 を WARN 扱い (PR ブロックなし)。
2026-06-01 以降に STRICT: 'true' へ切替予定 → R1 も FAIL 化。
4. よくあるエラーと対応
4.1 [R1 orphan-md] xxx.md is not registered in docs/_config.json nav array
新規 .md を追加したのに nav に未登録。対応はどちらか:
A. nav に登録する (デフォルト推奨)
docs/_config.json の対象 group の "pages" 配列に追記:
{
"file": "your/new/file.md",
"title": "X.Y.Z タイトル"
}
title のプレフィックス (F.X.NN / A.NN / E.X.NN 等) は周辺エントリに合わせる。
B. allowlist に追加 (nav 対象外と判断した場合)
.docs-nav-lint-allowlist.json の files 配列に追加:
{
"files": [
"your/new/file.md"
],
"patterns": []
}
ディレクトリ単位で除外したい場合は patterns に正規表現:
{
"patterns": [
"^your/dir/.+\\.md$"
]
}
4.2 [R2 broken-nav-entry] "xxx.md" does not exist on disk
nav に登録された file が実在しない (リネーム・削除漏れ)。
docs/_config.json を修正して該当エントリを削除 or path 訂正。
4.3 [R3 duplicate-nav-entry] "xxx.md" appears N times
同じ file が複数 nav エントリに登録。docs/_config.json を修正していずれか 1 つに統一。
5. PR ブロック時の救済 ([skip-nav-lint] ラベル)
緊急時に lint を bypass するには PR に [skip-nav-lint] ラベルを付与:
gh pr edit <PR番号> --add-label "[skip-nav-lint]"
workflow の if: 条件でジョブがスキップされる (ADR-0051 §7 救済手順)。
bypass 利用後は必ず後続 PR で根本対応すること (allowlist 追加 or nav 登録)。
6. allowlist のメンテナンス
- 個別 file 追記: 上記 §4.1.B 参照
- pattern 追記: ディレクトリ全体を除外する場合 (例:
daily_log/配下は週次で増えるため pattern 化済) - 上限 30 件目安: allowlist が肥大化する = 「nav 登録すべきだが運用上できないファイル群」増加 = 設計上の歪み (ADR-0051 §8 負債化リスク)
- 上限超えたら
_config.jsonの group 構造そのものを見直し起案
7. 撤退条件モニタリング
月初に以下を実行し、docs-nav-lint workflow の failure 件数を集計:
gh run list --workflow=docs-nav-lint.yml --status=failure \
--created-after=$(date -v-1m +%Y-%m-%d) --json conclusion \
| jq 'length'
5 件超を 2 ヶ月連続 → R1 を WARN-only に格下げ判断 (ADR-0051 §7)。
注: 上記コマンドは BSD date (macOS) 構文。Linux/CI で実行する場合は
date --date='1 month ago' +%Y-%m-%dに置換。
8. CI 撤去手順 (撤退判断後)
.github/workflows/docs-nav-lint.ymlを.yml.disabledにリネーム (1 コミット)npm run docs:lintは package.json に残置 (ローカル任意実行のみ可)- 撤退時の最終 PR にレビュアー sign-off 必須 (撤退根拠の記録保持)
9. 関連ドキュメント
- ADR-0051:
docs/adr/0051-add-lint-for-unregistered-md-files-in-docs-config-nav.md - 設定ファイル:
docs/_config.json/.docs-nav-lint-allowlist.json - 関連 ADR: ADR-0042 (Prompt Lifecycle 管理 — 同じ「SSoT + 機械チェック + 運用ガード」パターン)