docs: add audit report for slash delay & blacklist fix and update readme (#1753) #306
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Claude Code Review Workflow | |
| # - Auto-reviews PRs targeting main (excludes drafts and forks) | |
| # - Responds to @claude mentions from org members only | |
| # - Uses OIDC auth with Claude GitHub App (id-token: write) | |
| name: Claude review | |
| on: | |
| # Trigger: new/updated PRs to main | |
| # pull_request: | |
| # types: [opened, synchronize, ready_for_review, reopened] | |
| # branches: | |
| # - main | |
| # Trigger: @claude mentions in comments | |
| issue_comment: | |
| types: [created] | |
| pull_request_review_comment: | |
| types: [created] | |
| pull_request_review: | |
| types: [submitted] | |
| jobs: | |
| # Job 1: Auto-review on PR open/update (no forks, no drafts) | |
| # auto-review: | |
| # if: | | |
| # github.event_name == 'pull_request' && | |
| # !github.event.pull_request.draft && | |
| # !github.event.pull_request.head.repo.fork | |
| # runs-on: ubuntu-latest | |
| # timeout-minutes: 15 | |
| # permissions: | |
| # contents: read | |
| # pull-requests: write | |
| # id-token: write | |
| # actions: read | |
| # steps: | |
| # # Checkout base branch (trusted) - Claude reads PR diff via gh pr diff | |
| # # This avoids CodeQL "checkout of untrusted code in trusted context" warning | |
| # - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | |
| # with: | |
| # fetch-depth: 20 | |
| # | |
| # - name: Apply PR diff to workspace | |
| # id: apply_diff | |
| # env: | |
| # GH_TOKEN: ${{ github.token }} | |
| # PR_NUMBER: ${{ github.event.pull_request.number }} | |
| # REPO: ${{ github.repository }} | |
| # run: | | |
| # set -euo pipefail | |
| # base_sha="$(gh pr view "$PR_NUMBER" --repo "$REPO" --json baseRefOid -q '.baseRefOid')" | |
| # git fetch --depth=1 origin "$base_sha" | |
| # git checkout --detach "$base_sha" | |
| # gh pr diff "$PR_NUMBER" > pr.diff | |
| # if ! git apply --3way --whitespace=nowarn pr.diff; then | |
| # rm -f pr.diff | |
| # echo "apply_ok=false" >> "$GITHUB_OUTPUT" | |
| # exit 0 | |
| # fi | |
| # rm pr.diff | |
| # echo "apply_ok=true" >> "$GITHUB_OUTPUT" | |
| # | |
| # - name: Comment when diff apply fails | |
| # if: steps.apply_diff.outputs.apply_ok == 'false' | |
| # env: | |
| # GH_TOKEN: ${{ github.token }} | |
| # PR_NUMBER: ${{ github.event.pull_request.number }} | |
| # run: | | |
| # gh pr comment "$PR_NUMBER" --repo "${{ github.repository }}" \ | |
| # --body "<!-- claude-apply-fail -->Skipped: PR diff failed to apply. Rebase and re-push." | |
| # | |
| # - uses: anthropics/claude-code-action@70e16deb18402428bd09e08d1ec3662a872e3c72 # v1 | |
| # if: steps.apply_diff.outputs.apply_ok != 'false' | |
| # with: | |
| # anthropic_api_key: ${{ secrets.ORG_ANTHROPIC_API_KEY }} | |
| # additional_permissions: "actions: read" | |
| # track_progress: true | |
| # use_sticky_comment: true | |
| # prompt: | | |
| # Follow CLAUDE.md for project context and conventions. | |
| # For contract details, read the relevant docs in /docs folder. | |
| # | |
| # REPO: ${{ github.repository }} | |
| # PR NUMBER: ${{ github.event.pull_request.number }} | |
| # | |
| # First, identify the PR type from the title (feat|fix|docs|test|refactor|ci|perf|style|chore|release): | |
| # - **feat/fix**: Full review - correctness, security, edge cases, gas, events, test coverage | |
| # - **perf**: Focus on gas optimization correctness and no functional regressions | |
| # - **test**: Check assertions are correct, edge cases covered, no false positives | |
| # - **docs**: Check accuracy against actual code behavior | |
| # - **style/refactor**: No functional changes - verify behavior is preserved | |
| # - **chore/ci/release**: Light review - check for unintended side effects | |
| # | |
| # For Solidity changes, check: | |
| # 1. **Correctness**: Does it work? Edge cases handled? Invariants preserved? | |
| # 2. **Security**: Access control, reentrancy, overflow, unsafe external calls | |
| # 3. **Integration**: How do changes affect other contracts that interact with this one? | |
| # | |
| # For each issue found: | |
| # - Use inline comment on the specific line | |
| # - Explain the problem | |
| # - Provide a suggested fix as a diff block: | |
| # ```diff | |
| # - old code | |
| # + new code | |
| # ``` | |
| # | |
| # Use top-level comment for summary only. | |
| # | |
| # claude_args: | | |
| # --allowedTools "Read,Glob,Grep,mcp__github_inline_comment__create_inline_comment,Bash(git fetch:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr checks:*),Bash(gh run list:*),Bash(gh run view:*)" | |
| # --system-prompt "If you inspect CI logs, never paste raw logs. Summarize likely cause only. Redact tokens, keys, credentials, or URLs with credentials. If unsure, say log may contain sensitive data and stop." | |
| # --max-turns 15 | |
| # Job 2: @claude mentions in any PR comment (members only) | |
| # - issue_comment: PR conversation comments (no fork info available, member-check is sufficient) | |
| # - pull_request_review_comment: inline review comments (fork check added) | |
| # - pull_request_review: review submissions (fork check added) | |
| mention-response: | |
| if: | | |
| ( | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '@claude') && | |
| ( | |
| github.event.comment.author_association == 'MEMBER' || | |
| github.event.comment.author_association == 'COLLABORATOR' || | |
| github.event.comment.author_association == 'OWNER' | |
| ) | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review_comment' && | |
| contains(github.event.comment.body, '@claude') && | |
| ( | |
| github.event.comment.author_association == 'MEMBER' || | |
| github.event.comment.author_association == 'COLLABORATOR' || | |
| github.event.comment.author_association == 'OWNER' | |
| ) | |
| ) || | |
| ( | |
| github.event_name == 'pull_request_review' && | |
| contains(github.event.review.body, '@claude') && | |
| ( | |
| github.event.review.author_association == 'MEMBER' || | |
| github.event.review.author_association == 'COLLABORATOR' || | |
| github.event.review.author_association == 'OWNER' | |
| ) | |
| ) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| id-token: write | |
| actions: read | |
| steps: | |
| # Checkout base (trusted) for mention triggers | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | |
| with: | |
| fetch-depth: 20 | |
| - name: Resolve PR metadata | |
| id: prmeta | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| if [ "$EVENT_NAME" = "issue_comment" ]; then | |
| PR_NUM="$ISSUE_NUMBER" | |
| else | |
| PR_NUM="$PR_NUMBER" | |
| fi | |
| pr_json="$(gh pr view "$PR_NUM" --repo "$REPO" --json isCrossRepository,baseRefOid)" | |
| echo "pr_num=$PR_NUM" >> "$GITHUB_OUTPUT" | |
| echo "is_fork=$(printf '%s' "$pr_json" | jq -r '.isCrossRepository')" >> "$GITHUB_OUTPUT" | |
| echo "base_sha=$(printf '%s' "$pr_json" | jq -r '.baseRefOid')" >> "$GITHUB_OUTPUT" | |
| - name: Apply PR diff to workspace | |
| id: apply_diff | |
| if: steps.prmeta.outputs.is_fork != 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ steps.prmeta.outputs.pr_num }} | |
| BASE_SHA: ${{ steps.prmeta.outputs.base_sha }} | |
| run: | | |
| set -euo pipefail | |
| git fetch --depth=1 origin "$BASE_SHA" | |
| git checkout --detach "$BASE_SHA" | |
| gh pr diff "$PR_NUMBER" > pr.diff | |
| if ! git apply --3way --whitespace=nowarn pr.diff; then | |
| rm -f pr.diff | |
| echo "apply_ok=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| rm pr.diff | |
| echo "apply_ok=true" >> "$GITHUB_OUTPUT" | |
| # If this is a fork PR, leave a friendly note explaining why Claude doesn't run. | |
| # Avoid duplicates by checking for a marker we include in the comment body. | |
| - name: Explain fork PR limitation (issue_comment) | |
| if: github.event_name == 'issue_comment' && steps.prmeta.outputs.is_fork == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ steps.prmeta.outputs.pr_num }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| MARKER="<!-- claude-fork-skip -->" | |
| # Check existing PR (issue) comments for the marker to avoid posting duplicates. | |
| if gh api "repos/$REPO/issues/$PR_NUMBER/comments" --paginate --jq '.[].body' | grep -Fq "$MARKER"; then | |
| echo "Fork explanation already posted; skipping." | |
| exit 0 | |
| fi | |
| gh pr comment "$PR_NUMBER" --repo "$REPO" \ | |
| --body "${MARKER}Skipped: fork PRs are not supported. Push the branch to this repo and re-open." | |
| - name: Comment when diff apply fails | |
| if: steps.apply_diff.outputs.apply_ok == 'false' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ steps.prmeta.outputs.pr_num }} | |
| run: | | |
| gh pr comment "$PR_NUMBER" --repo "${{ github.repository }}" \ | |
| --body "<!-- claude-apply-fail -->Skipped: PR diff failed to apply. Rebase and re-push." | |
| - uses: anthropics/claude-code-action@70e16deb18402428bd09e08d1ec3662a872e3c72 # v1 | |
| # Skip Claude entirely on fork PRs or when diff apply fails. | |
| if: steps.prmeta.outputs.is_fork != 'true' && steps.apply_diff.outputs.apply_ok != 'false' | |
| with: | |
| anthropic_api_key: ${{ secrets.ORG_ANTHROPIC_API_KEY }} | |
| additional_permissions: "actions: read" | |
| track_progress: true | |
| prompt: | | |
| Follow CLAUDE.md for project context and conventions. | |
| For contract details, read the relevant docs in /docs folder. | |
| REPO: ${{ github.repository }} | |
| PR NUMBER: ${{ steps.prmeta.outputs.pr_num }} | |
| For Solidity changes, check: | |
| 1. **Correctness**: Does it work? Edge cases handled? Invariants preserved? | |
| 2. **Security**: Access control, reentrancy, overflow, unsafe external calls | |
| 3. **Integration**: How do changes affect other contracts that interact with this one? | |
| For each issue found: | |
| - Use inline comment on the specific line | |
| - Explain the problem | |
| - Provide a suggested fix as a diff block: | |
| ```diff | |
| - old code | |
| + new code | |
| ``` | |
| Use top-level comment for summary only. | |
| claude_args: | | |
| --allowedTools "Read,Glob,Grep,mcp__github_inline_comment__create_inline_comment,Bash(git fetch:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr checks:*),Bash(gh run list:*),Bash(gh run view:*)" | |
| --system-prompt "If you inspect CI logs, never paste raw logs. Summarize likely cause only. Redact tokens, keys, credentials, or URLs with credentials. If unsure, say log may contain sensitive data and stop." | |
| --max-turns 10 |