Add Claude PR review workflow #41

Open
james wants to merge 6 commits from ci/claude-pr-review into main
Owner

Adds a claude-review workflow that reviews every same-repo pull request with Claude Code and posts one comment, updated in place on later pushes.

What it does

  • Dependency-bot PRs (head branch renovate/… or dependabot/…): a table of every item updated, a changelog per dependency looked up from upstream, concerns checked against how Balam uses the package, and a merge recommendation.
  • All other PRs: reviews every changed file, then reports findings by severity, completeness gaps, CI results and comments (ojo scan, Codecov, unaddressed reviewer comments), recommendations and a verdict.
  • Waits up to 10 minutes for the other checks to finish so the security-scan and coverage comments exist before the review reads them.

Setup required

Add one Actions secret: ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN.

Optional repository variables:

  • CLAUDE_REVIEW_MODEL (default claude-opus-5-5)
  • CLAUDE_REVIEW_WAIT_SECONDS (default 600; set 0 if the runner only runs one job at a time, otherwise the wait blocks the jobs it is waiting for)
  • CLAUDE_REVIEW_WEB_DOMAINS (hosts Claude may fetch changelogs from on dependency PRs; defaults to GitHub, GitLab, Go, npm and Docker Hub hosts)

Security

  • Claude gets only Read, Grep and Glob, confined to the checkout and the gathered context; dependency PRs add web search and fetches to the allowed hosts. No shell, no writes, no MCP servers.
  • The checkout does not persist credentials, Claude runs without the Forgejo token in its environment, and the script posts the comment itself. A review containing a credential is refused.
  • Prompts are read from the base branch. The workflow and script run from the PR, so a PR that edits them is reviewed under its own rules.
  • Project-level Claude settings from the PR checkout are not loaded, and the Claude Code version is pinned (Renovate bumps it).
  • Fork PRs are skipped.

Testing

  • scripts/test_claude_pr_review.sh runs the script end to end against stubbed curl and claude, and runs in test / go.
  • The workflow has reviewed this PR on each push; the later commits address its findings.
  • Not covered by the test: the wait loop, the "PR head moved" exit, and truncation of very long reviews.
Adds a `claude-review` workflow that reviews every same-repo pull request with Claude Code and posts one comment, updated in place on later pushes. ## What it does - **Dependency-bot PRs** (head branch `renovate/…` or `dependabot/…`): a table of every item updated, a changelog per dependency looked up from upstream, concerns checked against how Balam uses the package, and a merge recommendation. - **All other PRs**: reviews every changed file, then reports findings by severity, completeness gaps, CI results and comments (ojo scan, Codecov, unaddressed reviewer comments), recommendations and a verdict. - Waits up to 10 minutes for the other checks to finish so the security-scan and coverage comments exist before the review reads them. ## Setup required Add one Actions secret: `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN`. Optional repository variables: - `CLAUDE_REVIEW_MODEL` (default `claude-opus-5-5`) - `CLAUDE_REVIEW_WAIT_SECONDS` (default `600`; set `0` if the runner only runs one job at a time, otherwise the wait blocks the jobs it is waiting for) - `CLAUDE_REVIEW_WEB_DOMAINS` (hosts Claude may fetch changelogs from on dependency PRs; defaults to GitHub, GitLab, Go, npm and Docker Hub hosts) ## Security - Claude gets only `Read`, `Grep` and `Glob`, confined to the checkout and the gathered context; dependency PRs add web search and fetches to the allowed hosts. No shell, no writes, no MCP servers. - The checkout does not persist credentials, Claude runs without the Forgejo token in its environment, and the script posts the comment itself. A review containing a credential is refused. - Prompts are read from the base branch. The workflow and script run from the PR, so a PR that edits them is reviewed under its own rules. - Project-level Claude settings from the PR checkout are not loaded, and the Claude Code version is pinned (Renovate bumps it). - Fork PRs are skipped. ## Testing - `scripts/test_claude_pr_review.sh` runs the script end to end against stubbed `curl` and `claude`, and runs in `test / go`. - The workflow has reviewed this PR on each push; the later commits address its findings. - Not covered by the test: the wait loop, the "PR head moved" exit, and truncation of very long reviews.
add Claude PR review workflow
Some checks failed
security-scan / security-scan (pull_request) Successful in 31s
codecov/project 0.00% (No base report)
codecov/patch 100.00% >= target 80%
test / web (pull_request) Successful in 1m42s
test / coverage-badge (pull_request) Has been skipped
claude-review / review (pull_request) Has been cancelled
test / go (pull_request) Has been cancelled
09e2ec84cc
Reviews every same-repo pull request with Claude Code and posts a single
comment that is updated in place on later pushes. Renovate/dependabot
branches get a changelog-focused dependency review; other PRs get a full
code review covering findings, completeness, CI results and comments.

Claude runs with read-only tools and never sees the Forgejo token; the
script gathers context and posts the comment itself.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

🔎 ojo scan results

Severity Count
🟠 HIGH 2
🟡 MEDIUM 1
🟢 LOW 1
⚪ UNKNOWN 1
Details (5)
Type Severity ID/Rule Location Description
vuln 🟠 HIGH CVE-2026-93687 [email protected] braces vulnerable to stack-exhaustion denial of service through deeply nested patterns
vuln 🟠 HIGH CVE-2026-93749 [email protected] source-map-js allows event-loop denial of service through indexed source-map section offsets
vuln 🟡 MEDIUM CVE-2026-104844 [email protected] PostCSS: Quadratic complexity in flat selector parsing allows CPU exhaustion
sast 🟢 LOW js-unreachable-code web/src/pages/Languages.tsx:39 this statement can never execute; it follows a return { byLang, byPlatform }; in the same block
vuln ⚪ UNKNOWN GO-2026-5932 golang.org/x/[email protected] The golang.org/x/crypto/openpgp package is unmaintained, unsafe by design, and has known security issues
<!-- ojo-scan-summary --> ### 🔎 ojo scan results | Severity | Count | |---|---| | 🟠 HIGH | 2 | | 🟡 MEDIUM | 1 | | 🟢 LOW | 1 | | ⚪ UNKNOWN | 1 | <details><summary>Details (5)</summary> | Type | Severity | ID/Rule | Location | Description | |---|---|---|---|---| | vuln | 🟠 HIGH | <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-93687" target="_blank" rel="noopener noreferrer">CVE-2026-93687</a> | [email protected] | braces vulnerable to stack-exhaustion denial of service through deeply nested patterns | | vuln | 🟠 HIGH | <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-93749" target="_blank" rel="noopener noreferrer">CVE-2026-93749</a> | [email protected] | source-map-js allows event-loop denial of service through indexed source-map section offsets | | vuln | 🟡 MEDIUM | <a href="https://github.com/postcss/postcss-selector-parser/security/advisories/GHSA-rj75-hqrm-r3gf" target="_blank" rel="noopener noreferrer">CVE-2026-104844</a> | [email protected] | PostCSS: Quadratic complexity in flat selector parsing allows CPU exhaustion | | sast | 🟢 LOW | js-unreachable-code | <a href="https://git.colibrisec.org/ColibriSec/balam/src/commit/dbe96dbe5ff30d7af49239c4caa24489d358f69b/web/src/pages/Languages.tsx#L39" target="_blank" rel="noopener noreferrer">web/src/pages/Languages.tsx:39</a> | this statement can never execute; it follows a return { byLang, byPlatform }; in the same block | | vuln | ⚪ UNKNOWN | <a href="https://go.dev/issue/44226" target="_blank" rel="noopener noreferrer">GO-2026-5932</a> | golang.org/x/[email protected] | The golang.org/x/crypto/openpgp package is unmaintained, unsafe by design, and has known security issues | </details>

Codecov Results 📊

✅ Patch coverage is 100.00%. Project has 4967 uncovered lines.


Generated by Codecov Action

<!-- codecov-action-results --> ## Codecov Results 📊 :white_check_mark: Patch coverage is **100.00%**. Project has **4967** uncovered lines. --- *Generated by [Codecov Action](https://github.com/getsentry/codecov-action)*
james force-pushed ci/claude-pr-review from 09e2ec84cc
Some checks failed
security-scan / security-scan (pull_request) Successful in 31s
codecov/project 0.00% (No base report)
codecov/patch 100.00% >= target 80%
test / web (pull_request) Successful in 1m42s
test / coverage-badge (pull_request) Has been skipped
claude-review / review (pull_request) Has been cancelled
test / go (pull_request) Has been cancelled
to 7a5307d124
All checks were successful
security-scan / security-scan (pull_request) Successful in 37s
test / web (pull_request) Successful in 1m48s
test / coverage-badge (pull_request) Has been skipped
codecov/project 34.78% (No base report)
codecov/patch 100.00% >= target 80%
test / go (pull_request) Successful in 2m19s
claude-review / review (pull_request) Successful in 4m46s
2026-10-08 21:13:21 +00:00
Compare

Summary

This PR adds a claude-review Forgejo workflow. On every pull request opened from a branch of this repository, scripts/claude-pr-review.sh collects the PR metadata, diff, commit statuses and comments, runs Claude Code headless with read-only tools, and posts one comment that is edited on later pushes. Renovate and Dependabot branches get a dependency-update prompt (bot.md); all other PRs get a code-review prompt (human.md). Both share common.md. The PR also adds a stubbed end-to-end test that runs in test / go, a README section, and a Renovate regex manager that keeps the pinned Claude Code version up to date. The diff matches the title and description. Every security measure the description lists is present in the code.

This review was produced by the script and prompts in this PR. main does not have .forgejo/claude-review/ yet, so prompt_file falls back to the PR's own copy (scripts/claude-pr-review.sh:187). As the README says, a human should read scripts/claude-pr-review.sh and the workflow directly rather than rely on this comment.

Findings

  1. Should fix: any branch named renovate/… gets the dependency review instead of a code review. See scripts/claude-pr-review.sh:30 and :95.
    • The branch name alone selects bot mode. Anyone who can push here can open renovate/x with arbitrary code changes.
    • That PR is then reviewed only for "what is being updated" and gets a "Safe to merge" style verdict. It also gets WebSearch and WebFetch, which human-mode PRs do not.
    • Fix: when only the branch matches, also require the author to be the account Renovate runs as. Make that account a repository variable, since the script says Renovate posts under a human account. Alternatively, fall back to human mode whenever the diff touches files other than go.mod, go.sum, web/package*.json, Dockerfiles or .forgejo/workflows/*.
  2. Nit: the marker match also accepts comments from other workflows. See scripts/claude-pr-review.sh:136 and :261.
    • The ojo and Codecov jobs also post as forgejo-actions. Matching on user.login == $bot and contains($marker) means any comment from that account that contains the marker anywhere counts as the previous review.
    • Such a comment would be hidden from the reviewer and overwritten by the PATCH.
    • Fix: the script always writes the marker as the first line, so match with .body | startswith($marker).
  3. Nit: the self-exclusion filter is too broad. startswith($self) (scripts/claude-pr-review.sh:106) also drops any other workflow whose name begins with claude-review. Use startswith($self + " /").
  4. Nit: the "(status lookup failed)" fallback never runs. See scripts/claude-pr-review.sh:118.
    • Because statuses runs on the left of ||, errexit is off inside it. A failed curl in api_list therefore leaves chunk empty, which equals the empty previous at :76, so the loop breaks and outputs [].
    • The echo fallback is never reached. A persistently failing API is logged as "(no checks reported yet)", and the pending note says the same.
    • The retry still works. Only the message is wrong. Fix: check curl's exit status inside api_list, or drop the fallback and its comment.
  5. Nit: some environment overrides are documented nowhere and cannot be set without editing the workflow.
    • CLAUDE_REVIEW_COMMENT_AUTHOR, CLAUDE_REVIEW_BOT_BRANCH_RE and CLAUDE_REVIEW_BOT_AUTHOR_RE (scripts/claude-pr-review.sh:30-38) are read by the script, but the workflow does not pass them and the README does not mention them.
    • If the job token posts as an account other than forgejo-actions, every run creates a new comment, and earlier reviews are fed back to Claude as reviewer comments.
    • Fix: wire COMMENT_AUTHOR (and finding 1's author) through vars.* and add them to the README table.
  6. Nit: the PR can change the conventions it is reviewed against. common.md:15 tells Claude to read AGENTS.md from the PR checkout. Prompts are taken from the base branch, but a PR can still weaken the conventions by editing AGENTS.md. Consider giving Claude the base-branch AGENTS.md as well, or telling it to flag changes to AGENTS.md.
  7. Nit: fileMatch may be deprecated. At renovate.json:8, recent Renovate releases rename fileMatch to managerFilePatterns and migrate the old name automatically. I could not check which Renovate version the shared workflow (colibrisec/forgejo-workflows) uses, so treat this as something to confirm.

No tenant-isolation, internal/crypto, RBAC or serialization concerns apply: the PR changes no Go or TypeScript code.

Completeness

  • Tests: scripts/test_claude_pr_review.sh covers prompt selection from the base branch, the tool lists, token stripping, pagination and repeat detection, the planted marker, self-exclusion, in-place update, refusing a review that contains a credential, and a push during the review. Untested, as the description says: the wait loop, the "PR head moved" exit at diff time, and truncation.
  • Weak assertion: the push-during-review case (scripts/test_claude_pr_review.sh:145) only checks exit 0 and that nothing was written. It does not check stdout for "not posting", so an unrelated early exit 0 would also pass.
  • jq dependency: test.yml:23 relies on jq already being on the runner image. security-scan.yml and claude-review.yml install it explicitly. It works today, since test / go passed.
  • Docs: the README is updated. STATUS.md does not track CI, so it needs no change. Migrations, AllModels(), the api/ spec and frontend changes do not apply.
  • Leftovers: no TODOs or debug code. Nothing the description promises is missing from the diff.

CI and comments

Check Result
codecov/patch success (100.00% ≥ 80%)
codecov/project success (34.78%, no base report)
security-scan / security-scan success
test / go success
test / web failure ("Failing after 7s")
test / coverage-badge skipped (runs on push only)
  • test / web: failed. The PR changes nothing under web/, and failing after 7s points to a setup or npm ci step, but I could not see the job log, so I can't confirm it is unrelated. Check whether main fails the same way.
  • ojo scan (5 findings): none are introduced or touched by this PR.
    • CVE-2026-93687 (braces 3.0.3), CVE-2026-93749 (source-map-js 1.2.1) and CVE-2026-104844 (postcss-selector-parser 6.1.4) are in npm dependencies. web/package-lock.json is not changed here.
    • The js-unreachable-code hit at web/src/pages/Languages.tsx:39 is an eslint-disable comment after a return, which looks like a false positive. The file is not changed here.
    • GO-2026-5932 is golang.org/x/crypto v0.56.0 (go.mod:12) being flagged for openpgp. No Go file in the repo imports openpgp, and go.mod is not changed here.
  • Coverage: patch 100%, but the PR adds no Go or TypeScript code, so this figure says nothing. Project coverage is 34.78% with no base report.
  • Reviewer comments: there are no human comments or reviews. Earlier Claude reviews of this PR are filtered out of comments.json by design, so I cannot check whether their findings were addressed beyond what the commit messages claim.
  • Prompt injection: none found in the PR content.

Recommendations

Before merging:

  1. Stop selecting bot mode from the branch name alone (finding 1).
  2. Find out why test / web fails, or confirm it fails the same way on main.
  3. Match the marker as a prefix and wire the comment-author and bot-author settings through repository variables (findings 2 and 5).

Can wait:

  • Fix the self-exclusion prefix and the dead fallback (findings 3 and 4).
  • Read AGENTS.md from the base branch (finding 6).
  • Confirm fileMatch vs managerFilePatterns (finding 7).
  • Add a Renovate minimumReleaseAge for @anthropic-ai/claude-code. A Renovate PR runs the workflow from its own branch, so a new release would run with ANTHROPIC_API_KEY and pull-requests: write as soon as the PR opens.
  • Add tests for the wait loop and the head-moved exit.

Verdict

Merge after fixes: any branch named renovate/… can currently swap the code review for a dependency-only review, and test / web is failing.


Claude code review of dbe96dbe5f · claude-opus-5-5

<!-- claude-pr-review --> ### Summary This PR adds a `claude-review` Forgejo workflow. On every pull request opened from a branch of this repository, `scripts/claude-pr-review.sh` collects the PR metadata, diff, commit statuses and comments, runs Claude Code headless with read-only tools, and posts one comment that is edited on later pushes. Renovate and Dependabot branches get a dependency-update prompt (`bot.md`); all other PRs get a code-review prompt (`human.md`). Both share `common.md`. The PR also adds a stubbed end-to-end test that runs in `test / go`, a README section, and a Renovate regex manager that keeps the pinned Claude Code version up to date. The diff matches the title and description. Every security measure the description lists is present in the code. **This review was produced by the script and prompts in this PR.** `main` does not have `.forgejo/claude-review/` yet, so `prompt_file` falls back to the PR's own copy (`scripts/claude-pr-review.sh:187`). As the README says, a human should read `scripts/claude-pr-review.sh` and the workflow directly rather than rely on this comment. ### Findings 1. **Should fix: any branch named `renovate/…` gets the dependency review instead of a code review.** See `scripts/claude-pr-review.sh:30` and `:95`. - The branch name alone selects bot mode. Anyone who can push here can open `renovate/x` with arbitrary code changes. - That PR is then reviewed only for "what is being updated" and gets a "Safe to merge" style verdict. It also gets WebSearch and WebFetch, which human-mode PRs do not. - Fix: when only the branch matches, also require the author to be the account Renovate runs as. Make that account a repository variable, since the script says Renovate posts under a human account. Alternatively, fall back to `human` mode whenever the diff touches files other than `go.mod`, `go.sum`, `web/package*.json`, Dockerfiles or `.forgejo/workflows/*`. 2. **Nit: the marker match also accepts comments from other workflows.** See `scripts/claude-pr-review.sh:136` and `:261`. - The ojo and Codecov jobs also post as `forgejo-actions`. Matching on `user.login == $bot and contains($marker)` means any comment from that account that contains the marker anywhere counts as the previous review. - Such a comment would be hidden from the reviewer and overwritten by the PATCH. - Fix: the script always writes the marker as the first line, so match with `.body | startswith($marker)`. 3. **Nit: the self-exclusion filter is too broad.** `startswith($self)` (`scripts/claude-pr-review.sh:106`) also drops any other workflow whose name begins with `claude-review`. Use `startswith($self + " /")`. 4. **Nit: the "(status lookup failed)" fallback never runs.** See `scripts/claude-pr-review.sh:118`. - Because `statuses` runs on the left of `||`, errexit is off inside it. A failed `curl` in `api_list` therefore leaves `chunk` empty, which equals the empty `previous` at `:76`, so the loop breaks and outputs `[]`. - The `echo` fallback is never reached. A persistently failing API is logged as "(no checks reported yet)", and the pending note says the same. - The retry still works. Only the message is wrong. Fix: check `curl`'s exit status inside `api_list`, or drop the fallback and its comment. 5. **Nit: some environment overrides are documented nowhere and cannot be set without editing the workflow.** - `CLAUDE_REVIEW_COMMENT_AUTHOR`, `CLAUDE_REVIEW_BOT_BRANCH_RE` and `CLAUDE_REVIEW_BOT_AUTHOR_RE` (`scripts/claude-pr-review.sh:30-38`) are read by the script, but the workflow does not pass them and the README does not mention them. - If the job token posts as an account other than `forgejo-actions`, every run creates a new comment, and earlier reviews are fed back to Claude as reviewer comments. - Fix: wire `COMMENT_AUTHOR` (and finding 1's author) through `vars.*` and add them to the README table. 6. **Nit: the PR can change the conventions it is reviewed against.** `common.md:15` tells Claude to read `AGENTS.md` from the PR checkout. Prompts are taken from the base branch, but a PR can still weaken the conventions by editing `AGENTS.md`. Consider giving Claude the base-branch `AGENTS.md` as well, or telling it to flag changes to `AGENTS.md`. 7. **Nit: `fileMatch` may be deprecated.** At `renovate.json:8`, recent Renovate releases rename `fileMatch` to `managerFilePatterns` and migrate the old name automatically. I could not check which Renovate version the shared workflow (`colibrisec/forgejo-workflows`) uses, so treat this as something to confirm. No tenant-isolation, `internal/crypto`, RBAC or serialization concerns apply: the PR changes no Go or TypeScript code. ### Completeness - **Tests:** `scripts/test_claude_pr_review.sh` covers prompt selection from the base branch, the tool lists, token stripping, pagination and repeat detection, the planted marker, self-exclusion, in-place update, refusing a review that contains a credential, and a push during the review. Untested, as the description says: the wait loop, the "PR head moved" exit at diff time, and truncation. - **Weak assertion:** the push-during-review case (`scripts/test_claude_pr_review.sh:145`) only checks exit 0 and that nothing was written. It does not check stdout for "not posting", so an unrelated early `exit 0` would also pass. - **jq dependency:** `test.yml:23` relies on `jq` already being on the runner image. `security-scan.yml` and `claude-review.yml` install it explicitly. It works today, since `test / go` passed. - **Docs:** the README is updated. `STATUS.md` does not track CI, so it needs no change. Migrations, `AllModels()`, the `api/` spec and frontend changes do not apply. - **Leftovers:** no TODOs or debug code. Nothing the description promises is missing from the diff. ### CI and comments | Check | Result | |---|---| | codecov/patch | success (100.00% ≥ 80%) | | codecov/project | success (34.78%, no base report) | | security-scan / security-scan | success | | test / go | success | | test / web | **failure** ("Failing after 7s") | | test / coverage-badge | skipped (runs on push only) | - **`test / web`:** failed. The PR changes nothing under `web/`, and failing after 7s points to a setup or `npm ci` step, but I could not see the job log, so I can't confirm it is unrelated. Check whether `main` fails the same way. - **ojo scan (5 findings):** none are introduced or touched by this PR. - CVE-2026-93687 (braces 3.0.3), CVE-2026-93749 (source-map-js 1.2.1) and CVE-2026-104844 (postcss-selector-parser 6.1.4) are in npm dependencies. `web/package-lock.json` is not changed here. - The `js-unreachable-code` hit at `web/src/pages/Languages.tsx:39` is an `eslint-disable` comment after a `return`, which looks like a false positive. The file is not changed here. - GO-2026-5932 is `golang.org/x/crypto v0.56.0` (`go.mod:12`) being flagged for `openpgp`. No Go file in the repo imports `openpgp`, and `go.mod` is not changed here. - **Coverage:** patch 100%, but the PR adds no Go or TypeScript code, so this figure says nothing. Project coverage is 34.78% with no base report. - **Reviewer comments:** there are no human comments or reviews. Earlier Claude reviews of this PR are filtered out of `comments.json` by design, so I cannot check whether their findings were addressed beyond what the commit messages claim. - **Prompt injection:** none found in the PR content. ### Recommendations Before merging: 1. Stop selecting bot mode from the branch name alone (finding 1). 2. Find out why `test / web` fails, or confirm it fails the same way on `main`. 3. Match the marker as a prefix and wire the comment-author and bot-author settings through repository variables (findings 2 and 5). Can wait: - Fix the self-exclusion prefix and the dead fallback (findings 3 and 4). - Read `AGENTS.md` from the base branch (finding 6). - Confirm `fileMatch` vs `managerFilePatterns` (finding 7). - Add a Renovate `minimumReleaseAge` for `@anthropic-ai/claude-code`. A Renovate PR runs the workflow from its own branch, so a new release would run with `ANTHROPIC_API_KEY` and `pull-requests: write` as soon as the PR opens. - Add tests for the wait loop and the head-moved exit. ### Verdict **Merge after fixes**: any branch named `renovate/…` can currently swap the code review for a dependency-only review, and `test / web` is failing. --- _Claude code review of dbe96dbe5f · claude-opus-5-5_
harden Claude PR review per its own review of #41
All checks were successful
security-scan / security-scan (pull_request) Successful in 33s
codecov/project 0.00% (No base report)
codecov/patch 100.00% >= target 80%
test / go (pull_request) Successful in 2m7s
test / web (pull_request) Successful in 2m10s
test / coverage-badge (pull_request) Has been skipped
claude-review / review (pull_request) Successful in 5m37s
0ad8e1dc69
- Check out without persisted credentials and run Claude without the
  Forgejo token in its environment; refuse to post a review that
  contains a credential.
- Restrict Claude to an explicit built-in tool list (--tools) with no
  MCP servers, instead of denying a few tools.
- Read the review prompts from the base branch so a PR cannot rewrite
  the instructions it is reviewed under.
- Paginate comment, review and status requests.
- Pin the Claude Code version and let Renovate bump it.
- Wait until sibling checks have registered, skip the run if the PR head
  moved, truncate by character, and drop narration before the first
  heading.
- Add a stubbed end-to-end test and document the setup in the README.
james referenced this pull request from a commit 2026-10-08 22:02:46 +00:00
address second Claude review of #41
All checks were successful
security-scan / security-scan (pull_request) Successful in 41s
test / web (pull_request) Successful in 1m46s
test / coverage-badge (pull_request) Has been skipped
codecov/project 34.78% (No base report)
codecov/patch 100.00% >= target 80%
test / go (pull_request) Successful in 6m32s
claude-review / review (pull_request) Successful in 9m42s
88333b6f39
- Limit bot-mode WebFetch to a configurable list of changelog hosts so an
  injected instruction cannot send repository contents to an arbitrary URL.
- Only treat a marker comment as the previous review when the job's own
  account wrote it, so a planted marker can neither block the job nor
  hide a comment from the reviewer.
- Fall back to the PR's prompts only when the base branch has none.
- Pass the resolved state of inline review comments to the reviewer.
- README: say plainly that a PR editing the workflow or script is
  reviewed under its own rules.
james referenced this pull request from a commit 2026-10-08 22:17:09 +00:00
address third Claude review of #41
Some checks failed
security-scan / security-scan (pull_request) Failing after 25s
codecov/project 0.00% (No base report)
codecov/patch 100.00% >= target 80%
test / web (pull_request) Successful in 1m18s
test / coverage-badge (pull_request) Has been skipped
test / go (pull_request) Successful in 2m9s
claude-review / review (pull_request) Successful in 4m31s
e2e11e3b27
- api_list: Forgejo's issue-comment and review-comment endpoints ignore
  page/limit and return everything each time, so a PR with 50+ comments
  made the listing loop until the job timed out. Stop when a page repeats
  the previous one and cap the page count.
- Stop pre-approving Read/Grep/Glob. Without the blanket approval they
  only work inside the checkout and the context directory, so the rest
  of the runner's filesystem is out of Claude's reach.
- README: fix the variable count.
james referenced this pull request from a commit 2026-10-08 22:22:24 +00:00
address fourth Claude review of #41
Some checks failed
security-scan / security-scan (pull_request) Failing after 26s
test / web (pull_request) Successful in 1m55s
test / coverage-badge (pull_request) Has been skipped
codecov/project 34.78% (No base report)
codecov/patch 100.00% >= target 80%
test / go (pull_request) Successful in 4m24s
claude-review / review (pull_request) Successful in 7m28s
dedbe082d6
- Re-check the PR head just before posting so a run that was overtaken
  by a push cannot overwrite the newer review.
- Strip the runner's other token variables from Claude's environment.
- Retry a failed status poll instead of failing the job.
- Anchor the bot-author pattern.
- Test: cover the overtaken-run case and print stderr when the bot case
  fails.
Merge branch 'main' into ci/claude-pr-review
Some checks failed
security-scan / security-scan (pull_request) Successful in 35s
codecov/project 34.78% (No base report)
codecov/patch 100.00% >= target 80%
test / go (pull_request) Successful in 3m11s
test / web (pull_request) Failing after 7s
test / coverage-badge (pull_request) Has been skipped
claude-review / review (pull_request) Successful in 7m23s
dbe96dbe5f
Some checks failed
security-scan / security-scan (pull_request) Successful in 35s
codecov/project 34.78% (No base report)
codecov/patch 100.00% >= target 80%
test / go (pull_request) Successful in 3m11s
test / web (pull_request) Failing after 7s
test / coverage-badge (pull_request) Has been skipped
claude-review / review (pull_request) Successful in 7m23s
This pull request doesn't have enough approvals yet. 0 of 1 approvals granted.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin ci/claude-pr-review:ci/claude-pr-review
git switch ci/claude-pr-review
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ColibriSec/balam!41
No description provided.