diff --git a/.github/workflows/reproduce-and-fix-issues-claude.yml b/.github/workflows/reproduce-and-fix-issues-claude.yml new file mode 100644 index 000000000..1f5774fb7 --- /dev/null +++ b/.github/workflows/reproduce-and-fix-issues-claude.yml @@ -0,0 +1,122 @@ +name: Claude Auto Issue Fix + +on: + issues: + types: [opened] + +jobs: + claude_auto_issue_fix: + runs-on: ubuntu-latest + + # Prevent multiple runs for the same issue + concurrency: + group: claude-auto-issue-${{ github.repository }}-${{ github.event.issue.number }} + cancel-in-progress: false + + permissions: + contents: write + pull-requests: write + issues: write + id-token: write + + steps: + - name: Checkout code + uses: actions/checkout@v6.0.1 + with: + fetch-depth: 0 + + - name: Run Claude Code (auto issue handler) + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + prompt: | + You are an autonomous coding agent running in CI for this repository. + This workflow runs automatically whenever a new GitHub issue is opened. + + === Context === + REPO: ${{ github.repository }} + ISSUE NUMBER: ${{ github.event.issue.number }} + ISSUE TITLE: ${{ github.event.issue.title }} + ISSUE URL: ${{ github.event.issue.html_url }} + + ISSUE BODY: + ${{ github.event.issue.body }} + + === Goal === + Apply a strict “repro test → fix” methodology. Produce exactly ONE of these outcomes: + 1) Repro PR + Fix PR (preferred for actionable bugs) + 2) Repro PR only (if reproducible but cannot fix) + 3) Comment-only “Needs info / Not actionable / Question answer draft” + No other outcomes. + + === Hard rules (non-negotiable) === + - Never claim reproduction unless a test fails due to a concrete behavioral assertion. + - Never use “does not throw / does not crash” as the primary assertion unless: + (a) the issue explicitly says throwing is the bug, AND + (b) the correct behavior is explicitly “should not throw”. + - Never “fix” by skipping, swallowing, or ignoring the problematic case + (e.g. guard clauses / try-catch that hides the error) unless the issue explicitly says that is correct. + Any conditional handling must still implement the intended behavior. + - Do not weaken tests to make them pass. Do not remove assertions. Do not skip tests. Do not mark flaky. + - Keep changes minimal and scoped. No refactors. No drive-by formatting. + - If expected behavior is unclear or not testable, STOP and request the minimum missing info. + + === Step 0: Determine actionability === + From the issue, extract: + - Expected behavior (must be explicit & testable) + - Actual behavior + - Repro steps / minimal example + If you cannot extract a testable expected behavior: + - Post a GitHub comment requesting the minimum missing details (inputs, expected outputs, versions, etc.) + - Stop (no PRs) + + === Step 1: Reproduction test (behavioral oracle) === + Create a minimal unit/integration test that asserts the expected behavior: + - Test name must describe intended behavior (NOT “reproduces issue #…”) + - Assert concrete outcomes: returned values, state transitions, emitted events, persisted data, etc. + - Add at least one “anti-noop” assertion that would fail if the code simply “does nothing” + (e.g. verify a state change, returned value, side effect). + - If the issue involves an error, prefer asserting correct error type/message or correct recovery/result. + + === Step 2: Prove it reproduces on base === + Run tests on base: + - Confirm the new test FAILS due to assertion mismatch (not due to broken test setup). + If the test passes on base: + - Do NOT fake a repro by weakening assertions. + - If the issue seems intermittent, attempt to make repro deterministic; otherwise comment “not reproducible” and stop. + + Commit repro and open PR: + - Branch: ai/issue-${{ github.event.issue.number }}-repro + - Commit message: test: assert (issue #${{ github.event.issue.number }}) + - PR title: [repro] (issue #${{ github.event.issue.number }}) + - PR body: link issue + what test asserts + how to run + observed failure + + === Step 3: Fix (stacked on repro) === + Create fix branch from repro branch: + - Branch: ai/issue-${{ github.event.issue.number }}-fix + Implement the minimal fix. + Validation: + - Previously failing test MUST now pass. + - Fix must not be a no-op. + - If you add guards/conditionals, justify why it's correct behavior (not hiding bug), + and ensure intended work still occurs. + + Commit fix and open stacked PR: + - Commit message: fix: (issue #${{ github.event.issue.number }}) + - PR title: [fix] (issue #${{ github.event.issue.number }}) + - PR body: link issue + link repro PR + root cause + fix explanation + how to test + + === If stuck === + If you cannot fix without derailing: + - Still open the repro PR if it's valid (high value). + - Post a comment summarizing findings and blockers. + - Do NOT force a “fix” that silences symptoms. + + === Quality checklist (must satisfy before marking fixed) === + - [ ] Expected behavior asserted (not “no throw” unless truly correct) + - [ ] Test fails on base for the right reason + - [ ] Fix makes test pass without weakening assertions + - [ ] Fix is not “skip/swallow/ignore” + - [ ] Changes minimal and scoped + + Proceed now.