mcpField
W
work-sweep

work-sweep

github.com/djalmajrエージェントワークフロー454 回インストール5 週間前に更新
リポジトリ

work-sweep について

work-sweepは、コードやシステムを複数の観点から調査するエージェントスキルです。独立した検索を並行実行し、全件の完了後に結果を統合・検証して、未調査領域も示します。

主な機能

  1. 01観点別のブラインド並列検索
  2. 02バリア方式での結果収集
  3. 03永続的なseenセットによる重複排除
  4. 04新しい発見の検証
  5. 05調査範囲の不足の特定

活用シーン

  1. 01単一の検索方法では見つからない問題の発見
  2. 02セキュリティやデータ露出リスクのレビュー
  3. 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"

オーケストレーターは、調査フェーズと初期レビューのフェーズでこのスキルを多用します。

仕組み

  1. モダリティ/角度を定義する

    • 指定がない場合は、次のセットをデフォルトで使用します:
      • 構造(ファイル構成、モジュール、エントリーポイント)
      • 内容/意味(キーワード、パターン、ビジネスルール)
      • 履歴(git blame、最近の変更、リファクタリング)
      • エンティティ/データフロー(Order、Stage、Draft などの特定のドメインオブジェクト)
      • エラー/失敗経路
      • ユーザー/外部インターフェースの経路
    • または、呼び出し元が指定した角度を受け入れます。
  2. ブラインドで並列にサーチャーを起動する

    • 角度ごとにサブエージェントを起動します。
    • 各サブエージェントには、概要レベルの目標と担当する角度の指示だけを渡します。
    • 「このラウンドでは、他の角度の結果は見えません。自分の視点だけで検索してください」と明示的に伝えます。
    • 利用可能なすべてのツール(grep、読み取り、ターミナルなど)を使用しますが、担当するモダリティの範囲内にとどまります。
  3. バリア — 永続的な SEEN セットと照合して収集・重複排除(L4)

    • マージする前に、すべての検索担当(またはフィルタリングされた失敗)が完了するまで待ちます。
    • 安定した識別子(正規化された locations[] とクレームのスラッグ)をキーとする永続的な seen セットを維持し、ラウンドをまたいで引き継ぎ、再開時にも決してリセットしません(これはジャーナルの信頼できる唯一の情報源です)。
    • 各候補の検出結果について、キーが seen にまだない場合にのみ報告します。すでに seen にあるキーと一致する検出結果は、前のラウンドで却下されたものも含めて、再報告せず、重複として破棄します。
    • 更新後のセットとして seen ∪ new を、真に新しい検出結果のリストとともに返します。残存項目ではなく seen と照合すると、却下された項目が毎ラウンド再び現れて work-exhaust が収束しなくなります。seen と照合することで、ループを枯渇させられます。
    • 新しい検出結果には、それを発見したアングルをタグ付けします(来歴はシグナルです。独立した2つのアングルで検出された結果は、より信頼性が高くなります)。
  4. 検証ゲート — 単なる形式的な確認ではなく、実際のゲートです(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 はここではなく、そちらにあります)。
  5. 網羅性 — どのアングルも対象にしなかったものは何ですか?(L5) マージ後に「見つかったのはこれです」で終わらせてはいけません。最も価値の高い作業は、一度も調査されていない範囲を明らかにすることです。

    • completenessGaps[] を列挙します。すべてのアングルの調査範囲外にあるモジュール/ファイル、およびどのアングルも触れていないモダリティ(例:ストレージパス、設定/レルムの観点、下流の利用側、非同期/ジョブの経路、公開エンドポイントを調べていないアングル)。
    • アングルのリスト外にある項目を見つけるため、少なくとも1つのグローバルオラクルを実行します。リポジトリ全体を対象にコアエンティティを grep するか、スコープの網羅性を比較します(アングルが触れたファイルと対象に言及しているファイルの差分)。これは、誰の視野にも入らない隙間にある孤立したコードパスを見つけるための手軽な方法です。
    • completenessGaps[] を ../work-gaps/SKILL.md に渡すか、次の work-exhaust ラウンドの新しいアングルとして追加します。
  6. 出力

    • 構造化された 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 を割り当ててはいけません。

スキルは統合とゲート判定を行い、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 による重複排除 + オラクルゲート + 網羅性チェックによって、未加工のヒットが監査可能で収束性のある結果に変わります。

コメント