fix(gateway): stop Desktop retries from silently truncating session history - #86605
Closed
fangliquanflq wants to merge 1 commit into
Closed
Conversation
2 tasks
Contributor
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.
What does this PR do?
Desktop retries and resubmits could silently truncate a durable session at the wrong user turn when the client supplied only a renderer ordinal. This could discard active model context while the Desktop transcript still showed those messages. The gateway now fails closed for ordinal-only truncation when durable user row IDs are available, while preserving ordinal-only compatibility for ephemeral histories without durable row IDs.
Symptom
After a failed Desktop turn, retrying or resubmitting could reduce the gateway history at an earlier user turn even though the Desktop transcript still displayed the dropped messages.
Impact
The Desktop transcript and the model's persisted context could silently diverge. In the reported session, 68 active context records were dropped from the model history until recovery from the archive.
Bug Cause
Trigger:
tui_gateway/methods_prompt.pyin theprompt.submitordinal fallback whenconfirm_truncateis true and onlytruncate_before_user_ordinalis supplied.Causal chain:
Why it is wrong: Durable row IDs are stable across rebuilds, while ordinals are positional and can drift. Trusting the weaker positional target when durable identities exist permits an ambiguous destructive operation.
Working sibling / contrast: Requests with
truncate_before_row_idor a message ID already resolve a durable target and reconcile the client ordinal before truncating. Ephemeral histories without durable row IDs retain the legacy ordinal-only compatibility path.Ruled out: Failed-turn prompt planning itself does not request truncation. Explicit Desktop restore, reload, and edit paths use the shared truncation helper and attach a row ID when one is available, so the unsafe behavior was isolated to the gateway's ordinal-only fallback.
Fix
Reject ordinal-only truncation before any in-memory or database mutation when an active user turn has a durable row ID. A regression test exercises the real
prompt.submithandler and verifies the request returns error 4004 without replacing persisted messages, mutating history, or starting a turn.Related Issue
Fixes #86573
Type of Change
Changes Made
tui_gateway/methods_prompt.py- fail closed when ordinal-only truncation targets durable session history.tests/test_tui_gateway_server.py- prove the unsafe request cannot mutate memory or persistence and cannot start a turn.How to Test
truncate_before_user_ordinal.The targeted regression passed (1 test). The related file passed all 556 tests; the wrapper retried one unrelated scheduling timeout and the fresh retry passed.
Checklist
Code
fix(scope):,feat(scope):, etc.)Documentation & Housekeeping
cli-config.yaml.exampleupdates are N/A because no config keys changedCONTRIBUTING.mdandAGENTS.mdupdates are N/A because architecture and workflows are unchangedScreenshots / Logs
N/A. The automated regression verifies the failure response and absence of state mutation directly.