fix(server): show turns the provider starts on its own - #266
Merged
Conversation
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
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
Claude Code continues on its own when a background task finishes: the CLI re-invokes the model and the adapter opens a synthetic turn for the assistant output. Those turns carry no admission request id because no user message admitted them.
Pylon's strict ingestion gate discards every turn-scoped event whose admission request id does not match the session's active request id, and it also drops any
turn.startedthat is not the exact pending admission. So on an incarnation-tracked session every synthetic turn ran completely hidden: no turn start, no assistant text, no activities, no completion. In the nightly database on 2026-09-04 one such hidden turn merged PR 261. Upstream shows these turns, because upstream has no strict gate; this is the one place where Pylon's admission model regressed visible behavior relative to T3.Fix
Ingestion admits a provider-initiated
turn.startedwhen the incarnation-tracked session is idle: same incarnation, no admission id, no pending admission, no active turn. While that turn is active and the session has no admitted request id, its own events pass the gate. Everything else is unchanged:turn.startedarrives.A user message sent while a provider-initiated turn is running is handled by #264: the decider issues an exact start, the adapter closes the synthetic turn and opens an admitted one.
Verification
turn.started, a stale item for another turn, the turn's own assistant item, andturn.completed. Asserts the turn becomes active with no request id, the stale item stays out, the assistant text is persisted, and the session returns to ready.vp test runon ingestion, reactor, decider, and command invariant suites: 17 files, 267 passed.vp run -F t3 typecheck: clean.vp fmt --checkandvp linton the touched files: clean.Companion PRs: #264 (decider no longer steers unadmitted turns) and #265 (adapter stops projecting between-turn status and the resume handshake as lifecycle).
Model: Claude Fable 5.1. Harness: Pylon (Claude Code provider).
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.