Skip to content

[RemoteChat] - Design and implement remote AgentChat hosting and viewing #1483

Description

@JoshuaRowePhantom

Note: This bug has been split into ten true sub-issues. The design below is the approved source of truth; each child is self-contained for its commit.

Design source

https://github.com/JoshuaRowePhantom/Phantom.Workspaces/blob/0c6578641befad31d5a38003baf6c0f0fe64748a/docs/design/remote-agent-sessions.md

Requirements

Status and compatibility

  • Full-remote AgentChat ownership and the attach-agent-session proxy protocol are designed here but are not implemented.
  • ChatClientOverTransport, ChatClientTransportSession, and the split-client design in remote-chat-client-session.md are reusable lower-level mechanisms. They remote an IChatClient/Copilot session, not a complete running AgentChat, and must not be described as an existing full-session attach implementation.
  • Existing local sessions and legacy session entities must remain usable.
  • The new protocol must use the existing ITransport / message-channel infrastructure rather than creating a second network stack.

Session/profile association and persistence

  • Every newly created agent-session entity must persist exactly one owning user-computer-profile reference.
  • A legacy session with no owner is associated with the current user-computer-profile when it is next started successfully. That write is the only legacy migration.
  • Persist the session owner, an ownership generation, executor/profile bindings, the selected trust-profile reference plus expected revision needed to reconstruct effective trust intent, and the explicit per-session continue-in-background preference. The preference defaults to false; a missing value on a legacy entity is read as false.
  • Do not persist an MXC SDK object, SandboxPolicy, SandboxRequest, process handle, policy-file path, or other host-specific runtime state.
  • MxcProcessPolicy, approved by [mxc] - Compile effective trust profiles into MXC sandbox policies #1475 as a versioned local execution DTO, may cross only the protected same-machine wrapper handoff defined by [mxc] - Launch copilot.exe through the MXC process executor #1476. It must not cross a machine transport or be persisted as session authority.
  • The agent-session entity-type-view groups sessions by the persisted owning-profile field using the existing group-by-parent mechanism. Unstarted legacy sessions remain ungrouped.

Starting, attaching, and taking over

  • Opening a session owned by the current profile starts or reuses the local owning runtime.
  • Opening a session owned by another profile offers:
    1. Connect on owning profile ΓÇö start there if absent, otherwise attach to the existing runtime.
    2. Resume locally ΓÇö perform an ownership takeover, terminate the old owning runtime, persist the new owner/generation, and reconstruct locally.
  • Before showing that choice, the GUI performs an authorized status query and displays Running,
    Not running, or Unavailable for the owning profile. Unauthorized/not-found are both
    Unavailable and reveal no session metadata.
  • Every session-opening and restore path must enforce the same decision.
  • At most one owning runtime may accept mutations for an ownership generation. Takeover must use an ownership-generation compare/exchange or equivalent lease check.
  • If the old owner cannot confirm termination and its ownership lease has not expired, takeover fails closed rather than starting a concurrent local AgentChat.
  • Takeover rebuilds AgentServices, resolves the effective TrustProfile, and recompiles any required process confinement on the new host. Runtime MXC state is never migrated.

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.

Process and non-process tools

Attach protocol and UI

  • attach-agent-session is a dedicated bidirectional session protocol, separate from the chat-client request/response protocol.
  • Initial attach returns an authoritative snapshot followed by ordered deltas. Each frame carries an owning-runtime epoch and monotonically increasing sequence.
  • Reconnect supplies the last applied epoch/sequence. The host resumes from retained deltas when possible and otherwise sends a fresh snapshot. Reconnect does not reconstruct AgentChat or relaunch children.
  • The owning AgentChat is authoritative for every input queue. Local and remote GUIs submit acknowledged commands with stable queue/item ids, a command id, and an expected revision; the owner applies each command once and broadcasts the resulting ordered delta. GUI code never receives a mutable owner collection or mutates queue projections optimistically.
  • A session snapshot contains every default, immediate, held, and custom queue. Queue deltas share the session epoch/global sequence, so reconnect and multiple attached GUIs converge on the same owner state.
  • The proxy is registered in IRunningAgentChatTable; the existing RunningAgentBrainViewModel.Rows collection and RunningAgentBrainControl popup show local owned sessions and remote sessions to which this instance is attached, but do not discover unrelated remote sessions.
  • Tools and subagents are mirrored for display and navigation; execution remains on the owning/routed host.
  • Each top-level running row exposes interrupt and terminate. A remote row also exposes a Continue in background checkbox that updates the persisted session preference through the owner; subagents remain filtered out.
  • A session can raise multiple modal requests. Each agent editor displays its own modal stack above its input and gates only that editor. The root editor aggregates descendant modal presence for the tab notification.
  • Notifications are keyed by (tab id, kind) so future kinds coexist. chat-idle clears on tab
    activation; modal-pending clears only when all relevant modals are dismissed.
    NotificationsViewModel.HasUnread remains the application-wide logical OR of every unread kind.

Lifecycle

  • An owning runtime has a host-owned RemoteAgentSessionLease; each attached GUI has an independent RemoteAgentAttachmentLease. The runtime serializes attachment-count, retention-preference, and termination transitions under one lifecycle gate.
  • continue-in-background is an explicit persisted per-session preference, defaults to false, and is copied into every runtime snapshot. When the last viewer detaches and the value is false, the owner gracefully stops the runtime. When it is true, the runtime may continue with zero viewers until explicit termination, takeover, owner-host shutdown, or runtime-lease expiry.
  • Explicit detach, proxy disposal, UI tab close, and graceful viewer-application shutdown release that viewer immediately. Unexpected channel/transport loss instead reserves that logical attachment for a five-second reconnect grace period; reconnect with the same attachment token cancels expiry without changing the logical viewer count. When the grace expires, the attachment is released and the last-viewer rule runs.
  • A new attach racing with last-viewer stop is serialized by the lifecycle gate. If attachment reservation wins, stop is cancelled and attach receives the existing epoch. If fencing wins, that epoch accepts no attach or mutation; Attach returns the indistinguishable not-found result and StartOrAttach may create a fresh epoch only after terminal persistence and registry removal complete.
  • Multiple viewers are independent: removing any non-final viewer never stops the runtime. Setting continue-in-background to true preserves a zero-viewer runtime; setting it to false while viewers remain changes persistence and the snapshot but does not interrupt the run; setting it to false when the viewer count is already zero starts graceful stop immediately.
  • Owner-host application shutdown and runtime-lease expiry stop every runtime regardless of the preference. Viewer-application shutdown is only a graceful detach. A host crash cannot emit a terminal frame, but process containment kills owned children and recovery records the interrupted epoch as stopped before any new epoch starts; the persisted preference remains unchanged and does not itself imply auto-resume.
  • Graceful stop first fences the epoch so it accepts no new mutations, cancels/interrupts an active turn if needed, disposes AgentChat, component transports, MXC/process-executor leases, wrappers, stdio MCP transports, and contained child sessions/trees, persists the terminal completion and stopped state, then removes the registry entry. It emits exactly one session-terminal event after persistence and before closing attachment channels where the transport remains writable.
  • Interrupt cancels only the active run; terminate ends the owning runtime. These are distinct protocol verbs and UI actions.

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.

Considered / Background

Option A — Extend ChatClientOverTransport

Add session attach, tools, subagents, modals, lifecycle, and replay to the existing chat-client
protocol. This reuses framing, but overloads IChatClient, mixes per-run and whole-session lifetimes,
and makes reconnect and independent owning-runtime lifetime difficult.

Option B — Dedicated attach-agent-session protocol

Add a session-oriented listener/client pair over existing message channels and keep
ChatClientOverTransport focused on lower-level remote chat-client execution. This adds a protocol
vocabulary and proxy abstraction, but gives ownership, authorization, replay, lifecycle, multiple
viewers, and subagent channels explicit boundaries.

Option C — Entity-store mirror plus thin control channel

Read persisted history/tools/subagents through entity observation and use a channel only for live
state and control. This reduces control-channel data, but creates two ordering domains and cannot
reliably reconstruct unpersisted streaming, queue, modal, and lifecycle state.

Chosen design

Approach

Choose Option B, a dedicated attach-agent-session protocol.

The owning host holds a real AgentChat behind a host-owned runtime lease. An authorized RemoteAgentSessionClient receives a snapshot and ordered event stream and backs the new RemoteAgentChat implementation of the new common IAgentChat surface. IRunningAgentChatTable, AgentViewModel, and session tabs consume IAgentChat, allowing the existing concrete AgentChat and the proxy to participate without subclassing the currently sealed AgentChat.

ChatClientOverTransport is unchanged in role: it is the lower-level remote IChatClient mechanism used by split-client execution. It is not the remote-session proxy.

All APIs in this chosen design follow the named-initializer convention: APIs carrying multiple independent values use property-based *Request or *Options records, with semantically required members declared required init and optional members given explicit defaults. Constructors remain only for compact value objects that enforce a scalar invariant or for small cohesive dependency sets. Protocol DTO/property records preserve the version-1 kebab-case serializer contract, required/optional wire members, strict unknown-member rejection, and fixed concrete discriminators; only their C# construction shape changes.

Rationale

One ordered session stream avoids entity/control ordering races and gives authorization, reconnect, viewer lifetime, takeover, and sanitized failures explicit homes. A common IAgentChat surface resolves the old subclassing ambiguity without making AgentChat virtual merely for remoting. Separate owning-runtime and attachment leases permit a short reconnect grace without making viewer lifetime ambiguous: by default the final released attachment stops the runtime, while an explicit persisted preference keeps it alive.

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? owning-profile binding + attach-agent-session host
Component placement Which host executes the model/tool component? persisted ExecutorBindings / connection descriptor
Process confinement How is a process restricted on that host? launch-host effective TrustProfile + #1475 compiler + #1474 executor

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.

Overlap matrix

Concern Remote-agent design owns MXC / executor design owns Integration rule
Remote AgentChat protocol Start/attach, snapshots, ordered deltas, proxy commands None Protocol selects/observes owner; it does not launch or sandbox.
Executor routing Persists and restores session/component intent ExecutorBindings resolves component connection descriptors Owner routes; final executor host enforces.
Trust-profile resolution Carries stable profile reference + expected revision #1472 schema/composition and #1475 compiler input Resolve effective profile again on the launch host; reject stale/missing revision.
Process execution Owns runtime/component lease boundaries #1474 ordinary/MXC streaming executor A non-final detach does not dispose executor handles; final detach disposes them unless background continuation is enabled.
Copilot wrapper Reports lifecycle/error events #1476 wrapper, one-use policy file, direct path when uncontained Wrapper and handoff are created only on the Copilot launch host.
stdio MCP Routes tool to selected host #1477 executor-backed MCP transport Selected host compiles and launches; channel caller sends no policy.
Persistence Owner/generation, bindings, trust intent, history No runtime MXC persistence Reconstruct and recompile after restart/takeover.
Lifecycle Owning lease, attachment leases, reconnect grace, background preference, terminate/takeover Process handle/tree disposal 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.

Impedance mismatches and resolutions

  1. Per-run IChatClient lifetime versus persistent AgentChat lifetime.
    Resolution: retain chat-client for split-client calls and add attach-agent-session for whole-session ownership, replay, and multiple viewers.

  2. AgentChat is sealed but the UI and running table need a proxy with equivalent behavior.
    Resolution: introduce IAgentChat; adapt the existing AgentChat to implement it and add RemoteAgentChat. Do not subclass or add transport branches throughout AgentChat.

  3. 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.

  4. [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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. Reconnect can be mistaken for session recreation.
    Resolution: reconnect by attachment token, runtime epoch, and replay cursor during the five-second transport-loss grace. Reattach to the existing runtime and use a fresh snapshot when replay is unavailable. After grace expiry stops a default-policy runtime, Attach cannot resurrect it and StartOrAttach creates a new epoch only after stop completes.

  11. Existing queue classes expose owner objects and use indexes for some edits.
    Resolution: retain AgentInputQueue, AgentChatQueue, AgentInputQueueManager, and
    AgentChatQueueManager as local implementation types, but expose immutable queue/item snapshots
    through IAgentInputQueues. Assign stable ids at creation/enqueue, use indexes only as placement
    hints, and route every mutation through owner-authoritative revisioned commands.

  12. Steering is an execution decision, not a separate kind of user input.
    Resolution: there is no steering member on IAgentChat and no steer protocol verb. A GUI
    enqueues through the same queue API whether a run is idle or active. The owning AgentChat
    decides from queue immediacy, mode, and current-run state whether to consume that item as
    Copilot steering or as a future turn.

Request/options type audit

The complete design contains exactly 28 request/options types: 22 public and 6 internal. Public: CreateAgentInputQueueRequest, DeleteAgentInputQueueRequest, EnqueueAgentInputRequest, EditAgentInputQueueItemRequest, RemoveAgentInputQueueItemRequest, MoveAgentInputQueueItemRequest, ConfigureAgentInputQueueRequest, RemoteAgentChatAttachOptions, AgentSessionStatusRequest, TerminateAgentSessionRequest, OpenAgentSubagentRequest, RespondToAgentModalRequest, SetAgentToolEnabledRequest, SetAgentSessionRetentionRequest, AgentSessionOpenRequest, CreateAgentSessionEntityDataRequest, AcquireAgentChatRequest, AgentViewModelOptions, CreateAgentSessionTabForRestoreRequest, CreateAgentSessionTabRequest, ComposeSessionAgentViewModelOptions, and NotificationTargetRequest. Internal: AgentSessionAuthorizationRequest, OpenAgentSessionHostRequest, TerminateAgentSessionRuntimeRequest, UpdateAgentSessionRuntimeRetentionRequest, AttachRemoteAgentSessionRequest, and AgentSessionTakeoverRequest.

Every one follows the named-initializer convention above. Property-shape tests reflect RequiredMemberAttribute, instantiate documented optional defaults, verify named mapping, and, for wire DTOs, verify exact kebab-case serialization and fixed discriminators. The unchanged #1474 ProcessExecutionRequest is excluded from this audit.

Test matrix audit

The complete committed matrix contains 373 scenario bullets representing 376 named test methods;
three integration bullets each name two methods. Existing unchanged tests retain their scope. Shape
changes add or update the committed named tests for Usage defaults/named initialization,
AgentInformation required members/named initialization, queue request required/default/named
mapping, client request named mapping, protocol DTO required/default/fixed-discriminator mapping,
runtime/authorization/host request mapping, entity-factory request mapping, AgentViewModelOptions,
session UI request/options mapping, and notification property/target-request mapping. The client
matrix tests direct InterruptAsync(Guid commandId, CancellationToken ct = default) and contains no
interrupt request-record shape test.

Implementation plan

Each step is independently committable and leaves existing local behavior passing.

Commit 1 - #1484 - Persist and hydrate runtime intent

Files: Phantom.Workspaces.Data.Core/JsonSchemas/agent-session.json,
AgentSessionEntityFactory, CreateAgentSessionEntityDataRequest, AgentSessionRuntimeIntentData,
PersistedAgentSessionRuntimeIntent, AgentSessionRuntimeContext,
IAgentSessionRuntimeContextFactory, AgentSessionRuntimeContextFactory,
JsonEntities/entity-type-views/agent-session-entity-type-view.json, and acquisition callers.
Tests: request required-member/default/named-initializer mapping, factory, default/true background persistence, restart hydration, round-trip, legacy,
grouping, malformed, no-policy, and fresh/non-GUI acquisition tests above.
Boundary: follows #1481: entity JSON is interpreted at the shared acquisition layer, never in GUI
routing. It consumes the already-present AgentSessionExecutorBindings and ExecutorBindings
surfaces on features; it neither waits for nor recreates the later MXC APIs.
Dependencies: none.

Commit 2 - #1485 - Add the common chat surface

Exact common state contracts

The state records have exactly this property-based shape; these names, fields, types, defaults, and semantics are normative:

public readonly record struct Usage
{
    public Usage() { }
    public long? TotalInputTokenCount { get; init; } = null;
    public long? TotalOutputTokenCount { get; init; } = null;
    public long? TotalCacheReadTokenCount { get; init; } = null;
    public long? TotalCacheWriteTokenCount { get; init; } = null;
    public long? TotalReasoningTokenCount { get; init; } = null;
    public double? TotalSessionCostUsd { get; init; } = null;
}

public readonly record struct AgentInformation
{
    public AgentInformation() { }
    public required string AgentSessionId { get; init; }
    public required string AgentId { get; init; }
    public required string Name { get; init; }
    public required string DisplayName { get; init; }
    public required string Description { get; init; }
    public required bool AcceptsUserInput { get; init; }
    public string? CurrentModelId { get; init; } = null;
    public required AgentDefinition AgentDefinition { get; init; }
}

Usage uses null for an unreported metric; reported counts and USD cost are nonnegative. AgentInformation requires non-null, nonblank values for its first five strings and a non-null complete AgentDefinition; CurrentModelId is null or nonblank. Publishers and the codec validate invariants, construct/deserialize a complete replacement, assign it atomically on the foreground scheduler, and then raise one corresponding change event per applied session sequence. Record equality is value equality. Both records use the existing JSON options and kebab-case protocol naming.

For every authorized viewer, AgentInformation carries the full AgentDefinition; authorization completes before serialization and there is no field-level redaction after authorization. The owner serializes it with AgentDefinition.ToJson() and the client deserializes it with PhantomAgentSchema.AgentDefinitionFromJson(string). Unauthorized peers receive no definition bytes or other session metadata.

Interrupt intentionally has no request record: there is no InterruptAgentSessionRequest. The client API is exactly Task InterruptAsync(Guid commandId, CancellationToken ct = default); the internal property-based InterruptCommand carries the shared required command/correlation/epoch members and its fixed interrupt discriminator.

Files: IAgentChat, property-based Usage and AgentInformation, IAgentInputQueues, the seven queue request types and property-based snapshot/configuration/result types,
owner queue adapter, stable ids/revisions in the existing queue domain, AgentChat,
RunningAgentChat, RunningAgentChatLease, RunningAgentChatWithEntityInfo, AgentViewModel,
AgentViewModelOptions, and
InputQueueViewModel.
Tests: required-init metadata, optional defaults, named initializers, serialization,
AgentChatInterfaceTests, AgentInputQueuesTests, internal Copilot/non-Copilot queue consumption
tests, options/common-surface tests, and unchanged local regression suite. Migrate
the UI away from concrete queue collections and index identity. No transport behavior yet.
Dependencies: none.

Commit 3 - #1486 - Add strict protocol and proxy state

Files: Phantom.Workspaces.Llm.Core/Remote/AgentSessionProtocol.cs, property-based protocol DTOs
and codec, RemoteAgentSessionClient, its public request types, RemoteAgentChat, and
RemoteAgentChatAttachOptions.
Tests: required-init metadata, optional defaults, named-initializer construction, exact discriminator/serialization round trips, codec, all client public methods (including direct InterruptAsync(Guid commandId, CancellationToken ct = default) and no interrupt request type), atomic usage/information, proxy queue parity,
full authorized AgentDefinition, no metadata on denial, background command/event/snapshot,
revisions/conflicts/deduplication, state/events/commands, cancellation, and disposal. The protocol
contains enqueue/edit/remove/move/configure/create/delete queue commands and no steering command.
Use an in-memory IMessageChannel; no server runtime or MXC dependency.
Dependencies: #1485.

Commit 4 - #1487 - Add authorization, host, and viewer lifecycle

Files: property-based peer identity/authorization/host/runtime request records, peer identity provider, attach authorizer, listener, host, runtime registry, runtime and
attachment leases, replay buffer, transport composition registration.
Tests: required-member/default/named-initializer mapping for all five non-wire internal request types, listener, authorizer, host, registry, replay limits, multiple viewers, sanitized errors, and
no existence disclosure, including default final-viewer stop, persisted background retention,
five-second reconnect grace, attach/stop races, explicit-terminate precedence, complete graceful
cleanup, queue convergence, and reconnect snapshot/replay.
Dependencies: #1484 and #1486.

Commit 5 - #1488 - Integrate running table and all open paths

Files: AcquireAgentChatRequest, IRunningAgentChatTable, RunningAgentChatTable,
OpenAgentSessionShortcutHandler, CreateAgentSessionTabForRestoreRequest, CreateAgentSessionTabRequest, ComposeSessionAgentViewModelOptions, fresh launcher, auto-resume, non-GUI acquisition path.
Tests: request required-member/default/named-initializer tests, every table method, local/remote single-flight, restore/fresh/auto-resume parity, and no
rehydration of an existing runtime. Includes local/remote background preference dispatch and
authoritative running-row metadata.
Dependencies: #1484, #1485, #1486, and #1487.

Commit 6 - #1489 - Add takeover and deterministic runtime shutdown

Files: persisted ownership compare/exchange, host takeover coordinator, runtime fencing,
termination acknowledgement, lease expiry.
Tests: successful takeover, stale generation/epoch, unconfirmed old lease, command fencing,
terminal ordering, ten-second renewal/thirty-second expiry, crash recovery, and complete child
cleanup.
Dependencies: #1487 and #1488.

Commit 7 - #1490 - Integrate host-local trust and component placement

Files: runtime hydration into AgentServices, CurrentSessionContext,
AgentExecutionTrustContext, existing ExecutorBindings consumers, remote MCP/Copilot requests.
Tests: stale trust revision, per-session context isolation, and all eight
agent-placement/component-placement/containment combinations.
Dependencies: #1488 and #1472, #1474, #1475, and #1477.

Commit 8 - #1491 - Integrate Copilot wrapper and stdio MCP ownership

Files: existing #1476 CopilotRuntimeConnectionFactory 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: #1490 and #1473-#1477.

Commit 9 - #1492 - Complete remote UI, modals, and notifications

Files: AgentViewModel, AgentSessionWorkspaceTabViewModel, editor/modal controls,
Phantom.Workspaces/ViewModels/RunningAgentBrainViewModel.cs,
Phantom.Workspaces/ViewModels/RunningAgentRowViewModel.cs,
Phantom.Workspaces/Controls/RunningAgentBrainControl.axaml(.cs), Notification,
NotificationEntry, NotificationTargetRequest, INotificationService, NotificationService, and NotificationsViewModel.
Tests: UI request/options required-member/default/named-initializer tests, UI public API tests above, multiple modal ownership, descendant aggregation, independent
notification clearing, remote interrupt versus terminate, and checkbox binding, command,
enabled/pending state, and accessibility.
Dependencies: #1485, #1488, and #1489.

Commit 10 - #1493 - End-to-end security and lifecycle validation

Files: tests only except defects found by integration.
Tests: transport ordering, replay/snapshot fallback, concurrent viewers, authorization denial,
cancellation, default/background lifecycle, reconnect grace, attach/stop and terminate races,
persistence/restart, disposal, takeover, fail-closed MXC, complete placement/containment
cross-product, no compiled policy on wire, and no cross-session CurrentSessionContext
contamination.
Dependencies: #1484-#1492 and completed #1471-#1477 surfaces.

Sub-issues

Complete in dependency order (items without mutual dependencies may proceed in parallel):

  1. [RemoteChat] - Persist and hydrate runtime intent #1484 ΓÇö [RemoteChat] - Persist and hydrate runtime intent (no dependencies)
  2. [RemoteChat] - Add the common chat surface #1485 ΓÇö [RemoteChat] - Add the common chat surface (no dependencies)
  3. [RemoteChat] - Add strict protocol and proxy state #1486 ΓÇö [RemoteChat] - Add strict protocol and proxy state (depends on [RemoteChat] - Add the common chat surface #1485)
  4. [RemoteChat] - Add authorization, host, and viewer lifecycle #1487 ΓÇö [RemoteChat] - Add authorization, host, and viewer lifecycle (depends on [RemoteChat] - Persist and hydrate runtime intent #1484, [RemoteChat] - Add strict protocol and proxy state #1486)
  5. [RemoteChat] - Integrate running table and all open paths #1488 ΓÇö [RemoteChat] - Integrate running table and all open paths (depends on [RemoteChat] - Persist and hydrate runtime intent #1484, [RemoteChat] - Add the common chat surface #1485, [RemoteChat] - Add strict protocol and proxy state #1486, [RemoteChat] - Add authorization, host, and viewer lifecycle #1487)
  6. [RemoteChat] - Add takeover and deterministic runtime shutdown #1489 ΓÇö [RemoteChat] - Add takeover and deterministic runtime shutdown (depends on [RemoteChat] - Add authorization, host, and viewer lifecycle #1487, [RemoteChat] - Integrate running table and all open paths #1488)
  7. [RemoteChat] - Integrate host-local trust and component placement #1490 ΓÇö [RemoteChat] - Integrate host-local trust and component placement (depends on [RemoteChat] - Integrate running table and all open paths #1488, [mxc] - Align trust-profile filesystem and network schema with MXC #1472, [mxc] - Streaming process executor backed by MXC #1474, [mxc] - Compile effective trust profiles into MXC sandbox policies #1475, [mxc] - Execute MCP tools through MXC-constrained process executor #1477)
  8. [RemoteChat] - Integrate Copilot wrapper and stdio MCP ownership #1491 ΓÇö [RemoteChat] - Integrate Copilot wrapper and stdio MCP ownership (depends on [RemoteChat] - Integrate host-local trust and component placement #1490, [mxc] - Add Microsoft.Mxc.Sdk and native build support #1473, [mxc] - Streaming process executor backed by MXC #1474, [mxc] - Compile effective trust profiles into MXC sandbox policies #1475, [mxc] - Launch copilot.exe through the MXC process executor #1476, [mxc] - Execute MCP tools through MXC-constrained process executor #1477)
  9. [RemoteChat] - Complete remote UI, modals, and notifications #1492 ΓÇö [RemoteChat] - Complete remote UI, modals, and notifications (depends on [RemoteChat] - Add the common chat surface #1485, [RemoteChat] - Integrate running table and all open paths #1488, [RemoteChat] - Add takeover and deterministic runtime shutdown #1489)
  10. [RemoteChat] - Add end-to-end security and lifecycle validation #1493 ΓÇö [RemoteChat] - Add end-to-end security and lifecycle validation (depends on [RemoteChat] - Persist and hydrate runtime intent #1484, [RemoteChat] - Add the common chat surface #1485, [RemoteChat] - Add strict protocol and proxy state #1486, [RemoteChat] - Add authorization, host, and viewer lifecycle #1487, [RemoteChat] - Integrate running table and all open paths #1488, [RemoteChat] - Add takeover and deterministic runtime shutdown #1489, [RemoteChat] - Integrate host-local trust and component placement #1490, [RemoteChat] - Integrate Copilot wrapper and stdio MCP ownership #1491, [RemoteChat] - Complete remote UI, modals, and notifications #1492, [mxc] - Integrate MXC-enforced process execution with trust profiles #1471, [mxc] - Align trust-profile filesystem and network schema with MXC #1472, [mxc] - Add Microsoft.Mxc.Sdk and native build support #1473, [mxc] - Streaming process executor backed by MXC #1474, [mxc] - Compile effective trust profiles into MXC sandbox policies #1475, [mxc] - Launch copilot.exe through the MXC process executor #1476, [mxc] - Execute MCP tools through MXC-constrained process executor #1477)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions