型付き辺: 出 10 / 入 0
ADR-0038: adr-lint.mjs にメタデータ規約 6 ルールを追加 — Confirmation 形骸化を CI で自動検出
- Status: Accepted
- Mode: Standard
- Kruchten Type: Property/Executive
- Scope: platform
- Implementation Status: Done (PR #721)
- 起案者: [email protected]
- 起案日時 (JST): 2026-05-14 02:56
- 承認日時 (JST): 2026-05-14 03:14
- Deciders: [email protected] (単独)
1. コンテキスト
1.1 背景 (Background)
ADR-0036 (Accepted 2026-05-14) で ADR テンプレに Confirmation セクション必須化を採用し、各 ADR の fitness function を 3 要素 (検証手段 / 実行頻度 / 違反時の対応) で記述する運用を開始した。しかし ADR-0036 実装プロンプト (tasks/prompts/impl_adr-0036_confirmation_section.md) 作成時に scripts/adr-lint.mjs の実カバレッジを精査したところ、現状 5 ルール (numbered-header / context-section / decision-section / no-placeholder / min-length) のみで、メタ ADR が定めた規約の大半が lint で未強制であることが判明した。
結果: ADR-0036 §2.3 検証手段マッピングで 5 件のメタ ADR (ADR-0023 / 0024 / 0030 / 0031 / 0032) の Confirmation が「手動レビューのみ」となり、PR #703 で Claude が指摘した形骸化リスクが構造的に残る状態。具体的には:
- ADR-0023 (リポ構造): ファイル配置
docs/adr/限定 + 4 桁連番 + kebab-case 命名規約 → lint 未実装 - ADR-0024 (テンプレ構造): 全 6 必須 H2 セクション (コンテキスト / 決定 / 検討した代替案 / 影響 / 撤退条件 / 参照) の存在 + 順序 → lint は 2 セクションのみカバー
- ADR-0030 (Kruchten 分類): メタデータに
Kruchten Type: (Existence|Property|Executive)存在 → lint 未実装 - ADR-0031 (遡及追加許可): 遡及追加箇所に corrigendum 注記行 (
> *本セクションは ADR-NNNN で遡及追加された) の併記 → lint 未実装 - ADR-0032 (Implementation Status): メタデータに
Implementation Status: (Not Started|In Progress|Done|N/A)存在 + enum 値 → lint 未実装 - ADR-0036 (Confirmation セクション):
## Confirmation存在 → lint 未実装 (本日 Accepted)
1.2 現状 (Current State / As-Is)
scripts/adr-lint.mjsの RULES 配列に登録された規則数: 5 (line 11-37)- 全 ADR 数: 37 本 (ADR-0000〜0036、ADR-0037 マージ進行中)
- 上記 6 ルールでチェックすべき ADR 件数: ADR-0023 が制定する命名規約は 全 37 ADR が対象、ADR-0024 のテンプレ規約も 全 37 ADR 対象、Kruchten Type は ADR-0030 以降 (8 ADR)、Implementation Status は ADR-0032 以降 (6 ADR)
- 現状 lint pass 率: 37/37 (100%) ※ ただしカバレッジが薄いため実態は不明、実カバレッジ向上後の pass 率は不明
- 月次振り返り (本日 2026-05-14 初回): Confirmation 形骸化サンプリングで「scripts/adr-lint.mjs と書いてあるが lint で実検証されていない」を 5 件確認 (ADR-0023/0024/0030/0031/0032)
1.3 課題 (Problem)
- Confirmation 形骸化の構造的継続: ADR-0036 で Confirmation 必須化したが、各 ADR の検証手段に「scripts/adr-lint.mjs」と書いても実際の lint 規則が存在しないため、書いた瞬間から形骸化
- 既存 37 ADR のメタデータ品質ばらつき: ADR-0030 (Kruchten) 採用前の ADR-0000〜0029 にはフィールド不在、ADR-0031 遡及で付与した ADR と未遡及 ADR が混在、人間レビューで全件確認は非現実的
- 新規 ADR 起案時の規約遵守バラつき: Pipeline body_generation.ts は新規 ADR にメタデータを自動付与するが、付与漏れの即時検出機構がない (起案者が PR 段階で気付くまでラグ)
- ADR-0036 完了条件 #4 の信頼性低下:
for f in docs/adr/00[0-3][0-9]-*.md; do grep -q '^## Confirmation' "$f"; doneで## Confirmation存在は確認できるが、内容の妥当性 (3 要素揃っているか / N/A の理由明記など) は未検証
1.4 制約・要件 (Constraints & Requirements)
- ADR-0036 本文は不変 (Accepted 後のイミュータブル原則)、本 ADR は ADR-0036 の補完 (Supersede 関係ではなく、ADR-0036 の MAPPING で「手動レビューのみ」とした検証手段を adr-lint.mjs に格上げ)
- 既存 37 ADR への遡及補完: 新ルール導入前に ADR-0036 Python スクリプト (Step 4) を活用してメタデータ不在 ADR への一括補完を完了させる順序にする (lint 有効化時に初日 fail を回避)
- 単一 lint スクリプトで完結 (新規ツール導入なし、adr-kit / ArchUnit 等は別 ADR で検討)
- 実装規模 ≤ 3 時間 (RULES 配列に 6 ルール追加 + テスト用 fixture + CI workflow 更新)
- 既存 5 ルールは破壊しない (RULES 配列に append のみ、既存 ID 再利用なし)
1.5 目標 (Goals / To-Be)
scripts/adr-lint.mjsに 6 ルール追加し、メタ ADR (0023/0024/0030/0031/0032/0036) の規約を CI で自動検証- ADR-0036 §2.3 MAPPING の 5 件のメタ ADR Confirmation を「手動レビューのみ」→ 「scripts/adr-lint.mjs (実カバー済) + 手動レビュー (lint 範囲外)」に更新
- 形骸化率測定: ADR-0036 §影響 §7 観測指標「Confirmation 形骸化率 (実検証なし)」を月次 < 10% に維持 (本 ADR 採用で形骸化案件を構造的に削減)
- 新規 ADR 起案時に PR で即時 fail することで、起案者の認知負荷 (形式不備の後追い修正) を削減
2. 決定
scripts/adr-lint.mjs の RULES 配列にメタ ADR 規約 6 ルール (filename-pattern / template-sections / confirmation-section / kruchten-type-meta / implementation-status-meta / corrigendum-marker) を append し、CI workflow で PR ごとに自動実行する。導入前に既存 37 ADR へメタデータ補完を一括実施 (ADR-0036 Step 4 スクリプト派生 + ADR-0031 corrigendum パターン準拠) し、初日 fail を回避。Accepted + lint 拡張完了後、ADR-0036 MAPPING の 5 メタ ADR Confirmation を「手動レビューのみ」→「scripts/adr-lint.mjs + 手動レビュー (lint 範囲外)」に更新する。
2.1 scripts/adr-lint.mjs の RULES 配列に 6 ルール追加
既存 RULES 配列の末尾に以下を追加 (各約 10-15 行、合計約 90 行):
{
id: 'filename-pattern',
desc: 'ファイル名が 4 桁連番 + kebab-case (ADR-0023)',
check: (src, filePath) => /^\d{4}-[a-z0-9-]+\.md$/.test(filePath.split('/').pop()),
},
{
id: 'template-sections',
desc: '必須 H2 セクション 6 種が順序通りに存在 (ADR-0024)',
check: (src) => {
const required = ['コンテキスト', '決定', '検討した代替案|代替案', '影響', '撤退条件', '参照'];
let lastIdx = -1;
for (const sec of required) {
const m = new RegExp(`^##\\s*(${sec})`, 'm').exec(src);
if (!m || m.index < lastIdx) return false;
lastIdx = m.index;
}
return true;
},
},
{
id: 'confirmation-section',
desc: 'Confirmation セクションが存在 (ADR-0036)',
check: (src) => /^##\s*Confirmation/m.test(src),
},
{
id: 'kruchten-type-meta',
desc: 'メタデータに Kruchten Type フィールドが存在 (ADR-0030)',
check: (src) => /^-\s+\*\*Kruchten Type\*\*:\s+(Existence|Property|Executive)/m.test(src),
},
{
id: 'implementation-status-meta',
desc: 'メタデータに Implementation Status フィールドが存在 (ADR-0032)',
check: (src) => /^-\s+\*\*Implementation Status\*\*:\s+(Not Started|In Progress|Done|N\/A)/m.test(src),
},
{
id: 'corrigendum-marker',
desc: '遡及追加箇所に corrigendum 注記行が併記 (ADR-0031)',
check: (src) => {
const hasRetroactive = /遡及追加|retroactively added/i.test(src);
if (!hasRetroactive) return true;
return /\*本.*ADR-\d{4}.*で遡及追加/m.test(src);
},
},
2.2 既存 37 ADR の補完 (本実装の事前作業)
ADR-0036 §2.3 Python スクリプト (scripts/B_add_confirmation_section.py) の処理範囲を拡張し、以下を一括処理:
- メタデータに
Kruchten Type/Implementation Statusフィールド欠落 → デフォルト値 (例:Property/Done/N/A) を ADR-0031 corrigendum パターンで追記 - 遡及追加された箇所 (Confirmation セクション等) に corrigendum 注記行を併記
- ファイル名が 4 桁連番 + kebab-case 形式に違反する場合 → 別途 PR で rename (ADR-0023 イミュータブル原則違反候補、慎重判断)
2.3 CI workflow 統合
.github/workflows/adr-lint.yml (新規) または既存 markdown-link-check.yml に lint 実行 step 追加:
- name: ADR lint
run: node scripts/adr-lint.mjs docs/adr/
PR ごと自動実行、違反時は CI fail で起案者にフィードバック。
2.4 ADR-0036 MAPPING の更新 (事後作業)
本 ADR Accepted + lint 拡張完了後、tasks/prompts/impl_adr-0036_confirmation_section.md の MAPPING dict を「手動レビューのみ」→「scripts/adr-lint.mjs + 手動レビュー (lint 範囲外)」に更新。
2.5 判断基準 (重み付き)
- Confirmation 形骸化の構造的防止 (最重要)
- 既存 lint 資産の最大活用 (高) — 5 → 11 ルールへ拡張のみ
- 新規 ADR の即時フィードバック (高)
- 既存 ADR への影響最小化 (中) — 事前補完で初日 fail を回避
3. 検討した代替案 (Alternatives Considered)
- 案 A (採用):
scripts/adr-lint.mjsに 6 ルール追加 — 既存 lint 資産を最大活用、新規ツール導入なし、実装規模 2-3 時間。PR ごと CI fail で起案者への即時フィードバック、形骸化を構造的に防止。Bad: 既存 37 ADR に補完が必要 (約 1 時間)、corrigendum-markerルールは grep ベースで偽陽性・偽陰性リスクあり人間レビュー併用必須。 - 案 B: 6 ルールを個別 ADR で 6 件起案 (ADR-0038〜0043) — 不採用理由: 起案コストが 6 倍 (本 ADR 約 1h × 6 = 6h)、ADR 数の急増で読解負荷増、Stage 1-2 ワークフロー (ADR-0034) の D1 → A5 通過時間が悪化。
- 案 C: adr-kit / ArchUnit 等の外部ツール導入 — 不採用理由: 導入コスト過大 (推定 16h)、bizlp 規模 (37 ADR + Jr 1 名予定) に過剰投資。ADR-0036 §7 で 6 ヶ月後の検討課題として明記済。
- 案 D: 現状維持 (Confirmation 形骸化を月次レビュー + 手動チェックのみで対応) — 不採用理由: PR #703 で Claude が指摘した形骸化リスクが構造的に継続、Jr 入社後の独学コスト増。
- 案 E: 手動チェックリスト化 (テンプレに「PR 起案時に手動で 6 項目確認」を明記、CI 強制ゼロ) — 不採用理由: CI 強制がないため形骸化リスクは現状とほぼ同じ、起案者の認知負荷も毎回 6 項目の手動確認で増える。
4. コスト試算
| 項目 | 工数 | 金額 |
|---|---|---|
| 6 ルール実装 (RULES 配列 + lintFile filePath 引数追加) | 1.5 h | $0 |
| CI workflow 統合 | 0.5 h | $0 |
| 既存 37 ADR への補完 (Python スクリプト拡張、ADR-0036 Step 4 派生) | 1.0 h | $0 |
| 動作確認 (全 ADR で lint pass 確認) + デプロイ | 0.5 h | $0 |
| ADR-0038 起案 + Accepted + マージ | 1 h | $3 |
| 合計 | 約 4.5 時間 | 約 $3 (≈ [MASKED:AMOUNT]) |
機会費用換算: 4.5 h × Jr 想定時給 [MASKED:AMOUNT]/h = [MASKED:AMOUNT] + LLM [MASKED:AMOUNT] ≈ [MASKED:AMOUNT] 投資
年間削減効果:
- Confirmation 形骸化検出の手動コスト削減: 月 30 分 × 12 ヶ月 = 年 6 時間 × [MASKED:AMOUNT]/h = [MASKED:AMOUNT]/年
- 新規 ADR の規約不備修正リードタイム短縮: 年 5-10 件 × 15 分 × [MASKED:AMOUNT]/h = [MASKED:AMOUNT]-10,000/年
- Jr オンボーディング時の規約学習コスト削減: Jr 1 人 × 2 時間 × [MASKED:AMOUNT]/h = [MASKED:AMOUNT] (一時)
- 合計: 年 [MASKED:AMOUNT]-34,000 削減見込み + 初回 [MASKED:AMOUNT] (投資回収約 6-7 ヶ月)
5. 影響 (Consequences)
5.1 正の影響 (Good)
- Existence 影響: RULES 配列に 6 ルール追加 (filename-pattern / template-sections / confirmation-section / kruchten-type-meta / implementation-status-meta / corrigendum-marker)、
.github/workflows/adr-lint.yml(新規 or 既存 workflow への step 追加) - Property 影響: 全 37 ADR + 新規 ADR に対し、ADR-0023/0024/0030/0031/0032/0036 が定めた規約を CI 強制で横断適用
- Executive 影響: lint ツールに adr-kit / ArchUnit 等の外部導入を選択せず、自製
scripts/adr-lint.mjsの拡張で完結する方針を確定 - ADR-0036 §2.3 MAPPING の 5 件メタ ADR Confirmation を「手動レビューのみ」→「実検証付き」に格上げし、形骸化を構造的に防止
- 新規 ADR 起案者は PR ごと即時フィードバックを得られ、形式不備の後追い修正の認知負荷を削減
- Jr 入社時 (2026-10 予定) の規約学習が lint 結果から自動で得られ、オンボーディングコスト約 2 時間削減
5.2 負の影響 (Bad)
- 既存 37 ADR の補完コスト約 1.5 時間が事前に必要 (ADR-0036 Step 4 スクリプト拡張で吸収)
corrigendum-markerルールは「遡及追加|retroactively added」を grep ベースで検出するため偽陽性・偽陰性リスクあり、人間レビューを併用必須- ファイル名が ADR-0023 規約違反の旧 ADR は理論上 rename 必要だがイミュータブル原則と衝突、現実的には旧ファイルを残し新ルール対象外フラグで除外する妥協が必要
- lint 規則 5 → 11 への倍増で、長期的に adr-lint.mjs がモノリス化するリスク (6 ヶ月後の課題、§7 で言及)
5.3 中立・トレードオフ (Neutral / Trade-offs)
- 本 ADR は ADR-0036 の補完であり Supersede ではない (ADR-0036 本文は不変、MAPPING のみ後続作業で更新)
- 厳格な enforcement が起案者にとって過剰負荷となった場合、§撤退条件の閾値で warning 化 (fail させず log のみ) への段階的緩和が可能
- 本実装の変更ファイル:
scripts/adr-lint.mjs(+95 行)、.github/workflows/adr-lint.yml(新規、+10 行)、tasks/prompts/impl_adr-0036_confirmation_section.md(約 +10 行修正)、既存 37 ADR (メタデータ補完、Python スクリプト一括) - 不変対象: 既存 5 lint ルール (append のみ)、ADR-0001〜0037 の本文意思決定内容 (メタデータ補完のみ)、scripts/4_review_specs_by_gemini.js / Pipeline Gate 2 / 既存テスト
6. Confirmation (準拠確認 / Fitness Function)
6.1 検証手段
- 自動 (主):
node scripts/adr-lint.mjs docs/adr/を CI (.github/workflows/adr-lint.yml) で実行。RULES 配列に 6 ルールが登録されていること、および全 ADR が PASS することを継続検証 - 自動 (補助):
grep -cE "filename-pattern|template-sections|confirmation-section|kruchten-type-meta|implementation-status-meta|corrigendum-marker" scripts/adr-lint.mjsの出力 = 6 - 自動 (補助):
grep -c "adr-lint.mjs" .github/workflows/*.ymlの出力 >= 1 - 手動: 月次振り返りで偽陽性・偽陰性件数を確認 (特に
corrigendum-markerの grep ベース判定の精度)、ADR-0036 MAPPING 更新済か目視確認
6.2 実行頻度
- 自動 lint: PR ごと (push / pull_request トリガ)
- メトリクス測定: 月次 (Confirmation 形骸化率、新規 ADR lint fail 件数、既存 ADR pass 率)
- Review After 集中レビュー: 1 ヶ月後 (2026-06-14) / 3 ヶ月後 (2026-08-14) / 6 ヶ月後 (2026-11-14)
6.3 違反時の対応
- CI fail (新規 ADR): 起案者が PR 内で即時修正、マージブロック
- CI fail (既存 ADR): 該当 ADR について ADR-0031 corrigendum パターンで遡及補完 PR を起案
Status / Mode / Scope は 2026-06-11 に遡及追加 (ADR-0031 corrigendum パターン)。出典: Status = 旧形式「## ステータス」節の機械転記 / Mode = 旧 README §既存 ADR 一覧の推定値 (git 履歴) / Scope = ADR-0049 4 層分類の遡及付与 (PR レビューで確定)。
- 偽陽性報告 (月 3 件超): §撤退条件に基づき該当ルールの check 関数改善 or 範囲縮小
- 形骸化率 > 10% が 6 ヶ月継続: §撤退条件に基づき adr-kit / ArchUnit 等の外部ツール移行を別 ADR で検討
7. 完了条件 (定量メトリクス)
- RULES 配列に 6 ルール追加:
grep -cE "filename-pattern|template-sections|confirmation-section|kruchten-type-meta|implementation-status-meta|corrigendum-marker" scripts/adr-lint.mjs→ 6 - 既存 37 ADR で全件 PASS:
node scripts/adr-lint.mjs docs/adr/→ 100% pass - CI workflow 統合済:
grep -c "adr-lint.mjs" .github/workflows/*.yml→ >= 1 - ADR-0036 MAPPING 更新済:
tasks/prompts/impl_adr-0036_confirmation_section.mdの 5 メタ ADR 行で「手動レビューのみ」→「adr-lint.mjs + 手動レビュー」に変更 - 新規 ADR PR で CI fail テスト: 故意に Kruchten Type 欠落 ADR を起案 → PR で adr-lint.mjs が fail することを確認
- CI markdown-link-check PASS / TypeScript build PASS
8. 撤退条件 (Rollback Plan)
| 判定指標 | 閾値 | 判定タイミング | 対応 |
|---|---|---|---|
| 既存 ADR で予期せぬ fail が頻発 | lint 有効化後 1 週間で fail 5 件以上 | デプロイ直後 + 週次 | 該当ルールを RULES 配列から temporal disable、補完スクリプトで対応 |
| 起案者の認知負荷増加 | 月 1on1 で「lint 制約がうざい」評価 2 ヶ月連続 | 月次振り返り | 厳格すぎるルールを warning 化 (fail させず log のみ)、段階的 enforcement |
| 偽陽性が頻発 (誤検出) | 月 3 件超の「lint fail だが実は規約準拠」報告 | 月次振り返り | 該当ルールの check 関数を改善 or 範囲を縮小 |
| Confirmation 形骸化率が改善しない | 6 ヶ月後 lint 拡張後も形骸化率 > 10% | 6 ヶ月後 Review After | adr-kit / ArchUnit 等の外部ツール導入を別 ADR で検討 |
9. 長期影響
6 ヶ月後の負債化リスク:
- lint 規則の肥大化: 各メタ ADR が追加ルールを要求し続けると adr-lint.mjs が単一モノリスファイル化 → ルールごとに別ファイル分割 (例:
scripts/adr-lint/rules/*.mjs) を別 ADR で検討 - 規則の偽陽性蓄積: 業務ロジック ADR では適用しない方が良いルールが混入 → ルールのカテゴリ別タグ付け + 適用範囲フィルタを別 ADR で検討
- adr-kit / ArchUnit 等への移行: 6 ヶ月後の Review After で形骸化率改善が頭打ちなら外部ツール導入 (ADR-0036 §7 と整合)
観測指標 (月次):
- adr-lint.mjs 拡張ルールの fail 検出件数 (新規 ADR PR): 目標 月次平均 ≤ 1 件
- Confirmation 形骸化率: 目標 月次 < 10% (ADR-0036 §影響 §7 と整合)
- 既存 ADR の lint pass 率: 目標 100% 維持
- 新規 ADR 起案時のメタデータ補完リードタイム: 目標 PR 作成から 5 分以内
Review After:
- 1 ヶ月後 (2026-06-14): 新規 ADR 1-2 本で lint 動作確認、偽陽性チェック
- 3 ヶ月後 (2026-08-14): 形骸化率測定、ルール追加・修正要否判定
- 6 ヶ月後 (2026-11-14): adr-kit / ArchUnit 移行検討、Jr 入社後の運用感ヒアリング
10. 参照 (References)
- 関連 ADR:
- ADR-0023 (リポ構造 / ファイル命名規約) — 補完対象
- ADR-0024 (テンプレ構造 / 必須 H2 セクション) — 補完対象
- ADR-0030 (Kruchten 分類) — 補完対象
- ADR-0031 (遡及追加許可 / corrigendum パターン) — 補完対象、本 ADR の補完作業の根拠
- ADR-0032 (Implementation Status) — 補完対象
- ADR-0034 (Stage 1-2 ワークフロー) — 案 B 不採用理由の根拠
- ADR-0036 (Confirmation セクション必須化) — 本 ADR の親 ADR、MAPPING 更新対象
- 関連 PR/Issue:
- PR #703 (Claude による Confirmation 形骸化リスク指摘) — (要追記: PR URL)
tasks/prompts/impl_adr-0036_confirmation_section.md— 事後更新対象
- 外部資料:
- adr-kit / ArchUnit — 6 ヶ月後の代替案検討候補 (本 ADR では不採用)