corpus-review¶
Exhaustive review with a provable coverage ledger
Reads a corpus too large to fit in one context — a document set, log archive, or file tree — and reports what was actually inspected. Retrieval finds the relevant; this plugin accounts for everything.
corpus-review declares dependencies: ["plan-execute", "verify"]. It reuses
plan-execute's cheap-worker fan-out to read shards, and
raises verify's unable-to-check discipline from a single claim
to a whole corpus. verify already pulls the
retrieval spine.
Install¶
Components¶
| Component | What it is |
|---|---|
corpus-review skill |
The frame → inventory → shard → dispatch → aggregate → report pipeline, the disposition vocabulary, and the absence rule. |
corpus-reviewer subagent |
Reads one shard against the supplied review question and returns findings plus its own coverage. Read-only and shard-scoped — the command persists what it returns. |
/review-corpus command |
Runs the pipeline end to end over a corpus root. |
inventory-corpus.py |
Enumerates the corpus into deterministic hashed units with an inspectability signal. |
plan-shards.py |
Packs units into bounded shards whose digests make resumption safe. |
aggregate-findings.py |
Merges shard findings into a coverage ledger and refuses to call an incomplete run complete. |
Review is not retrieval¶
| Retrieval | Corpus review | |
|---|---|---|
| Success condition | relevant hits surfaced | every unit accounted for |
| Recall | best-effort, unmeasured | stated and provable |
| Output | ranked candidates | a disposition per unit |
| Absence | not measured | first-class and two-valued |
Reach for retrieval-strategy,
code-search, or indexkit first. Escalate
here only when someone will act on what was not found — ranked hits cannot
establish that nothing was skipped.
change-impact is also not this: it deliberately stops at useful
coverage for a proposed change's blast radius.
Pipeline¶
flowchart LR
F[frame<br/>question + scope + taxonomy] --> I[inventory<br/>hashed units]
I --> S[shard<br/>bounded budgets]
S --> D[dispatch<br/>resumable workers]
D --> A[aggregate<br/>coverage ledger]
A --> R[report<br/>findings + denominator]
ROOT="${CONTEXT_KIT_CORPUS_REVIEW_ROOT:-plugins/corpus-review}"
python3 "$ROOT/scripts/inventory-corpus.py" \
--root ./corpus --out ./work/inventory.json \
--include '**/*.md' --exclude '**/node_modules/**'
python3 "$ROOT/scripts/plan-shards.py" \
--inventory ./work/inventory.json --out ./work/shards.json \
--max-bytes 200000 --max-units 25
# dispatch one corpus-reviewer per shard -> ./work/findings/<shard>.md
python3 "$ROOT/scripts/aggregate-findings.py" \
--inventory ./work/inventory.json --shards ./work/shards.json \
--findings-dir ./work/findings --out-dir ./work/report \
--expected ./work/expected.txt
--expected is what makes absence verdicts available; omit it and the ledger
reports them as unavailable rather than guessing.
Claude Code components may use CLAUDE_PLUGIN_ROOT as the plugin-root fallback.
Dispositions¶
Every unit in the inventory ends in exactly one, and the dispositions sum to the inventory total:
| Disposition | Assigned when |
|---|---|
reviewed |
a worker listed the unit as read in full |
partial |
reviewed, with a bounded portion recorded as unreadable |
uninspectable |
present, but the content could not be read at all |
out_of_scope |
excluded by a stated scope rule, not by omission |
failed |
its shard errored, or its findings file is malformed |
pending |
in a shard with no findings file, or omitted by its worker |
pending is the default, so a worker's silence never reads as coverage.
Aggregation exits nonzero while any unit is pending or failed.
Coverage is reported two ways, and never only the first: unit coverage alone hides a skipped 4 MB archive among 600 small files, byte coverage alone hides 40 skipped one-line configs.
Absence: the rule that matters¶
indeterminate outranks not-found
An expected item nobody found is a real gap (not-found) only when every
unit that could contain it was actually reviewed. While any unit is
uninspectable, partial, failed, or pending, absence is undecidable
and is reported as indeterminate.
Downgrading that — treating an unread unit as if it had been read and found empty — is the characteristic failure of automated review, and the one that causes real harm: a phantom gap gets acted on as fact. Without an expected inventory — or with no unit in scope at all — absence verdicts are reported as unavailable rather than inferred.
Route the buckets differently: uninspectable to remediation, failed to
retry, pending to finishing the run, indeterminate to resolving the blocking
units — and only not-found to acting on the gap.
Resumability¶
The findings directory is the state. Each shard carries a digest over its
member content hashes:
- a findings file whose digest matches is reused and the shard is skipped;
- a mismatch means the corpus changed under the review, so the shard is re-dispatched and the change is reported rather than merged silently.
The shard plan also records inventory_sha256, a digest over the inventory's
scope rules and units rather than its raw bytes. Aggregating against different
content is refused outright, since coverage would otherwise be computed against
the wrong denominator — but simply re-running the inventory reproduces the same
digest, so a resumed review is never invalidated by a fresh timestamp.
At a glance¶
- Requires Python 3 for the standard-library scripts. Extracting non-text
units relies on the optional
data-and-docs-searchtools. - Reads only. All three scripts refuse to write their output inside the corpus root, so a re-run cannot enumerate the review's own artifacts.
- Hermetic tests:
python3 -m unittest discover -s plugins/corpus-review/tests -p 'test_*.py'