fix(wire): reject steer messages after turn ends#1591
Open
howardpen9 wants to merge 1 commit intoMoonshotAI:mainfrom
Open
fix(wire): reject steer messages after turn ends#1591howardpen9 wants to merge 1 commit intoMoonshotAI:mainfrom
howardpen9 wants to merge 1 commit intoMoonshotAI:mainfrom
Conversation
…ssage loss The WireServer used `_is_streaming` (based on `_cancel_event is not None`) to gate steer acceptance. Since `_cancel_event` is only cleared in the `finally` block of `_handle_prompt()`, there was a window after `run_soul()` returns but before cleanup where steers would be accepted with `status=steered` but never consumed — silently lost. This adds a `_turn_active` flag that tracks the actual soul execution lifecycle, set to True at turn start and False immediately when `run_soul()` returns. `_handle_steer()` now checks `_turn_active` instead of `_is_streaming`.
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.
Summary
WireServer._handle_steer()where steer messages sent afterrun_soul()returns but before_cancel_eventcleanup would be accepted withstatus=steeredbut never consumed — silently lost_turn_activeflag to precisely track soul execution lifecycle, replacing the_is_streamingcheck (which relied on_cancel_event is not None) for steer gatingProblem
_is_streamingis derived from_cancel_event is not None. Since_cancel_eventis only cleared in thefinallyblock of_handle_prompt(), there's a window betweenrun_soul()returning and thefinallycleanup where:TurnEndevent_handle_steer()sees_is_streaming == Trueand accepts itsoul.steer()queues the message_agent_loop()discards it as "stale"Since
_read_loop()dispatches inbound JSON-RPC messages concurrently viaasyncio.create_task, the ordering between_handle_prompt's finally block and_handle_steeris scheduler-dependent.Fix
Add a
_turn_active: boolflag that is:Truewhen_handle_prompt()startsrun_soul()Falseimmediately whenrun_soul()returns (beforefinallycleanup)_handle_steer()now checks_turn_activeinstead of_is_streaming, closing the tail window.Test plan
test_handle_steer_rejects_after_turn_ends— simulates the exact race windowtest_handle_steer_queues_input_when_streaming— sets_turn_active = True