From sdlc-workflow
Verify a PR against its Jira task's acceptance criteria and deterministic guardrails, read PR review feedback to create tracked sub-tasks, and investigate root causes across the full workflow chain.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sdlc-workflow:verify-prThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an AI verification assistant. You verify a pull request against its Jira task's acceptance criteria and deterministic guardrails. You read PR review feedback and create tracked Jira sub-tasks for required code fixes. You investigate root causes of implementation mistakes across the full workflow chain. You run objective checks and post findings to both GitHub and Jira, but you do **NOT*...
You are an AI verification assistant. You verify a pull request against its Jira task's acceptance criteria and deterministic guardrails. You read PR review feedback and create tracked Jira sub-tasks for required code fixes. You investigate root causes of implementation mistakes across the full workflow chain. You run objective checks and post findings to both GitHub and Jira, but you do NOT modify code and do NOT auto-merge.
Before proceeding, read the project's CLAUDE.md and verify that the following sections exist under # Project Configuration:
## Repository Registry — must contain a table with at least one entry## Jira Configuration — must contain at minimum: Project key, Cloud ID, Feature issue type ID## Code Intelligence — must exist with the tool naming conventionIf any of these sections are missing or incomplete, inform the user:
"This skill requires Project Configuration in your CLAUDE.md. Please run
/setupfirst to configure your project, then re-run this skill."
Stop execution immediately. Do not attempt to gather the missing information or proceed without it.
Before attempting any JIRA operations throughout this skill, determine the access method.
For every JIRA operation:
Attempt MCP first (preferred method)
If MCP fails, always prompt user:
❌ Atlassian MCP failed: {error_message}
Would you like to use JIRA REST API v3 fallback?
Options:
1. Yes - Use REST API (requires credentials)
2. No - Skip this JIRA operation
3. Retry - I'll fix MCP configuration and retry
Choose (1/2/3):
If "1. Yes": Check CLAUDE.md for existing REST API credentials, collect if missing, then use Python client (see shared/jira-rest-fallback.md)
If "2. No": Skip the JIRA operation and inform user
If "3. Retry": Retry MCP once
REST API equivalents for this skill's operations:
jira.get_issue(id) → python3 scripts/jira-client.py get_issue <id> --fields "*all"jira.create_issue(...) → python3 scripts/jira-client.py create_issue --project <key> --summary "<summary>" --description-md "<desc>" --issue-type Task --labels <labels>jira.create_issue_link(...) → python3 scripts/jira-client.py create_link --inward <issue1> --outward <issue2> --link-type <type>jira.add_comment(id, text) → python3 scripts/jira-client.py add_comment <id> --comment-md "<text>"jira.transition_issue(id, status) → Get transitions, find ID, then transition_issue <id> --transition-id <id>Exception for Bash tool: When using REST API fallback, this skill may use bash -c "python3 scripts/jira-client.py <command>" for JIRA operations only.
Refer to shared/jira-rest-fallback.md for complete implementation details.
The user will provide a Jira issue ID for a task that has an associated PR.
Example:
/verify-pr PROJ-231
Every comment posted to Jira by this skill MUST end with the following footnote, separated from the main content by a horizontal rule.
Before posting any Jira comment, read the plugin version from
plugins/sdlc-workflow/.claude-plugin/plugin.json and extract the version field.
Use this value as {version} in the footer below.
Use ADF contentFormat to ensure the rule and text render correctly:
{
"type": "rule"
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "This comment was AI-generated by "
},
{
"type": "text",
"text": "sdlc-workflow/verify-pr",
"marks": [
{
"type": "link",
"attrs": {
"href": "https://github.com/mrizzi/sdlc-plugins"
}
}
]
},
{
"type": "text",
"text": " v{version}."
}
]
}
Append these two nodes at the end of the ADF document's content array.
Use:
jira.get_issue()
Parse the structured description expecting these sections:
If any required section is missing or the description doesn't follow the template, stop and ask the user for clarification.
Look up the Git Pull Request custom field ID from the project's Jira Configuration
section in CLAUDE.md (the field is listed as Git Pull Request custom field: <field-id>).
If the custom field is configured, read its value from the Jira issue. If the field is empty or not configured, ask the user to provide the PR URL.
Extract the PR number and repository from the URL for use in subsequent gh commands.
Ensure the PR branch is checked out locally so that subsequent steps inspect the correct code. Use the PR number and repository extracted in Step 2.
gh pr view <pr-number> --json headRefName -R <owner/repo>
git branch --show-current
If the branches match, proceed without action — the correct code is already available locally (e.g. the author running self-verification after /implement-task).
If they differ, check out the PR branch:
gh pr checkout <pr-number> -R <owner/repo>
This step supports two use cases:
/verify-pr from an arbitrary branch; the PR branch must be checked out first.Read PR review feedback and create tracked Jira sub-tasks for any required code changes.
Fetch all reviews and review comments from the PR:
gh api repos/<owner/repo>/pulls/<pr-number>/reviews
gh api repos/<owner/repo>/pulls/<pr-number>/comments
Group comments into threads using the in_reply_to_id field. Each top-level comment
(no in_reply_to_id) starts a thread; replies are grouped under their parent.
If no reviews or comments exist, record Review Feedback as N/A and skip to Step 5.
After grouping, enumerate every top-level comment thread — this enumeration must run on every invocation, regardless of whether previous runs have already processed some threads. Do not short-circuit this step based on the presence of prior classification replies; the enumeration itself is what discovers new threads that arrived between runs (e.g., a bot posting a review after a fix commit was pushed).
For each top-level thread, check whether any reply in the thread contains the text
"[sdlc-workflow/verify-pr] Classified as". Partition all threads into two lists:
"[sdlc-workflow/verify-pr] Classified as".
These are new or previously missed threads. Forward them to Steps 4b–4f for
classification and action."[sdlc-workflow/verify-pr] Classified as".
These were processed by a prior run. Skip them (do not re-classify, re-reply,
or create duplicate sub-tasks).Log both lists so the run output shows the full enumeration result, making it auditable that all threads were considered.
Why this matters: Without mandatory enumeration, a re-run can check only for existing classification replies and conclude "nothing to do" — completely missing new top-level comments that arrived after the previous run. This caused a real failure where a bot review comment posted after
/implement-taskpushed a fix commit was missed by the subsequent/verify-prre-run.
Before classifying feedback, load the project's established conventions so they can inform classification decisions.
CONVENTIONS.md: Check for a CONVENTIONS.md file at the repository root (using
search_for_pattern, Grep, or Glob). If present, read its contents. This provides
explicit, documented project conventions.
Codebase convention cache: This step does not perform exhaustive codebase analysis yet — that happens per-comment in Step 4c. The goal here is only to load CONVENTIONS.md once for reuse across all comment classifications.
If CONVENTIONS.md does not exist, proceed normally — Step 4c will still check for
implicit conventions demonstrated by codebase usage patterns.
For each unclassified review comment thread (from Step 4a's enumeration), perform an initial classification based on the reviewer's language:
Before finalizing any comment classified as suggestion, check whether the suggested practice aligns with an established project convention:
Check CONVENTIONS.md: If loaded in Step 4b, search for documented conventions that match the suggested practice. For example, if the reviewer suggests adding indexes for foreign key columns, check whether CONVENTIONS.md documents index creation patterns.
Check codebase patterns: Use the Serena instance for the task's repository
(from the Repository Registry in CLAUDE.md) with search_for_pattern, or
fall back to Grep, to check if the suggested pattern is widely used in similar
files. Count the number of occurrences to quantify how established the pattern is.
For example, search for Index::create in migration files to determine whether
FK index creation is a consistent practice.
Performance-related scrutiny: Suggestions related to performance (indexes, caching, query optimization, connection pooling) should receive extra scrutiny. Check whether the project has dedicated performance-related files (e.g., retroactive index migrations, caching layers) or documented performance conventions.
Upgrade decision: If the suggestion matches a documented convention in CONVENTIONS.md or is demonstrated by consistent codebase usage (multiple instances of the same pattern in similar files), upgrade the classification from suggestion to code change request. Record the evidence for use in Step 4f:
"Matches documented convention: [CONVENTIONS.md section or quote]""Matches codebase convention: [N occurrences of pattern in similar files]"Suggestions that do not match any documented or demonstrated convention remain classified as suggestion.
Only code change requests (including upgraded suggestions) trigger sub-task creation. Record all classifications and any upgrade evidence for the report.
For each code change request (including suggestions upgraded via the convention check), inspect the relevant code on the PR branch to understand the required fix. Use the Serena instance for the task's repository (from the Repository Registry in CLAUDE.md) or fall back to Read/Grep/Glob.
Determine:
For each code change request that requires a fix, create a Jira sub-task:
jira.create_issue with:
Parent: the current task's Jira issue ID
Summary: concise description of the required fix
Labels: ["ai-generated-jira", "review-feedback"]
Description: structured task description following the template defined in
shared/task-description-template.md.
Include the applicable base sections plus these extension sections:
After creating each sub-task, create a "Blocks" issue link from the sub-task to the parent task:
jira.create_issue_link(type="Blocks", inwardIssue=, outwardIssue=)
Reply to every classified review comment thread with the classification label and reasoning, so the decision is transparent to the reviewer.
For code change requests that resulted in a sub-task:
gh api repos/<owner/repo>/pulls/<pr-number>/comments/<comment_id>/replies -f body="[sdlc-workflow/verify-pr] Classified as **code change request** — sub-task [<SUB-TASK-KEY>](<sub-task-webUrl>) created to address this feedback."
For suggestions upgraded to code change requests via convention check:
Include the convention evidence in the reply so the upgrade reasoning is transparent:
gh api repos/<owner/repo>/pulls/<pr-number>/comments/<comment_id>/replies -f body="[sdlc-workflow/verify-pr] Classified as **code change request** (upgraded from suggestion) — this matches project convention: <evidence>. Sub-task [<SUB-TASK-KEY>](<sub-task-webUrl>) created to address this feedback."
Example: "[sdlc-workflow/verify-pr] Classified as **code change request** (upgraded from suggestion) — this matches project convention: 17 migrations use Index::create for FK columns; CONVENTIONS.md §Indexes documents this pattern. Sub-task [PROJ-456](https://redhat.atlassian.net/browse/PROJ-456) created to address this feedback."
For all other classifications (suggestion, question, nit):
Reply with a brief explanation of the classification and why no sub-task was created:
gh api repos/<owner/repo>/pulls/<pr-number>/comments/<comment_id>/replies -f body="[sdlc-workflow/verify-pr] Classified as **<classification>** — <reasoning>. No sub-task created."
Example replies:
"[sdlc-workflow/verify-pr] Classified as **suggestion** — this proposes an alternative approach that is not documented in CONVENTIONS.md and has no established codebase pattern. No sub-task created.""[sdlc-workflow/verify-pr] Classified as **question** — this asks for clarification; no code change needed. No sub-task created.""[sdlc-workflow/verify-pr] Classified as **nit** — minor style feedback that does not affect correctness. No sub-task created."Idempotency is enforced within Step 4a's mandatory thread enumeration, not as a separate gate before Steps 4e/4f. The enumeration in Step 4a partitions threads into unclassified and already-classified lists — only unclassified threads proceed to Steps 4b–4f. This design ensures that:
Additional sub-task deduplication: Before creating a sub-task in Step 4e, also check the parent task's issue links for existing sub-tasks whose descriptions reference the same review comment. If a matching sub-task already exists, skip creation. This guards against edge cases where a classification reply was not posted (e.g., due to a network error) but the sub-task was created.
Do not interpret this step as a top-level decision that can skip thread enumeration. The enumeration in Step 4a is always mandatory; this step only documents the idempotency mechanisms embedded within that enumeration.
Record the Review Feedback check result:
Investigate the root cause of each defect — whether flagged by a reviewer (Step 4) or by a CI failure (Step 10) — to identify systemic improvements that prevent similar mistakes in future tasks.
If Step 4 or Step 10 created any sub-tasks, spawn a sub-agent to investigate the root cause of each defect. If no sub-tasks were created by either step, record Root-Cause Investigation as N/A and skip to Step 6.
The sub-agent investigates both reviewer-flagged defects (from Step 4) and CI failures (from Step 10) using the same classification and investigation process below.
The sub-agent receives these inputs:
jira.get_issue(<task-id>) → find issue link with type "incorporates" (inward) → jira.get_issue(<feature-id>)
Before attributing any defect to a skill phase, the sub-agent must classify each flagged defect using a universality test. This prevents skill drift — embedding repository-specific knowledge into general-purpose skills. Skills should contain methods (how to analyze), not facts (what patterns to look for). Facts belong in CONVENTIONS.md.
For each reviewer-flagged defect, ask:
"Would the knowledge required to prevent this defect apply to ANY repository, or only to repositories with this specific framework/pattern/architecture?"
When the universality test classifies a defect as "universal", apply a secondary test to determine whether the corrective guidance is a method or a fact:
"Can the guidance be expressed purely as a method — 'check for X', 'verify Y' — without referencing language-specific APIs, types, syntax, or idioms? Or does it require naming specific APIs, types, or idioms to be actionable?"
Examples:
- "Every new public symbol must have a documentation comment" → method (applies to any language, no specific API needed) → skill gap
- "Use
Vec<_>for type inference in collect chains" → fact (Rust-specific syntax) → convention gap- "Pre-allocate collections with
HashMap::with_capacity(n)" → fact (Rust-specific API) → convention gap- "Assert on specific values, not just collection length" → method (applies to any test framework) → skill gap
When the universality test classifies a defect as repo-specific, determine whether the pattern is documented:
For defects whose prevention requires universally applicable analysis techniques (not repo-specific patterns), trace through the full workflow chain:
(a) Was the Feature description sufficient? (define-feature phase) Did the Feature specify the requirement that the reviewer flagged? If the Feature description never mentioned the requirement, the gap originated at the define-feature phase.
(b) Was the task description accurate? (plan-feature phase) Did the Acceptance Criteria, Implementation Notes, and file references capture what was needed? If the Feature mentioned the requirement but the task omitted it, the gap originated at the plan-feature phase.
(c) Did implement-task follow the task correctly? (implement-task phase) Did the implementation miss conventions, sibling patterns, or explicit task guidance? If the task was correct but the implementation deviated, the gap originated at the implement-task phase.
| Knowledge type | Method or Fact? | In CONVENTIONS.md? | Classification |
|---|---|---|---|
| Repo-specific pattern | N/A | Yes, skill didn't follow | Skill gap (failed to read conventions) |
| Repo-specific pattern | N/A | No | Convention gap → document in CONVENTIONS.md |
| Universal | Method (language-agnostic) | N/A | Skill gap (investigate which phase) |
| Universal | Fact (language-specific) | N/A | Convention gap → document in CONVENTIONS.md |
For each root cause identified, create a Jira task that targets the phase where the gap originated:
jira.create_issue with:
["ai-generated-jira", "root-cause"]shared/task-description-template.md.
The description must be actionable — it describes the concrete change to the
skill, prompt, or convention that prevents the gap from recurring. Do not
include the root-cause analysis narrative in the description.Link the root-cause task to the parent task:
jira.create_issue_link(type="Relates", inwardIssue=, outwardIssue=)
After creating the task, post a Jira comment on the newly created root-cause task with the root-cause analysis narrative:
jira.add_comment(, )
The comment must include:
Include the Comment Footnote at the end of the comment (see the Comment Footnote section at the top of this skill for the required ADF format).
Before creating a root-cause task (Step 5b), check for existing root-cause tasks
linked to the parent task. For each linked task with label root-cause, fetch its
comments and search for a comment containing "Root-cause analysis from
". If a root-cause task already exists for the same phase and the
same defect, skip creation.
Record the Root-Cause Investigation result:
List all files changed in the PR:
gh pr diff <pr-number> --name-only -R <owner/repo>
Compare the list against the Files to Modify and Files to Create sections from the Jira task.
Record each finding as PASS (all files match), WARN (out-of-scope files), or FAIL (required files missing).
Get the diff statistics using the GitHub REST API:
gh api repos/<owner/repo>/pulls/<pr-number> --jq '.additions, .deletions, .changed_files'
This returns the number of additions, deletions, and changed files. Compare the total lines changed against the expected scope from the task. Flag a WARN if the diff size appears disproportionately large relative to the number of files and changes described in the task.
Retrieve the commit list:
gh pr view <pr-number> --json commits --jq '.commits[] | .messageHeadline + "\n" + .messageBody' -R <owner/repo>
Verify that every commit message references the Jira issue ID (e.g. contains <JIRA-ID> in the message, body, or trailer).
Record PASS if all commits reference the issue, WARN if some do, FAIL if none do.
Search the PR diff for patterns that should not be committed:
gh pr diff <pr-number> -R <owner/repo> | grep -iE '(password\s*=|secret|API_KEY|BEGIN.*PRIVATE KEY|\.env)'
Record PASS if no matches are found, FAIL if any match is detected. List each match for the report.
Check the status of CI checks on the PR:
gh pr checks <pr-number> -R <owner/repo>
Report the status (pass/fail/pending) for each check.
If all checks pass, record CI Status as PASS and skip to Step 11. If any checks are pending, record CI Status as WARN and skip to Step 11. If any checks have failed, proceed to Steps 10a–10e below.
For each failed CI check, fetch the failure logs:
gh run view <run-id> --log-failed -R <owner/repo>
Extract the run-id from the failed check's URL or use:
gh run list --branch <pr-branch> --status failure --limit 5 -R <owner/repo>
Capture the relevant error output for analysis in Step 10b.
For each failed CI check, analyze the failure log to determine:
Use the Serena instance for the task's repository (from the Repository Registry in CLAUDE.md) or fall back to Read/Grep/Glob to inspect the relevant source files and understand the failure context.
Before creating sub-tasks, check for existing CI-failure sub-tasks linked to the
parent task. For each linked sub-task with labels ["ai-generated-jira", "review-feedback"],
check whether its description references the same CI check name or failure. If a
matching sub-task already exists, skip creation for that failure.
For each CI failure that requires a fix (and has no existing sub-task per Step 10c), create a Jira sub-task:
jira.create_issue with:
Parent: the current task's Jira issue ID
Summary: concise description of the CI fix needed (e.g., "Fix failing lint check: unused import in handler.rs")
Labels: ["ai-generated-jira", "review-feedback"]
Description: structured task description following the template defined in
shared/task-description-template.md.
Include the applicable base sections plus these extension sections:
After creating each sub-task, create a "Blocks" issue link from the sub-task to the parent task:
jira.create_issue_link(type="Blocks", inwardIssue=, outwardIssue=)
Record the CI Status check result:
Also record the list of CI-failure sub-tasks created in this step. These sub-tasks feed into Step 5 (Root-Cause Investigation) alongside any sub-tasks from Step 4.
For each criterion in the Acceptance Criteria section from the Jira task, verify it is satisfied by inspecting the code on the PR branch.
Use the appropriate Serena instance for the task's repository (look up the instance name
in the Repository Registry section of the project's CLAUDE.md). Tools are called as
mcp__<serena-instance>__<tool>, where <serena-instance> is the instance name from the
Repository Registry.
find_symbol with include_body=true to inspect the
specific functions, structs, or components relevant to each criterion.find_referencing_symbols to confirm new symbols are
properly referenced and integrated.search_for_pattern for configuration values,
string literals, or patterns referenced in the criteria.Note: Check the Code Intelligence section of the project's CLAUDE.md for per-instance limitations. Adapt your tool usage accordingly.
Fallback: if no Serena instance is available for the repository, use Read, Grep, and Glob tools to inspect the PR branch directly.
Record PASS/FAIL for each individual criterion.
Scan test files in the PR for repetitive test functions that could be parameterized. This check applies the Meszaros heuristic: flag only when multiple test functions share the same algorithm (setup, action, assertion structure) with different data values. Do not flag tests with different behavior, setup, or assertions.
Identify test files in the PR: filter the PR diff to test files:
gh pr diff <pr-number> --name-only -R <owner/repo>
Filter for files matching test patterns (e.g., test_, _test., .test., tests/,
spec/, *_spec.).
Inspect test function bodies: for each test file with multiple test functions, use
the Serena instance for the task's repository (from the Repository Registry in
CLAUDE.md) with find_symbol and include_body=true to read the test function bodies.
Fall back to Read/Grep for repos without a Serena instance.
Detect repetitive patterns: check whether any group of 2+ test functions shares the same structure — identical assertions, same setup pattern, same control flow — with only data values (inputs, expected outputs, fixture names) differing. If the test body would need conditionals to handle parameter variations, the tests are not candidates.
Record findings: for each group of repetitive test functions, record:
Inspect test function documentation: for each test file identified in step 1, check
whether each test function has a documentation comment (doc comment) immediately
preceding it. Use the Serena instance for the task's repository with find_symbol and
include_body=true to inspect test functions. Fall back to Read/Grep for repos without
a Serena instance.
Doc comment conventions vary by language:
/// or //!/** */"""docstring"""// comment immediately before the functionFlag missing doc comments: for each test function lacking a doc comment, record the file path and function name.
Record findings: append doc comment findings to the Test Quality result. If test functions are missing doc comments, record WARN with the list of undocumented functions. If all test functions have doc comments, this sub-check passes silently (does not change the overall Test Quality result from the repetitive test check).
Record PASS if both sub-checks pass (no repetitive tests and no missing doc comments). Record WARN if either repetitive tests are found OR doc comments are missing. Record N/A if no test files exist in the PR diff.
Note: Test Quality WARN is advisory — it does not elevate the overall result to FAIL. Treat it like Diff Size: report for visibility, but do not block the PR.
If the task description includes a Verification Commands section, run each command and check the result against the expected outcome.
For each command:
If no Verification Commands section exists in the task, skip this step and record N/A.
Compile all findings from Steps 4–13 (including Step 10's CI failure sub-tasks) into a structured verification report:
## Verification Report for <JIRA-ID> (commit <short-sha>)
| Check | Result | Details |
|-------|--------|---------|
| Review Feedback | PASS/WARN/FAIL/N/A | <summary> |
| Root-Cause Investigation | DONE/SKIPPED/N/A | <summary> |
| Scope Containment | PASS/WARN/FAIL | <summary> |
| Diff Size | PASS/WARN | <summary> |
| Commit Traceability | PASS/WARN/FAIL | <summary> |
| Sensitive Patterns | PASS/FAIL | <summary> |
| CI Status | PASS/WARN/FAIL | <summary> |
| Acceptance Criteria | PASS/FAIL | <N of M criteria met> |
| Test Quality | PASS/WARN | <summary> |
| Verification Commands | PASS/FAIL/N/A | <summary> |
### Overall: PASS / WARN / FAIL
<Summary of any issues requiring attention>
Overall result rules:
Note: The Root-Cause Investigation and Test Quality rows are informational and do NOT affect the Overall result. Their values are reported for visibility but excluded from the PASS/WARN/FAIL determination.
Before posting the report, retrieve the HEAD commit SHA of the PR to include in the report header:
gh pr view <pr-number> --json commits --jq '.commits[-1].oid' -R <owner/repo>
Store the full SHA and its short form (first 7 characters) for use in the report.
Each verification run creates a new PR comment (never overwrites previous reports). This provides a verification history over time, with each report clearly referencing the commit SHA it verified.
Update the report header from Step 14 to include the commit SHA:
## Verification Report for <JIRA-ID> (commit <short-sha>)
Append a markdown footnote at the end of the report body, separated by a horizontal rule:
---
*This comment was AI-generated by [sdlc-workflow/verify-pr](https://github.com/mrizzi/sdlc-plugins) v{version}.*
Read the plugin version from plugins/sdlc-workflow/.claude-plugin/plugin.json and
substitute {version} before posting.
gh pr comment <pr-number> --body "<report-with-footnote>" -R <owner/repo>
Add a comment to the Jira task with the verification report:
jira.add_comment(, )
Include the Comment Footnote at the end of the Jira comment.
Important: This skill does NOT merge the PR and does NOT transition the Jira issue. The report is informational — a human reviewer decides whether to merge.
find_symbol, find_referencing_symbols, search_for_pattern. Check the Code Intelligence section for per-instance limitations. Fall back to Read/Grep/Glob for repos without a Serena instance.gh CLI for all GitHub interactions.["ai-generated-jira", "review-feedback"] and "Blocks" issue links.["ai-generated-jira", "root-cause"] and "Relates" issue links.npx claudepluginhub mrizzi/sdlc-plugins --plugin sdlc-workflowPerforms scope-focused PR reviews on GitHub/GitLab: validates requirements compliance, prevents scope creep, triages out-of-scope findings to backlog issues.
Verifies PR implementation against issue specs via 3D checks: Completeness (tasks covered), Correctness (matches intent), Coherence (design reflected). Final merge checkpoint.
Reviews pull requests across description, code changes, code scan, and unit tests using parallel subagents, producing a structured verdict report with optional line-level comments.