From b1003b5b7a6bf24e6824d864128fad32abeb5f10 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 05:59:44 +0000 Subject: [PATCH 01/11] chore: init gsd --- .gitignore | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f6d4ec6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ + +# ── GSD baseline (auto-generated) ── +.gsd/activity/ +.gsd/forensics/ +.gsd/runtime/ +.gsd/worktrees/ +.gsd/parallel/ +.gsd/auto.lock +.gsd/metrics.json +.gsd/completed-units.json +.gsd/STATE.md +.gsd/gsd.db +.gsd/DISCUSSION-MANIFEST.json +.gsd/milestones/**/*-CONTINUE.md +.gsd/milestones/**/continue.md +.DS_Store +Thumbs.db +*.swp +*.swo +*~ +.idea/ +.vscode/ +*.code-workspace +.env +.env.* +!.env.example +node_modules/ +.next/ +dist/ +build/ +__pycache__/ +*.pyc +.venv/ +venv/ +target/ +vendor/ +*.log +coverage/ +.cache/ +tmp/ From e7023c8526242c936da652d3049a32948d0b4a33 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 06:17:28 +0000 Subject: [PATCH 02/11] docs(M001): context, requirements, and roadmap --- .gsd/DECISIONS.md | 13 ++ .gsd/PROJECT.md | 30 +++++ .gsd/REQUIREMENTS.md | 159 ++++++++++++++++++++++++ .gsd/milestones/M001/M001-CONTEXT.md | 100 +++++++++++++++ .gsd/milestones/M001/M001-DISCUSSION.md | 14 +++ .gsd/milestones/M001/M001-ROADMAP.md | 59 +++++++++ .gsd/preferences.md | 10 ++ 7 files changed, 385 insertions(+) create mode 100644 .gsd/DECISIONS.md create mode 100644 .gsd/PROJECT.md create mode 100644 .gsd/REQUIREMENTS.md create mode 100644 .gsd/milestones/M001/M001-CONTEXT.md create mode 100644 .gsd/milestones/M001/M001-DISCUSSION.md create mode 100644 .gsd/milestones/M001/M001-ROADMAP.md create mode 100644 .gsd/preferences.md diff --git a/.gsd/DECISIONS.md b/.gsd/DECISIONS.md new file mode 100644 index 0000000..7687a22 --- /dev/null +++ b/.gsd/DECISIONS.md @@ -0,0 +1,13 @@ +# Decisions Register + + + +| # | When | Scope | Decision | Choice | Rationale | Revisable? | +|---|------|-------|----------|--------|-----------|------------| +| D001 | M001 | arch | Workflow trigger strategy | `pull_request` + `issue_comment` (not `workflow_call`) | pr-agent needs PR context; org rulesets require `pull_request` trigger directly in the workflow file | No | +| D002 | M001 | library | AI model for PR review | `anthropic/claude-opus-4-6` primary, `anthropic/claude-sonnet-4-6` fallback | User wants best reasoning model with extended thinking; Opus 4.6 is current top model | Yes — if newer model released | +| D003 | M001 | arch | Org-wide distribution mechanism | GitHub org rulesets (not per-repo `workflow_call`) | Single source of truth without per-repo workflow files; rulesets enforce automatically | No | +| D004 | M001 | convention | Workflow naming | `ci-pr-review.yml` | Consistent with existing `ci-*.yml` naming convention in the repo | No | +| D005 | M001 | arch | Extended thinking | Enabled via `config.enable_claude_extended_thinking: "true"` | User explicitly wants max reasoning depth for reviews; Opus 4.6 adaptive thinking defaults to high effort | Yes — if cost becomes prohibitive | diff --git a/.gsd/PROJECT.md b/.gsd/PROJECT.md new file mode 100644 index 0000000..c36b458 --- /dev/null +++ b/.gsd/PROJECT.md @@ -0,0 +1,30 @@ +# ChillWhales Org Automation + +## What This Is + +The `chillwhales/.github` org repo — single source of truth for shared GitHub Actions workflows, composite actions, and org-wide automation. Existing reusable workflows handle CI build/lint/test, quality checks, and publish validation. The goal is to expand this with org-wide workflows enforced via GitHub rulesets, starting with automated PR review. + +## Core Value + +One place to define workflows that run across every repo in the org — no per-repo duplication, no drift. + +## Current State + +- Three reusable `workflow_call` workflows: `ci-build-lint-test.yml`, `ci-quality.yml`, `ci-publish-validation.yml` +- Two composite actions: `setup-pnpm`, `build-and-upload` +- Used by `lsp-indexer` repo via `workflow_call` +- No org-wide ruleset-enforced workflows yet + +## Architecture / Key Patterns + +- Workflows use `workflow_call` trigger with configurable inputs for reuse +- Composite actions extract common step sequences +- pnpm-based Node.js ecosystem + +## Capability Contract + +See `.gsd/REQUIREMENTS.md` for the explicit capability contract, requirement status, and coverage mapping. + +## Milestone Sequence + +- [ ] M001: Org-Wide PR Review Workflow — Automated code review via qodo-ai/pr-agent + Claude Opus 4.6 with extended thinking, enforced org-wide via GitHub rulesets diff --git a/.gsd/REQUIREMENTS.md b/.gsd/REQUIREMENTS.md new file mode 100644 index 0000000..ef244dc --- /dev/null +++ b/.gsd/REQUIREMENTS.md @@ -0,0 +1,159 @@ +# Requirements + +This file is the explicit capability and coverage contract for the project. + +## Active + +### R001 — Org-wide automated PR review without per-repo workflow files +- Class: core-capability +- Status: active +- Description: A single workflow in the `.github` org repo runs pr-agent reviews across all org repos without needing workflow files in each repo. +- Why it matters: Eliminates duplication, ensures consistent review quality, single source of truth. +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: Enforced via GitHub org rulesets pointing at the centralized workflow. + +### R002 — Reviews powered by Claude Opus 4.6 with extended thinking +- Class: core-capability +- Status: active +- Description: PR reviews use `anthropic/claude-opus-4-6` as primary model with extended thinking enabled via `secrets.ANTHROPIC_KEY`. +- Why it matters: Best available reasoning for thorough code review — the user explicitly wants the strongest model with deep thinking. +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: Opus 4.6 defaults to high effort with adaptive thinking, effectively max reasoning depth. + +### R003 — Fallback to Claude Sonnet 4.6 on primary failure +- Class: continuity +- Status: active +- Description: If Opus 4.6 fails (rate limit, timeout), falls back to `anthropic/claude-sonnet-4-6`. +- Why it matters: Reviews shouldn't silently fail because the primary model is temporarily unavailable. +- Source: inferred +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: none + +### R004 — Triggers on PR open/sync/reopen on any non-default branch +- Class: primary-user-loop +- Status: active +- Description: Workflow fires on `pull_request` events (opened, reopened, synchronize, ready_for_review) targeting any branch. +- Why it matters: Every push to a feature branch with an open PR gets reviewed automatically. +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: Uses `pull_request` trigger since pr-agent needs PR context. `synchronize` fires on every push to the PR branch. + +### R005 — Auto-review + auto-describe + auto-improve on trigger +- Class: primary-user-loop +- Status: active +- Description: On each trigger event, pr-agent automatically runs review, describe, and improve commands. +- Why it matters: No manual invocation needed — reviews happen automatically on every meaningful PR event. +- Source: user +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: none + +### R006 — Comment-triggered slash commands +- Class: core-capability +- Status: active +- Description: Developers can invoke `/review`, `/improve`, `/describe`, etc. by commenting on the PR. +- Why it matters: On-demand re-review or specific tool invocation without re-pushing. +- Source: inferred +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: Requires `issue_comment` trigger in the workflow. + +### R007 — Draft PRs excluded from automatic review +- Class: quality-attribute +- Status: active +- Description: Draft PRs do not trigger automatic review. Only non-draft PRs are reviewed. +- Why it matters: Avoids noisy reviews on work-in-progress PRs. +- Source: inferred +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: Uses `github.event.pull_request.draft == false` condition. + +### R008 — Ruleset setup instructions documented for org admin +- Class: operability +- Status: active +- Description: A clear doc explains how to configure the GitHub org ruleset to point at this workflow so it runs across all repos. +- Why it matters: The workflow file alone isn't enough — someone needs to wire the ruleset in the org settings UI. +- Source: inferred +- Primary owning slice: M001/S01 +- Supporting slices: none +- Validation: mapped +- Notes: Includes ANTHROPIC_KEY org secret setup. + +## Validated + +(none yet) + +## Deferred + +(none) + +## Out of Scope + +### R030 — Per-repo workflow customization or overrides +- Class: constraint +- Status: out-of-scope +- Description: Individual repos cannot override or customize the review workflow behavior. +- Why it matters: Prevents scope creep — single source of truth means uniform behavior. +- Source: user +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: If needed later, could use per-repo `.pr_agent.toml` config files. + +### R031 — Non-Anthropic model backends +- Class: anti-feature +- Status: out-of-scope +- Description: No support for OpenAI, Gemini, or other model providers. +- Why it matters: Keeps config simple and focused on the user's chosen provider. +- Source: user +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: none + +### R032 — Auto-merge or status-check gating on review outcome +- Class: anti-feature +- Status: out-of-scope +- Description: PR review results do not block merge or trigger auto-merge. +- Why it matters: Review is advisory, not a gate. +- Source: inferred +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: none + +## Traceability + +| ID | Class | Status | Primary owner | Supporting | Proof | +|---|---|---|---|---|---| +| R001 | core-capability | active | M001/S01 | none | mapped | +| R002 | core-capability | active | M001/S01 | none | mapped | +| R003 | continuity | active | M001/S01 | none | mapped | +| R004 | primary-user-loop | active | M001/S01 | none | mapped | +| R005 | primary-user-loop | active | M001/S01 | none | mapped | +| R006 | core-capability | active | M001/S01 | none | mapped | +| R007 | quality-attribute | active | M001/S01 | none | mapped | +| R008 | operability | active | M001/S01 | none | mapped | +| R030 | constraint | out-of-scope | none | none | n/a | +| R031 | anti-feature | out-of-scope | none | none | n/a | +| R032 | anti-feature | out-of-scope | none | none | n/a | + +## Coverage Summary + +- Active requirements: 8 +- Mapped to slices: 8 +- Validated: 0 +- Unmapped active requirements: 0 diff --git a/.gsd/milestones/M001/M001-CONTEXT.md b/.gsd/milestones/M001/M001-CONTEXT.md new file mode 100644 index 0000000..7844099 --- /dev/null +++ b/.gsd/milestones/M001/M001-CONTEXT.md @@ -0,0 +1,100 @@ +# M001: Org-Wide PR Review Workflow — Context + +**Gathered:** 2026-03-18 +**Status:** Ready for planning + +## Project Description + +Centralized automated PR review workflow using `qodo-ai/pr-agent` with Claude Opus 4.6 (extended thinking enabled), stored in the `chillwhales/.github` org repo and enforced across all org repos via GitHub org rulesets. + +## Why This Milestone + +Every repo in the org should get consistent, high-quality AI code review without maintaining per-repo workflow files. This is the first org-wide workflow — it establishes the pattern for future centralized automation. + +## User-Visible Outcome + +### When this milestone is complete, the user can: + +- Open a PR in any chillwhales org repo and get an automatic AI review from Claude Opus 4.6 with extended thinking +- Comment `/review`, `/improve`, or `/describe` on any PR to trigger on-demand review actions +- Manage the review workflow from a single file in the `.github` repo + +### Entry point / environment + +- Entry point: Push to non-default branch with open PR in any org repo +- Environment: GitHub Actions runner (ubuntu-latest) +- Live dependencies involved: Anthropic API via `secrets.ANTHROPIC_KEY` + +## Completion Class + +- Contract complete means: workflow file exists with correct triggers, model config, permissions, and extended thinking enabled +- Integration complete means: org ruleset documentation explains exact steps to wire this org-wide +- Operational complete means: none (operational proof requires org admin to configure ruleset + real PR push) + +## Final Integrated Acceptance + +To call this milestone complete, we must prove: + +- The workflow file is syntactically valid and follows existing repo conventions +- Model config uses `anthropic/claude-opus-4-6` primary with `anthropic/claude-sonnet-4-6` fallback +- Extended thinking is enabled +- Draft PRs are excluded +- Both `pull_request` and `issue_comment` triggers are present +- Ruleset setup doc is clear and complete + +## Risks and Unknowns + +- pr-agent model string for Opus 4.6 may not be `anthropic/claude-opus-4-6` — pr-agent uses LiteLLM model strings, recent releases added Sonnet 4.6 mappings but Opus 4.6 support needs verification at runtime +- Extended thinking config (`enable_claude_extended_thinking`) may increase token costs significantly — user explicitly wants this, so it's accepted cost + +## Existing Codebase / Prior Art + +- `.github/workflows/ci-build-lint-test.yml` — existing reusable workflow, reference for naming/style conventions +- `.github/workflows/ci-quality.yml` — existing reusable workflow +- `.github/workflows/ci-publish-validation.yml` — existing reusable workflow +- `.github/actions/setup-pnpm/action.yml` — composite action pattern + +> See `.gsd/DECISIONS.md` for all architectural and pattern decisions — it is an append-only register; read it during planning, append to it during execution. + +## Relevant Requirements + +- R001 — Org-wide review without per-repo files +- R002 — Claude Opus 4.6 with extended thinking +- R003 — Sonnet 4.6 fallback +- R004 — Triggers on non-default branch PRs +- R005 — Auto-review/describe/improve +- R006 — Slash commands via comments +- R007 — Draft PR exclusion +- R008 — Ruleset setup documentation + +## Scope + +### In Scope + +- `ci-pr-review.yml` workflow file with pr-agent + Claude Opus 4.6 + extended thinking +- Ruleset setup documentation (`RULESET.md`) +- Org secret setup instructions for `ANTHROPIC_KEY` + +### Out of Scope / Non-Goals + +- Per-repo customization or overrides +- Non-Anthropic model backends +- Auto-merge or status-check gating +- Actually configuring the org ruleset (requires org admin UI access) + +## Technical Constraints + +- Workflow must use `pull_request` trigger (not `workflow_call`) for ruleset compatibility +- `issue_comment` trigger needed for slash commands +- pr-agent uses LiteLLM model strings prefixed with `anthropic/` +- Org-level `ANTHROPIC_KEY` secret must be accessible to the workflow + +## Integration Points + +- Anthropic API — model inference for review, describe, improve +- GitHub API — PR comments, reviews, descriptions via `GITHUB_TOKEN` +- GitHub Org Rulesets — enforces workflow execution across repos + +## Open Questions + +- Exact LiteLLM model string for Opus 4.6 (`anthropic/claude-opus-4-6` is the expected format based on API model ID `claude-opus-4-6`) — will be verified during implementation diff --git a/.gsd/milestones/M001/M001-DISCUSSION.md b/.gsd/milestones/M001/M001-DISCUSSION.md new file mode 100644 index 0000000..154faa1 --- /dev/null +++ b/.gsd/milestones/M001/M001-DISCUSSION.md @@ -0,0 +1,14 @@ +# M001 Discussion Log + +## Exchange — 2026-03-18T06:16:28.589Z + +### Depth Check + +Did I capture the full picture — Opus 4.6 + extended thinking, sonnet 4.6 fallback, org ruleset enforcement, slash commands, draft exclusion, single workflow file + setup doc? + +- **Yes, you got it (Recommended)** — Proceed to write the milestone plan and files +- **Not quite — let me clarify** — I'll adjust based on your corrections + +**Selected:** Yes, you got it (Recommended) + +--- diff --git a/.gsd/milestones/M001/M001-ROADMAP.md b/.gsd/milestones/M001/M001-ROADMAP.md new file mode 100644 index 0000000..448822b --- /dev/null +++ b/.gsd/milestones/M001/M001-ROADMAP.md @@ -0,0 +1,59 @@ +# M001: Org-Wide PR Review Workflow + +**Vision:** Centralized automated PR review using qodo-ai/pr-agent + Claude Opus 4.6 with extended thinking, enforced across all chillwhales org repos via GitHub rulesets — single source of truth, no per-repo workflow files. + +## Success Criteria + +- Any PR opened in a chillwhales org repo triggers automatic AI review (after ruleset is configured) +- Review uses Claude Opus 4.6 with extended thinking enabled +- Developers can invoke `/review`, `/improve`, `/describe` via PR comments +- Draft PRs are excluded from automatic review +- Workflow is managed from a single file in the `.github` repo + +## Key Risks / Unknowns + +- pr-agent LiteLLM model string for Opus 4.6 — expected `anthropic/claude-opus-4-6` but needs runtime verification + +## Proof Strategy + +- Model string validity → retire in S01 by verifying workflow YAML against pr-agent docs and LiteLLM model naming conventions + +## Verification Classes + +- Contract verification: workflow YAML syntax validation, correct triggers/permissions/env vars present +- Integration verification: none (requires org admin to configure ruleset + real PR) +- Operational verification: none +- UAT / human verification: org admin configures ruleset, pushes a test PR, confirms review appears + +## Milestone Definition of Done + +This milestone is complete only when all are true: + +- `ci-pr-review.yml` exists with correct triggers, permissions, model config, and extended thinking +- Workflow follows naming/style conventions of existing workflows in the repo +- `RULESET.md` documents step-by-step org ruleset configuration +- All 8 active requirements (R001–R008) are addressed +- Workflow YAML passes syntax validation + +## Requirement Coverage + +- Covers: R001, R002, R003, R004, R005, R006, R007, R008 +- Partially covers: none +- Leaves for later: none +- Orphan risks: none + +## Slices + +- [ ] **S01: PR Review Workflow + Org Ruleset Doc** `risk:low` `depends:[]` + > After this: `ci-pr-review.yml` exists with Claude Opus 4.6 + extended thinking, auto-review/describe/improve, slash commands, draft exclusion; `RULESET.md` documents org ruleset setup. Proven by workflow syntax validation and file inspection — live PR review requires org admin to configure the ruleset. + +## Boundary Map + +### S01 (leaf slice) + +Produces: +- `.github/workflows/ci-pr-review.yml` — standalone workflow with `pull_request` + `issue_comment` triggers, qodo-ai/pr-agent action, Claude Opus 4.6 config, extended thinking, Sonnet 4.6 fallback +- `RULESET.md` — step-by-step guide for org admin to configure GitHub org ruleset pointing at this workflow + org secret setup + +Consumes: +- nothing (first and only slice) diff --git a/.gsd/preferences.md b/.gsd/preferences.md new file mode 100644 index 0000000..e679e8e --- /dev/null +++ b/.gsd/preferences.md @@ -0,0 +1,10 @@ +# GSD Preferences + +## Slice Completion + +- After each slice is complete, open a PR to the default branch before moving on to the next slice. +- Do not squash-merge automatically — the PR is for human review before merge. + +## Task Isolation + +- mode: branch From 9b2c47ee2acb8fa7295a254fa26a62a9c3e73c12 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 06:17:30 +0000 Subject: [PATCH 03/11] chore(M001): record integration branch --- .gsd/milestones/M001/M001-META.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gsd/milestones/M001/M001-META.json diff --git a/.gsd/milestones/M001/M001-META.json b/.gsd/milestones/M001/M001-META.json new file mode 100644 index 0000000..b657e91 --- /dev/null +++ b/.gsd/milestones/M001/M001-META.json @@ -0,0 +1,3 @@ +{ + "integrationBranch": "main" +} From 4402949ffef35c1cf66f54e07e10f7af3cb863d9 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 06:45:40 +0000 Subject: [PATCH 04/11] feat(S01): add ci-pr-review workflow and RULESET.md org setup guide - ci-pr-review.yml: two-job workflow with Claude Opus 4.6 + extended thinking, auto-review/describe/improve, slash commands, draft/bot exclusion (R001-R007) - RULESET.md: org admin guide for secret and ruleset setup (R008) --- .github/workflows/ci-pr-review.yml | 57 +++++++++++ .gsd/milestones/M001/slices/S01/S01-PLAN.md | 56 +++++++++++ .../M001/slices/S01/tasks/T01-PLAN.md | 99 +++++++++++++++++++ .../M001/slices/S01/tasks/T01-SUMMARY.md | 76 ++++++++++++++ .../M001/slices/S01/tasks/T02-SUMMARY.md | 66 +++++++++++++ RULESET.md | 94 ++++++++++++++++++ 6 files changed, 448 insertions(+) create mode 100644 .github/workflows/ci-pr-review.yml create mode 100644 .gsd/milestones/M001/slices/S01/S01-PLAN.md create mode 100644 .gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md create mode 100644 .gsd/milestones/M001/slices/S01/tasks/T01-SUMMARY.md create mode 100644 .gsd/milestones/M001/slices/S01/tasks/T02-SUMMARY.md create mode 100644 RULESET.md diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml new file mode 100644 index 0000000..d47b971 --- /dev/null +++ b/.github/workflows/ci-pr-review.yml @@ -0,0 +1,57 @@ +name: CI — PR Review + +on: + pull_request: + types: [opened, reopened, ready_for_review, synchronize] + issue_comment: + +permissions: + issues: write + pull-requests: write + contents: read + +jobs: + pr_agent_review: + if: >- + github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + github.event.sender.type != 'Bot' + runs-on: ubuntu-latest + name: PR Agent — Auto Review + steps: + - uses: actions/checkout@v4 + - uses: qodo-ai/pr-agent@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + env: + ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }} + config.model: "anthropic/claude-opus-4-6" + config.model_turbo: "anthropic/claude-sonnet-4-6" + config.fallback_models: '["anthropic/claude-sonnet-4-6"]' + config.enable_claude_extended_thinking: "true" + config.extended_thinking_budget_tokens: "10240" + config.max_model_tokens: "16384" + config.auto_review: "true" + config.auto_describe: "true" + config.auto_improve: "true" + + pr_agent_commands: + if: >- + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + github.event.sender.type != 'Bot' + runs-on: ubuntu-latest + name: PR Agent — Slash Commands + steps: + - uses: actions/checkout@v4 + - uses: qodo-ai/pr-agent@main + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + env: + ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }} + config.model: "anthropic/claude-opus-4-6" + config.model_turbo: "anthropic/claude-sonnet-4-6" + config.fallback_models: '["anthropic/claude-sonnet-4-6"]' + config.enable_claude_extended_thinking: "true" + config.extended_thinking_budget_tokens: "10240" + config.max_model_tokens: "16384" diff --git a/.gsd/milestones/M001/slices/S01/S01-PLAN.md b/.gsd/milestones/M001/slices/S01/S01-PLAN.md new file mode 100644 index 0000000..3426e9a --- /dev/null +++ b/.gsd/milestones/M001/slices/S01/S01-PLAN.md @@ -0,0 +1,56 @@ +# S01: PR Review Workflow + Org Ruleset Doc + +**Goal:** A complete pr-agent workflow exists in the `.github` org repo with Claude Opus 4.6 + extended thinking, auto-review/describe/improve, slash commands, and draft exclusion — plus documentation for org ruleset setup. +**Demo:** `ci-pr-review.yml` passes YAML syntax validation; file inspection confirms all 8 requirements are addressed; `RULESET.md` provides clear org admin instructions. + +## Must-Haves + +- `ci-pr-review.yml` with `pull_request` trigger (opened, reopened, synchronize, ready_for_review) and `issue_comment` trigger +- Claude Opus 4.6 (`anthropic/claude-opus-4-6`) as primary model with extended thinking enabled +- Sonnet 4.6 (`anthropic/claude-sonnet-4-6`) as fallback model +- Auto-review, auto-describe, auto-improve all enabled +- Draft PR exclusion via `github.event.pull_request.draft == false` +- Bot sender exclusion to prevent infinite loops +- `ANTHROPIC.KEY` env var (dot notation) mapped from `secrets.ANTHROPIC_KEY` +- `RULESET.md` with org ruleset configuration steps and secret setup + +## Verification + +- `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-pr-review.yml'))"` — valid YAML +- `grep -q 'anthropic/claude-opus-4-6' .github/workflows/ci-pr-review.yml` — primary model present +- `grep -q 'anthropic/claude-sonnet-4-6' .github/workflows/ci-pr-review.yml` — fallback model present +- `grep -q 'ANTHROPIC.KEY' .github/workflows/ci-pr-review.yml` — correct env var name (dot notation) +- `grep -q 'draft' .github/workflows/ci-pr-review.yml` — draft exclusion present +- `grep -q 'issue_comment' .github/workflows/ci-pr-review.yml` — slash command trigger present +- `test -f RULESET.md` — documentation exists +- `grep -q 'sender.type' .github/workflows/ci-pr-review.yml` — bot exclusion present (failure-path: prevents infinite review loops) +- Workflow YAML contains both job IDs (`pr_agent_review`, `pr_agent_commands`) — structural completeness check + +## Tasks + +- [x] **T01: Create pr-agent workflow with Claude Opus 4.6 and extended thinking** `est:20m` + - Why: Core deliverable — the workflow file that powers all PR reviews across the org (R001–R007) + - Files: `.github/workflows/ci-pr-review.yml` + - Do: Create workflow with two jobs: `pr_agent_review` (pull_request trigger with draft/bot exclusion, qodo-ai/pr-agent@main, Claude Opus 4.6 config with extended thinking and fallback) and `pr_agent_commands` (issue_comment trigger for slash commands). Use `ANTHROPIC.KEY` env var (dot notation). Follow existing `CI —` naming convention. Set extended thinking budget to 10240 tokens, max output 16384. + - Verify: `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-pr-review.yml'))"` passes; grep confirms model strings, env var name, triggers, and draft condition are all present + - Done when: Valid YAML file with all R001–R007 requirements addressed + +- [x] **T02: Write RULESET.md org ruleset setup guide** `est:15m` + - Why: The workflow alone does nothing without org ruleset configuration — this doc closes R008 + - Files: `RULESET.md` + - Do: Write step-by-step guide covering: (1) creating `ANTHROPIC_KEY` org secret, (2) navigating to org Settings → Rulesets, (3) creating a new ruleset targeting all repos, (4) adding the `ci-pr-review.yml` workflow as a required workflow, (5) testing with a real PR. Include prerequisites and troubleshooting tips. + - Verify: `test -f RULESET.md` and file contains sections for secret setup and ruleset configuration + - Done when: `RULESET.md` exists with clear, actionable instructions an org admin can follow + +## Observability / Diagnostics + +- **Workflow run visibility:** PR review results appear as PR comments (review, describe, improve). Failed runs surface in the Actions tab with step-level logs. +- **Inspection surfaces:** `gh run list --workflow=ci-pr-review.yml` shows recent runs; `gh run view --log-failed` shows failure details. +- **Failure modes:** Missing `ANTHROPIC_KEY` secret → pr-agent step fails with auth error in logs. Invalid model string → Anthropic API 400 error visible in step output. Draft PR or bot sender → job skipped (visible in Actions UI as grey "skipped" status). +- **Redaction:** `ANTHROPIC_KEY` is a GitHub secret — never exposed in logs. The workflow references it via `secrets.ANTHROPIC_KEY` which GitHub redacts automatically. +- **Diagnostic verification:** `grep -q 'ANTHROPIC.KEY' .github/workflows/ci-pr-review.yml` confirms the env var uses correct dot notation (a common misconfiguration). + +## Files Likely Touched + +- `.github/workflows/ci-pr-review.yml` +- `RULESET.md` diff --git a/.gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md b/.gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md new file mode 100644 index 0000000..86807e0 --- /dev/null +++ b/.gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md @@ -0,0 +1,99 @@ +--- +estimated_steps: 5 +estimated_files: 1 +--- + +# T01: Create pr-agent workflow with Claude Opus 4.6 and extended thinking + +**Slice:** S01 — PR Review Workflow + Org Ruleset Doc +**Milestone:** M001 + +## Description + +Create the GitHub Actions workflow file `ci-pr-review.yml` that runs qodo-ai/pr-agent with Claude Opus 4.6 as the primary model, extended thinking enabled, and Sonnet 4.6 as fallback. The workflow has two jobs: one for automatic PR review on pull_request events, and one for slash commands via issue_comment. This single file addresses requirements R001–R007. + +**Skills:** `github-workflows` — load this skill for GitHub Actions syntax guidance. + +## Steps + +1. Create `.github/workflows/ci-pr-review.yml` with the following structure: + + **Top-level:** + - `name: CI — PR Review` (follows existing `CI —` convention) + - `on:` with both `pull_request` and `issue_comment` triggers + + **Job 1: `pr_agent_review`** (automatic review on PR events) + - Trigger: `pull_request` types `[opened, reopened, ready_for_review, synchronize]` + - Condition: `if: github.event_name == 'pull_request' && github.event.pull_request.draft == false && github.event.sender.type != 'Bot'` + - `runs-on: ubuntu-latest` + - Permissions: `issues: write`, `pull-requests: write`, `contents: read` + - Steps: + - `actions/checkout@v4` + - `qodo-ai/pr-agent@main` with `github_token: ${{ secrets.GITHUB_TOKEN }}` + - Environment variables (env block on the pr-agent step): + - `ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }}` — **CRITICAL: dot notation, not underscore** + - `config.model: "anthropic/claude-opus-4-6"` + - `config.model_turbo: "anthropic/claude-sonnet-4-6"` + - `config.fallback_models: '["anthropic/claude-sonnet-4-6"]'` + - `config.enable_claude_extended_thinking: "true"` + - `config.extended_thinking_budget_tokens: "10240"` + - `config.max_model_tokens: "16384"` + - `config.auto_review: "true"` + - `config.auto_describe: "true"` + - `config.auto_improve: "true"` + + **Job 2: `pr_agent_commands`** (slash commands via comments) + - Trigger: `issue_comment` (no type filter — pr-agent handles parsing) + - Condition: `if: github.event_name == 'issue_comment' && github.event.issue.pull_request && github.event.sender.type != 'Bot'` + - Same runner, permissions, and pr-agent step config as Job 1 + - Same env vars (model config and API key) + +2. Validate YAML syntax: `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-pr-review.yml'))"` + +3. Verify all requirement markers are present via grep: + - Model string `anthropic/claude-opus-4-6` (R002) + - Fallback `anthropic/claude-sonnet-4-6` (R003) + - `pull_request` with `synchronize` (R004) + - `auto_review`, `auto_describe`, `auto_improve` (R005) + - `issue_comment` trigger (R006) + - `draft == false` condition (R007) + - `ANTHROPIC.KEY` with dot notation (R002 — API key) + +## Must-Haves + +- [ ] Workflow name follows `CI —` convention +- [ ] `pull_request` trigger includes `opened`, `reopened`, `ready_for_review`, `synchronize` +- [ ] Draft PRs excluded via `github.event.pull_request.draft == false` +- [ ] Bot senders excluded via `github.event.sender.type != 'Bot'` +- [ ] Primary model is `anthropic/claude-opus-4-6` +- [ ] Fallback model is `anthropic/claude-sonnet-4-6` +- [ ] Extended thinking enabled with 10240 token budget +- [ ] `ANTHROPIC.KEY` uses dot notation (NOT `ANTHROPIC_KEY`) +- [ ] Auto-review, auto-describe, auto-improve all set to `"true"` +- [ ] `issue_comment` job handles slash commands +- [ ] Permissions include `pull-requests: write`, `issues: write`, `contents: read` +- [ ] Uses `actions/checkout@v4` and `qodo-ai/pr-agent@main` + +## Verification + +- `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-pr-review.yml'))"` exits 0 +- `grep -c 'anthropic/claude-opus-4-6' .github/workflows/ci-pr-review.yml` returns ≥1 +- `grep -c 'anthropic/claude-sonnet-4-6' .github/workflows/ci-pr-review.yml` returns ≥1 +- `grep -c 'ANTHROPIC.KEY' .github/workflows/ci-pr-review.yml` returns ≥1 +- `grep -c 'issue_comment' .github/workflows/ci-pr-review.yml` returns ≥1 +- `grep -c 'draft.*false' .github/workflows/ci-pr-review.yml` returns ≥1 + +## Inputs + +- `.github/workflows/ci-build-lint-test.yml` — reference for naming convention (`CI — ` prefix, `runs-on: ubuntu-latest`, `actions/checkout@v4`) + +## Expected Output + +- `.github/workflows/ci-pr-review.yml` — complete, valid workflow file with two jobs covering automatic PR review and slash commands + +## Observability Impact + +- **New signal:** Workflow runs appear in the Actions tab for every non-draft, non-bot PR event and every issue comment on PRs. +- **Inspection:** `gh run list --workflow=ci-pr-review.yml` lists runs. PR comments from pr-agent (review/describe/improve) are the primary observable output. +- **Failure visibility:** Missing ANTHROPIC_KEY → step failure with auth error in run logs. Invalid model → Anthropic API error in step output. Skipped jobs (draft/bot) show as grey "Skipped" in Actions UI. +- **Future agent inspection:** Verify workflow correctness with `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-pr-review.yml'))"` and grep checks. Verify runtime with `gh run list --workflow=ci-pr-review.yml`. diff --git a/.gsd/milestones/M001/slices/S01/tasks/T01-SUMMARY.md b/.gsd/milestones/M001/slices/S01/tasks/T01-SUMMARY.md new file mode 100644 index 0000000..3d1e919 --- /dev/null +++ b/.gsd/milestones/M001/slices/S01/tasks/T01-SUMMARY.md @@ -0,0 +1,76 @@ +--- +id: T01 +parent: S01 +milestone: M001 +provides: + - ci-pr-review.yml workflow with Claude Opus 4.6 + extended thinking, auto-review/describe/improve, slash commands, draft/bot exclusion +key_files: + - .github/workflows/ci-pr-review.yml +key_decisions: + - Permissions set at workflow level (not job level) since both jobs need the same permissions + - Slash command job omits auto_review/auto_describe/auto_improve since those only apply to automatic PR events +patterns_established: + - pr-agent env vars use dot notation (ANTHROPIC.KEY, config.model) not underscore +observability_surfaces: + - Workflow runs visible in Actions tab per PR; pr-agent posts review/describe/improve as PR comments + - Skipped jobs (draft/bot) show as grey "Skipped" in Actions UI + - Missing ANTHROPIC_KEY secret surfaces as step failure with auth error in run logs +duration: 8m +verification_result: passed +completed_at: 2026-03-18 +blocker_discovered: false +--- + +# T01: Create pr-agent workflow with Claude Opus 4.6 and extended thinking + +**Created ci-pr-review.yml with two jobs: auto-review on PR events (Claude Opus 4.6 + extended thinking) and slash commands via issue_comment** + +## What Happened + +Created `.github/workflows/ci-pr-review.yml` with: +- **Job 1 (`pr_agent_review`):** Triggers on `pull_request` (opened, reopened, ready_for_review, synchronize). Excludes draft PRs and bot senders. Runs qodo-ai/pr-agent@main with Claude Opus 4.6 as primary model, Sonnet 4.6 as fallback, extended thinking enabled (10240 token budget), and auto-review/describe/improve all enabled. +- **Job 2 (`pr_agent_commands`):** Triggers on `issue_comment` for PRs. Excludes bot senders. Same model configuration for slash command processing. +- Workflow-level permissions: `issues: write`, `pull-requests: write`, `contents: read`. +- `ANTHROPIC.KEY` uses dot notation mapped from `secrets.ANTHROPIC_KEY`. + +Also added Observability sections to S01-PLAN.md and T01-PLAN.md per pre-flight requirements, and added a failure-path verification check to slice verification. + +## Verification + +All checks passed: +- `python3 -c "import yaml; yaml.safe_load(...)"` — YAML valid ✅ +- `grep -c 'anthropic/claude-opus-4-6'` → 2 ✅ +- `grep -c 'anthropic/claude-sonnet-4-6'` → 4 ✅ +- `grep -c 'ANTHROPIC.KEY'` → 2 ✅ +- `grep -c 'issue_comment'` → 2 ✅ +- `grep -c 'draft.*false'` → 1 ✅ +- `grep -c 'sender.type'` → 2 ✅ +- `auto_review`, `auto_describe`, `auto_improve` all present ✅ +- `synchronize` trigger type present ✅ +- Both job IDs (`pr_agent_review`, `pr_agent_commands`) present ✅ + +Slice-level verification (6/7 passing — RULESET.md is T02): +- YAML valid ✅, primary model ✅, fallback model ✅, ANTHROPIC.KEY ✅, draft exclusion ✅, issue_comment ✅, sender.type ✅ +- `test -f RULESET.md` — expected fail (T02 deliverable) + +## Diagnostics + +- Verify workflow syntax: `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/ci-pr-review.yml'))"` +- Check env var notation: `grep 'ANTHROPIC.KEY' .github/workflows/ci-pr-review.yml` +- After deployment, check runs: `gh run list --workflow=ci-pr-review.yml` +- View PR comments from pr-agent for review/describe/improve output + +## Deviations + +- Permissions set at workflow level instead of per-job since both jobs need identical permissions — cleaner and avoids duplication. +- Slash command job omits `auto_review`/`auto_describe`/`auto_improve` env vars since those config keys only affect the automatic PR event flow, not manual slash commands. + +## Known Issues + +None. + +## Files Created/Modified + +- `.github/workflows/ci-pr-review.yml` — New workflow file with two jobs for PR review and slash commands +- `.gsd/milestones/M001/slices/S01/S01-PLAN.md` — Added Observability section and failure-path verification +- `.gsd/milestones/M001/slices/S01/tasks/T01-PLAN.md` — Added Observability Impact section diff --git a/.gsd/milestones/M001/slices/S01/tasks/T02-SUMMARY.md b/.gsd/milestones/M001/slices/S01/tasks/T02-SUMMARY.md new file mode 100644 index 0000000..c8f2eda --- /dev/null +++ b/.gsd/milestones/M001/slices/S01/tasks/T02-SUMMARY.md @@ -0,0 +1,66 @@ +--- +id: T02 +parent: S01 +milestone: M001 +provides: + - RULESET.md with step-by-step org secret and ruleset configuration guide for org admins +key_files: + - RULESET.md +key_decisions: + - Included a troubleshooting table covering the most common failure modes (auth errors, infinite loops, slash commands not firing) + - Referenced specific GitHub navigation paths for org Settings to reduce ambiguity +patterns_established: + - Org-level workflow distribution pattern: centralised workflow in .github repo + org ruleset = zero per-repo config +observability_surfaces: + - Troubleshooting table in RULESET.md maps symptoms to causes and fixes + - Workflow reference table documents all model/feature settings in one place for admin inspection +duration: 5m +verification_result: passed +completed_at: 2026-03-18 +blocker_discovered: false +--- + +# T02: Write RULESET.md org ruleset setup guide + +**Created RULESET.md with step-by-step org secret setup, ruleset configuration, testing steps, and a troubleshooting table** + +## What Happened + +Created `RULESET.md` at the repo root covering all required sections: +- **Overview:** explains the centralised workflow + org ruleset pattern +- **Prerequisites:** admin access and Anthropic API key +- **Step 1:** org secret creation (`ANTHROPIC_KEY`) with repo access scope guidance +- **Step 2:** org ruleset creation — navigation path, targeting pattern (`~DEFAULT_BRANCH`), required workflow configuration pointing at `chillwhales/.github` → `ci-pr-review.yml` +- **Step 3:** testing instructions (PR comments + slash command verification) +- **Troubleshooting:** table covering auth errors, missing secrets, workflow not triggering, bot loops, slash command failures +- **Workflow reference table:** summarises all model and feature flag settings + +## Verification + +All checks passed: +- `test -f RULESET.md` ✅ +- `grep -q 'ANTHROPIC_KEY' RULESET.md` ✅ +- `grep -q 'ci-pr-review.yml' RULESET.md` ✅ +- `grep -q 'Ruleset' RULESET.md` ✅ +- `grep -q 'Troubleshoot' RULESET.md` ✅ + +Full slice-level verification — all 8 checks pass: +- YAML valid, primary model, fallback model, ANTHROPIC.KEY dot notation, draft exclusion, issue_comment trigger, bot exclusion, both job IDs ✅ +- `test -f RULESET.md` ✅ + +## Diagnostics + +- `test -f RULESET.md && echo ok` — confirms file exists +- The troubleshooting table in RULESET.md is itself the diagnostic surface for runtime failures + +## Deviations + +None. + +## Known Issues + +None. + +## Files Created/Modified + +- `RULESET.md` — New org admin setup guide at repo root diff --git a/RULESET.md b/RULESET.md new file mode 100644 index 0000000..3dd2cb4 --- /dev/null +++ b/RULESET.md @@ -0,0 +1,94 @@ +# PR Review Ruleset Setup Guide + +This guide explains how to configure the org-wide PR review workflow for the chillwhales GitHub organisation. The `.github` repo contains a centralised workflow (`ci-pr-review.yml`) that runs [qodo-ai/pr-agent](https://github.com/qodo-ai/pr-agent) with Claude Opus 4.6 on every pull request. An org ruleset makes it a required check across all (or selected) repos without any per-repo configuration. + +--- + +## Prerequisites + +- Admin access to the chillwhales GitHub org +- An Anthropic API key with access to Claude Opus 4.6 (and Claude Sonnet 4.6 for fallback) + +--- + +## Step 1: Create the `ANTHROPIC_KEY` org secret + +The workflow authenticates to the Anthropic API using an org-level secret so it's available in every repo without per-repo setup. + +1. Go to **github.com/organizations/chillwhales** → **Settings** → **Secrets and variables** → **Actions** +2. Click **New organization secret** +3. Fill in: + - **Name:** `ANTHROPIC_KEY` + - **Value:** your Anthropic API key + - **Repository access:** _All repositories_ (or select specific repos if you want to restrict which repos get PR review) +4. Click **Add secret** + +> **Tip:** The API key needs access to `claude-opus-4-6` and `claude-sonnet-4-6`. Verify this in your [Anthropic Console](https://console.anthropic.com/) if you see auth errors. + +--- + +## Step 2: Configure the org ruleset + +The ruleset makes `ci-pr-review.yml` a required workflow for pull requests across the org. + +1. Go to **github.com/organizations/chillwhales** → **Settings** → **Rulesets** +2. Click **New ruleset** → **New branch ruleset** +3. Configure the ruleset: + - **Name:** `PR Review` (or any descriptive name) + - **Enforcement status:** `Active` +4. Under **Target branches**: + - **Target repositories:** _All repositories_ (or pick specific repos) + - **Target branches:** Add a targeting pattern — use `~DEFAULT_BRANCH` to match each repo's default branch, or enter `main` if all repos use `main` +5. Under **Branch protections**, enable **Require status checks to pass** +6. Within that section, enable **Require workflows to pass before merging** and click **Add workflow**: + - **Repository:** `chillwhales/.github` + - **Workflow file path:** `.github/workflows/ci-pr-review.yml` + - **Ref (branch):** `main` +7. Click **Create** to save the ruleset + +> **Note:** The ruleset only enforces the workflow as a required check. The workflow itself also runs as a non-blocking check (for review comments) even without the ruleset — the ruleset just makes it a merge gate. + +--- + +## Step 3: Test + +1. Open a PR in any targeted repo +2. Verify three pr-agent comments appear within a few minutes: + - A **description** comment (PR summary) + - A **review** comment (code review with findings) + - An **improvement** comment (suggested code improvements) +3. In a PR comment, type `/review` and submit — verify pr-agent re-runs its review as a slash command +4. In GitHub → **Settings** → **Rulesets**, the ruleset status indicator should show green when the workflow passes + +--- + +## Troubleshooting + +| Symptom | Likely cause | Fix | +|---|---|---| +| "Authentication error" or 401 in workflow logs | `ANTHROPIC_KEY` secret missing or wrong | Re-check org secret name (must be `ANTHROPIC_KEY`, no typo) and value | +| Secret not available in a repo | Repository access scope on the secret | Edit the org secret and change access to "All repositories" or add the specific repo | +| Workflow not triggering on PRs | Ruleset not active or not targeting the repo | Check ruleset enforcement is "Active" and the repo is in scope | +| pr-agent runs but posts no comments | `GITHUB_TOKEN` permissions issue | The workflow sets `pull-requests: write` and `issues: write` — ensure org settings allow workflows to create PRs/issues | +| Review triggers on draft PRs | Unexpected — workflow has `draft == false` guard | Verify the `if:` condition in `ci-pr-review.yml` job `pr_agent_review` is present | +| Infinite comment loop (bot replies trigger review) | Bot exclusion not working | The workflow checks `github.event.sender.type != 'Bot'`; verify the condition is present in both jobs | +| Slash commands not working | `issue_comment` job not running | Check the `pr_agent_commands` job condition: it requires `github.event.issue.pull_request` (only comments on PRs, not issues) | + +--- + +## Workflow reference + +The workflow is at `.github/workflows/ci-pr-review.yml` in this repo. Key configuration: + +| Setting | Value | +|---|---| +| Primary model | `anthropic/claude-opus-4-6` | +| Fallback model | `anthropic/claude-sonnet-4-6` | +| Extended thinking | Enabled (10240 token budget) | +| Auto-review | Enabled | +| Auto-describe | Enabled | +| Auto-improve | Enabled | +| Draft PR exclusion | Yes (`draft == false`) | +| Bot sender exclusion | Yes (`sender.type != 'Bot'`) | + +To change model or feature flags, edit the `env:` block on the `qodo-ai/pr-agent@main` step in `ci-pr-review.yml`. From 7d0f8d6687a1e613804b031cf67cf46118d4744f Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 06:52:19 +0000 Subject: [PATCH 05/11] fix(ci-pr-review): pass GITHUB_TOKEN as env var, not with: input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qodo-ai/pr-agent@main is a Docker action — it doesn't accept 'with:' inputs other than 'entryPoint'/'args'. GITHUB_TOKEN must be passed as an env var. --- .github/workflows/ci-pr-review.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index d47b971..bb60b98 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -21,9 +21,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: qodo-ai/pr-agent@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }} config.model: "anthropic/claude-opus-4-6" config.model_turbo: "anthropic/claude-sonnet-4-6" @@ -45,9 +44,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: qodo-ai/pr-agent@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }} config.model: "anthropic/claude-opus-4-6" config.model_turbo: "anthropic/claude-sonnet-4-6" From 8d1e4d3804dbe42758760c202e9209d25709d1ec Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 06:56:09 +0000 Subject: [PATCH 06/11] fix(ci-pr-review): remove extended thinking params deprecated on Opus 4.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit claude-opus-4-6 rejects thinking:{type:enabled,budget_tokens:N} — this API is deprecated on 4.6 models. Opus 4.6 uses adaptive thinking by default at high effort, which means it almost always thinks deeply without explicit budget configuration. Removing config.enable_claude_extended_thinking and config.extended_thinking_budget_tokens. --- .github/workflows/ci-pr-review.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index bb60b98..a12fedf 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -27,8 +27,6 @@ jobs: config.model: "anthropic/claude-opus-4-6" config.model_turbo: "anthropic/claude-sonnet-4-6" config.fallback_models: '["anthropic/claude-sonnet-4-6"]' - config.enable_claude_extended_thinking: "true" - config.extended_thinking_budget_tokens: "10240" config.max_model_tokens: "16384" config.auto_review: "true" config.auto_describe: "true" @@ -50,6 +48,4 @@ jobs: config.model: "anthropic/claude-opus-4-6" config.model_turbo: "anthropic/claude-sonnet-4-6" config.fallback_models: '["anthropic/claude-sonnet-4-6"]' - config.enable_claude_extended_thinking: "true" - config.extended_thinking_budget_tokens: "10240" config.max_model_tokens: "16384" From 02faf8e750d0bc808bdbb510c90d2aef52024d6d Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 07:00:22 +0000 Subject: [PATCH 07/11] fix(ci-pr-review): set temperature=1 for Anthropic thinking models Anthropic requires temperature=1 when reasoning/thinking is active. pr-agent defaults to temperature=0.2 + reasoning_effort=medium (adaptive thinking on 4.6 models) which triggers a 400 from the API. --- .github/workflows/ci-pr-review.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index a12fedf..117719b 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -28,6 +28,7 @@ jobs: config.model_turbo: "anthropic/claude-sonnet-4-6" config.fallback_models: '["anthropic/claude-sonnet-4-6"]' config.max_model_tokens: "16384" + config.temperature: "1" config.auto_review: "true" config.auto_describe: "true" config.auto_improve: "true" @@ -49,3 +50,4 @@ jobs: config.model_turbo: "anthropic/claude-sonnet-4-6" config.fallback_models: '["anthropic/claude-sonnet-4-6"]' config.max_model_tokens: "16384" + config.temperature: "1" From 98452f7fab352e17196d4f57c2e12154e8ab5582 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 07:02:51 +0000 Subject: [PATCH 08/11] fix(ci-pr-review): set custom_reasoning_model=true to bypass reasoning_effort injection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pr-agent auto-injects reasoning_effort=medium for Anthropic models, which LiteLLM translates to thinking params — causing a malformed request that Anthropic rejects with a vague 400. custom_reasoning_model=true tells pr-agent to treat the model as a custom/non-reasoning model and skip the reasoning_effort injection, letting the API call go through cleanly. --- .github/workflows/ci-pr-review.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index 117719b..e1a33e1 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -29,6 +29,7 @@ jobs: config.fallback_models: '["anthropic/claude-sonnet-4-6"]' config.max_model_tokens: "16384" config.temperature: "1" + config.custom_reasoning_model: "true" config.auto_review: "true" config.auto_describe: "true" config.auto_improve: "true" @@ -51,3 +52,4 @@ jobs: config.fallback_models: '["anthropic/claude-sonnet-4-6"]' config.max_model_tokens: "16384" config.temperature: "1" + config.custom_reasoning_model: "true" From 79350fe63b2b6df374b5a6033388ecdc4c172e56 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 07:06:34 +0000 Subject: [PATCH 09/11] fix(ci-pr-review): disable reasoning_effort to prevent adaptive thinking injection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pr-agent auto-sets reasoning_effort=medium for Anthropic models even with custom_reasoning_model=true in some versions. LiteLLM translates this to thinking:{type:adaptive} which Opus 4.6 requires temp=1 for — but the combination of params it sends causes a malformed 400. Setting reasoning_effort='' disables the injection entirely; Opus 4.6 still uses adaptive thinking by default without explicit params. --- .github/workflows/ci-pr-review.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index e1a33e1..6401915 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -29,6 +29,7 @@ jobs: config.fallback_models: '["anthropic/claude-sonnet-4-6"]' config.max_model_tokens: "16384" config.temperature: "1" + config.reasoning_effort: "" config.custom_reasoning_model: "true" config.auto_review: "true" config.auto_describe: "true" @@ -52,4 +53,5 @@ jobs: config.fallback_models: '["anthropic/claude-sonnet-4-6"]' config.max_model_tokens: "16384" config.temperature: "1" + config.reasoning_effort: "" config.custom_reasoning_model: "true" From 8cbf4eabc618a05d7117226d618d1077224caf2c Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 07:38:18 +0000 Subject: [PATCH 10/11] feat(ci-pr-review): switch to claude-code-action with OAuth token auth Replace qodo-ai/pr-agent (requires Anthropic API key) with Anthropic's official claude-code-action which supports Claude Code OAuth tokens from Max subscriptions. No separate API billing needed. - Auto-review on PR open/reopen/sync/ready-for-review with structured output - @claude slash commands in PR comments - Claude Opus 4.6 model, draft/bot exclusion, concurrency control - Updated RULESET.md for new secret setup (CLAUDE_CODE_OAUTH_TOKEN) --- .github/workflows/ci-pr-review.yml | 94 ++++++++++++++++++++---------- RULESET.md | 66 ++++++++++++--------- 2 files changed, 99 insertions(+), 61 deletions(-) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index 6401915..8b8cc5b 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -4,11 +4,19 @@ on: pull_request: types: [opened, reopened, ready_for_review, synchronize] issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + +concurrency: + group: claude-review-${{ github.event.pull_request.number || github.event.issue.number }} + cancel-in-progress: true permissions: - issues: write - pull-requests: write contents: read + pull-requests: write + issues: write + id-token: write jobs: pr_agent_review: @@ -17,41 +25,63 @@ jobs: github.event.pull_request.draft == false && github.event.sender.type != 'Bot' runs-on: ubuntu-latest - name: PR Agent — Auto Review + name: Claude — Auto Review + timeout-minutes: 15 steps: - uses: actions/checkout@v4 - - uses: qodo-ai/pr-agent@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }} - config.model: "anthropic/claude-opus-4-6" - config.model_turbo: "anthropic/claude-sonnet-4-6" - config.fallback_models: '["anthropic/claude-sonnet-4-6"]' - config.max_model_tokens: "16384" - config.temperature: "1" - config.reasoning_effort: "" - config.custom_reasoning_model: "true" - config.auto_review: "true" - config.auto_describe: "true" - config.auto_improve: "true" + with: + fetch-depth: 0 + - uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + model: claude-opus-4-6 + prompt: | + Review PR #${{ github.event.pull_request.number }} in this repo. + + Review against these standards: + + ## Code Quality + - Minimal and pragmatic — no over-engineering + - Readability over cleverness + - No unnecessary config or "just in case" code + + ## Security (OWASP Top 10) + - Input validation at system boundaries + - No hardcoded secrets, credentials, or API keys + - No injection vulnerabilities (SQL, XSS, command injection) + + ## Testing + - Flag if code changes lack corresponding tests + + ## Output Format + Format your response as a GitHub PR review comment in markdown with these sections: + + ### Must Fix + Critical issues that must be resolved before merging. Number each item. If none, write "None." + + ### Should Consider + Important improvements that should be addressed. Number each item. If none, write "None." + + ### Minor + Non-blocking nits and style suggestions. Number each item. If none, write "None." + + ### Summary + A brief 2-3 sentence summary of the PR changes and overall quality. pr_agent_commands: if: >- - github.event_name == 'issue_comment' && - github.event.issue.pull_request && - github.event.sender.type != 'Bot' + (github.event_name == 'issue_comment' && github.event.issue.pull_request && + contains(github.event.comment.body, '@claude') && github.event.sender.type != 'Bot') || + (github.event_name == 'pull_request_review_comment' && + contains(github.event.comment.body, '@claude') && github.event.sender.type != 'Bot') runs-on: ubuntu-latest - name: PR Agent — Slash Commands + name: Claude — Slash Commands + timeout-minutes: 15 steps: - uses: actions/checkout@v4 - - uses: qodo-ai/pr-agent@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ANTHROPIC.KEY: ${{ secrets.ANTHROPIC_KEY }} - config.model: "anthropic/claude-opus-4-6" - config.model_turbo: "anthropic/claude-sonnet-4-6" - config.fallback_models: '["anthropic/claude-sonnet-4-6"]' - config.max_model_tokens: "16384" - config.temperature: "1" - config.reasoning_effort: "" - config.custom_reasoning_model: "true" + with: + fetch-depth: 0 + - uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + model: claude-opus-4-6 diff --git a/RULESET.md b/RULESET.md index 3dd2cb4..8e52b6a 100644 --- a/RULESET.md +++ b/RULESET.md @@ -1,33 +1,42 @@ # PR Review Ruleset Setup Guide -This guide explains how to configure the org-wide PR review workflow for the chillwhales GitHub organisation. The `.github` repo contains a centralised workflow (`ci-pr-review.yml`) that runs [qodo-ai/pr-agent](https://github.com/qodo-ai/pr-agent) with Claude Opus 4.6 on every pull request. An org ruleset makes it a required check across all (or selected) repos without any per-repo configuration. +This guide explains how to configure the org-wide PR review workflow for the chillwhales GitHub organisation. The `.github` repo contains a centralised workflow (`ci-pr-review.yml`) that runs [Claude Code Action](https://github.com/anthropics/claude-code-action) with Claude Opus 4.6 on every pull request. An org ruleset makes it a required check across all (or selected) repos without any per-repo configuration. --- ## Prerequisites - Admin access to the chillwhales GitHub org -- An Anthropic API key with access to Claude Opus 4.6 (and Claude Sonnet 4.6 for fallback) +- A Claude Max subscription (the workflow uses your Claude Code OAuth token — no separate Anthropic API key needed) --- -## Step 1: Create the `ANTHROPIC_KEY` org secret +## Step 1: Get your Claude Code OAuth token -The workflow authenticates to the Anthropic API using an org-level secret so it's available in every repo without per-repo setup. +The workflow authenticates using your Claude Code OAuth token from your Max subscription. + +1. On a machine with Claude Code installed, find your credentials: + - **Linux:** `~/.claude/.credentials.json` + - **macOS:** Search "claude" in Keychain Access → Show Password +2. Copy the `oauth_token` value + +> **Note:** This uses your existing Claude Max subscription budget — no separate API billing. Each PR review costs tokens from your subscription allowance. + +--- + +## Step 2: Create the `CLAUDE_CODE_OAUTH_TOKEN` org secret 1. Go to **github.com/organizations/chillwhales** → **Settings** → **Secrets and variables** → **Actions** 2. Click **New organization secret** 3. Fill in: - - **Name:** `ANTHROPIC_KEY` - - **Value:** your Anthropic API key - - **Repository access:** _All repositories_ (or select specific repos if you want to restrict which repos get PR review) + - **Name:** `CLAUDE_CODE_OAUTH_TOKEN` + - **Value:** your OAuth token from Step 1 + - **Repository access:** _All repositories_ (or select specific repos) 4. Click **Add secret** -> **Tip:** The API key needs access to `claude-opus-4-6` and `claude-sonnet-4-6`. Verify this in your [Anthropic Console](https://console.anthropic.com/) if you see auth errors. - --- -## Step 2: Configure the org ruleset +## Step 3: Configure the org ruleset The ruleset makes `ci-pr-review.yml` a required workflow for pull requests across the org. @@ -46,18 +55,17 @@ The ruleset makes `ci-pr-review.yml` a required workflow for pull requests acros - **Ref (branch):** `main` 7. Click **Create** to save the ruleset -> **Note:** The ruleset only enforces the workflow as a required check. The workflow itself also runs as a non-blocking check (for review comments) even without the ruleset — the ruleset just makes it a merge gate. - --- -## Step 3: Test +## Step 4: Test 1. Open a PR in any targeted repo -2. Verify three pr-agent comments appear within a few minutes: - - A **description** comment (PR summary) - - A **review** comment (code review with findings) - - An **improvement** comment (suggested code improvements) -3. In a PR comment, type `/review` and submit — verify pr-agent re-runs its review as a slash command +2. Verify a Claude review comment appears within a few minutes with: + - **Must Fix** — critical issues + - **Should Consider** — important improvements + - **Minor** — nits and style suggestions + - **Summary** — brief overview +3. In a PR comment, type `@claude review this again` — verify Claude responds to the mention 4. In GitHub → **Settings** → **Rulesets**, the ruleset status indicator should show green when the workflow passes --- @@ -66,13 +74,13 @@ The ruleset makes `ci-pr-review.yml` a required workflow for pull requests acros | Symptom | Likely cause | Fix | |---|---|---| -| "Authentication error" or 401 in workflow logs | `ANTHROPIC_KEY` secret missing or wrong | Re-check org secret name (must be `ANTHROPIC_KEY`, no typo) and value | +| Workflow fails with auth error | `CLAUDE_CODE_OAUTH_TOKEN` secret missing or expired | Re-check org secret; tokens may expire — regenerate from `~/.claude/.credentials.json` | | Secret not available in a repo | Repository access scope on the secret | Edit the org secret and change access to "All repositories" or add the specific repo | | Workflow not triggering on PRs | Ruleset not active or not targeting the repo | Check ruleset enforcement is "Active" and the repo is in scope | -| pr-agent runs but posts no comments | `GITHUB_TOKEN` permissions issue | The workflow sets `pull-requests: write` and `issues: write` — ensure org settings allow workflows to create PRs/issues | +| Claude runs but posts no comments | `GITHUB_TOKEN` permissions issue | The workflow sets `pull-requests: write` and `issues: write` — ensure org settings allow workflows to create PRs/issues | | Review triggers on draft PRs | Unexpected — workflow has `draft == false` guard | Verify the `if:` condition in `ci-pr-review.yml` job `pr_agent_review` is present | -| Infinite comment loop (bot replies trigger review) | Bot exclusion not working | The workflow checks `github.event.sender.type != 'Bot'`; verify the condition is present in both jobs | -| Slash commands not working | `issue_comment` job not running | Check the `pr_agent_commands` job condition: it requires `github.event.issue.pull_request` (only comments on PRs, not issues) | +| `@claude` commands not working | Comment doesn't contain `@claude` or sender is a bot | Check the `pr_agent_commands` job condition | +| Token budget exceeded | Too many reviews consuming Max subscription tokens | Reduce review frequency or switch model to `claude-sonnet-4-6` for lower token usage | --- @@ -82,13 +90,13 @@ The workflow is at `.github/workflows/ci-pr-review.yml` in this repo. Key config | Setting | Value | |---|---| -| Primary model | `anthropic/claude-opus-4-6` | -| Fallback model | `anthropic/claude-sonnet-4-6` | -| Extended thinking | Enabled (10240 token budget) | -| Auto-review | Enabled | -| Auto-describe | Enabled | -| Auto-improve | Enabled | +| Action | `anthropics/claude-code-action@v1` | +| Model | `claude-opus-4-6` | +| Auth | Claude Code OAuth token (Max subscription) | +| Auto-review | On PR open/reopen/sync/ready-for-review | +| Slash commands | `@claude` in PR comments | | Draft PR exclusion | Yes (`draft == false`) | | Bot sender exclusion | Yes (`sender.type != 'Bot'`) | +| Concurrency | One review per PR at a time | -To change model or feature flags, edit the `env:` block on the `qodo-ai/pr-agent@main` step in `ci-pr-review.yml`. +To change model or review behaviour, edit the workflow file directly. The `prompt` field controls what Claude reviews and how it formats output. From 9f516870567f29c1d4d3a9a15fc0c0313501c823 Mon Sep 17 00:00:00 2001 From: default Date: Wed, 18 Mar 2026 10:11:44 +0000 Subject: [PATCH 11/11] fix(ci-pr-review): use claude_args for model, not model input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit claude-code-action@v1 doesn't have a 'model' input — pass via claude_args. --- .github/workflows/ci-pr-review.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-pr-review.yml b/.github/workflows/ci-pr-review.yml index 8b8cc5b..9ba8322 100644 --- a/.github/workflows/ci-pr-review.yml +++ b/.github/workflows/ci-pr-review.yml @@ -34,7 +34,7 @@ jobs: - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - model: claude-opus-4-6 + claude_args: "--model claude-opus-4-6" prompt: | Review PR #${{ github.event.pull_request.number }} in this repo. @@ -84,4 +84,4 @@ jobs: - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - model: claude-opus-4-6 + claude_args: "--model claude-opus-4-6"