Repository navigation
FIX: replace re-emitted progress deltas instead of counting them twice - #3184
Merged
Roman Lutz (romanlutz) merged 4 commits intoOct 14, 2026
Merged
Roman Lutz (romanlutz) merged 4 commits into
Roman Lutz (romanlutz) merged 4 commits into
Conversation
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>
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
Roman Lutz (romanlutz)
approved these changes
Oct 14, 2026
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #3183
get_scenario_attack_result_deltas_asyncpages 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_asyncappended every page withextend(), 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. Fulltests/unit/backend/test_scenario_progress_read_model.pysuite passes (24 tests).No documentation change needed, so I did not run JupyText.