背景 / コンテキスト
/forge:review code --auto の AI レビュー実行中、forge:reviewer Agent(engine=codex)が Codex の出力を findings_<種別>.json に構造化変換する際に発生した。このセッション内で異なる2つのレビュー実行にわたって独立に2回観察されており、単発の偶然ではなく再現性のある不具合と判断した。
現象(実際の動作)
Codex(run_review_engine.sh 経由で起動)がレビュー結果を 1. **[問題名]** [severity]: 説明... という順序(severity ラベルが **問題名** の後)で出力するケースがある。この出力を convert_codex_findings.py(内部で findings_parser.py の FINDING_PATTERN 正規表現を使用)に渡すと、FINDING_PATTERN は N. [severity] **問題名**:(severity ラベルが **問題名** の前)という順序を前提としているため一致せず、finding_count: 0 が返る。この際エラーは発生せず、レビュー結果が静かに空として扱われる(サイレント障害)。実際に指摘が存在していても、下流の findings_<種別>.json には何も反映されない。
期待動作
Codex の出力順序が [severity] **title** / **title** [severity] のどちらであっても、FINDING_PATTERN が finding を正しく抽出できるべきである。少なくとも、パースに失敗した場合はサイレントに 0 件を返すのではなく、パース失敗を検知できるようにするべきである(例: Codex 出力に番号付きリストの行が存在するにもかかわらず finding が 0 件の場合は警告を出す等)。
再現手順
/forge:review code --files <対象ファイル> --auto を実行する(engine=codex)
- Codex が
1. **[問題名]** [critical]: ... の順序(severity ラベルが title の後)でレビュー結果を出力する
convert_codex_findings.py --kind code を実行する
findings_code.json の finding_count が 0 になることを確認する(実際には Codex が finding を報告しているにもかかわらず)
Codex の出力順序はプロンプトで厳密に固定されていないため、100% 確実な再現手順ではなく発生確率のある不具合である。
環境情報
- リポジトリ: BlueEventHorizon/bw-cc-plugins(
develop ブランチ、plugins/forge/scripts/review/convert_codex_findings.py および findings_parser.py の FINDING_PATTERN)
- 実行環境: Claude Code、Codex CLI(
codex-cli 0.144.1 で確認)
重大度
機能に支障あり
証跡
なし
原因
findings_parser.py の FINDING_PATTERN 正規表現が N. [severity] **title**: という固定順序のみを想定しており、Codex が N. **title** [severity]: という別順序で出力した場合にマッチしない。agents/reviewer.md の「finding 出力フォーマット」節でも severity ラベルの位置がテキストの説明とサンプルで厳密に固定されておらず、Codex 側の出力順序のばらつきを吸収できていない。
実装計画
関連ドキュメント
仕様書
参考 PR(実装パターン)
実装スコープ
| レイヤー |
実装内容 |
ファイルパス |
| Codex 構造化変換 parser |
FINDING_PATTERN を拡張し、severity ラベル/emoji marker を **title** の前後どちらでも許容する(group 番号ズレに伴う参照箇所も追従修正) |
plugins/forge/scripts/review/findings_parser.py |
| Codex 構造化変換 parser |
番号付きリスト形式のエントリが content 中に存在するにもかかわらず findings が 0 件の場合、stderr に警告を出すフォールバック検知を追加(ADR-033 §6 が定める「パース失敗時の 0 件抽出 + 警告」という安全側動作を強化) |
plugins/forge/scripts/review/findings_parser.py |
スコープ外
| 項目 |
理由 |
担当 |
agents/reviewer.md / templates/review_result.md の出力フォーマット規約変更 |
現行の規約 (severity は **title**: 説明 とは別の - severity: 行で表現) は既に明確。プロンプト強化のみでの対症療法は ADR-033 の方針(根治は parser 側の堅牢化)に反するため対象外 |
本 Issue |
convert_codex_findings.py の変更 |
findings_parser.convert_to_findings_json() を呼ぶのみで、内部ロジックの変更が波及しない見込み |
本 Issue |
TODO
着手前確認
実装する
テストを書く
確認・レビュー準備を行う
完了する
背景 / コンテキスト
/forge:review code --autoの AI レビュー実行中、forge:reviewerAgent(engine=codex)が Codex の出力をfindings_<種別>.jsonに構造化変換する際に発生した。このセッション内で異なる2つのレビュー実行にわたって独立に2回観察されており、単発の偶然ではなく再現性のある不具合と判断した。現象(実際の動作)
Codex(
run_review_engine.sh経由で起動)がレビュー結果を1. **[問題名]** [severity]: 説明...という順序(severity ラベルが**問題名**の後)で出力するケースがある。この出力をconvert_codex_findings.py(内部でfindings_parser.pyのFINDING_PATTERN正規表現を使用)に渡すと、FINDING_PATTERNはN. [severity] **問題名**:(severity ラベルが**問題名**の前)という順序を前提としているため一致せず、finding_count: 0が返る。この際エラーは発生せず、レビュー結果が静かに空として扱われる(サイレント障害)。実際に指摘が存在していても、下流のfindings_<種別>.jsonには何も反映されない。期待動作
Codex の出力順序が
[severity] **title**/**title** [severity]のどちらであっても、FINDING_PATTERNが finding を正しく抽出できるべきである。少なくとも、パースに失敗した場合はサイレントに 0 件を返すのではなく、パース失敗を検知できるようにするべきである(例: Codex 出力に番号付きリストの行が存在するにもかかわらず finding が 0 件の場合は警告を出す等)。再現手順
/forge:review code --files <対象ファイル> --autoを実行する(engine=codex)1. **[問題名]** [critical]: ...の順序(severity ラベルが title の後)でレビュー結果を出力するconvert_codex_findings.py --kind codeを実行するfindings_code.jsonのfinding_countが0になることを確認する(実際には Codex が finding を報告しているにもかかわらず)Codex の出力順序はプロンプトで厳密に固定されていないため、100% 確実な再現手順ではなく発生確率のある不具合である。
環境情報
developブランチ、plugins/forge/scripts/review/convert_codex_findings.pyおよびfindings_parser.pyのFINDING_PATTERN)codex-cli 0.144.1で確認)重大度
機能に支障あり
証跡
なし
原因
findings_parser.pyのFINDING_PATTERN正規表現がN. [severity] **title**:という固定順序のみを想定しており、Codex がN. **title** [severity]:という別順序で出力した場合にマッチしない。agents/reviewer.mdの「finding 出力フォーマット」節でも severity ラベルの位置がテキストの説明とサンプルで厳密に固定されておらず、Codex 側の出力順序のばらつきを吸収できていない。実装計画
関連ドキュメント
仕様書
参考 PR(実装パターン)
findings_parser.py) のFINDING_PATTERN起因バグを正規表現拡張 + 回帰テスト追加で直接修正したパターン実装スコープ
FINDING_PATTERNを拡張し、severity ラベル/emoji marker を**title**の前後どちらでも許容する(group 番号ズレに伴う参照箇所も追従修正)plugins/forge/scripts/review/findings_parser.pyfindingsが 0 件の場合、stderr に警告を出すフォールバック検知を追加(ADR-033 §6 が定める「パース失敗時の 0 件抽出 + 警告」という安全側動作を強化)plugins/forge/scripts/review/findings_parser.pyスコープ外
agents/reviewer.md/templates/review_result.mdの出力フォーマット規約変更**title**: 説明とは別の- severity:行で表現) は既に明確。プロンプト強化のみでの対症療法は ADR-033 の方針(根治は parser 側の堅牢化)に反するため対象外convert_codex_findings.pyの変更findings_parser.convert_to_findings_json()を呼ぶのみで、内部ロジックの変更が波及しない見込みTODO
着手前確認
実装する
FINDING_PATTERNに**title**後方の severity ラベル/emoji marker 許容を追加extract_findings(2 箇所)・_strip_leading_finding_markerの参照箇所を追従修正findingsが 0 件の場合の警告出力をextract_findingsに追加テストを書く
tests/forge/review/test_findings_parser.py: severity ラベルが**title**の後に来るケース(Issue [Bug] convert_codex_findings.py が Codex 出力の severity/title 順序違いでサイレントに finding 0 件を返す #201 再現)の抽出テストtests/forge/review/test_findings_parser.py: 番号付きリストが存在するのに finding 0 件の場合に警告が出力されることのテストpython3 -m unittest tests.forge.review.test_findings_parser -v)確認・レビュー準備を行う
python3 -m unittest discover -s tests -p 'test_*.py' -v)完了する