Skip to content

fix: stop merging sub-agent turns into parent session#335

Merged
BYK merged 2 commits into
mainfrom
fix/subagent-session-isolation
May 15, 2026
Merged

fix: stop merging sub-agent turns into parent session#335
BYK merged 2 commits into
mainfrom
fix/subagent-session-isolation

Conversation

@BYK
Copy link
Copy Markdown
Owner

@BYK BYK commented May 15, 2026

Summary

  • Sub-agent requests (OpenCode explore/general agents) were being merged into the parent session via x-parent-session-id header lookup, causing the full Lore pipeline to run on the sub-agent's messages using the parent's session state — corrupting gradient state, cache analytics, timing baselines, and model tracking
  • Removed the parent-merge priority in identifySession() so sub-agents naturally get independent sessions through their own x-session-affinity header, benefiting from the full pipeline (LTM, gradient, distillation, curation) on their own state
  • Cleaned up all now-dead isSubagentTurn guards from handleConversationTurn(), postResponse(), and the structural compaction dispatch

Problem

When OpenCode spawns a sub-agent (e.g. "explore" for file search), the gateway merged it into the parent session, then ran the full pipeline against the parent's state with the sub-agent's completely different system prompt and messages. This caused:

  1. False cache divergence alerts — sub-agent body compared against parent's lastRequestBody
  2. Gradient state corruption — sub-agent's tiny message array overwrote parent's lastLayer, lastTransformedCount
  3. Cache analytics poisoning — sub-agent body stored as lastRequestBody, poisoning next parent comparison
  4. Bust rate contamination — sub-agent's always-cold cache stats fed into parent's dynamic context cap
  5. Model/protocol corruption — sub-agent's model overwrote parent's lastModel for warmup profile
  6. Timing corruptionlastRequestTime reset by sub-agent in getOrCreateSession()

Approach

Sub-agents already carry their own x-session-affinity nanoid. The fix simply removes the x-parent-session-id merge priority in identifySession(), letting sub-agents fall through to the normal Tier 1 path where they get independent sessions. Net deletion: -113 lines.

Files changed

File Change
packages/gateway/src/pipeline.ts Remove parent-merge in identifySession(), remove all isSubagentTurn logic, remove structural compaction sub-agent guard
packages/gateway/test/cache-warmer.test.ts Update simulateGapRecording helper, remove 3 obsolete sub-agent tests

BYK added 2 commits May 15, 2026 11:48
Sub-agent requests (OpenCode explore/general agents) were being merged
into the parent session via x-parent-session-id header lookup in
identifySession(). This caused the full Lore pipeline to run on the
sub-agent's messages using the parent's session state, corrupting
gradient state, cache analytics, timing baselines, and model tracking.

Sub-agents already carry their own x-session-affinity header with a
unique nanoid. By removing the parent-merge priority, they naturally
get independent sessions through the normal Tier 1 identification path,
benefiting from the full pipeline (LTM, gradient, distillation) on
their own state without corrupting the parent.

Removes all isSubagentTurn guards from handleConversationTurn() and
postResponse() — now dead code since sub-agents are separate sessions.
- Remove extractParentSessionId(), PARENT_SESSION_HEADERS and their
  tests — no longer used after parent-merge removal
- Fix stale doc comments in pipeline.ts, session.ts, and types.ts that
  still referenced x-parent-session-id or sub-agent merging behavior
- Remove unnecessary bare block scope in postResponse() temporal storage
@BYK BYK merged commit dc52b65 into main May 15, 2026
7 checks passed
@BYK BYK deleted the fix/subagent-session-isolation branch May 15, 2026 12:01
This was referenced May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant