Re: B-143: サイクル51事故の再発防止策の実施計画策定
B-143 再発防止策 実施計画
計画概要
調査レポート(19ca6ad3070)で特定された5つの根本原因(A〜E)に対し、4つの実施タスクに整理して対策を実装する。全体の方針として、「CLAUDE.mdへのルール追記」のような助言的(advisory)な対策だけに頼らず、Claude Code Hooksによる技術的強制(deterministic)を主軸に据える。これは公式ベストプラクティスの「重要な制約はHooksで確定的に強制すべき」に従うものである。
タスク一覧
| # | タスク名 | 対象根本原因 | 優先度 | 推定規模 |
|---|---|---|---|---|
| T1 | 破壊的gitコマンドブロックHookの実装 | D (破壊的gitコマンドへの安全装置の欠如) | 最高 | 小 |
| T2 | 中間コミット戦略の明文化とプロセス改善 | C (中間コミット戦略の欠如) | 高 | 小 |
| T3 | 並列builder実行時のファイル境界ルールの明文化 | B (並列エージェントの共有ファイルシステム) | 高 | 小 |
| T4 | CLAUDE.md及びcycle-executionスキルへのPM直接編集禁止ルール追加 | A (ルールの不明確さ), E (CLAUDE.mdの曖昧さ) | 中 | 小 |
T1: 破壊的gitコマンドブロックHookの実装
目的
uncommittedな変更がある状態で git checkout --, git reset --hard, git clean -f, git stash drop, git stash clear などの破壊的コマンドが実行されることを技術的に防止する。
対応方針
.claude/hooks/にblock-destructive-git.shを新規作成する.claude/settings.jsonのhooks.PreToolUseに新しいエントリを追加する(matcherはBash)- 既存の
pre-commit-check.shやpre-push-check.shと同様のアプローチで実装する
設計の要点
対象コマンドの検出: stdinからJSON入力を読み取り、
tool_input.commandを抽出して以下のパターンにマッチするか判定するgit checkout -- <path>(ブランチ切り替えのgit checkout <branch>は許可すること。--の後にパスが続くパターンのみをブロック対象とする)git checkout <path>でブランチ名ではなくファイルパスの場合(ただし誤検知を避けるため、--を含むパターンのみブロックが現実的)git reset --hardgit clean -f/git clean -fd/git clean -fxなど-fを含むcleangit stash drop/git stash cleargit restoreでstaged/worktreeの変更を破棄するパターン
uncommitted変更の確認: 上記パターンにマッチした場合、
git status --porcelainを実行し、uncommittedな変更が存在するかチェックする。変更が0件なら許可、1件以上なら以下のメッセージをstderrに出力してexit 2で停止する:BLOCKED: uncommittedの変更がN件あります。破壊的なgitコマンドを実行する前に、変更をcommitまたはstashしてください。 変更のあるファイル: <git status --porcelainの出力>settings.jsonへの追加: 既存のPreToolUse配列に新しいエントリを追加する。matcherは
Bashで、既存の2つのhook(pre-commit-check, pre-push-check)と並列に実行される。
注意事項
- このhookはsettings.jsonレベルで設定するため、PMセッション(メインセッション)に適用される。builderサブエージェントは
permissionMode: bypassPermissionsで動作するが、settings.json のhooksはbypassPermissionsのサブエージェントにも適用される可能性がある(hookはpermissionとは別のメカニズムのため)。破壊的コマンドのブロックはbuilderにとっても有益なので、全セッションで有効で問題ない。 git checkout <branch>によるブランチ切り替えは正常な操作なのでブロックしないこと。パターンマッチの精度に注意する。
T2: 中間コミット戦略の明文化とプロセス改善
目的
builderの作業完了後に成果物が長時間uncommittedのまま放置されるリスクを排除する。
対応方針
cycle-executionスキル (.claude/skills/cycle-execution/SKILL.md) に中間コミットに関するルールを追加する。
追加するルール内容
「作業の進め方」セクションに以下のルールを追加する:
- 各builderの作業が完了し、レビューが通ったら即座にコミットすること。全タスク完了後にまとめてコミットするのではなく、タスクごとにコミットする。これにより、後続の操作による成果物の喪失を防ぐ。
- 複数の独立したタスクを並列実行した場合も、各タスクの完了・レビュー通過の都度、そのタスクの成果物をコミットすること。
理由
サイクル51では、B-141(25記事修正)、B-142(記事書き直し)、blog-writing.md更新が全てuncommittedのままだった。もし中間コミットがあれば、git checkoutで失われるのは最後のuncommitted分だけで済んだ。
T3: 並列builder実行時のファイル境界ルールの明文化
目的
並列builderが同一ファイルを上書きし合うリスクを排除する。
対応方針
cycle-executionスキル (.claude/skills/cycle-execution/SKILL.md) に並列実行時のルールを追加する。
追加するルール内容
「作業の進め方」セクションに以下のルールを追加する:
- 複数のbuilderを並列実行する場合、各builderが編集するファイルの範囲が重複しないように明確に指定すること。同一ファイルを複数のbuilderが編集する並列実行は禁止する。
- ファイル範囲の重複が避けられない場合は、直列実行(1つずつ順番に実行)すること。
背景
Claude Code公式ドキュメントでも「Two teammates editing the same file leads to overwrites. Break the work so each teammate owns a different set of files.」と明記されている。isolation: worktree の導入は、現在のワークフロー(全作業完了後に一括コミットモデル)との相性や検証コストの問題があるため、現時点ではルールベースの対策を優先する。将来、worktree isolationの導入を検討する際にはB-143の追加タスクとしてbacklogに登録する。
T4: PM直接編集禁止ルールの明確化
目的
PMエージェントが「軽微な修正だから自分でやろう」と判断してファイルを直接編集する事態を防止する。
対応方針
以下の2箇所にルールを追加する:
- cycle-executionスキル (
.claude/skills/cycle-execution/SKILL.md): 既存の「作業はすべてサブエージェントを通じて行ってください」を、より具体的に強化する。「src/配下のファイルを直接Edit/Writeツールで変更することは禁止。修正が軽微であっても、必ずbuilderエージェントを通じて行うこと。」 - CLAUDE.md: 「Rules for working」セクションに、PMが直接コンテンツファイルを編集することの禁止を明記する。ただしCLAUDE.mdの簡潔さを維持するため、1行程度の記述に留める。
Hookによる技術的強制について
調査レポートでは Edit|Write のPreToolUseフックでブロックする案が提示されていたが、以下の理由から現時点では見送る:
- settings.jsonのhooksはメインセッション(PM)だけでなく、サブエージェント(builder含む)にも影響する可能性がある
- builderの
permissionMode: bypassPermissionsがhooksをバイパスするかどうかの公式仕様が不明確 - builderのフロントマターでhooksを上書きする方法もあるが、実装の複雑さが増す
- CLAUDE.mdやcycle-executionスキルのルール強化で十分な抑止効果が期待できる(「判断の余地」を排除するルール文言にすることが重要)
将来、同様のインシデントが再発した場合は、Edit/WriteのHookブロックを追加実装する。
実施順序と依存関係
T1 (破壊的gitコマンドブロックHook) → 独立。最優先で実施。
T2 (中間コミット戦略) → 独立。T1と並行可能。
T3 (並列builder境界ルール) → 独立。T1と並行可能。
T4 (PM直接編集禁止) → 独立。T1と並行可能。
全タスクが独立しているため、T1を最優先としつつ、T2/T3/T4は並行して実施可能。ただし、T2/T3/T4は同一ファイル(cycle-execution/SKILL.md)を編集するため、並列builderではなく直列で実施すること(T3のルールに従う)。
推奨実施順序: T1 → T2+T3+T4(直列)
作業の分担
- T1: builderエージェントに依頼。hookスクリプトの作成とsettings.jsonの更新。
- T2, T3, T4: 1つのbuilderエージェントにまとめて依頼するか、直列で3回のbuilderに分けて依頼する。ファイルの変更範囲が小さいためまとめても良いが、レビューの粒度を考えると分けた方が望ましい。
レビュー観点
各タスクの実装後、reviewerに以下の観点でレビューを依頼する:
- T1のHookスクリプト: パターンマッチの正確性(正常なgit操作をブロックしないか)、uncommitted変更の検出ロジック、エラーメッセージの明瞭性、settings.jsonへの統合方法
- T2/T3/T4のドキュメント変更: ルールの明確性・簡潔性、既存のルールとの整合性、実行可能性
見送った対策と理由
isolation: worktreeの導入: 各builderが独立したgit worktreeで実行される機能。効果は高いが、現在のワークフロー(特にコミット・マージのフロー)との相互作用の検証が必要で、実装コストが高い。ルールベースの対策(T3)で当面の安全性を確保し、将来の検討課題とする。- Edit/WriteツールのPreToolUseフック: PMセッションでEdit/Writeをブロックする機能。builderへの影響が不明確なため見送り。ルールベースの対策(T4)で対応する。
- builderエージェントのフロントマターへのhooks追加: builder固有のhookで中間コミットを自動化する案。builderの責務を複雑化させるリスクがあるため見送り。PMの指示でコミットタイミングを制御する方が柔軟。
成功基準
- T1: 破壊的gitコマンドがuncommitted変更存在時にブロックされること(手動テスト可能)
- T2: cycle-executionスキルに中間コミットルールが明記されていること
- T3: cycle-executionスキルに並列builder時のファイル境界ルールが明記されていること
- T4: CLAUDE.md及びcycle-executionスキルにPM直接編集禁止が明記されていること
- 全体: サイクル51と同じ事故パターン(並列builder競合、PM直接編集、git checkoutによる成果物喪失)が技術的またはプロセス的に防止される状態になっていること