From c03cdc1149b9bda95c9670fd1e36ad3e7feb1036 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 05:21:45 +0000 Subject: [PATCH 1/9] Add axon-pr-reviewer TaskSpawner to replace cubic-dev-ai Introduce a new TaskSpawner that watches for pull requests labeled ok-to-test and performs automated code reviews, replacing the external cubic-dev-ai GitHub App. The reviewer reads the full PR diff, checks it against project conventions, evaluates correctness, test coverage, style, security, and simplicity, then posts a structured review comment on the PR. Closes #408 Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 17 ++++ self-development/axon-pr-reviewer.yaml | 103 +++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 self-development/axon-pr-reviewer.yaml diff --git a/self-development/README.md b/self-development/README.md index 1d604b5f..5a5caa7b 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -160,6 +160,23 @@ This spawner uses a cron schedule (`0 */12 * * *`) and will create a task every - **Integration Opportunities** — identify tools/platforms Axon could integrate with (CI systems, monitoring, chat ops, etc.) - **New CRDs & API Extensions** — propose new Custom Resource Definitions or extensions to existing CRDs that would expand Axon's capabilities +### axon-pr-reviewer.yaml + +This TaskSpawner watches for open pull requests labeled `ok-to-test` and performs automated code reviews, replacing the need for external code review bots. + +**Deploy:** +```bash +kubectl apply -f self-development/axon-pr-reviewer.yaml +``` + +This spawner polls for new PRs and creates a task for each one to: +- Read the full PR diff and understand the changes +- Review for correctness, test coverage, style, security, and simplicity +- Post a structured review comment on the PR +- Add the `axon/needs-input` label to avoid re-reviewing + +The reviewer is read-only — it does not push code or modify files. + ## Customizing for Your Repository To adapt these examples for your own repository: diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml new file mode 100644 index 00000000..e0c00abb --- /dev/null +++ b/self-development/axon-pr-reviewer.yaml @@ -0,0 +1,103 @@ +apiVersion: axon.io/v1alpha1 +kind: TaskSpawner +metadata: + name: axon-pr-reviewer +spec: + when: + githubIssues: + types: + - pulls + labels: + - ok-to-test + excludeLabels: + - axon/needs-input + maxConcurrency: 3 + taskTemplate: + workspaceRef: + name: axon-agent + model: opus + type: claude-code + ttlSecondsAfterFinished: 3600 + credentials: + type: oauth + secretRef: + name: axon-credentials + podOverrides: + resources: + requests: + cpu: "250m" + memory: "512Mi" + ephemeral-storage: "4Gi" + limits: + cpu: "1" + memory: "2Gi" + ephemeral-storage: "4Gi" + agentConfigRef: + name: axon-dev-agent + promptTemplate: | + You are a code reviewer for the Axon project (github.com/axon-core/axon). + Your job is to review pull request #{{.Number}} and provide constructive feedback. + + ## Context + + PR #{{.Number}}: {{.Title}} + {{.Body}} + + ## Your tasks + + ### 1. Read the full diff + Fetch the PR diff and understand all changes: + ``` + git fetch --unshallow || true + git fetch origin main + gh pr diff {{.Number}} + ``` + + ### 2. Read the project conventions + Read `CLAUDE.md` (or `AGENTS.md`) in the repository root so your review + aligns with the project's coding standards. + + ### 3. Review the changes + Evaluate the PR for: + - **Correctness**: Does the code do what it claims? Are there logic errors or edge cases? + - **Tests**: Are there adequate tests for the changes? Are existing tests updated if needed? + - **Style & conventions**: Does the code follow the project's conventions (see CLAUDE.md)? + - **Security**: Are there any security concerns (injection, hardcoded secrets, etc.)? + - **Simplicity**: Is the change minimal and focused, or does it include unnecessary refactoring? + + ### 4. Post your review + Post a single review comment on the PR using `gh`: + ``` + gh pr review {{.Number}} --comment --body "..." + ``` + + Format the comment as: + + ``` + ## Summary + <1-3 sentence summary of what the PR does> + + ## Review + + + + ## Verdict + **LGTM** / **Changes requested** + + + ``` + + After posting the review, add the `axon/needs-input` label to the PR so + it is not re-reviewed: + ``` + gh pr edit {{.Number}} --add-label axon/needs-input + ``` + + ## Constraints + - Do NOT push code, create commits, or modify any files. This is a read-only review. + - Do NOT approve or request changes via GitHub's formal review mechanism. + Use `--comment` only. + - Be constructive and specific. Avoid vague feedback. + - Focus on substantive issues, not style nitpicks that a linter would catch. + pollInterval: 1m From 15395321d84df2a5e2701f70c7cefc5f0131871a Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 05:47:13 +0000 Subject: [PATCH 2/9] Enable re-reviewing PRs on new commits Remove excludeLabels and axon/needs-input labeling so the PR reviewer re-triggers after Task TTL expires. Add a new-commits check so the agent skips posting if nothing changed since the last review. Closes #408 Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 9 +++++-- self-development/axon-pr-reviewer.yaml | 36 +++++++++++++++++--------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/self-development/README.md b/self-development/README.md index 5a5caa7b..e42642c8 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -169,11 +169,16 @@ This TaskSpawner watches for open pull requests labeled `ok-to-test` and perform kubectl apply -f self-development/axon-pr-reviewer.yaml ``` -This spawner polls for new PRs and creates a task for each one to: +This spawner polls for PRs labeled `ok-to-test` and creates a task for each one to: +- Check if there are new commits since the last axon review - Read the full PR diff and understand the changes - Review for correctness, test coverage, style, security, and simplicity - Post a structured review comment on the PR -- Add the `axon/needs-input` label to avoid re-reviewing + +The reviewer automatically re-reviews PRs when new commits are pushed. +After the review Task's TTL expires, the spawner rediscovers the PR and +spawns a new review. The agent skips posting if there are no new commits +since its last review, so only meaningful updates trigger new feedback. The reviewer is read-only — it does not push code or modify files. diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index e0c00abb..28fb538c 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -9,8 +9,6 @@ spec: - pulls labels: - ok-to-test - excludeLabels: - - axon/needs-input maxConcurrency: 3 taskTemplate: workspaceRef: @@ -45,7 +43,25 @@ spec: ## Your tasks - ### 1. Read the full diff + ### 1. Check for new commits since last review + Before doing anything, check whether this PR has new commits since the + last axon review. Run: + ``` + LAST_REVIEW_DATE=$(gh api repos/{owner}/{repo}/pulls/{{.Number}}/reviews \ + --jq '[.[] | select(.user.login == "axon-agent" or (.body | test("Axon Agent"))) | .submitted_at] | sort | last // empty') + if [ -n "$LAST_REVIEW_DATE" ]; then + NEW_COMMITS=$(gh api repos/{owner}/{repo}/pulls/{{.Number}}/commits \ + --jq "[.[] | select(.commit.committer.date > \"$LAST_REVIEW_DATE\")] | length") + if [ "$NEW_COMMITS" = "0" ]; then + echo "No new commits since last review. Skipping." + exit 0 + fi + fi + ``` + If there are no new commits since the last axon review, exit immediately + without posting a review. + + ### 2. Read the full diff Fetch the PR diff and understand all changes: ``` git fetch --unshallow || true @@ -53,11 +69,11 @@ spec: gh pr diff {{.Number}} ``` - ### 2. Read the project conventions + ### 3. Read the project conventions Read `CLAUDE.md` (or `AGENTS.md`) in the repository root so your review aligns with the project's coding standards. - ### 3. Review the changes + ### 4. Review the changes Evaluate the PR for: - **Correctness**: Does the code do what it claims? Are there logic errors or edge cases? - **Tests**: Are there adequate tests for the changes? Are existing tests updated if needed? @@ -65,7 +81,7 @@ spec: - **Security**: Are there any security concerns (injection, hardcoded secrets, etc.)? - **Simplicity**: Is the change minimal and focused, or does it include unnecessary refactoring? - ### 4. Post your review + ### 5. Post your review Post a single review comment on the PR using `gh`: ``` gh pr review {{.Number}} --comment --body "..." @@ -74,6 +90,8 @@ spec: Format the comment as: ``` + 🤖 **Axon PR Reviewer** + ## Summary <1-3 sentence summary of what the PR does> @@ -88,12 +106,6 @@ spec: ``` - After posting the review, add the `axon/needs-input` label to the PR so - it is not re-reviewed: - ``` - gh pr edit {{.Number}} --add-label axon/needs-input - ``` - ## Constraints - Do NOT push code, create commits, or modify any files. This is a read-only review. - Do NOT approve or request changes via GitHub's formal review mechanism. From 341805d7b94106799e7dcbaf320c8a968ea61503 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 06:53:15 +0000 Subject: [PATCH 3/9] Set reviewer task TTL to zero for faster re-reviews Set ttlSecondsAfterFinished to 0 so the review task is deleted immediately after finishing. This lets the spawner rediscover the PR on the next poll cycle and re-review within ~1 minute of new commits being pushed, instead of waiting up to 1 hour for the old TTL to expire. Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 7 ++++--- self-development/axon-pr-reviewer.yaml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/self-development/README.md b/self-development/README.md index e42642c8..e2f3330d 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -176,9 +176,10 @@ This spawner polls for PRs labeled `ok-to-test` and creates a task for each one - Post a structured review comment on the PR The reviewer automatically re-reviews PRs when new commits are pushed. -After the review Task's TTL expires, the spawner rediscovers the PR and -spawns a new review. The agent skips posting if there are no new commits -since its last review, so only meaningful updates trigger new feedback. +The Task's TTL is set to zero so it is deleted as soon as the review +finishes, letting the spawner rediscover the PR on the next poll cycle. +The agent skips posting if there are no new commits since its last +review, so only meaningful updates trigger new feedback. The reviewer is read-only — it does not push code or modify files. diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index 28fb538c..c4630a6e 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -15,7 +15,7 @@ spec: name: axon-agent model: opus type: claude-code - ttlSecondsAfterFinished: 3600 + ttlSecondsAfterFinished: 0 credentials: type: oauth secretRef: From f53fb06f322fd0cca85dc325660939ae0c9625be Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 07:58:37 +0000 Subject: [PATCH 4/9] Use commit SHA comparison for skip-review check Replace date-based comparison with SHA comparison when deciding whether to skip a review. The reviewer now compares the PR head SHA against the commit_id from the last axon review, which is more reliable across rebases and force pushes. Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 6 +++--- self-development/axon-pr-reviewer.yaml | 19 ++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/self-development/README.md b/self-development/README.md index e2f3330d..90a4fc96 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -170,7 +170,7 @@ kubectl apply -f self-development/axon-pr-reviewer.yaml ``` This spawner polls for PRs labeled `ok-to-test` and creates a task for each one to: -- Check if there are new commits since the last axon review +- Check if the PR head has changed since the last axon review - Read the full PR diff and understand the changes - Review for correctness, test coverage, style, security, and simplicity - Post a structured review comment on the PR @@ -178,8 +178,8 @@ This spawner polls for PRs labeled `ok-to-test` and creates a task for each one The reviewer automatically re-reviews PRs when new commits are pushed. The Task's TTL is set to zero so it is deleted as soon as the review finishes, letting the spawner rediscover the PR on the next poll cycle. -The agent skips posting if there are no new commits since its last -review, so only meaningful updates trigger new feedback. +The agent compares the PR head SHA against the last reviewed commit +and skips posting if they match, so only new pushes trigger feedback. The reviewer is read-only — it does not push code or modify files. diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index c4630a6e..78296790 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -44,21 +44,18 @@ spec: ## Your tasks ### 1. Check for new commits since last review - Before doing anything, check whether this PR has new commits since the + Before doing anything, check whether the PR head has changed since the last axon review. Run: ``` - LAST_REVIEW_DATE=$(gh api repos/{owner}/{repo}/pulls/{{.Number}}/reviews \ - --jq '[.[] | select(.user.login == "axon-agent" or (.body | test("Axon Agent"))) | .submitted_at] | sort | last // empty') - if [ -n "$LAST_REVIEW_DATE" ]; then - NEW_COMMITS=$(gh api repos/{owner}/{repo}/pulls/{{.Number}}/commits \ - --jq "[.[] | select(.commit.committer.date > \"$LAST_REVIEW_DATE\")] | length") - if [ "$NEW_COMMITS" = "0" ]; then - echo "No new commits since last review. Skipping." - exit 0 - fi + HEAD_SHA=$(gh api repos/{owner}/{repo}/pulls/{{.Number}} --jq '.head.sha') + LAST_REVIEWED_SHA=$(gh api repos/{owner}/{repo}/pulls/{{.Number}}/reviews \ + --jq '[.[] | select(.user.login == "axon-agent" or (.body | test("Axon Agent"))) | .commit_id] | last // empty') + if [ "$HEAD_SHA" = "$LAST_REVIEWED_SHA" ]; then + echo "Already reviewed commit $HEAD_SHA. Skipping." + exit 0 fi ``` - If there are no new commits since the last axon review, exit immediately + If the PR head SHA matches the last reviewed commit, exit immediately without posting a review. ### 2. Read the full diff From ff3ee3bd59f31c5f66ec2e6f17d0faa6be174f4b Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 09:04:51 +0000 Subject: [PATCH 5/9] Fix skip-review check to reliably detect new commits - Replace broken {owner}/{repo} placeholders with dynamic repo detection via `gh repo view` and `gh pr view` - Add null check for LAST_REVIEWED_SHA so the first review always runs - Match review comments by "Axon PR Reviewer" instead of "Axon Agent" to align with the actual review comment format - Include reviewed commit SHA in review output for reliable comparison - Add diagnostic logging for review decisions Co-Authored-By: Claude Opus 4.6 --- self-development/axon-pr-reviewer.yaml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index 78296790..6fa7c9c4 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -47,16 +47,18 @@ spec: Before doing anything, check whether the PR head has changed since the last axon review. Run: ``` - HEAD_SHA=$(gh api repos/{owner}/{repo}/pulls/{{.Number}} --jq '.head.sha') - LAST_REVIEWED_SHA=$(gh api repos/{owner}/{repo}/pulls/{{.Number}}/reviews \ - --jq '[.[] | select(.user.login == "axon-agent" or (.body | test("Axon Agent"))) | .commit_id] | last // empty') - if [ "$HEAD_SHA" = "$LAST_REVIEWED_SHA" ]; then + REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) + HEAD_SHA=$(gh pr view {{.Number}} --json headRefOid -q .headRefOid) + LAST_REVIEWED_SHA=$(gh api "repos/${REPO}/pulls/{{.Number}}/reviews" \ + --jq '[.[] | select(.user.login == "axon-agent" or (.body | test("Axon PR Reviewer"))) | .commit_id] | last // empty') + if [ -n "$LAST_REVIEWED_SHA" ] && [ "$HEAD_SHA" = "$LAST_REVIEWED_SHA" ]; then echo "Already reviewed commit $HEAD_SHA. Skipping." exit 0 fi + echo "Reviewing commit $HEAD_SHA (last reviewed: ${LAST_REVIEWED_SHA:-none})" ``` If the PR head SHA matches the last reviewed commit, exit immediately - without posting a review. + without posting a review. Otherwise, proceed with the review. ### 2. Read the full diff Fetch the PR diff and understand all changes: @@ -89,6 +91,8 @@ spec: ``` 🤖 **Axon PR Reviewer** + **Reviewed commit:** + ## Summary <1-3 sentence summary of what the PR does> @@ -109,4 +113,5 @@ spec: Use `--comment` only. - Be constructive and specific. Avoid vague feedback. - Focus on substantive issues, not style nitpicks that a linter would catch. + - Always include the reviewed commit SHA in the review comment header. pollInterval: 1m From b85aa207058f0cfa333ece76f1788c216b4f08d2 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 11:15:17 +0000 Subject: [PATCH 6/9] Use issue comments for reliable skip-review detection Switch review posting from `gh pr review --comment` to `gh pr comment` so that the skip-review check can reliably find prior reviews via `gh pr view --json comments`. The previous approach used the reviews API which required fragile jq filters on user login and body content. The new approach parses the reviewed commit SHA directly from comment bodies, making skip detection consistent with the posting mechanism. Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 7 ++++--- self-development/axon-pr-reviewer.yaml | 23 +++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/self-development/README.md b/self-development/README.md index 90a4fc96..5db33883 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -173,13 +173,14 @@ This spawner polls for PRs labeled `ok-to-test` and creates a task for each one - Check if the PR head has changed since the last axon review - Read the full PR diff and understand the changes - Review for correctness, test coverage, style, security, and simplicity -- Post a structured review comment on the PR +- Post a structured comment on the PR The reviewer automatically re-reviews PRs when new commits are pushed. The Task's TTL is set to zero so it is deleted as soon as the review finishes, letting the spawner rediscover the PR on the next poll cycle. -The agent compares the PR head SHA against the last reviewed commit -and skips posting if they match, so only new pushes trigger feedback. +The agent compares the PR head SHA against the reviewed commit SHA +embedded in prior comments and skips if they match, so only new pushes +trigger a new review. The reviewer is read-only — it does not push code or modify files. diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index 6fa7c9c4..bc38a23c 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -47,18 +47,17 @@ spec: Before doing anything, check whether the PR head has changed since the last axon review. Run: ``` - REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) HEAD_SHA=$(gh pr view {{.Number}} --json headRefOid -q .headRefOid) - LAST_REVIEWED_SHA=$(gh api "repos/${REPO}/pulls/{{.Number}}/reviews" \ - --jq '[.[] | select(.user.login == "axon-agent" or (.body | test("Axon PR Reviewer"))) | .commit_id] | last // empty') - if [ -n "$LAST_REVIEWED_SHA" ] && [ "$HEAD_SHA" = "$LAST_REVIEWED_SHA" ]; then + LAST_REVIEWED=$(gh pr view {{.Number}} --json comments \ + --jq '[.comments[] | select(.body | test("Axon PR Reviewer")) | .body | capture("Reviewed commit:.* (?[0-9a-f]{7,40})") | .sha] | last // empty') + if [ -n "$LAST_REVIEWED" ] && [ "$HEAD_SHA" = "$LAST_REVIEWED" ]; then echo "Already reviewed commit $HEAD_SHA. Skipping." exit 0 fi - echo "Reviewing commit $HEAD_SHA (last reviewed: ${LAST_REVIEWED_SHA:-none})" + echo "Reviewing commit $HEAD_SHA (last reviewed: ${LAST_REVIEWED:-none})" ``` - If the PR head SHA matches the last reviewed commit, exit immediately - without posting a review. Otherwise, proceed with the review. + If the output says "Skipping", stop immediately without posting a review. + Otherwise, proceed with the review. ### 2. Read the full diff Fetch the PR diff and understand all changes: @@ -81,9 +80,9 @@ spec: - **Simplicity**: Is the change minimal and focused, or does it include unnecessary refactoring? ### 5. Post your review - Post a single review comment on the PR using `gh`: + Post a single comment on the PR using `gh`: ``` - gh pr review {{.Number}} --comment --body "..." + gh pr comment {{.Number}} --body "..." ``` Format the comment as: @@ -91,7 +90,7 @@ spec: ``` 🤖 **Axon PR Reviewer** - **Reviewed commit:** + **Reviewed commit:** ## Summary <1-3 sentence summary of what the PR does> @@ -110,8 +109,8 @@ spec: ## Constraints - Do NOT push code, create commits, or modify any files. This is a read-only review. - Do NOT approve or request changes via GitHub's formal review mechanism. - Use `--comment` only. + Post comments only via `gh pr comment`. - Be constructive and specific. Avoid vague feedback. - Focus on substantive issues, not style nitpicks that a linter would catch. - - Always include the reviewed commit SHA in the review comment header. + - Always include the full reviewed commit SHA in the review comment header. pollInterval: 1m From e0e56b91eee91de2653eb360a54d990d5ff3d60f Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 12:18:11 +0000 Subject: [PATCH 7/9] Guard jq capture call against comments without reviewed commit SHA Add the jq try operator (?) to the capture() call so that comments matching "Axon PR Reviewer" but lacking a "Reviewed commit" line silently produce no output instead of erroring and forcing unnecessary re-reviews. Co-Authored-By: Claude Opus 4.6 --- self-development/axon-pr-reviewer.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index bc38a23c..458a267d 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -49,7 +49,7 @@ spec: ``` HEAD_SHA=$(gh pr view {{.Number}} --json headRefOid -q .headRefOid) LAST_REVIEWED=$(gh pr view {{.Number}} --json comments \ - --jq '[.comments[] | select(.body | test("Axon PR Reviewer")) | .body | capture("Reviewed commit:.* (?[0-9a-f]{7,40})") | .sha] | last // empty') + --jq '[.comments[] | select(.body | test("Axon PR Reviewer")) | .body | capture("Reviewed commit:.* (?[0-9a-f]{7,40})")? | .sha] | last // empty') if [ -n "$LAST_REVIEWED" ] && [ "$HEAD_SHA" = "$LAST_REVIEWED" ]; then echo "Already reviewed commit $HEAD_SHA. Skipping." exit 0 From 4146f035096bd95fa1ce542e05109c7b16a3cf72 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Sun, 22 Feb 2026 14:26:19 +0000 Subject: [PATCH 8/9] Review incremental diff on follow-up reviews When the PR has been reviewed before, the reviewer now fetches the incremental diff (LAST_REVIEWED...HEAD_SHA) in addition to the full PR diff. Follow-up review comments use a distinct format that shows the "Changes since" SHA and focuses feedback on the new commits while noting whether prior feedback has been addressed. Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 4 ++- self-development/axon-pr-reviewer.yaml | 37 ++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/self-development/README.md b/self-development/README.md index 5db33883..0d4dac45 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -171,11 +171,13 @@ kubectl apply -f self-development/axon-pr-reviewer.yaml This spawner polls for PRs labeled `ok-to-test` and creates a task for each one to: - Check if the PR head has changed since the last axon review -- Read the full PR diff and understand the changes +- Read the full PR diff for context and the incremental diff since the last review - Review for correctness, test coverage, style, security, and simplicity - Post a structured comment on the PR The reviewer automatically re-reviews PRs when new commits are pushed. +On follow-up reviews it focuses on the incremental diff (changes since the +last reviewed commit) while using the full PR diff for overall context. The Task's TTL is set to zero so it is deleted as soon as the review finishes, letting the spawner rediscover the PR on the next poll cycle. The agent compares the PR head SHA against the reviewed commit SHA diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index 458a267d..e2bb11ff 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -59,14 +59,24 @@ spec: If the output says "Skipping", stop immediately without posting a review. Otherwise, proceed with the review. - ### 2. Read the full diff - Fetch the PR diff and understand all changes: + ### 2. Read the diff + Fetch the PR diff and understand the changes: ``` git fetch --unshallow || true git fetch origin main gh pr diff {{.Number}} ``` + If `LAST_REVIEWED` is set (i.e., a previous review exists), also fetch + the incremental diff covering only the commits added since the last review: + ``` + git diff "$LAST_REVIEWED"..."$HEAD_SHA" + ``` + Focus your review on the incremental diff, but use the full PR diff for + overall context. + + If `LAST_REVIEWED` is empty (first review), review the full PR diff. + ### 3. Read the project conventions Read `CLAUDE.md` (or `AGENTS.md`) in the repository root so your review aligns with the project's coding standards. @@ -87,6 +97,7 @@ spec: Format the comment as: + For a **first review** (no previous review): ``` 🤖 **Axon PR Reviewer** @@ -106,6 +117,28 @@ spec: ``` + For a **follow-up review** (previous review exists): + ``` + 🤖 **Axon PR Reviewer** + + **Reviewed commit:** + **Changes since:** + + ## Summary + <1-3 sentence summary of what changed since the last review> + + ## Review + + + + ## Verdict + **LGTM** / **Changes requested** + + + ``` + ## Constraints - Do NOT push code, create commits, or modify any files. This is a read-only review. - Do NOT approve or request changes via GitHub's formal review mechanism. From 85ceeff043ecffe63016fd54c440badc4962ee55 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Mon, 23 Feb 2026 13:48:36 +0000 Subject: [PATCH 9/9] Use TTL 3600s instead of 0 to prevent constant task re-spawning Address review feedback: ttlSecondsAfterFinished: 0 caused the spawner to continuously create new review tasks every poll cycle (1 minute), wasting tokens even when the PR had not changed. Switch to TTL 3600s (matching axon-workers) so the Task persists after completion and prevents re-spawning. Re-reviews can be triggered via /reset-worker. Remove the skip-if-already-reviewed logic from the prompt since the spawner's own deduplication (by task name) now handles this. The agent still detects previous reviews for incremental diff purposes. Co-Authored-By: Claude Opus 4.6 --- self-development/README.md | 11 ++++------- self-development/axon-pr-reviewer.yaml | 15 ++++----------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/self-development/README.md b/self-development/README.md index 0d4dac45..fc17386a 100644 --- a/self-development/README.md +++ b/self-development/README.md @@ -170,19 +170,16 @@ kubectl apply -f self-development/axon-pr-reviewer.yaml ``` This spawner polls for PRs labeled `ok-to-test` and creates a task for each one to: -- Check if the PR head has changed since the last axon review - Read the full PR diff for context and the incremental diff since the last review - Review for correctness, test coverage, style, security, and simplicity - Post a structured comment on the PR -The reviewer automatically re-reviews PRs when new commits are pushed. On follow-up reviews it focuses on the incremental diff (changes since the last reviewed commit) while using the full PR diff for overall context. -The Task's TTL is set to zero so it is deleted as soon as the review -finishes, letting the spawner rediscover the PR on the next poll cycle. -The agent compares the PR head SHA against the reviewed commit SHA -embedded in prior comments and skips if they match, so only new pushes -trigger a new review. +The Task persists for one hour after completion (TTL 3600s), preventing +repeated spawns. To re-trigger a review after pushing new commits, use +the `/reset-worker` comment pattern to delete the existing Task so the +spawner can recreate it on the next poll cycle. The reviewer is read-only — it does not push code or modify files. diff --git a/self-development/axon-pr-reviewer.yaml b/self-development/axon-pr-reviewer.yaml index e2bb11ff..31b5fb73 100644 --- a/self-development/axon-pr-reviewer.yaml +++ b/self-development/axon-pr-reviewer.yaml @@ -15,7 +15,7 @@ spec: name: axon-agent model: opus type: claude-code - ttlSecondsAfterFinished: 0 + ttlSecondsAfterFinished: 3600 credentials: type: oauth secretRef: @@ -43,21 +43,14 @@ spec: ## Your tasks - ### 1. Check for new commits since last review - Before doing anything, check whether the PR head has changed since the - last axon review. Run: + ### 1. Gather context + Fetch the current HEAD SHA and check whether a previous axon review exists: ``` HEAD_SHA=$(gh pr view {{.Number}} --json headRefOid -q .headRefOid) LAST_REVIEWED=$(gh pr view {{.Number}} --json comments \ --jq '[.comments[] | select(.body | test("Axon PR Reviewer")) | .body | capture("Reviewed commit:.* (?[0-9a-f]{7,40})")? | .sha] | last // empty') - if [ -n "$LAST_REVIEWED" ] && [ "$HEAD_SHA" = "$LAST_REVIEWED" ]; then - echo "Already reviewed commit $HEAD_SHA. Skipping." - exit 0 - fi - echo "Reviewing commit $HEAD_SHA (last reviewed: ${LAST_REVIEWED:-none})" + echo "HEAD: $HEAD_SHA, last reviewed: ${LAST_REVIEWED:-none}" ``` - If the output says "Skipping", stop immediately without posting a review. - Otherwise, proceed with the review. ### 2. Read the diff Fetch the PR diff and understand the changes: