型付き辺: 出 4 / 入 0
ADR-0148: パイプライン生成 ADR の型付き辺と相手側逆辺・status 変更を autofix で自動反映する
- Status: Accepted (PR #1918 merge = 受理の規約により 2026-06-13 受理・代表取締役判断)
- Mode: Standard
- Kruchten Type: Executive/Property
- Scope: platform
- Implementation Status: Done
- 起案者: [email protected]
- 起案日時 (JST): 2026-06-13 00:18
- 承認日時 (JST): 2026-06-13 00:34
- Approver Role: platform
- Approver Who: [email protected]
- Driver: [email protected]
- Consulted: Decision Pipeline AI 審査 (Gate 0-4)
コンテキスト
§1.1 背景
ADR-0131 は型付き辺のグラフ衛生規約として「辺を張ったら相手側の逆辺・status 変更を同一 PR で」を定め、adr-lint の --check-edges --enforce で機械検査が CI 稼働中である。一方、パイプライン生成 ADR は本文「参照 (References)」に型付き辺の宣言 (supersedes/amends/relates_to) を書く一方で、frontmatter の辺キーは全て空配列のまま出力され、相手側 ADR の書き換えも誰も自動化していないため、受理のたびに人間が手作業で後修正している。
§1.2 現状 (As-Is)
2026-06-12 の ADR-0146 受理での実測:
- 本文 References に supersedes 2 本・amends 1 本・relates_to 2 本が宣言されていたが、frontmatter は空配列のため人間が転記
- 相手側 5 本 (0138/0140 superseded_by・0139 amended_by・0107/0142 relates_to 逆辺) を手動追記
--check-edges --enforceが「superseded_by 宣言と status 変更の同時性」を強制するため、0138/0140 の frontmatter status・本文太字メタ Status 行も手で書き換え。順序を誤り CI fail を 1 回踏んだ (edge-status-mismatch)
同型の後修正は ADR-0145 受理 (同日・コミット a740ddcd) でも、ADR-0147 受理 (同日・follows_up_on 1 本+relates_to 2 本の frontmatter 転記と相手側逆辺 3 本) でも発生しており、受理 3 連続で 0.5〜1 時間の定番手作業+CI fail リスクが再生産されている。
既存基盤 (実査): パイプライン PR の後修正は pipeline-pr-autofix.mjs (trio/nav/index) で機械化済み・本番稼働中。検査側は adr-lint の typed-edges が dangling・片方向・status 不一致を error 化済み。
§1.3 課題
「検査」だけが機械化され「自動修正」が欠けているため、受理 PR ごとに 0.5〜1 時間の手作業と CI fail リスクが恒常的に再生産されている。受理頻度は直近で数本/週、ADR-0145/0146/0147 の連続例が示す通り 1 週間で 3 件のペースで発生している。
§1.4 制約・要件
- グラフ衛生規約 (ADR-0131) は無変更で履行を引き上げる (規約・検査仕様は触らない)
- 既存の pipeline-pr-autofix CI (PR ブランチへの自動 commit) の枠組みに組み込む
- 機械追記は事後に
--check-edges --enforceで検証 pass することを commit 条件にする - 相手側 ADR の書き換えは逆辺キーの追記と status 系 3 点に限定 (本文の他節には触れない)
- 適用範囲はパイプライン生成 PR のみ。手書き ADR の辺は従来どおり起案者が書く
§1.5 目標 (To-Be)
受理 PR が人手ゼロで ADR-0131 のグラフ衛生を満たす状態にする。Non-Goals: 手書き ADR (パイプライン外) の辺宣言の自動反映は本決定では扱わない。
決定
pipeline-pr-autofix.mjs を拡張し、(1) 本文「参照 (References)」の型付き辺箇条 (- **supersedes**: ADR-NNNN (説明) 形式) を parse して自己 frontmatter の対応キーへ機械転記し、(2) supersedes/amends/relates_to の宣言に応じて相手側 ADR に逆辺キーを追記し、supersedes 時は frontmatter status・本文太字メタ Status 行も書き換える。実行は既存の autofix CI 上で PR ブランチに自動 commit され、機械追記後に --check-edges --enforce をローカル再実行し pass しない場合は commit せず CI fail で人間に差し戻す。
展開:
- 自己 frontmatter 反映: References の型付き辺箇条を parse し frontmatter の対応キーへ id+コメント (説明の要約) を機械転記。References の既存形式は変更しない (body_generation プロンプトが固定出力済)
- 相手側逆辺の機械追記: supersedes → 相手側に
superseded_by追記+frontmatterstatus: superseded+本文太字メタ Status 行を「Superseded by ADR-NNNN (置換概要・日付。元の受理 = 元の文言を保持)」へ書き換え。amends →amended_by追記のみ (status 不変)。relates_to → 相手側 relates_to へ逆辺追記 - 実行位置: 既存の pipeline-pr-autofix CI に組み込む。adr-index/INDEX 再生成は既存処理が後続で面倒を見る
- 安全装置: 機械追記後に
--check-edges --enforceを再実行し error が残れば commit せず CI fail。相手側書き換えは逆辺キー追記と status 系 3 点に限定。parse 結果が期待 id セットと完全一致しない場合 (説明文に別 ADR 番号が含まれるなど) は autofix を中断し CI fail。References の ADR 番号がリポジトリ内に実在することを事前検証し、存在しなければ該当辺をスキップして CI warning。Status 行の表記ゆれでマッチしない場合は書き換えをスキップして CI warning。autofix 実行前に対象相手側 ファイルを git fetch で最新化し conflict 検出時は書き換えをスキップして CI fail+PR コメント。edges 検査 fail 時はファイル変更をgit checkout --で全破棄してから CI fail を返す (dirty state を残さない)。パイプライン生成 ADR で辺宣言が 1 本もない場合は異常とみなし CI warning を出す閾値ルールを追加 (parser 全取りこぼしの無言劣化を検知) - 適用範囲: パイプライン生成 PR のみ (既存 autofix と同じトリガー)
判断基準 (Decision Drivers)
3.1 評価軸
| # | 軸 | 重要度 (係数) | 案件特有の解釈 |
|---|---|---|---|
| 1 | #maintainable | [Must] (×2.0) | 受理 PR がグラフ衛生 (ADR-0131) を人手ゼロで満たし、手作業の転記ミス・順序ミス由来の CI fail が消える |
| 2 | #reliable | [Must] (×2.0) | 機械追記が誤った辺・誤った status を作らない。事後 --check-edges --enforce pass を commit 条件にし、相手側本文の他節には触れない |
| 3 | #efficient | [Medium] (×0.5) | 受理ごとの定番手作業 0.5〜1 時間 × 数本/週を解消する |
K.O. criterion: Must 軸の score < 3 は不採用。
3.2 評価軸 × 案スコア表
| 軸 | 係数 | 採択案 (autofix 拡張) | 案 B (手順書化) | 案 C (worker 側で書く) | 案 D (起案者必須) | 案 E (現状維持) |
|---|---|---|---|---|---|---|
#maintainable [Must] | ×2.0 | 5 | 2 | 3 | 2 | 1 |
#reliable [Must] | ×2.0 | 4 | 2 | 3 | 3 | 2 |
#efficient [Medium] | ×0.5 | 5 | 1 | 3 | 2 | 1 |
| 加重和 (正規化) | 0.900 | 0.380 | 0.600 | 0.500 | 0.300 | |
| K.O. 通過 (Must ≥3) | ✓ | ❌ | ✓ | ❌ | ❌ |
検討した代替案 (Alternatives Considered)
- 案 B: 手順書化のみ (operator_guide に後修正チェックリスト) — 作業は残り、転記ミス・順序ミス (status と逆辺の同時性) のリスクも残る。検査 (enforce) があるのに修正が手動という非対称が続く。不採用
- 案 C: worker (webhook) 側で PR 生成時に相手側ファイルも書く — worker の GitHub 書込が複数ファイルに広がり subrequest が増える (Workers 50/req 制約・KPI-9)。autofix CI ならリポ checkout 済みで既存自動 commit 基盤に乗るだけ。不採用
- 案 D: 辺の宣言を起案者の生テキスト必須にする (パイプライン入力で完結) — 起案時点では採番 (ADR-NNNN) が未確定で、相手側の status 変更はどのみち受理 PR でしか書けない。入力負担も増える。不採用
- 案 E: 現状維持 (毎回手作業) — 0145/0146 で 2 日連続の同型作業・CI fail 実績。受理頻度 (数本/週) を考えると再生産が続く。不採用
影響 (Consequences)
§5.1 正の影響 (Good)
- supersede/amend を含む受理が人手ゼロでグラフ衛生 (ADR-0131) を満たす
- 後修正の所要 0.5〜1 時間と CI fail リスクが消える
- autofix の diff は PR 上で人間が確認でき、監査証跡も残る
- 機械追記の commit メッセージに「自動追記した辺の一覧 (例: ADR-0138 に superseded_by: ADR-0146 を追記)」を箇条書きで含めることで、レビュアーが CI グリーンに依存せず diff を読む動線を作る
§5.2 負の影響 (Bad)
- autofix が相手側 ADR ファイルを書き換える権限を持つ (誤動作時は受理済み文書に誤った status が入る — PR diff レビューと事後 edges 検査で防ぐ)
- References の箇条形式が暗黙の機械契約になる (body_generation プロンプトが References の出力形式を変えると parser が全取りこぼし → frontmatter 空配列 → 検査通過 → CI green のままグラフ汚染が蓄積するリスク。プロンプトの出力形式変更は ADR 改定とみなす運用ルールとする)
- 受理済み ADR の status 誤変更は、その ADR を根拠にした組織決定の有効性が事後的に疑われ監査対応コストを生む潜在リスクがある (1 件目発覚から撤退 PR マージまでの時間窓に次の受理 PR が同じ誤りを繰り返す可能性があるため、撤退条件は status 誤変更については 1 件で発動する)
§5.3 中立・トレードオフ (Neutral / Trade-offs)
- References の説明文が長文・変則のとき parse を取りこぼす → 取りこぼしは「frontmatter 未反映」として既存の edges 検査に出る。あわせて「辺宣言 0 本」閾値ルールで無言劣化を検知
- 本文太字メタ Status 行の文言は ADR ごとに表記ゆれがある (例:
**Status**: Accepted/**ステータス**: 承認済/Status: **Accepted**) → 書き換えは「Superseded by」プレフィックス付与+元文言の括弧内保持に限定し、マッチしない場合はスキップして CI warning - LLM が存在しない ADR 番号や誤った関係を幻覚出力するリスクは原理的にある → parser 内で実在性チェック+受理前の人間レビューチェックポイントで二重防御
- 同日複数受理での相手側ファイル競合 → 実行前 git fetch+conflict 時スキップで対処
撤退条件 (Rollback Plan)
- 機械追記の誤り (誤った辺・相手側本文の意図しない変更) が 2 件以上発生 → 該当機能を無効化し手作業へ戻す (フラグ 1 つで旧動作)
- status の誤変更は 1 件で撤退発動 (受理済み決定の公式記録への影響が重く、時間窓での再生産リスクがあるため)
- References 形式の変更に parser が追従できず取りこぼし警告が常態化 (5 PR 連続) → 形式と parser の契約を再設計するまで無効化
- 撤退操作:
pipeline-pr-autofix.mjsの辺処理を skip するフラグ追加 PR のみ (既存 trio/nav/index 処理は無影響・完全可逆)
コスト試算
- 実装 約 0.7〜1.0 人日:
- References parser + frontmatter 転記 約 0.3 人日
- 相手側逆辺+status 書き換え 約 0.3 人日
- unit test (0145/0146 の実例 fixture・「edges 検査 pass が commit 条件」の golden-path・説明文内に別 ADR 番号/複数行/入れ子括弧/Status 行表記ゆれ ADR-0107〜0147 全バリエーション fixture) 約 0.2〜0.3 人日
- 追加調査: 既存
pipeline-pr-autofix.mjsの失敗時ロールバック (git checkout --) の有無を実査。未実装の場合は追加 0.1 人日見込み - 運用従量: なし (既存 autofix CI の実行時間が数秒延びるのみ)
- 効果: 受理 1 回あたり手作業 0.5〜1 時間 × 受理頻度 (数本/週) の恒常削減
Confirmation
- 検証手段:
① unit test (0145/0146 実例 fixture・golden-path「edges 検査 fail なら commit しない」・説明文内に別 ADR 番号が登場するケース・複数行にまたがるケース・括弧が入れ子になるケース・Status 行表記ゆれ ADR-0107〜0147 全バリエーション fixture) を CI 毎に実行
② 受理 PR ごとに autofix の diff を人間が PR レビューで確認 (commit メッセージに自動追記した辺一覧が箇条書きで含まれることでレビュー動線を確保)
③
--check-edges --enforceの error 0 件維持 (既存 CI) ④ autofix が status を変更したファイル一覧を PR description に自動追記し、「status 変更を含む」PR がレビュアーに一目で識別可能にする ⑤ 生成 ADR の References 内容を受理前の人間レビューチェックポイントで確認 (幻覚 ADR 番号の検知) - 実行頻度: ①③ CI 毎、②④⑤ 受理 PR 毎
- 違反時対応: 機械追記の誤りを検知したら当該 PR で手修正し、誤りパターンを fixture へ追加。status 誤変更は 1 件、その他は 2 件で撤退条件を発動
Review After
- 次回レビュー: 2026-12-13(運用 6 ヶ月後。機械追記の誤り率〔Confirmation の fixture 蓄積〕と References 箇条形式という暗黙契約の安定性を再評価する時期)
- レビュー主体: ADR 制度の所有者(現任 = 代表取締役)
- 前倒しトリガ: ① 撤退条件のいずれかに抵触した時 ② body_generation の References 出力形式を変更する時 — parser の契約が壊れるため同一 PR での追従が必要 ③ ADR-0131 の辺タイプ・グラフ衛生規約の改訂時 — 逆辺の生成ロジックが連鎖して変わるため
参照 (References)
- 関連 ADR:
- follows_up_on: ADR-0131 (型付き辺のグラフ衛生と機械検査 — 0131 が導入した「同一 PR で逆辺・status 変更」規約の履行を、検査任せから自動修正へ引き上げる運用フォローアップ。規約・検査仕様は無変更)
- relates_to: ADR-0107 (ADR 資産インデックスと依存グラフ — adr-index.json のグラフが本決定の出力先。再生成は既存 autofix が継続)
- relates_to: ADR-0141 (承認者検査の受理 PR 層所有 — 受理 PR を機械検査・機械修正の集約点とする同じ方向。本決定はグラフ衛生の修正を同じ層へ置く)
- relates_to: ADR-0146 (早わかりの派生ビュー化 — 本決定の起点となった実害事例の出どころ。0146 受理の手作業 5 本+CI fail 1 回が定量根拠)
- 関連 PR/Issue: コミット a740ddcd (ADR-0145 受理時の「型付き辺+相手側逆辺」手修正)
- 外部資料: -