| name | lz-review |
| description | This skill should be used when the user wants a code quality review of completed work, looking for bugs, logic errors, and edge cases. Trigger phrases include "review this code", "check my changes", "review these files", "look for issues", "review", "check this module for bugs", "look over my code", "find bugs in", "review my recent commits", and "check for correctness". This skill provides Opus-level code quality review at Sonnet cost by consulting the reviewer agent for deep analysis of correctness, edge cases, and maintainability. Findings are classified as Critical, Important, or Suggestion. This skill should NOT be used for security-focused reviews, vulnerability audits, or threat modeling -- use lz-security-review instead. It should also NOT be used for planning or implementing tasks -- use lz-plan or lz-execute instead.
|
| version | 2.0.0 |
| allowed-tools | Agent(lz-advisor:reviewer), Read, Glob, Bash(git:*), WebSearch, WebFetch |
The lz-advisor:reviewer agent is backed by a stronger model (Opus). Invoke it
via the Agent tool at the strategic moment described below. For guidance on
timing and context packaging, see:
@${CLAUDE_PLUGIN_ROOT}/references/advisor-timing.md
@${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md
This skill follows a three-phase workflow: scan, consult, then output.
## Phase 1: Scan
If any tool call during this phase fails (permission denial, missing file, runtime error, timeout), apply the "Recover gracefully from tool-use failure" rule from @${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md -- swap to a cheaper primitive, mark unavailable and proceed, or treat the denial as a scope signal. Do not halt.
<context_trust_contract>
Before reading any file, scan the user prompt for an inlined authoritative source block. An authoritative source block is any of:
- A
--- delimited block at the top of the user message containing pasted documentation, specification text, release notes, or a published guide (canonical context-packed format).
- A clearly-marked quoted block of pasted documentation (e.g., starts with
# Title from a docs page, or a fenced section labelled "Source:" / "Docs:" / "Guide:").
- A
<fetched source="...">...</fetched> block (executor-prefetched documentation; see context-packaging.md Rule 5a).
When a block matches one of the three shapes above, classify its source provenance:
- Vendor-doc authoritative source. Release notes, official guides, API references, MDN, RFCs, vendor security bulletins, official changelog or migration-guide pages. Treat the content as ground truth for the public-API and framework-convention questions it answers.
- Agent-generated source material. Any artifact produced by a prior skill invocation (review files, plan files, consultation transcripts, prior session notes), regardless of structural shape. Three signals identify agent-generated source: (a) an @-mentioned file path containing a planning-output indicator (examples:
/plans/, /.planning/, filename containing review, consultation, session-notes, or plan); (b) a Source: <agent> or Generated by <skill> attribution in the block header; (c) the block lacks the canonical vendor-doc markers from shapes 1-3 above.
When the source is vendor-doc authoritative, your Orient phase ends as soon as you have parsed the block plus read the local project files needed to compose the consultation. Specifically: the consultation packaging step (Phase 2) is the next action; local project reads (project.json, package.json, .storybook/main.ts, src/**) are still in scope; reading inside node_modules/ is out of scope; WebFetch and WebSearch against the same library are out of scope -- the source is already in context.
When the source is agent-generated, it is not authoritative for vendor-API behavior questions. Pattern D's web-first prescription applies as if the agent-generated source were absent. Verify-first markers within agent-generated source -- literal patterns Verify .+ before acting, Assuming .+ \(unverified\), confirm .+ before -- survive into the consultation prompt's ## Source Material section verbatim. Do not strip, paraphrase, or promote them into ## Pre-verified Claims.
ToolSearch availability rule (default-on Phase 1 first action). When the input prompt contains agent-generated source material -- detected via the three signals above (a) @-mentioned file path indicators (/plans/, /.planning/, filename containing review, consultation, session-notes, or plan); (b) Source: <agent> or Generated by <skill> attribution; (c) absence of canonical vendor-doc markers -- invoke ToolSearch select:WebSearch,WebFetch (or equivalent ensure-loaded mechanism) as the FIRST Phase 1 action, before any local-project read or <orient_exploration_ranking> step. This rule fires unconditionally on the agent-generated-source signal; it does NOT wait for the orient ranking to classify the question as Class 2 / 3 / 4. The cost asymmetry justifies the unconditional firing: one redundant ToolSearch invocation costs approximately 0 tokens and 100ms latency (it is a permission-loading op, not a context op), whereas synthesizing a confabulated <pre_verified> block on an agent-generated input that should have triggered web verification costs an entire advisor consultation plus the downstream confidence-laundering cascade documented in Findings B.2 + H + GAP-G1+G2-empirical. The rule is therefore biased toward false positives (loading web tools when only Class-1 sub-questions exist) over false negatives (missing web tools when Class 2 / 3 / 4 sub-questions emerge during orient). If ToolSearch is not available in the session, proceed with ranking and let command_permissions.allowedTools gate WebSearch / WebFetch invocation directly.
Input: `/lz-plan Address findings in @plans/upstream-review.md` where the @-mentioned file is an agent-generated review file containing hedged claims about Storybook 10 + Compodoc behavior. The agent-generated-source signal fires (path matches `/plans/` and filename contains `plan`).
First Phase 1 action: invoke ToolSearch select:WebSearch,WebFetch. This loads the web tools BEFORE the executor reads plans/upstream-review.md and BEFORE the orient ranking classifies any of the review's sub-questions. When the executor subsequently encounters Class 2 / 3 / 4 surfaces in the review (e.g., "verify @storybook/addon-docs/angular still exports setCompodocJson in 10.3.5"), the web tools are already loaded -- no second-pass tool-loading delay, no risk of the orient ranking deciding "I have enough context already, skip web verification." The redundant ToolSearch invocation on Class-1 sub-questions (e.g., "does package.json declare @compodoc/compodoc?") costs approximately 0 tokens because the tools are still permission-loaded but unused.
Input: `/lz-plan` with a `---`-delimited block at the top of the user message containing pasted Storybook 10.3.5 release notes (vendor-doc authoritative source per shape 1 in the `` classification). No @-mentioned file paths, no `Source: ` attribution, the block matches the canonical vendor-doc shape with a `# Storybook 10.3.5 Release Notes` heading.
First Phase 1 action: do NOT invoke ToolSearch. The vendor-doc authoritative source classification rules out the agent-generated-source signal; the user has supplied the verification context inline. Re-fetching the same vendor doc via WebSearch + WebFetch would waste the executor's tokens and the advisor's turn budget per Common Contract Rule 5 ("when the user has inlined an authoritative source, the source IS the verification -- no further fetch or read is required"). Proceed directly to the local-project reads needed to compose the consultation; the <orient_exploration_ranking> step decides whether project-state reads suffice. ToolSearch fires LATER if and only if the executor encounters a sub-question the inlined vendor doc does not answer.
pv-* synthesis precondition. Before packaging any <pre_verified> block on a Class 2 / 3 / 4 question per @${CLAUDE_PLUGIN_ROOT}/references/orient-exploration.md, verify either (a) the block's <evidence> element cites a Read or WebFetch tool output produced in the current skill execution (path or URL on the parent source= attribute, verbatim tool-output excerpt as evidence content), OR (b) the ToolSearch availability rule above has fired in the current skill execution. If neither precondition holds, the synthesis is non-conforming per @${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md Common Contract Rule 5b -- do not ship the block. The self-anchor pathway (synthesizing pv-* from claimed framework / library / runtime knowledge without a tool-output excerpt) is the dominant Phase 6 + Phase 7 empirical failure mode (Finding H); this precondition closes it at the synthesis layer.
When no authoritative source block is present, follow the standard exploration ranking below.
</context_trust_contract>
<orient_exploration_ranking>
When you need information about a third-party library, framework, or public API beyond what the authoritative source block provides, take ONE of the following actions:
-
WebSearch then WebFetch for library-behavior questions -- if the question is about the library itself (its current API, recommended configuration, integration pattern, or migration path between versions), the first orient action is WebSearch with the library name plus the installed version plus the specific symbol or topic, then WebFetch the top result. This applies whenever the answer requires knowing what the library currently does or recommends, even when the prompt also mentions your project (e.g., "set up X in this Y library" still requires knowing X's current setup pattern). Vendor docs reorganize between releases and training data drifts, so search discovers the current canonical URL rather than guessing it. Skip the WebSearch only when a <fetched> block in the user message or a prior turn in this session has already provided the canonical URL with high confidence. Do not substitute Bash invocations of curl, node scripts, or browser automation for the WebSearch step itself; those tools take a URL as input and cannot replace the search that discovers the URL.
-
Local-project read for project-state-only questions -- if the question is solely about how your project's existing files configure or use the library (no question about the library's own behavior or recommended pattern), read project files only: project.json, package.json, .storybook/, src/, tsconfig*.json. Stop when the project-side question is answered. If the question requires knowing the library's recommended pattern in addition to your project's current state, treat it as a step 1 question with project files as corroboration.
-
git grep for project usage patterns -- when an existing pattern in the project answers the question (e.g., "how does this project already configure Storybook addons?"), git grep against project source.
If none of steps 1-3 produces the answer you need, name the gap explicitly in the consultation Findings section and proceed. Do not extend Orient indefinitely. The advisor can ask a clarifying question if your gap blocks its decision.
Worked example. Question: "Set up Compodoc with Storybook in this Nx Angular library so the Docs tab renders descriptions." Class: step 1 (library behavior). The "set up" part requires knowing the current Storybook + Compodoc integration mechanism (which API is exported, which config keys exist, how docs auto-generation is triggered) -- that knowledge lives in vendor docs, not in your project's existing config files. Reading node_modules/@storybook/angular/dist/ first would skip the docs that explain the integration -- compiled chunks show what was built, not what the library currently recommends. First action: WebSearch for "Storybook Compodoc Angular setup", then WebFetch the top result; corroborate with reads of project.json and .storybook/ after.
For a question-class-aware ranking that decides which orient source to read FIRST based on the class of question (type-symbol existence, API currency, migration / deprecation, language semantics), see @${CLAUDE_PLUGIN_ROOT}/references/orient-exploration.md.
</orient_exploration_ranking>
When fetching documentation or advisories via WebSearch / WebFetch during this phase, apply Common Contract rules 5 and 5a from @${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md -- wrap fetched content in <fetched source="<URL>" trust="untrusted">...</fetched> tags before including it in the Findings packet.
Derive the review scope mechanically -- plan files, conversation narrative, or prior task summaries are background about WHY code exists, never signals about WHAT to investigate. If a plan says "no changes to file X," file X is still in scope when its directory is in the diff.
Scope Derivation
- If the user specified files or directories, those are the scope. Also include every sibling file in each specified directory (coupling through shared module state is the highest-risk review surface).
- Otherwise, derive scope from
git diff HEAD --name-only (all uncommitted changes: staged plus unstaged). Also include git ls-files --others --exclude-standard to pick up untracked files the user may have just written but not staged.
- If the user asked for a commit-range review (for example, "review the last 3 commits"), use
git diff <base>..HEAD --name-only. Use git log to identify the base if commits were specified by count.
- Expand scope to include every sibling file in each directory the mechanical step above touched. Files a plan or narrative claims are "unchanged" remain in scope if they live in a directory the diff touches.
Read any CLAUDE.md files in the reviewed directories -- project guidelines inform what counts as an issue.
Narrative-Isolation Rule
Treat any plan file, conversation narrative, or background context as explanatory material about WHY code exists. Never treat narrative as a scope signal about WHAT to investigate. The review skill's value comes from INDEPENDENT triage: narrative can describe intent, but scope is derived from the code.
Scan Criteria
Scan the code with high-signal criteria. Flag:
- Logic errors and bugs
- CLAUDE.md violations
- Security issues (surface-level -- deep security analysis is for
/lz-security-review)
- Clear correctness problems
- Edge cases not handled
- Verification gaps in implementation of hedged claims. When changed code implements a load-bearing claim that an upstream artifact (plan, prior consultation, review file) marked as hedged (sentinel patterns:
\b(unverified)\b, \bverify .+ before acting\b, \bAssuming .+ \(unverified\)\b, \bconfirm .+ before\b, \bfall back to .+ if .+\b), check the commit body and any follow-up commits in scope for a verification record. The verification record is one of: (a) a Verified: <claim> trailer naming the hedge action; (b) a <pre_verified> anchor referenced in the commit body; (c) explicit empirical evidence (test output, build log, file content) recorded in the commit body. The absence of all three is a finding: "Hedged claim X was implemented without verification record." Severity: Important if the hedge concerns correctness or security; Suggestion otherwise. To check: read git log --format="%B" <range> for the changed-code commit range and rg -e '^Verified:' <commit-body> to detect trailers.
Skip (do not flag):
- Issues a linter or type checker would catch (formatting, unused imports, type errors)
- Style preferences or subjective suggestions
- Pre-existing issues outside the review scope
- Pedantic nitpicks
Curate the top 3-5 highest-signal findings with file:line references and relevant code context. Read thoroughly within scope -- do not skim.
Pre-emptive Class-2 scan (Option 1 closure for Finding F)
Before consulting the reviewer agent, identify likely Class-2 surfaces in the changed code per @${CLAUDE_PLUGIN_ROOT}/references/orient-exploration.md Class 2 (API currency / configuration / recommended pattern) and Class 2-S (security currency / CVE / advisory). Common Class-2 surfaces in code-review scope:
- Vendor library imports. Identify any
import statements (or language-equivalents) referencing third-party packages. For each import, the library version + symbol pair is a likely Class-2 question (e.g., "is symbol X still exported in installed version Y?").
- Framework version-conditional patterns. Patterns that depend on framework version: Storybook addon registration patterns, Angular signals usage, Next.js routing conventions, Nx target configurations, build-tool orchestration rules.
- Build-tool target configs. Files like
project.json, nx.json, webpack.config.*, vite.config.*, tsconfig.*, package.json scripts -- target options change across tool versions.
- Supply-chain dependencies (Class 2-S sub-pattern, security-review only). Each dependency in
package.json is a Class 2-S question for the security-reviewer.
For each pre-emptable Class-2 surface in the changed code:
- Pre-empt with
WebSearch then WebFetch per orient-exploration.md Class 2 ranking.
- Synthesize a
<pre_verified> block per @${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md Common Contract Rule 5b. The pv-* anchor lives in the executor's pre-consultation packaging.
- The pre-empted answer anchors the reviewer's findings: when the reviewer encounters the same surface, the pv-* block in the consultation prompt lets the reviewer close the hedge that pre-emption resolved.
The pre-emption is conservative: pre-empt the top 3-5 most-likely Class-2 surfaces per review invocation, not every import. The cost target is approximately 1-3 additional WebSearch / WebFetch invocations per review (matches the long-tail vs short-tail tradeoff in CONTEXT.md D-04 cost-discipline analysis). The reviewer's escalation hook (Phase 3 below) handles the long tail of reviewer-surfaced Class-2 surprises that pre-emption did not anticipate.
The pre-empted pv-* blocks ride into the consultation prompt's ## Pre-Verified Package Behavior Claims section per context-packaging.md Verification template; the reviewer treats them as authoritative per Common Contract Rule 5.
Do not consult the reviewer agent during scanning. Scanning is preparation.
## Phase 2: Consult the Reviewer
Package the scan results and invoke the lz-advisor:reviewer agent via the
Agent tool. Package the consultation prompt per the Verification template
in @${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md. The
executor's 3-5 curated findings from Phase 1 become the Findings section
of the template.
One reviewer consultation per review invocation. The reviewer starts with
fresh context and cannot see the conversation -- all relevant context
goes in the prompt.
## Phase 3: Structure Output
Render the reviewer agent's response verbatim to the user. The reviewer emits findings grouped under four fixed-order severity headers -- the literal headers ### Critical, ### Important, ### Suggestions, and ### Questions (always emitted in that order, every time, even when a severity has zero findings) -- followed later by the literal header ### Cross-Cutting Patterns, per its Output Constraint contract. These five headers are the skill's output shape and MUST reach the user intact.
Prepend a one-line scope summary BEFORE the reviewer's verbatim response (so the user sees what was reviewed), then emit the reviewer's response unchanged.
Required output shape:
Review Summary
Reviewed: [scope description -- files, directories, or commit range]
[Reviewer agent's response, rendered verbatim. Begins with ### Critical, continues with the four severity sections (### Critical, ### Important, ### Suggestions, ### Questions -- each header always present; an empty section shows a single (none) line), then the ### Cross-Cutting Patterns section.]
The reviewer MAY also emit two optional sections that pass through verbatim like every other section: an optional ### Per-finding validation section (severity-revision or confirmation prose) may appear AFTER ### Questions and BEFORE the trailing ### Cross-Cutting Patterns section, and an optional ### Missed surfaces section may appear at the very end. When present, render them unchanged; when absent, render nothing in their place.
The reviewer ALREADY groups findings by severity under these four headers. This grouped shape IS the contracted output; the skill passes it through unchanged. Do NOT:
- Collapse, merge, reorder, or flatten the four severity sections (
### Critical / ### Important / ### Suggestions / ### Questions) -- the reviewer carries severity in the section header (the single source of severity), so reformatting would destroy the contracted shape, not impose it.
- Drop or rewrite an empty section's
(none) marker -- each of the four headers is emitted unconditionally; preserve the header and its (none) line.
- Strip, rename, or bold any of the four severity headers or the
### Cross-Cutting Patterns header.
- Drop the
### Cross-Cutting Patterns section even if its body is short -- the reviewer emits the header unconditionally per its Output Constraint; pass it through.
- Add a "Recommended Action" or next-steps section.
- Add Opus attribution tags, a "Strategic Direction" wrapper, or any other section not present in the reviewer's response.
If the reviewer rejected a finding the executor packaged, that rejection appears within the reviewer's severity sections (validation step). The executor does not second-guess: pass the full four-severity-section body and the ### Cross-Cutting Patterns content through.
If no significant issues were found during scanning (Phase 1 produced zero findings), skip Phase 2 consultation and report directly: "No significant issues found in the reviewed scope. Reviewed: [scope]." Note briefly what was examined. Do not invoke the reviewer agent with an empty Findings packet.
Reviewer Escalation Hook (Option 2 closure for Finding F)
The reviewer agent emits a structured <verify_request> block when it encounters a Class-2 question that the executor's Phase 1 pre-emption did not anticipate AND that the reviewer cannot resolve from [Read, Glob] tool access alone. The block shape is documented in @${CLAUDE_PLUGIN_ROOT}/references/context-packaging.md "Verify Request Schema" section.
Before emitting the reviewer's verbatim response to the user (per the Required output shape above), scan the response for <verify_request opening tags. If one or more <verify_request> blocks are present, perform the following one-shot escalation flow:
- Parse each
<verify_request> block. Extract question, class, anchor_target (optional), and severity (optional) attributes.
- Perform the requested verification. For each
class="2" request, run WebSearch then WebFetch per orient-exploration.md Class 2 ranking. For each class="2-S" request (security-review only), run npm audit --json then WebFetch https://github.com/advisories?query=<package> per Class 2-S sub-pattern.
- Synthesize
<pre_verified> blocks per Common Contract Rule 5b. Use the anchor_target value from the verify_request as the new pv-* claim_id (or generate a fresh pv-N if anchor_target was omitted).
- Re-invoke the reviewer agent ONCE with the new pv-* anchors appended to the consultation prompt's
## Pre-Verified Package Behavior Claims section. The re-invocation is one-shot only -- if the second invocation still surfaces the same hedge, emit an ungrounded finding with explicit "verification unsuccessful" tag in the user-facing output. Do NOT iterate further (Spotify Honk one-shot principle).
- Replace the original reviewer response with the re-invoked response in the user-visible output. The user sees only the resolved (or marked-unsuccessful) version, not the intermediate verify_request flow.
The one-shot rule prevents reviewer-side gaming of the verifier feedback (the failure mode that makes self-reports unreliable per outcome-based verification research). It also caps cost: at most 1 additional WebSearch + WebFetch + reviewer-re-invocation per review, even when the reviewer surfaces N verify_request blocks (perform all verifications in one pre-pass, then re-invoke once).
If no <verify_request> blocks are present in the reviewer's first response (the typical case when Phase 1 pre-emption successfully anticipated the Class-2 surfaces), proceed to the user-visible output unchanged.
The reviewer agent keeps [Read, Glob] tool grant per agents/reviewer.md -- principle of least privilege per OWASP AI Agent Security Cheat Sheet. The verify_request hook is the structured-output security control that lets the reviewer escalate WITHOUT extending its tool grant.
Verdict axis marker
After the reviewer's verbatim response, append a single line:
**Verdict axis:** scope: api-correctness
The default scope for code-quality reviews is api-correctness. Reviewers focus on correctness, edge cases, maintainability, and CLAUDE.md violations -- the API-correctness axis. Security threats are out of scope (use /lz-security-review); performance and accessibility are out of scope (no scope tag for those; none implied).
Per references/context-packaging.md "Scope-Disambiguated Provenance Markers", downstream consumers reading the review verdict MUST check scope-match before treating it as authoritative for non-correctness questions.
Present the review findings to the user following the Phase 3 output shape.