Scenario progress double-counts an attack result after its timestamp is bumped
Les mainteneurs répondent en général sous 2 jours
Évaluation
- Difficulté
- 3/5
- Temps estimé
- Une demi-journée
- Accessibilité débutants
- 25/100
Piste de recherche
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.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
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)
- Langage dominant
- Python
- Étoiles
- 4.6k
- Forks
- 944
- Merge moyen
- 2 j 18 h
- PR mergées (30 j)
- 358
Préparer son environnement
Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Aucun guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de microsoft/PyRIT
-
BUG: label queries only return the final conversation of an attackPeut-être pris @u7k4rs6 l’a pris il y a 2 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
microsoft/PyRIT#3095 · 4 commentaires · 1 personne assignée ·
Les mainteneurs répondent en général sous 2 jours
-
BUG Configuration keeps runtime-status errors after polling recoversPeut-être pris @joeyvictorino l’a pris il y a 5 jours. OuverteBug: triage GUI help wanted
Difficulté 2/5 1-3 heures Accessibilité débutants 86/100
microsoft/PyRIT#2868 · 6 commentaires ·
Les mainteneurs répondent en général sous 2 jours
-
Crescendo backtracking keeps the refused prompt when the objective target made a tool callPeut-être pris @RachelWanggg l’a pris aujourd’hui. Ouverte
Difficulté 3/5 1-2 jours Accessibilité débutants 30/100
Les mainteneurs répondent en général sous 2 jours
-
BUG BinAsciiConverter UUencode output cannot be decoded when all words are convertedPeut-être pris @barkha1research-ai l’a pris aujourd’hui. OuverteBug: triage
Difficulté 2/5 1-3 heures Accessibilité débutants 25/100
Les mainteneurs répondent en général sous 2 jours
-
FEAT Proposal: red-team decision models as targets (decision flip-rate testing)Peut-être pris @shashank03-dev l’a pris aujourd’hui. Ouverte
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 15/100
microsoft/PyRIT#3246 · 2 commentaires ·
Les mainteneurs répondent en général sous 2 jours
Toutes les issues de microsoft/PyRIT
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
huggingface/sentence-transformers#4186 ·
Les mainteneurs répondent en général sous 5 jours
-
documentation
Difficulté 1/5 Moins d'une heure Accessibilité débutants 92/100
QuantEcon/QuantEcon.py#988 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
fabriziosalmi/certmate#1247 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
Les mainteneurs répondent en général sous 1 jour
-
documentation good first issue
Difficulté 2/5 Une demi-journée Accessibilité débutants 72/100
sujithputta02/Esapay#13 ·