ADR-0070: nav title = 本文 H1 一致 rule の確立 + docs-nav-lint R6 追加
- Status: Accepted
- Mode: Standard
- Scope: platform
- Kruchten Type: Property
- Implementation Status: Not Started
- 起案者: [email protected]
- 起案日時 (JST): 2026-05-26 12:30
- 承認日時 (JST): 2026-05-26 12:45 (Pipeline Web UI full audit Standard 43/50 通過)
- Review After: 2026-08-26 (3 ヶ月), 2026-11-26 (6 ヶ月), 2027-05-26 (1 年)
- Deciders: [email protected] (単独)
1. コンテキスト
1.1 背景
ADR-0055 で nav 採番形式 <NS>.<NN>.* を確立したが、各 entry の title 本体については形式自由。結果として docs/_config.json の title field に 本文 H1 にない括弧書き補足 (例: (ADR-0058 / 4 rule + 許容値 SSoT)) や検索キーワード羅列が追加される傾向が積み重なった。
1.2 現状
2026-05-26 時点 全 526 nav entries 中:
| 状態 | 件数 | 割合 |
|---|---|---|
nav title = <numbering> <本文 H1> 完全一致 | 37 | 7% |
| 不一致 | 489 | 93% |
| うち括弧書き補足が title にのみ追加されている | 113 | 21.5% |
| うち省略 / 言い換え / 順序違い | 376 | 71.5% |
具体例 (RQ-046_synthesis.md):
- 本文 H1:
RQ-046 Synthesis: ドキュメントインベントリ管理・カバレッジ追跡 - config title:
I.01.4.14 RQ-046 ドキュメントインベントリ管理・カバレッジ追跡ベストプラクティス(Synthesis: 3モデル合意 / nav SSOT + status 5値 + COVERAGE_GAPS.md + 段階的CI導入 / ADR-0046 起草インプット)
サイドバー表示は docs-build.mjs:177-185 の displayPageTitle で <numbering>_<kebab(basename)>_<title から numbering を除いた残り> の 2 行構造で render される (ADR 化されていない暫定実装)。この場合「title から numbering を除いた残り」が肥大化してサイドバー視認性が損なわれる。
1.3 課題
- 可読性: サイドバーの 2 行目が長くなり、何のページか一目で判別できない
- 整合性: ページに到達すると本文 H1 が違って起案者の意図/SSoT が不明確
- メンテ負荷: 本文 H1 と config title の二重メンテ + drift 発生 (CI 検出なし)
- 新規参加者の混乱: 既存 lint reference doc (ADR-0058 / 0062 / 0063) が括弧書きパターンで先行整備されたため、後続 entry が継承しがち
1.4 制約・要件
- ADR-0055 (
<NS>.<NN>.*採番形式) は維持 - 既存 489 件不一致の一括修正は別 PR (本 ADR は rule + lint 確立のみ)
- docs-build.mjs
displayPageTitle仕様は維持 (rendering 側の話、本 ADR は config title 側の規約)
2. 決定
docs/_config.json 各 nav entry の title field は <NS>.<NN>.* <本文 .md ファイル H1 verbatim> の形式に統一する。括弧書き補足 / SSoT 識別子 / 検索キーワード羅列の追加は禁止。
2.1 例
| Before (NG) | After (OK) |
|---|---|
I.05.16 bizlp frontmatter Lint Rule Reference (ADR-0058 / 4 rule + 許容値 SSoT) | I.05.16 bizlp frontmatter Lint Rule Reference |
I.01.4.14 RQ-046 ドキュメントインベントリ管理・カバレッジ追跡ベストプラクティス(Synthesis: 3モデル合意 / ...) | I.01.4.14 RQ-046 Synthesis: ドキュメントインベントリ管理・カバレッジ追跡 (本文 H1 に整合させる) |
2.2 docs-nav-lint R6 追加
scripts/docs-nav-lint.mjs に R6 title-h1-consistency を追加:
- 各 nav entry の file を読み、本文 H1 (
^#matched 最初の行) を抽出 title.replace(/^[A-Z]\.[\d.]+\d\s+/, "")と比較- 不一致は WARN (grace period 6 ヶ月) → 後日 ERROR 昇格
- 例外許容: file が H1 なし or 機械生成 (例:
index.mdの生成テンプレート) はallowlistdocs-nav-lint-r6-allowlist.jsonで除外
Regex 検証 (全 NS パターン対応)
/^[A-Z]\.[\d.]+\d\s+/ を実 nav 採番に対して node 検証 (2026-05-26):
| サンプル | match | 備考 |
|---|---|---|
I.05.16 hoge | ✅ | 3 segments (top-level doc) |
I.01.3.1 hoge | ✅ | 4 segments (sub-group) |
I.01.4.14 hoge | ✅ | 4 segments + 2 桁 page |
A.09 hoge | ✅ | 2 segments minimal |
A.09.1.1 hoge | ✅ | 4 segments domains |
M.01.1 hoge | ✅ | 3 segments meta |
I.05.10.1 hoge | ✅ | adr-lint sub-rule |
I.01.0.1 hoge | ✅ | _jtbd_list 例 |
全パターン pass。I.NN.X.Y / A.NN.X.Y / O.NN.X.Y / M.NN.X.Y の 2-4 segment いずれも cover。
2.3 既存 489 件修正は別 PR (3 段階、絶対時期付き)
- Phase 1: 括弧書き補足追加 113 件を一括修正 (sub workspace、本 ADR Accepted 後即着手、想定完了 2026-06)
- Phase 2: 省略 / 言い換え 376 件を ADR-0055 と整合させながら個別判断 (sub workspace、複数 session)
- 月 4-8h sub session 想定 × 5-10 分/件 = 月 24-96 件
- 想定完了 2026-10 〜 2027-02 (4-8 ヶ月)
- Phase 3: R6 lint を WARN → ERROR 昇格 (main workspace、Phase 2 完了 6 ヶ月後)
- 絶対時期: 2027-04 〜 2027-08 (Phase 2 完了想定 + 6 ヶ月猶予)
- Phase 2 が遅延した場合は Review After 2026-11-26 / 2027-05-26 で絶対時期再見積もり
3. 判断基準 (Decision Drivers)
ADR-0050 / ADR-0054 / ADR-0058 と同 Q42 5 軸 + WSM + K.O. criterion (Suhr 1999 CBA 準拠)。
3.1 評価軸
| # | 軸 | 重要度 (係数) | 案件特有の解釈 |
|---|---|---|---|
| 1 | #maintainable | [Must] (×2.0) | nav title と本文 H1 の SSoT 一元化、drift 自動検出による永続的保守 |
| 2 | #operable | [Must] (×2.0) | Jr / Web UI 利用者のサイドバー視認性、認知負荷最小化 |
| 3 | #reliable | [High] (×1.0) | R6 lint による CI 機械検証、false positive 低減 |
| 4 | #suitable | [High] (×1.0) | ADR-0055 nav 採番との補完、scope の明確性 |
| 5 | #usable | [Medium] (×0.5) | 新規 nav entry 追加時の起案者の参照容易性 |
K.O. criterion: Must 軸 (#maintainable / #operable) score < 3 は不採用。
3.2 評価軸 × 案スコア表
| 軸 | 係数 | 採択 (rule + R6 + 3-Phase) | X1 何もしない | X2 H1 を title に合わせる | X3 rendering 切詰 |
|---|---|---|---|---|---|
#maintainable [Must] | ×2.0 | 5 (SSoT 化 + drift 検出) | 1 (drift 拡大) | 2 (本文側肥大、読み辛い) | 3 (config 依然冗長) |
#operable [Must] | ×2.0 | 5 (サイドバー視認性向上) | 1 (現状維持、肥大継続) | 3 | 4 (見える範囲は改善) |
#reliable High | ×1.0 | 5 (R6 lint CI 検証) | 1 | 3 | 2 (検証なし) |
#suitable High | ×1.0 | 5 (ADR-0055 補完) | 2 | 2 (逆方向で衝突) | 3 |
#usable Medium | ×0.5 | 4 (rule 明示) | 5 (何もしないので易) | 3 | 4 |
| 加重和 (正規化) | 0.945 | 0.273 | 0.391 | 0.582 | |
| K.O. 通過 (Must ≥3) | ✓ | ❌ | ❌ | ❌ |
採択首位 = rule + R6 + 3-Phase (加重和 0.945、他案は K.O. 落ち)。
4. 検討した代替案 (Alternatives Considered)
- 採用案: rule 確立 + R6 lint + 3 段階修正 — title drift を機械検出可能化、加重和 0.945
- X1: 何もしない — K.O. (
#maintainable=1/#operable=1、drift 拡大、Jr 入社時に混乱) - X2: 本文 H1 を config title に合わせる (逆方向) — K.O. (
#maintainable=2、H1 は SEO / 読み手の最初の認知、肥大化させると本文も読み辛い) - X3: rendering 側 (docs-build.mjs) で title を切り詰める表示制御 — K.O. (
#maintainable=3だが#operable=4で Must 通過しつつ加重和 0.582 で採択案 0.945 に劣後、config が依然冗長で見えないだけ)
5. 影響
Good: サイドバー視認性向上 / config title と本文 H1 の SSoT 一元化 / drift CI 検出 / Jr onboarding 容易
Bad: 489 件修正の作業負荷 (sub workspace 推定 33-67h) / 既存 lint reference doc (ADR-0058 / 0062 / 0063) の title 履歴を corrigendum 注記で対応
Neutral: docs-build.mjs displayPageTitle の rendering 仕様は維持 (本 ADR は config 側のみ)
5.1 ステークホルダー影響
| Stakeholder | 影響 | 受益 / 負担 |
|---|---|---|
| 起案者 (代表取締役) | sub session で Phase 1-2 修正 (33-67h、複数 session 分散) | 負担 |
| PR レビュアー (代表取締役 self-review) | 新規 nav entry 追加 PR で R6 lint 検証必須化 | 軽負担 (CI 自動化) |
| CI 担当者 (main session、Phase 3 で起動) | scripts/docs-nav-lint.mjs R6 実装 + allowlist json 新設 2-3h | 軽負担 |
| Web UI / Jr (将来 2026-10〜) | サイドバー視認性向上 (括弧書き肥大 113 件解消) | 受益 |
| 既存 lint reference doc 起案者 (= 代表取締役) | ADR-0058 / 0062 / 0063 等の title 改訂 (corrigendum 注記) | 軽負担 |
5.2 コスト試算 (詳細 breakdown)
| 項目 | 試算 |
|---|---|
| Phase 1 (sub) | 113 件 × 1-2 分/件 (機械的修正: 本文 H1 取得 + 括弧除去) = 1.9-3.8h、1 PR |
| Phase 2 (sub) | 376 件 × 5-10 分/件 (個別判断: 関連情報過不足の判定 + 本文編集の要否判断) = 31-63h、複数 PR |
| R6 lint 実装 (main) | scripts/docs-nav-lint.mjs +50-80 行 + docs-nav-lint-r6-allowlist.json 新規 = 2-3h |
| 合計 | sub 33-67h + main 2-3h = 35-70h |
| 削減効果 | サイドバー視認性向上による経路探索時間短縮 (Jr 入社後 ~5min/日 × 200 日 = ~17h/年) |
| ROI 回収 | Phase 1 単独で ~6-12 ヶ月、Phase 2 完了込みで ~3-4 年 (Jr 入社後加速) |
R6 lint 実装工数 (旧版で未計上) を含めた net cost。
6. 撤退条件 (Rollback Plan)
6.1 撤退判断指標
- 3 ヶ月後 (2026-08-26): 修正後に sidebar 利用者から「本文 H1 が情報不足で sidebar から判別できない」フィードバック ≥3 件 → 本 ADR Superseded、本文 H1 を逆方向に拡張する別 ADR 検討
- R6 lint false positive >10% (allowlist 肥大化、件数 >50) → R6 を WARN 維持 or 削除
6.2 ロールバック手順 (Phase 別)
| Phase | 状況 | revert 手順 |
|---|---|---|
| Phase 1 (113 件 1 PR) | merge 済を撤退 | git revert <merge-commit> 1 コマンドで即時 revert。docs/_config.json のみ変更のため副作用なし |
| Phase 2 (複数 PR) | 部分撤退 / 全撤退 | 各 PR を順次 git revert。または起案者裁定で「Phase 2 採択時点に戻す」 base commit を target に branch reset → PR レビュー後 force-push (履歴改変、main protect 解除必要) |
| R6 lint (main) | 撤退 | scripts/docs-nav-lint.mjs から R6 関数削除 PR + docs-nav-lint-r6-allowlist.json 削除。WARN 状態なら CI 通過なので即時無害化、ERROR 昇格済の場合は WARN への降格 PR 経由 |
データ復旧: docs/_config.json は git history のみ保持 (DB 等の永続化なし)。Phase 1 完了から Phase 2 着手まで 1 週間以上の checkpoint 確保で revert reference を残す。
7. Confirmation (準拠確認 / Fitness Function)
- 検証 1 (機械):
docs-nav-lint.mjs --check-r6で全 nav entry の title vs H1 一致を WARN/ERROR 出力、毎 PR - 検証 2 (手動): 新規 nav entry 追加 PR レビュー時に reviewer が括弧書き補足の有無を目視
- 検証 3 (移行): Phase 1 完了 PR で 113 件 → 0 件、Phase 2 完了で全 489 件 → 0 件 (allowlist 除外分のぞく)
8. 参照 (References)
- ADR-0055 (Confirms): nav 採番形式
<NS>.<NN>.*の確立、本 ADR は title 本体規約として補完 - ADR-0051 (Confirms): docs-nav-lint R1-R4 lint 設計、本 ADR で R6 追加
- ADR-0058 / 0062 / 0063 (Refines target): 既存 lint reference doc の title は本 ADR で修正対象
- 関連 memory: [[feedback-nav-title-h1-consistency]]
- 関連実装:
scripts/docs-build.mjs:177-185(displayPageTitle 関数) - 関連 PR/Issue: PR #975 (本 ADR 起案 Proposed merge + Accept transition)
9. 参照: Pipeline 審査履歴 (2026-05-26 Web UI 実行時)
本セクションは Decision Pipeline (LangGraph TS on Cloudflare Workers) で本 ADR 草案を Web UI 経由で審査した結果のログ。sub session の curl 経由 audit は Cloudflare 100s edge timeout で Gate 1-4 完走不可 (ADR-0066 async polling 未実装、ADR-0041 と同パターン)。Gate 0 Triage のみ curl で 13.5s で部分確認後、user が Web UI で full audit を実行。Standard 閾値 40 + Critical 閾値 45 ぎりぎりで 43/50 通過。ADR-0056 §8 / ADR-0058 §11 / ADR-0062 §8 / ADR-0063 §8 で確立した §audit history パターンの 第九適用例。デフォルトでは折りたたまれており、
▶をクリックで展開する。
📋 Pipeline 審査履歴 全 Gate 結果 (合格 Score 43 / 50, Standard 閾値 PASS) — クリックで展開
Mode 判定の遷移
| Gate | Mode |
|---|---|
| Gate 0 Triage (curl 13.5s) | Light |
| Web UI full audit (scoring 時) | Standard (Pipeline 内で reclassify) |
curl の triageOnly では Light、Web UI 経由 full audit では nav rule + lint 設計 + 489 件 migration 影響範囲が大きいため Standard 扱い。本 ADR header Mode は Standard に確定。
Gate 0-4 結果
- Gate 0 Triage: needsAdr=true / triageMode=Standard (curl では Light、UI full audit で reclassify) / 理由: ナビゲーションタイトルと本文H1の一致ルールを確立し、リンターで強制することで、ドキュメントの可読性と整合性を向上させる。
- Gate 1 Socratic: pass=true (追加質問 0 件)
- Gate 2 Consistency: PASS (ADR-0055 / 0051 / 0058 / 0062 / 0063 整合性 + Refines target 明示)
- Gate 3 Parallel Review: 3 vendor 出力は §改善余地 に要約
- Gate 4 Scoring: 43 / 50
| # | 採点項目 | 点数 | コメント |
|---|---|---|---|
| 1 | 問題定義 | 5 | 526件中489件(93%)不一致、内訳 113+376 と具体的数値。RQ-046 等の具体例とサイドバー render 仕様も提示され痛みの解像度が高い |
| 2 | 代替案 | 5 | X1 (何もしない) / X2 (逆方向) / X3 (rendering切詰) の 3 案 + 却下理由 + 評価軸×スコア表で加重和まで計算。網羅的 |
| 3 | 判断基準 | 5 | 5軸 + 係数 + 案件特有の解釈 + K.O. criterion 明示。加重和 0.945 vs 0.582 等で定量比較済 |
| 4 | 過去ADR整合性 | 4 | ADR-0055/0051/0058/0062/0063 を Confirms / Refines target で関係明示。ただし本 ADR 番号が '???' のまま未採番で参照困難 (本 PR で 0070 確定) |
| 5 | 影響範囲 | 4 | ファイル/モジュール/データ (title field) 明示。ただしステークホルダーは起案者単独 + Jr 言及のみで、PR レビュアーや CI 担当者の影響が不明 (本 PR §4.1 で 5 stakeholder + 影響表追加) |
| 6 | 運用上の罠 | 4 | allowlist false positive、WARN/ERROR 昇格基準あり。ただし title.replace(/^[A-Z]\.[\d.]+\d\s+/, '') 正規表現が全 NS パターン (I.01.4.14 等 4 階層) に対応するか未検証 (本 PR §2.2 で 9 サンプル node 検証結果表追加) |
| 7 | ロールバック性 | 4 | 判定指標 2 つ (利用者 FB ≥3件 / false positive >10%) と期限 (3ヶ月) あり。ただし Phase 1/2 で 489 件修正後の git revert やデータ復旧手順は明示なし (本 PR §5.2 で Phase 別ロールバック手順表追加) |
| 8 | コスト試算 | 3 | sub workspace 6-10h と数値あり。だが 489 件で 6-10h は 1 件 1 分換算で楽観的。Phase 2 の 376 件は『個別判断』要と自認しつつ平均判断時間 × 件数の積み上げ不在。R6 lint 実装工数も未計上 (本 PR §4.2 で詳細 breakdown: Phase 1 1.9-3.8h + Phase 2 31-63h + R6 lint 2-3h = 合計 35-70h、ROI 計算追加) |
| 9 | 完了条件 | 5 | 機械 (--check-r6) / 手動 (PR レビュー) / 移行進捗 (113→0, 489→0) の 3 層、Phase 毎の数値目標明確で観測可能 |
| 10 | 長期影響 | 4 | Review After 3ヶ月、grace period 6ヶ月。ただし Phase 2 完了時期の見積りがないため『Phase 2 完了 6 ヶ月後』に ERROR 昇格する条件の絶対時刻が不確定で半年後負債化リスク残 (本 PR §2.3 で Phase 2 想定完了 2026-10〜2027-02、Phase 3 ERROR 昇格 2027-04〜2027-08 の絶対時期追加) |
合計: 43 / 50 (Standard 閾値 40 → PASS, Critical 閾値 45 → marginal)
改善余地 (本 PR で全 5 件反映済)
| # | 指摘 | 反映先 | 効果 |
|---|---|---|---|
| 1 | 本 ADR 番号 '???' のまま未採番 | header line 1 を ADR-0070 で確定 | 過去ADR整合性 4/5 → 5/5 見込 |
| 2 | ステークホルダー: PR レビュアー + CI 担当者 不明 | §4.1 に 5 stakeholder 影響表追加 | 影響範囲 4/5 → 5/5 見込 |
| 3 | 正規表現 全 NS パターン未検証 | §2.2 に 9 サンプル node 検証結果表追加 (全 pass 確認) | 運用罠 4/5 → 5/5 見込 |
| 4 | 489 件修正後のロールバック手順なし | §5.2 に Phase 別 git revert / 部分撤退 / data 復旧手順追加 | ロールバック 4/5 → 5/5 見込 |
| 5 | cost 6-10h 楽観 / R6 lint 未計上 | §4.2 に詳細 breakdown (35-70h) + ROI 試算追加 | コスト試算 3/5 → 5/5 見込 |
| 6 | Phase 3 ERROR 昇格絶対時期不明 | §2.3 に Phase 2 想定完了 2026-10〜2027-02、Phase 3 ERROR 昇格 2027-04〜2027-08 追加 | 長期影響 4/5 → 5/5 見込 |
改善効果見込: 43/50 → 50/50 達成可能性。Critical 閾値 45 も余裕クリア。
Status 遷移
- v1 起案 (2026-05-26 12:30, sub session) → KV 投入 HTTP 201
- curl /chat/start → 180s timeout で Gate 1-4 未完走
- triageOnly curl → 13.5s で
needsAdr=true / triageMode=Light部分確認 - Web UI full audit (user 手動実行) → Standard 43/50 PASS、6 改善余地取得
- Status: Proposed → Accepted (本 PR で全 6 改善反映 + §8 audit history 追加)