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
Phase 3c: formalize the three version axes and the negotiation flow (#582)
This PR rewrites the conceptual sections of docs/versioning.md to match the
post-3a/3b reality. It formalizes the three independent, never-conflated version
axes and replaces the old version-centric "Version Negotiation" steps with the
three-stage, capability-driven runtime flow.
Details:
- Add a "Three version axes" section: schema/config version (the version field;
semver; 0.6.x floor through 0.8.x dev ceiling; major.minor compared), product
version (Rust workspace + npm; independent; check-version-sync.js), and host
capability (negotiated at runtime, never a string in the config). States the
Phase 3a invariant: schema version no longer selects the Windows backend.
- Rewrite "Version Negotiation" as three ordered stages: (1) schema-range check
at the trust boundary; (2) containment resolve (abstract process/vm intent ->
concrete backend per host, independent of version); (3) host-capability
negotiate (BaseContainer when is_base_container_usable(), else AppContainer
BFS/DACL, logged; the only fallback). Updates the Data Flow diagram to match.
- Correct the BaseContainer OS handshake: today MXC uses a fixed
SANDBOX_SPEC_VERSION and calls Experimental_CreateProcessInSandbox directly;
the EnumerateSandboxSpecVersionInfo spec-version handshake is marked
forward-looking / not yet implemented (it had been written as current behavior).
- Tighten the Error Contract: schema-range, capability (BackendUnavailable on the
ScriptResponse / SDK spawn paths), and policy-unsupported (e.g. deniedPaths)
failures are typed and actionable; security policy never fuzzy-falls-back.
- Fixups surfaced while editing: bump a stale 0.4.0 example to 0.6.0-alpha; note
retired 0.4/0.5 stable schemas are kept as artifacts; correct a promotion-step
reference to a non-existent parser symbol.
Tests:
- Docs-only change; no code or CI gates affected. Draft fact-checked against
config_parser.rs, models.rs, fallback_detector.rs, dispatcher.rs, and
base_container_runner.rs (SANDBOX_SPEC_VERSION = "0.1.0",
Experimental_CreateProcessInSandbox).
Generated-with: claude-opus-4.8
Co-authored-by: Gudge <gudge@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@@ -12,8 +12,8 @@ The `version` field in SandboxPolicy must match the MXC config
12
12
JSON version: they are the same version, tied 1:1.
13
13
14
14
When a consumer specifies a SandboxPolicy version (e.g.,
15
-
`0.4.0`), MXC creates the corresponding configuration using the
16
-
`0.4.0` schema.
15
+
`0.6.0-alpha`), MXC creates the corresponding configuration using the
16
+
`0.6.0-alpha` schema.
17
17
18
18
```typescript
19
19
// sdk/node/src/types.ts
@@ -43,19 +43,53 @@ Per [semver.org](https://semver.org/):
43
43
-**Minor** (x.Y.0) — new features, backward compatible
44
44
-**Major** (X.0.0) — breaking changes
45
45
46
+
## The three version axes
47
+
48
+
MXC tracks three independent "versions" that are deliberately **never
49
+
conflated**. Each answers a different question and changes for different
50
+
reasons:
51
+
52
+
| Axis | What it describes | Where it lives | Who decides it |
53
+
|---|---|---|---|
54
+
|**Schema (config) version**| The *shape* of the config JSON — which fields exist and what values they accept. | The `version` field in the config / `SandboxPolicy`. | The config author. |
55
+
|**Product version**| The MXC *binaries and npm package* that do the work. | Rust workspace version (`src/Cargo.toml`) + `sdk/package.json`. | The release. |
56
+
|**Host capability**| What the *running OS* can actually enforce (e.g. whether the BaseContainer sandbox API is usable, velocity keys, Hyper-V). | Negotiated at runtime — **never a string in the config**. | The host, probed at execution time. |
57
+
58
+
-**Schema version** is semver and is checked at the trust boundary: the parser
59
+
accepts the `0.6.x` floor line through the `0.8.x` dev-ceiling line (the
60
+
canonical min/max constants are currently `0.6.0-alpha` and `0.8.0-alpha` in
61
+
`schemas/schema-version.json`), and the SDK mirrors that range. Only
62
+
`major.minor` is compared — patch and pre-release labels are ignored — and both
63
+
back-dated and forward-dated versions are rejected.
64
+
-**Product version** tracks the shipped artifacts and moves independently of the
65
+
schema version; a binary release can fix bugs without changing the config shape.
66
+
`scripts/check-version-sync.js` keeps the Rust workspace and npm versions in
67
+
step, and `scripts/versioning/check-schema-versions.js` keeps the schema-version
68
+
constants in step — but the two axes are not tied to each other.
69
+
-**Host capability** is resolved by runtime negotiation, not by a version string.
70
+
As of Phase 3a the schema `version` no longer selects the Windows backend:
71
+
ProcessContainer resolves to BaseContainer or AppContainer purely by host
72
+
capability (see [Version Negotiation](#version-negotiation)). An identical
73
+
config runs the same way regardless of which (in-range) schema version it
74
+
declares.
75
+
46
76
## Schema Shipping Model
47
77
48
78
```
49
79
mxc/schemas/
50
80
├── stable/
51
-
│ ├── mxc-config.schema.0.4.0-alpha.json
52
-
│ ├── mxc-config.schema.0.5.0-alpha.json
53
-
│ ├── mxc-config.schema.0.6.0-alpha.json
81
+
│ ├── mxc-config.schema.0.4.0-alpha.json (retired — below the supported floor)
82
+
│ ├── mxc-config.schema.0.5.0-alpha.json (retired — below the supported floor)
0 commit comments