--- name: triage-integration description: 調べ終わった Coverity の警告の結果をいくつか比べ、原因が1つのものだけを1つにまとめる計画(integration/plan.json の形。まとめる作業・理由・修正の作り方・まとめた結果・ぶつかる修正)を作り、スクリプトで決まりを確かめる。コードは変えない。チャットで「この3件、同じ原因ならまとめて」「この警告たちは同じ原因?」「同じマクロが原因の警告を1つにして」のように頼まれたとき、トリアージの結果を同じ原因でまとめるときに使う。いくつかの警告をまとめるかどうかを決めるときは、必ずこのスキルを使う。 allowed-tools: ["shell(uv run:*)"] --- # 同じ原因の警告のまとめ方 まとめるのは、**原因が1つ**で、**1か所を直せば(または1つの理由で)すべての警告が片付く**ものだけです。 場所が近い、チェッカーが同じ、というだけではまとめません。迷うときはまとめません。まとめ間違えると、人が警告を別々に判断する機会がなくなるからです。 コードは変えません(まとめた修正は、計画をもとに後で作られます)。差分がぶつかるかを試すときも、利用者のフォルダに一時のファイルやコピーを作りません(`git apply --check` のように書かずに確かめるか、一時フォルダで試します)。 ## 進め方 ``` - [ ] 1. 材料をそろえる(候補の作業・結果・差分) - [ ] 2. 原因が同じかを、コードで比べる - [ ] 3. まとめるものを決める(決まりを守る) - [ ] 4. 修正の作り方を選ぶ - [ ] 5. まとめた結果を書く - [ ] 6. ぶつかる修正を書く - [ ] 7. 書く・確かめる・返す ``` 頼みの文や、それが指すファイル(指示ファイル)が、進み具合のファイルと段を示していれば、節目ごとにそのファイルを上書きします。書けなくても続けます。 ### 1. 材料をそろえる - 候補の作業ごとに:作業の ID(CID か G1 など)、CID、チェッカー、警告の場所と ★(問題の起きる場所)、調べた結果(`result.json` の形の `verdict`・`fix`・`deviation`・`confidence`)、修正の差分(あれば)。 - 読むコードの場所。 - 足りないとき:Coverity から警告経路を取れる道具があれば、それで取る。なければ頼んだ人に聞く。聞けないとき(ほかのエージェントからの頼みなど)は、足りない作業をまとめない。推測で補わない。 - リポジトリに `.coverity-triage/knowledge.md` があれば読む。チェッカーごとの見方の資料があれば、それも読む。 ### 2. 原因が同じかを、コードで比べる - それぞれの ★ と根拠の場所(`verdict.evidence`)を、コードで読み直す。 - 原因が同じかを確かめる。例:同じマクロの定義、同じ関数の戻り値の確かめ忘れ、同じ構造体の初期化漏れ。MISRA で、1つのマクロや型定義が原因で何件も出ている違反は、原因の1か所を直せばまとめて片付く。 - 修正の差分が、その同じ原因を直しているかを確かめる。 - 同じチェッカー・同じ変数・同じ関数でも、原因が同じとは限らない。例:同じ変数の NULL の警告でも、NULL を返す関数が違う(入力の形で NULL になる `strchr()` と、メモリ不足で NULL になる `malloc()`)なら、確かめを2か所に足す必要があり、原因は別。1か所の修正で片付くかで決める。 - 頼んだ人が「同じ原因だと思う」と言っていても、コードで確かめて決める。違えば、まとめない理由を伝える。 ### 3. まとめるものを決める - まとめる作業は**2つ以上**。1つの作業は**1つのまとまりにだけ**入れる。 - 1つのまとまりの CID は、合わせて**10件まで**。 - 候補として渡された、調べ終わった作業だけをまとめる。グループにしないと決まっている CID(頼みの文や `.coverity-triage/no-grouping.yaml` にあるもの)を含む作業はまとめない。 - まとめるものがなければ、`merges` を空にする。 ### 4. 修正の作り方を選ぶ(`fix_source`) | 値 | いつ | | --- | --- | | `item:` | まとめる作業の1つ(``)の修正だけで、すべての警告が片付く | | `combine` | それぞれの修正が別の場所を直していて、全部を合わせれば片付く | | `rework` | どの修正も足りない、または修正どうしがぶつかる。もとの結果を読んで作り直す | ### 5. まとめた結果を書く(`result`) `result` は、1件の結果(`result.json`)と同じ項目です(`item` と `group_excluded_cids` は書かなくてよく、書いても使われません)。 - `verdict.summary`:まとめた原因を1行で。 - `verdict.rationale`:なぜ同じ原因と言えるか、それぞれの CID の警告経路がどう同じ原因に行き着くかを順に。 - `verdict.evidence`:原因のコードの場所と、それぞれの警告の場所。 - `confidence`:まとめる作業の**いちばん低い確信度以下**にする。 - `deviation.comment`:**すべての CID に当てはまる1つの逸脱コメント**。「誤検知。」「意図的。」「本物の不具合。」のどれかで始め、判定区分のあと1〜2文、200文字以内、前後に空白なし。理由 → 根拠の場所の順に、条件を付けずに言い切る(「ただし」「〜の場合に限る」「おそらく」、調べた過程、「修正を推奨」「確認してください」は書かない)。逸脱コメントを書く手順がほかにあれば、それに従う(決まりは同じ)。 - `fix`:選んだ作り方で直す内容と影響。Classification・Action・Severity は、逸脱が「誤検知 → False Positive / Ignore / Unspecified」「意図的 → Intentional / Ignore / Unspecified」「本物の不具合で直さない → Bug / Ignore / Major・Moderate・Minor」、修正が Bug / Fix Required が目安。 ### 6. ぶつかる修正を書く(`conflicts`) 原因は違うのに、修正が同じ場所を変えている作業は、まとめずに `conflicts` に書きます。人が反映するときの注意になります。 ### 7. 書く・確かめる・返す 計画の形です(正は `assets/plan.schema.json`)。 ```json { "merges": [ { "members": ["30101", "30102"], "reason": "どちらもマクロ MSG_NAME_LEN(include/msg.h:8)の定義が配列の大きさと合っていないことが原因", "fix_source": "item:30101", "result": { "verdict": {"judgement": "true_bug", "summary": "MSG_NAME_LEN が配列より 1 大きい", "rationale": "30101(src/msg.c:41)と 30102(src/msg.c:58)は、どちらも MSG_NAME_LEN を添字の上限に使っており、配列は MSG_NAME_LEN - 1 要素しかない。", "evidence": [{"file": "include/msg.h", "line": 8, "note": "MSG_NAME_LEN の定義"}, {"file": "src/msg.c", "line": 41, "note": "30101 の警告の場所"}, {"file": "src/msg.c", "line": 58, "note": "30102 の警告の場所"}]}, "recommendation": "fix", "confidence": "medium", "confidence_reason": "2つの警告の経路とマクロの定義をコードで確かめた。30102 の確信度が中なので、それに合わせた", "deviation": {"classification": "Bug", "action": "Ignore", "severity": "Major", "comment": "本物の不具合。MSG_NAME_LEN(include/msg.h:8)が配列の大きさより 1 大きく、src/msg.c:41 と src/msg.c:58 で配列の外を書くため、直さない理由は説明できない。"}, "fix": {"classification": "Bug", "action": "Fix Required", "severity": "Major", "summary": "MSG_NAME_LEN を配列の大きさに合わせる", "impact": "MSG_NAME_LEN を使う2か所の上限が 1 小さくなる", "exceeded_constraints": [], "already_fixed_on_latest": false}, "revision_drift": {"status": "none", "detail": ""} } } ], "conflicts": [{"items": ["30110", "30115"], "note": "どちらも src/net.c の 40〜44 行目を変えるが、原因は別"}] } ``` ファイルに書くよう頼まれたときは、書いたあとで確かめます(RUN。中を読む必要はありません)。 ``` uv run --native-tls --quiet "<このスキルのフォルダ>/scripts/check_plan.py" --plan "" --member "30101:30101:high" --member "30102:30102:medium" ``` - `<このスキルのフォルダ>` は、この SKILL.md があるフォルダです。 - `--member` は候補の作業ごとに1つ、`<作業の ID>::<その作業の確信度>` で渡します(グループなら `G1:30001,30002:high`)。グループにしない CID は `--no-grouping 30005` で渡します。候補の一覧が JSON のファイルであれば `--items "<ファイル>"` でも渡せます。 - `ok` が `false` なら、`problems` の `message` のとおりに**計画のファイルだけ**を直し、通るまで繰り返します。確かめを別のやり方で済ませません。3 回直しても `ok` にならなければ、それ以上は直さず、残った `problems` と今の案をそのまま返して止めます(決まりは曲げません)。 - コマンドを使えないとき(ほかのエージェントからの作業など)は、3と5の決まり(2つ以上、1つの作業は1つのまとまりだけ、CID は10件まで、確信度はいちばん低いもの以下、逸脱コメントの決まり、`item:` はまとめる作業の ID)を自分で1つずつ見て、最後まで進めます(決まった形の確かめは、頼んだ側が行います)。 返し方: - 頼みの文や指示ファイルが返す形を決めていれば、それに従います。決まっていなければ、1行で返します:`統合: 1つにまとめる(30101, 30102)`、まとめないときは `統合: まとめるものはない`。 - 候補なのにまとめなかった作業があれば、同じ行に短い理由と一緒に足します。例 `統合: 1つにまとめる(30101, 30102)/まとめない: 30103(原因が違う:別の関数の引数の確かめ漏れ)`、`統合: まとめるものはない/まとめない: 30201, 30202(同じ行だが原因が違う)`。`plan.json` の形は変えず、まとめない理由はこの行にだけ書きます(ぶつかる修正は `conflicts` にも書きます)。 - チャットで頼まれたときは、ファイルを作らずに(差分を試しに当てる一時的なコピーも作らずに、差分を読んで判断します)、チャットで返します。返すもの:まとめるかどうかとその理由、まとめるなら、まとめる作業、同じ原因と言える理由(原因の場所と、それぞれの警告の場所)、修正の作り方(`item:`・`combine`・`rework` のどれかと理由)、すべての警告に当てはまる1つの逸脱コメント、確信度(まとめる・まとめないの判断そのものの確信度を、高/中/低と理由で。まとめないときも付ける)。ぶつかる修正があれば、それも返します。