Skip to content

[API Surface] State-aware: Add 'phase' APIs + remove 'phase' ops from schema - #1219

Open
Jeff Whiteside (jsidewhite) wants to merge 7 commits into
mainfrom
jsidewhite/stateaware_fix_schema_SQ918_clean_SQ2
Open

Jeff Whiteside (jsidewhite) wants to merge 7 commits into
mainfrom
jsidewhite/stateaware_fix_schema_SQ918_clean_SQ2

Conversation

@jsidewhite

@jsidewhite Jeff Whiteside (jsidewhite) commented Sep 18, 2026

Copy link
Copy Markdown
Member
  1. State-aware is now functions (not "pass a config json")
  2. Removed 'phase' and 'provision' (duplicated schema bits) from the 0.9.0-alpha json schema

Rust mxc_sdk example

let provisioned = sandbox::provision(
    r#"{"version":"0.9.0-alpha","containment":"isolation_session",
        "network":{"egress":{"default":"allow"},
          "ingress":{"default":"allow","hostLoopback":"allow"}}}"#,
    true,  // experimental
)?;

Closes #1218

Microsoft Reviewers: Open in CodeFlow

… schema

Route provision, start, exec, stop, and deprovision through explicit CLI and SDK operations, with sandbox identity supplied separately from operation-neutral request JSON.
@jsidewhite
Jeff Whiteside (jsidewhite) requested review from a team and a balanced review from Copilot September 18, 2026 20:16
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d4685110-c467-408f-930e-250aab2025c4

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Versioning tests and Windows lint deterministically fail, and several renamed engine APIs retain broken rustdoc links.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 High severity · 2 Low severity

Open (4)
What changed in this PR

Moves state-aware lifecycle operations and sandbox IDs out of JSON configuration and into SDK/CLI API parameters, making the 0.9 schema operation-neutral.

Changes:

  • Introduces operation-specific Rust, Node, .NET, CLI, engine, and FFI APIs.
  • Consolidates lifecycle schemas into one request contract and updates validation.
  • Migrates documentation, examples, tests, and fixtures to the new API.
File Description
.github/​copilot-instructions.md Documents operation-neutral lifecycle JSON.
docs/​isolation-session/​state-aware-rust.md Updates IsolationSession Rust examples.
docs/​schema.md Documents the unified request schema.
docs/​state-aware-lifecycle/​mxc-state-aware-sandbox-api-overview.md Updates the lifecycle API overview.
docs/​state-aware-lifecycle/​mxc-state-aware-sandbox-api.md Revises detailed lifecycle API guidance.
docs/​version-specific-parser-migration-inventory.md Updates parser migration status.
docs/​windows-sandbox/​windows-sandbox.md Migrates Windows Sandbox examples.
docs/​wsl/​wslc-state-aware.md Migrates WSLc lifecycle documentation.
schemas/​dev/​mxc-config.schema.0.9.0-alpha.json Consolidates the alpha request schema.
schemas/​dev/​mxc-config.schema.0.9.0-dev.json Consolidates the development request schema.
scripts/​versioning/​check-contract-codegen.js Changes the expected schema root.
scripts/​versioning/​config-validation-exemptions.json Updates validation exemptions.
sdk/​dotnet/​Microsoft.Mxc.Sdk.Tests/​MxcLifecycleTests.cs Tests operation-specific .NET APIs.
sdk/​dotnet/​Microsoft.Mxc.Sdk/​MxcLifecycle.cs Exposes .NET lifecycle methods.
sdk/​node/​README.md Documents Node lifecycle methods.
sdk/​node/​src/​generated/​v0_9_0_alpha/​wire.ts Updates generated alpha wire types.
sdk/​node/​src/​generated/​wire.ts Updates generated development wire types.
sdk/​node/​src/​helper.ts Adapts Node helper routing.
sdk/​node/​src/​state-aware-helper.ts Updates lifecycle request helpers.
sdk/​node/​src/​state-aware-types.ts Revises lifecycle types.
sdk/​node/​src/​state-aware.ts Exposes operation-specific Node APIs.
sdk/​node/​tests/​unit/​state-aware.test.ts Tests the revised Node API.
sdk/​node/​tests/​unit/​wire-conformance-state-aware.test.ts Updates lifecycle wire conformance tests.
sdk/​node/​tests/​unit/​wire-conformance.test.ts Updates shared wire conformance tests.
src/​backends/​isolation_session/​common/​src/​state_aware.rs Consumes separately supplied operations.
src/​core/​mxc-sdk/​README.md Documents Rust lifecycle methods.
src/​core/​mxc-sdk/​examples/​isolation_session_console.rs Migrates the console example.
src/​core/​mxc-sdk/​examples/​sta_probe.rs Migrates the STA lifecycle probe.
src/​core/​mxc-sdk/​src/​lib.rs Exports the revised SDK surface.
src/​core/​mxc-sdk/​src/​sandbox.rs Adds operation-specific sandbox functions.
src/​core/​mxc-sdk/​src/​sandbox_operations.rs Implements lifecycle operation routing.
src/​core/​mxc-sdk/​tests/​isolation_session.rs Updates IsolationSession SDK tests.
src/​core/​mxc-sdk/​tests/​state_aware.rs Updates lifecycle SDK tests.
src/​core/​mxc_config_contract/​src/​dev/​experimental.rs Flattens experimental provision settings.
src/​core/​mxc_config_contract/​src/​dev/​mod.rs Reorganizes development contracts.
src/​core/​mxc_config_contract/​src/​dev/​one_shot.rs Refactors the former one-shot contract.
src/​core/​mxc_config_contract/​src/​dev/​request.rs Defines the unified request contract.
src/​core/​mxc_config_contract/​src/​dev/​schema.rs Generates the unified schema root.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​deprovision.rs Removes the separate deprovision contract.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​exec.rs Removes the separate exec contract.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​mod.rs Simplifies lifecycle contract modules.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​phase.rs Removes JSON phase modeling.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​provision/​containment.rs Removes duplicated provision containment.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​provision/​isolation_session.rs Removes the separate provision contract.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​provision/​mod.rs Removes provision schema composition.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​provision/​windows_sandbox.rs Removes Windows provision duplication.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​provision/​wslc.rs Removes WSLc provision duplication.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​start.rs Removes the separate start contract.
src/​core/​mxc_config_contract/​src/​dev/​state_aware/​stop.rs Removes the separate stop contract.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha.rs Updates alpha contract test registration.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures.rs Updates fixture discovery.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​deprovision/​invalid/​foreign_containment.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​deprovision/​valid/​minimal.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​exec/​invalid/​legacy_proxy.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​exec/​invalid/​missing_process.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​exec/​valid/​minimal.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​exec/​valid/​runtime_proxy.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​isolation_session_provision/​invalid/​empty_network.json Migrates provision validation coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​isolation_session_provision/​invalid/​missing_network.json Migrates provision validation coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​isolation_session_provision/​valid/​directional_network.json Migrates provision validation coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​isolation_session_provision/​valid/​directional_network_with_app_id.json Migrates App ID provision coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​isolation_session_provision/​valid/​minimal.json Migrates minimal provision coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​start/​invalid/​foreign_process.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​start/​valid/​minimal.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​stop/​invalid/​unknown_field.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​stop/​valid/​minimal.json Removes an operation-specific fixture.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​windows_sandbox_provision/​invalid/​foreign_network.json Migrates Windows provision validation.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​windows_sandbox_provision/​valid/​minimal.json Migrates Windows provision validation.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​wslc_provision/​invalid/​foreign_sandbox_id.json Migrates WSLc provision validation.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​wslc_provision/​invalid/​runtime_proxy.json Migrates WSLc proxy validation.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​wslc_provision/​valid/​directional_network.json Migrates WSLc network coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​fixtures/​wslc_provision/​valid/​minimal.json Migrates minimal WSLc coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​network.rs Updates network contract tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​one_shot.rs Updates one-shot validation tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​request.rs Adds unified request tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware.rs Revises lifecycle contract coverage.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​deprovision.rs Removes deprovision schema tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​exec.rs Removes exec schema tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​provision/​isolation_session.rs Updates IsolationSession provision tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​provision/​mod.rs Updates provision test structure.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​provision/​windows_sandbox.rs Updates Windows provision tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​provision/​wslc.rs Updates WSLc provision tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​start.rs Removes start schema tests.
src/​core/​mxc_config_contract/​tests/​v0_9_0_alpha/​state_aware/​stop.rs Removes stop schema tests.
src/​core/​mxc_config_contract/​tests/​version_boundaries/​state_aware.rs Updates version-boundary coverage.
src/​core/​mxc_engine/​src/​lib.rs Exports revised lifecycle engine APIs.
src/​core/​mxc_engine/​src/​policy/​exact/​v0_9.rs Uses the unified exact contract.
src/​core/​mxc_engine/​src/​state_aware.rs Routes explicit lifecycle operations.
src/​core/​wxc/​src/​main.rs Adds lifecycle CLI arguments.
src/​core/​wxc_common/​src/​config_contract_adapters/​dev/​mod.rs Registers revised adapters.
src/​core/​wxc_common/​src/​config_contract_adapters/​dev/​one_shot.rs Adapts unified one-shot requests.
src/​core/​wxc_common/​src/​config_contract_adapters/​dev/​state_aware.rs Applies operation-specific validation.
src/​core/​wxc_common/​src/​config_parser.rs Parses operation-neutral lifecycle JSON.
src/​core/​wxc_common/​src/​policy_identity.rs Updates lifecycle policy identity handling.
src/​core/​wxc_common/​src/​splice.rs Updates command-line splicing.
src/​core/​wxc_common/​src/​state_aware_binding_tests.rs Tests revised lifecycle binding.
src/​core/​wxc_common/​src/​state_aware_dispatch.rs Dispatches explicit lifecycle operations.
src/​core/​wxc_common/​src/​wire.rs Revises lifecycle wire types.
src/​ffi/​mxc_ffi/​examples/​attached_console_ffi.rs Migrates the FFI console example.
src/​ffi/​mxc_ffi/​src/​state_aware.rs Accepts operation and ID separately.
src/​testing/​wxc_e2e_tests/​src/​lib.rs Updates lifecycle test helpers.
src/​testing/​wxc_e2e_tests/​tests/​e2e_isolation_session_policy.rs Migrates IsolationSession policy tests.
src/​testing/​wxc_e2e_tests/​tests/​e2e_state_aware.rs Migrates lifecycle end-to-end tests.
src/​testing/​wxc_e2e_tests/​tests/​e2e_windows.rs Migrates Windows lifecycle tests.
tests/​configs/​isolation_session_state_aware_deprovision.json Removes operation-bearing deprovision JSON.
tests/​configs/​isolation_session_state_aware_exec_basic.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_cwd.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_env_absent.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_env_initial.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_env_modified.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_exit_0.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_exit_1.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_exit_2.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_read_marker.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_read_persist.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_setx_initial.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_setx_modified.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_exec_write_marker.json Removes operation-bearing exec JSON.
tests/​configs/​isolation_session_state_aware_provision.json Makes provision JSON operation-neutral.
tests/​configs/​isolation_session_state_aware_provision_appid.json Makes App ID provision JSON neutral.
tests/​configs/​isolation_session_state_aware_provision_appid_control.json Migrates App ID control configuration.
tests/​configs/​isolation_session_state_aware_provision_appid_empty.json Migrates empty App ID configuration.
tests/​configs/​isolation_session_state_aware_provision_appid_too_long.json Migrates App ID limit configuration.
tests/​configs/​isolation_session_state_aware_provision_rejected_denied.json Migrates rejected provision configuration.
tests/​configs/​isolation_session_state_aware_provision_rejected_network.json Migrates rejected network configuration.
tests/​configs/​isolation_session_state_aware_provision_rejected_ui.json Migrates rejected UI configuration.
tests/​configs/​isolation_session_state_aware_provision_with_filesystem.json Migrates filesystem provision JSON.
tests/​configs/​isolation_session_state_aware_start.json Removes operation-bearing start JSON.
tests/​configs/​isolation_session_state_aware_stop.json Removes operation-bearing stop JSON.
tests/​configs/​wslc_state_aware_deprovision.json Removes operation-bearing deprovision JSON.
tests/​configs/​wslc_state_aware_exec_basic.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_drip.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_env.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_exit_0.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_exit_1.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_exit_7.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_proxy.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_read_marker.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_rejected_filesystem.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_exec_write_marker.json Removes operation-bearing exec JSON.
tests/​configs/​wslc_state_aware_provision.json Flattens WSLc provision settings.
tests/​configs/​wslc_state_aware_provision_bridged.json Flattens bridged provision settings.
tests/​configs/​wslc_state_aware_provision_rejected_denied.json Flattens rejected provision settings.
tests/​configs/​wslc_state_aware_provision_rejected_hosts.json Flattens rejected host settings.
tests/​configs/​wslc_state_aware_provision_rejected_proxy.json Flattens rejected proxy settings.
tests/​configs/​wslc_state_aware_provision_with_filesystem.json Flattens filesystem provision settings.
tests/​configs/​wslc_state_aware_start.json Removes operation-bearing start JSON.
tests/​configs/​wslc_state_aware_stop.json Removes operation-bearing stop JSON.
tests/​policy/​state-aware-wslc-exec.json Removes operation and ID from policy JSON.
tests/​policy/​state-aware-wslc-provision.json Flattens operation-neutral provision policy.
tests/​scripts/​run_isolation_session_state_aware_tests.ps1 Passes operations through CLI arguments.
tests/​scripts/​run_windows_sandbox_state_aware_tests.ps1 Passes operations through CLI arguments.
tests/​scripts/​run_wslc_state_aware_tests.ps1 Passes operations through CLI arguments.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

exec: "ExecRequest",
stop: "StopRequest",
deprovision: "DeprovisionRequest",
one_shot: "Request",
Comment thread src/core/mxc-sdk/examples/sta_probe.rs Outdated
@@ -302,9 +336,10 @@ fn with_attached_exec_claim<T>(work: impl FnOnce() -> T) -> Option<T> {
/// [`ExecOutcome::Exited`], because the relay rejects anything else.
pub fn exec_state_aware_attached(
@@ -513,18 +556,20 @@ pub fn run_state_aware_json(
///
/// `experimental` opts in to the experimental backends, as for
/// [`run_state_aware_json`].
Copilot AI review requested due to automatic review settings September 18, 2026 20:22
| `process.{cwd,env,timeout}` | **honored** | rejected | rejected | **honored** | rejected | rejected |
| `experimental.isolation_session.provision.appId` | rejected | **honored** | n/a | n/a | n/a | n/a |
| `experimental.isolation_session.appId` | rejected | **honored** | n/a | n/a | n/a | n/a |
| `experimental.isolation_session.<another phase>.*` | rejected | rejected | rejected | rejected | rejected | rejected |

@adpa-ms adpa-ms Sep 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can get rid of this line since phase is dead

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AgentAssisted] Two more statements in this file are now inaccurate for the same reason: the bullet saying process on non-exec phases is "structurally rejected" (it is now a semantic check in the operation adapter), and the error-table row saying "fields excluded by an exact request root fail earlier as malformed_request" (there is one shared root now).

Provision filesystem and network also reach IsolationSession policy validation and surface policy_validation, not malformed_request.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The IsolationSession test script retains obsolete phase-root error assertions that will fail under the unified contract.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 3 High severity · 2 Low severity

Open (5)
Previously missed (1)

In code that hasn't changed since last review

Low severity Include wslc in the supported backend list

docs/​schema.md:442

This backend list omits wslc, even though the immediately preceding lifecycle example and provision settings document WSLc and the dispatcher supports it. Include wslc so the schema guide does not incorrectly tell API consumers that its lifecycle operations are unsupported.

Comment thread tests/scripts/run_isolation_session_state_aware_tests.ps1
"properties": {
"appId": {
"description": "Optional identifier for the calling application.\n\n**A packaged application must supply its Package Family Name in the form `PFN:<packageFamilyName>`** (for example `PFN:Contoso.App_8wekyb3d8bbwe`). An unpackaged application may pass any string. Carried inside the `sandboxId` so later lifecycle phases can recover it without the caller re-supplying it.",
"description": "Lifecycle provision application identifier.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might not want to lose all of the information from the previous comment here. The PFN format is important for the underlying OS API call.

* Optional identifier for the calling application.
*
* **A packaged application must supply its Package Family Name in the form `PFN:<packageFamilyName>`** (for example `PFN:Contoso.App_8wekyb3d8bbwe`). An unpackaged application may pass any string. Carried inside the `sandboxId` so later lifecycle phases can recover it without the caller re-supplying it.
* Lifecycle provision application identifier.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment to a previous one - please keep some of the context from the older comment about the format if passing in the PFN.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to understand, have I lost a bunch of my tests?

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d4685110-c467-408f-930e-250aab2025c4
Copilot AI review requested due to automatic review settings September 18, 2026 20:45
@jsidewhite Jeff Whiteside (jsidewhite) changed the title [API Surface] State-aware: Remove 'phase' operations from json schema [API Surface] State-aware: Add 'phase' APIs + remove 'phase' ops from schema Sep 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The rolling oracle is unintentionally narrowed, the Rust replacement API drops documented dry-run functionality, and lifecycle documentation remains inconsistent.

Review effort: Balanced
Findings: 3 High severity · 2 Low severity

Open (5)
Previously missed (4)

In code that hasn't changed since last review

Medium severity Replacement Rust API removes dry-run lifecycle support

src/​core/​mxc-sdk/​src/​sandbox_operations.rs:16

The replacement Rust API hardcodes dry_run to false for every lifecycle method, while the removed public run_state_aware_json supported dry-running all phases and the CLI/.NET surfaces still preserve that capability. Add explicit dry-run methods or an operation options parameter before retiring the old entry point so Rust callers do not lose validation-only execution.

Medium severity Keep legacy routing fields in rolling wire artifacts

src/​core/​wxc_common/​src/​wire.rs:59

This changes the rolling wxc_common::wire artifact, not just the authoritative 0.9-alpha contract. docs/versioning.md:88-105 and docs/schema-codegen.md:36-47 define mxc-config.schema.0.9.0-dev.json and generated/wire.ts as rolling differential oracles generated from this model, but these new skips remove historical routing fields from those artifacts while the rolling parser still accepts them. Keep the rolling fields schema-visible (including the analogous sandboxId and legacy provision fields below) and remove them only from mxc_config_contract::dev, then regenerate both artifact sets.

Low severity Update documentation for the single-root contract

docs/​schema.md:412

The canonical versioning documentation was not updated with this new single-root contract: docs/versioning.md:103-104 still says 0.9-alpha has eight one-shot/state-aware roots, and docs/schema-codegen.md:64-65 still documents dispatch by the JSON phase field. Update those references alongside this section; otherwise contributors will regenerate or extend the schema using the removed model.

Low severity Document WSLc as a supported state-aware lifecycle

docs/​schema.md:442

This paragraph still lists only IsolationSession and Windows Sandbox, even though this PR keeps WSLc lifecycle provisioning and the engine explicitly treats WSLc as state-aware. Include wslc so the updated lifecycle documentation does not incorrectly tell users that its operations are unsupported.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d4685110-c467-408f-930e-250aab2025c4
Copilot AI review requested due to automatic review settings September 18, 2026 21:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Several changed API and schema documents still contradict the new generated surface or omit WSLc lifecycle support.

Review effort: Balanced
Findings: 2 High severity · 2 Low severity

Open (4)
Resolved since last review (1)
Previously missed (3)

In code that hasn't changed since last review

Low severity Clarify provision is for rolling-parser compatibility only

docs/​wsl/​wslc-state-aware.md:58

This documentation still describes provision as schema/type-oracle input, but the new schemars(skip) removes that field and WslcProvisionPhase from both generated artifacts. Describe it as rolling-parser differential compatibility only so the subsystem guide matches the generated schema and TypeScript wire type.

`experimental.wslc`. Engine-side checked binding preserves an absent
config, a present empty config, and supplied `image`/`imageTarPath` values
without reparsing JSON. An omitted image remains `None` until the backend
chooses its default. The separate rolling `wire::WslcProvisionPhase` survives
only as schema/type-oracle input and test characterization, not the backend's
Low severity Include WSLc in the supported lifecycle list

docs/​schema.md:442

WSLc also implements this lifecycle and is used by the commands immediately above, so this list is now incomplete. Include wslc; otherwise readers are told that a documented supported route has not opted in.

Low severity Mark provision schema as a legacy rolling-parser representation

src/​core/​wxc_common/​src/​wire.rs:673

The comment still presents this as the current experimental.wslc.provision schema surface, although the added schemars(skip) deliberately removes it from generated schemas and exact 0.9 now uses the flat fields. Mark it as the legacy rolling-parser representation to avoid documenting a rejected configuration shape.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d4685110-c467-408f-930e-250aab2025c4
Copilot AI review requested due to automatic review settings September 18, 2026 21:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The central schema documentation incorrectly omits WSLc from the supported lifecycle backends.

Review effort: Balanced
Findings: 2 High severity · 2 Low severity

Open (4)
Previously missed (1)

In code that hasn't changed since last review

Low severity Backend list omits supported wslc route

docs/​schema.md:442

This backend list omits wslc, even though the lifecycle API and the examples immediately above support the wslc: route. That makes the updated lifecycle documentation incorrectly tell users that only two backends are available.

Comment on lines +438 to +449
fn parse_exact_state_aware_development(
json: &str,
phase: Phase,
sandbox_id: Option<&str>,
logger: &mut Logger,
) -> Result<ParsedStateAwareRequest, ParseError> {
let discriminator: RequestDiscriminator<'_> = config_deserialize::from_str(json)
.map_err(|error| ParseError::StateAware(MxcError::malformed_request(error.to_string())))?;
reject_legacy_telemetry_raw(discriminator.experimental.map(RawValue::get))
.map_err(|error| ParseError::StateAware(MxcError::malformed_request(error.to_string())))?;
let request: mxc_config_contract::dev::OneShotRequest =
deserialize_development_root(json, "lifecycle operation", true)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AgentAssisted] development_network_migration keys its backend-specific guidance on the contract labels "IsolationSession provision" and "WSLC provision", but deserialize_development_root is now only ever called with "lifecycle operation" or "one-shot", so 6 of its 10 arms are unreachable.

The effect is a wrong instruction: an isolation_session config using network.allowedHosts now gets use network.egress.allow/deny CIDR rules, which IsolationSession cannot satisfy — it accepts only the all-allow posture, which is what the previous message named.

exact_development_network_migration_guidance_is_contract_aware was updated to assert the message no longer contains IsolationSession requires, so the test now pins this under a name claiming the opposite.

Suggest keying the lookup on the selected containment so the backend-specific arms stay reachable.

Comment on lines +178 to +181
pub(super) fn operation_into_input(
request: contract::OneShotRequest,
phase: Phase,
sandbox_id: Option<&str>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AgentAssisted] This function now owns all per-operation validation that the deleted per-phase contract roots enforced structurally, including IsolationSession provision. The #[cfg(test)] #[path = "state_aware_tests/mod.rs"] mod tests; declaration was removed here, but the 7 files (16 #[test]) remain on disk and are compiled by nothing; one_shot.rs keeps its equivalent declaration.

They also cannot just be re-linked — state_aware_tests/common.rs uses adapt_request and AdaptedWireRequest::StateAware, both removed in this change.

Either port them to operation_into_input(request, phase, sandbox_id) and restore the declaration, or delete them. As it stands the new validation has no unit coverage beside it.

Comment thread src/core/wxc/src/main.rs
Comment on lines +1255 to +1267
Err(error) => {
let error = match error {
ParseError::StateAware(error) => error,
ParseError::Decode(error)
| ParseError::Version(error)
| ParseError::OneShot(error)
| ParseError::OneShotMalformed(error) => {
MxcError::malformed_request(error.to_string())
}
};
log_state_aware_dispatch_error(&mut logger, &error);
print_error_envelope(&error);
process::exit(1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AgentAssisted] This branch prints the diagnostic and envelope then exits without calling log_request_parse_rejection, so lifecycle parse rejections no longer emit the mxc.ConfigRejected audit record — log_state_aware_dispatch_error only writes a diagnostic line. One-shot parse failures still emit it via the Err arm below, and state-aware failures did too before this change, since both went through that path.

Suggest emitting the structured rejection before printing the envelope.

Comment on lines +193 to +225
Phase::Exec => {
if common.filesystem.is_some() || common.ui.is_some() {
return Err(malformed(
"filesystem and ui are not accepted by the exec operation",
));
}
StateAwareOperation::Exec {
sandbox_id: require_sandbox_id(phase, sandbox_id)?,
}
}
Phase::Start => {
reject_non_exec_process(&common, phase)?;
reject_non_exec_policy(&common, phase)?;
StateAwareOperation::Start {
sandbox_id: require_sandbox_id(phase, sandbox_id)?,
}
}
Phase::Stop => {
reject_non_exec_process(&common, phase)?;
reject_non_exec_policy(&common, phase)?;
StateAwareOperation::Stop {
sandbox_id: require_sandbox_id(phase, sandbox_id)?,
}
}
Phase::Deprovision => {
reject_non_exec_process(&common, phase)?;
reject_non_exec_policy(&common, phase)?;
StateAwareOperation::Deprovision {
sandbox_id: require_sandbox_id(phase, sandbox_id)?,
}
}
};
StateAwareInput::new(common, operation)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AgentAssisted] take_experimental runs only in provision_operation, so on exec/start/stop/deprovision common.experimental survives into StateAwareInput::new and is rejected as State-aware common input must not contain operation or one-shot field(s): experimental. That reads as though experimental is one-shot-only, but it is accepted on provision.

"experimental":{} was valid on all four of these operations before this change — the cases covering it were dropped from public_preflight_duplicate_experimental_fields_follow_the_selected_request_kind and from the policy_identity phase loop rather than re-asserted. If rejecting it is intended, reject_non_exec_policy is the natural place, with a message matching the others.

Comment on lines +704 to +706
var sandboxIdBuf = sandboxId is null
? null
: ToNullTerminatedUtf8(sandboxId.Value.Value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[AgentAssisted] Sandbox IDs now cross the ABI as raw NUL-terminated strings and ToNullTerminatedUtf8 does not reject an embedded NUL, so CStr::from_ptr truncates at it — iso:<valid>\0suffix addresses iso:<valid>. Previously the ID travelled inside the JSON envelope, where \u0000 survived to reach validation and be rejected.

Low likelihood while IDs only originate from ProvisionSandbox, but the failure is a silent wrong target. Suggest rejecting embedded NUL in SandboxId or in the marshalling helper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d4685110-c467-408f-930e-250aab2025c4
Copilot AI review requested due to automatic review settings September 18, 2026 22:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The WSLc guide still describes removed JSON routing and deleted fixtures, and the schema guide omits WSLc from its supported-backend list.

Review effort: Balanced
Findings: 2 High severity · 2 Low severity

Open (4)
Previously missed (2)

In code that hasn't changed since last review

Low severity Add WSLc to supported state-aware operation capabilities

docs/​schema.md:435

This section now documents WSLc lifecycle provisioning, but the capability list immediately below still says only IsolationSession and Windows Sandbox support state-aware operations. Include wslc so readers are not told that the documented operation is unsupported.

Low severity Update WSLc guide for new operation-neutral wire contract

docs/​wsl/​wslc-state-aware.md:54

This path update leaves the rest of the WSLc guide describing the removed wire contract. Lines 63–65 still say sandboxId is carried in JSON, lines 114–118 describe phase-specific request roots, and lines 180–195 instruct users to substitute IDs into post-provision fixture files that this PR deletes. Update those sections to use operation-neutral JSON plus --operation/--sandbox-id; line 57 should also stop calling the skipped WslcProvisionPhase a schema/type-oracle input.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d4685110-c467-408f-930e-250aab2025c4
Copilot AI review requested due to automatic review settings September 18, 2026 22:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The cross-language API, FFI, schema, parser, and backend migration requires final human validation, and two documentation issues remain.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity · 3 Low severity

Open (5)
Resolved since last review (1)

Comment on lines +465 to +466
let sandbox_id = serde_json::from_str::<serde_json::Value>(&provisioned)?
["result"]["sandboxId"].as_str().unwrap().to_owned();
Comment thread docs/schema.md
Comment on lines 440 to +442
State-aware-capable backends today: `isolation_session` and `windows_sandbox`
(both Windows-only, both still experimental). The dispatcher rejects
state-aware envelopes for backends that have not opted in.
lifecycle operations for backends that have not opted in.

This branch has not been deployed

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

Labels

Copilot-Instructions PR modifies Copilot instruction files (.github/copilot-instructions.md or .github/instructions/)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Surface] State-aware: Remove 'phase' operations from json schema

3 participants