Skip to content

Dev#14

Merged
FutureUnreal merged 6 commits intomainfrom
dev
Feb 7, 2026
Merged

Dev#14
FutureUnreal merged 6 commits intomainfrom
dev

Conversation

@FutureUnreal
Copy link
Member

@FutureUnreal FutureUnreal commented Feb 7, 2026

变更说明

关联 Issue / 需求

自测方式

  • 后端:cd backend && uv run uvicorn app.main:app --reload --port 8090
  • 前端:cd frontend && pnpm --filter @whalewhisper/web dev

风险 & 回滚

Checklist

  • 已保证改动聚焦(不混杂无关重构)
  • 已更新相关文档(如 README / 配置示例)
  • 未提交任何密钥/个人信息
  • CI(PR Checks)通过

📝 PR 说明(Codex 自动生成)

  • 变更概览:本 PR 聚焦于 Claude 相关的 GitHub Actions 工作流安全与稳定性调整:限制自动修复/自动回复仅在“同仓 PR + 明确触发”场景运行,并改进 CI 失败日志获取与 Codex workflow run 的匹配逻辑。CI Auto-Fix 现在会将失败日志拉取到 failed.log,供后续分析/修复使用。
  • 影响范围:ci(.github/workflows/claude-ci-autofix.yml.github/workflows/claude-pr-review.yml.github/workflows/claude-review-responder.yml
  • 如何验证:1) 在同仓 PR 提交一条包含 @claude 的 Review(submitted),确认触发 Claude PR Review Responder;不包含 @claude 的 review 不应触发。2) 让同仓 PR 的 PR ChecksTest Suite 失败,确认触发 Claude CI Auto-Fix,且运行中出现 “Fetch failed logs” 步骤并生成/写入 failed.log。3) 在 Claude PR Review (Fallback)check-codex-status 日志中确认能基于 head_sha + pull_requests 找到对应的 Codex run(不再依赖时间窗口匹配)。
  • 风险点Claude CI Auto-Fix 现在监听的 workflow 名称包含 Test Suite(若仓库中实际名称不一致会导致不触发);自动回复/自动修复增加“同仓 PR”限制,fork PR 将不再触发(安全收紧但可能影响外部贡献流程);Claude PR Review Responder checkout 改用 head.ref,PR 频繁更新时可能拉到最新分支状态而非被 review 的精确提交。

FutureUnreal and others added 5 commits February 8, 2026 00:29
* chore: add comprehensive contributing guide

* Update CONTRIBUTING.md

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update CONTRIBUTING.md

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
- Restore backend and frontend PR checks
- Enable Python syntax check and import test for backend
- Enable pnpm build check for frontend
- Fix 'Expected — Waiting for status to be reported' issue
- Upgrade codex-pr-review.md to 6-perspective review with confidence scoring
- Rewrite claude-pr-review.yml with Codex-first fallback pattern
- Add claude-ci-autofix.yml for auto-fixing CI failures + dev sync
- Add claude-review-responder.yml for auto-responding to PR reviews
- Update CI_CD_SETUP.md with new workflow documentation
- [Critical] auto-fix: restrict to same-repo PRs only (fork protection)
- [High] review-responder: require explicit @claude mention, restrict to same-repo
- [Medium] auto-fix: use `gh run view --log-failed` instead of broken API call
- [Medium] pr-review: fix Codex matching to use head_sha + pull_requests
- [Low] auto-fix: correct workflow name "Tests" → "Test Suite"
@github-actions github-actions bot added area/ci Touches CI/CD (.github) needs-review Needs careful review (large/complex changes) size/XL PR size: >= 1000 lines changed labels Feb 7, 2026
@qodo-code-review
Copy link

Review Summary by Qodo

Enhance CI/CD with Codex-first review, auto-fix, and comprehensive contributing guide

✨ Enhancement 📝 Documentation

Grey Divider

Walkthroughs

Description
• Upgrade PR review system with Codex-first fallback pattern
• Add comprehensive 6-perspective code review framework with confidence scoring
• Implement CI auto-fix workflow for safe mechanical error fixes
• Add PR review responder for automated feedback implementation
• Restore and simplify PR checks workflow for backend/frontend validation
• Create comprehensive bilingual contributing guide (Chinese + English)
Diagram
flowchart LR
  PR["Pull Request"] -->|opened/sync| CheckCodex["Check Codex Status"]
  CheckCodex -->|success| Skip["Skip Claude Review"]
  CheckCodex -->|failure/timeout| Claude["Claude PR Review<br/>6-perspective analysis"]
  Claude -->|inline comments| Review["Review Summary"]
  
  CIFail["CI Failure"] -->|workflow_run| AutoFix["Claude CI Auto-Fix<br/>Safe mechanical fixes"]
  AutoFix -->|creates PR| FixPR["Fix PR to dev"]
  
  Review -->|changes_requested| Responder["Claude Review Responder<br/>Implement feedback"]
  Responder -->|commits| UpdatePR["Update PR Branch"]
  
  PRChecks["PR Checks"] -->|backend/frontend| Validate["Syntax + Import Tests"]
  Validate -->|pass| Merge["Ready to Merge"]
Loading

Grey Divider

File Changes

1. .github/CI_CD_SETUP.md 📝 Documentation +17/-2

Document new CI/CD workflows and Codex fallback pattern

• Updated Claude PR Review description to reflect Codex-first fallback pattern with 10-minute
 timeout
• Added documentation for new Claude CI Auto-Fix workflow (ci-fix and sync-dev modes)
• Added documentation for new Claude PR Review Responder workflow
• Clarified security design and configuration requirements for all workflows

.github/CI_CD_SETUP.md


2. .github/prompts/codex-pr-review.md ✨ Enhancement +372/-38

Implement elite 6-perspective code review framework

• Completely rewrote prompt from simple review to comprehensive 6-perspective framework
• Added detailed execution workflow with 7 phases (data gathering, size calculation, categorization,
 6 perspectives, confidence scoring, validation, false positive filtering)
• Implemented 6 specialized review perspectives: Comment Analyzer, Test Analyzer, Silent Failure
 Hunter, Type Design Auditor, General Code Reviewer, Code Simplifier
• Added confidence scoring system with 80-point threshold and validation/reflection phase
• Defined severity levels and structured output format with inline comments and summary report
• Added comprehensive false positive filter and anti-patterns to avoid

.github/prompts/codex-pr-review.md


3. .github/workflows/claude-ci-autofix.yml ✨ Enhancement +449/-0

Add Claude-powered CI auto-fix and branch sync workflow

• New workflow triggered on PR Checks or Test Suite failures
• Implements sync-dev task for rebasing main → dev with intelligent conflict resolution
• Implements ci-fix task for analyzing CI logs and applying safe mechanical fixes (formatting, lint,
 imports)
• Uses Claude Code action with restricted tools (Read, Write, Edit, Bash)
• Includes security validation for branch parameters and fork protection
• Creates fix PRs or pushes directly based on context

.github/workflows/claude-ci-autofix.yml


View more (4)
4. .github/workflows/claude-pr-review.yml ✨ Enhancement +190/-26

Implement Codex-first fallback pattern for PR review

• Renamed to "Claude PR Review (Fallback)" to reflect new role
• Added check-codex-status job that waits up to 10 minutes for Codex workflow completion
• Implements Codex-first pattern: skip Claude if Codex succeeds, run Claude if Codex fails/times out
• Updated prompt to reference comprehensive 6-perspective review framework from codex-pr-review.md
• Added PR size labeling and structured output format with confidence scoring
• Restricted to internal users (external users always trigger Claude)

.github/workflows/claude-pr-review.yml


5. .github/workflows/claude-review-responder.yml ✨ Enhancement +234/-0

Add Claude-powered PR review responder workflow

• New workflow triggered on PR reviews with changes_requested state or @claude mention
• Analyzes reviewer feedback and classifies into Must Fix / Should Fix / Consider / Question
 categories
• Implements safe changes to address feedback with validation and verification steps
• Creates structured response documenting what was changed and why
• Includes handling for ambiguous feedback and conflicts with PR intent
• Restricted to same-repo PRs only (fork protection)

.github/workflows/claude-review-responder.yml


6. .github/workflows/pr-check.yml ✨ Enhancement +3/-38

Simplify PR checks workflow structure

• Simplified backend job by removing conditional detection logic (always runs)
• Simplified frontend job by removing conditional detection logic and adding working-directory
 default
• Removed redundant if conditions on individual steps
• Kept core checks: Python syntax (compileall), import smoke test, pnpm build
• Streamlined workflow for clarity and reduced complexity

.github/workflows/pr-check.yml


7. CONTRIBUTING.md 📝 Documentation +659/-0

Add comprehensive bilingual contributing guide

• Created comprehensive bilingual contributing guide (Chinese + English sections)
• Chinese section covers: introduction, code of conduct, quick start, contribution workflow, branch
 naming, commit format, code style, testing, PR process, issue reporting
• English section provides complete translation with same structure and content
• Includes setup instructions for backend (uv/venv) and frontend (pnpm)
• Defines branch naming conventions (feature/, fix/, hotfix/, chore/)
• Specifies Conventional Commits format with examples
• Documents code style for Python (PEP 8, async-first, type hints) and TypeScript/Vue (2-space,
 strict mode, Composition API)
• Provides testing checklist and PR submission process
• Includes issue template examples and feature request guidelines

CONTRIBUTING.md


Grey Divider

Qodo Logo

@github-actions github-actions bot added size/S PR size: < 200 lines changed and removed size/XL PR size: >= 1000 lines changed labels Feb 7, 2026
@FutureUnreal FutureUnreal merged commit 7f1958e into main Feb 7, 2026
4 checks passed
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 7, 2026

Greptile Overview

Greptile Summary

This PR significantly enhances the CI/CD infrastructure with intelligent workflow orchestration. The changes introduce three new automated workflows (CI Auto-Fix, Review Responder, and enhanced PR Review with Codex/Claude fallback) while improving existing workflows and adding comprehensive documentation.

Key improvements:

  • Codex PR review prioritization with Claude as fallback reduces redundant AI reviews
  • CI Auto-Fix workflow automates mechanical fixes (formatting, linting) after test failures
  • Review Responder enables AI-assisted implementation of reviewer feedback via @claude mentions
  • Simplified pr-check.yml removes conditional detection logic for cleaner code
  • Enhanced review prompt with 6 specialized perspectives and 80% confidence threshold
  • Comprehensive bilingual CONTRIBUTING.md guide

Issues identified:

  • CI Auto-Fix workflow has logic bugs when triggered via workflow_dispatch - undefined github.event.workflow_run fields cause failures (lines 207, 215, 223-226)
  • Review Responder uses incorrect token reference secrets.GITHUB_TOKEN instead of github.token

These issues affect manual workflow triggers but don't impact the primary workflow_run trigger path. The security design is sound with proper branch validation, read-only checkouts for untrusted code, and safe git operations using --force-with-lease.

Confidence Score: 4/5

  • This PR is safe to merge with minor workflow fixes needed for manual triggers
  • Score of 4 reflects well-designed CI/CD enhancements with strong security practices (read-only checkouts, branch validation, safe git operations), but deducted 1 point for logic bugs in manual workflow dispatch paths that will cause failures. The primary workflow_run triggers work correctly. Issues are isolated to optional manual trigger functionality and easily fixed.
  • .github/workflows/claude-ci-autofix.yml requires fixes for manual dispatch trigger handling (lines 207, 215, 223-226). .github/workflows/claude-review-responder.yml needs token reference correction (line 34).

Important Files Changed

Filename Overview
.github/workflows/claude-ci-autofix.yml New workflow for auto-fixing CI failures and syncing dev branch. Includes security validation for branch parameters and safe git operations with --force-with-lease.
.github/workflows/claude-review-responder.yml New workflow that responds to PR review feedback mentioning @claude. Safely implements requested changes with validation and verification steps.
.github/workflows/claude-pr-review.yml Enhanced PR review workflow with Codex prioritization and Claude fallback. Implements wait logic for Codex completion and comprehensive review perspectives.
.github/prompts/codex-pr-review.md Comprehensive prompt overhaul with 6 review perspectives, confidence scoring (threshold 80), validation phase, and false positive filtering for higher quality reviews.

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant PR as Pull Request
    participant Codex as Codex PR Review
    participant Claude as Claude PR Review
    participant Checks as PR Checks
    participant AutoFix as CI Auto-Fix
    participant Responder as Review Responder

    Dev->>PR: Opens/updates PR
    
    par Parallel Workflows
        PR->>Checks: Trigger PR Checks
        Checks->>Checks: Run backend tests
        Checks->>Checks: Run frontend build
        
        PR->>Codex: Trigger Codex Review
        Codex->>Codex: Analyze code (read-only)
        Codex-->>PR: Post review comments
        
        PR->>Claude: Trigger Claude Review
        Claude->>Claude: Wait for Codex (10min max)
        
        alt Codex Succeeds
            Claude->>Claude: Skip (Codex handled it)
        else Codex Fails/Timeout
            Claude->>Claude: Run comprehensive review
            Claude-->>PR: Post review comments
        end
    end
    
    alt PR Checks Fail
        Checks->>AutoFix: Trigger CI Auto-Fix
        AutoFix->>AutoFix: Fetch failure logs
        AutoFix->>AutoFix: Apply safe fixes (lint/format)
        AutoFix-->>PR: Create fix commit or PR
    end
    
    alt Reviewer comments with @claude
        Dev->>PR: Reviewer posts review
        PR->>Responder: Trigger Review Responder
        Responder->>Responder: Classify feedback priority
        Responder->>Responder: Implement safe changes
        Responder-->>PR: Commit changes + reply
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@@ -205,6 +207,14 @@ jobs:
ref: ${{ github.event.workflow_run.head_branch }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined variable when workflow is manually triggered

When workflow_dispatch triggers the auto-fix job, github.event.workflow_run.head_branch is undefined since there's no workflow_run event. This will cause the checkout to fail.

Consider adding a conditional or using different sources:

Suggested change
ref: ${{ github.event.workflow_run.head_branch }}
ref: ${{ github.event.workflow_run.head_branch || github.ref }}

env:
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
run: |
gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Command will fail during manual workflow_dispatch

github.event.workflow_run.id is undefined when the workflow is triggered via workflow_dispatch, causing the gh run view command to fail with an invalid run ID.

Add a condition or provide a fallback:

Suggested change
gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
gh run view ${{ github.event.workflow_run.id || github.run_id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 7, 2026

Additional Comments (2)

.github/workflows/claude-review-responder.yml
Token fallback order may cause permission issues when GITHUB_TOKEN is undefined

The expression ${{ secrets.GITHUB_TOKEN || secrets.GH_PAT }} will fail if neither token is available. In GitHub Actions, secrets.GITHUB_TOKEN is automatically available as github.token, not as a secret.

          github_token: ${{ secrets.GH_PAT || github.token }}

.github/workflows/claude-ci-autofix.yml
API calls will fail with undefined run_id during manual dispatch

When triggered via workflow_dispatch, github.event.workflow_run.id doesn't exist, causing these API calls to fail. The workflow should either:

  1. Skip the auto-fix job for manual dispatch
  2. Accept run_id as an input parameter
  3. Use different logic paths
            const runId = ${{ github.event.workflow_run.id || 'null' }};
            if (!runId) {
              return { runUrl: '', workflowName: 'Manual', failedJobs: [], hasPR: false, prNumber: null, headBranch: '' };
            }
            const run = await github.rest.actions.getWorkflowRun({

GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
run: |
gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
echo "log_path=failed.log" >> "$GITHUB_OUTPUT"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ERROR-SILENT] Silent failure when fetching CI logs

If gh run view fails, the error message "Failed to fetch logs" is written to the file, but the workflow continues without alerting the user. The Claude agent will then attempt to analyze a file containing only this error message instead of actual logs, leading to ineffective debugging.

Suggestion:

- name: Fetch failed logs
  id: failed_logs
  env:
    GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
  run: |
    if \! gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>&1; then
      echo "::error::Failed to fetch CI logs for run ${{ github.event.workflow_run.id }}"
      echo "ERROR: Could not fetch logs. Please check the CI run manually at: ${{ fromJSON(steps.failure_details.outputs.result).runUrl }}" > failed.log
      exit 1
    fi
    echo "log_path=failed.log" >> "$GITHUB_OUTPUT"

!endsWith(github.event.review.user.login, '[bot]') &&
(github.event.review.state == 'changes_requested' ||
contains(github.event.review.body, '@claude'))
contains(github.event.review.body, '@claude') &&
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOGIC-BUG] Significant behavior change: removed automatic trigger on change requests

The workflow previously triggered on both changes_requested reviews AND @claude mentions. Now it ONLY triggers on @claude mentions. This means reviewers requesting changes will no longer automatically get Claude responses unless they explicitly mention @claude.

Impact: This is a breaking change in user experience. Reviewers may expect automatic responses to change requests.

Suggestion: If this change is intentional, document it in the PR description. Otherwise, restore the original condition:

if: |
  \!endsWith(github.event.review.user.login, '[bot]') &&
  (github.event.review.state == 'changes_requested' ||
   contains(github.event.review.body, '@claude')) &&
  github.event.pull_request.head.repo.full_name == github.repository

with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
ref: ${{ github.event.pull_request.head.ref }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOGIC-BUG] Race condition: checking out branch ref instead of commit SHA

Using head.ref (branch name) instead of head.sha (commit SHA) introduces a race condition. If the PR is updated after the review is submitted but before this workflow runs, Claude will respond to the newer code, not the code that was actually reviewed.

Example scenario:

  1. Reviewer submits review on commit abc123
  2. Author pushes new commit def456 to the PR
  3. This workflow triggers and checks out def456 (latest on branch)
  4. Claude responds to code the reviewer never saw

Suggestion: Revert to using the commit SHA:

ref: ${{ github.event.pull_request.head.sha }}

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

This PR improves GitHub Actions workflow reliability with better PR matching logic and security hardening. However, 3 critical issues were identified that could cause silent failures and race conditions.

PR Size: XS

Issues Found

Category Critical High Medium Low
Error Handling 1 0 0 0
Logic/Correctness 2 0 0 0
Total 3 0 0 0

Critical Issues

  1. claude-ci-autofix.yml:216 - [ERROR-SILENT] Silent failure when fetching CI logs. If log fetching fails, the workflow continues without alerting users, causing Claude to analyze an error message instead of actual logs.

  2. claude-review-responder.yml:26 - [LOGIC-BUG] Race condition introduced by using head.ref instead of head.sha. Claude may respond to code that wasn't reviewed.

  3. claude-review-responder.yml:11 - [LOGIC-BUG] Breaking behavior change: removed automatic trigger on changes_requested reviews. Now only triggers on explicit @claude mentions.

Positive Changes

  • claude-pr-review.yml:55-59 - Excellent improvement replacing time-based PR matching with SHA + PR number matching, eliminating race conditions.
  • claude-ci-autofix.yml:191-193 - Good security hardening with fork and event type checks.
  • claude-ci-autofix.yml:5 - Correct workflow name reference ("Test Suite").

Review Coverage

  • Logic and correctness
  • Security (OWASP Top 10)
  • Error handling
  • Type safety
  • Documentation accuracy
  • Test coverage
  • Code clarity

Automated review by Claude AI

@qodo-code-review
Copy link

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Untrusted branch run with secrets 📘 Rule violation ⛨ Security
Description
• The auto-fix and review-responder workflows checkout the PR head branch and run
  anthropics/claude-code-action with write permissions and powerful tool access (Bash(*), Write,
  Edit).
• This treats untrusted PR content/review content as executable input while exposing secrets
  (ANTHROPIC_API_KEY, potentially GH_PAT) and repo write capabilities, creating a high-risk path
  for injection/exfiltration.
• This violates the requirement to validate/sanitize external inputs and handle data securely,
  especially when automation can execute commands and push changes.
Code

.github/workflows/claude-ci-autofix.yml[R188-256]

+  auto-fix:
+    if: |
+      (github.event_name == 'workflow_run' &&
+       github.event.workflow_run.conclusion == 'failure' &&
+       github.event.workflow_run.event == 'pull_request' &&
+       github.event.workflow_run.head_repository.full_name == github.repository &&
+       !startsWith(github.event.workflow_run.head_branch, 'claude-fix-')) ||
+      (github.event_name == 'workflow_dispatch' && github.event.inputs.task_type == 'ci-fix')
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
+      actions: read
+      issues: write
+
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v5
+        with:
+          ref: ${{ github.event.workflow_run.head_branch }}
+          fetch-depth: 0
+
+      - name: Fetch failed logs
+        id: failed_logs
+        env:
+          GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
+        run: |
+          gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
+          echo "log_path=failed.log" >> "$GITHUB_OUTPUT"
+
+      - name: Get CI failure details
+        id: failure_details
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const run = await github.rest.actions.getWorkflowRun({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              run_id: ${{ github.event.workflow_run.id }}
+            });
+
+            const jobs = await github.rest.actions.listJobsForWorkflowRun({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              run_id: ${{ github.event.workflow_run.id }}
+            });
+
+            const failedJobs = jobs.data.jobs.filter(job => job.conclusion === 'failure');
+
+            const pullRequests = ${{ toJSON(github.event.workflow_run.pull_requests) }};
+            const hasPR = pullRequests && pullRequests.length > 0;
+
+            return {
+              runUrl: run.data.html_url,
+              workflowName: run.data.name,
+              failedJobs: failedJobs.map(j => j.name),
+              hasPR: hasPR,
+              prNumber: hasPR ? pullRequests[0].number : null,
+              headBranch: '${{ github.event.workflow_run.head_branch }}'
+            };
+
+      - name: Run Claude Code for Auto-Fix
+        uses: anthropics/claude-code-action@v1
+        env:
+          ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }}
+        with:
+          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
+          github_token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
+
Evidence
PR Compliance ID 6 requires validating/sanitizing external inputs and preventing injection-style
risks. The new workflows explicitly checkout PR head refs and invoke an agent capable of arbitrary
Bash with repository write permissions and secrets available, which is unsafe for untrusted
PR-derived content.

Rule 6: Generic: Security-First Input Validation and Data Handling
.github/workflows/claude-ci-autofix.yml[188-208]
.github/workflows/claude-ci-autofix.yml[249-256]
.github/workflows/claude-review-responder.yml[22-35]
.github/workflows/claude-review-responder.yml[233-233]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workflows execute agent-driven Bash/editing on PR head branches while providing secrets and write permissions, which is unsafe for untrusted PR-derived inputs.

## Issue Context
This can enable command execution or data exfiltration through the agent (or through scripts it runs) using `ANTHROPIC_API_KEY` and potentially `GH_PAT`/write-scoped `GITHUB_TOKEN`.

## Fix Focus Areas
- .github/workflows/claude-ci-autofix.yml[188-208]
- .github/workflows/claude-ci-autofix.yml[249-256]
- .github/workflows/claude-review-responder.yml[22-35]
- .github/workflows/claude-review-responder.yml[233-233]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. CI log fetch errors swallowed 📘 Rule violation ⛯ Reliability
Description
• The Fetch failed logs step suppresses stderr and replaces the real failure reason with a generic
  string, which can hide the underlying error and prevent actionable debugging.
• This creates a silent/low-context failure mode that can cause the downstream auto-fix agent to
  operate on incomplete or misleading data.
• This violates the requirement for robust error handling with meaningful context about what failed
  and why.
Code

.github/workflows/claude-ci-autofix.yml[R210-216]

+      - name: Fetch failed logs
+        id: failed_logs
+        env:
+          GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
+        run: |
+          gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
+          echo "log_path=failed.log" >> "$GITHUB_OUTPUT"
Evidence
PR Compliance ID 3 requires handling failure points with actionable context. The new workflow
explicitly discards stderr and overwrites the log with a generic message, losing the reason for the
failure and making it impossible to reconstruct what happened.

Rule 3: Generic: Robust Error Handling and Edge Case Management
.github/workflows/claude-ci-autofix.yml[210-216]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workflow suppresses `gh run view` errors and replaces the real error output with a generic placeholder, creating a silent failure mode.

## Issue Context
Downstream steps rely on `failed.log` for diagnosis; if it&#x27;s wrong/empty, automated fixes may be misapplied.

## Fix Focus Areas
- .github/workflows/claude-ci-autofix.yml[210-216]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Dispatch ci-fix is broken 🐞 Bug ⛯ Reliability
Description
claude-ci-autofix.yml allows workflow_dispatch with task_type=ci-fix, but the job’s steps
  unconditionally read github.event.workflow_run.* (branch, run id, PR list).
• On a manual dispatch event those fields don’t exist, so checkout/log fetching/API calls will fail
  and the workflow can’t be used as documented.
• Impact: maintainers trying to run CI auto-fix manually will hit runtime failures rather than
  getting a fix PR.
Code

.github/workflows/claude-ci-autofix.yml[R188-233]

+  auto-fix:
+    if: |
+      (github.event_name == 'workflow_run' &&
+       github.event.workflow_run.conclusion == 'failure' &&
+       github.event.workflow_run.event == 'pull_request' &&
+       github.event.workflow_run.head_repository.full_name == github.repository &&
+       !startsWith(github.event.workflow_run.head_branch, 'claude-fix-')) ||
+      (github.event_name == 'workflow_dispatch' && github.event.inputs.task_type == 'ci-fix')
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
+      actions: read
+      issues: write
+
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v5
+        with:
+          ref: ${{ github.event.workflow_run.head_branch }}
+          fetch-depth: 0
+
+      - name: Fetch failed logs
+        id: failed_logs
+        env:
+          GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
+        run: |
+          gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
+          echo "log_path=failed.log" >> "$GITHUB_OUTPUT"
+
+      - name: Get CI failure details
+        id: failure_details
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const run = await github.rest.actions.getWorkflowRun({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              run_id: ${{ github.event.workflow_run.id }}
+            });
+
+            const jobs = await github.rest.actions.listJobsForWorkflowRun({
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              run_id: ${{ github.event.workflow_run.id }}
+            });
Evidence
The auto-fix job is enabled for both workflow_run and workflow_dispatch, but its steps always
reference workflow_run payload fields (head_branch/id) and build prompt context off those results.

.github/workflows/claude-ci-autofix.yml[188-209]
.github/workflows/claude-ci-autofix.yml[210-233]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`auto-fix` supports `workflow_dispatch` in its job `if`, but steps hard-code `github.event.workflow_run.*`, causing failures on manual runs.

### Issue Context
For `workflow_dispatch`, `github.event.workflow_run` is absent. The job must either (a) not run on `workflow_dispatch` or (b) accept inputs and branch its logic.

### Fix Focus Areas
- .github/workflows/claude-ci-autofix.yml[8-32]
- .github/workflows/claude-ci-autofix.yml[188-247]
- .github/workflows/claude-ci-autofix.yml[257-272]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Responder prompt injection 🐞 Bug ⛨ Security
Description
claude-review-responder.yml embeds the raw PR review body into the LLM prompt and triggers when
  that body contains @claude.
• The job also checks out the PR head branch and grants contents: write + Bash(*) +
  Write/Edit, enabling an injected instruction to run commands and push commits.
• Impact: a malicious/compromised reviewer (or any reviewer who can submit a review) could coerce
  the agent into destructive actions or secret exfiltration.
Code

.github/workflows/claude-review-responder.yml[R17-35]

+    permissions:
+      contents: write
+      pull-requests: write
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v5
+        with:
+          fetch-depth: 0
+          ref: ${{ github.event.pull_request.head.ref }}
+
+      - name: Run Claude Code for Review Response
+        uses: anthropics/claude-code-action@v1
+        env:
+          ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }}
+        with:
+          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
+          github_token: ${{ secrets.GITHUB_TOKEN || secrets.GH_PAT }}
+
Evidence
The workflow is explicitly driven by reviewer-controlled text, injects that text verbatim into the
prompt, and provides powerful tools and write permissions on a checked-out PR branch. This is the
classic prompt-injection pattern, but with direct write/push capability. For contrast, existing
Claude automation for issues keeps contents: read when using Claude tooling.

.github/workflows/claude-review-responder.yml[9-13]
.github/workflows/claude-review-responder.yml[17-27]
.github/workflows/claude-review-responder.yml[45-50]
.github/workflows/claude-review-responder.yml[140-152]
.github/workflows/claude-review-responder.yml[233-234]
.github/workflows/claude-issue-auto-response.yml[88-91]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The review responder is triggered by reviewer-controlled text and injects `${{ github.event.review.body }}` into an LLM prompt while granting repo write + `Bash(*)`.

### Issue Context
This is a prompt-injection risk with direct repo modification capability.

### Fix Focus Areas
- .github/workflows/claude-review-responder.yml[9-20]
- .github/workflows/claude-review-responder.yml[22-35]
- .github/workflows/claude-review-responder.yml[45-50]
- .github/workflows/claude-review-responder.yml[233-234]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Sync-dev force-push risk 🐞 Bug ⛯ Reliability
Description
sync-dev directs an LLM to git rebase and then git push --force-with-lease to the dev
  branch.
• Even with --force-with-lease (safer than --force), this is still a history rewrite that can be
  disruptive if it lands unexpectedly.
• The verification instructions also ignore install failures (|| true), which may reduce
  confidence in the “verify before push” guarantee.
Code

.github/workflows/claude-ci-autofix.yml[R146-171]

+            ```bash
+            # Backend verification
+            if [ -d backend ]; then
+              cd backend
+              pip install -e . 2>/dev/null || true
+              python -m compileall -q app
+              python -c "from app.main import app; print('backend import: ok')"
+              cd ..
+            fi
+
+            # Frontend verification
+            if [ -d frontend ]; then
+              cd frontend
+              pnpm install --frozen-lockfile 2>/dev/null || true
+              pnpm --filter @whalewhisper/web build
+              cd ..
+            fi
+
+            git log --oneline -10
+            ```
+
+            ### Phase 5: Push
+
+            ```bash
+            git push origin ${{ github.event.inputs.target_branch }} --force-with-lease
+            ```
Evidence
The prompt explicitly includes a rebase workflow followed by a force-with-lease push, and the
verification step uses || true around dependency installation, potentially masking verification
problems.

.github/workflows/claude-ci-autofix.yml[150-161]
.github/workflows/claude-ci-autofix.yml[169-171]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The sync flow uses `rebase` + `--force-with-lease` push to `dev`, and the verification sequence ignores install failures.

### Issue Context
This is an operational risk rather than a deterministic bug, but it can lead to disruptive branch rewrites or weaker verification.

### Fix Focus Areas
- .github/workflows/claude-ci-autofix.yml[144-171]
- .github/workflows/claude-ci-autofix.yml[34-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +210 to +216
- name: Fetch failed logs
id: failed_logs
env:
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
run: |
gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log
echo "log_path=failed.log" >> "$GITHUB_OUTPUT"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Ci log fetch errors swallowed 📘 Rule violation ⛯ Reliability

• The Fetch failed logs step suppresses stderr and replaces the real failure reason with a generic
  string, which can hide the underlying error and prevent actionable debugging.
• This creates a silent/low-context failure mode that can cause the downstream auto-fix agent to
  operate on incomplete or misleading data.
• This violates the requirement for robust error handling with meaningful context about what failed
  and why.
Agent Prompt
## Issue description
The workflow suppresses `gh run view` errors and replaces the real error output with a generic placeholder, creating a silent failure mode.

## Issue Context
Downstream steps rely on `failed.log` for diagnosis; if it's wrong/empty, automated fixes may be misapplied.

## Fix Focus Areas
- .github/workflows/claude-ci-autofix.yml[210-216]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

Blocker

  • gh can’t reach api.github.com in this runner (error connecting to api.github.com), so I couldn’t apply labels or post PR comments/review. Best-effort review is based on local git diff a1df5af..origin/dev (d3d5bea).

PR Size

  • Size: S (53 lines changed; 3 files). Intended label: size/S.

Issue (diff-only)

  • .github/workflows/claude-ci-autofix.yml:215 [High] [ERROR-SILENT] — the new log-fetch step suppresses gh run view failures (2>/dev/null + fallback writing only to failed.log), so permission/rate-limit/repo errors become invisible in the Actions log and the auto-fix may proceed with non-actionable context.
REPO="datawhalechina/whale-whisper"
PR="14"
SHA="d3d5bea16d98079f9a2bf7d1dc0cf9518144da24"

# Size label (will fail here due to no GitHub API connectivity)
gh pr edit "$PR" --repo "$REPO" --add-label "size/S"

# Inline comment for the issue
comment_body="$(cat <<'EOF'
**[High]** [ERROR-SILENT] `gh run view` failures are suppressed in the log-fetch step

**Evidence** (`.github/workflows/claude-ci-autofix.yml:215`):
`gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>/dev/null || echo "Failed to fetch logs" > failed.log`

**Why this is a problem**: Redirecting stderr to `/dev/null` and overwriting `failed.log` with a generic message makes auth/permissions/rate-limit errors invisible in the Actions log, while the Claude auto-fix step still runs expecting real failure context.

**Suggested fix**:
```yaml
      - name: Fetch failed logs
        id: failed_logs
        env:
          GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
        run: |
          if ! gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>&1; then
            echo "::warning::Failed to fetch failed-job logs for run_id=${{ github.event.workflow_run.id }}; see failed.log for details."
          fi
          echo "log_path=failed.log" >> "$GITHUB_OUTPUT"

EOF
)"

gh api "repos/$REPO/pulls/$PR/comments"
-f body="$comment_body"
-f commit_id="$SHA"
-f path=".github/workflows/claude-ci-autofix.yml"
-f line=215
-f side="RIGHT"

Summary review

summary_body="$(cat <<'EOF'

Codex PR Review

Workflow-only PR updating Claude automation triggers and CI-log ingestion. Main risk is suppressed failures when fetching CI logs, which can cause auto-fix to proceed without actionable failure context.

PR Size: S

  • Lines changed: 53
  • Files changed: 3

Issues Found

Category Critical High Medium Low
Logic/Bugs 0 0 0 0
Security 0 0 0 0
Error Handling 0 1 0 0
Types 0 0 0 0
Comments/Docs 0 0 0 0
Tests 0 0 0 0
Simplification 0 0 0 0

Critical Issues (Must Fix)

  • None

High Priority Issues (Should Fix)

  • .github/workflows/claude-ci-autofix.yml:215 [ERROR-SILENT] gh run view ... failures are suppressed; emit a warning and preserve stderr in failed.log. (Confidence: 90)

Review Coverage

  • Logic and correctness
  • Security (OWASP Top 10)
  • Error handling
  • Type safety
  • Documentation accuracy
  • Test coverage
  • Code clarity

Automated review by Codex AI
EOF
)"

gh pr review "$PR" --repo "$REPO" --comment --body "$summary_body"

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

This PR improves security and reliability of Claude-powered GitHub Actions workflows by restricting triggers to same-repository PRs and improving workflow run matching logic. However, there are several issues that need attention.

PR Size: XS (53 lines changed, 3 files)

Issues Found

Category Critical High Medium Low
Security 1 0 0 0
Logic 0 1 0 0
Error Handling 0 1 0 0
Total 1 2 0 0

Critical Issues

1. [SECURITY-VULNERABILITY] Race condition with mutable ref checkout

File: .github/workflows/claude-review-responder.yml:26

Changed from head.sha (immutable) to head.ref (mutable branch name). If the PR is updated while this workflow runs, it will checkout the latest commit instead of the one being reviewed.

Impact: Claude may respond to different code than what the reviewer actually saw, causing confusion and potentially incorrect fixes.

Suggestion:

- name: Checkout repository
  uses: actions/checkout@v5
  with:
    fetch-depth: 0
    ref: ${{ github.event.pull_request.head.sha }}

High Priority Issues

2. [LOGIC-BUG] Removed automatic response to changes_requested reviews

File: .github/workflows/claude-review-responder.yml:11-12

The old condition triggered on changes_requested OR @claude. The new condition only triggers when @claude is mentioned. This means reviewers who request changes without explicitly mentioning @claude will no longer get automated responses.

Impact: Breaking behavior change that may frustrate reviewers expecting automated responses.

Suggestion:
If this change is intentional (to reduce noise), document it in the PR description. Otherwise, restore the original behavior:

if: |
  \!endsWith(github.event.review.user.login, '[bot]') &&
  (github.event.review.state == 'changes_requested' ||
   contains(github.event.review.body, '@claude')) &&
  github.event.pull_request.head.repo.full_name == github.repository

3. [ERROR-SILENT] Missing error handling for log fetch failure

File: .github/workflows/claude-ci-autofix.yml:215

The new log fetch step uses || echo "Failed to fetch logs" > failed.log which silently fails. The prompt then instructs Claude to read failed.log, which may only contain the error message instead of actual CI logs.

Impact: Claude will attempt to fix CI failures without seeing the actual error logs, likely resulting in ineffective fixes.

Suggestion:

- name: Fetch failed logs
  id: failed_logs
  env:
    GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
  run: |
    if \! gh run view ${{ github.event.workflow_run.id }} --log-failed > failed.log 2>&1; then
      echo "::warning::Failed to fetch CI logs, Claude will have limited context"
      echo "ERROR: Could not fetch logs from run ${{ github.event.workflow_run.id }}" > failed.log
      echo "Please check the run manually at: ${{ github.event.workflow_run.html_url }}" >> failed.log
    fi
    echo "log_path=failed.log" >> "$GITHUB_OUTPUT"

Positive Changes

  • ✅ Added same-repository check to prevent fork PR exploitation
  • ✅ Improved workflow run matching from time-based to SHA + PR number based (more reliable)
  • ✅ Changed token priority to prefer GH_PAT for better permissions
  • ✅ Simplified log handling by using file-based approach instead of JSON embedding

Review Coverage

  • Logic and correctness
  • Security (OWASP Top 10)
  • Error handling
  • Type safety (N/A for YAML)
  • Documentation accuracy
  • Test coverage (N/A for workflow files)
  • Code clarity

Automated review by Claude AI

@github-actions github-actions bot added the size/XS PR size: < 50 lines changed label Feb 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci Touches CI/CD (.github) needs-review Needs careful review (large/complex changes) size/S PR size: < 200 lines changed size/XS PR size: < 50 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant