Skip to content

fix(server): show turns the provider starts on its own - #266

Merged
rynfar merged 1 commit into
pylonfrom
fix/admit-provider-initiated-turns
Sep 4, 2026
Merged

fix(server): show turns the provider starts on its own#266
rynfar merged 1 commit into
pylonfrom
fix/admit-provider-initiated-turns

Conversation

@rynfar

@rynfar rynfar commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

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.started that 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.started when 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:

  • an event that carries a request id still needs the exact match;
  • output for any other turn id is still dropped;
  • a pending exact admission still fences all output and lifecycle until the matching turn.started arrives.

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

  • New ingestion test, watched failing first (timed out waiting for the turn to become active): seeds an idle incarnation-tracked session, emits an unadmitted turn.started, a stale item for another turn, the turn's own assistant item, and turn.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 run on ingestion, reactor, decider, and command invariant suites: 17 files, 267 passed.
  • vp run -F t3 typecheck: clean. vp fmt --check and vp lint on 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).


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.6 KiB 13.6 KiB −4 B (−0.0%) 15.1 KiB
Codex Thread snapshot wire 7.1 KiB 7.1 KiB −5 B (−0.1%) 7.3 KiB
Codex Live turn WebSocket wire 6.5 KiB 6.5 KiB +1 B (+0.0%) 7.8 KiB
Codex Live turn WebSocket decoded 56.5 KiB 56.5 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 8 8 0 (0.0%) 21
Claude Total thread wire 13.6 KiB 13.7 KiB +9 B (+0.1%) 15.1 KiB
Claude Thread snapshot wire 7.1 KiB 7.1 KiB −2 B (−0.0%) 7.3 KiB
Claude Live turn WebSocket wire 6.6 KiB 6.6 KiB +11 B (+0.2%) 7.8 KiB
Claude Live turn WebSocket decoded 57.3 KiB 57.3 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 8 8 0 (0.0%) 21

Baseline: bfc5631 · PR result: 6d6f81c · Source CI: success

Scenario and decoded snapshot size

10 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.

  • Codex decoded thread snapshot: 111.2 KiB
  • Claude decoded thread snapshot: 111.9 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar
rynfar merged commit b671cb6 into pylon Sep 4, 2026
17 checks passed
@rynfar
rynfar deleted the fix/admit-provider-initiated-turns branch September 4, 2026 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant