Repository navigation
Conversation
…nnot file a finding twice The duplicate check awaits an LLM call and compares the candidate with the findings that were stored when it started. Two agents filing the same finding at the same moment each saw a list without the other's report, passed the check and both stored it. Reproduced against the real create functions with a slow check: three concurrent identical filings were stored three times, while a sequential fourth was correctly rejected. Hold a per-run asyncio lock across read existing -> check -> add in both create_vulnerability_report and create_dependency_report. Distinct findings still go through, one duplicate check at a time. The candidate and field dicts are built before the lock (they do not depend on the stored list), so the diff is mostly indentation: `git diff -w` is 13 lines. Fixes usestrix#627 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
|
| async def _slow_check(candidate: dict[str, Any], existing: list[dict[str, Any]]) -> dict[str, Any]: | ||
| """Stand in for the real check: it judges the candidate against the snapshot it is handed.""" | ||
| await asyncio.sleep(0.05) # the real one is a model call | ||
| for report in existing: | ||
| if report.get("title") == candidate["title"]: |
There was a problem hiding this comment.
Each test starts with no stored findings, but _slow_check always pauses. The real check_duplicate returns right away for an empty list and for matching dependency CVE/package pairs. These tests could pass even if the race returns on a path that waits for the model. Seed an unrelated finding in the vulnerability test and test a dependency case that reaches the model check.
Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/test_reporting_dedupe_race.py
Line: 45-49
Comment:
**Race tests miss real waits**
Each test starts with no stored findings, but `_slow_check` always pauses. The real `check_duplicate` returns right away for an empty list and for matching dependency CVE/package pairs. These tests could pass even if the race returns on a path that waits for the model. Seed an unrelated finding in the vulnerability test and test a dependency case that reaches the model check.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Bump to 1.7.0+shvia.22 and add the FORK.md row plus the four contributions (usestrix#1469 dedupe lock, usestrix#1470 whitebox repository targets, usestrix#1471 test isolation from the real home, usestrix#1472 trust fields in the PDF report). CLAUDE.md now says the suite no longer writes the real ~/.strix, and that `import litellm` loads the current directory's .env unless LITELLM_MODE=PRODUCTION. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
Resolves the conflicts with the retry and reporting changes that landed on main since this branch was opened. The resulting tree is the PR rebased onto main, tested there. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TavwVMH7PvrD68JTDfd6Hb
Concurrent agents can both store the same finding while the duplicate check awaits its model response. Each compares against a snapshot that does not yet contain the other filing.
Hold a per-run
ReportState.dedupe_lockacross reading stored findings, checking for duplicates and inserting the accepted report. Bothcreate_vulnerability_reportandcreate_dependency_reportuse the same lock.Dependency checks normally resolve synchronously from CVE/package identity. However, an existing same-CVE report without package metadata can send the check through the model. That fallback has the same race and now receives the same protection. The structured package-identity fast path remains model-free. Distinct findings remain accepted, and an exceptional check releases the lock.
Fixes #627.
Validation on macOS/Apple Silicon, Python 3.12.14, with isolated HOME/configuration:
check_duplicate; only the model is replaced with a synthetic response that yields execution.6b7ae2ebapplied cleanly and passed the same 182 tests.git diff --checkpassed.The trade-off is that filings in one run wait for an in-flight duplicate check. The lock is scoped to the report state, not shared across separate runs.
The complete repository suite, real model calls and live scans were not exercised. Remote CI still requires maintainer approval.
Prepared with AI assistance.