work-sweep について
work-sweepは、コードやシステムを複数の観点から調査するエージェントスキルです。独立した検索を並行実行し、全件の完了後に結果を統合・検証して、未調査領域も示します。
主な機能
- 01観点別のブラインド並列検索
- 02バリア方式での結果収集
- 03永続的なseenセットによる重複排除
- 04新しい発見の検証
- 05調査範囲の不足の特定
活用シーン
- 01単一の検索方法では見つからない問題の発見
- 02セキュリティやデータ露出リスクのレビュー
- 03異なる観点からのコードベース調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ djalmajr/ skills --skill work-sweepインストール後、Claude Code で/work-sweepを入力して読み込まれたか確認します。
詳細
/work-sweep — 多角度ブラインド探索
マルチモーダルスイープパターンを実装します。
オーケストレーションの形:並列実行し、マージ時にバリアを設ける
このスキルは、並列に分岐し、重複排除/マージの段階でバリアを設ける形です。詳細は、../work/references/workflow-mode.md §1 の3つの形を参照してください。
- 分岐は並列です: N 個のブラインドサーチャーが、それぞれ異なる角度を担当して同時に実行され、完全に独立しています。サーチャー間にバリアはありません。
- マージでは本物のバリアが必要です: 重複排除と完全性チェックは項目間の処理であるため、すべてのサーチャーを待つ必要があります。「異なる2つの経路で見つかった同じ問題は1件として数える」ことや、「どの角度でもカバーされていない内容は何か」を計算できるのは、すべての角度から報告が揃った後だけです。これはバリアの根拠となる、まさに項目間の依存関係です(workflow-mode §1:結果セット全体にわたる重複排除/マージ)。都合上設けるバリアではなく、角度間の比較には実際に全結果が必要です。
- バリアは単純な集合演算であり、エージェントの呼び出しではありません。 重複排除と完全性チェックは、オーケストレーター自身のコンテキスト内で
seenセットを使って実行してください。「マージ」するサブエージェントを起動してはいけません。
角度の探索に失敗しても、バリアを待ち状態にしてはいけません。その角度を除外し、残った角度についてカバレッジを再計算し、除外したことを記録してください(「実行の仕組み」→「Null の処理」を参照)。
このスイープを work-exhaust の1ラウンドとして実行する場合、バリアの出力(新たな発見と更新された seen セット)が次のラウンドに渡されます。ループの形は ../work-exhaust/SKILL.md にあり、このスキルは各ラウンドの分岐とバリアを提供します。
使用する場面
- 1つの検索戦略(grep で1つの用語を検索する、数ファイルを読む、1つのエージェントに「問題を探して」と依頼する)だけでは、重要なケースを見落とします。
- システムの異なる側面(コード構造、実行時の動作、過去の変更、データエンティティ、ユーザージャーニー、エラー状態)から、それぞれ異なる情報が得られます。
- サーチャー同士が互いの結果に影響されない状態(ラウンド中はブラインドのまま)で、網羅性を高めたい場合に使用します。
複数回のラウンドを実行するために、work-exhaust と組み合わせることもよくあります。
使用方法
/work-sweep "what to discover" [angles=...]
例:
/work-sweep "ジョブのSLAやステータスの可視性に影響する可能性がある箇所"/work-sweep "サインアップフローにおけるセキュリティとデータ露出のリスク" angles="authz,storage,logging,public-endpoints,third-party-calls"
オーケストレーターは、調査フェーズと初期レビューのフェーズでこのスキルを多用します。
仕組み
-
モダリティ/角度を定義する
- 指定がない場合は、次のセットをデフォルトで使用します:
- 構造(ファイル構成、モジュール、エントリーポイント)
- 内容/意味(キーワード、パターン、ビジネスルール)
- 履歴(git blame、最近の変更、リファクタリング)
- エンティティ/データフロー(Order、Stage、Draft などの特定のドメインオブジェクト)
- エラー/失敗経路
- ユーザー/外部インターフェースの経路
- または、呼び出し元が指定した角度を受け入れます。
- 指定がない場合は、次のセットをデフォルトで使用します:
-
ブラインドで並列にサーチャーを起動する
- 角度ごとにサブエージェントを起動します。
- 各サブエージェントには、概要レベルの目標と担当する角度の指示だけを渡します。
- 「このラウンドでは、他の角度の結果は見えません。自分の視点だけで検索してください」と明示的に伝えます。
- 利用可能なすべてのツール(grep、読み取り、ターミナルなど)を使用しますが、担当するモダリティの範囲内にとどまります。
-
バリア — 永続的な SEEN セットと照合して収集・重複排除(L4)
- マージする前に、すべての検索担当(またはフィルタリングされた失敗)が完了するまで待ちます。
- 安定した識別子(正規化された
locations[]とクレームのスラッグ)をキーとする永続的なseenセットを維持し、ラウンドをまたいで引き継ぎ、再開時にも決してリセットしません(これはジャーナルの信頼できる唯一の情報源です)。 - 各候補の検出結果について、キーが
seenにまだない場合にのみ報告します。すでにseenにあるキーと一致する検出結果は、前のラウンドで却下されたものも含めて、再報告せず、重複として破棄します。 - 更新後のセットとして
seen ∪ newを、真に新しい検出結果のリストとともに返します。残存項目ではなく seen と照合すると、却下された項目が毎ラウンド再び現れてwork-exhaustが収束しなくなります。seen と照合することで、ループを枯渇させられます。 - 新しい検出結果には、それを発見したアングルをタグ付けします(来歴はシグナルです。独立した2つのアングルで検出された結果は、より信頼性が高くなります)。
-
検証ゲート — 単なる形式的な確認ではなく、実際のゲートです(L1、L2、L8) このスキルから出す前に、新しい検出結果すべてについて、次のことを行います。
- L1 — まず直接オラクルを使います。 決定論的なオラクル(テスト、型チェック、正確な
grepと手動確認、git、アプリケーションの実行)がある場合は、検出結果を信じる前に実行します。利用可能なオラクルがあるのに実行していない検出結果は、confirmedではなくneeds_reviewです。エージェントの主張よりもオラクルを優先します。 - L2 — 現在のソースで
locations[]の各エントリーをすべて開き直します。 検索担当が引用したevidenceをそのまま受け入れてはいけません。locations[]の再確認に失敗した検出結果(行が移動した、コードがなくなった、引用箇所が見つからない)はneeds_reviewとします。黙って保持してはいけません(実際の問題でも古い可能性があります)。また、黙って破棄してもいけません(検索担当の引用が不正確なだけで、実際のバグかもしれません)。再読した内容をreReadSourcesに記録します。 - L8 — 却下が有効なのは、必要な作業を行った場合だけです。 「問題ない/すでに対処済み」という理由で検出結果を
droppedに降格する判断が有効なのは、コードを再読し、file:lineの根拠を示した場合に限ります(workDone: true、reReadSourcesが空でないこと)。怠惰な却下は判断保留です。検出結果はneeds_reviewのまま次のラウンドに引き継がれます。十分な根拠のある反証1件は、根拠のない「問題なさそう」2件を上回ります。 - 残ったセキュリティ/認証/マルチテナンシー/データ整合性に関する検出結果は、観点の異なる反証のために
../work-refute/SKILL.mdに渡します(L3 はここではなく、そちらにあります)。
- L1 — まず直接オラクルを使います。 決定論的なオラクル(テスト、型チェック、正確な
-
網羅性 — どのアングルも対象にしなかったものは何ですか?(L5) マージ後に「見つかったのはこれです」で終わらせてはいけません。最も価値の高い作業は、一度も調査されていない範囲を明らかにすることです。
completenessGaps[]を列挙します。すべてのアングルの調査範囲外にあるモジュール/ファイル、およびどのアングルも触れていないモダリティ(例:ストレージパス、設定/レルムの観点、下流の利用側、非同期/ジョブの経路、公開エンドポイントを調べていないアングル)。- アングルのリスト外にある項目を見つけるため、少なくとも1つのグローバルオラクルを実行します。リポジトリ全体を対象にコアエンティティを
grepするか、スコープの網羅性を比較します(アングルが触れたファイルと対象に言及しているファイルの差分)。これは、誰の視野にも入らない隙間にある孤立したコードパスを見つけるための手軽な方法です。 completenessGaps[]を../work-gaps/SKILL.mdに渡すか、次のwork-exhaustラウンドの新しいアングルとして追加します。
-
出力
- 構造化された
SweepResult(下記のコントラクトを参照):来歴付きの新しい一意な検出結果、更新後のseenセット、completenessGaps[]、およびdropped[](失敗したアングルと、重複排除/却下された検出結果を、それぞれ理由付きで記載します。黙って上限を設けてはいけません。L7)。 - 弱かった、またはコストがかかったモダリティに関する注記。
- 次のラウンドへの提案(別のアングル、または
work-exhaustへの引き継ぎ)。
- 構造化された
構造化 I/O 契約
自由形式の重大度文字列では適切な調整ができないため(L6)、重大度は検証済みの影響度基準に基づく列挙型とし、検証ステータスはゲートが設定する列挙型とします。スキーマの規約については、
../work/references/workflow-mode.md §4 を参照してください。
各ブラインド検索担当者は次を返します(返信の末尾にフェンス付きの ```json ブロックを記載):
{
"angle": "alternative-storage-path",
"findings": [
{
"title": "storage tenant derived from ?hostname, not session",
"description": "Orphan code path: the storage layer re-resolves the tenant from a request query param after auth, bypassing the session-bound tenant.",
"locations": ["src/storage/resolve.ts:88"],
"evidence": "resolve.ts:88 — `const tenant = req.query.hostname ?? session.tenant` (query wins)",
"severity": "high"
}
]
}
検索担当者が見つけた項目のフィールド規則:
locations— 必須のfile:line配列で、空であってはなりません(ゲートが各エントリを再度開いて確認します)。evidence— 呼び出し元がその場所で再確認できる短い引用。severity— 列挙型critical | high | medium | low(検索担当者による最初の推定値。ゲートが再調整する場合があります)。基準(L6、両方向):- critical / high — 到達可能であることが具体的に確認でき、損害をもたらし、現時点で対策されていない場合。到達可能性に関する論拠が必要です。推測上の欠落に
highを割り当ててはいけません。 - medium — もっともらしいものの未検証、またはオラクルを利用できなかった場合。
- low — 見た目だけの問題、開発時のみの問題、またはすでに軽減済みの場合。悪用可能であることが示されたものに
lowを割り当ててはいけません。
- critical / high — 到達可能であることが具体的に確認でき、損害をもたらし、現時点で対策されていない場合。到達可能性に関する論拠が必要です。推測上の欠落に
スキルは統合とゲート判定を行い、1 件の SweepResult を返します:
{
"goal": "multi-tenant isolation risks in the upload flow",
"anglesUsed": ["forgery", "config-realm", "alternative-storage-path", "error-paths"],
"round": 1,
"findings": [
{
"id": "storage-hostname-override",
"title": "storage tenant derived from ?hostname, not session",
"description": "...",
"angles": ["alternative-storage-path"],
"locations": ["src/storage/resolve.ts:88"],
"evidence": "resolve.ts:88 — query param wins over session tenant",
"reReadSources": ["src/storage/resolve.ts:88"],
"severity": "high",
"status": "confirmed",
"workDone": true,
"oracle": "grep '\\?\\.hostname' src/ + manual re-read of resolve.ts"
}
],
"seen": ["storage-hostname-override", "auth-issuer-check", "..."],
"completenessGaps": [
"No angle traced the async thumbnail-worker path (jobs/thumbnail.ts) — same tenant resolution may be duplicated there.",
"config/realm dimension only checked for the primary realm; secondary realms untested."
],
"dropped": [
{ "kind": "angle", "ref": "git-history", "reason": "sub-agent returned empty after one retry; coverage recomputed over 4 surviving angles" },
{ "kind": "finding", "ref": "logging-pii", "reason": "duplicate of seen 'pii-in-access-log' from round 0" },
{ "kind": "finding", "ref": "csrf-upload", "reason": "dismissed — re-read route, CSRF token enforced at middleware.ts:40 (workDone:true)" }
]
}
列挙型と必須のゲートフィールド:
status— 列挙型confirmed | needs_review | dropped。confirmed— 再読込による確認に合格し、かつ利用可能なオラクルを実行済みです(L1、L2)。needs_review— 再読込による確認に失敗した場合、またはオラクルがあったものの実行されなかった場合、または却下が L8 の作業テストに不合格だった場合です。黙って保持したり、黙って破棄したりしてはいけません。ここに保留します。dropped— 重複(すでにseenに含まれている)、または根拠を示した却下(workDone:true、reReadSourcesが空でない)の場合です。破棄した項目はすべて、reasonとともにdropped[]にも記載します。
severity— 上記と同じ列挙型および基準。最終判断はゲートが下します。oracle— 文字列。確認済みの指摘について実行した L1 のコマンドと結果(status==confirmedの場合は必須。それ以外は null または省略)。workDone: boolean+reReadSources: string[]— 手抜きの判定を検出して降格できるよう、ゲート判定対象のすべての指摘で必須です(L8)。completenessGaps[]— 必須(L5)。グローバルオラクルを実際に実行した後に限り[]とします。dropped[]— フィルタリングされたすべての観点と、重複排除または却下されたすべての指摘を、理由とともに記載します(L7、上限による黙示的な除外は禁止)。
実行の仕組み
各ブラインド検索者を、適切なサブエージェントロール(general-purpose)を持つサブエージェントとしてバックグラウンドで起動します。読み取り専用の調査には、分離されたワークツリーは不要です。ファイルを変更する観点に限り、ワークツリーを追加します。全員の完了を待ってバリアに到達したら、それぞれの結果を収集します。これらは
../work-tournament/SKILL.mdで使われているものと同じ基本要素です。用語を統一してください。ハーネスごとの具体的なツール名は、
../work/references/workflow-mode.mdにまとめて記載されています。
- 独立性/ブラインド性:価値の中核です。各検索者に渡すのは目標と各自の観点だけにし、明示的に次のように伝えます。「今回、ほかの観点の結果は見られません。自分の視点だけで検索してください。」 別々のサブエージェントコンテキストによって、この状態を確保します。
- 並列実行数の上限:観点は min(6, cores−2)程度を目安に、制御された複数の波に分けて起動します。超過分はキューに入ります。1回の調査で実施できる観点は、実用上6つが上限です。それを超える場合は、ラウンドを分けて延期を記録し(次の箇条書きを参照)、黙って起動数を減らしてはいけません。
- スキーマ検証+再試行1回(workflow-mode §3):各検索者のフェンス付き```jsonブロックを解析し、形式を検証します。出力が不正または空の場合は、同じ観点を1回だけ再依頼します。それでも不正な結果は失敗した観点として扱い(次の箇条書きを参照)、破棄して記録します。「該当なし」として黙って受け入れてはいけません。
- nullの処理(再計算して記録し、幽霊を数えない):停止した観点、エラーになった観点、または依然として不正な観点は除外します(
angles.filter(Boolean))。「この領域には問題がない」とは扱いません。除外後、残った観点を対象に網羅性を再計算し、そのモダリティを黙って網羅済みとせず、明示的なcompletenessGapとして扱います。また、dropped[]に{kind:"angle", ref, reason}の形式で除外を記録します。失敗した観点を「調査済みで該当なし」と読み替えるのは、L7が防ぐまさにその誤ったクリーン判定です。 - 結果がゼロの場合の早期終了:バリアの結果、新しい指摘がゼロ(すべての候補がすでに
seenに含まれている)の場合は、検証ゲートを完全に省略してラウンドを空振りとして報告します。空の集合に対して検証用サブエージェントを起動してはいけません。(これは、work-exhaustが連続K回の空振りによる終了判定に使用する、ラウンド単位のシグナルです。) - 上限を黙って適用しない(L7):並列実行数や予算の都合で優先度を下げた観点、延期したラウンド、上限に達した指摘は、すべて
dropped[]に名前付きの行として記録し、さらにハーネスのtodo/計画ツールにも反映します。読者が「問題なし」と「打ち切り」を見分けられるようにしてください。 - ワークツリーの分離:通常は不要です(読み取り専用の検索のため)。観点ごとに利用できます。
- ジャーナリング/再開:機械的に再開可能なイベントを、(エージェントのデータディレクトリ配下の)
quality-journals/<task-id>.jsonに書き込みます。形式は{ phasesDone[], seen[], anglesUsed[], findings[], completenessGaps[], dropped[] }です。再開時には**seen[]を読み込み、リセットしないでください**。これにより、却下された指摘が再度入ることや、完了済みの観点が再実行されることを防げます。 - 予算と並列実行数:上限はオーケストレーターが設定し、このスキルはそれを遵守して記録します。
- ハーネスのtodo/計画ツールを使ったログ/フェーズ:例:「4つの観点で調査中(git-historyをキューに追加、wave 2)…」、「バリア:候補7件 → seenとの重複除外後、新規3件」、「ゲート:確認済み2件、needs_review 1件(oracle未実行)」、「completenessGaps:thumbnail-workerの経路は未調査」。
作業例 — マルチテナントの孤立ストレージパス
目標:「アップロードフローにおけるマルチテナント分離のリスク」。オーケストレーターは、異なる4つの観点を選びます(多様性が重要です。同じプロンプトを4回使うのは、網羅ではなく重複です)。
| 観点 | 切り口 | 調査対象 |
|---|---|---|
forgery | なりすまし | 呼び出し元が別のテナントの ID を偽造/再利用できるか? |
config-realm | 設定/レルムの混同 | CIAM/発行者の共有、レルムの取り違え、デフォルトテナントへのフォールバック |
alternative-storage-path | コードパス | メインのガードを迂回してストレージに到達する 別の 方法があるか |
error-paths | 障害モード | エラー/catch によってテナント間で情報が漏れたり、テナント 0 がデフォルトになったりするか? |
3つの観点では認証ミドルウェアを読み、「発行者チェックで防げる」と結論づけます。これは一見妥当な単発の偽陰性です(この事例が
../work/references/anti-error-lessons.md
に記録する、まさに L2 の失敗です)。しかし、alternative-storage-path はストレージ層を読み直し、認証の後で ?hostname からテナントを導出する resolve.ts:88 を発見します。これは、ほかの観点では見つけられなかった孤立コードパスです。
バリアでは、この指摘のキーが seen にないため、報告されます(L4)。ゲートではオラクルが実行されます。grep '\?\.hostname' src/ と resolve.ts の手動での再確認(L1)により、クエリパラメーターがセッションのテナントより優先されることを確認し、status:"confirmed"、severity:"high"、workDone:true となります(L2、L8)。「発行者チェックで防げる」という3つの判断はコードを実際に読み直しているため、根拠があります。ただし、確認したのは認証だけなので、ストレージに関する指摘を覆すものではありません。続いて網羅性(L5)では、テナントリゾルバーをグローバルに grep し、completenessGaps: ["thumbnail-worker re-resolves tenant in jobs/thumbnail.ts — untouched by every angle"] を提示します。これが次の work-exhaust ラウンドの種になります。
結果として、単一の優秀なエージェント(または任意の1つの観点)では、実在する重大なバグを否定してしまいました。一方、多様な観点による調査 + seen による重複排除 + オラクルゲート + 網羅性チェックにより、バグを発見し、さらに次に調べるべき場所も特定できました。
ツールキットのほかの機能との連携
../work-exhaust/SKILL.mdの前に実施する最初のステップとして最適です(この調査で強力な初回ラウンドを実施し、そのseenセットをループで引き継ぐことで、K 回連続で空になるまで収束を目指せます)。- ゲートを通過した指摘は
../work-refute/SKILL.md(視点の多様性を活かした反証、L3)に渡され、completenessGaps[]は../work-gaps/SKILL.mdに渡されます。 - これらを組み合わせた完全版の Review ハーネスについては、
../work/references/workflow-mode.md§2 を参照してください。 - オーケストレーターはフェーズごとに観点のセット(セキュリティ調査、エッジケース調査、データフロー調査)を決定します。ゲートの根拠となる教訓は
../work/references/anti-error-lessons.mdに記載されています。
このパターンにより、単一の「優秀なエージェント」や単一の grep では見逃していた事柄を発見できる可能性が大幅に高まります。また、1回のラウンド内で調査者の集団思考を防ぎます。さらに、バリアでの seen による重複排除 + オラクルゲート + 網羅性チェックによって、未加工のヒットが監査可能で収束性のある結果に変わります。