Files
code-crispies/.wave/pipelines/ops-pr-review.yaml

243 lines
7.0 KiB
YAML

kind: WavePipeline
metadata:
name: ops-pr-review
description: "Pull request code review with automated security and quality analysis"
release: true
chat_context:
artifact_summaries:
- diff
- security
- quality
- verdict
suggested_questions:
- "What issues were found in the review?"
- "Are there any blocking concerns that must be addressed before merging?"
- "What should be fixed before the next review cycle?"
focus_areas:
- "Review findings and severity"
- "Code quality and maintainability"
- "Security concerns and vulnerabilities"
skills:
- "{{ project.skill }}"
- gh-cli
- software-design
requires:
tools:
- gh
input:
source: cli
example: "https://github.com/owner/repo/pull/42"
steps:
- id: diff-analysis
persona: navigator
model: claude-haiku
workspace:
mount:
- source: ./
target: /project
mode: readonly
exec:
type: prompt
source: |
Analyze the code changes for: {{ input }}
## Step 1: Extract PR Metadata
First, fetch PR metadata to populate the `pr_metadata` field in the output:
```bash
{{ forge.cli_tool }} {{ forge.pr_command }} view {{ input }} --json number,headRefName,baseRefName,url
```
Extract the number, url, headRefName (→ head_branch), and baseRefName (→ base_branch).
## Step 2: Checkout the PR Branch
Checkout the PR's head branch to ensure you analyze the correct code:
```bash
{{ forge.cli_tool }} {{ forge.pr_command }} checkout {{ input }}
```
## Step 3: Analyze Changes
1. Identify all modified files and their purposes
2. Map the change scope (which modules/packages affected)
3. Find related tests that should be updated
4. Check for breaking API changes
Produce a structured result matching the contract schema.
The `pr_metadata` field must contain the PR number, URL, head branch, and base branch.
output_artifacts:
- name: diff
path: .wave/output/diff-analysis.json
type: json
retry:
policy: patient
max_attempts: 2
handover:
contract:
type: json_schema
source: .wave/output/diff-analysis.json
schema_path: .wave/contracts/diff-analysis.schema.json
on_failure: retry
- id: security-review
persona: reviewer
dependencies: [diff-analysis]
memory:
inject_artifacts:
- step: diff-analysis
artifact: diff
as: changes
exec:
type: prompt
source: |
Security review of the PR changes.
Check for:
1. SQL injection, XSS, CSRF vulnerabilities
2. Hardcoded secrets or credentials
3. Insecure deserialization
4. Missing input validation
5. Authentication/authorization gaps
6. Sensitive data exposure
Output findings with severity (CRITICAL/HIGH/MEDIUM/LOW).
output_artifacts:
- name: security
path: .wave/output/security-review.md
type: markdown
handover:
contract:
type: llm_judge
source: .wave/output/security-review.md
model: claude-haiku
criteria:
- "Identifies injection vulnerabilities (SQL, command, XSS) if present in the diff"
- "Checks for hardcoded credentials or secrets"
- "Assesses authentication and authorization correctness"
- "Findings include severity levels and specific file references"
threshold: 0.75
on_failure: continue
- id: quality-review
persona: reviewer
dependencies: [diff-analysis]
memory:
inject_artifacts:
- step: diff-analysis
artifact: diff
as: changes
exec:
type: prompt
source: |
Quality review of the PR changes.
Check for:
1. Error handling completeness
2. Edge cases not covered
3. Code duplication
4. Naming consistency
5. Missing or inadequate tests
6. Performance implications
7. Documentation gaps
Output findings with severity and suggestions.
output_artifacts:
- name: quality
path: .wave/output/quality-review.md
type: markdown
handover:
contract:
type: non_empty_file
source: .wave/output/quality-review.md
- id: summary
persona: summarizer
model: claude-haiku
dependencies: [security-review, quality-review]
memory:
inject_artifacts:
- step: security-review
artifact: security
as: security_findings
- step: quality-review
artifact: quality
as: quality_findings
exec:
type: prompt
source: |
Synthesize the review findings into a final verdict.
Produce a unified review with:
1. Overall assessment (APPROVE / REQUEST_CHANGES / NEEDS_DISCUSSION)
2. Critical issues that must be fixed
3. Suggested improvements (optional but recommended)
4. Positive observations
Format as a PR review comment ready to post.
Do NOT include a title/header line — the publish step adds one.
output_artifacts:
- name: verdict
path: .wave/output/review-summary.md
type: markdown
handover:
contract:
type: non_empty_file
source: .wave/output/review-summary.md
- id: publish
persona: "gitea-commenter"
dependencies: [summary]
memory:
inject_artifacts:
- step: summary
artifact: verdict
as: review_summary
- step: diff-analysis
artifact: diff
as: pr_context
exec:
type: prompt
source: |
Post the code review summary as a PR comment.
Read the `pr_context` artifact first — it contains structured PR metadata
with `pr_metadata.number` and `pr_metadata.url`. Use these to identify the
target PR instead of parsing raw input text.
1. Read the `pr_context` artifact and extract `pr_metadata.number` for use in commands
2. Write the review content to a temp file, then post it as a PR comment:
cat > /tmp/pr-review-comment.md <<'REVIEW_EOF'
## Code Review (Wave Pipeline)
<review content>
---
*Generated by [Wave](https://github.com/re-cinq/wave) pr-review pipeline*
REVIEW_EOF
{{ forge.cli_tool }} {{ forge.pr_command }} comment <PR_NUMBER from pr_metadata> --body-file /tmp/pr-review-comment.md
output_artifacts:
- name: publish-result
path: .wave/output/publish-result.json
type: json
retry:
policy: aggressive
max_attempts: 2
handover:
contract:
type: json_schema
source: .wave/output/publish-result.json
schema_path: .wave/contracts/gh-pr-comment-result.schema.json
must_pass: true
on_failure: retry
outcomes:
- type: url
extract_from: .wave/output/publish-result.json
json_path: .comment_url
label: "Review Comment"