Skip to content

feat(subagent): add delegation-mode gating and token-level transcript streaming#6537

Merged
bug-ops merged 1 commit into
mainfrom
feat/issue-5857/subagent-delegation-messaging
Jul 20, 2026
Merged

feat(subagent): add delegation-mode gating and token-level transcript streaming#6537
bug-ops merged 1 commit into
mainfrom
feat/issue-5857/subagent-delegation-messaging

Conversation

@bug-ops

@bug-ops bug-ops commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a tri-state delegation_mode (disabled / explicit_request_only / proactive) to SubAgentConfig so an operator can restrict which spawn paths are permitted without disabling sub-agents entirely — e.g. block the autonomous orchestration scheduler from spawning while still allowing explicit /agent spawn//agent resume (parity: zeph-subagent lacks disabled/explicit-request-only/proactive delegation-mode control (Codex pattern) #5857). Enforcement is fail-closed: SpawnContext.origin defaults to the restrictive Autonomous value, and every real spawn call site (manager spawn/spawn_for_task, /agent resume, the ACP /subagent spawn path) is audited and gated behind a shared DelegationMode::permits_explicit() allow-list.
  • Extends live subagent transcript forwarding with token-level intra-turn streaming on providers with native streaming-with-tools support, reusing the existing AnyProvider::chat_with_tools_stream path rather than adding a new provider-trait method (subagent: token-level intra-turn transcript streaming (FR-002b, follow-up to #6359) #6456). Non-streaming backends keep the prior once-per-turn forwarding unchanged. The forwarding drain now buffers deltas with a bounded holdback window before sanitizing, closing a masking gap where a secret/PII pattern split across two delta boundaries could reach forwarded output unmasked.

Closes #5857
Closes #6456

Notes

  • zeph-subagent lacks live peer-to-peer messaging between concurrently spawned subagents #5871 (live peer-to-peer messaging between subagents), originally triaged together with these two issues, was split into its own follow-up per architect/critic design review: its spec (.local/specs/046-subagent-peer-messaging-parity/spec.md) has 4 unresolved open questions, introduces a new spawn-tree authorization boundary warranting its own dedicated security pass, and has heavy file overlap with this PR's changes that would force serialized edits if bundled. Not included here.
  • LLM serialization gate (branching.md): run live against claude-haiku-4-5-20251001 with a 2-turn, tool-call-containing prompt via /agent bg under --bare --forward-subagent-text. Confirmed well-formed request/response payloads, no 400/422, and the native per-delta streaming path firing (4 forwarded chunks across 2 turns instead of the 2 FR-002a alone would produce). Details in .local/testing/playbooks/subagent-token-streaming.md.

Test plan

  • cargo +nightly fmt --check
  • cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings
  • cargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins (14833/14833 passed)
  • rustdoc gate (RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler")
  • gitleaks protect --staged
  • Live LLM serialization gate against real Claude API (see Notes above)
  • Playbooks + coverage-status updated (.local/testing/playbooks/subagent-delegation-mode.md, .local/testing/playbooks/subagent-token-streaming.md, .local/testing/coverage-status.md)

… streaming

Adds a tri-state delegation_mode (disabled/explicit_request_only/proactive)
to SubAgentConfig so an operator can restrict which spawn paths are allowed
without disabling sub-agents entirely, closing a prompt-injection-relevant
gap where the autonomous orchestration scheduler could not be distinguished
from an explicit user-triggered spawn. Enforcement is fail-closed via a new
SpawnContext.origin field that defaults to the restrictive value, and every
real spawn call site (manager spawn/spawn_for_task, /agent resume, the ACP
/subagent spawn path) is audited and gated behind a shared allow-list
predicate.

Extends live subagent transcript forwarding (forward_transcript) with
token-level intra-turn streaming on providers with native streaming-with-
tools support, reusing the existing AnyProvider::chat_with_tools_stream
path rather than adding a new provider-trait method. Non-streaming backends
keep the prior once-per-turn forwarding unchanged. The forwarding drain now
buffers deltas with a bounded holdback window before sanitizing, closing a
masking gap where a secret/PII pattern split across two delta boundaries
could reach forwarded output unmasked.
@github-actions github-actions Bot added documentation Improvements or additions to documentation rust Rust code changes core zeph-core crate dependencies Dependency updates config Configuration file changes enhancement New feature or request size/XL Extra large PR (500+ lines) labels Jul 20, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 20, 2026 02:37
@bug-ops
bug-ops merged commit 3794893 into main Jul 20, 2026
47 checks passed
@bug-ops
bug-ops deleted the feat/issue-5857/subagent-delegation-messaging branch July 20, 2026 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration file changes core zeph-core crate dependencies Dependency updates documentation Improvements or additions to documentation enhancement New feature or request rust Rust code changes size/XL Extra large PR (500+ lines)

Projects

None yet

1 participant