work-gaps について
work-gaps は、複雑な作業の終了前に網羅性を確認するスキルです。実際に調査した範囲と本来の対象範囲を照合し、作業を完了できるか判断するための構造化された結果を返します。
主な機能
- 01実際に調査した範囲の再構成
- 02全体検索による範囲漏れの検出
- 03カテゴリ別の漏れチェック
- 04証拠の再確認と簡易検証
- 05影響に基づく漏れの優先順位付け
- 06構造化された終了判定
活用シーン
- 01コードレビュー完了前の未確認の呼び出し元の確認
- 02設計レビュー後の前提や下流影響の漏れの確認
- 03大規模または高リスクな作業での並列チェック
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ djalmajr/ skills --skill work-gapsインストール後、Claude Code で/work-gapsを入力して読み込まれたか確認します。
詳細
/work-gaps — ギャップと見落としの検出
Completeness critic パターンを実装します。品質システムの最終ゲートとして、find → dedup → verify の後に、「LIST / SCOPE 自体でカバーされていないものは何か?」を問い、オーケストレーターが分岐に使える、機械的にチェック可能な clearedToClose 判定を出力します。
使用するタイミング
- スイープ、レビューラウンド、設計フェーズの後、完了を宣言する前に使用します。
- 体系的なプロセスでも見落としがちなもの(忘れていたモダリティ、真実だと思い込んでいた主張、考慮していなかった下流の利用者)を、最後に意識的に確認したい場合に使用します。
実際には「考えついた重要なこと」をすべてカバーしただけなのに、「重要なことはすべてカバーした」と考えてしまう事態に備える、低コストの保険です。
ワークフローの形 — PARALLEL / BARRIER ゲート(デフォルトは単一パス)
このスキルは、標準の Review ハーネス
(find → dedup → work-refute → work-gaps。詳細は
workflow-mode.md §2 を参照)の
終了ゲートです。
- デフォルト:単一パスのクリティック。 再構成したスコープに対するクリティックを1回実行すれば、ほとんどの作業には十分で、ゲート対象の作業と比べて低コストです。
- スケールアップ版:PARALLEL / BARRIER ファンアウト。 大規模なスコープや重大な影響を伴うスコープでは、各見落としカテゴリにつき1つのブラインドなサブエージェント(modality-missing、unverified-claim、downstream、assumption、cross-cutting、…)に分散します。それぞれが他の観点を知らないようにして、同じギャップに収束するのを防ぎます。その後、すべての結果をバリアで収集し、ギャップを出力する前に、結果の和集合を
SEEN(検証で却下された項目を含む、これまでに発見されたすべての項目 — L4)と照合して重複排除します。終了判定の前に和集合の重複排除が必要となる、実際の項目間依存関係があるため、ここではバリアが妥当です。
パイプラインではなくバリアを使う理由:clearedToClose ゲートは、すべてのカテゴリの結果を一度に評価して行う単一の判定です。和集合が不完全な状態では終了できません。SEEN との重複排除は、単純な集合演算であり、エージェント呼び出しでは決してありません。
このスキル自体は LOOP ではありません。ただし、出力の gaps[] は LOOP の種になります。各ギャップが、別の work-sweep、
work-refute、または調査ラウンドへの入力になります(Integration を参照)。
使用方法
/work-gaps "context of what was done so far" [focus="optional extra areas"]
オーケストレーターは、自然なチェックポイントと複雑な作業の最終段階でこのスキルを呼び出します。
仕組み
ステップ 0 — スコープ網羅性の差分(必須。本当のバグを見つけるための手順)
カテゴリごとのギャップを探す前に、実際にスイープした範囲を再構成し、スイープすべきだった範囲と比較します(L5)。これは完全性を見極めるための、より鋭い方法です。すでにあるものを再確認するのではなく、リストに一度も載っていなかったものを見つけます。具体的には、次の手順を行います。
- todo/journal/handoff から、実際にスイープした集合を再構成します。読み込んだファイル、実施した観点の調査、検証した主張、追跡した利用者などが含まれます。
- ファンアウトリストに依存しない独立したグローバルオラクルを少なくとも1つ実行します。たとえば、タスクの中心となるエンティティ/識別子についてリポジトリ全体を対象にした
grep、すべての呼び出し元/利用者の一覧、変更セットとの差分を調べるgit diff --name-onlyなどです。目的はファンアウトリストの範囲外にある項目を見つけることです(これこそが、grounding の事例で孤立ファイル5つを見つけた方法です。詳細はanti-error-lessons.mdを参照してください)。 coverageDiff = global_oracle_set − actually_swept_setとします。差分内の各項目は、カテゴリがscope-gapで、オラクルが紐付けられたギャップ候補です。
オラクルのコマンドと結果を出力の step0.globalOracle に記録します。独立したグローバルオラクルを実行できない場合は、その旨を明示してください。それ自体が網羅性のギャップとなり、clearedToClose をブロックします(スコープが完全だったことを示す証拠がないためです)。
ステップ 1 — 実施した作業を再構成する
- クリティックには、すでに調査、検証、または決定した内容を渡します(またはツールと todo/journal を使って再構成します)。
- 使用した既知のモダリティ/観点、確認した主張、読んだソースなどの一覧を渡します。これが、ステップ 0 で比較する
実際にスイープした集合です。
ステップ 2 — カテゴリー別の体系的なギャップ調査
- プロンプトでは、一般的な見落としカテゴリーのチェックリスト(以下の
category列挙型)を批評者が確認するよう求めます。modality-missing— 使用されていないモダリティ/観点unverified-claim— 敵対的な検証が行われていない主張や調査結果downstream— 下流への影響/利用者が追跡されていないassumption— 直接的なチェックに落とし込まれていない前提cross-cutting— セキュリティ、可観測性、マルチテナント、エラーバジェット、負荷時のパフォーマンスtime-based— 過去/将来の状態、移行、順序に関する考慮事項docs-ops— ドキュメント/運用への影響scope-gap— ステップ 0 のグローバルオラクルで明らかになった項目(ファンアウトリスト外)
- さらに、見つけにくいケースも対象です(例:「一般公開ポータルからこれが呼び出された場合、どうなるか?」)。
- PARALLEL / BARRIER 方式では、各カテゴリーをブラインドサブエージェントが担当しますが、ここでは順番に確認します。
ステップ 3 — 各ギャップを責任を持って報告する(L1 + L2 — ただ主張するだけでは不十分)
ギャップの報告は主張です。主張と同じように扱ってください。ギャップを採用する前に、特に
downstream、assumption、unverified-claimについては、次を行います。
- 引用した
file:lineを独立して再度開き、現在のソースからギャップを確認します(L2)。記憶や引用済みの証拠をもとに「X は未対応」と報告してはいけません。再読した内容をギャップに記録します。 - まず最も手軽なオラクルを試します(L1):テスト、正確な
grepと手動での確認、型チェック、アプリの実行などです。コマンドと結果をoracleCheckに記載します。オラクルによってギャップが解消された場合(実際には対応済みだった場合)は、oracleCheck.closedGap: trueを設定して、そのギャップを破棄します(誤ったギャップを報告しないでください)。 - ギャップがオラクルを通過した場合、または利用できるオラクルがない場合は、オラクルの試行結果を記録して(
closedGap: false)報告します。
ステップ 4 — 両面の基準で優先順位を付ける(L6)
優先順位は、検証済みの実世界への影響に基づいて決めます。実際にはギャップでないものを過大評価する誤りと、本当のギャップを過小評価する誤りの両方を防ぎます。
| priority | 意味 |
|---|---|
high | 具体的に到達可能であり、有害で、現時点で未対応です。reachabilityArgumentが必須です(誰が、どの経路で到達するか)。これがなければhighにしてはいけません。 |
medium | 可能性はあるものの未検証、または解決の判断に使えるオラクルがない |
low | 表面的な問題/すでに緩和済み/開発時の衛生管理 |
推測上のギャップにhighを付けてはいけません。悪用可能なギャップをlowに埋もれさせてもいけません。
ステップ 5 — クローズ判定ゲートを計算する(L8 エビデンスゲート)
clearedToClose: trueにできるのは、すべてのcoveredCategoryに1つ以上の証拠(オラクルの結果、再読したfile:line、またはクリーンなステップ 0 のスコープ差分)があり、未解決のhighギャップがない場合に限ります。確認済みと主張しても、それを裏付ける証拠がなければ、確認済みとして数えません。そのカテゴリーをdroppedCoverage(L7)に記載してください。これはクローズを妨げます。批評者が失敗した場合にclearedToClose: falseを強制する方法については、Null-handling & the close gateを参照してください。
構造化出力(厳格な契約)
このスキーマに一致する ```json ブロックをちょうど 1 つ出力してください。オーケストレーターはこれを解析して検証し、clearedToClose に基づいて分岐します。不正な出力の場合は、失敗として扱う前に 1 回だけ再リクエストします(workflow-mode.md §3–4 に準拠)。
{
"step0": {
"actuallySweptSet": ["src/routes/upload-handler.ts", "auth-middleware.ts", "..."],
"globalOracle": { "command": "grep -rn 'storageTenant' src/", "result": "7 hits across 5 files; 2 not in swept set" },
"coverageDiff": ["src/storage/handlers.ts", "migration-runner.ts"]
},
"gaps": [
{
"category": "downstream",
"description": "storageTenant override is read in storage/handlers.ts, never traced by the review",
"suggestedAction": "Run work-refute on the ?hostname storage path with lens 'alternative-code-path'",
"priority": "high",
"reachabilityArgument": "the public-facing portal hits the upload handler with attacker-controlled ?hostname, post-auth, no session binding",
"reReadSources": ["src/storage/handlers.ts:212"],
"oracleCheck": { "command": "grep -n 'req.query.hostname' src/storage/handlers.ts", "result": "handlers.ts:212 uses it for tenant key", "closedGap": false }
}
],
"coveredCategories": [
{ "category": "unverified-claim", "evidence": "all 6 findings carry workDone:true from work-refute" },
{ "category": "modality-missing", "evidence": "Step 0 scope-diff clean for code paths; grep returned no un-swept callers" }
],
"droppedCoverage": [
{ "category": "time-based", "reason": "no migration/ordering oracle available this round; not investigated" }
],
"overallAssessment": "Coverage solid on code paths but one high-priority downstream gap is open",
"recommendation": "Run one more work-refute round on the storage path before closing",
"clearedToClose": false
}
フィールドのルール:
gaps[].category∈modality-missing | unverified-claim | downstream | assumption | cross-cutting | time-based | docs-ops | scope-gap。gaps[].priority∈high | medium | low。priorityがhighの場合、reachabilityArgumentは必須です。gaps[].reReadSources(任意)string[]:このギャップについて再度開き、独立して確認したfile:line形式のソース(Step 3 / L2)。downstream、assumption、unverified-claimのギャップは、記憶に基づく主張ではなく、現在のソースで確認する必要があるため、特に記載が強く推奨されます。gaps[].oracleCheckは L1 の試行を記録します:{ command, result, closedGap: boolean }。closedGap: trueのギャップは、記録するのではなく削除しておくべきです。coveredCategories[]の各項目にはevidence文字列(オラクルの結果、再読したfile:line、またはスコープ差分がないことの確認)を含めてください。証拠のないカテゴリはここではなく、droppedCoverageに記載します(L8)。droppedCoverage[]には、調査しなかったすべてのカテゴリと、その理由を列挙します(L7 — 上限による黙殺は禁止)。clearedToCloseはオーケストレーターが分岐に使うブール値です。trueにできるのは、すべてのcoveredCategoryに証拠があり、未解決のhighギャップがなく、Step 0 で実際にグローバルオラクルを実行した場合に限ります。
実行上の仕組み
全体の表については workflow-mode.md §3 を参照してください。このスキルを規定する仕組みは次のとおりです。
null の処理とクローズゲート
批評器の実行失敗、空の応答、不正な応答は、「ギャップが見つからなかった」ことを意味しません。 それは、気付かれない偽陰性です。実質的に機能していない批評器が「問題なし」と読み取られれば、カバレッジの証拠がゼロのままタスクをクローズしてしまいます。正しいルールは次のとおりです。
- 批評器の実行がエラーになる、タイムアウトする、または(許可された1 回の再リクエスト後も)解析不能な出力を返す場合、結果は「問題なし」ではなくUNKNOWNになります。
- UNKNOWN の場合は、
clearedToClose: falseにする必要があります。また、その失敗を判定記録に名前付きの行として記録し、ハーネスの todo/計画ツールを通じて表面化させます。批評器の結果が UNKNOWN の場合、タスクを完了として宣言してはいけません。 - PARALLEL / BARRIER 方式では、応答しないカテゴリサブエージェントは
.filter(Boolean)で除外されます。「そのカテゴリに問題がない」とは見なされません。そのカテゴリは理由critic-failedとともにdroppedCoverageに追加し、残ったカテゴリを再評価して、その除外を記録します。反証担当が 1 つ応答しなくても、それをカバレッジとして扱ってはいけません(L7、L8)。
その他の仕組み
- 網羅性そのものが品質パターンです:それによって許可される作業に比べて、低コストで実施できます。完了を宣言する前に、デフォルトの単一パスの批評を実行してください。ファンアウトは、大規模または重要度の高いスコープに限ってください。
- 直接的なオラクル ≫ パネル(L1):Step 0 と各ギャップの
oracleCheckでは、確率的な意見より決定論的なチェックを優先してください。オラクルで解決できるギャップは、議論するのではなく解決します。 - 構造化出力:上記の厳格な JSON コントラクトが適用されます。失敗とみなす前に、検証して一度だけ再リクエストしてください。
- 並行実行の上限(ファンアウト方式のみ):カテゴリ別のサブエージェントは、
min(16, cores−2)程度の制御された波で起動します。上限を超えた分はキューに入ります。 - 予算への配慮:予算が不足しそうな場合は、ファンアウトするカテゴリ数を明示的に減らし、実行しなかったカテゴリを
droppedCoverageに列挙してください。カテゴリを黙って省略してはいけません(L7)。予算の圧迫によってclearedToCloseがtrueになることはありません。 - 上限を黙って設けない(L7):未実行のカテゴリ、未検討の観点、破棄したギャップはすべて、
droppedCoverageとハーネスの todo/plan ツールに個別の項目として記録してください。読者が「問題なし」と「打ち切り」を区別できるようにします。 - ログ/フェーズ:ハーネスの todo/plan ツールを使って、各フェーズを告知してください。「Step 0 scope-diff: global grep, 2 items outside swept set」「Completeness critic: raised 4 gaps, 1 high-priority open, clearedToClose=false」
- ループに戻す:ここで生成される
gaps[]は、work-exhaustの次の反復、別のwork-sweep、または対象を絞ったwork-refuteの起点になります。その起点は、残存項目ではなくSEENと照合して重複を排除してください(L4)。却下した項目が再び入り込まないようにします。
実例(グラウンディングのケースから、単一パス)
参照のクリーンアップで、タスクリスト上のすべてのファイルを編集し、 「完了」と報告しました。クローズ判定のゲートとして work-gaps critic を実行しました。
- Step 0 では、対象範囲(タスクリスト上のファイル)を再構成し、独立したグローバルオラクル
grep -rln '<deleted-entity-id>' .を実行しました。grep により、タスクリストに一度も含まれていないファイルが5つ見つかりました。coverageDiffはこれら5つの未処理ファイルです。 - 各未処理ファイルは
scope-gapギャップとして記録され、reachabilityArgument(削除されたエンティティを引き続きインポートしているためビルドが失敗する)を付けてpriority: highに設定されました。oracleCheckは grep のヒット、closedGapはfalseです。 - 未解決の
highギャップがあったため、clearedToClose: falseとなり、クローズは阻止され、5つの未処理ファイルはクリーンアップのラウンドに戻されました。Step 0 のグローバルオラクルなしで「すべてのカテゴリが網羅されているようだ」と判断する単純な批評では、バグを含んだままタスクを完了していたでしょう。
統合
workから主要フェーズの後、および「タスク完了」の最終ゲートとして呼び出されます。オーケストレーターはclearedToCloseに応じて分岐します。work-refuteまたはwork-judgeの後に実行すると非常に効果的です(敵対的プロセスで排除されなかったものにも、まだギャップが残っている可能性があります)。- 生成された
gaps[]は、work-sweep(新しい観点)、work-refute(新たに表面化した主張)、およびwork-exhaustのラウンド構造に渡されます。常にSEENと照合して重複を排除してください(L4)。 - 共有モデルは
workflow-mode.mdとanti-error-lessons.mdにあります。このスキルは L1、L2、L4、L5、L6、L7、L8 を運用に落とし込みます。 - 人間とエージェントの共同作業による出力に対しても実行できます。
これは、低コストで大きな効果が得られるパターンのひとつです。発見と検証という大変な作業を終えたら、もう少し時間をかけて、「プロセス上、体系的に見落としていたものは何か」と問いかけてください。