Scenario progress double-counts an attack result after its timestamp is bumped
I maintainer di solito rispondono entro 2 giorni
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- Mezza giornata
- Idoneità per principianti
- 25/100
Direzione di ricerca
Start in ScenarioProgressReadModel._hydrate_new_deltas_async, where each page is appended with entry.deltas.extend(page) and nothing is deduplicated by attack_result_id. Then read get_scenario_attack_result_deltas_async to see how the keyset cursor over (timestamp, id) re-emits bumped rows. A re-emitted delta should update the cached copy of that attempt, not add a second one. Linked PR #3184 is already open against this, so check it before starting.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
The scenario progress read model double-counts an attack result whose row timestamp is later bumped.
get_scenario_attack_result_deltas_async pages rows in ascending keyset order over (timestamp, id), so any row whose timestamp moves forward compares greater than the stored cursor and is emitted again. That happens today: AttackService.update_attack_async and remove_human_score_async write "timestamp": datetime.now(UTC) on every edit, and promote_attack_conversation rewrites timestamps too.
ScenarioProgressReadModel._hydrate_new_deltas_async handles each page with entry.deltas.extend(page) and no dedup by attack_result_id, so the re-emitted row is appended as a second copy of the same attempt. The snapshot's results then contains the same attack twice, which inflates per-unit attempt counts and retry pressure for the lifetime of the cache entry.
Steps/Code to Reproduce
- Poll
GET /scenarios/{id}/progressonce so the read model caches the run's deltas and cursor. - Edit any attack result that belongs to that scenario (for example
PUT /attacks/{attack_result_id}), which bumps the row's timestamp. - Poll the scenario progress endpoint again.
The storage feed re-emits the edited row (keyset timestamp > cursor), and the read model appends it again.
Minimal reproduction against the read model:
memory.get_scenario_attack_result_deltas_async = AsyncMock(
side_effect=[([delta], False), ([bumped_delta_with_same_id], False)]
)
read_model = ScenarioProgressReadModel(memory=memory)
first = await read_model.get_snapshot_async(scenario_result_id="run", ...)
second = await read_model.get_snapshot_async(scenario_result_id="run", ...)
# second.results holds the same attack_result_id twice
Expected Results
A re-emitted delta updates the already cached copy of that attempt instead of adding a second one.
Actual Results
The same attack result id appears twice in the snapshot results, inflating attempt counts.
Screenshots
N/A
Versions
OS: macOS
Python version: 3.14
PyRIT version: installed from main (66c41fa)
- Lingua principale
- Python
- Stelle
- 4.6k
- Fork
- 944
- Merge medio
- 2g 16h
- PR unite (30g)
- 350
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di microsoft/PyRIT
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
microsoft/PyRIT#3204 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
BUG: label queries only return the final conversation of an attackForse già presa @u7k4rs6 l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
microsoft/PyRIT#3095 · 4 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 2 giorni
-
BUG Configuration keeps runtime-status errors after polling recoversForse già presa @joeyvictorino l’ha presa 5 giorni fa. ApertaBug: triage GUI help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
microsoft/PyRIT#2868 · 4 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 2 giorni
-
BUG: HTTPTarget sends conflicting Content-Length and Transfer-Encoding headersForse già presa @Kaap10 l’ha presa 9 giorni fa. ApertaBug: triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
microsoft/PyRIT#3202 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 Mezza giornata Idoneità per principianti 25/100
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di microsoft/PyRIT
Issue simili
-
`burr` fails to start when the Python path has a space in itForse già presa @enekoreto l’ha presa oggi. Apertastatus/needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 5 giorni
-
gemini 出现了新的域名需要加入Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
-
Difficoltà 2/5 Mezza giornata Idoneità per principianti 72/100
debpalash/VoiceStudio#2903 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
dagster-io/community-integrations#367 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
aws-samples/sample-per-model-bedrock#243 ·
I maintainer di solito rispondono entro 1 giorno