Implements the Completeness critic pattern — the final gate of the
quality system: after find → dedup → verify, it asks "what did the LIST / SCOPE
itself never cover?" and emits a machine-checkable clearedToClose verdict the
orchestrator can branch on.
When to use
- After a sweep, review round, or design phase, before you are ready to say "we're done".
- You want a deliberate, last-mile check for the things that systematic processes tend to miss (the modality you forgot, the claim that was assumed true, the downstream consumer you didn't think about).
It is cheap insurance against "we covered everything important" when you actually covered everything we thought of.
Workflow shape — PARALLEL / BARRIER gate (default single-pass)
This skill is the closing gate of the canonical Review harness
(find → dedup → work-refute → work-gaps; see
workflow-mode.md §2).
- Default: single-pass critic. One critic run over the reconstructed scope is enough for most work, and it is cheap relative to the work it gates.
- Scale-up variant: PARALLEL / BARRIER fan-out. For large or
high-stakes scopes, fan out one blind sub-agent per omission category
(modality-missing, unverified-claim, downstream, assumption, cross-cutting,
…), each unaware of the others' angle so they don't collapse onto the same
gaps. Then barrier-collect all results and dedup the union against
SEEN(everything ever discovered, including verifier-rejected items — L4) before emitting gaps. The barrier is justified here by a real cross-item dependency: the union must be deduped before the close decision.
Why a barrier and not a pipeline: the clearedToClose gate is a single decision
computed over all category results at once — you cannot close on a partial
union. The dedup-against-SEEN step is plain set logic, never an agent call.
This skill is not a LOOP itself — but its gaps[] output is the seed that
feeds a LOOP: each gap becomes input for another work-sweep,
work-refute, or research round (see Integration).
Usage
/work-gaps "context of what was done so far" [focus="optional extra areas"]
The orchestrator calls this at natural checkpoints and at the very end of complex work.
How it works
Step 0 — Scope-coverage diff (mandatory; this is the move that catches the real bug)
Before hunting category gaps, reconstruct the set you actually swept and diff it against the territory that should have been swept (L5). This is the sharp version of completeness — finding what was never on the list, not re-checking what was. Concretely:
- Reconstruct, from todo/journal/handoff, the actually-swept set: files read, angles run, claims verified, consumers traced.
- Run at least one independent global oracle that does NOT depend on the
fan-out list — e.g. a repo-wide
grepfor the core entity/identifier of the task, a list of all callers/consumers, agit diff --name-onlyagainst the change set. The point is to surface items outside the fan-out list (this is exactly what caught the 5 orphan files in the grounding case — seeanti-error-lessons.md). coverageDiff = global_oracle_set − actually_swept_set. Every item in the diff is a candidate gap with categoryscope-gapand an oracle attached.
Record the oracle command and its result in the output (step0.globalOracle).
If you cannot run any independent global oracle, say so explicitly — that is
itself a coverage gap, and it blocks clearedToClose (you have no evidence the
scope was complete).
Step 1 — Reconstruct the work done
- The critic gets (or reconstructs via tools + todo/journal) what has already been explored, verified, or decided.
- It receives the list of known modalities/angles used, claims that were checked, sources read, etc. This is the
actually-swept setStep 0 diffs against.
Step 2 — Systematic gap hunt (by categories)
- The prompt forces the critic to go through a checklist of common omission categories (the
categoryenum below):modality-missing— modalities / angles not usedunverified-claim— claims or findings never adversarially verifieddownstream— downstream effects / consumers not tracedassumption— assumptions never turned into direct checkscross-cutting— security, observability, multi-tenancy, error budgets, performance under loadtime-based— historical / future-state / migration / ordering considerationsdocs-ops— documentation / operational impactscope-gap— items surfaced by the Step 0 global oracle (outside the fan-out list)
- Plus the hard-to-see cases (e.g., "what happens when this is called from the public-facing portal?").
- In the PARALLEL / BARRIER variant each category is a blind sub-agent; here you walk them sequentially.
Step 3 — File each gap responsibly (L1 + L2 — do NOT just assert it)
Filing a gap is a claim; treat it like one. Before promoting a gap — especially
downstream, assumption, or unverified-claim:
- Re-open the cited
file:lineindependently and confirm the gap from the current source (L2). Never file "X is unhandled" off remembered or quoted evidence — re-read it. Record what you re-read in the gap. - Try the cheapest oracle first (L1): a test, an exact
grep+ manual confirm, a type-check, running the app. Put the command + result inoracleCheck. If the oracle closes the gap (it turns out handled), setoracleCheck.closedGap: trueand drop the gap (do not file a phantom). - A gap that survives its oracle, or for which no oracle exists, is filed
with the oracle attempt recorded (
closedGap: false).
Step 4 — Prioritize with the two-sided rubric (L6)
Anchor priority in verified real-world impact, guarding both errors — over-rating a non-gap and under-rating a real one:
| priority | meaning |
|---|---|
high |
concretely reachable + damaging + currently uncovered. Requires a reachabilityArgument (who reaches it, by what path). No high without it. |
medium |
plausible but unverified, or no oracle available to settle it |
low |
cosmetic / already-mitigated / dev-time hygiene |
Never assign high to a speculative gap; never bury an exploitable one at low.
Step 5 — Compute the close gate (L8 evidence gate)
clearedToClose: true only if every coveredCategory carries ≥1 piece of
evidence — an oracle result, a re-read file:line, or a clean Step 0
scope-diff — and no high gap is open. A category you claim to have
covered but cannot back with evidence does not count as covered: list it in
droppedCoverage (L7) and it blocks the close. See
Null-handling & the close gate for how a failed
critic forces clearedToClose: false.
Structured Output (STRICT contract)
Emit exactly one fenced ```json block matching this schema. The orchestrator
parses and validates it and branches on clearedToClose; it re-requests
once on malformed output before treating the run as failed (per
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
}
Field rules:
gaps[].category∈modality-missing | unverified-claim | downstream | assumption | cross-cutting | time-based | docs-ops | scope-gap.gaps[].priority∈high | medium | low.reachabilityArgumentis required whenpriorityishigh.gaps[].reReadSources(optional)string[]: thefile:linesources re-opened and independently confirmed for this gap (Step 3 / L2). Strongly expected fordownstream,assumption, andunverified-claimgaps, since those must be confirmed from current source rather than asserted from memory.gaps[].oracleCheckrecords the L1 attempt:{ command, result, closedGap: boolean }. A gap withclosedGap: trueshould have been dropped, not filed.coveredCategories[]each carry anevidencestring (oracle result, re-readfile:line, or clean scope-diff). A category with no evidence belongs indroppedCoverage, not here (L8).droppedCoverage[]lists every category not investigated and why (L7 — no silent caps).clearedToCloseis a boolean the orchestrator branches on:trueonly when everycoveredCategoryhas evidence and nohighgap is open and Step 0 ran a real global oracle.
Execution Mechanics
See workflow-mode.md §3
for the full table; the mechanics that bind this skill:
Null-handling & the close gate
A failed/empty/malformed critic does NOT mean "no gaps found". That was a silent false-negative — a dead critic that read as "all clear" would close a task with zero coverage evidence. The correct rule:
- A critic run that errors, times out, or returns un-parseable output (after the one allowed re-request) yields result UNKNOWN, not "clean".
- UNKNOWN forces
clearedToClose: false, and the failure is logged as a named line in the decision record + surfaced via your harness's todo/plan tool. The task may not be declared complete on an UNKNOWN critic. - In the PARALLEL / BARRIER variant, a dead category sub-agent is
filtered out (
.filter(Boolean)) — it is not counted as "that category is clean". Its category goes intodroppedCoveragewith reasoncritic-failed, the surviving categories are re-evaluated, and the drop is logged. One dead refuter must never read as coverage (L7, L8).
Other mechanics
- Completeness is itself a quality pattern: cheap relative to the work it gates. Run the default single-pass critic before declaring done; reserve the fan-out for large/high-stakes scopes.
- Direct oracle ≫ panel (L1): Step 0 and every gap's
oracleCheckprefer a deterministic check over a probabilistic opinion. A gap an oracle can settle is settled, not argued. - Structured output: the strict JSON contract above is enforced; validate + re-request once before treating as failed.
- Concurrency cap (fan-out variant only): launch category sub-agents in controlled waves of ~
min(16, cores−2); excess queues. - Budget awareness: if budget runs low, reduce the number of fan-out categories explicitly and list the un-run ones in
droppedCoverage— never silently skip a category (L7). Budget pressure never flipsclearedToClosetotrue. - No silent caps (L7): every un-run category, un-run angle, or dropped gap is a named line in
droppedCoverage+ your harness's todo/plan tool. A reader must be able to tell "clean" from "truncated". - log/phase: announce phases via your harness's todo/plan tool — "Step 0 scope-diff: global grep, 2 items outside swept set", "Completeness critic: raised 4 gaps, 1 high-priority open, clearedToClose=false".
- Feeds the loop: the
gaps[]it produces are the seed for the next iteration ofwork-exhaust, anotherwork-sweep, or targetedwork-refute. Dedup that seed againstSEEN, not survivors (L4), so rejected items don't re-enter.
Worked example (single-pass, from the grounding case)
A reference-cleanup fan-out edited every file on its task list and reported "done". The work-gaps critic ran as the close gate:
- Step 0 reconstructed the swept set (the task-list files) and ran an
independent global oracle:
grep -rln '<deleted-entity-id>' .. The grep returned 5 files that were never on the task list —coverageDiff= those 5 orphans. - Each orphan was filed as a
scope-gapgap,priority: highwith areachabilityArgument(they still import the deleted entity → build breaks),oracleCheck= the grep hit,closedGap: false. - Because a
highgap was open,clearedToClose: false— the close was blocked and the 5 orphans fed back into a cleanup round. A naive "categories all look covered" critic with no Step 0 global oracle would have closed the task with the bug shipped.
Integration
- Called by
workafter major phases and as the final gate before "task complete"; the orchestrator branches onclearedToClose. - Works extremely well after
work-refuteorwork-judge(the things the adversarial process didn't kill may still have gaps around them). - Its
gaps[]feedwork-sweep(new angles),work-refute(newly-surfaced claims), and the round structure ofwork-exhaust— always deduped againstSEEN(L4). - The shared model lives in
workflow-mode.mdandanti-error-lessons.md; this skill operationalizes L1, L2, L4, L5, L6, L7, L8. - Can be run on the output of a human + agent collaboration too.
This is one of the highest-leverage cheap patterns: after you've done the hard work of finding and verifying, spend a little more to ask "what did our process systematically fail to look at?"