First-pass extraction systematically misses 15–25% of extractable content because LLMs satisfice; this skill is the gate that catches those misses before they ship to a client-facing deliverable. It's a mandatory second-pass adversarial re-read of source material against the synthesis or extraction it produced. Use whenever a workflow extracts content, consumes transcripts, reviews attachments, or fetches documents and that extraction feeds a downstream deliverable. User says: "second pass," ...
Installs into .claude/skills of the current project.
Are you the author of Adversarial Re Read?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/shawnclybor-adversarial-re-read)
---
name: adversarial-re-read
description: >
First-pass extraction systematically misses 15–25% of extractable content because LLMs satisfice; this skill is the gate that catches those misses before they ship to a client-facing deliverable. It's a mandatory second-pass adversarial re-read of source material against the synthesis or extraction it produced. Use whenever a workflow extracts content, consumes transcripts, reviews attachments, or fetches documents and that extraction feeds a downstream deliverable. User says: "second pass," "re-read the source," "verify extraction," "what did I miss in the source," "did I capture everything," "diff my extract against the original."
---
## Why this exists
First-pass extraction systematically misses 15–25% of extractable content. Three failure modes compound:
1. **Truncation by default** — `head 200`, `pdftotext file.pdf | head`, and "summarize this" prompts to subagents silently lose content past the window. The reader doesn't see what they didn't read.
2. **Synthesis pressure** — once you have ~80% of the headline points, the pull toward writing the deliverable is stronger than the pull toward exhausting the source. "I have enough to synthesize" feels like done-ness; it's satisficing.
3. **Table-and-image blindness** — text PDFs get attention; structured comparison tables and images get a quick glance. The cells you skim past are often where the implications hide.
When extraction feeds a client-facing deliverable, the missed 15–25% can include items that change the deliverable shape — a hard requirement you didn't notice, a risk that becomes a new pre-flight task, a constraint that narrows the scope, a piece of context that changes the pricing posture.
The mandatory second pass forces the misses to surface before they ship.
## When to invoke
Triggered by:
- A calling skill's pre-flight checklist line: "Run `adversarial-re-read` after Phase 1 curation — do not skip."
- Self-trigger: any time you've just produced a synthesis or extraction that will feed a client-facing deliverable, before presenting the synthesis as final.
## When NOT to invoke
- Single-source quick-lookup tasks ("what does this email say")
- Routine retrieval ("summarize this calendar event")
- Content Claude generated itself with no external source to re-read against
- Trivial Q&A or formatting fixes
## The procedure
Five steps. None skippable. Step 3d is conditional on its own trigger — the condition is not optional, the step is.
### 1. Bound the source explicitly
Before reading anything, count the source in full:
```bash
wc -l <source-file> # for text/PDF (after pdftotext)
file <image> # confirm dimensions for images
```
State the count out loud in your reasoning. If the source is multi-file, list every file with its line count or size. The point: future-you cannot claim "I read the whole thing" without having seen the bound.
### 2. Read the FULL source — no truncation
For text: read every line. No `head`, no `| head -200`, no agent prompts that say "summarize." If the source is too large for one read window, slice it in spans and confirm you covered 100% of the line count from step 1. For PDFs: `pdftotext -layout file.pdf - | wc -l` first, then read every line from line 1 to N.
For images: re-view at full resolution, not a thumbnail. For tables, read every cell — every row × every column.
For multi-source web ingest: read every page that was fetched, not the search snippets that surfaced them.
### 3. Diff the synthesis against the source
Open your existing synthesis next to the source. For each section of the source (paragraph, bullet, table row, image cell), ask: **does my synthesis reflect what this says, or did I skim past it?**
This is the adversarial step. The mindset is: "I'm trying to find what I missed, not confirm what I got." If everything reflects, the synthesis is solid. If items are missing, list them.
### 3b. Quotation-mark audit (every quoted string, no exceptions)
The diff in step 3 asks *"did I miss anything?"* This step asks the opposite: *"did I invent anything?"* Omission and fabrication are different failures and step 3 only catches the first.
**Extract every string in the synthesis that sits inside quotation marks. For each one, find it in the source and match it character by character.** Not "is this the gist" — is this *the string*. There is no partial credit; a quote is either verbatim or it is not a quote.
Three failure shapes, in rising order of danger:
1. **Cleaned** — disfluencies, filler, and stutters removed (`"that that"` → `"that"`, dropped `"you know"`). Acceptable *if* meaning is untouched. Prefer `[…]` or a bracketed note.
2. **Stitched** — two or more non-adjacent turns fused into one quotation. Must be marked as such, never presented as a single utterance.
3. **Paraphrased-in-quotes** — a summary wearing quotation marks. **Always a defect.** Either quote it or don't, but never both.
**The tell to hunt for: a quote that is partly real.** Fabrications rarely invent whole cloth — they keep the source's distinctive tail and swap the subject and the verb. The surviving fragment is what makes it feel checked. If a quoted string *sounds* like the source but you cannot land it on a contiguous span of source text, it is not a quote — it is a reconstruction, and it must be rewritten as one.
Example of the shape: a note quoted a client as admitting *"[we] haven't figured out the costs on that properly yet."* The transcript said the *tool* "does not actually have the ability for me to control costs on that properly yet." A missing product capability was reported as unfinished homework at the client, and a downstream recommendation was built on the inversion. Every other quote in that section was verbatim — which is precisely why nobody looked twice.
**When the source cannot be reached** (paywalled sheet, permissions-scoped doc, deleted thread), a quotation from it is **unverifiable, not verified**. Say so explicitly next to it. An unverifiable quote may be entirely correct — but no future audit can ever confirm it, and it must never be treated as settled.
### 3c. Framing audit — check what the quote is said to PROVE, not just what it says
3b asks *"is this quote real?"* This asks *"is the sentence next to it real?"* A verbatim quote can sit inside a false frame, and the frame is what gets acted on. 3b passes it every time, because the quote is fine.
**Audit every attribution and sequence word attached to a quote.** The high-risk vocabulary is small and worth memorising:
- **sequence** — *unprompted · before I raised it · independently · without being asked · first · spontaneously*
- **strength** — *confirms · corroborates · proves · validates · agrees* (vs. the weaker truth: *did not object · went along with it*)
- **authority** — *the client said · the vendor states · X's own position* (vs. someone repeating what they heard)
For each, land it on the transcript and check **turn order**. Who spoke first? Did the second speaker open with assent (*"yeah, I agree"*, *"right"*, *"exactly"*) before adding their content? **Assent-then-detail is not independent corroboration** — it is agreement plus, at best, a detail the first speaker could not have supplied. That residue is often still valuable; say precisely what it is.
**Follow the claim downstream.** The escalation usually is not in the note — it is in the task, memo, or email *derived* from the note, written later by someone with less of the source in view. If the extraction feeds a downstream record, re-read that record against the source too, not just against the note. **A claim that gained confidence between two records without gaining evidence is the defect.**
**Rule of thumb:** if a framing word makes a finding *more useful to argue with*, it is exactly the word to check. Convenience and accuracy drift apart quietly, and the direction of drift is never random.
### 3d. Check the other direction — when the synthesis carries quotes or attributed claims
Steps 1–3 look for **omission**: what the source says that the synthesis dropped. They cannot catch
the opposite defect — a claim in the synthesis that traces to nothing, or to the wrong speaker. A
fabricated claim survives steps 1–3, because nothing in the source contradicts it; it simply is not
there. 3b and 3c catch it for quoted strings; this step covers figures, dates and paraphrased
attributions too, with a fresh reader.
**Run this when the synthesis contains a direct quote, a figure, a date, or a claim attributed to a
named person.** Skip it when the synthesis is your own summary prose with nothing attributed.
```
Agent(
subagent_type="evidence-auditor",
description="Verify the synthesis's claims trace to the source",
prompt="Synthesis: <paste>. Source: <paths, with the line bound from step 1>. Work synthesis-to-source, the opposite direction from a completeness check: for EACH direct quote, figure, date and claim attributed to a named person, report TRACES / MISATTRIBUTED / NOT IN SOURCE, naming the source line that decides it. A quote that is close but not verbatim is MISATTRIBUTED, not TRACES. Do not report anything the synthesis omitted — that is already covered. No edits."
)
```
Anything back as MISATTRIBUTED or NOT IN SOURCE is corrected against the source or cut before the
synthesis moves on. A wrong attribution is not a smaller error than a miss — it is the one a reader
cannot detect.
### 4. Categorize each missed item
For every item the diff surfaces:
- **Synthesis addition** — a finding that just needs to land in the existing doc. Add it.
- **Deliverable-shape change** — something that changes how the downstream deliverable should be structured (new section, removed section, reframed section). Flag explicitly to the user before continuing.
- **New task** — something that becomes a pre-flight or pre-deliverable item the calling workflow needs to track. Create the task; don't just note it.
- **Risk** — something that could collapse the engagement scope if missed. Flag urgently to the user.
### 5. Document the second-pass result
Before declaring extraction complete, state:
- What the source bound was (line count, image dims, page count)
- What the diff produced (Nothing missed / N items found, categorized)
- What the quotation-mark and framing audits (3b, 3c) found
- Whether step 3d ran, and what it returned (or why its trigger did not apply)
- Whether any items required deliverable-shape changes or new tasks (and which)
This is short — 3–5 lines in the working doc or chat. Its purpose is leaving a trace so future-you (or a fresh session) can tell the second pass actually happened, vs. was claimed.
## The output
Concrete: an updated synthesis, plus (when applicable) new tasks, deliverable-shape flags, and a 3–5 line second-pass note in the working doc.
If the second pass surfaces zero misses, that's a valid outcome. State it explicitly: "Second pass: read all 437 lines + image at full res; nothing missed." Don't skip the documentation.
## Why this works
1. **Explicit comparison forces close reading.** Diffing synthesis-vs-source forces every cell, every row, every paragraph to be acknowledged. First-pass reading lets the eye skip.
2. **Forces full-source consumption.** "Did I read every line?" is binary. Synthesis-driven reading is continuous and hard to bound.
3. **Decouples extraction from synthesis.** First pass mixes both — read a paragraph, decide if it's important, maybe note it. Second pass separates them — re-read as data, not as input to synthesis.
4. **Catches truncation defaults.** `wc -l` first, then read all of them, surfaces silent truncation that head/limit-style reads hide.