Uh oh!
There was an error while loading. Please reload this page.
Resolve the command before the request is parsed - #969
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Moves CLI command resolution before request parsing and makes Rust SDK requests complete at construction.
Changes:
- Adds backend/phase probing and command splicing.
- Requires commands in request-builder APIs and removes
set_script. - Updates tests, FFI callers, and documentation.
Show a summary per file
| File | Description |
|---|---|
src/ffi/mxc_ffi/src/streaming.rs | Passes commands during request construction. |
src/ffi/mxc_ffi/src/lib.rs | Updates run-to-completion request creation. |
src/core/wxc/src/main.rs | Integrates pre-parse CLI command resolution and tests. |
src/core/wxc_common/src/state_aware_dispatch.rs | Exposes backend-prefix resolution internally. |
src/core/wxc_common/src/splice.rs | Adds JSON command splicing. |
src/core/wxc_common/src/probe.rs | Adds backend and phase probes. |
src/core/wxc_common/src/lib.rs | Registers new internal modules. |
src/core/wxc_common/src/config_parser.rs | Applies CLI commands before typed parsing. |
src/core/mxc-sdk/tests/streaming.rs | Updates streaming test request construction. |
src/core/mxc-sdk/tests/streaming_processcontainer.rs | Updates ProcessContainer streaming test. |
src/core/mxc-sdk/tests/sdk_helpers.rs | Updates SDK helper tests. |
src/core/mxc-sdk/tests/sandbox.rs | Updates sandbox tests. |
src/core/mxc-sdk/src/lib.rs | Revises SDK examples. |
src/core/mxc-sdk/README.md | Documents command-at-build usage. |
src/core/mxc_engine/src/policy.rs | Requires commands in builder APIs. |
src/core/mxc_engine/src/dispatch.rs | Updates dispatch tests. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 16/16 changed files
- Comments generated: 3
- Review effort level: Balanced
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Darren Hoehna (dhoehna)
left a comment
There was a problem hiding this comment.
Besides the comments about de-duplication the code is sound. I am concerned to see duplicate methods for one-shot and state-aware. Merging those paths is a future issue.
This PR updates the version-specific parser plan for the current state: Phase 5 is fully merged, Phase 6 is awaiting signoff in PR #968, and Phase 6.5 is rebased onto it as a single commit. Details * Rewrite the status paragraph: #966 merged, #968 awaiting a final signoff and now carrying the directional networking port, Phase 6.5 rebased onto it, and Phase 7a open as PR #969. * Mark steps 1 through 5 of the publication sequence with their outcomes, and record that the step 2 port landed inside #968 rather than separately because a review of that pull request identified the same gap. * Add a "Phase 6.5 as rebased" section describing what the branch contains and the two version-marker errors the rebase surfaced, both found by a failing test rather than by inspection. * Correct the development version suffix from 0.9.0-dev to 0.9.0-alpha throughout the contract-side text, leaving the rolling-artifact references unchanged since -dev remains correct there. * Mark the fixture schema reference and the registry path items of the immediate remediation as done, noting that the stable artifact itself is published by the old stack rather than by this work. Tests * Documentation-only change; no build, lint, or test gate applies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a8e0d88-21dd-48e5-8e44-df2393b8a664
3b44ef1 to
6581290CompareThere was a problem hiding this comment.
Review details
Suppressed comments (4)
src/core/mxc-sdk/tests/streaming.rs:36
- This identifier is misspelled, so the
mxc-sdkstreaming integration-test target does not compile. Use the existingcommandparameter.
let request = build_request(&policy, commmand, None).expect("build_request should succeed");
src/core/wxc_common/src/splice.rs:14
- Parsing into
serde_json::Valuebefore the real typed parser silently collapses duplicate object keys. With a CLI command, a request containing duplicateprocess,network, or other policy sections is therefore accepted using the last value instead of being rejected as a duplicate field, potentially changing the enforced policy. Preserve the original structure during splicing or explicitly reject duplicate keys before converting toValue.
let mut doc: Value = serde_json::from_str(json).ok()?;
src/core/wxc_common/src/splice.rs:22
- Serializing the modified DOM into a compact string moves every subsequent typed parse error to line 1, contradicting
parse_mxc_request_json's source-location guarantee. For example, an invalid multilinefilesystemfield with a CLI command no longer reports its original line/column. Splice into the original source text (or retain an offset map) rather than reserializing the whole document.
Some(Spliced {
json: serde_json::to_string(&doc).ok()?,
src/core/wxc_common/src/config_parser.rs:254
- Command-rendering failures are always classified as
Decode, even afterphaseidentified a state-aware exec request. Previously this path emitted a state-aware stdout envelope; it now emits the pre-discrimination stderr diagnostic, contrary toParseError's routing contract. Classify this error asStateAwarewhenphase.is_some()(and apply the same rule to the empty-command branch below).
let command = cmdline_from_argv_for_context(argv, context).map_err(|e| {
ParseError::Decode(WxcError::ConfigParse(format!(
"invalid CLI command override: {e}"
)))
})?;
- Files reviewed: 16/16 changed files
- Comments generated: 2
- Review effort level: Balanced
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This PR updates the version-specific parser plan for the current state: Phase 5 is fully merged, Phase 6 is awaiting signoff in PR #968, and Phase 6.5 is rebased onto it as a single commit. Details * Rewrite the status paragraph: #966 merged, #968 awaiting a final signoff and now carrying the directional networking port, Phase 6.5 rebased onto it, and Phase 7a open as PR #969. * Mark steps 1 through 5 of the publication sequence with their outcomes, and record that the step 2 port landed inside #968 rather than separately because a review of that pull request identified the same gap. * Add a "Phase 6.5 as rebased" section describing what the branch contains and the two version-marker errors the rebase surfaced, both found by a failing test rather than by inspection. * Correct the development version suffix from 0.9.0-dev to 0.9.0-alpha throughout the contract-side text, leaving the rolling-artifact references unchanged since -dev remains correct there. * Mark the fixture schema reference and the registry path items of the immediate remediation as done, noting that the stable artifact itself is published by the old stack rather than by this work. Tests * Documentation-only change; no build, lint, or test gate applies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a8e0d88-21dd-48e5-8e44-df2393b8a664
This PR updates the version-specific parser plan for the current state: Phase 5 is fully merged, Phase 6 is awaiting signoff in PR #968, and Phase 6.5 is rebased onto it as a single commit. Details * Rewrite the status paragraph: #966 merged, #968 awaiting a final signoff and now carrying the directional networking port, Phase 6.5 rebased onto it, and Phase 7a open as PR #969. * Mark steps 1 through 5 of the publication sequence with their outcomes, and record that the step 2 port landed inside #968 rather than separately because a review of that pull request identified the same gap. * Add a "Phase 6.5 as rebased" section describing what the branch contains and the two version-marker errors the rebase surfaced, both found by a failing test rather than by inspection. * Correct the development version suffix from 0.9.0-dev to 0.9.0-alpha throughout the contract-side text, leaving the rolling-artifact references unchanged since -dev remains correct there. * Mark the fixture schema reference and the registry path items of the immediate remediation as done, noting that the stable artifact itself is published by the old stack rather than by this work. Tests * Documentation-only change; no build, lint, or test gate applies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a8e0d88-21dd-48e5-8e44-df2393b8a664
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This PR updates the version-specific parser plan for the current state: Phase 5 is fully merged, Phase 6 is awaiting signoff in PR #968, and Phase 6.5 is rebased onto it as a single commit. Details * Rewrite the status paragraph: #966 merged, #968 awaiting a final signoff and now carrying the directional networking port, Phase 6.5 rebased onto it, and Phase 7a open as PR #969. * Mark steps 1 through 5 of the publication sequence with their outcomes, and record that the step 2 port landed inside #968 rather than separately because a review of that pull request identified the same gap. * Add a "Phase 6.5 as rebased" section describing what the branch contains and the two version-marker errors the rebase surfaced, both found by a failing test rather than by inspection. * Correct the development version suffix from 0.9.0-dev to 0.9.0-alpha throughout the contract-side text, leaving the rolling-artifact references unchanged since -dev remains correct there. * Mark the fixture schema reference and the registry path items of the immediate remediation as done, noting that the stable artifact itself is published by the old stack rather than by this work. Tests * Documentation-only change; no build, lint, or test gate applies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a8e0d88-21dd-48e5-8e44-df2393b8a664
This PR updates the version-specific parser plan for the current state: Phase 5 is fully merged, Phase 6 is awaiting signoff in PR #968, and Phase 6.5 is rebased onto it as a single commit. Details * Rewrite the status paragraph: #966 merged, #968 awaiting a final signoff and now carrying the directional networking port, Phase 6.5 rebased onto it, and Phase 7a open as PR #969. * Mark steps 1 through 5 of the publication sequence with their outcomes, and record that the step 2 port landed inside #968 rather than separately because a review of that pull request identified the same gap. * Add a "Phase 6.5 as rebased" section describing what the branch contains and the two version-marker errors the rebase surfaced, both found by a failing test rather than by inspection. * Correct the development version suffix from 0.9.0-dev to 0.9.0-alpha throughout the contract-side text, leaving the rolling-artifact references unchanged since -dev remains correct there. * Mark the fixture schema reference and the registry path items of the immediate remediation as done, noting that the stable artifact itself is published by the old stack rather than by this work. Tests * Documentation-only change; no build, lint, or test gate applies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2a8e0d88-21dd-48e5-8e44-df2393b8a664
e26201e to
3a295c0CompareThere was a problem hiding this comment.
Copilot review overview
Review tier: Balanced
Findings: 2
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/splice.rs — process: null now bypasses the CLI override: deserializing it as RawObject fails, so the… |
Pre-existing issues (2)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/config_parser.rs — These branches now return probe/override errors before the typed parser runs, changing error… View comment | |
src/core/mxc_engine/src/policy.rs — This migration replaced the test's existing Some("test-container") argument with None, leaving… View comment |
Issues resolved since last review (4)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/splice.rs — A non-string process.commandLine is currently overwritten before typed deserialization, so… View resolved comment | |
src/core/mxc_engine/src/policy.rs — The API change leaves tests/isolation_session.rs:109,128 calling this function with the old… View resolved comment | |
src/core/wxc_common/src/config_parser.rs — Command-rendering failures are always classified as Decode, even after phase was successfully… View resolved comment | |
src/core/wxc_common/src/splice.rs — Round-tripping the unvalidated policy through serde_json::Value changes the parser's validation… View resolved comment |
Suppressed comments (1)
src/core/wxc_common/src/config_parser.rs:242
- The state-aware backend probe is surfaced directly, so parser-owned
sandboxIdfailures no longer retain their existing diagnostics. For example, an exec request with"sandboxId": 42previously went throughconfig_deserializeand reported thesandboxIdJSON path; this probe now emits plain serde text before the typed parser runs (and a missing ID also changes fromphase exec requires a sandboxIdto a new message). Pass through probe failures caused by malformed/missing field values so the typed parser and normal backend resolution preserve the established error text; only use the probe result when it successfully identifies a backend.
let backend =
crate::probe::probe_state_aware_backend(json).map_err(ParseError::StateAware)?;
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Copilot review overview
Review tier: Balanced
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/config_parser.rs — splice_command returning None does not imply the typed parser will reject the document.… |
Issues resolved since last review (2)
| Severity | Finding |
|---|---|
docs/state-aware-lifecycle/mxc-state-aware-sandbox-api.md — This example propagates apply_cli_command failures immediately with ?, contradicting the… View resolved comment | |
src/core/wxc_common/src/splice.rs — The override can now hide an invalid policy command. A non-empty string containing \u0000… View resolved comment |
Uh oh!
There was an error while loading. Please reload this page.
e294f68 to
63cc982CompareThere was a problem hiding this comment.
Copilot review overview
Review tier: Balanced
Findings: 1
New issues introduced by this change (1)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/config_parser.rs — This logs the override before typed parsing has succeeded. If any unrelated policy field is… |
Issues resolved since last review (1)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/config_parser.rs — splice_command returning None does not imply the typed parser will reject the document.… View resolved comment |
Uh oh!
There was an error while loading. Please reload this page.
63cc982 to
499fcdaCompare499fcda to
2675e62CompareThere was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The API migration is complete and the new parsing behavior has comprehensive edge-case coverage.
Review tier: Balanced
Findings: None
Issues resolved since last review (1)
| Severity | Finding |
|---|---|
src/core/wxc_common/src/config_parser.rs — This logs the override before typed parsing has succeeded. If any unrelated policy field is… View resolved comment |
This PR records that PR #969 now points to the verified, squashed Phase 7a redux implementation. Details * Note the local and remote branch replacement performed with --force-with-lease. * Replace the obsolete pending-push status in the version-specific parser plan. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 651084c2-3d1e-4824-917a-6994d62feba0
This PR updates the Phase 7a implementation record for the final rebase and the consolidated command-source design. Details * Record PR #969 at rebased tip 2675e62 on origin/main 878936a. * Replace deleted backend-probe names with CommandSource and its exhaustive containment parity test. Tests * git diff --check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 651084c2-3d1e-4824-917a-6994d62feba0
This PR updates the parser roadmap for the squashed Phase 7.2 implementation and its stacked pull request. Details * Record Phase 7.2 on the phase7b branch at 401ba0c. * Link PR #1091 and its Phase 7a base PR #969 in the status and delivery table. Tests * git diff --check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 651084c2-3d1e-4824-917a-6994d62feba0
Uh oh!
There was an error while loading. Please reload this page.
2675e62 to
f609a17CompareThere was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Two updated documents incorrectly claim command-less templates are invalid under every supported JSON schema.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 2
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
README.md — The “not schema-valid” claim is not true for every supported schema:… | |
docs/schema.md — This conflates runtime completeness with JSON Schema validity. In particular, the immutable 0.8… |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
f609a17 to
fff9cf3CompareThere was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The new splice path regresses trailing-command templates containing "process": null.
Review tier: Balanced
Findings: None
Issues resolved since last review (2)
| Severity | Finding |
|---|---|
docs/schema.md — This conflates runtime completeness with JSON Schema validity. In particular, the immutable 0.8… View resolved comment | |
README.md — The “not schema-valid” claim is not true for every supported schema:… View resolved comment |
Suppressed comments (1)
src/core/wxc_common/src/splice.rs:172
- A trailing command no longer completes a template with
"process": null. The previous relaxed parse treated this as an absent optional process and applied the CLI command afterward; this splice instead returnsNone, so typed parsing now fails with “'process' section is required.” Handle JSONnulllike a missing process while leaving other non-object values for typed validation.
MemberMatch::Unique(process_raw) => {
let process_source = process_raw.get();
let process: RawObject<'_> = serde_json::from_str(process_source).ok()?;
This PR changes CLI command handling so trailing commands are resolved and inserted before request parsing, and Rust SDK requests receive their command at construction time. It preserves behavior for valid requests and requests without a trailing CLI command; command-preparation failures remain entry-point errors when the command and policy are independently invalid. Details * Probe the request phase and reuse one duplicate-preserving raw source pass to select backend-specific quoting and edit process.commandLine. * Keep typed validation authoritative for the effective document, route request errors through one production helper, and log replacements only after parsing succeeds. * Require commands in request-builder APIs, remove post-build script mutation, and migrate SDK and FFI callers with direct validation coverage. * Document native CLI syntax, state-aware exec restrictions, and the distinction between independently executable requests and CLI templates. Tests * cargo fmt --all -- --check * cargo check --workspace --all-targets * cargo clippy --workspace --all-targets -- -D warnings * cargo test --workspace * cargo check -p mxc_engine --tests --target x86_64-apple-darwin Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0f04437d-4a05-487a-b402-4ed4c774e8e0
fff9cf3 to
aa6c12dCompareThere was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Null process templates regress, and command-render failures lose rejection classification, attribution, and telemetry.
Review tier: Balanced
Findings: None
Suppressed comments (2)
src/core/wxc_common/src/splice.rs:172
process: nullis a valid “absent process” representation for the wire model (Option<Process>), and the previousallow_missing_commandpath accepted it when trailing CLI arguments supplied the command. ParsingnullasRawObjectfails here, so the source is left unchanged and the typed parser now rejects the request instead of applying the override. Treat a null process value like a missing process and replace it with an object containingcommandLine; cover both one-shot and state-aware exec templates.
MemberMatch::Unique(process_raw) => {
let process_source = process_raw.get();
let process: RawObject<'_> = serde_json::from_str(process_source).ok()?;
src/core/wxc_common/src/config_parser.rs:385
- Encoding command-render failures as generic
Decode/StateAwareerrors loses their origin. The new main path records valid-JSON one-shot failures asmalformed_jsonand state-aware failures asschema_violationwith unknown backend/phase, then exits before telemetry initialization; the removed paths usedInvalidCommandOverride, retained backend/phase attribution, and emitted early-exit telemetry. Preserve a typed command-override error with its routing/context and handle it through the dedicated rejection and telemetry paths.
let command = cmdline_from_argv_for_context(argv, context).map_err(|e| match phase {
None => ParseError::Decode(WxcError::ConfigParse(format!(
"invalid CLI command override: {e}"
))),
Some(_) => ParseError::StateAware(MxcError::malformed_request(format!(



Resolve the command before the request is parsed
This PR changes CLI command handling so trailing commands are resolved and
inserted before request parsing, and Rust SDK requests receive their command at
construction time. It preserves behavior for valid requests and requests
without a trailing CLI command; command-preparation failures remain entry-point
errors when the command and policy are independently invalid.
Details
select backend-specific quoting and edit
process.commandLine.errors through one production helper, and log replacements only after parsing
succeeds.
and migrate SDK and FFI callers with direct validation coverage.
between complete schema-valid requests and CLI templates.
Tests
cargo fmt --all -- --checkcargo check --workspace --all-targetscargo clippy --workspace --all-targets -- -D warningscargo test --workspacecargo check -p mxc_engine --tests --target x86_64-apple-darwinMicrosoft Reviewers: Open in CodeFlow