| 575 | |
| 576 | |
| 577 | def _append_found(path: Path, crash: CrashArtifact, run_idx: int) -> None: |
| 578 | # Raw ASAN excerpt — SUMMARY line + first stack frames. Agents parse the |
| 579 | # signature themselves; the pipeline doesn't pre-canonicalize crash_type or |
| 580 | # top_frame anymore (that was a fragility point — adjacent lines, format |
| 581 | # variance, free-text agent tags all fragmented the dedup). |
| 582 | entry = { |
| 583 | "run_idx": run_idx, |
| 584 | "asan_excerpt": asan_excerpt(crash.crash_output), |
| 585 | } |
| 586 | with open(path, "a") as f: |
| 587 | f.write(json.dumps(entry) + "\n") |
| 588 | |
| 589 | |
| 590 | def _read_found_summaries(path: Path) -> list[str]: |