Skip to content

FIX: replace re-emitted progress deltas instead of counting them twice - #3184

Merged
Roman Lutz (romanlutz) merged 4 commits into
microsoft:mainfrom
ManoharPaturi:fix/progress-delta-dedup
Oct 14, 2026
Merged

Roman Lutz (romanlutz) merged 4 commits into
microsoft:mainfrom
ManoharPaturi:fix/progress-delta-dedup

Conversation

@ManoharPaturi

Copy link
Copy Markdown
Contributor

Description

Fixes #3183

get_scenario_attack_result_deltas_async pages rows in ascending (timestamp, id) keyset order, so a row whose timestamp moves forward (an edit through the attack REST routes, a conversation promotion) compares greater than the stored cursor and is emitted again. _hydrate_new_deltas_async appended every page with extend(), so the same attempt landed twice in the cached deltas and the snapshot results, inflating attempt counts and retry pressure until the cache entry was dropped.

A re-emitted delta is an update of an attempt already cached. The read model now tracks cached deltas by attack_result_id: new rows append as before, a re-emitted row replaces its cached copy in place, the mapped results from that position are rebuilt from the updated deltas, and the summary rebuilds whenever anything was appended or replaced.

Tests and Documentation

Added test_get_snapshot_replaces_reemitted_delta_instead_of_duplicating, which feeds the same attack_result_id twice (second time with a bumped timestamp and a changed outcome) and asserts the snapshot keeps exactly one result showing the updated outcome. Fails on main with the attempt duplicated, passes with the change. Full tests/unit/backend/test_scenario_progress_read_model.py suite passes (24 tests).

No documentation change needed, so I did not run JupyText.

The progress keyset is ordered by (timestamp, id), so an attack result
whose timestamp is bumped by an edit is emitted again after the stored
cursor. The read model appended every page with extend(), so the edited
attempt appeared twice in the snapshot and inflated attempt counts.

Track cached deltas by attack_result_id: a re-emitted row replaces its
cached copy, the mapped results from that position are rebuilt, and the
summary rebuilds when anything was appended or replaced.

Fixes microsoft#3183

Signed-off-by: Manohar Paturi <186662190+ManoharPaturi@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 13, 2026 15:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sort and remap the affected cached suffix after timestamp-bumped replacements so cursor pagination and latest-attempt summaries agree with storage order. Add regression coverage for real SQLite attack edits, page limits, replay, tied timestamps, multiple storage pages, and interrupted refreshes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2643b541-19cf-48c2-b27a-e1a68cc4a6e7
…3184

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2643b541-19cf-48c2-b27a-e1a68cc4a6e7
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2643b541-19cf-48c2-b27a-e1a68cc4a6e7
@romanlutz
Roman Lutz (romanlutz) added this pull request to the merge queue Oct 14, 2026
Merged via the queue into microsoft:main with commit 38b9e6c Oct 14, 2026
55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scenario progress double-counts an attack result after its timestamp is bumped

3 participants