Skip to content

[Bug] convert_codex_findings.py の抽出品質不具合(空セクション混入・titleへのseverityラベル断片残存) #203

Description

@BlueEventHorizon

背景 / コンテキスト

/forge:start-implement で forge-msg feature を実装中、/forge:review code --auto(engine=codex)の AI レビュー実行中に発生した。convert_codex_findings.pyreview_<種別>.md の Codex 自由記述 Markdown を findings_<種別>.json に構造化変換するスクリプト)の抽出品質に関する不具合を2件確認した。いずれも Issue #201(severity/title 順序違いによるサイレントな finding 0件化)とは異なる症状であり、findingの検出自体は成功するが、抽出されたフィールドの内容にノイズが混入する種類の不具合のため、別 Issue として起票する。

現象(実際の動作)

症状1: 隣接する空 severity セクションの内容が finding の body/target_snippet に混入する

Codex のレビュー出力は 🔴致命的問題 / 🟡品質問題 / 🟢改善提案 の3セクション構成で、該当なしのセクションは規約により (なし) と記述される(agents/reviewer.md finding 出力フォーマット規約)。convert_codex_findings.py がある1件の finding を抽出する際、後続の空セクションの (なし) という文字列が誤って対象 finding の body/target_snippet フィールド末尾に連結される。

観察例(findings_code.json 内の実際のフィールド値):

"...この場合メッセージは未読のまま残り、次回また検知される\n\n\n(なし)\n\n\n(なし)"

症状2: title フィールドに severity ラベルの断片が残存する

Codex が 1. **[critical] タイトル文言**: 説明... のように severity ラベルを **...** の内側先頭に埋め込んだ場合、convert_codex_findings.py の title 抽出処理が [ の除去に失敗し、critical] という断片が title 文字列の先頭に残る。

観察例:

{"title": "critical] notify.py の単体テストが存在しない", "severity": "critical", ...}

severity/priority/recommendation 等の判定用フィールド自体は正しく抽出されており、下流の evaluator 判定処理には実害がないが、title/body/target_snippet が人間向け表示(review_<種別>.md の正規化ビュー等)に使われる際にノイズとして残る。

期待動作

  • 症状1: 対象 finding のセクション境界を正しく検出し、後続の空セクション文字列((なし)等)が finding のフィールドに混入しないこと
  • 症状2: severity ラベル([critical] 等)が **...** の内側に埋め込まれていても、title 抽出時にラベル全体([] を含む)を正しく除去すること

再現手順

いずれも Codex の出力の自由度に依存するため、100% 確実な再現手順ではない。

症状1:

  1. /forge:review code --files <対象ファイル> --auto(engine=codex)を実行する
  2. Codex が finding の説明文の後に空行を複数含む形式で出力し、かつ後続に空の severity セクション((なし))が続く
  3. convert_codex_findings.py --kind code 実行後、findings_code.json の該当 finding の body/target_snippet 末尾に (なし) が連結されていることを確認する

症状2:

  1. 同上の /forge:review code --auto を実行する
  2. Codex が 1. **[severity] タイトル**: ... の形式(severity ラベルを **...** の内側先頭に埋め込む)で出力する
  3. findings_code.json の該当 finding の title フィールド先頭に severity] という断片が残っていることを確認する

環境情報

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

重大度

軽微

証跡

なし

原因

convert_codex_findings.py(内部で findings_parser.py の抽出ロジックを使用)のセクション境界検出・フィールド抽出用の正規表現が、Codex の出力形式の揺れ(空セクションの直後に別 finding の内容が続く配置、severity ラベルが **...** の内側に埋め込まれる配置)を十分に吸収できていない。Issue #201(severity/title 順序違いによる finding 0件化)と根本原因(Codex 出力形式の揺れに対する抽出ロジックの脆弱性)は共通するが、症状・影響範囲が異なるため別 Issue として管理する。

実装計画

関連ドキュメント

仕様書

種類 ドキュメント
ADR ADR-033: reviewer/evaluator finding 出力の構造化データ移行
ルール 実装ガイドライン

参考 PR(実装パターン)

PR 参考ポイント
#211 convert_codex_findings.py が Codex 出力の severity/title 順序違いでサイレントに finding 0 件を返す 同一ファイル(findings_parser.py)の正規表現不具合修正 + 回帰テスト追加という同種の対症パターン

実装スコープ

レイヤー 実装内容 ファイルパス
Codex 構造化変換(縮退経路、ADR-033 §6) 症状1: extract_findings() のセクション境界検出で、#### P1/P2/P3 サブセクション見出し(h4以深)通過時も flush_body() を呼び、直前 finding の body/target_snippet を確定させる(severity 自体は継続、Issue #151 と非衝突) plugins/forge/scripts/review/findings_parser.py
同上 症状2: FINDING_PATTERN**[label] title** 形式(severity ラベルが太字内・タイトル前)専用の分岐を追加し、title 抽出時にラベル全体([/] 含む)を除去する。group 番号変更に伴う参照箇所(heading 側 if match: ブロック・body 側 if match: ブロックの計2箇所、_strip_leading_finding_marker)を追従修正 同上

スコープ外

項目 理由 担当
agents/reviewer.md / templates/review_result.md の出力フォーマット規約変更 PR #211 と同方針。プロンプト強化のみでの対症療法は行わない -
convert_codex_findings.py の変更 findings_parser の関数を呼ぶのみで内部ロジック変更は波及しない -

TODO

着手前確認

  • 仕様書の確認完了
  • 実装ルールの確認完了
  • 参考 PR のパターン確認完了

実装する

  • FINDING_PATTERN に severity ラベルのインライン分岐を追加し、**[label] title** 形式の title からラベル断片が残らないよう修正
  • extract_findings() の見出し処理で、h4 以深のサブセクション見出しも flush_body() を呼ぶよう修正(severity は継続)
  • group 番号変更に伴う参照箇所(extract_findings 内2箇所、_strip_leading_finding_marker)を追従修正

テストを書く

  • findings_parser.extract_findings: 症状1(空サブセクションプレースホルダーの body 混入)の回帰テスト
  • findings_parser.extract_findings: 症状2(**[label] title** 形式の title 抽出)の回帰テスト

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

  • テストを実行する(python3 -m unittest discover -s tests -p 'test_*.py'、全1463件パス)

完了する

  • 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