fix(server): remove retracted messages after revert - #22
Merged
Merged
Conversation
Long-thread reverts could backfill a retracted null-turn user message when capped checkpoint retention left a count shortfall. Exclude completed retraction message IDs from both projection retention passes and clean existing completed-retraction orphans in migration 044. Model and harness: GPT-5 via Codex
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.
Esc-retracted user messages survived the revert on long threads: capped checkpoint retention leaves a user-message count shortfall, and both projection paths' backfill fallbacks admitted the retracted null-turn message as filler (observed live: 9/11 retractions on a long thread cleaned fully, the 2 past the checkpoint cap leaked).
The thread.reverted payload already carries the retracted messageId, so both retention passes (in-memory projector + sqlite ProjectionPipeline) now exclude it from linkage and backfill. Migration 044 sweeps existing orphans (table-guarded, idempotent; verified against a copy of the live DB — deletes exactly the 2 known orphan rows out of 1,064).
Tests: leak repro pre-fix now passing, fallback regression guard, migration exact-cleanup/no-op-rerun — 60 passing across the retraction suites; server typecheck clean.