Part of #1471
Dependencies
Summary
Add a deterministic compiler from an already composed effective TrustProfile to a versioned, serializable MxcProcessPolicy consumed by the process executor. The compiler decides whether containment is required, canonicalizes and validates host-local paths and capabilities, translates data-sharing mode into appropriate scoped directories and environment overrides, and fails closed with structured diagnostics. It does not launch processes. The portable result may cross the local Copilot-wrapper process boundary, but compiled policy is never accepted across a machine boundary.
Root Cause
Phantom.Workspaces.Llm.Core/AgentFactory.cs:1178-1195 resolves the selected profile and checks local authorization, but no component translates its filesystem/network restrictions and data-sharing mode into enforceable MXC configuration. Returning an SDK SandboxPolicy object directly would also couple every caller to MXC SDK object lifetime/serialization and would not provide a stable local wrapper handoff.
Affected Files
| File / Area |
Change |
| Trust model introduced by #1472 |
Consume effective filesystem paths, presence-aware network capabilities, and data-sharing specification. |
New compiler files under Phantom.Workspaces.Llm.Core/Trust/ |
Implement containment decisions, host-local validation, data-sharing translation, and diagnostics. |
| Shared execution-contract project from #1474 |
Define the versioned immutable MxcProcessPolicy DTO consumed by ordinary in-process callers and the Copilot wrapper. |
Corresponding Phantom.Workspaces.Llm.Core.Tests files |
Verify translation, fail-closed behavior, data-sharing resolution, and serialization round trips. |
Design / Fix
Contract
Introduce a contract equivalent to:
public interface ITrustProfileProcessPolicyCompiler
{
TrustProfileProcessPolicyCompilation Compile(TrustProfile effectiveProfile);
}
public sealed record TrustProfileProcessPolicyCompilation(
bool RequiresContainment,
MxcProcessPolicy? Policy,
IReadOnlyList<TrustProfilePolicyDiagnostic> Diagnostics);
MxcProcessPolicy is a versioned, immutable, JSON-serializable execution DTO containing only normalized filesystem grants, validated network capabilities, translated data-sharing configuration, and explicit MXC containment/settings required by #1474. It is not the user-authored TrustProfile and not raw arbitrary SandboxPolicy JSON. The #1474 MXC branch maps this DTO to the pinned SDK's SandboxPolicy/SandboxRequest immediately before MxcSandbox.Spawn.
The compiler is deterministic and does not launch, route, or mutate files. Read-only SDK platform/backend probes are allowed.
Containment decision
Containment is required when:
- at least one effective filesystem path grant exists; or
NetworkCapabilities is present, including present-empty.
Containment is unnecessary only when both are absent/empty as defined by #1472. Client-instance authorization, MCP tool-schema authorization, and execution-target routing remain outside this compiler.
Filesystem and network compilation
- Resolve
target-path ?? source-path, canonicalize on the launch host, and reject invalid, relative, escaping, or ambiguous paths.
- Reject normalized source/target inequality because ProcessContainer does not create a mount namespace.
- Map read-only/read-write entries to the corresponding MXC filesystem grants.
- Validate capability names with the pinned MXC SDK and preserve accepted names exactly. Present-empty grants no network capability.
- Add only documented executor/runtime bootstrap grants required to start the selected executable; these grants are explicit diagnostics and cannot be supplied by untrusted profile input.
- DACL mutation fallback is allowed. Do not set
allowDaclMutation=false; surface fallback/restoration warnings where the SDK exposes them.
Data-sharing translation
Translate the effective TrustDataSharing mode (from #1472) into scoped configuration directories and process environment overrides:
Full sharing
if (dataSharing is TrustDataSharing.Full)
{
// Copilot uses its default paths; no environment override needed.
// Compiler automatically grants ~/.copilot/ and configured session-temp as R/W.
// No environment variable changes.
}
Regime-scoped sharing
if (dataSharing is TrustDataSharing.RegimeScoped regime)
{
string regimeConfigPath = Path.Combine(userCopilotBaseDir, $"{regime.RegimeName}-session");
string regimeSessionTempPath = Path.Combine(tempDir, $"copilot-{regime.RegimeName}-{sessionNonce}");
// Add to policy:
// - regimeConfigPath as R/W (copilot config home)
// - regimeSessionTempPath as R/W (session temp)
// - Set environment override: COPILOT_CONFIG_HOME = regimeConfigPath
}
Each regime gets isolated ~/.copilot/<regime>-session/ for auth/cache/history, plus isolated temp directories. Multiple containment instances with the same regime name share that scope; different regimes are completely isolated.
Ephemeral (none)
if (dataSharing is TrustDataSharing.None)
{
string ephemeralConfigPath = Path.Combine(tempDir, $"copilot-ephemeral-{sessionNonce}");
string ephemeralSessionTempPath = Path.Combine(tempDir, $"copilot-session-{sessionNonce}");
// Add to policy:
// - ephemeralConfigPath as R/W (copilot config home)
// - ephemeralSessionTempPath as R/W (session temp)
// - Set environment override: COPILOT_CONFIG_HOME = ephemeralConfigPath
}
Ephemeral mode creates a unique temp directory per session; data is not persisted and is isolated from all other instances.
Environment variable semantics: If the effective TrustDataSharing requires a COPILOT_CONFIG_HOME override, the MxcProcessPolicy includes an entry in its EnvironmentOverrides dict. The MXC branch (#1474) or Copilot wrapper (#1476) applies this override to the child process environment.
SDK settings and diagnostics
Boundary rules
Local in-process MCP execution may pass MxcProcessPolicy directly to #1474. The local Copilot host may serialize it to the one-use policy file defined by #1476. Remote model/MCP protocols carry only a trust-profile reference and revision; the remote launch host resolves and compiles its own MxcProcessPolicy. Reject caller-supplied compiled policy on remote boundaries.
Expected Tests
| Test Name |
Class |
What It Verifies |
Compile_NoFilesystemOrNetworkPolicy_ReturnsUncontained |
MxcTrustProfilePolicyCompilerTests |
No relevant policy produces no containment requirement. |
Compile_EmptyNetworkCapabilities_RequiresContainerAndGrantsNoCapabilities |
MxcTrustProfilePolicyCompilerTests |
Present-empty networking requires containment with no capability grants. |
Compile_FilesystemPolicy_MapsReadonlyAndReadwritePaths |
MxcTrustProfilePolicyCompilerTests |
Canonical path grants map to the portable execution policy. |
Compile_RemappedTarget_ReturnsValidationFailure |
MxcTrustProfilePolicyCompilerTests |
Unsupported source/target remapping fails closed. |
Compile_UnsupportedCapability_ReturnsValidationFailure |
MxcTrustProfilePolicyCompilerTests |
The pinned SDK rejects unsupported capability names. |
Compile_UnsupportedHost_ReturnsActionableFailure |
MxcTrustProfilePolicyCompilerTests |
Missing host/backend support never yields an uncontained fallback. |
Compile_DataSharingFull_NoEnvironmentOverride |
MxcTrustProfilePolicyCompilerTests |
Full sharing does not add COPILOT_CONFIG_HOME override. |
Compile_DataSharingRegime_GrantsRegimeScopedPathsAndOverride |
MxcTrustProfilePolicyCompilerTests |
Regime-scoped sharing grants ~/.copilot/<regime>-session/ and sets COPILOT_CONFIG_HOME. |
Compile_DataSharingNone_GrantsEphemeralPathsAndOverride |
MxcTrustProfilePolicyCompilerTests |
Ephemeral sharing grants temp-only paths and sets COPILOT_CONFIG_HOME. |
Compile_RegimeScopedSharing_CreatesEphemeralSessionTempDir |
MxcTrustProfilePolicyCompilerTests |
Regime mode grants both scoped config and unique session temp. |
Compile_DataSharingEnforcesCopilotPathGrant |
MxcTrustProfilePolicyCompilerTests |
All data-sharing modes grant the real CLI/runtime directory. |
MxcProcessPolicy_SerializeDeserialize_RoundTripsExactly |
MxcProcessPolicySerializationTests |
The versioned local-wrapper DTO round-trips without losing restrictions. |
Compile_DaclFallbackAvailable_DoesNotRejectPolicy |
MxcTrustProfilePolicyCompilerTests |
Product policy permits the MXC DACL fallback tier. |
Part of #1471
Dependencies
Summary
Add a deterministic compiler from an already composed effective
TrustProfileto a versioned, serializableMxcProcessPolicyconsumed by the process executor. The compiler decides whether containment is required, canonicalizes and validates host-local paths and capabilities, translates data-sharing mode into appropriate scoped directories and environment overrides, and fails closed with structured diagnostics. It does not launch processes. The portable result may cross the local Copilot-wrapper process boundary, but compiled policy is never accepted across a machine boundary.Root Cause
Phantom.Workspaces.Llm.Core/AgentFactory.cs:1178-1195resolves the selected profile and checks local authorization, but no component translates its filesystem/network restrictions and data-sharing mode into enforceable MXC configuration. Returning an SDKSandboxPolicyobject directly would also couple every caller to MXC SDK object lifetime/serialization and would not provide a stable local wrapper handoff.Affected Files
Phantom.Workspaces.Llm.Core/Trust/MxcProcessPolicyDTO consumed by ordinary in-process callers and the Copilot wrapper.Phantom.Workspaces.Llm.Core.TestsfilesDesign / Fix
Contract
Introduce a contract equivalent to:
MxcProcessPolicyis a versioned, immutable, JSON-serializable execution DTO containing only normalized filesystem grants, validated network capabilities, translated data-sharing configuration, and explicit MXC containment/settings required by #1474. It is not the user-authoredTrustProfileand not raw arbitrarySandboxPolicyJSON. The #1474 MXC branch maps this DTO to the pinned SDK'sSandboxPolicy/SandboxRequestimmediately beforeMxcSandbox.Spawn.The compiler is deterministic and does not launch, route, or mutate files. Read-only SDK platform/backend probes are allowed.
Containment decision
Containment is required when:
NetworkCapabilitiesis present, including present-empty.Containment is unnecessary only when both are absent/empty as defined by #1472. Client-instance authorization, MCP tool-schema authorization, and execution-target routing remain outside this compiler.
Filesystem and network compilation
target-path ?? source-path, canonicalize on the launch host, and reject invalid, relative, escaping, or ambiguous paths.allowDaclMutation=false; surface fallback/restoration warnings where the SDK exposes them.Data-sharing translation
Translate the effective
TrustDataSharingmode (from #1472) into scoped configuration directories and process environment overrides:Full sharing
Regime-scoped sharing
Each regime gets isolated
~/.copilot/<regime>-session/for auth/cache/history, plus isolated temp directories. Multiple containment instances with the same regime name share that scope; different regimes are completely isolated.Ephemeral (none)
Ephemeral mode creates a unique temp directory per session; data is not persisted and is isolated from all other instances.
Environment variable semantics: If the effective
TrustDataSharingrequires aCOPILOT_CONFIG_HOMEoverride, theMxcProcessPolicyincludes an entry in itsEnvironmentOverridesdict. The MXC branch (#1474) or Copilot wrapper (#1476) applies this override to the child process environment.SDK settings and diagnostics
GetPlatformSupport/GetAvailableBackends. Unsupported hosts/backends return actionable failure and never an uncontained result.MxcExceptionoperation/native-code/remediation information.Boundary rules
Local in-process MCP execution may pass
MxcProcessPolicydirectly to #1474. The local Copilot host may serialize it to the one-use policy file defined by #1476. Remote model/MCP protocols carry only a trust-profile reference and revision; the remote launch host resolves and compiles its ownMxcProcessPolicy. Reject caller-supplied compiled policy on remote boundaries.Expected Tests
Compile_NoFilesystemOrNetworkPolicy_ReturnsUncontainedMxcTrustProfilePolicyCompilerTestsCompile_EmptyNetworkCapabilities_RequiresContainerAndGrantsNoCapabilitiesMxcTrustProfilePolicyCompilerTestsCompile_FilesystemPolicy_MapsReadonlyAndReadwritePathsMxcTrustProfilePolicyCompilerTestsCompile_RemappedTarget_ReturnsValidationFailureMxcTrustProfilePolicyCompilerTestsCompile_UnsupportedCapability_ReturnsValidationFailureMxcTrustProfilePolicyCompilerTestsCompile_UnsupportedHost_ReturnsActionableFailureMxcTrustProfilePolicyCompilerTestsCompile_DataSharingFull_NoEnvironmentOverrideMxcTrustProfilePolicyCompilerTestsCompile_DataSharingRegime_GrantsRegimeScopedPathsAndOverrideMxcTrustProfilePolicyCompilerTests~/.copilot/<regime>-session/and sets COPILOT_CONFIG_HOME.Compile_DataSharingNone_GrantsEphemeralPathsAndOverrideMxcTrustProfilePolicyCompilerTestsCompile_RegimeScopedSharing_CreatesEphemeralSessionTempDirMxcTrustProfilePolicyCompilerTestsCompile_DataSharingEnforcesCopilotPathGrantMxcTrustProfilePolicyCompilerTestsMxcProcessPolicy_SerializeDeserialize_RoundTripsExactlyMxcProcessPolicySerializationTestsCompile_DaclFallbackAvailable_DoesNotRejectPolicyMxcTrustProfilePolicyCompilerTests