Skip to content

[Bug] convert_codex_findings.py が Codex 出力の severity/title 順序違いでサイレントに finding 0 件を返す #201

Description

@BlueEventHorizon

背景 / コンテキスト

/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.pyFINDING_PATTERN 正規表現を使用)に渡すと、FINDING_PATTERNN. [severity] **問題名**:(severity ラベルが **問題名**)という順序を前提としているため一致せず、finding_count: 0 が返る。この際エラーは発生せず、レビュー結果が静かに空として扱われる(サイレント障害)。実際に指摘が存在していても、下流の findings_<種別>.json には何も反映されない。

期待動作

Codex の出力順序が [severity] **title** / **title** [severity] のどちらであっても、FINDING_PATTERN が finding を正しく抽出できるべきである。少なくとも、パースに失敗した場合はサイレントに 0 件を返すのではなく、パース失敗を検知できるようにするべきである(例: Codex 出力に番号付きリストの行が存在するにもかかわらず finding が 0 件の場合は警告を出す等)。

再現手順

  1. /forge:review code --files <対象ファイル> --auto を実行する(engine=codex
  2. Codex が 1. **[問題名]** [critical]: ... の順序(severity ラベルが title の後)でレビュー結果を出力する
  3. convert_codex_findings.py --kind code を実行する
  4. findings_code.jsonfinding_count0 になることを確認する(実際には Codex が finding を報告しているにもかかわらず)

Codex の出力順序はプロンプトで厳密に固定されていないため、100% 確実な再現手順ではなく発生確率のある不具合である。

環境情報

  • リポジトリ: BlueEventHorizon/bw-cc-plugins(develop ブランチ、plugins/forge/scripts/review/convert_codex_findings.py および findings_parser.pyFINDING_PATTERN
  • 実行環境: Claude Code、Codex CLI(codex-cli 0.144.1 で確認)

重大度

機能に支障あり

証跡

なし

原因

findings_parser.pyFINDING_PATTERN 正規表現が N. [severity] **title**: という固定順序のみを想定しており、Codex が N. **title** [severity]: という別順序で出力した場合にマッチしない。agents/reviewer.md の「finding 出力フォーマット」節でも severity ラベルの位置がテキストの説明とサンプルで厳密に固定されておらず、Codex 側の出力順序のばらつきを吸収できていない。

実装計画

関連ドキュメント

仕様書

種類 ドキュメント
ADR(finding 構造化) ADR-033_structured_finding_output.md
設計書(review policy) DES-028_review_policy_design.md
reviewer 出力フォーマット規約 reviewer.md

参考 PR(実装パターン)

PR 参考ポイント
#152 extract_review_findings が規定外セクションを幻の finding として登録する問題を修正 同一ファイル (findings_parser.py) の FINDING_PATTERN 起因バグを正規表現拡張 + 回帰テスト追加で直接修正したパターン
#165 finding の箇所フィールド名を target: に統一 同種の parser パターン修正を軽量スコープで完結させた前例

実装スコープ

レイヤー 実装内容 ファイルパス
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

着手前確認

実装する

  • FINDING_PATTERN**title** 後方の severity ラベル/emoji marker 許容を追加
  • group 番号変更に伴う extract_findings(2 箇所)・_strip_leading_finding_marker の参照箇所を追従修正
  • 番号付きリスト形式のエントリが存在するのに findings が 0 件の場合の警告出力を extract_findings に追加

テストを書く

確認・レビュー準備を行う

  • 静的解析を実行する(該当なし、Python 標準ライブラリのみ)
  • テストを実行する(python3 -m unittest discover -s tests -p 'test_*.py' -v

完了する

  • PR を作成する
  • レビューに対応する

Metadata

Metadata

Assignees

No one assigned

    Labels

    BUGSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions