• Status: Accepted (PR #1762 merge = 受理の規約により 2026-06-11 受理)
  • Mode: Standard
  • Kruchten Type: Executive/Property
  • Scope: platform
  • Implementation Status: In Progress (Phase 1 完了 2026-06-11: backfill 901 値 + 消費者切替 + frontmatter-meta-sync lint。残 = Phase 2 = 生成側 + 本文一括削除 + 規約文書改訂)
  • 起案者: [email protected]
  • 起案日時 (JST): 2026-06-11 17:01
  • 承認日時 (JST): 2026-06-11 18:05
  • Deciders: [email protected] (単独)

決定の早わかり(Y-statement)

本節は ADR-0140 の方針で遡及追加された本文の要約で、新しい意味は加えていない (意思決定内容は不変)。「文脈で問題に直面し、対抗案でなくこの案を選び、目的のため代償を受け入れる」と読む。詳細はコンテキスト以降の本文に展開する。

  • 文脈: ADR-0131 §5.3 が「属性側の統合は将来の別決定」と明記し、本 ADR がそれを行う。Phase 0 (common トリオ backfill + sync lint) は完了済みである。
  • 問題: ADR メタデータが本文太字メタ欄 (原本) と frontmatter (写し) の 2 箇所にあり、記載の無駄 (1 本あたり約 10 行)・drift の温床・設計の非対称が並存している。
  • 問題点と課題(直せる原因 → 発生を止めるためにやること):
    • 同じ情報を 2 回書き、status 以外は drift の機械検知がない → 原本を frontmatter に一本化し、移行中は sync lint を全フィールドへ拡張して防御する。
    • 「機械は frontmatter のみを読む」(ADR-0131) と「ADR メタは本文が原本」が非対称 → 機械消費者 6 系統の読み先を frontmatter へ切替する。
  • 前提(解決を課題に立てない与件):
    • CI が読めない期間が 1 コミットでも生じてはならない (二重保持期間を必ず設ける)。
    • 各メタフィールド (ADR-0030 / 0032 / 0049 / 0117 導入) の意味・運用は不変で、置き場所のみ移す。
  • 決定(対応策): 即時削除・現状維持・frontmatter 生成物化でなく、「①frontmatter へ複製 → ②機械の読み先を frontmatter へ切替 → ③本文太字メタ欄を削除」の 3 段階移行を採用する。
  • 目的: メタデータの原本が frontmatter に一本化され、drift の構造的原因が消え、Phase 2 完了で sync lint も撤去できる状態。
  • 代償: 消費者 6 系統 + 規約文書群の改訂 (約 3.0〜3.5 人日)。移行期間中は sync lint の維持が要る。PR の diff ビューでは太字メタ欄のような一目把握が失われる。
  • 詳細は本文の影響・撤退条件セクションを参照のこと

コンテキスト

§1.1 背景

ADR-0131 §5.3 は「frontmatter と太字メタ欄の二重管理は本決定では作らない (辺のみ frontmatter、Status 等は太字欄のまま)。属性側の統合は将来の別決定」と明記しており、本 ADR はその「将来の別決定」を行う。2026-06-11 の common トリオ (id/type/status) backfill 134 本 (PR #1761) と frontmatter-status-sync lint 導入によって Phase 0 は完了済みで、残り 6 フィールド (mode/kruchten/scope/implementation_status/proposed_at/approved_at/deciders) の二重記載解消が次の課題となっている。

§1.2 現状 (As-Is)

ADR メタデータ (Status/Mode/Kruchten Type/Scope/Implementation Status/起案日時/承認日時/Deciders) は本文冒頭の太字メタ欄 (原本) と frontmatter (写し) の 2 箇所に記載される。本文太字メタ欄を読む機械消費者は 6 系統:

  1. scripts/adr-index.mjs の META_RES (7 フィールド全部・ADR-0107 抽出器 SSoT)
  2. scripts/lib/adr-lint-rules.mjs の 8+ ルール (Mode 条件分岐・Status/Kruchten/Scope/Impl 検査)
  3. scripts/lib/adr_edges.mjs の STATUS_RE (edge-status-mismatch 検査)
  4. 遡及スクリプト群 (adr-edges-migrate.mjs / B_complete_adr_metadata.mjs / C_backfill_status_mode_scope.mjs — 役目終了済みで廃止候補)
  5. テスト fixture (tests/adr-index.test.mjs 等)
  6. 生成側: prompts/production/body-generation/prompt.md + drp/src/nodes/body_generation.ts の FALLBACK_PROMPT (一字一句同期規約・main 領分・merge = 即本番デプロイ)

現在は status 1 フィールドのみ sync lint で drift 防御し、残り 6 フィールドは frontmatter 未収載で機械は本文の正規表現抽出に依存している。

§1.3 課題

(1) 同じ情報を 2 回書く記載の無駄 (ADR 1 本あたり約 10 行)、(2) 片方だけ更新される drift の温床 (status 以外は機械検知なし)、(3) 「機械は frontmatter のみを読む」(ADR-0131) と「ADR メタは本文が原本」という設計の非対称、の 3 つの問題が並存している。

§1.4 制約・要件

  • CI が読めない期間が 1 コミットでも生じてはならない (二重保持期間を必ず設ける)。
  • 生成側変更は main 領分で merge = 即本番デプロイのため、prompt-cicd ゲート + golden eval を経由する。
  • 「機械は frontmatter のみを読む」(ADR-0131) を全メタデータへ拡張すること。
  • 人間可読性は docs サイト frontmatter チップ表示 (common/type/page 3 層・2026-06-11 実装済み) と GitHub 標準の frontmatter テーブル表示で代替する。
  • ADR-0030 / 0032 / 0049 / 0117 で導入された各メタフィールドの意味・運用は不変。

§1.5 目標 (To-Be)

メタデータの原本を frontmatter に一本化し、本文太字メタ欄を全 134 本から削除する。Non-Goals: 各メタフィールドの意味・必須性・運用フロー (Status flip / Impl Status 手動更新) の変更は行わない。

決定

「①frontmatter へ複製 → ②機械の読み先を frontmatter へ切替 → ③本文太字メタ欄を削除」の 3 段階移行を採用する。Phase 0 (common トリオ backfill + sync lint) は完了済み。Phase 1 で残り 6 フィールドを frontmatter へ機械 backfill し sync lint を全フィールドへ拡張、消費者 1〜5 を frontmatter 読みへ順次切替する。Phase 2 で生成側を新形式へ変更し本文太字メタ欄を一括削除、規約文書 (template.md / ADR-0123・0131 Corrigendum / ADR-0032 運用読み替え / README・writing-guide・decision_drivers_guide) を改訂する。二重保持期間中は sync lint で drift を防御し、Phase 2 完了で sync lint を撤去する。

判断基準 (Decision Drivers)

3.1 評価軸

#重要度 (係数)案件特有の解釈
1#reliable[Must] (×2.0)移行中・移行後に index/lint/生成が壊れないか。K.O.: CI が読めない期間が 1 コミットでも生じる案は不可
2#maintainable[Must] (×2.0)メタデータの置き場所が 1 箇所になり drift 検査が不要になるか
3#operable[High] (×1.0)起案者・受理者の運用 (Status flip 等) が複雑化しないか
4#efficient[Medium] (×0.5)移行の総工数が見合うか (消費者 6 系統の改修)

K.O. criterion: Must 軸 (#reliable / #maintainable) の score < 3 は不採用。

3.2 評価軸 × 案スコア表

係数採択案 (3 段階移行)案 A (即時削除)案 B (現状維持)案 C (frontmatter 生成物化)
#reliable×2.04052
#maintainable×2.05512
#operable×1.04142
#efficient×0.53553
加重和 (正規化)0.850.430.690.40
K.O. 通過 (Must ≥3)❌ (#reliable=0)❌ (#maintainable=1)❌ (#reliable=2, #maintainable=2)

検討した代替案 (Alternatives Considered)

  • 案 A: 本文太字メタ欄を即時削除 (検証・複製なし): 不採用。adr-lint 8+ ルール・adr-index・辺整合検査・DRP 生成が同時に壊れ、CI 全停止と新規 ADR 起案不能が確定 (#reliable K.O.)。
  • 案 B: 現状維持 (二重管理の恒久化): 不採用。sync lint を全 7 フィールドへ広げて恒久運用する道はあるが、記載の無駄と lint 維持コストが永続し ADR-0131 の「属性側の統合」を放棄する (#maintainable 不充足)。
  • 案 C: 本文を原本のまま、frontmatter を生成物にする (ビルド時に本文から自動生成): 不採用。frontmatter は git 上のファイル実体であり、生成物化すると「機械は frontmatter のみを読む」(ADR-0131) の前提が「機械は生成パイプライン経由でしか読めない」に劣化する。エディタ・GitHub 上での直接参照という frontmatter の利点も失う。
  • 案 D: 削除せず本文メタ欄を 1 行要約に縮退: 不採用 (主案に一部吸収)。表示は docs サイトのチップが既に担っており、縮退形を本文に残しても drift 対象は残る。

影響 (Consequences)

§5.1 正の影響 (Good)

  • メタデータの原本が frontmatter に一本化され、drift の構造的原因が消える。
  • ADR 1 本あたり約 10 行の重複記載が消える。
  • ADR-0131 の非対称設計 (辺は frontmatter・属性は本文) が解消され「機械は frontmatter のみを読む」が全メタデータで成立する。
  • Phase 2 完了で sync lint を撤去でき、lint 維持コストが減る。

§5.2 負の影響 (Bad)

  • 消費者 6 系統 + 規約文書群 (template.md / ADR-0123・0131 Corrigendum / ADR-0032 運用読み替え / README・writing-guide・decision_drivers_guide) の改訂が必要。
  • 生成側の変更は main 領分で merge = 即本番デプロイのため、審査 run 非実行中の確認と golden eval が必要。
  • 移行期間中は sync lint の維持が必要 (Phase 2 完了で撤去)。
  • 多値フィールド (deciders 等) を YAML 配列で backfill すると、META_RES がカンマ区切り文字列を抽出している現行設計と非互換になり、lint-rules.mjs の .trim() や文字列比較で TypeError が連鎖する可能性がある。本 ADR の方針は 多値フィールドも文字列 (カンマ区切り) で frontmatter に格納し、配列化は将来の別決定とする。Phase 1 着手前に lint-rules.mjs の型依存箇所をリストアップし、文字列前提の互換性を機械検査する。
  • GitHub PR の Files Changed (diff) ビューでは frontmatter が YAML テキストとして表示され、太字メタ欄のような一目把握が失われる。docs サイトチップ・GitHub の Markdown プレビュータブ・frontmatter テーブル表示はいずれも diff ビューでは機能しない。受け入れ可否は Phase 1 着手前にレビュアー (ADR 受理者) にヒアリングし、受け入れ不可の場合は PR テンプレートへのメタサマリー自動挿入を代替手段として検討する (Phase 1 完了時 (受理後 4 週) までに結論)。
  • 監査・内部統制レビューで frontmatter が承認証跡として認められない場合、全 134 本の再編集対応が発生する。Phase 1 着手前に社内変更管理規程の担当部門 (現時点で対応部門未確定。受理後 2 週以内に管理本部へ照会) に frontmatter を承認記録として扱えるか確認する。
  • 「Accepted 済み ADR の本文一括削除」は ADR-0031 が許容する誤字修正範疇 (意味不変の機械的編集) の逆操作にあたり、適用拡大の先例になりうる。Phase 2 着手前に 5〜10 本のサンプル削除 PR で異議申し立ての有無を確認する (撤退条件 3 と接続)。

§5.3 中立・トレードオフ (Neutral / Trade-offs)

  • Status flip (Proposed→Accepted) や Implementation Status の手動更新は、本文編集から frontmatter 編集に変わるだけで運用フローは不変。
  • 消費者切替を 1 PR ごとに進める設計では「adr-index は frontmatter / lint-rules は本文」のような読み先混在期間が発生する。これは「片方が生きている」とは別事象であり、特定フィールドの lint チェックが一時的に無効化されうる。緩和策: Phase 1 開始時に消費者切替順序と各ステップで有効な lint ルールの対応表を実装計画に添付し、可能な範囲で全 8 ルールをフィーチャーフラグ (環境変数 ADR_LINT_FRONTMATTER_FIRST=1) で一括切替できる実装方式を採る (中間状態を 1 コミットに圧縮)。
  • 撤退条件 1 のロールバックは「消費者切替の進捗段階」によって所要時間が変わる (1 系統切替なら 1 PR revert / 4 系統切替なら 4 PR revert)。沈没費用バイアスを避けるため撤退条件 1 で段階別の revert 手順を明示する。

撤退条件 (Rollback Plan)

  1. Phase 1 の消費者切替後 2 週以内に、frontmatter 起因の index 欠落・lint 誤検知が計 5 件超発生したら、読み先を本文へ戻し移行を中断する。段階別 revert 手順: (a) 1 系統切替時点 = 該当 PR 1 本を git revert、所要 15 分。(b) 2〜3 系統切替時点 = 該当 PR を逆順に revert、所要 30〜45 分。(c) 4 系統以上切替時点 = フィーチャーフラグ ADR_LINT_FRONTMATTER_FIRST=0 への一括戻し PR 1 本、所要 30 分。担当: 起案者。
  2. Phase 2 の生成側変更後、最初のパイプライン生成 ADR PR が新形式起因で adr-lint fail したら、生成側を旧形式へ即時ロールバックする (prompt-cicd の revert 1 PR)。2 回連続で fail したら Phase 2 を中断し本 ADR を見直す。事前手順: Phase 2 着手前にパイプライン生成 PR のキューを空にしてから prompt 変更をマージする。複数 PR が同時 fail した場合は最古の PR を優先調査、エスカレーション先 = 起案者 → DRP 主担当 (現状 [email protected] 兼任)。
  3. 本文太字メタ欄の一括削除後 4 週以内に「本文側メタが無くて困る」実害 (監査・レビューでの参照不能等) が 2 件以上報告されたら、案 D (1 行要約の復元) へ縮退する。Phase 2 一括削除の直前に 5〜10 本のサンプル削除 PR を出し、1 週間異議がないことを確認したうえで本実行する。
  4. Phase 1 着手が受理後 4 週以内に始まらなければ、二重管理が常態化するため本 ADR を見直す (ADR-0132 撤退条件 4 と同型)。

コスト試算

  • Phase 1 (sub 中心):
    • 残り属性 backfill スクリプト + sync lint 拡張: 0.5 人日
    • 消費者切替 (adr-index META_RES / lint-rules 8 ルール / adr_edges / tests): 約 1 人日
    • 遡及スクリプト 3 本の廃止判断: 0.1 人日
    • 追加計上 (Phase 1): lint-rules.mjs 8 ルールの条件分岐書き換えと境界値テスト更新、frontmatter 型依存箇所の機械検査スクリプト: +0.3 人日 (最悪 +0.6 人日)
  • Phase 2 (main + sub):
    • 生成側 (prompt.md + FALLBACK 同期 + promptfoo/golden eval): 約 0.5 人日 (main)
    • 本文太字メタ欄の一括削除スクリプト + 実行 (サンプル 5〜10 本先行 + 本実行): 0.25 人日
    • 規約文書改訂 (テンプレ / Corrigendum 2 本 / ガイド 3 本): 0.5 人日 (sub)
    • 追加計上 (Phase 2): golden eval の合格基準再定義 (生成形式変更に伴う): +0.2 人日 (最悪 +0.4 人日)
  • 合計: 約 3.0〜3.5 人日 (最悪上限 4.0 人日)
  • 根拠 = 起案前の網羅 grep 調査で消費者 6 系統と改修点を実数把握済み。類似実績: ADR-0131 辺移行が調査込み同規模 (ただし lint ルール条件分岐の書き換えは ADR-0131 では発生していないため上振れ要因として上限値に反映)。
  • 直接金銭支出: 0 円 (golden eval の LLM 従量 ~数百円/run のみ)

Confirmation

  • 検証手段:
    • (a) adr-index.json の null フィールド数 (機械抽出の欠落検知・現状 0 を維持)
    • (b) frontmatter-status-sync 拡張 lint の違反数 = 0
    • (c) Phase 2 完了後に本文太字メタ欄の残存数 = 0 (grep -c '^\- \*\*Status\*\*:' docs/adr/*.md 相当の機械検査を adr-lint へ追加)
    • (d) lint-rules.mjs の frontmatter 型依存箇所の機械検査 (Phase 1 着手時に追加し TypeError 連鎖を未然検知)
    • (e) ADR-0031 適用範囲拡大についてレビュアー (ADR 受理者) からの明示合意取得記録 (Phase 2 着手前)
  • 実行頻度: (a)(b)(d) は CI (PR 毎)。(c) は Phase 2 完了時に 1 回 + 以後 CI 常設。(e) は Phase 2 着手前に 1 回。
  • 違反時対応: 撤退条件 1〜3 の該当判定。(d) 違反時は Phase 1 中断 + 型設計再検討。(e) 合意未取得の場合は Phase 2 着手延期。
  • KPI / 移行完了の定義: 消費者 6 系統すべてが frontmatter 読み + 太字メタ欄残存 0 本 + sync lint 撤去済み (二重管理期間の終了)。目標期日 = 受理後 8 週以内 (Phase 1 が 4 週・Phase 2 が 4 週)。

参照 (References)

  • 関連 ADR:
    • ADR-0131 (Refine): §5.3 が明示した「属性側の統合は将来の別決定」の行き先。「機械は frontmatter のみを読む」原則を全メタデータへ拡張する。受理時に 0131 へ Corrigendum で逆参照を追記する。
    • ADR-0123 (補完): frontmatter 3 層モデル (common/type/page) の docs/adr への適用を完成させる。
    • ADR-0030 / 0032 / 0049 / 0117 (補完): 各メタフィールド (Kruchten/Implementation Status/Scope/Covers) の導入決定。意味・運用は不変で置き場所のみ frontmatter へ移る (0032 の手動更新運用は frontmatter 編集に読み替え)。
    • ADR-0031 (依拠): 業界標準メタデータの遡及追加 = 誤字修正範疇の先例。本 ADR の一括削除は同範疇の逆操作 (機械的・意味不変) として依拠する。
  • 関連 PR/Issue: PR #1761 (Phase 0 実装: common トリオ backfill + sync lint)
  • 外部資料: -

実装記録 (Phase 1・2026-06-11)

本 ADR は immutable。本節は ADR-0031 corrigendum 方式による実装後の追記で、決定本文は変更しない。

実装内容 (1 PR に圧縮 = §5.3 緩和策の「中間状態を 1 コミットに圧縮」):

  1. backfill: 全 138 本へ 7 キーを機械複製 (901 値・存在する本文メタ行のみ・捏造なし)。全値 JSON 互換の二重引用符 (: / # を含む値の YAML パーサ差異対策)。gray-matter での全数パース (901 値すべて文字列) を検証済み。
  2. 読み出し層: scripts/lib/adr_meta.mjs 新設 (pure module・依存ゼロ)。全消費者がここを経由する。
  3. sync lint: frontmatter-meta-sync (error) を adr-lint #23 として新設 — 7 キーの frontmatter ⇔ 本文一致 + 文字列型強制 (YAML 配列禁止 = Confirmation d の機械検査)。
  4. 廃止判断: 遡及スクリプト 3 本 (adr-edges-migrate / B_complete_adr_metadata / C_backfill_status_mode_scope) を削除 (役目終了済み + 機械再生成の再実行が手動辺・全数再レビュー結果を上書きする事故リスクの除去。git 履歴で復元可能)。

消費者切替の対応表 (フラグ ADR_LINT_FRONTMATTER_FIRST・既定 ON・false で一括ロールバック = 撤退条件 1c):

消費者切替後の読み先フラグ false 時有効な lint
adr-index.mjs (旧 META_RES)frontmatter 優先 → 本文フォールバック本文のみadr-index --check + 完全性テスト
adr-lint-rules.mjs Mode 分岐 6 ルール + 存在検査 4 ルール同上本文のみ各ルール自体 + frontmatter-meta-sync
adr_edges.mjs statusOf本文優先 (status 特例・下記)同左edge-status-mismatch
テスト fixture両形式を試験 (fm 優先 / 本文のみ / fm のみ)adr-index.test / adr-lint-rules.test

本文フォールバックを残す理由: (a) パイプライン生成直後の ADR は frontmatter メタ未収載 (生成側対応 = Phase 2・main 領分)、(b) triage 起案前ゲートの synthetic draft は本文形式のみ。切替は読み先の優先順位の変更であり、二重保持期間中はどちらを読んでも同値 (sync lint #23 が保証)。切替前後で adr-index.json / INDEX.md の出力が両フラグ状態で完全一致することを確認済み。

PR diff ビュー可読性のヒアリング (§5.2 の事前確認): 2026-06-11、レビュアー (ADR 受理者 = 代表取締役) が「diff のままで構わない」と受け入れを表明。代替策 (PR テンプレートへのメタサマリー自動挿入) は実施しない。

status の特例 (Phase 2 への申し送り): status は本文優先のまま据え置いた。frontmatter の status は正規化値 (ADR-0123 値域) で、本文 raw が持つ注釈 — 受理 PR 番号 (Accepted (PR #N merge = 受理...)) / accepted-with-residual-risks タグ (ADR-0109・residual-risks-status-tag lint が参照) / Superseded by ADR-NNNN の置換先 (edge-status-mismatch が参照) — を保持できないため。Phase 2 の本文一括削除前に、これら注釈の frontmatter 上の置き場所 (例: status_note キー) を決める必要がある。同様に起案者行は本決定の 7 キーに含まれていない (Deciders と実質重複) ため、Phase 2 の削除時に廃止か frontmatter 追加かを決める。