fix(server): a steered turn start no longer wedges the follow-up queue forever - #15
Merged
Merged
Conversation
…e forever A provider that steers folds a mid-turn send into the turn it is already running: no turn.started, and no session change, so the pending turn-start row is never adopted and never cleared. The queue gate treats a pending turn start as work in flight, so from that moment on the thread's queue never dispatched again — a follow-up queued at 14:11 was still sitting there when the thread had been idle for two minutes, and the user deleted it and retyped the message. The gate now ignores a pending turn start that some turn completed after: that request already had its answer, and no turn will ever be named for it. A pending start with no turn completed since still holds the queue, so a start racing adoption is unaffected. Built with Claude Opus 5 on Oh My Pi.
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.
Problem
A queued follow-up was never sent. From the event log of the thread it happened in:
A provider that steers folds the request into the turn it is already running, so no
turn.startedis emitted and the session snapshot does not change. The pending turn-start row (turn_id IS NULL, state='pending') is therefore never adopted and never cleared, andFollowUpQueueReactortreats a pending turn start as work in flight. From that moment the thread's queue never dispatches again — for the life of the thread. Not omp-specific: Claude and OpenCode steering leave the same ghost.Fix
The gate ignores a pending turn start that some turn completed after: that request has already had its answer, and no turn will ever be named for it. A pending start with no turn completed since still holds the queue, so a start that is merely racing adoption is unaffected. The reactor stays read-only — the projection keeps owning its rows.
Verification
main-xavier, passes here.FollowUpQueueReactor+ProjectionPipeline.followUpQueue: 17 tests green. tsgo clean; lint/format clean.Built with Claude Opus 5 on Oh My Pi.