@@ -100,13 +100,121 @@ jobs:
100100 echo "Extracted: target=$TARGET, crash_file=$CRASH_FILE"
101101 rm -f issue_body.txt
102102
103+ - name : Validate issue details
104+ id : validate
105+ env :
106+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
107+ run : |
108+ ISSUE_NUM="${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.issue_number || github.event.issue.number }}"
109+
110+ # Check if issue exists and has fuzzer label
111+ ISSUE_LABELS=$(gh issue view "$ISSUE_NUM" --repo ${{ github.repository }} --json labels --jq '.labels[].name')
112+
113+ if ! echo "$ISSUE_LABELS" | grep -q "fuzzer"; then
114+ echo "❌ Issue #$ISSUE_NUM does not have 'fuzzer' label"
115+ exit 1
116+ fi
117+
118+ echo "✅ Issue #$ISSUE_NUM has 'fuzzer' label"
119+
120+ # Check if we have required crash details
121+ if [ -z "${{ steps.extract.outputs.crash_file }}" ]; then
122+ echo "❌ Could not extract crash file name from issue"
123+ exit 1
124+ fi
125+
126+ if [ -z "${{ steps.extract.outputs.artifact_url }}" ]; then
127+ echo "❌ Could not extract artifact URL from issue"
128+ exit 1
129+ fi
130+
131+ echo "✅ Extracted crash details: target=${{ steps.extract.outputs.target }}, crash_file=${{ steps.extract.outputs.crash_file }}"
132+
133+ - name : Download and verify crash artifact
134+ id : download
135+ env :
136+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
137+ run : |
138+ # Extract run ID from artifact URL
139+ ARTIFACT_URL="${{ steps.extract.outputs.artifact_url }}"
140+ RUN_ID=$(echo "$ARTIFACT_URL" | grep -oP 'runs/\K[0-9]+')
141+ ARTIFACT_ID=$(echo "$ARTIFACT_URL" | grep -oP 'artifacts/\K[0-9]+')
142+
143+ echo "Downloading artifact $ARTIFACT_ID from run $RUN_ID"
144+
145+ # Download the artifact
146+ gh run download "$RUN_ID" --name "${{ steps.extract.outputs.target }}-fuzzing-crash-artifacts" --repo ${{ github.repository }}
147+
148+ # Verify crash file exists
149+ CRASH_FILE_PATH="${{ steps.extract.outputs.target }}/${{ steps.extract.outputs.crash_file }}"
150+ if [ ! -f "$CRASH_FILE_PATH" ]; then
151+ echo "❌ Crash file not found: $CRASH_FILE_PATH"
152+ ls -la "${{ steps.extract.outputs.target }}/" || true
153+ exit 1
154+ fi
155+
156+ echo "✅ Downloaded crash file: $CRASH_FILE_PATH"
157+ echo "crash_file_path=$CRASH_FILE_PATH" >> $GITHUB_OUTPUT
158+
159+ - name : Reproduce crash
160+ id : reproduce
161+ continue-on-error : true
162+ run : |
163+ echo "Attempting to reproduce crash with fuzzer..."
164+
165+ # Run fuzzer with crash file (no sanitizer, just reproduce)
166+ timeout 30s cargo +nightly fuzz run --sanitizer=none "${{ steps.extract.outputs.target }}" "${{ steps.download.outputs.crash_file_path }}" -- -runs=1 2>&1 | tee crash_reproduction.log
167+
168+ FUZZ_EXIT_CODE=${PIPESTATUS[0]}
169+
170+ if [ $FUZZ_EXIT_CODE -eq 0 ]; then
171+ echo "⚠️ Fuzzer did not crash - may have been fixed already"
172+ echo "crash_reproduced=false" >> $GITHUB_OUTPUT
173+ else
174+ echo "✅ Crash reproduced (exit code: $FUZZ_EXIT_CODE)"
175+ echo "crash_reproduced=true" >> $GITHUB_OUTPUT
176+ fi
177+
178+ - name : Check if crash still exists
179+ if : steps.reproduce.outputs.crash_reproduced == 'false'
180+ env :
181+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
182+ run : |
183+ ISSUE_NUM="${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.issue_number || github.event.issue.number }}"
184+
185+ gh issue comment "$ISSUE_NUM" --repo ${{ github.repository }} --body "## 🤖 Automated Analysis
186+
187+ I attempted to reproduce this crash but the fuzzer completed successfully without crashing.
188+
189+ **This likely means the issue has already been fixed.**
190+
191+ ### Verification Steps
192+
193+ I ran:
194+ \`\`\`bash
195+ cargo +nightly fuzz run --sanitizer=none ${{ steps.extract.outputs.target }} ${{ steps.download.outputs.crash_file_path }} -- -runs=1
196+ \`\`\`
197+
198+ The fuzzer exited with code 0 (success).
199+
200+ ### Next Steps
201+
202+ - Verify if a recent commit fixed this issue
203+ - If confirmed fixed, close this issue
204+ - If not fixed, the crash may be non-deterministic and requires further investigation"
205+
206+ echo "Crash could not be reproduced - skipping fix attempt"
207+ exit 0
208+
103209 - name : Attempt to fix crash with Claude
210+ if : steps.reproduce.outputs.crash_reproduced == 'true'
104211 env :
105212 ISSUE_NUMBER : ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.issue_number || github.event.issue.number }}
106213 ISSUE_TITLE : ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && steps.fetch_issue.outputs.issue_title || github.event.issue.title }}
107214 ISSUE_BODY : ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && steps.fetch_issue.outputs.issue_body || github.event.issue.body }}
108215 TARGET : ${{ steps.extract.outputs.target }}
109216 CRASH_FILE : ${{ steps.extract.outputs.crash_file }}
217+ CRASH_FILE_PATH : ${{ steps.download.outputs.crash_file_path }}
110218 ARTIFACT_URL : ${{ steps.extract.outputs.artifact_url }}
111219 uses : anthropics/claude-code-action@v1
112220 with :
@@ -134,32 +242,28 @@ jobs:
134242 - **Target**: ${{ env.TARGET }}
135243 - **Crash File**: ${{ env.CRASH_FILE }}
136244
137- ## Step 1: Download the Crash Artifact
245+ ## ✅ Pre-Validated Information
138246
139- The issue body contains an artifact URL. Extract it and download the crash file:
247+ **Good news!** The crash artifact has already been downloaded and the crash has been reproduced.
140248
141- ```bash
142- # The issue body should contain the crash artifact URL
143- # Download it using gh or curl
144- # Example:
145- gh run download RUN_ID --name ${{ env.TARGET }}-fuzzing-crash-artifacts
146- ```
249+ - **Crash file location**: `${{ env.CRASH_FILE_PATH }}`
250+ - **Crash reproduction log**: `crash_reproduction.log`
147251
148- Look for the artifact URL in the issue body. If you can't download it automatically, note this in your comment and provide manual instructions .
252+ The crash has been confirmed to still exist on the current codebase, so you can proceed with analysis and fixing .
149253
150- ## Step 2: Reproduce the Crash
254+ ## Step 1: Analyze the Crash
151255
152- Once you have the crash file, reproduce it :
256+ Read the crash reproduction log to see the actual crash output :
153257
154258 ```bash
155- cargo +nightly fuzz run --sanitizer=none ${{ env.TARGET }} <path-to-crash-file>
259+ cat crash_reproduction.log
156260 ```
157261
158- Capture the output and verify you can reproduce the panic/crash .
262+ This will show you the panic message, stack trace, and any debug output .
159263
160- ## Step 3 : Analyze the Root Cause
264+ ## Step 2 : Analyze the Root Cause
161265
162- 1. Read the **Stack Trace** from the issue body
266+ 1. Read the **Stack Trace** from the crash reproduction log
163267 2. Identify the **Crash Location** (file and line)
164268 3. Read the source code at that location
165269 4. Understand what input caused the crash (check the Debug Output in the issue)
@@ -170,7 +274,7 @@ jobs:
170274 - Integer overflow?
171275 - etc.
172276
173- ## Step 4 : Assess Fixability
277+ ## Step 3 : Assess Fixability
174278
175279 Determine if this is something you can fix:
176280
@@ -188,15 +292,15 @@ jobs:
188292 - Multiple files/modules affected
189293 - Unclear requirements
190294
191- ## Step 5 : If Fixable - Create the Fix
295+ ## Step 4 : If Fixable - Create the Fix
192296
193297 1. **Modify the source code** to fix the issue
194298 2. **Add validation** or bounds checks as needed
195299 3. **Handle the edge case** properly
196300 4. **Follow the project's code style** (see CLAUDE.md)
197301 5. **Keep changes minimal** - only fix the specific issue
198302
199- ## Step 6 : Write Regression Tests
303+ ## Step 5 : Write Regression Tests
200304
201305 Create tests that:
202306 1. **Would fail before your fix** (reproduce the crash)
@@ -221,7 +325,7 @@ jobs:
221325 }
222326 ```
223327
224- ## Step 7 : Verify Your Fix
328+ ## Step 6 : Verify Your Fix
225329
226330 1. Run the new regression test:
227331 ```bash
@@ -230,7 +334,7 @@ jobs:
230334
231335 2. Run the fuzzer with the crash file:
232336 ```bash
233- cargo +nightly fuzz run --sanitizer=none ${{ env.TARGET }} <path-to-crash-file> -- -runs=100
337+ cargo +nightly fuzz run --sanitizer=none ${{ env.TARGET }} ${{ env.CRASH_FILE_PATH }} -- -runs=100
234338 ```
235339
236340 3. Run related tests:
@@ -248,7 +352,7 @@ jobs:
248352 cargo +nightly fmt --all
249353 ```
250354
251- ## Step 8 : Post Your Analysis
355+ ## Step 7 : Post Your Analysis
252356
253357 Comment on issue #${{ env.ISSUE_NUMBER }} with your findings:
254358
0 commit comments