Repository navigation
Ask panel follow-ups: lane order, one Stop notice, peer slugs, a flaky test - #189
Merged
Merged
Conversation
…y test Four follow-ups from the live run of "Ask <app>" (#184). 1. Order across lanes. Each lane counts its own cursor.seq (the peer's session is long, the person's context new), so sorting both by seq drew the system agent's request below the person's later question. The kernel also sends a turn's user message only when the turn ENDS, and never for a stopped turn, so the request line sat after its answer and a stopped request never showed. Now: within a lane, ledger order; across lanes, one clock (the order events reached the panel: stream events carry no time; history comes merged by persisted_at). A turn's request line stands where the turn started: the broker records the words it sent (the person's message, the system agent's peer/input) and hands them over with turn/started (`request`), and the conversation's history adds a stopped turn's request the kernel never recorded, at the time it started. 2. Stop said "turn interrupted by client" twice: once from the turn's end, once from the send's error. The send's error is shown only when the turn never started. 3. The system agent tried the app id (os.news) with peer_send_input. The note and agents.list now give the peer slug (os-news-22a12f90; OctosAppService::peer_slug) and say to use it, or to find it with peer_list, never the app id. 4. the_person_and_the_system_agent_talk_in_parallel_lanes_that_share_history failed under load with turn_in_progress: the test drives the system session itself and started its second turn while the first was still finishing (after peer_send_input the system agent still writes its own answer). Not a broker race: the test now waits for its session, as the system chat does. Reproduced by slowing that answer in the scripted model; 20 runs at --test-threads=4 pass. Tests: two lanes replayed with interleaved arrival (out-of-order envelopes, user messages at the end, a stopped turn); the panel's Stop shows one notice; the broker hands a turn's words over at its start and keeps a stopped turn's request in history; the note and agents.list carry the slug. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Follow-ups from the live run of the "Ask " panel (#184): issues 1, 2, 3 and 5 of that run's list. Issue 4 (script-app agents asking questions) comes in a separate PR after App Hub.
1. Order across lanes; a stopped turn's request stays
cursor.seq(the peer's session is long, the person's context new), so the panel's seq sort mixed the lanes. Also, the kernel sends a turn'suser_messageonly when the turn ENDS (ledger of the live run: the person's question at seq 226 after its answer; the stopped turn hasturn_startedand no user message at all). So the request line landed after its answer, and a stopped turn's request never showed.app_chat::model: within a lane, ledger order. Across lanes, one clock: the order events reached the panel (stream events carry no time;assistant_persistedalone haspersisted_at). History already comes merged bypersisted_at(feat(app-peers): the person's lane runs in parallel with the system agent's, sharing history; pin octos e045c727 [skip ci] #173). A turn's request line stands where the turn started. The broker records the words it sent (the person's message, the system agent'speer/input) and hands them over withturn/started(request: {text, speaker}). The conversation's history adds a stopped turn's unrecorded request at its start time.2. One "turn interrupted by client" on Stop
The send's error is shown only when the turn never started. Once it started, its
turn_terminalalready says how it ended.3. The peer slug for the system agent
The system-chat note and
agents.list(andagents.ask) now carry the peer slug (os-news-22a12f90, via newOctosAppService::peer_slug, defaultNone). They say to use it withpeer_send_input, or to find it withpeer_list, and never the app id.5. The flaky real-kernel test
the_person_and_the_system_agent_talk_in_parallel_lanes_that_share_historyfailed under load withsystem turn: ... (turn_in_progress). The test drives the system session itself (turn/startviahost_request). It started its second system turn while the first was still finishing: afterpeer_send_inputreturns, the system agent still writes its own answer. It is not a broker race. The test now waits for its session, as the system chat does. I reproduced it deterministically by slowing that answer in the scripted model: the old test fails, the new one retries and passes. With the fix: 20/20 runs at--test-threads=4.Tests
app_chat::tests::two_lanes_interleave_by_arrival_and_a_stopped_request_stays: the live run replayed (big peer seqs, small person seqs, user messages at the end, an out-of-order envelope, a stopped turn).agents.listand the note.broker.rs:turn/startedcarries the turn's words;a_stopped_turns_request_stays_in_the_conversations_history.Local checks
mobile-appswith a real kernel): all pass--test-threads=1): passoctos-core,ws, real kernel): pass, plus clippyoctos-core,llm): pass, plus clippycargo check --lockedfor desktop and phone (default andmobile-apps): passnative_apps.py --checkandsetup.py --check --cargo: pass🤖 Generated with Claude Code