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) --- *Generated by [Wave](https://github.com/re-cinq/wave) pr-review pipeline* REVIEW_EOF {{ forge.cli_tool }} {{ forge.pr_command }} comment --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"