You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Integrate the existing Copilot wrapper handoff and executor-backed stdio MCP ownership without replacement APIs or cross-machine compiled policy.
Scope
Implement only commit 8 of the approved design. Preserve the contracts below exactly; local and remote behavior must remain compatible.
Implementation Commit Mapping
This issue implements Commit 8 — Integrate Copilot wrapper and stdio MCP ownership from exact design commit 0c6578641befad31d5a38003baf6c0f0fe64748a.
Commit 8 - Integrate Copilot wrapper and stdio MCP ownership
Files: existing #1476CopilotRuntimeConnectionFactory handoff and #1477 ProcessExecutorBackedClientTransport/ProcessOwnedMcpTransport integration only; no replacement
types. Tests: direct versus wrapper selection, stdio ownership, constrained HTTP/SSE rejection,
fail-closed launch, sanitized projection, and no compiled policy on a machine frame. Dependencies: Commit 7 and #1473-#1477.
Applicable product requirements
Full-remote AgentChat
The owning host constructs the real AgentChat, its AgentServices, persistence services, tool providers, and current-session identity from that host's WorkspaceEntitySession / CurrentSessionContext.
The owning host resolves executor bindings and routes each component to its selected execution host.
The host that actually launches a process resolves the referenced effective TrustProfile, checks the expected revision, compiles MXC locally, and launches through the shared process executor.
A local proxy mirrors history, queue state, streaming state, busy state, tools, subagents, modals, and errors. It submits user input through the common queue API and forwards modal responses and interrupt/terminate requests.
The proxy does not launch remote Copilot, stdio MCP, or tool subprocesses and must never claim to enforce their containment.
Opening a remote subagent creates another authorized proxy to the remote subagent; it does not re-parent the subagent locally.
Split-client topology
The topology in remote-chat-client-session.md remains distinct: the local host owns AgentChat, while a remote model host owns the Copilot client/process.
In split-client mode, the remote model host resolves and compiles MXC for the Copilot process. Each tool's selected executor host independently resolves and compiles MXC for subprocesses it launches.
Component executor bindings from per-component-executor-binding.md remain the source of execution placement. Agent ownership does not override an explicit component binding.
GUI-only and entity-only tools remain in-process application-authorization surfaces. They are not process launches and must not be represented as MXC-contained.
Tool-schema authorization, client-instance authorization, and MXC confinement are cumulative and remain separate.
Security and failure semantics
attach-agent-session authenticates the transport peer and authorizes that peer for the requested owning profile and session before revealing whether the session exists.
Attach authorization is evaluated on every initial attach, reconnect, child-subagent attach, mutation verb, and takeover request. Existing execution-target reachability alone is not sufficient proof of session access.
MXC does not authorize attach, and transport authorization does not sandbox processes.
A required containment compile, handoff, wrapper, or launch failure fails closed. No layer retries with a null policy or direct uncontained launch.
Host-local details remain in protected logs. Wire errors contain only a stable error code, safe operation category, retryability, user-safe message, and correlation id. They exclude policy JSON, grants, local paths, environment values, command arguments, stderr containing secrets, native handles, and credentials.
operation-error terminates the affected operation without necessarily terminating the owning session. A fatal runtime error additionally emits session-terminal.
MXC is a preview dependency and must not be described as a production-grade security boundary.
Non-goals
Discovering every running session on every profile.
Migrating live AgentChat, process handles, wrapper handoffs, or compiled MXC state between hosts.
Sending compiled MXC policy across transport.
Replacing transport authentication with containment or replacing application authorization with MXC.
Sandboxing in-process GUI/entity operations.
Merging full-remote and split-client topologies into one ambiguous mode.
Replacing ConPTY or containing processes Phantom does not launch.
API and protocol guardrails
API shape convention
Every method and constructor in this design is audited for call-site clarity. A method with four or
more independent arguments (including similarly typed identifiers), or any method whose positional
arguments are easy to transpose, takes one property-based *Request or *Options value plus an
optional CancellationToken. Small cohesive operations remain direct, for example ConnectAsync(AgentSessionOpenRequest request, CancellationToken ct = default).
Request/options and data records use object initializers. Semantically required members are required init; optional members have explicit defaults. Constructors are reserved for enforcing a
scalar value invariant or receiving a small cohesive set of services.
Protocol DTOs are property-based records with required init payload members. Their fixed Type
discriminator is initialized by the concrete DTO and is not caller-selectable. This changes only
the C# construction shape: version-1 kebab-case JSON names, required/optional wire members,
discriminators, strict unknown-member rejection, and semantics remain unchanged.
The complete design contains exactly 28 request/options types: 22 public and 6 internal. This issue introduces no replacement request/options type and does not change that count. In particular, there is no InterruptAgentSessionRequest; the client API remains Task InterruptAsync(Guid commandId, CancellationToken ct = default).
The shared snapshot state used by reconnect and wire projections retains these exact public property-based definitions and semantics:
The two state values are New public readonly record structs in Phantom.Workspaces.Llm.Core/IAgentChat.cs, with exactly these public names, fields, types, and
semantics:
Usage permits null for a metric the provider did not report; counts must otherwise be nonnegative
and cost remains a nonnegative double measured in USD. AgentInformation requires non-null,
nonblank values for its first five strings and a non-null complete AgentDefinition; CurrentModelId is null or nonblank. Required members provide compile-time construction checks;
local publishers and the protocol codec validate value invariants before accepting,
serializing, or publishing them. Local implementations build a complete replacement value before
publishing it. Proxy implementations deserialize and validate a complete replacement value before
one foreground assignment. UsageChanged and InformationChanged are raised only after that atomic
assignment, once per applied session sequence; observers never see fields from different versions.
Record equality is the intended value equality.
Both records use the existing JSON options and kebab-case protocol naming. After authorization, the
owner serializes the full definition with AgentDefinition.ToJson() and the client deserializes it
with PhantomAgentSchema.AgentDefinitionFromJson(string). Every authorized attached GUI receives
the same complete definition in AgentInformation; this is mandatory protocol state, not an
optional capability. Authorization completes before runtime lookup, snapshot construction, or
definition serialization. An unauthorized peer receives only the indistinguishable sanitized
denial and no session metadata, definition bytes, existence signal, or redacted AgentInformation.
No field-level redaction is applied after authorization.
Containment relationship and background
Relationship to MXC process containment
Remote ownership and containment compose as three axes:
Axis
Decision
Authority
Agent placement
Which host owns AgentChat and publishes its event stream?
For full-remote operation, the owning host constructs AgentChat and routes components. If it launches Copilot or stdio MCP locally, it resolves and compiles there. If a binding sends a component to another host, that final host resolves and compiles there. The viewer never supplies a compiled policy.
For split-client operation, local AgentChat owns routing and persistence, the remote model host confines Copilot, and each tool executor confines its own subprocesses. The same launch-host rule applies even though no full-session proxy is involved.
The only approved serialization of MxcProcessPolicy is the protected, one-use, same-machine Copilot wrapper handoff in #1476. Machine boundaries carry stable trust-profile identity/revision and component binding intent, never compiled policy or runtime handles.
Session lease owns children; the final released attachment stops it by default.
Errors
Sanitized ordered protocol events
Structured local compiler/executor diagnostics
Map detailed host error to safe wire DTO with correlation id.
Security
Peer/session attach authorization
Filesystem/network process confinement
Both checks are required and neither substitutes for the other.
The relevant resolved impedance mismatches remain:
Connection descriptors select a host, while MXC policy is host-specific. Resolution: persist descriptors and trust references/revisions. The selected launch host resolves, canonicalizes, compiles, and applies policy locally.
Viewer/channel disposal must normally stop an unobserved remote session without making transient network loss destructive. Resolution: separate RemoteAgentSessionLease from RemoteAgentAttachmentLease, count logical viewers under the runtime lifecycle gate, and reserve an unexpectedly lost attachment for five seconds. Final explicit detach, or grace expiry with continue-in-background == false, gracefully stops the runtime; the persisted opt-in is the only ordinary zero-viewer retention path.
Takeover wants continuity, while confinement contains host-local paths, capabilities, temp directories, and handles. Resolution: transfer persisted history and stable intent only. Terminate the old runtime, advance ownership generation, rebuild services, and compile fresh policy on the new host.
Transport errors need useful UI messages, while MXC diagnostics may expose paths or policy details. Resolution: map local diagnostics to RemoteAgentOperationError; retain details under a correlation id in host logs.
Full-remote routing may include GUI/entity tools that are not child processes. Resolution: route them according to the application/component binding and enforce normal application authorization. Do not fabricate an MXC guarantee for in-process code.
Interrupt and shutdown have different child-process consequences. Resolution:interrupt cancels the active turn while retaining the runtime and reusable clients; terminate-session releases the runtime lease and disposes all process-backed resources.
Detailed design
MXC/executor-facing types - Existing plans, integrated without parallel APIs
ExecutorBindings - Existing from the component-binding design, public sealed record in Phantom.Workspaces.Llm.Core.Manifest, Phantom.Workspaces.Llm.Core/Manifest/ExecutorBindings.cs. Remote integration adds no member and
calls existing JsonElement ResolveComponent(string? executorName), ExecutorTopology ToTopology(), and JsonElement ToPersistableMap(). Resolution is deterministic and local; unknown names throw and
no transport is opened.
AgentExecutionTrustContext - New in [mxc] - Execute MCP tools through MXC-constrained process executor #1477, public sealed class in Phantom.Workspaces.Llm.Trust, Phantom.Workspaces.Llm.Core/Trust/AgentExecutionTrustContext.cs. Remote integration adds no
parallel context. Its consumed operation is ValueTask<TrustProfileProcessPolicyCompilation> GetCompilationAsync(CancellationToken ct = default). The first caller resolves the expected revision and compiles on the launch host;
concurrent callers share the result. Caller cancellation stops only that wait after work starts.
Missing/stale profiles and compiler errors are cached failures for the runtime epoch.
ITrustProfileProcessPolicyCompiler, TrustProfileProcessPolicyCompilation, and MxcProcessPolicy - New in [mxc] - Compile effective trust profiles into MXC sandbox policies #1475, public interface
and immutable records in Phantom.Workspaces.Llm.Trust, Phantom.Workspaces.Llm.Core/Trust/ITrustProfileProcessPolicyCompiler.cs and MxcProcessPolicy.cs. Exact consumed signature: TrustProfileProcessPolicyCompilation Compile(TrustProfile effectiveProfile). It validates a
nonnull composed profile, performs no launch, and returns either uncontained, a complete policy,
or diagnostics; required-policy failure is never interpreted as uncontained.
IProcessExecutor, ProcessExecutionRequest, and IProcessHandle - New in [mxc] - Streaming process executor backed by MXC #1474, public
interface/records in Phantom.Workspaces.Processes, Phantom.Workspaces.Processes/IProcessExecutor.cs. Exact consumed signatures are Task<IProcessHandle> StartAsync(ProcessExecutionRequest request, CancellationToken ct = default), Task<ProcessExitResult> WaitAsync(CancellationToken ct = default), Task TerminateAsync(CancellationToken ct = default), and ValueTask DisposeAsync().
Start cancellation owns and cleans any partial process; wait cancellation does not transfer
ownership; terminate and disposal are idempotent and kill the tree. An MXC launch failure never
retries ordinary execution.
CopilotRuntimeConnectionFactory and CopilotLaunchPolicyEnvelope - New in [mxc] - Launch copilot.exe through the MXC process executor #1476, public
sealed class/internal strict handoff record in Phantom.Workspaces.Llm.Copilot, Phantom.Workspaces.Llm.Core/Copilot/CopilotRuntimeConnectionFactory.cs. Exact integration method: Task<CopilotRuntimeConnectionLease> CreateConnectionAsync(AgentExecutionTrustContext trustContext, string? cliPath, CancellationToken ct = default). It returns one async-disposable direct-or-wrapper
connection lease per CopilotSdkChatClient; constrained mode writes a protected one-use local
envelope. Cancellation/failure deletes unconsumed files. The lease, envelope, policy, and path
never cross machine transport. CopilotRuntimeConnectionLease is the New in [mxc] - Launch copilot.exe through the MXC process executor #1476 public sealed async-disposable result in
the same file; it exposes RuntimeConnection Connection { get; } and idempotent ValueTask DisposeAsync(). Disposal deletes only an unconsumed handoff and never kills an
SDK-owned runtime after ownership has transferred.
ProcessExecutorBackedClientTransport and ProcessOwnedMcpTransport - New in [mxc] - Execute MCP tools through MXC-constrained process executor #1477, public
sealed IClientTransport and internal sealed ITransport decorator in Phantom.Workspaces.Llm.Core/Mcp/ProcessExecutorBackedClientTransport.cs. Exact public members are string Name { get; } and Task<ModelContextProtocol.Protocol.ITransport> ConnectAsync(CancellationToken cancellationToken = default). Connect is single-use, always launches via IProcessExecutor, separates stderr, and
returns the process-owning transport. Its DisposeAsync() closes MCP/stdin, kills a still-running
tree, and drains exit/stderr tasks. A non-final viewer detach does not dispose it; final detach
reaches it only through graceful runtime stop when background continuation is disabled.
Effective trust resolution is host-local: the persisted reference/revision is resolved/composed,
then Compile is called. Missing/stale references, unavailable MXC, compiler failure, wrapper
failure, or executor failure never downgrade to null policy or direct launch.
Data flow
Create/persist. The creator persists owner, generation, executor bindings, and trust
reference/revision. No runtime policy is persisted.
Hydrate.RunningAgentChatTable.AcquireAsync calls the runtime-context factory once at first
materialization and merges the result into a new AgentServices record. The owning host creates CurrentSessionContext from its own profile/user/computer, never from viewer claims.
Open. The client opens a message channel with the strict open descriptor. The listener obtains
authenticated peer identity and the host authorizes before runtime lookup.
Start/attach. The registry single-flights runtime creation. An attachment subscribes before
snapshot capture. The host sends a retained replay only when the supplied cursor is fully covered;
otherwise it sends one authoritative snapshot.
Mutate. Each command is reauthorized and deduplicated, then checked against current
generation+epoch. The host mutates the real AgentChat, appends the resulting event under the
runtime scheduler, and broadcasts it in sequence.
Queue and steer. Every user input, including one intended to affect an active run, is an enqueue-input command against a stable target queue and expected aggregate revision. The owner assigns the
item id, applies once, acknowledges, and broadcasts queue-changed. Based on current-run state,
queue immediacy, and mode, owning AgentChat may consume the item immediately through the
internal Copilot path; that consumption is another ordered queue delta. Otherwise the item
remains for a tool boundary or future turn. The remote GUI never invokes Copilot and there is no
steering command.
Reconnect. The proxy keeps only its cursor and persisted open request. Reconnect reauthorizes
and reuses the runtime. A snapshot includes Usage, AgentInformation, and all queue snapshots;
retained replay applies queue deltas by epoch/global sequence. It neither reconstructs AgentChat nor relaunches children.
Take over. The old host fences mutations and confirms complete runtime disposal. Persistence
compare/exchanges owner and increments generation. The new host hydrates and starts a fresh epoch.
Failure to confirm an unexpired old lease blocks takeover.
Detach/stop. Explicit detach, proxy disposal, UI tab close, and viewer-application shutdown
release immediately; transport loss reserves the attachment token for five seconds. On final
release, continue-in-background == false fences and gracefully stops the runtime. Explicit
terminate, takeover, owner-host shutdown, or runtime-lease expiry always fences and stops it.
Stop rejects mutations, interrupts the active turn if required, disposes the chat, component
transports, MXC/process leases, wrappers, process-owned MCP transports and child trees, persists
terminal/stopped state, emits terminal where the channel remains writable, and closes channels.
This matrix also consumes the public-method tests owned by #1474-#1477: Compile_* in MxcTrustProfilePolicyCompilerTests, ProcessExecutor_*/ProcessHandle_*, CreateConnection_* in CopilotRuntimeConnectionFactoryTests, ConnectAsync_*/DisposeAsync_* in ProcessExecutorBackedClientTransportTests, and RemoteStdio_* in RemoteMcpHostHandlerTests. Those APIs are not duplicated here.
Remote integration additionally requires:
GetCompilationAsync_ConcurrentCallers_ResolveAndCompileOnce in AgentExecutionTrustContextTests.
GetCompilationAsync_StaleRevision_CachesFailClosedResult in AgentExecutionTrustContextTests.
StartAsync_CancelledDuringLaunch_CleansPartialProcess and TerminateAsync_RepeatedCall_KillsTreeOnce in ProcessExecutorTests.
WaitAsync_Cancelled_DoesNotReleaseProcessOwnership in ProcessHandleTests.
CreateConnectionAsync_ConcurrentLifecyclePaths_ReturnsOneSelection and CreateConnectionAsync_Cancelled_RemovesUnconsumedEnvelope in CopilotRuntimeConnectionFactoryTests.
DisposeAsync_UnconsumedHandoff_DeletesFileOnce and DisposeAsync_TransferredConnection_DoesNotKillSdkRuntime in CopilotRuntimeConnectionFactoryTests.
Name_ConstructedTransport_ReturnsConfiguredName in ProcessExecutorBackedClientTransportTests.
Part of #1483
Summary
Integrate the existing Copilot wrapper handoff and executor-backed stdio MCP ownership without replacement APIs or cross-machine compiled policy.
Scope
Implement only commit 8 of the approved design. Preserve the contracts below exactly; local and remote behavior must remain compatible.
Implementation Commit Mapping
This issue implements Commit 8 — Integrate Copilot wrapper and stdio MCP ownership from exact design commit
0c6578641befad31d5a38003baf6c0f0fe64748a.Commit 8 - Integrate Copilot wrapper and stdio MCP ownership
Files: existing #1476
CopilotRuntimeConnectionFactoryhandoff and #1477ProcessExecutorBackedClientTransport/ProcessOwnedMcpTransportintegration only; no replacementtypes.
Tests: direct versus wrapper selection, stdio ownership, constrained HTTP/SSE rejection,
fail-closed launch, sanitized projection, and no compiled policy on a machine frame.
Dependencies: Commit 7 and #1473-#1477.
Applicable product requirements
Full-remote
AgentChatAgentChat, itsAgentServices, persistence services, tool providers, and current-session identity from that host'sWorkspaceEntitySession/CurrentSessionContext.TrustProfile, checks the expected revision, compiles MXC locally, and launches through the shared process executor.Split-client topology
remote-chat-client-session.mdremains distinct: the local host ownsAgentChat, while a remote model host owns the Copilot client/process.per-component-executor-binding.mdremain the source of execution placement. Agent ownership does not override an explicit component binding.Process and non-process tools
ProcessExecutorBackedClientTransportfrom [mxc] - Execute MCP tools through MXC-constrained process executor #1477. A null policy selects the ordinary-process branch; a required policy selects MXC.Security and failure semantics
attach-agent-sessionauthenticates the transport peer and authorizes that peer for the requested owning profile and session before revealing whether the session exists.operation-errorterminates the affected operation without necessarily terminating the owning session. A fatal runtime error additionally emitssession-terminal.Non-goals
AgentChat, process handles, wrapper handoffs, or compiled MXC state between hosts.API and protocol guardrails
API shape convention
more independent arguments (including similarly typed identifiers), or any method whose positional
arguments are easy to transpose, takes one property-based
*Requestor*Optionsvalue plus anoptional
CancellationToken. Small cohesive operations remain direct, for exampleConnectAsync(AgentSessionOpenRequest request, CancellationToken ct = default).required init; optional members have explicit defaults. Constructors are reserved for enforcing ascalar value invariant or receiving a small cohesive set of services.
required initpayload members. Their fixedTypediscriminator is initialized by the concrete DTO and is not caller-selectable. This changes only
the C# construction shape: version-1 kebab-case JSON names, required/optional wire members,
discriminators, strict unknown-member rejection, and semantics remain unchanged.
from [mxc] - Streaming process executor backed by MXC #1474-[mxc] - Execute MCP tools through MXC-constrained process executor #1477 retain the signatures owned and tested by those designs. Neither case introduces a
new positional API in this design.
The complete design contains exactly 28 request/options types: 22 public and 6 internal. This issue introduces no replacement request/options type and does not change that count. In particular, there is no
InterruptAgentSessionRequest; the client API remainsTask InterruptAsync(Guid commandId, CancellationToken ct = default).The shared snapshot state used by reconnect and wire projections retains these exact public property-based definitions and semantics:
The two state values are New public readonly record structs in
Phantom.Workspaces.Llm.Core/IAgentChat.cs, with exactly these public names, fields, types, andsemantics:
Usagepermits null for a metric the provider did not report; counts must otherwise be nonnegativeand cost remains a nonnegative
doublemeasured in USD.AgentInformationrequires non-null,nonblank values for its first five strings and a non-null complete
AgentDefinition;CurrentModelIdis null or nonblank. Required members provide compile-time construction checks;local publishers and the protocol codec validate value invariants before accepting,
serializing, or publishing them. Local implementations build a complete replacement value before
publishing it. Proxy implementations deserialize and validate a complete replacement value before
one foreground assignment.
UsageChangedandInformationChangedare raised only after that atomicassignment, once per applied session sequence; observers never see fields from different versions.
Record equality is the intended value equality.
Both records use the existing JSON options and kebab-case protocol naming. After authorization, the
owner serializes the full definition with
AgentDefinition.ToJson()and the client deserializes itwith
PhantomAgentSchema.AgentDefinitionFromJson(string). Every authorized attached GUI receivesthe same complete definition in
AgentInformation; this is mandatory protocol state, not anoptional capability. Authorization completes before runtime lookup, snapshot construction, or
definition serialization. An unauthorized peer receives only the indistinguishable sanitized
denial and no session metadata, definition bytes, existence signal, or redacted
AgentInformation.No field-level redaction is applied after authorization.
Containment relationship and background
Relationship to MXC process containment
Remote ownership and containment compose as three axes:
AgentChatand publishes its event stream?attach-agent-sessionhostExecutorBindings/ connection descriptorTrustProfile+ #1475 compiler + #1474 executorFor full-remote operation, the owning host constructs
AgentChatand routes components. If it launches Copilot or stdio MCP locally, it resolves and compiles there. If a binding sends a component to another host, that final host resolves and compiles there. The viewer never supplies a compiled policy.For split-client operation, local
AgentChatowns routing and persistence, the remote model host confines Copilot, and each tool executor confines its own subprocesses. The same launch-host rule applies even though no full-session proxy is involved.The only approved serialization of
MxcProcessPolicyis the protected, one-use, same-machine Copilot wrapper handoff in #1476. Machine boundaries carry stable trust-profile identity/revision and component binding intent, never compiled policy or runtime handles.Overlap matrix
AgentChatprotocolExecutorBindingsresolves component connection descriptorsThe relevant resolved impedance mismatches remain:
Connection descriptors select a host, while MXC policy is host-specific.
Resolution: persist descriptors and trust references/revisions. The selected launch host resolves, canonicalizes, compiles, and applies policy locally.
[mxc] - Compile effective trust profiles into MXC sandbox policies #1475 defines a serializable
MxcProcessPolicy, which could be mistaken for a network DTO.Resolution: permit it only in-process and in [mxc] - Launch copilot.exe through the MXC process executor #1476's protected same-machine wrapper envelope. Remote contracts have no compiled-policy property and reject unknown attempts to add one.
Viewer/channel disposal must normally stop an unobserved remote session without making transient network loss destructive.
Resolution: separate
RemoteAgentSessionLeasefromRemoteAgentAttachmentLease, count logical viewers under the runtime lifecycle gate, and reserve an unexpectedly lost attachment for five seconds. Final explicit detach, or grace expiry withcontinue-in-background == false, gracefully stops the runtime; the persisted opt-in is the only ordinary zero-viewer retention path.Takeover wants continuity, while confinement contains host-local paths, capabilities, temp directories, and handles.
Resolution: transfer persisted history and stable intent only. Terminate the old runtime, advance ownership generation, rebuild services, and compile fresh policy on the new host.
Transport errors need useful UI messages, while MXC diagnostics may expose paths or policy details.
Resolution: map local diagnostics to
RemoteAgentOperationError; retain details under a correlation id in host logs.Full-remote routing may include GUI/entity tools that are not child processes.
Resolution: route them according to the application/component binding and enforce normal application authorization. Do not fabricate an MXC guarantee for in-process code.
Interrupt and shutdown have different child-process consequences.
Resolution:
interruptcancels the active turn while retaining the runtime and reusable clients;terminate-sessionreleases the runtime lease and disposes all process-backed resources.Detailed design
MXC/executor-facing types - Existing plans, integrated without parallel APIs
ExecutorBindings- Existing from the component-binding design, public sealed record inPhantom.Workspaces.Llm.Core.Manifest,Phantom.Workspaces.Llm.Core/Manifest/ExecutorBindings.cs. Remote integration adds no member andcalls existing
JsonElement ResolveComponent(string? executorName),ExecutorTopology ToTopology(), andJsonElement ToPersistableMap(). Resolution is deterministic and local; unknown names throw andno transport is opened.
AgentExecutionTrustContext- New in [mxc] - Execute MCP tools through MXC-constrained process executor #1477, public sealed class inPhantom.Workspaces.Llm.Trust,Phantom.Workspaces.Llm.Core/Trust/AgentExecutionTrustContext.cs. Remote integration adds noparallel context. Its consumed operation is
ValueTask<TrustProfileProcessPolicyCompilation> GetCompilationAsync(CancellationToken ct = default). The first caller resolves the expected revision and compiles on the launch host;concurrent callers share the result. Caller cancellation stops only that wait after work starts.
Missing/stale profiles and compiler errors are cached failures for the runtime epoch.
ITrustProfileProcessPolicyCompiler,TrustProfileProcessPolicyCompilation, andMxcProcessPolicy- New in [mxc] - Compile effective trust profiles into MXC sandbox policies #1475, public interfaceand immutable records in
Phantom.Workspaces.Llm.Trust,Phantom.Workspaces.Llm.Core/Trust/ITrustProfileProcessPolicyCompiler.csandMxcProcessPolicy.cs. Exact consumed signature:TrustProfileProcessPolicyCompilation Compile(TrustProfile effectiveProfile). It validates anonnull composed profile, performs no launch, and returns either uncontained, a complete policy,
or diagnostics; required-policy failure is never interpreted as uncontained.
IProcessExecutor,ProcessExecutionRequest, andIProcessHandle- New in [mxc] - Streaming process executor backed by MXC #1474, publicinterface/records in
Phantom.Workspaces.Processes,Phantom.Workspaces.Processes/IProcessExecutor.cs. Exact consumed signatures areTask<IProcessHandle> StartAsync(ProcessExecutionRequest request, CancellationToken ct = default),Task<ProcessExitResult> WaitAsync(CancellationToken ct = default),Task TerminateAsync(CancellationToken ct = default), andValueTask DisposeAsync().Start cancellation owns and cleans any partial process; wait cancellation does not transfer
ownership; terminate and disposal are idempotent and kill the tree. An MXC launch failure never
retries ordinary execution.
CopilotRuntimeConnectionFactoryandCopilotLaunchPolicyEnvelope- New in [mxc] - Launch copilot.exe through the MXC process executor #1476, publicsealed class/internal strict handoff record in
Phantom.Workspaces.Llm.Copilot,Phantom.Workspaces.Llm.Core/Copilot/CopilotRuntimeConnectionFactory.cs. Exact integration method:Task<CopilotRuntimeConnectionLease> CreateConnectionAsync(AgentExecutionTrustContext trustContext, string? cliPath, CancellationToken ct = default). It returns one async-disposable direct-or-wrapperconnection lease per
CopilotSdkChatClient; constrained mode writes a protected one-use localenvelope. Cancellation/failure deletes unconsumed files. The lease, envelope, policy, and path
never cross machine transport.
CopilotRuntimeConnectionLeaseis the New in [mxc] - Launch copilot.exe through the MXC process executor #1476 public sealed async-disposable result inthe same file; it exposes
RuntimeConnection Connection { get; }and idempotentValueTask DisposeAsync(). Disposal deletes only an unconsumed handoff and never kills anSDK-owned runtime after ownership has transferred.
ProcessExecutorBackedClientTransportandProcessOwnedMcpTransport- New in [mxc] - Execute MCP tools through MXC-constrained process executor #1477, publicsealed
IClientTransportand internal sealedITransportdecorator inPhantom.Workspaces.Llm.Core/Mcp/ProcessExecutorBackedClientTransport.cs. Exact public members arestring Name { get; }andTask<ModelContextProtocol.Protocol.ITransport> ConnectAsync(CancellationToken cancellationToken = default). Connect is single-use, always launches viaIProcessExecutor, separates stderr, andreturns the process-owning transport. Its
DisposeAsync()closes MCP/stdin, kills a still-runningtree, and drains exit/stderr tasks. A non-final viewer detach does not dispose it; final detach
reaches it only through graceful runtime stop when background continuation is disabled.
then
Compileis called. Missing/stale references, unavailable MXC, compiler failure, wrapperfailure, or executor failure never downgrade to null policy or direct launch.
Data flow
reference/revision. No runtime policy is persisted.
RunningAgentChatTable.AcquireAsynccalls the runtime-context factory once at firstmaterialization and merges the result into a new
AgentServicesrecord. The owning host createsCurrentSessionContextfrom its own profile/user/computer, never from viewer claims.authenticated peer identity and the host authorizes before runtime lookup.
snapshot capture. The host sends a retained replay only when the supplied cursor is fully covered;
otherwise it sends one authoritative snapshot.
generation+epoch. The host mutates the real
AgentChat, appends the resulting event under theruntime scheduler, and broadcasts it in sequence.
enqueue-inputcommand against a stable target queue and expected aggregate revision. The owner assigns theitem id, applies once, acknowledges, and broadcasts
queue-changed. Based on current-run state,queue immediacy, and mode, owning
AgentChatmay consume the item immediately through theinternal Copilot path; that consumption is another ordered queue delta. Otherwise the item
remains for a tool boundary or future turn. The remote GUI never invokes Copilot and there is no
steering command.
ExecutorBindingschooses the final component host. That host resolves thepersisted trust reference/revision, composes the effective profile, compiles once through [mxc] - Compile effective trust profiles into MXC sandbox policies #1475,
and launches through [mxc] - Streaming process executor backed by MXC #1474/[mxc] - Launch copilot.exe through the MXC process executor #1476/[mxc] - Execute MCP tools through MXC-constrained process executor #1477. Machine transports serialize trust intent, never compiled
policy.
and reuses the runtime. A snapshot includes
Usage,AgentInformation, and all queue snapshots;retained replay applies queue deltas by epoch/global sequence. It neither reconstructs
AgentChatnor relaunches children.compare/exchanges owner and increments generation. The new host hydrates and starts a fresh epoch.
Failure to confirm an unexpired old lease blocks takeover.
release immediately; transport loss reserves the attachment token for five seconds. On final
release,
continue-in-background == falsefences and gracefully stops the runtime. Explicitterminate, takeover, owner-host shutdown, or runtime-lease expiry always fences and stops it.
Stop rejects mutations, interrupts the active turn if required, disposes the chat, component
transports, MXC/process leases, wrappers, process-owned MCP transports and child trees, persists
terminal/stopped state, emits terminal where the channel remains writable, and closes channels.
Tests
RemoteExecutionContainmentMatrixTests:ExecutionMatrix_AllEightPlacementContainmentCases_UseExpectedAgentAndLaunchHosts.ExecutionMatrix_AllEightCases_ResolveTrustOnlyOnFinalLaunchHost.ExecutionMatrix_ContainmentNotRequired_UsesOrdinaryExecutorBranch.ExecutionMatrix_ContainmentRequired_UsesMxcExecutorBranch.ExecutionMatrix_RemoteBoundary_ContainsNoCompiledPolicyOrPolicyPath.ExecutionMatrix_GuiAndEntityTools_UseApplicationAuthorizationNotMxcClaim.SplitClient_RemoteCopilot_LocalAgentChat_PreservesDistinctTopology.ContainedCopilot_RemoteOwner_CreatesWrapperEnvelopeOnlyOnCopilotHost.ContainedStdioMcp_RemoteExecutor_OwnsProcessTransportOnToolHost.ContainmentCompileFails_ReturnsSanitizedErrorAndDoesNotLaunch.MxcLaunchFails_DoesNotFallbackUncontained.ConstrainedHttpOrSse_ReturnsUnsupportedPolicy.RemoteError_PolicyPathEnvironmentArgvAndStderr_AreAbsent.Takeover_NewHost_RehydratesIntentAndRecompilesPolicy.This matrix also consumes the public-method tests owned by #1474-#1477:
Compile_*inMxcTrustProfilePolicyCompilerTests,ProcessExecutor_*/ProcessHandle_*,CreateConnection_*inCopilotRuntimeConnectionFactoryTests,ConnectAsync_*/DisposeAsync_*inProcessExecutorBackedClientTransportTests, andRemoteStdio_*inRemoteMcpHostHandlerTests. Those APIs are not duplicated here.Remote integration additionally requires:
GetCompilationAsync_ConcurrentCallers_ResolveAndCompileOnceinAgentExecutionTrustContextTests.GetCompilationAsync_StaleRevision_CachesFailClosedResultinAgentExecutionTrustContextTests.StartAsync_CancelledDuringLaunch_CleansPartialProcessandTerminateAsync_RepeatedCall_KillsTreeOnceinProcessExecutorTests.WaitAsync_Cancelled_DoesNotReleaseProcessOwnershipinProcessHandleTests.CreateConnectionAsync_ConcurrentLifecyclePaths_ReturnsOneSelectionandCreateConnectionAsync_Cancelled_RemovesUnconsumedEnvelopeinCopilotRuntimeConnectionFactoryTests.DisposeAsync_UnconsumedHandoff_DeletesFileOnceandDisposeAsync_TransferredConnection_DoesNotKillSdkRuntimeinCopilotRuntimeConnectionFactoryTests.Name_ConstructedTransport_ReturnsConfiguredNameinProcessExecutorBackedClientTransportTests.Dependencies