--- name: triage-investigation description: Coverity の警告の真偽を調べる手順と、確信度・推奨の決め方。Coverity の CID を調べて、本物のバグか誤検知かを判断するときに使う。ほかのスキルとサブエージェントが読む手順書で、人が直接頼むものではない。 --- # 警告の真偽の調べ方 指示ファイル(`brief.md`)に、警告の情報、警告経路(Coverity のイベント)、調べるコードと修正するコードのフォルダ、結果ファイルの場所が書いてあります。ファイルを読む・探すのは、ふだんのファイルの読み取りと検索の機能で行います。 ## 基本の考え方 - 警告経路は「こう実行されたら問題になる」という**仮説**です。仮説の各段階がコードで本当に成り立つかを、1 つずつ確かめます。 - 判断の根拠は、すべて**コードの場所(ファイルと行)**で示します。「たぶん」「ふつうは」で判断しません。 - 調べるのは「調べるコード」のフォルダです。修正は「修正するコード」のフォルダで行います。両者のリビジョンは違うことがあるので、行番号のずれに注意します。 ## プロジェクトの知識 指示ファイルに知識のファイル(`knowledge.md`)があれば、調べる前に読みます。このプロジェクトで人が確かめて書いた知識です。 - 当てはまる知識(戻らない関数、呼び出し元が保証している前提、推奨の方針など)があれば判断に使い、`verdict.rationale` に「プロジェクトの知識:〇〇」と書く。できれば、その知識をコードでも確かめる。 - 知識とコードが食い違うときは**コードを優先**し、食い違いを `verdict.rationale` に書く。 - 「推奨の方針」は、下の「推奨の決め方」より優先する。 ## 手順 1. **チェッカーの観点を読む**:スキル `checker-knowledge` で、このチェッカーの観点を確かめる。 2. **警告経路を順に読む**:進み具合を `read` にする(下の「進み具合の記録」)。指示ファイルの警告経路を順に、調べるコードの該当行の前後(目安 ±20 行)を読む。★ の付いたイベントが問題の起きる場所。 3. **経路が成り立つ条件を書き出す**:進み具合を `judge` にする。その経路を通るのに必要な条件(分岐の条件、引数の値、戻り値など)を挙げる。 4. **条件を 1 つずつ確かめる**: - 値の出どころを、関数名・マクロ名・変数名で検索して、呼び出し元・定義までたどる。 - すべての呼び出し元が条件を満たさない(例:どの呼び出し元も NULL を確かめてから渡す)なら、その経路は成り立たない。 - 1 つでも条件を満たす呼び出し元があれば、経路は成り立ちうる。 5. **判定する**(`verdict.judgement`) - `true_bug`:経路が成り立ち、実際に問題が起きる。 - `false_positive`:経路が成り立たない(Coverity が見落とした条件がある)。 - `intentional`:経路は成り立つが、設計どおりの動きで問題にならない(意図的なフォールスルーなど)。 - `undetermined`:実行時の値や外部の仕様によるため、コードからは決められない。 6. **最新のリビジョンを確かめる**:修正するコードのフォルダで同じ箇所を読み、もう直っていないか確かめる(直っていれば `fix.already_fixed_on_latest` を true にし、修正はしない)。 ## 進み具合の記録 人が画面で、調査の進み具合を見ています。指示ファイルの「フォルダとファイル」の表に進み具合のファイル(`progress.json`)があれば、節目ごとに、編集の機能で丸ごと上書きします。 ```json {"item": "20001", "phase": "judge", "note": "呼び出し元 read_config() を確かめている"} ``` - `phase` は、警告経路とコードを読み始めるときに `read`、真偽を判断し始めるときに `judge`、修正を作り始めるときに `fix`、逸脱コメントを書き始めるときに `deviation`、結果ファイルを書き始めるときに `result` にする。 - `item` は作業の ID、`note` はいましていることを 1 行で書く。時刻は書かない(ファイルの更新時刻を使う)。 - 書けなくても、そのまま調査を続ける。このファイルのために調査を止めたり、遅らせたりしない。 ## グループのとき - まず代表の CID を上の手順で調べ、残りの CID が**同じ理由**で同じ結論になるかを確かめる。 - 理由が違う CID は `group_excluded_cids` に入れて、個別の作業に戻す。迷うときも外す(まとめ間違えるより安全)。 ## 手元のコードで調べるとき(ずれの確認) 指示ファイルに「解析したリビジョンが分からない」とあるときは、調べるコードが Coverity の解析したコードと違うかもしれません。 - 警告経路の各行に、イベントの説明と合うコードがあるかを確かめる。指示ファイルの「機械的に見つけたずれ」も見る。 - 合わなければ `revision_drift.status` を `detected` にして、何がずれているかを `detail` に書き、確信度を下げる。 - 合っていれば `none`、確かめきれなければ `unknown` にする。 - このとき調べるコードは利用者の作業中のファイルです。**絶対に変更しない。** ## 確信度の基準 | 確信度 | 基準 | |---|---| | `high`(高) | 警告経路をコードで最後まで追え、根拠がすべてコードにある | | `medium`(中) | 根拠の一部に推定がある(呼び出し元の一部を追いきれない、マクロの展開を推定した など) | | `low`(低) | 実行時の値や外部の仕様など、コードから決められない前提による。またはリビジョンのずれがある | `confidence_reason` には、どの基準に当たるかを具体的に書きます(例「呼び出し元 3 箇所すべてで NULL を確かめていた」)。 ビルドでの検証(オプション)を使う実行では、全部の調査が終わったあとにまとめてビルドします。そこで問題が出た修正の推奨は、一覧とレポートで確信度を「低」として見せます。独立した検証(オプション)で確信度の上限が付いたときも同じです(どちらも結果ファイルは変えません)。 ## 推奨の決め方 プロジェクトの知識に「推奨の方針」があればそれに従います。無ければ次を目安にします。 - `true_bug` → 修正を推奨する。 - `false_positive` / `intentional` → 逸脱を推奨する。ただし、逸脱を推奨できるのは、どんな状況でも問題にならないことを、条件や但し書きを付けずに逸脱コメントに書けるときだけ(スキル `deviation-comment`)。書けなければ修正を推奨する。また、修正が小さく安全で、コードの意図も分かりやすくなるなら、修正を推奨してもよい。 - `undetermined` → 修正のリスクが小さければ修正、大きければ逸脱を推奨し、確信度は `low` にする。 調べ終わったら、スキル `code-fix` で修正案を、スキル `deviation-comment` で逸脱コメント案を作り、スキル `triage-report` の形で結果ファイルを書きます。