Skip to content

fix(pair): a paired thread briefs its executor instead of fanning out - #652

Merged
rynfar merged 1 commit into
pylonfrom
fix/pair-blocks-fanout
Sep 18, 2026
Merged

rynfar merged 1 commit into
pylonfrom
fix/pair-blocks-fanout

Conversation

@rynfar

@rynfar rynfar commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

What

A paired thread can no longer fan out with Pylon's own delegation tools.

  • delegate_thread refuses with DelegationPairedError while the thread's pair executor exists and is not archived. The message tells the agent to brief the executor with pair_handoff, and to ask the user to turn Pair off if the work really needs parallel threads.
  • read_delegation_skill returns the pair protocol on a paired thread instead of the fan-out workflow.
  • The pair protocol now says that delegate_thread is refused while paired and that a user asking to "delegate" or "use delegation" means the executor.
  • delegated_thread_status, delegated_thread_result, send_to_delegated_thread and interrupt_delegated_thread still work, so children started before the pair can be wound down.

Why

Seen in real use on nightly .201. A Claude Opus lead was paired with an Antigravity executor. The user then told it "you can resume using delegation". It looked up the delegation tools, called read_delegation_skill, started two Antigravity children with delegate_thread, and never sent its executor a single brief.

Pairing already denied the provider's own subagents, but left Pylon's fan-out toolkit fully available to the same lead, and the word the user naturally reached for pointed straight at it. One pair is supposed to mean one executor.

How

Both checks read the projection (pairExecutorThreadId(thread) exists and archivedAt === null) rather than the session's pair capability, so a pair started mid-session is covered immediately. Turning the pair off archives or deletes the executor, which lifts the refusal.

Verification

  • vp test run on apps/server/src/mcp/toolkits, RuntimeInstructions.test.ts and apps/server/src/orchestration: 972 passed. New tests written first and seen failing, the first by actually creating the fan-out child: the refusal and its message, no commands dispatched, the skill swap, and both lifted again once the executor is archived; plus the protocol wording.
  • Typecheck t3: 0 errors. Lint, format and vp run knip:check clean.
  • Not run live.

Part of #622.

Model: Claude Fable 5.1, in Pylon via the Claude Code harness.


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 18, 2026
@vercel

vercel Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
pylon-marketing Canceled Canceled Sep 18, 2026 10:04pm UTC

@rynfar
rynfar force-pushed the fix/pair-blocks-fanout branch from a127986 to 9758f84 Compare September 18, 2026 21:06
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 14.0 KiB 13.9 KiB −49 B (−0.3%) 15.1 KiB ✅
Codex Thread snapshot wire 7.2 KiB 7.2 KiB +5 B (+0.1%) 7.3 KiB ✅
Codex Live turn WebSocket wire 6.7 KiB 6.7 KiB −54 B (−0.8%) 7.8 KiB ✅
Codex Live turn WebSocket decoded 58.0 KiB 58.0 KiB −44 B (−0.1%) 66.4 KiB ✅
Codex Live turn messages 9 8 −1 (−11.1%) 21 ✅
Claude Total thread wire 13.9 KiB 14.0 KiB +92 B (+0.6%) 15.1 KiB ✅
Claude Thread snapshot wire 7.2 KiB 7.2 KiB +3 B (+0.0%) 7.3 KiB ✅
Claude Live turn WebSocket wire 6.7 KiB 6.8 KiB +89 B (+1.3%) 7.8 KiB ✅
Claude Live turn WebSocket decoded 58.8 KiB 58.9 KiB +88 B (+0.1%) 66.4 KiB ✅
Claude Live turn messages 8 10 +2 (+25.0%) 21 ✅

Baseline: bff59e8 · PR result: 9758f84 · 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: 115.6 KiB
  • Claude decoded thread snapshot: 116.3 KiB

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

@rynfar
rynfar merged commit 6ca905c into pylon Sep 18, 2026
18 checks passed
@rynfar
rynfar deleted the fix/pair-blocks-fanout branch September 18, 2026 21:15

This branch was successfully deployed

1 active deployment
Preview — 9758f844 Deployed Sep 18, 2026 by vercel[bot]
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