Install
$ agentstack add skill-lunarcommand-claude-skills-adversarial-review ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Adversarial review skill
Generates review findings from scratch. This is the pre-merge self-review counterpart to pr-review (which triages existing comments). Its whole reason to exist is to catch the defects a diff-scoped bot structurally can't: whole-system, failure-mode, and consistency bugs. The method's power comes from independent lenses and adversarial verification — preserve both.
Input
$SCOPE — free text describing what to review and, optionally, what to focus on. The agent interprets it; it is not a rigid parser. Accepted forms:
- A file or directory —
app/services/payments.py,app/api/. - A PR number —
PR #123or123. Pull the diff and the changed files. - A diff / "the current change" — the default when nothing is given: the
uncommitted work, or if that's empty, the branch vs its merge base.
- A topic or subsystem —
the upstream fetch retry path,cache invalidation.
First resolve which files it means (grep/explore), then review those; a topic is inferred scope, so it's less precise than naming files.
- Any of the above plus focus instructions — `app/services/orders.py — focus on
transaction/rollback semantics, or the checkout endpoint; I care most about the concurrency angle, skip style nits`.
Delta mode: reviewing changes made since a previous review
When this skill has already reviewed the change and work continued afterwards (fixes for the findings, a new requirement, a follow-up commit), do not review the whole thing again, and do not skip it either. Review the delta:
- Set
args.baseRefto the previously-reviewed commit andargs.reviewRefto
the current one, so the scope is literally git diff .
- Say in
args.contextthat the baseline was already reviewed and what it
validated, so the lenses do not re-derive settled ground.
- List the prior findings and their fixes, with the instruction: do not
re-report the original issue, but do check whether each fix is correct, complete, and free of new defects. A fix is unreviewed code.
- Fence off settled design decisions explicitly ("do not re-litigate X"),
or a fresh panel will re-argue choices you already worked through.
- Measure the delta first and say how big it is. Post-review fix batches are
routinely large enough to deserve their own review: signature changes, new logic, and relocated call sites all hide in them.
This is worth doing because the reviewed artifact and the merged artifact are not the same thing. It has found a false negative in a default code path that the full review of the baseline never reached.
Separate the two parts of whatever you're given:
- The scope decides which files to pull into context (Step 1).
- Any focus / emphasis / exclusion is threaded into the assembled context so the
lenses weight their passes accordingly — and on the workflow path it goes into args.context verbatim so it reaches the lens agents. Honor exclusions ("skip nits"), but never let a focus instruction suppress a blocker in another area: surface those regardless, flagged as outside the requested focus.
Step 0 — Protect the working tree (do this first, every time)
The strongest protection is worktree isolation: when the reviewed state is committed, every agent runs in its own throwaway checkout (Step 3b), so a stray mutating git command rewrites a sandbox and can never reach the user's real tree. It's preventive, not reactive — prefer it whenever it's available. A worktree only holds committed work; the steps below decide whether isolation is on the table and keep a git snapshot guard for when it isn't.
> The worktree is cut from the DEFAULT BRANCH, not from current HEAD. A > review commit sitting on a feature branch is therefore not checked out inside > it — the agents see the pre-change files. Isolation protects the tree; it > does not deliver the change. So whenever you set args.isolate: true you > MUST also pass args.reviewRef (and args.baseRef), which the workflow turns > into a standing instruction to read changed files via git show :. > This has already produced a wrong review: three verifier agents refuted a real > blocker as "factually false" because the offending entry was absent from > their checkout. Also put the diff itself in args.context so the change is > reachable even without git.
- Check whether the tree is dirty:
git status --porcelain. - If the reviewed state is already committed (a PR, or a committed branch vs
its merge base), set args.isolate: true and args.reviewRef (Step 3b) and proceed — the agents run isolated and cannot touch the tree.
- If it is dirty and the scope is the local diff, do not start yet. Offer, in
order of preference:
- (a) commit to a WIP/branch first — recommended: it captures the work
AND unlocks worktree isolation (set args.isolate: true and pass the new commit as args.reviewRef — without it the isolated agents cannot see the change at all), the only option that makes the agents physically unable to mutate the tree. This commit is scaffolding for isolation, not the final state: once the review and any fixes have landed, restore the uncommitted working state (git reset --soft , e.g. the branch point or main) so the reviewed change + fixes remain as uncommitted edits to review in the editor — unless the user explicitly wants the commit kept to push/PR immediately.
- (b)
git stash— noting the review then sees nothing. - (c) proceed in place, uncommitted — explicitly accepting the risk: agents
run in the real tree, args.isolate stays false, and the only guards are the read-only mandate and the snapshot below. Wait for the user's choice.
- Snapshot before the fan-out (cheap, and the fallback guard when not
isolated): ``bash SNAP="${CLAUDE_JOB_DIR:-/tmp}/tmp"; mkdir -p "$SNAP" git status --porcelain > "$SNAP/ar_tree_before.txt" git diff HEAD > "$SNAP/ar_diff_before.txt" # UNTRACKED files are invisible to git diff HEAD, so copy them too or the # snapshot silently fails to cover brand-new files (a new module, a new test). # tar -T - reads the NUL-separated list on stdin in ONE invocation. Piping # through xargs instead loses files: past ARG_MAX xargs runs tar repeatedly # and czf recreates the archive each time, so only the final batch survives # (measured: 64 of 3000 files). It also avoids xargs -r, which is GNU-only. git ls-files --others --exclude-standard -z \ | tar czf "$SNAP/ar_untracked_before.tgz" --null -T - # SUBMODULES are also invisible to git diff HEAD (it reports only a changed # POINTER, never dirty content inside). Record their state separately. git submodule status --recursive > "$SNAP/ar_submodules_before.txt" 2>/dev/null || true git submodule foreach --recursive --quiet \ 'git status --porcelain | sed "s|^|$displaypath |"' \ > "$SNAP/ar_submodule_dirt_before.txt" 2>/dev/null || true ``
If the change adds new files, say so when offering option (c): the snapshot's coverage of them is the weakest part of an in-place review.
This step exists because it has already gone wrong: a lens agent ran git checkout to compare pre-change behaviour and silently reverted a file holding uncommitted work. Worktree isolation is the enforcement that a prompt rule (READ_ONLY_MANDATE) can only request — a sandboxed agent's git checkout rewrites its own throwaway checkout, not the user's file. The snapshot is the last line for the one case isolation can't cover: a deliberate in-place review of uncommitted work.
Step 1 — Assemble context (do this before any reviewing)
Context quality is the single biggest determinant of review quality.
- The change itself — the diff, and the full text of every changed file
(not just hunks).
- Collaborators — for each changed file, pull its callers and callees and any
config/constants it depends on, including unchanged files. Grep for callers; read the config. (Defects hide in the interaction between a changed file and an unchanged one — e.g. an engine's isolation setting deciding whether a rollback in another file even works.)
- Invariants — read the target repo's
CLAUDE.md, especially an
"Operational Invariants" section if present. These are non-negotiables; a violation is a blocker. If none exist, infer them and note that they're unwritten.
Step 2 — Choose scale (and understand the fidelity tradeoff)
The two paths are not equal-fidelity — this is the most important choice here.
- Inline (this agent runs the lenses in its own context) — a quick, lighter
structured review. Good for one file, a small focused diff, or a fast sanity check. Its limitation: the lenses run in a single context, so they bleed toward one averaged review, and the refutation is the same mind that made the finding — i.e. it partly reintroduces the single-pass weakness the method exists to fix. Cheap and conversational. Go to Step 3a.
- Workflow (the bundled multi-agent engine) — the full-fidelity path, and the
one that earns the method its keep. Each lens is a separate agent (genuinely independent), findings are merged into distinct defects, then each is verified by independent refuters before it surfaces. Use it for a PR, several files, a release check, whenever the user asks for "thorough" / "deep" / "adversarial", or whenever the answer actually matters. Heavier and slower (runs in the background). Go to Step 3b.
When in doubt, prefer the workflow: inline is the convenience, the workflow is the method.
Step 3a — Inline lenses
Run each lens below as its own focused pass — do not merge them into one "review everything" prompt. For each pass, the instruction is "try to break this," never "review this." Describe nothing; find the input, state, timing, or failure that makes it wrong. An empty result for a lens is a valid answer — say so and move on.
Then run Step 4 (refute) and Step 5 (rank + report).
Step 3b — Workflow escalation
Two engines ship with this skill. Pick by what is under review:
| Engine | Use it for | | --- | --- | | adversarial-review.workflow.js | Code, or a mixed code+spec change. The default. | | spec-accept-review.workflow.js | A spec/RFC change — normative prose and conformance fixtures — about to be committed, tagged, or published. |
Resolve the path first — never guess it and never glob for the file. More than one copy of this skill can exist on a machine and they drift independently, so a glob can hand the Workflow tool a stale engine. Run:
adversarial_review_path.sh adversarial-review.workflow.js
That prints the absolute path of the engine inside the copy of the skill that is actually loaded. Pass the result verbatim as scriptPath.
Then call the Workflow tool with that path and the assembled context as args:
Workflow({
scriptPath: "",
args: {
scope: "",
context: "",
invariants: "",
targetKind: "code" | "spec" | "any", // optional, defaults to "any"
isolate: true | false, // Step 0: true when the reviewed state
// is committed, false for in-place work
reviewRef: "", // REQUIRED when isolate is
baseRef: "" // true — the worktree is at
// the DEFAULT BRANCH, so without these
// the agents never see the change
}
})
Set targetKind from what you actually read in Step 1 — you already know whether the changed files are source or prose:
spec— the changed files are specs, schemas, docs,.md/.yaml/IDL, with
no meaningful executable logic. Skips the three code lenses.
code— source changes with no spec/prose component. Skips the two spec lenses.any(default, and the right choice whenever unsure) — mixed changes, or a
spec repo that also ships a reference implementation, which is exactly where spec↔implementation drift lives and where you want both sets running.
The workflow fans the lenses out in parallel, verifies each finding by refutation (diverse angles, majority survives), dedupes, and returns findings ranked by severity. Relay its result via Step 5.
The spec/RFC engine
For a spec or RFC change about to be committed, tagged, or published, use spec-accept-review.workflow.js instead. It carries lenses tuned to normative prose and conformance fixtures — a fixture that can pass wrongly, a stale cross-reference, a coverage gap against precedent, a CHANGELOG date that does not match the tag day. It takes only two args:
Workflow({
scriptPath: "",
args: {
scope: "",
context: ""
}
})
There is no isolate option, and that is deliberate: this engine reviews uncommitted work in the real tree, and a git worktree can only hold committed work. Nothing enforces read-only here except the prompt mandate, so Step 0's snapshot is not optional on this path — take it before you call.
On worktree isolation. Set args.isolate: true and the workflow runs every lens, merge, and verify agent in its own throwaway git worktree — via the harness's built-in isolation: 'worktree', so there are no shell commands and no added permissions, and the worktrees are auto-cleaned. A destructive git command then rewrites a sandbox instead of the user's tree: this is the enforcement the READ_ONLY_MANDATE prompt rule can only ask for. It is not a substitute for Step 0's judgement — a worktree holds only committed work, so uncommitted work is invisible inside it. Set it whenever the reviewed state is committed (a PR, a committed branch, or after a Step 0 commit); leave it false only for a deliberate in-place review of uncommitted work, which then relies on the read-only mandate and the snapshot guard.
Isolation does not deliver the change — you must. The worktree is cut from the default branch, so on a feature branch the agents open pre-change files. Always pass args.reviewRef (+ args.baseRef) alongside isolate: true; the workflow turns them into a standing instruction to read changed files with git show : and to never infer absence from the working copy. Put the diff in args.context as well, so the change survives even if an agent ignores git entirely. Skip this and the run still looks healthy — agents review the old code and report confidently on it.
Step 4 — Refute every finding (inline path)
Before surfacing anything, try to refute each finding — but refute on validity, not severity:
- REFUTE only if the finding is wrong: the claim is factually false, it describes intended
behavior, or the proposed fix would regress or is unnecessary. A finding that is factually correct but low-impact is not refuted — it survives as a nit (adjust its severity down; don't discard it). Do not conflate "minor" with "invalid."
- "Reproduce it" means different things by target. For a runtime bug, construct the concrete
input/state that triggers it — if you can't, it's likely not real. For a spec / docs / config / prose target, most real defects have no triggering input: "reproduction" is showing concretely how the artifact misleads a reader, makes two conforming implementations diverge, contradicts another section, or states something false. Don't drop a real consistency / accuracy / parity defect just because it has no runtime repro — that filter is code-calibrated and mis-fires on documentation.
- No charitable-reading dismissals. If a claim is false or a reference ambiguous under a plain
reading, that's a real defect even if a generous interpretation exists.
- **Never refute on "I looked an
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: LunarCommand
- Source: LunarCommand/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.