Schema codegen: generate the dev schema from the Rust wire model#543
Open
MGudgin wants to merge 2 commits into
Open
Schema codegen: generate the dev schema from the Rust wire model#543MGudgin wants to merge 2 commits into
MGudgin wants to merge 2 commits into
Conversation
e181a70 to
75930ab
Compare
This PR changes the committed dev JSON Schema to be generated from the Rust wire model (`wxc_common::wire`) instead of hand-authored, so the schema can no longer drift from the type definitions that form the parser's trust boundary. Details: - Extend the wire model to cover the full config surface (one-shot + state-aware: a Phase enum, top-level phase/sandboxId, per-phase isolation_session nesting). Stable surface stays strict (deny_unknown_fields); experimental stays permissive. - Post-process the generated output: inject the canonical $id, normalize schemars' non-standard integer formats to draft-07 (minimum:0 for unsigned), and float the root metadata ($schema/$id/title/description) to the top via render_root_ordered (self-contained, no serde_json feature, so nested objects stay alphabetical and the schema diff stays minimal). - Set title via #[schemars(title)] and description via the MxcConfig doc comment (replacing the stale "one-shot request" wording). - Add scripts/versioning/check-schema-codegen.js: a regenerate + diff CI gate (line-ending-insensitive) wired into the Versioning Checks job. - Cross-field allOf rules are intentionally left out of the schema; the parser enforces them. Document the architecture + a schema-equivalence analysis in docs/schema-codegen.md, and note in copilot-instructions that the dev schema is generated (do not hand-edit). Tests: - 167/167 corpus configs validate against the generated schema. - Codegen + schema-version + config-sync CI gates green. - wxc_common 338 tests pass; clippy (incl. --features schema-gen) + fmt clean. - Verified the generated schema is semantically identical to the prior hand-written one via a deep-sorted comparison. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
75930ab to
227691d
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR makes wxc_common::wire the single source of truth for the dev MXC config JSON Schema by generating schemas/dev/mxc-config.schema.0.8.0-dev.json from a dedicated Rust wire model, and adds a CI gate to prevent schema drift.
Changes:
- Add a
wxc_common::wireRust wire model (behind aschema-genfeature) plus amxc_schema_gentool to emit the dev schema from the model. - Add
scripts/versioning/check-schema-codegen.jsand wire it into the GitHub Actions “Versioning Checks” job to regenerate-and-diff the committed schema (line-ending-insensitive). - Update the committed dev schema and adjust macOS example configs to match the new schema surface (e.g., removing the old
seatbelt.mode).
Show a summary per file
| File | Description |
|---|---|
| tests/examples/15_mac_hello_world.json | Removes legacy seatbelt block fields to align examples with the current seatbelt config surface. |
| tests/examples/16_mac_deny_network.json | Same as above for the deny-network example. |
| tests/examples/17_mac_deny_filesystem.json | Same as above for the deny-filesystem example. |
| tests/examples/18_mac_filesystem_access.json | Same as above for filesystem allow example. |
| tests/examples/19_mac_network_restricted.json | Same as above for restricted network example. |
| tests/examples/20_mac_combined_restrictions.json | Same as above for combined restrictions example. |
| tests/examples/21_mac_python_info.json | Same as above for python-info example. |
| tests/examples/22_mac_network_allow_all.json | Same as above for allow-all network example. |
| tests/examples/23_mac_blocked_hosts_unsupported.json | Same as above for blocked-hosts example. |
| tests/examples/24_mac_ui_disabled.json | Same as above for UI-disabled example. |
| tests/examples/25_mac_ui_clipboard_enabled.json | Same as above for clipboard-enabled example. |
| src/tools/mxc_schema_gen/src/main.rs | New CLI tool that calls wxc_common::wire::generate_config_schema_json() and writes the schema to stdout/file. |
| src/tools/mxc_schema_gen/Cargo.toml | Adds the schema generator tool crate and depends on wxc_common with schema-gen. |
| src/core/wxc_common/src/wire.rs | Introduces the dedicated wire model and schema post-processing (inject $id, normalize integer formats, root key ordering). |
| src/core/wxc_common/src/lib.rs | Exposes wire behind the schema-gen feature. |
| src/core/wxc_common/Cargo.toml | Adds the schema-gen feature and optional schemars dependency. |
| src/Cargo.toml | Adds tools/mxc_schema_gen to the Rust workspace. |
| src/Cargo.lock | Records new dependencies for schema generation tooling (schemars, etc.). |
| scripts/versioning/check-schema-codegen.js | New gate script that regenerates the schema and diffs against the committed dev schema. |
| schemas/dev/mxc-config.schema.0.8.0-dev.json | Updated dev schema artifact to the code-generated output. |
| docs/schema-codegen.md | New documentation describing the schema codegen architecture, gates, and equivalence notes. |
| .github/workflows/Versioning.Checks.Job.yml | Adds the schema codegen check to the Versioning Checks workflow. |
Copilot's findings
- Files reviewed: 22/23 changed files
- Comments generated: 7
…sage) This PR addresses Copilot review feedback on the schema-codegen change. Details: - Advertise the 1..=65535 port range on the wire model's port fields (PortMapping.windowsPort/containerPort, Proxy.localhost) via #[schemars(range)], so the generated schema matches the parser (which rejects port 0) instead of allowing minimum:0. - Fix the regeneration command everywhere it appears (mxc_schema_gen usage, check-schema-codegen.js failure message, docs/schema-codegen.md, copilot-instructions): use `cargo run --manifest-path src/Cargo.toml ...` since the Cargo workspace is src/ and the repo root has no Cargo.toml. - Print the generator's "wrote schema" status to stdout instead of stderr so the CI codegen gate (which suppresses stdout, inherits stderr for build errors) stays quiet on success. Tests: - 167/167 corpus configs still validate; port fields now show minimum:1/maximum:65535. - Codegen gate green; wxc_common 338 tests; clippy (incl. --features schema-gen) + fmt clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
Thanks for the review. Addressed in c166225:
Declined the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📖 Description
This PR changes the committed dev JSON Schema to be generated from the Rust wire model (
wxc_common::wire) instead of hand-authored, so the schema can no longer drift from the type definitions that form the parser's trust boundary.Details:
Phaseenum, top-levelphase/sandboxId, per-phaseisolation_sessionnesting). Stable surface stays strict (deny_unknown_fields); experimental stays permissive.$id, normalize schemars' non-standard integer formats to draft-07 (minimum:0for unsigned), and float the root metadata ($schema/$id/title/description) to the top viarender_root_ordered(self-contained, noserde_jsonfeature, so nested objects stay alphabetical and the schema diff stays minimal).titlevia#[schemars(title)]anddescriptionvia theMxcConfigdoc comment (replacing the stale "one-shot request" wording).scripts/versioning/check-schema-codegen.js: a regenerate + diff CI gate (line-ending-insensitive) wired into the Versioning Checks job.allOfrules are intentionally left out of the schema; the parser enforces them. Document the architecture + a schema-equivalence analysis indocs/schema-codegen.md, and note in copilot-instructions that the dev schema is generated (do not hand-edit).🔗 References
Part of the schema-versioning remediation effort (follows the phase 0/1 work in #508 and #509). A follow-up rewires the parser to deserialize directly into the wire model and deletes the
Raw*structs.🔍 Validation
wxc_common338 tests pass; clippy (incl.--features schema-gen) + fmt clean.definitions/$ref— intentionally-closed nested objects, and added documentation).