Skip to content

Commit 2336943

Browse files
committed
wip
Signed-off-by: Joe Isaacs <[email protected]>
1 parent 9902f37 commit 2336943

File tree

1 file changed

+154
-60
lines changed

1 file changed

+154
-60
lines changed

.github/workflows/fuzz.yml

Lines changed: 154 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -155,44 +155,113 @@ jobs:
155155
echo "=== Fuzzer log preview (last 100 lines, where crashes are reported) ==="
156156
tail -100 logs/fuzz_output.log || echo "No log file"
157157
158-
- name: Setup Python
159-
uses: actions/setup-python@v5
158+
# Use Claude Code Action to analyze crash and decide if duplicate
159+
- name: Analyze crash with Claude
160+
uses: anthropics/claude-code-action@v1
160161
with:
161-
python-version: '3.11'
162-
163-
- name: Install dependencies
164-
run: pip install anthropic
165-
166-
# - name: Check for duplicate issue
167-
# id: dedup
168-
# env:
169-
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
170-
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
171-
# run: |
172-
# python scripts/check_fuzzer_duplicate.py \
173-
# "${{ needs.io_fuzz.outputs.first_crash_name }}" \
174-
# "logs/fuzz_output.log" \
175-
# "${{ github.repository }}" > dedup_result.json
176-
#
177-
# # Check exit code (0 = not duplicate, 1 = duplicate)
178-
# if [ $? -eq 0 ]; then
179-
# echo "is_duplicate=false" >> $GITHUB_OUTPUT
180-
# echo "Not a duplicate, will create new issue"
181-
# else
182-
# echo "is_duplicate=true" >> $GITHUB_OUTPUT
183-
# ISSUE_NUM=$(jq -r '.issue_number' dedup_result.json)
184-
# echo "issue_number=$ISSUE_NUM" >> $GITHUB_OUTPUT
185-
# echo "Duplicate of issue #$ISSUE_NUM"
186-
# fi
187-
#
188-
# # Show result
189-
# cat dedup_result.json
190-
191-
- name: Create GitHub issue
192-
if: 0 && steps.dedup.outputs.is_duplicate == 'false'
162+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
163+
prompt: |
164+
# Fuzzer Crash Analysis Task
165+
166+
A fuzzing run for the `file_io` target has detected a crash. Your task is to analyze it and determine if it's a duplicate of an existing issue.
167+
168+
## Step 1: Analyze the Crash
169+
170+
1. Read the fuzzer log: `logs/fuzz_output.log`
171+
2. Extract the stack trace (lines starting with `#0`, `#1`, etc.)
172+
3. Extract the error message (look for "panicked at" or "ERROR:")
173+
4. Identify the crash location (top frame in the stack trace from user code, not std/core)
174+
5. Read the source code at the crash location to understand what failed
175+
176+
## Step 2: Check for Duplicates
177+
178+
1. List existing fuzzer issues:
179+
```bash
180+
gh issue list --repo ${{ github.repository }} --label fuzzer --state open --json number,title,body --limit 50
181+
```
182+
183+
2. For each existing issue:
184+
- Compare stack traces: Do they crash at the same location (same file + function)?
185+
- Compare error messages: Are they the same error pattern?
186+
- IMPORTANT: Normalize values when comparing!
187+
- "index 5 out of bounds" and "index 12 out of bounds" are THE SAME bug
188+
- "len is 100" and "len is 5" are THE SAME bug
189+
- If needed, read source code at the crash location to understand if it's the same assertion/panic
190+
191+
3. Make a decision:
192+
- **DUPLICATE** if: Same crash location + same error pattern (values can differ)
193+
- **NEW BUG** if: Different location OR different error type
194+
195+
## Step 3: Output Decision
196+
197+
Create a file `decision.json` with this exact format:
198+
199+
```json
200+
{
201+
"is_duplicate": true or false,
202+
"duplicate_of": issue_number (if duplicate) or null,
203+
"confidence": "high" | "medium" | "low",
204+
"reasoning": "Explain your decision in 2-3 sentences",
205+
"crash_location": "file.rs:function_name",
206+
"error_message": "the extracted error message",
207+
"stack_trace_preview": "top 5 frames",
208+
"suggested_title": "Brief title for new issue (if not duplicate)"
209+
}
210+
```
211+
212+
## Important Notes
213+
214+
- You have full access to the repository - read any source files you need
215+
- Be conservative: when unsure, mark as NEW BUG (false negatives are better than false positives)
216+
- The goal is to prevent duplicate issues while being careful not to merge distinct bugs
217+
- Focus on the ROOT CAUSE, not the specific values in error messages
218+
219+
## Context
220+
221+
- Target: file_io
222+
- Crash file: ${{ needs.io_fuzz.outputs.first_crash_name }}
223+
- Total crashes: ${{ needs.io_fuzz.outputs.crash_count }}
224+
- Workflow: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
225+
226+
Start by reading the fuzzer log.
227+
claude_args: |
228+
--model claude-sonnet-4-5-20250929
229+
--max-turns 20
230+
231+
- name: Read Claude's decision
232+
id: decision
233+
run: |
234+
if [ ! -f decision.json ]; then
235+
echo "Error: decision.json not found"
236+
exit 1
237+
fi
238+
239+
cat decision.json
240+
241+
IS_DUP=$(jq -r '.is_duplicate' decision.json)
242+
DUPLICATE_OF=$(jq -r '.duplicate_of // empty' decision.json)
243+
244+
echo "is_duplicate=$IS_DUP" >> $GITHUB_OUTPUT
245+
echo "duplicate_of=$DUPLICATE_OF" >> $GITHUB_OUTPUT
246+
247+
if [ "$IS_DUP" = "true" ]; then
248+
echo "✓ Claude identified this as a duplicate of issue #$DUPLICATE_OF"
249+
else
250+
echo "✓ Claude identified this as a NEW bug"
251+
fi
252+
253+
- name: Create GitHub issue for new bug
254+
if: steps.decision.outputs.is_duplicate == 'false'
193255
env:
194256
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
195257
run: |
258+
# Extract data from Claude's analysis
259+
TITLE=$(jq -r '.suggested_title' decision.json)
260+
CRASH_LOCATION=$(jq -r '.crash_location' decision.json)
261+
ERROR_MESSAGE=$(jq -r '.error_message' decision.json)
262+
STACK_TRACE=$(jq -r '.stack_trace_preview' decision.json)
263+
REASONING=$(jq -r '.reasoning' decision.json)
264+
196265
# Extract crash type from filename
197266
CRASH_FILE="${{ needs.io_fuzz.outputs.first_crash_name }}"
198267
if [[ "$CRASH_FILE" == crash-* ]]; then
@@ -207,21 +276,37 @@ jobs:
207276
CRASH_TYPE="Unknown"
208277
fi
209278
210-
# Create issue with gh CLI
279+
# Create issue with gh CLI, using Claude's analysis
211280
gh issue create \
212281
--repo ${{ github.repository }} \
213-
--title "Fuzzing $CRASH_TYPE: file_io - $(date -u +%Y-%m-%d)" \
282+
--title "Fuzzing $CRASH_TYPE: $TITLE" \
214283
--label "bug,fuzzer" \
215-
--body-file - <<'EOF'
284+
--body "$(cat <<EOF_BODY
216285
## Fuzzing Crash Report
217286
218-
The `file_io` fuzzing target detected a $CRASH_TYPE during a scheduled fuzzing run.
287+
The \`file_io\` fuzzing target detected a $CRASH_TYPE during a scheduled fuzzing run.
288+
289+
### Claude's Analysis
290+
291+
**Crash Location**: \`$CRASH_LOCATION\`
292+
293+
**Error Message**:
294+
\`\`\`
295+
$ERROR_MESSAGE
296+
\`\`\`
297+
298+
**Stack Trace Preview**:
299+
\`\`\`
300+
$STACK_TRACE
301+
\`\`\`
302+
303+
**Analysis**: $REASONING
219304
220305
### Summary
221306
222307
- **Crash Type**: $CRASH_TYPE
223-
- **Target**: `file_io`
224-
- **Crash File**: `${{ needs.io_fuzz.outputs.first_crash_name }}`
308+
- **Target**: \`file_io\`
309+
- **Crash File**: \`${{ needs.io_fuzz.outputs.first_crash_name }}\`
225310
- **Total Crashes Found**: ${{ needs.io_fuzz.outputs.crash_count }}
226311
- **Workflow Run**: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
227312
- **Timestamp**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
@@ -234,38 +319,37 @@ jobs:
234319
**https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}**
235320
236321
Artifacts available:
237-
- `io-fuzzing-crash-artifacts` - All crash files found (includes ${{ needs.io_fuzz.outputs.crash_count }} crashes)
238-
- `io-fuzzing-logs` - Complete fuzzer output with stack traces
322+
- \`io-fuzzing-crash-artifacts\` - All crash files found (includes ${{ needs.io_fuzz.outputs.crash_count }} crashes)
323+
- \`io-fuzzing-logs\` - Complete fuzzer output with stack traces
239324
240325
### Reproduction Steps
241326
242-
1. Download the `io-fuzzing-crash-artifacts` from the workflow run above
243-
2. Extract the crash file to your local `fuzz/artifacts/file_io/` directory
327+
1. Download the \`io-fuzzing-crash-artifacts\` from the workflow run above
328+
2. Extract the crash file to your local \`fuzz/artifacts/file_io/\` directory
244329
3. Reproduce the crash locally:
245330
246-
```bash
331+
\`\`\`bash
247332
cargo +nightly fuzz run file_io fuzz/artifacts/file_io/${{ needs.io_fuzz.outputs.first_crash_name }}
248-
```
333+
\`\`\`
249334
250335
4. Get full backtrace:
251336
252-
```bash
337+
\`\`\`bash
253338
RUST_BACKTRACE=full cargo +nightly fuzz run file_io fuzz/artifacts/file_io/${{ needs.io_fuzz.outputs.first_crash_name }}
254-
```
339+
\`\`\`
255340
256341
5. Minimize the test case (optional):
257342
258-
```bash
343+
\`\`\`bash
259344
cargo +nightly fuzz tmin file_io fuzz/artifacts/file_io/${{ needs.io_fuzz.outputs.first_crash_name }}
260-
```
345+
\`\`\`
261346
262347
### Investigation Checklist
263348
264349
- [ ] Download crash artifacts from workflow run
265350
- [ ] Reproduce crash locally with full backtrace
266351
- [ ] Analyze stack trace and identify root cause
267352
- [ ] Determine severity (security vs stability)
268-
- [ ] Check if this is a duplicate of an existing issue
269353
- [ ] Minimize test case if needed
270354
- [ ] Create fix PR with reference to this issue
271355
- [ ] Add regression test
@@ -286,28 +370,37 @@ jobs:
286370
287371
---
288372
289-
*Automatically created by fuzzing workflow*
373+
*Automatically created by fuzzing workflow with Claude AI analysis*
290374
*Workflow file: [fuzz.yml](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/fuzz.yml)*
291375
*Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}*
292-
EOF
376+
EOF_BODY
377+
)"
293378
294379
- name: Comment on duplicate issue
295-
if: steps.dedup.outputs.is_duplicate == 'true'
380+
if: steps.decision.outputs.is_duplicate == 'true'
296381
env:
297382
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
298383
run: |
299-
ISSUE_NUM="${{ steps.dedup.outputs.issue_number }}"
384+
ISSUE_NUM="${{ steps.decision.outputs.duplicate_of }}"
385+
REASONING=$(jq -r '.reasoning' decision.json)
386+
CONFIDENCE=$(jq -r '.confidence' decision.json)
300387
301388
gh issue comment "$ISSUE_NUM" \
302389
--repo ${{ github.repository }} \
303-
--body-file - <<'EOF'
390+
--body "$(cat <<EOF_COMMENT
304391
## Additional Crash Detected
305392
306-
Another crash was found in the `file_io` fuzzing target that appears to be a duplicate of this issue.
393+
Another crash was found in the \`file_io\` fuzzing target that appears to be a duplicate of this issue.
394+
395+
### Claude's Analysis
396+
397+
**Confidence**: $CONFIDENCE
398+
399+
**Reasoning**: $REASONING
307400
308401
### Details
309402
310-
- **Crash File**: `${{ needs.io_fuzz.outputs.first_crash_name }}`
403+
- **Crash File**: \`${{ needs.io_fuzz.outputs.first_crash_name }}\`
311404
- **Total Crashes**: ${{ needs.io_fuzz.outputs.crash_count }} found in this run
312405
- **Workflow Run**: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
313406
- **Timestamp**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
@@ -316,11 +409,12 @@ jobs:
316409
317410
Download crash artifacts from: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
318411
319-
The fuzzing infrastructure detected this as a likely duplicate based on similar stack traces and error messages.
412+
Claude analyzed the crash and determined it matches this issue based on crash location, error pattern, and code analysis.
320413
321414
---
322415
*Automatically added by fuzzing workflow*
323-
EOF
416+
EOF_COMMENT
417+
)"
324418
325419
ops_fuzz:
326420
name: "Array Operations Fuzz"

0 commit comments

Comments
 (0)