Harness composition and subagent delegation
A harness can increasingly delegate work to isolated child agents, partition persistent named tasks, coordinate peer sessions, invoke other harness processes, or use protocol-mediated children. That internal topology is separate from UHP's external client-to-harness execution contract.
Page reviewed 4 Oct 2026 Source and review policy
Short answer
Section titled “Short answer”Subagent delegation is the runtime pattern in which a parent agent or harness hands a bounded task to one or more child agents with their own context and execution state. Harness composition is the broader descriptive term used by this guide when those children may be separate processes, separately configured agent runtimes, persistent named task contexts, peer sessions, or even different harness products.
Neither term is a UHP protocol primitive. UHP 2026-08-11 standardizes the external contract between a client/product and a server that runs a selected harness. What that harness does internally — including spawning children, partitioning persistent task contexts, coordinating peer sessions or invoking another harness — remains implementation behavior.
Product / client │ │ UHP ▼UHP server │ ▼Selected harness (parent) ├── isolated child of the same harness ├── persistent named task/session context ├── durable hosted room / peer-member driver ├── peer session of the same harness ├── out-of-process child ├── ACP-mediated child └── another harness product (for example Codex or Claude Code)The lower branches are examples of internal composition, not additional UHP hops.
Choose a delegation topology by its merge and failure contract
Section titled “Choose a delegation topology by its merge and failure contract”Begin with what the parent must recover, rather than how many agents can run. Current Hermes delegation documentation describes isolated child contexts; the product-specific examples below retain their original version scope.
| Work requirement | Useful topology | Parent’s proof obligation |
|---|---|---|
| Independent read-only research | Isolated children with bounded findings | Source traceability and coverage before synthesis |
| Concurrent edits to one repository | Disjoint ownership or separate worktrees | Diff integration, conflicts and tests against the integrated tree |
| Persistent tasks across parent reloads | Durable named contexts | Stable task identity and recovery classification |
| Different runtime/tool policy | Separate process or protocol-mediated child | Destination authority, credentials and cancellation boundary |
| Human/agent shared session | Explicit peer/control ownership | Who may mutate shared state now |
A parent that asks two children to edit the same file has created a merge problem even if both agents report success. Assign file ownership before dispatch, persist it with task IDs, and evaluate the combined artifact after integration. A worktree can reduce file collisions but does not automatically isolate secrets, permissions or external actions.
For failure, distinguish a child refused before admission from a child whose side effect is unknown. The second needs session recovery and effect reconciliation before redispatch. UHP’s external execution contract can carry a child task, but parent acceptance and artifact integration remain orchestration responsibilities.
Why this now deserves its own layer
Section titled “Why this now deserves its own layer”Choose an orchestration host deliberately
Section titled “Choose an orchestration host deliberately”A composition design needs an explicit owner for scheduling, child state and permissions. These guides offer different starting points rather than interchangeable UHP implementations:
| Where the work lives | Read next | Boundary to evaluate |
|---|---|---|
| Repository automation running as GitHub Actions jobs | GitHub Agentic Workflows | Compilation, sandboxed execution and SafeOutputs separate requested work from permitted writes. |
| A long-running harness with recursive or background delegation | Prime Agent | Durable control state and child execution must be distinguished from the outer protocol session. |
| A terminal or remotely reachable coding environment | Antigravity CLI | Headless execution, Remote Control, subagents and permission ownership need separate evaluation. |
For a Python application embedding its own harness, decide how workspace access and persistence relate to the parent task. Pydantic AI Harness separates the workspace capability from Coder; its local workspace executes with the host’s access rather than providing a sandbox. Deep Agents supplies planning, filesystem/context tools and delegation, but checkpoint continuity, persistent file storage and host filesystem access still depend on your chosen backends. Before letting a child mutate files, choose the state identity and execution boundary that the parent can recover and inspect.
The amount of orchestration you want to supply is another decision. Strands Agents distinguishes a ready harness from its lower-level SDK: choose the assembled configuration for a supplied tool/loop starting point, or the SDK when your application will define those policies. For declarative agent teams and portable YAML definitions, Docker Agent exposes a different configuration model. Decide whether it is consuming MCP tools, exporting an agent as a tool, serving A2A tasks or receiving ACP client traffic; these directions do not share one cancellation or permission contract.
When session state and approvals belong to a runtime service rather than the calling application, TrueForge separates the bundled chat UI, runtime HTTP API and MCP authorization. A parent should consume the runtime’s task/approval evidence instead of treating a UI transcript or successful login as proof that a tool action was authorized. These framework and runtime choices do not by themselves provide a UHP child binding: parent admission, cancellation ownership and artifact acceptance remain explicit integration responsibilities.
Recent upstream harness implementations make the topology explicit enough that “the harness” can no longer always be treated as one monolithic agent loop.
DeepSeek Harness: explicit multi-provider child architecture
Section titled “DeepSeek Harness: explicit multi-provider child architecture”DeepSeek Harness (dsh) provides the clearest example in the August source set. Release v0.1.0-rc.8 on 19 August 2026 made Claude Code and Codex subagents installable on demand as Profile Bundles, with non-interactive permission modes and multiple named instances. The current upstream subagent family is broader still:
| DeepSeek Harness child path | What it does |
|---|---|
| In-process spawn | Starts a fresh child inside the dsh runtime |
| In-process fork | Starts a child from the parent’s completed history |
| ACP provider | Starts an out-of-process child over Agent Client Protocol (ACP) |
| Codex provider | Starts a real Codex app-server child |
| Claude Code provider | Starts a real Claude Code child through the official Claude Agent SDK |
| dsh SDK provider | Starts an out-of-process DeepSeek Harness child through its TypeScript SDK |
Multiple named providers can coexist in one context. Codex and Claude Code remain optional bundles rather than dependencies in the default dsh production closure.
This is cross-harness composition in concrete upstream code: one harness can delegate to children implemented through different runtime/provider boundaries.
Codex: same-harness task delegation in stable 0.150.0
Section titled “Codex: same-harness task delegation in stable 0.150.0”OpenAI’s stable Codex 0.150.0 release on 26 August 2026 adds a separate composition style inside Codex itself. An active Codex task can receive a codex_tui tool namespace for listing, reading, waiting on, creating, forking, messaging, renaming, archiving and restoring other Codex tasks through app-server thread operations.
Delegation-capable task tools are routed through an authenticated local MCP server with explicit approval prompts, while respecting configured and managed MCP policy. The TUI also supports @ mentions for matching Codex tasks; selected tasks become bounded live thread references that the agent can inspect through read_thread and that survive start, resume and fork flows.
This is meaningful same-harness composition: a Codex task can coordinate other Codex task/thread objects without introducing another UHP hop. The use of MCP here is an internal approval-gated transport for Codex delegation tools; it does not make Codex task objects MCP Tasks or UHP tasks.
The release also adds an Interrupt hook for active top-level turns, with command or MCP handlers invoked after the transcript is flushed and before Codex emits the interrupted-abort event. That is a Codex lifecycle-extension point, not UHP cancellation semantics.
Qwen Code: owner-scoped named tasks in stable v0.22.3, concurrent control in the 31 Aug nightly
Section titled “Qwen Code: owner-scoped named tasks in stable v0.22.3, concurrent control in the 31 Aug nightly”Qwen Code v0.22.3, published 28 August 2026, adds another same-harness topology through pull request #10198: an opt-in named-task catalogue for daemon-managed Channels. With sessionScope: "user" and multiSession: true, one sender can create, list, select, close and reopen up to eight persistent named tasks in one chat, each retaining its exact daemon session and transcript.
This is not parent→child delegation. It is session multiplexing / persistent task partitioning inside one Qwen host interaction. Catalogues are isolated by Channel instance, chat and sender; inactive tasks are restored by exact session identifier instead of silently creating replacements; and the existing selected-session route remains a compatibility pointer.
Stable v0.22.3 keeps an idle-selected control policy: task creation/switching is refused while the selected task is busy or waiting for permission, and a busy task cannot be closed. The official 31 August nightly materially extends that topology. Pull request #10574 / merge 8ca93b49 removes only the selection-related busy guards, so already accepted turns reserve their exact named session before asynchronous preparation and can keep running while the user creates or selects another task. Late results retain their originating task label instead of following the newly selected compatibility route.
The nightly control boundaries remain task-specific: /session cancel [<name>] targets the selected or explicitly named owned active prompt without changing selection; bare permission commands consider only the selected task, while explicit request IDs can answer an owned inactive task. A busy task still cannot be closed. The named tasks continue to share one working directory, so simultaneous file writes can conflict; per-task worktrees remain deferred. Webhooks, group-history backfill, loops and standalone Channel execution also remain excluded. Upstream reports 660 focused named-session/Channel tests plus build, typecheck, lint and formatting checks; no live external Channel-adapter E2E was run.
From a UHP perspective these named task/session objects and their concurrency controls remain Qwen internals. HarnessRouter’s public Qwen evidence is against Qwen Code 0.22.1 using the CLI stream-json and native resume path; no current source establishes that HarnessRouter uses daemon-managed Channels or maps Qwen’s named tasks, cancellation or permission correlation into UHP-visible task/session objects.
Claude Code: peer sessions, managed MCP and subagent durability through 2.1.261
Section titled “Claude Code: peer sessions, managed MCP and subagent durability through 2.1.261”Anthropic’s Claude Code 2.1.248, published 27 August 2026, expands cross-session messaging through SendMessage and ListAgents to same-machine sessions on Bedrock, Vertex, Foundry and environments where telemetry is disabled. The same release tightens the crossSessionInbound setting and clarifies that when a subagent sends a message to another session, any reply returns to the parent session’s conversation.
This is a different composition topology from parent-owned subagents. Separately running Claude Code sessions can coordinate as peers while retaining their own session state. From a UHP perspective, that peer graph remains internal harness behavior: the current UHP specification does not define peer-session discovery, cross-session message routing or a mapping between Claude Code peer sessions and UHP-visible tasks/sessions.
Claude Code 2.1.248 also adds a --restricted / CLAUDE_CODE_RESTRICTED=1 execution profile that removes built-in command/code tools and WebFetch unless explicitly allowed, constrains file tools to the working directory, refuses bypassPermissions, and ignores user/project/local settings. That is relevant to capability isolation when composing agents, but it is a Claude Code runtime control rather than a UHP policy primitive.
Claude Code 2.1.251 on 28 August adds a host-observability layer to this topology: Remote Control clients can receive a foreground subagent’s tool calls and results live, while background subagents remain status-only. It also repairs several coordination paths — teammate final answers reach the team lead, background subagents can reply to unnamed sibling or parent agents, and replies to cross-session messages delivered by Claude Desktop can route back through Desktop instead of failing as unreachable.
2.1.251 also changes CLAUDE_CODE_SUBAGENT_MODEL from an unconditional override to a default, allowing an agent definition’s model: or an explicit per-spawn model to win. Its --input-format stream-json fix prevents client-injected assistant tool calls without message ids from being merged together with later results lost, including on resumed older sessions.
The reviewed stable line extends that composition boundary materially. 2.1.257 adds a Containment Escape rule to auto mode and CLAUDE_CODE_SUBAGENT_MODEL_FORCE for installations that deliberately want one model choice to override per-spawn or agent-definition child models. 2.1.259 adds organization-managed HTTP/SSE managedMcpServers, unattended-host --permission-prompts none, fixes concurrent sessions clobbering shared ~/.claude.json state, preserves nested background-subagent results in the parent subagent transcript, and repairs remote/scheduled continuation after a connector-tool permission prompt is approved.
Claude Code 2.1.260, published 3 September, adds /reload-plugins to headless/Desktop/Agent SDK command surfaces and fixes SDK-provided MCP servers sometimes missing from the first turn. Its composition fixes wake a subagent when an agent it resumed through SendMessage completes, preserve agent-team transcript messages during long retry waits, remove phantom duplicate interactive entries for background sessions in ListAgents, prevent long context compaction from causing Workflow subagents to be restarted as stalled, and remove the previous one-hour time limit on background commands started by subagents.
Latest observed stable 2.1.261, published 4 September, extends host/composition fidelity again. bashOutputMaxChars and taskOutputMaxChars can keep command and background-task output inline up to 128K characters before file spillover, while --append-subagent-system-prompt-file supports child-system prompts too large for a command-line argument. Session resume now preserves hook output and surrounding parallel-tool-call context, SDK/cloud sessions honor a Stop or interrupt sent just after the first prompt even before the turn begins, failed background-agent resume wake-ups no longer spin at sustained high CPU, and terminal progress stays active while a background workflow or agent is genuinely still running.
The release also corrects coordination state: SendMessage to an offline Remote Control session reports queued delivery until the target reconnects instead of claiming success, and in-process agent-team teammates no longer resend their first-turn tool/skill announcements on the second turn, avoiding a request-prefix change that defeated prompt caching. These are meaningful composition/integration controls, but they remain Claude Code internals: UHP does not define the peer/subagent/Remote Control stream, managed-MCP policy, unattended-prompt mode, child-model precedence, internal output-spill thresholds, prompt-cache behavior or the mapping of those objects to UHP-visible tasks and sessions.
Hermes: isolated delegation and nested orchestration
Section titled “Hermes: isolated delegation and nested orchestration”Hermes exposes delegate_task, which spawns child agent instances with isolated conversation context, inherited allowed tool access and separate terminal sessions. Parallel batches are supported, and nested delegation is opt-in through an orchestrator role and configurable spawn depth. The stable v0.21.0 release also highlights live subagent steering, explicit stop/list controls, structured child-output validation and per-delegation cost reporting as part of the shipped delegation surface.
Hermes therefore demonstrates one composition style in which a parent harness remains the orchestrator while children operate in fresh contexts and return summarized results. delegate_task itself remains process-local delegation and should not be conflated with the separate gateway-owned hosted-room runtime described next.
Hermes reviewed main snapshot: fan-out resource ownership is converging from per-child to process/workspace scope
Section titled “Hermes reviewed main snapshot: fan-out resource ownership is converging from per-child to process/workspace scope”Hermes reviewed main snapshot gained a coordinated resource-scaling batch on 3 September 2026 that is directly relevant to high-fan-out composition. The delegation semantics did not change; the implementation instead removes several hidden O(N) resource multipliers where each child previously acquired its own process, transport, retained transcript or timer even when the underlying resource was safely shareable at process or workspace scope.
Five same-day upstream commits define the measured boundary:
- Multi-root LSP reuse —
80fae22b: multi-root servers such as Pyright are now keyed by server identity and attach newly encountered worktrees throughworkspace/didChangeWorkspaceFoldersinstead of launching another server per worktree. Upstream reports a profiled fan-out across roughly 30 worktrees moving from 30–60 Pyright processes (about 8.7 GB) to one. Single-root language servers retain per-workspace behavior. - Shared synchronous model transports —
c3b411df: per-agenthttpx.Clientwrappers now mount shared synchronous transport pools keyed by endpoint/verification/proxy identity. Request stamping preserves targeted socket shutdown so aborting one child does not tear down another child’s stream. In the 30-child benchmark, peak RSS fell 286→195 MB, liveHTTPTransportobjects 183→2, and connection pools 183→7. Async clients remain unshared because their pools are event-loop-bound; proxy-backed clients keep per-client proxy transports. - Finished-child heap release —
c96568f6: the subagent-parentContextVarnow retains a weak reference rather than strongly pinning a finished child through copied asyncio contexts, andAIAgent.close()drops two additional transcript-related snapshots. The motivating 1,320-child / 13-hour parent had reached 2.6 GB RSS. With padded replies in the 30-child / 10-worktree benchmark, live closed-childAIAgentobjects fell 14→0 and post-fan-out RSS 636→556 MB. - Selective trigram indexing —
2b55ded1: schema v30 keeps canonical child messages and the standard word FTS index but excludes cron/subagent sessions from the heavier trigram substring/CJK index, because normalsession_searchalready hides those sessions. The motivating database reached 3.4 GB, with 70% of message bytes from subagents; a fresh 2,000 × 2 KB child-message fixture fell 22.4→12.5 MB, while trigram shadow storage fell 10.09 MB→0.02 MB. - One periodic scheduler —
561b053f: delegate heartbeats, durable-turn lease refresh and turn-liveness watchdogs now schedule periodic ticks on one process-wide daemon thread instead of creating sleeping timer threads per child/active turn. A profiled roughly 130-child session had carried about 1,000 threads; the 30-child / 10-worktree benchmark moves peak threads 168→132, with 30 per-child heartbeat threads replaced by one shared scheduler.
The accompanying fan-out benchmark commit c77b9d63 measures threads, RSS, file descriptors, Pyright processes, kernels and HTTP clients across child/worktree fan-out. These numbers are upstream source-pinned benchmark and incident measurements, not independent production certification and not universal capacity guarantees.
The broader harness-engineering invariant is that parallel delegation needs resource ownership to match the resource’s true isolation domain. Child-specific state, cancellation and authorization still need child-specific fences, but process-global transports, multi-root language servers and periodic scheduling should not be multiplied just because child count increases. Finished children must also stop retaining heap/index state once their result has been durably projected back to the parent.
This is post-v0.21.0 Hermes reviewed-main implementation behavior, not a released Hermes version, not a UHP/ACP/A2A primitive, not native Hermes UHP adoption, and not evidence that HarnessRouter’s UHP→Hermes adapter exposes or independently validates these fan-out resource paths.
Hermes: gateway-owned hosted Group Chats in stable v0.21.0
Section titled “Hermes: gateway-owned hosted Group Chats in stable v0.21.0”Hermes v2026.8.31 / v0.21.0, published 31 August 2026, now ships the gateway-owned Bot Mode Group Chat topology previously tracked only on main: a hosted room can be owned and executed by the gateway rather than by the Desktop process that created it, and selected room members can be routed to trusted peer gateways. The release highlights Bot Mode as a first-class Desktop feature and rolls up the underlying gateway work described below.
The implementation is deliberately layered:
- Authority/replay — PR #99007: room identity, membership and an ordered event log live in the gateway’s root
state.db; server-issued authority combinesauthority_gateway_idwith a monotonicauthority_epoch, and stale writers are fenced. This layer exposed inertgroups.*RPCs while leaving the driver off. - Replication/takeover — PR #99047: participant gateways can persist authority-stamped replay pages, reject sequence gaps and epoch regressions, explicitly promote a replica at
epoch + 1, and fence a returning stale authority. Promotion requiresconfirm: true; the storage primitive does not itself decide when takeover is safe. - Same-gateway execution driver — PR #99099: the authority process owns durable task scheduling through task identities, leases, execution/cancel generations, discussion projection and policy checkpoints, and runs local member turns through real agent sessions.
groups.stop,groups.retryandgroups.approveare added to the control surface. Upstream reports 247 hosted-room tests passing for this driver layer, including a deterministic disband/cancellation race that failed 5/5 before the follow-up correction and then passed. - Scoped cross-gateway transport — PR #99244: the room authority can dispatch member turns to bots on another trusted Hermes gateway using signed, TTL-bounded grants scoped to the room, member and target. Peer capability state is digest-frozen into the authorization boundary; grant refresh refuses execution-policy drift with HTTP 403
room_reauthorization_required, and remote room execution is refused while the target gateway runs YOLO/approvals-off. The transport uses authenticated signed tasks, verified results, retry-safe identities and peer-stop acknowledgement. Upstream reports 283 hosted-room/transport/grant tests passing across ten suites, plus a sabotage-verified policy-drift regression test.
Cross-gateway mode is opt-in rather than ambient discovery. Operators configure a peer-reachable HTTPS gateway.room_link_url or HERMES_ROOM_LINK_URL; plain HTTP is accepted only for loopback testing. The API server key authorizes the initial invitation, while scoped grants use a separate installation-private signing secret. Disbanding a Group Chat revokes its known peer routes, but rotating the API key by itself does not revoke those grants. Upstream documentation also recommends limiting network reachability to trusted peer gateways.
The result is stronger than Desktop-hosted peer coordination: laptop, homelab and VPS-hosted bots can participate in one gateway-owned room while Desktop remains a viewer rather than the relay. The room authority therefore needs to live on a host the selected peer gateways can actually reach.
The boundary is equally important. PR #99047 still exposes explicit replica promotion/fencing, while PR #99244 adds direct authenticated peer execution. Those are different mechanisms and should not be upgraded into a claim that Hermes automatically migrates an active room across gateways after failure or provides a distributed-consensus layer.
From a UHP perspective, hosted room ids, authority epochs, room replay events, peer grants/routes and driver tasks are Hermes internals. The current UHP specification does not define a Group Chat resource, a mapping from those room/member tasks to UHP-visible sessions/tasks, or a standardized UHP↔Hermes hosted-room binding.
Hermes: ACP-connected agents as providers in stable v0.21.0
Section titled “Hermes: ACP-connected agents as providers in stable v0.21.0”Upstream Hermes added another composition model on 26 August 2026: an ACP-connected CLI agent can act as a provider inside Hermes rather than ACP being treated as a Copilot-only special case. The path first shipped in v2026.8.27 / v0.20.6 and is now included in the latest stable v2026.8.31 / Hermes Agent v0.21.0 release. The v0.21.0 release explicitly rolls up the v0.20.1–v0.20.6 patch windows, and its annotated tag points to commit 29112bef.
The implementation has three relevant pieces:
- a shared ACP/OpenAI bridge carries allowed Hermes tool schemas through ACP’s text-oriented prompt/response boundary and parses Hermes-level tool calls back into the parent loop;
- generic
acp://runtime handling covers ACP clients as a class, keeping their one-shot subprocess completion shape away from incompatible Responses-API and iterable-stream assumptions; - an agent-as-provider projection path lets the provider return already-completed internal tool calls/results and a tool-iteration count. Hermes appends that work to its own transcript for memory/skill-review visibility instead of re-executing those finished child actions.
This is a stronger form of harness composition than simple summary-return delegation: the child agent retains its own execution loop while the parent Hermes runtime incorporates a safe projection of completed child activity into its own state.
Hermes: branch lifecycle is now bound to backend ownership on reviewed main snapshot
Section titled “Hermes: branch lifecycle is now bound to backend ownership on reviewed main snapshot”Hermes PR #100879, merged on 2 September 2026 as 2659c917, fixes a multi-backend Desktop failure in which branching a session owned by one gateway could create, resume or render the child through whichever gateway happened to be active. The concrete reproduction used a remote-owned parent while the local backend was active: before the fix the remote backend never received the branch create, the child eventually failed to load, repeated resume attempts could hit the tile resume-storm breaker, and a restart could lose the rowless branch.
The correction treats the execution owner as more than a profile name. In a multi-connection install, common profile names such as default are not globally unique, so branch routing now carries the full owner route — effectively connection plus profile — through the parent transcript read, child creation, optimistic row, owner hint, tile/socket hold and resume path. Project-scoped session rows are stamped with their profile, and a shared owner-resolution ladder prefers self-describing rows across Recents, cron, messaging and project-tree sources.
The persistence and concurrency edges are closed at the same seam. A seeded branch is explicit user intent, so session.create now persists its child row, lineage title and transcript immediately rather than waiting for the first prompt; a partial seed write is rolled back. Open owner-routed tiles pin the owning connection across unrelated reconnects, open tiles stay in the sidebar keep-set, and branch-create coalescing includes the owner so two different backends exposing the same parent session id cannot collapse into one child operation. Untagged parents preserve the existing ambient single-connection behavior.
Upstream reports a live two-gateway Desktop verification in which the remote backend received the create and completed the first child turn with the remote model/cwd, plus 214 targeted Desktop tests, the full 708-file Desktop UI suite green, 14 gateway branch/seed tests and 35 project-RPC tests. Those are upstream source/test results rather than an independent production certification.
For harness architecture, the reusable invariant is: a derived session must carry its execution-owner identity through every representation that can read, create, persist, resume, pin, coalesce or navigate it. A session id, profile label or current UI selection is not sufficient routing authority once multiple backends can expose overlapping identities.
This is post-v0.21.0 Hermes behavior on the reviewed development snapshot, not a released Hermes version, not a UHP/ACP/A2A protocol change, not native Hermes UHP adoption, and not evidence that HarnessRouter’s UHP→Hermes adapter uses or revalidates this Desktop branch path.
Hermes: multiplexed compaction now preserves profile secret scope on reviewed main snapshot
Section titled “Hermes: multiplexed compaction now preserves profile secret scope on reviewed main snapshot”Hermes PR #100950, merged on 2 September 2026 as c5c9aa8d, closes a separate multi-profile integrity defect in gateway session-hygiene compaction. Under gateway.multiplex_profiles, per-turn profile state such as the profile secret scope and HERMES_HOME override is carried in Python ContextVars. The hygiene path offloaded _compress_context through a bare run_in_executor(None, ...) worker, so that worker started without the caller’s execution context.
The consequence was fail-closed credential lookup followed by unsafe state loss. When the summary model called get_secret(<PROVIDER>_API_KEY), the missing scope raised UnscopedSecretError; the summary became unavailable, and the compressor fell through to its lossy placeholder-and-drop path. The upstream debug evidence records repeated hygiene passes reducing 697→642 and 645→426 messages with no LLM summary.
The merged correction closes both sides of that seam:
- both gateway hygiene executor hops — the detached-agent and Codex app-server paths — now run the compression call inside
copy_context().run, preserving the caller’s profile scope while retaining the default executor so a fence-cancelled hung summary does not occupy a gateway agent-work slot; DaemonThreadPoolExecutor.submitnow propagates caller context variables by default as defense in depth for other pool consumers; andUnscopedSecretErroris reclassified as an access/credential failure, so compaction aborts and preserves the session unchanged rather than dropping the middle window when the summarizer cannot safely authenticate.
Upstream reports a real A/B in which scoped get_secret("SURPLUS_API_KEY") failed on the bare worker and returned the scoped value after the fix, plus 46 targeted tests across gateway hygiene, daemon-pool, secret-scope and access-failure paths. These are upstream source/test results rather than an independent production certification.
For harness architecture, the reusable rule is broader than Hermes: execution scope is part of execution authority. Profile-specific credentials, home/config roots and related policy context must cross every asynchronous or executor boundary that performs state mutation or summarization; if a summary step loses that authority context, the safe fallback is to preserve canonical session state rather than silently discard it.
This is post-v0.21.0 Hermes behavior on the reviewed development snapshot, not a released Hermes version, not a UHP/ACP/A2A protocol change, not native Hermes UHP adoption, and not evidence that HarnessRouter’s UHP→Hermes adapter invokes or independently validates this internal hygiene-compaction path.
Hermes: single-use OAuth grants now keep one root authority on reviewed main snapshot
Section titled “Hermes: single-use OAuth grants now keep one root authority on reviewed main snapshot”Hermes PR #100929, merged on 2 September 2026 as 37f3ba11, closes a credential-ownership defect in named profiles. Anthropic, OpenAI Codex and xAI OAuth use single-use refresh grants: copying one grant into multiple profile stores does not create independent credentials, so the first profile to refresh a copied token can invalidate the copies still held by root and sibling profiles.
Current main now treats those grants differently from ordinary clonable profile data:
--clone-alland dashboard credential mirroring strip the affected OAuth pool rows and matching singleton/device-code state from the clone while continuing to copy static API-key rows;- a profile without its own grant borrows the root credential and writes rotations back to the root store under the root lock rather than materializing a local fork;
- an explicit
hermes -p <name> auth add <provider>still creates intentionally profile-owned authorization; and - an auto-heal path reconciles already-forked matching grants to the freshest known rotation at root and removes the profile copies, while preserving distinct-account or unmatched rows instead of guessing ownership.
Hermes’ current profile documentation now states this policy directly: Claude Pro/Max, Codex and xAI OAuth logins are shared from root, not copied. PR #100929 reports 15 dedicated real-file tests, wider credential/profile suites of 226 passed / 2 skipped and 282 passed, sabotage checks and a live single-use-token reproduction in which the corrected topology performs one rotation with no reuse of the spent root token.
For harness architecture, the reusable invariant is credential authority continuity: isolating or cloning runtime state must not split ownership of a non-forkable credential. A derived profile can borrow one authoritative grant without owning a duplicate, and refresh/rotation state must persist at the authority every borrower resolves.
This is post-v0.21.0 Hermes behavior on the reviewed development snapshot, not a released Hermes version, not a UHP credential/authentication primitive, not an ACP/A2A protocol change, not native Hermes UHP adoption, and not evidence that HarnessRouter’s UHP→Hermes adapter uses or independently validates this profile-auth path.
Harn: accepted steering now participates in completion authority on reviewed main snapshot
Section titled “Harn: accepted steering now participates in completion authority on reviewed main snapshot”Harn reviewed main snapshot merged PR #7785 on 1 September 2026 as 8d87d43d, fixing a control-plane mismatch exposed by a real mid-run steering repro. Before the change, an accepted session/inject steer reached the model conversation but not the completion judge: the judge continued evaluating the immutable task captured at session start, so it could reject a stop the user had just authorized and order withdrawn work to be redone.
The merged correction introduces a typed CompletionObligations value at the decision seam:
- the completion authority derives one obligation set from the original task plus accepted steering events;
- accepted steers are identified structurally from the host bridge’s typed delivery mode rather than inferred from transcript position or prose;
- later steering is rendered after the original goal/rubric/requirements with explicit supersession semantics, so narrowing or canceling work changes what the completion judge may still require; and
- terminal evidence identity includes an obligations digest, so two completion decisions that differ only by accepted steering cannot reuse the same evidence identity.
Upstream reports 9/9 steering-seam tests, 491/491 Harn tests and 12,836/12,836 workspace tests passing, plus lint/format/drift checks. The PR also keeps the no-steer path byte-stable and preserves the judge’s ability to veto an unverified stop.
The residual boundary matters. Open P1 issue #7580 remains unresolved: session/inject mode:"steer" still does not retarget the typed GoalSpec.objective or retire frozen success_criteria. In other words, #7785 fixes the exit/completion-authority half of steering, but later model-facing prompts can still carry the pre-steer goal until Harn gains an explicit goal-update control. The PR itself calls this out rather than claiming full steer retargeting.
For harness architecture, this makes a useful distinction explicit: accepting a control event is not enough; every authority that can continue, stop, judge or attest the run must consume the same accepted control state. Completion obligations and model-facing goals are related but separate state machines, and partial convergence can still produce contradictory behavior.
This is post-v0.10.125 Harn behavior on the reviewed development snapshot, not a released Harn version, not an ACP/A2A/UHP wire-semantics change, not a UHP steering primitive, and not evidence of native Harn UHP adoption or a HarnessRouter Harn backend.
Pi: extension-level subprocess delegation
Section titled “Pi: extension-level subprocess delegation”Pi ships a documented Subagent Example extension at v0.84.3. Each child runs as a separate pi process with an isolated context window. The example supports single-agent execution, parallel batches and sequential chains, with usage accounting and abort propagation.
The maturity boundary matters: this is a shipped example extension demonstrating the pattern, not evidence that UHP, ACP or another interoperability protocol is required by Pi’s core runtime.
Composition dimensions
Section titled “Composition dimensions”The implementations above show that “subagent” is not one transport or one protocol. Useful dimensions include:
| Dimension | Common choices |
|---|---|
| Process topology | Same process, child process, gateway-owned room, peer process/session, remote process/service |
| Runtime identity | Same harness family, differently configured instance, different harness product |
| Context model | Fresh context, forked history, named persistent task, durable room log, independent peer session, explicitly passed task/context |
| Delegation transport | Internal API, same-machine message bus, signed gateway-to-gateway room transport, SDK/process bridge, ACP, an A2A client surface, or another protocol |
| Scheduling | Single child, parallel fan-out, sequential chain, nested orchestration, concurrent named-task execution/switching, durable room scheduling, peer coordination |
| Capability boundary | Inherited tools, restricted child tools, provider-specific permissions |
| Result model | Final summary, structured result, named persisted session, room event/log state, peer message, streamed progress, persisted child session |
| Resource ownership | Per-child isolation where required; shared process/workspace pools where identity and cancellation remain safely fenced |
A system can combine several choices. “Multi-agent” alone therefore says little about interoperability unless the child/peer/task boundary and lifecycle are identified.
Where UHP stops
Section titled “Where UHP stops”UHP’s role remains outside this internal topology. A UHP client selects a configured harness and receives a standard task/session/file/event lifecycle from the UHP server. The current specification does not define:
- how many child agents a harness may spawn;
- how a harness partitions multiple named internal tasks for one human/channel interaction;
- whether a harness maintains a durable internal room authority/replay/replication/peer-route graph;
- whether peer harness sessions can discover or message one another;
- whether children share or fork context;
- which child protocol or SDK is used;
- how nested-agent budgets or concurrency trees are represented;
- whether a child is another instance of the same harness or a different product;
- how internal child/peer/named-task/room sessions map to the externally visible UHP session.
That separation is useful. A server can preserve one stable UHP contract even as the selected harness changes its internal orchestration strategy.
ACP can be an inner boundary without becoming UHP
Section titled “ACP can be an inner boundary without becoming UHP”There are now two concrete upstream composition examples:
- DeepSeek Harness can start an out-of-process child through its
subagent-acpprovider. - Hermes
v0.21.0can use ACP-connected CLI agents as provider runtimes and project their completed internal tool work back into the parent Hermes transcript; that ACP path first shipped inv0.20.6and remains part of the latest stable release.
Separately, HarnessRouter can run both DeepSeek Harness and Hermes as UHP backends. Those facts must not be collapsed into a protocol claim. A UHP request routed through HarnessRouter to one of those harnesses does not imply that ACP is part of UHP, that every task uses ACP, or that HarnessRouter’s UHP implementation depends on ACP. ACP is one possible internal child/provider boundary selected by the harness.
See UHP vs ACP for the protocol-level comparison.
A2A CLI can be an inner remote-agent boundary
Section titled “A2A CLI can be an inner remote-agent boundary”The A2A Project now maintains an official A2A CLI (a2a) specifically as a standardized command-line client for A2A agents. Its independent CLI specification is currently v0.2 in Review / pre-Proposed state, applies to A2A Protocol v1.0, and explicitly says it constrains CLI behavior rather than changing A2A wire semantics. The project published stable software v0.2.0 on 9 September 2026, while the CLI specification remains Review/pre-Proposed; software-release maturity and specification maturity are separate coordinates.
The released CLI is directly relevant to harness composition because it treats AI coding agents as first-class callers and defines a bundled SKILL.md descriptor so a coding harness can delegate work to an A2A agent without a harness-specific plugin. The CLI resolves Agent Cards, negotiates among JSON-RPC, HTTP+JSON and gRPC, and defines cumulative capability tiers plus a separate compliance model for CLI behavior.
That creates a practical inner-boundary pattern:
UHP client → UHP server → selected coding harness │ │ skill / `a2a` CLI ▼ remote A2A agentThis is still composition, not protocol fusion. If a UHP-served harness invokes the A2A CLI internally, UHP remains the outer harness-execution contract and A2A remains the remote-agent contract. The CLI does not establish a standardized UHP↔A2A binding, and its own conformance model applies to the CLI surface rather than UHP server conformance.
See A2A CLI and UHP for the release/tooling boundary and UHP vs A2A for the protocol-level comparison.
Team-level composition: Switch collaboration fabric
Section titled “Team-level composition: Switch collaboration fabric”A different composition pattern appears in Switch, an open human-and-agent collaboration framework maintained in sandbox-quantum/switch. Instead of one parent harness spawning children, Switch places multiple people and heterogeneous agents into shared rooms and workflows that can be bridged to Slack, Microsoft Teams, Discord, Telegram and Mattermost. Its README explicitly names Claude Code, Codex and OpenCode among the agent runtimes it can connect.
Switch is important here because it defines a separate Switch Agent Protocol between switch-core and its agent-runtime. The current artifact registry separates product versions from compatibility contracts: switch-core is 0.21.0, Switch Console is 0.31.2, agent-runtime is 0.3.3, while the agent-protocol compatibility contract remains revision 1 on both core and runtime. The protocol covers the event stream, frame shapes, resume cursor and tool-call channel; the project README describes agent→Switch traffic over HTTP and Switch→agent delivery over SSE. Provider connectors commonly combine a local MCP server with a skill that teaches the agent the Switch protocol.
This is team-level harness composition, not another subagent protocol. The collaboration fabric can coordinate multiple independently running harnesses and human participants while keeping their native execution loops intact. Its Matrix/Tuwunel-backed room model, roles, permissions, tracked tasks and messaging-app bridges sit around those runtimes rather than replacing them.
The distinction is useful for architecture: UHP normalizes how a product drives a complete harness; Switch normalizes how people and multiple agent runtimes participate in a shared collaboration fabric. A system could theoretically use both at different boundaries, but that composition is not standardized by either project today.
Adoption and conformance boundary
Section titled “Adoption and conformance boundary”UHP conformance evaluates the server-visible UHP behavior. Internal child/peer/task/room topology can affect whether the implementation ultimately behaves correctly, but the current 64-check suite does not standardize or certify the harness’s internal orchestration graph.
Why the pattern matters for harness engineering
Section titled “Why the pattern matters for harness engineering”Harness composition changes several practical design questions:
- Context isolation: delegated children, named task partitions and peer sessions can protect the initiating context from large intermediate traces.
- Model specialization: workers can use different models or configurations from the parent planner.
- Capability control: a child or peer can receive a narrower tool/permission surface.
- Resource scaling: high fan-out should share process/workspace-global resources where safe, while preserving per-child ownership for cancellation, authorization and mutable execution state; finished children must release retained heap/index state instead of leaving hidden O(N) multipliers.
- Execution-scope propagation: profile-specific credential, home/config and policy context must survive background, thread and executor hops that can mutate or summarize session state; otherwise the worker may act under the wrong authority or silently degrade state.
- Credential authority: copied or derived profile state must not fork a single-use refresh grant merely because the runtime state is isolated; one grant needs one authoritative persistence owner unless an explicitly separate login creates separate authority.
- Control authority: an accepted steer, cancel or scope change must reach every component that can continue, stop, judge or attest the run; otherwise different control-plane authorities can enforce different task obligations.
- Failure semantics: child/peer cancellation, timeout, crash, task switching, owner-route drift, hosted-room takeover, peer reachability/reauthorization and partial-result behavior need explicit handling.
- Auditability: observability must distinguish parent work from child/peer/named-task/room work and preserve causal relationships.
- Interoperability boundaries: protocols such as MCP, ACP or A2A may appear inside the harness while UHP remains the external execution contract.
These concerns are implementation architecture today, not a new UHP conformance class.
Related pages
Section titled “Related pages”Read Codex for the current same-harness task delegation surface, Qwen Code for stable named Channel tasks plus 31 Aug nightly concurrent control and daemon sessions, Claude Code for peer-session messaging, managed MCP and current subagent durability, DeepSeek Harness for cross-harness implementation, Hermes and Pi for other harnesses, A2A CLI for the official client tooling surface, UHP vs ACP and UHP vs A2A for protocol boundaries, UHP vs ATIF for whole-run trajectory interchange, and UHP architecture for the normative Client/Server/Harness model.
Primary sources
Section titled “Primary sources”- OpenAI Codex
0.150.0release - OpenAI Codex PR #40308 — TUI task management/delegation tools
- OpenAI Codex PR #40315 — task mentions
- OpenAI Codex PR #40511 —
Interrupthooks - Qwen Code
v0.22.3release - Qwen Code 31 Aug nightly prerelease
- Qwen Code PR #10198 — owner-scoped named Channel tasks
- Qwen Code PR #10574 — concurrent named Channel task control
- Qwen Code concurrent named-task merge —
8ca93b49 - Claude Code
v2.1.261release - Claude Code changelog at
v2.1.261 - Claude Code
v2.1.260release - Claude Code changelog at
v2.1.260 - Claude Code
v2.1.251release - Claude Code
v2.1.248release - DeepSeek Harness
v0.1.0-rc.8release - DeepSeek Harness subagent capability family
- DeepSeek Harness base bundle and optional product-provider boundary
- Hermes: Subagent Delegation
- Hermes: Delegation & Parallel Work
- Hermes
v2026.8.31/ v0.21.0 release - Hermes v0.21.0 release PR #99718
- Hermes fan-out resource benchmark —
c77b9d63 - Hermes multi-root Pyright reuse —
80fae22b - Hermes shared sync HTTP transport pools —
c3b411df - Hermes finished-child heap release —
c96568f6 - Hermes schema-v30 subagent trigram-index exclusion —
2b55ded1 - Hermes shared periodic scheduler —
561b053f - Hermes hosted-room authority/replay PR #99007
- Hermes hosted-room replication/takeover PR #99047
- Hermes same-gateway hosted-room driver PR #99099
- Hermes cross-gateway hosted-room transport PR #99244
- Hermes cross-gateway transport implementation —
e743391 - Hermes scoped-grant drift safeguard/current merge —
1cf3639 - Hermes shared ACP/OpenAI bridge —
083c592 - Hermes generic ACP runtime handling —
613164d - Hermes agent-as-provider projection —
07200e9 - Hermes PR #100879 — branched session loads on the backend that owns its parent
- Hermes branch-owner merge —
2659c917 - Hermes PR #100950 — multiplexed hygiene compaction preserves profile secret scope
- Hermes compaction-secret-scope merge —
c5c9aa8d - Hermes PR #100929 — single-use OAuth grants stay root-owned across profiles
- Hermes single-use OAuth grant-authority merge —
37f3ba11 - Hermes profiles documentation — OAuth logins are shared, not copied
- Harn v0.10.125 release
- Harn PR #7785 — accepted steering updates completion obligations
- Harn merge
8d87d43d - Harn open P1 #7580 — steer does not yet retarget
GoalSpec - Pi v0.84.3 Subagent Example
- Official A2A CLI repository
- A2A CLI
v0.2.0release - A2A CLI
v0.2specification atv0.2.0 - A2A CLI
v0.2compliance model atv0.2.0 - A2A CLI bundled Agent Skill at
v0.2.0 - Switch repository and architecture README
- Switch artifact/version and contract registry
- Switch changelog
- UHP 2026-08-11 architecture