fix(gateway): error recovery no longer duplicates accepted inputs (#104653) - #105334
Merged
Merged
Conversation
Contributor
૮ >ﻌ< ა ci reviewran on b8bda22 — fix(gateway): carry accepted-input ownership through persist
|
Namespace delivery markers and assign fresh keyless turn identities instead of inferring ownership from IDs or process-local row baselines. Query only marker existence on the canonical live compression continuation and ancestors. Preserve raw reply IDs and exclude metadata from provider wire messages. Expand the two existing invariants with resumed cross-chat ID collisions, a real independent SQLite writer, reaped siblings, and archived-history allocation controls. All 20 full-handler checkpoints and 63 targeted tests pass.
This was referenced Sep 7, 2026
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.
Gateway error recovery preserves separately accepted inputs without repeating an input already durably owned by the same delivery or turn.
Refs #104653; complements merged #104899 without claiming to explain historical ID/NULL pairs.
persist_user_display_metadatapath and the gateway fallback writer. Platform identities include platform/profile/scope/chat/thread plus inbound ID; keyless turns get fresh identities. Raw platform IDs remain unchanged for quote/reply lookup, and marker metadata never reaches provider wire messages.Root cause: exception recovery inferred current input ownership from replay text, then from insufficiently scoped IDs/new rows, rather than carrying the current accepted input's identity through persistence.
Validation
Live repro: full
_handle_message→ production_run_agent/TurnRunner → real AIAgent → loopback HTTP/SSE → on-disk SQLite → persistence/delivery. Same expanded 20-checkpoint fixture: base869228cab4a8276d3b4c78da9d9939670c47bd0f7/20, reviewed intermediate653cd72ef63b013798748774a2509f453b566a771/20, fixed 20/20. These are cumulative row-sequence checks, not counts of independent defects. All controlled fault boundaries reached; base/fixed each made 10 loopback requests and zero external connection attempts.Limits: constructor and voice-policy faults are controlled injection boundaries, not live messaging-service/vendor failures. Compression checks use real SQLite archives/tree/reroutes, not provider-driven compaction. This is exception-path arbitration, not global exactly-once delivery. Historical rows are unchanged; unmarked historical rows cannot establish ownership on redelivery. No historical data-loss repair or complete explanation of the original report is claimed.
Reproduction commands and fixture boundaries:
evals/gateway_failure_ownership/README.md.Infographic