Publish the mxc-sdk crate closure to crates.io - #716
Publish the mxc-sdk crate closure to crates.io#716Darren Hoehna (dhoehna) wants to merge 40 commits into
Conversation
Make the mxc-sdk crate closure publishable and add official-build packaging plus a guarded ESRP release flow with dependency ordering, checksum verification, propagation waits, and safe retries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f199a77f-51ec-4441-baa5-b87df8177b83
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f199a77f-51ec-4441-baa5-b87df8177b83
There was a problem hiding this comment.
Pull request overview
Adds opt-in packaging and ESRP publication of the mxc-sdk crate dependency closure to crates.io.
Changes:
- Adds publishable metadata and versioned internal dependencies for 18 crates.
- Adds packaging, dependency-order validation, checksum verification, and retry-safe publishing.
- Keeps crate packaging disabled pending Cargo #17196 resolution.
Reviewed changes
Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/Cargo.toml |
Adds repository metadata and dependency versions. |
src/mxc_telemetry/Cargo.toml |
Adds repository metadata. |
src/core/wxc_common/Cargo.toml |
Adds package metadata and NanVix version. |
src/core/mxc-sdk/Cargo.toml |
Adds repository metadata. |
src/core/mxc_pty/Cargo.toml |
Adds publishable metadata. |
src/core/mxc_engine/Cargo.toml |
Adds repository metadata. |
src/core/generated/base_container_specification/Cargo.toml |
Makes generated bindings publishable. |
src/backends/wslc/common/Cargo.toml |
Adds publishable metadata. |
src/backends/windows_sandbox/lifecycle/Cargo.toml |
Adds license and package metadata. |
src/backends/windows_sandbox/common/Cargo.toml |
Adds publishable metadata. |
src/backends/seatbelt/common/Cargo.toml |
Adds publishable metadata. |
src/backends/nanvix/runner/Cargo.toml |
Adds metadata and dependency version. |
src/backends/nanvix/common/Cargo.toml |
Adds repository metadata. |
src/backends/lxc/common/Cargo.toml |
Adds publishable metadata. |
src/backends/isolation_session/common/Cargo.toml |
Adds publishable metadata. |
src/backends/isolation_session/bindings/Cargo.toml |
Makes bindings publishable. |
src/backends/hyperlight/common/Cargo.toml |
Adds publishable metadata. |
src/backends/bubblewrap/common/Cargo.toml |
Adds publishable metadata. |
src/backends/appcontainer/common/Cargo.toml |
Adds publishable metadata. |
.azure-pipelines/templates/Publish.CratesIo.Job.yml |
Defines ordered ESRP publication workflow. |
.azure-pipelines/templates/Package.Crates.Job.yml |
Packages the crate closure as an artifact. |
.azure-pipelines/templates/1ES.Build.Stages.yml |
Adds the opt-in packaging stage. |
.azure-pipelines/scripts/crates_release.py |
Validates, stages, and verifies crate releases. |
.azure-pipelines/1ES.Release.yml |
Adds selectable npm and crates.io release stages. |
.azure-pipelines/1ES.Build.Official.yml |
Exposes the crate-packaging parameter. |
| default: false | ||
|
|
||
| jobs: | ||
| - deployment: publish_crates |
There was a problem hiding this comment.
Good catch - this was correct and would have failed validation before any step ran.
Confirmed against the 1ES release-job docs, whose deployment-job example annotates the field as required verbatim: environment: MyEnvironment # Required, name of the environment.
Fixed in d408846 by taking your second suggestion: converted to a standard job with templateContext.type: releaseJob and flattened strategy.runOnce.deploy.steps into plain steps:. That matches the NPM release job already working in 1ES.Release.yml, and it avoids provisioning an ADO Environment (and the approval gates that come with it) purely to satisfy the schema. The 1ES docs show the standard-job form for release jobs in four of their five examples, so it is the better-trodden path here.
Two independent blockers prevented the crates.io release path from working. B1 - packaging. With `[source.crates-io] replace-with = "Mxc-Azure-Feed"` active, `cargo package` resolves a just-packaged sibling through the replacement feed instead of its own in-memory overlay, so the sibling 404s (rust-lang/cargo#17196): cargo registers the overlay under the pre-replacement SourceId but looks it up under the post-replacement one. Pass `--registry Mxc-Azure-Feed` so the source override is not consulted. The resulting .crate is byte-identical to a no-replacement baseline, so no feed URL leaks into the published artifact. `--registry` defaults to `crates-io`, leaving local and developer builds unchanged. B2 - releasing. The release job made four reads of index.crates.io (probe, status, verify-dependencies, wait). The 1ES CFSClean isolation policy denies that host, so the job could not succeed on the pool regardless of the artifacts. Those reads are removed; ESRP publishes server-side and is unaffected. Correctness is preserved by three existing layers: 1. sibling version-req match is enforced by `cargo package` itself (exit 101) 2. leaf-first ordering is validated offline by _validate_release_graph 3. dependency name existence is enforced server-side by crates.io via a Postgres lookup on the crates table, so index propagation never gates sequential publishing `verify-order` now accepts a correctly ordered subset of the packaged order, so a partially failed release can be resumed by narrowing `crateOrder`; it emits warnings naming every dependency it therefore assumes is already published. release-order.json records sha256 per crate for out-of-band auditing. packageCrates and publishCrates still default to false. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f199a77f-51ec-4441-baa5-b87df8177b83
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
.azure-pipelines/templates/Publish.CratesIo.Job.yml:27
- The PR description promises automatic crates.io checksum/existence checks and checksum-aware reruns, but this implementation explicitly performs no registry reads and requires operators to remove crates manually. That means a resumed run can publish dependents based only on an unchecked operator assertion, and an unchanged rerun is not safe as described. Either restore the advertised preflight/ledger behavior in a network-capable stage or update the release design and PR description to make this manual safety boundary explicit.
# RESUMING A FAILED RELEASE: crates.io rejects a duplicate version, so simply
# re-running this job unchanged fails on the first crate that already landed.
# The pool cannot ask crates.io what landed, and 1ES forbids `checkout` in a
# release job, so there is no automated ledger. Instead the operator re-queues
# the release with the already-published crates removed from `crateOrder`.
# `verify-order` accepts that subset only if it is still in packaged leaf-first
# order, and logs every dependency it is consequently assuming is already live.
.azure-pipelines/scripts/crates_release.py:229
- This disables Cargo's only check that each generated archive can compile after workspace path dependencies are rewritten to registry dependencies. A successful workspace build does not cover missing packaged files or normalized-manifest problems, so the release can publish crates that consumers cannot build. Remove
--no-verify(the private-registry workaround should also support verification), or add an equivalent build-from-archive gate before this stage is enabled.
"--no-verify",
| source = _crate_file(args.order_file, entry) | ||
| if not os.path.isfile(source): | ||
| print(f"Crate file not found: {source}") | ||
| return 1 | ||
| shutil.copy2(source, os.path.join(out_dir, entry["file"])) |
The crates release job was a `deployment` job with no `environment:`. 1ES
documents `environment` as required for the deployment form of a release job
("environment: MyEnvironment # Required, name of the environment"), so the
stage would have failed YAML validation before any step ran.
Convert it to a standard `job` with `templateContext.type: releaseJob` and
flatten the `strategy.runOnce.deploy.steps` block into plain `steps:`. This
matches the NPM release job already working in 1ES.Release.yml, and avoids
provisioning an ADO Environment (and its approval gates) purely to satisfy the
schema.
Reported by the Copilot PR reviewer on microsoft#716.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f199a77f-51ec-4441-baa5-b87df8177b83
Two outstanding items that need a decisionBoth are external to this PR - no amount of code review resolves them, and both have lead time, so they are worth starting now rather than at release time. 1.
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 25 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.azure-pipelines/templates/Publish.CratesIo.Job.yml:94
- The release starts the next dependent crate immediately after ESRP reports completion, but crates.io index updates are asynchronous; the new dependency may not yet be resolvable, causing the next publish to fail with “dependency does not exist.” The PR’s Safety section says propagation is awaited, but this loop has no delay or retry. Add a supported propagation gate after each publish (preferably polling the sparse index from a network-enabled job, or a conservative wait if this pool must remain isolated).
- task: EsrpRelease@12
.azure-pipelines/templates/Publish.CratesIo.Job.yml:30
- This explicitly contradicts the PR’s Safety claim that reruns skip versions already published with the matching checksum. The implementation instead fails on duplicates and asks an operator to remove entries without verifying the published checksum, so a partial release is neither automatically resumable nor checksum-safe as described. Restore the live checksum/idempotency check (for example in a permitted network-enabled gate or trusted publication ledger), or revise the stated release guarantees before relying on this workflow.
# RESUMING A FAILED RELEASE: crates.io rejects a duplicate version, so simply
# re-running this job unchanged fails on the first crate that already landed.
# The pool cannot ask crates.io what landed, and 1ES forbids `checkout` in a
# release job, so there is no automated ledger. Instead the operator re-queues
# the release with the already-published crates removed from `crateOrder`.
Releasing crates previously took two queued runs: MXC-Official-Build with packageCrates to produce the artifact, then MXC-Official-Release with publishCrates to consume it. The intent is that releasing is one click. 1ES forbids `checkout` in a release JOB, but a regular job in the same PIPELINE may check out and build - 1ES documents this pattern explicitly, wiring a release job to a sibling build job's artifact via `input: pipelineArtifact` with `artifact:` rather than a cross-pipeline `pipeline:`/`artifactName:` pair. Add a Package_Crates_For_Release stage to 1ES.Release.yml that runs Package.Crates.Job.yml, and make Publish_to_CratesIo depend on it. The release job's artifact input switches from the cross-pipeline form to the same-run form. Queueing 1ES.Release.yml with publishCrates now packages the closure and then publishes it in one run. cratesDryRun packages and verifies while skipping ESRP, which is the cheap way to exercise the full 18-crate closure without publishing. The npm release is unchanged and still consumes mxc-npm-sdk-package from MXC-Official-Build. packageCrates on the official build is retained as a CI canary: it detects packaging breakage at merge time without requiring a release run. Note: the packaging job now runs CargoAuthenticate against Mxc-Azure-Feed from the release pipeline rather than the build pipeline. Both run in the same ADO project and so should share a build service identity, but that is unverified - a cratesDryRun run exercises exactly this path and publishes nothing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f199a77f-51ec-4441-baa5-b87df8177b83
| package_args = [ | ||
| "cargo", | ||
| "package", | ||
| "--no-verify", | ||
| "--allow-dirty", | ||
| "--registry", | ||
| args.registry, | ||
| "--manifest-path", | ||
| manifest, | ||
| ] |
| pipeline: MXC | ||
| targetPath: '$(Pipeline.Workspace)/packages' | ||
| artifactName: mxc-npm-sdk-package | ||
| - ${{ if parameters.publishNpm }}: |
Select the release in the Run dialog's "Pipeline version" picker instead of typing a tag into a parameter. The ref the run is queued against now supplies both the pipeline definition and the packaged source, so a release is immutable: changing anything about how a release is built, including this pipeline, requires cutting a new tag. A new Validate_Release_Ref stage fails the run unless Build.SourceBranch matches refs/tags/release/*, and the package and publish stages depend on it, so nothing is checked out or published from a branch, a bare version tag, or a raw commit. The check has to run at runtime because Build.SourceBranch is not available to compile-time template expressions. The stage is marked isSkippable: false so it cannot be deselected in the Run dialog's "Stages to run" panel, which would otherwise make the guard advisory. Re-enable cargo package verification. Passing --registry resolves workspace siblings against the temporary package registry, so rust-lang/cargo#17196 does not apply and --no-verify is unnecessary. --allow-dirty is likewise dropped: the only file the pipeline modifies is the workspace .cargo/config.toml, which lies outside every package directory, so a dirty-tree failure now means a crate source really was modified. The script's --registry default moves to Mxc-Azure-Feed to match, since the old crates-io default was only harmless while verification was off. Verify each staged .crate against the sha256 recorded at packaging time before handing it to ESRP, failing closed on a missing or mismatched digest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7cf82d0d-a130-47ee-8e7c-409209a3b4f9
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 27 changed files in this pull request and generated no new comments.
Suppressed comments (2)
docs/crates-release.md:67
- The release procedure will break on the next version bump. These newly versioned path dependencies keep literal
0.7.0requirements (including the two directnanvix_commondependencies), so changing only[workspace.package].versionmakes the local 0.8.0 siblings fail the 0.7.0 requirements;scripts/check-version-sync.jsdoes not update or validate them. The instructions must require updating every first-party dependency requirement in lockstep (and the SDK versions checked by the existing sync gate).
1. Bump the version in `src/Cargo.toml`.
.azure-pipelines/1ES.Release.Crates.yml:80
- The release entry point advertised in the PR description is not present: this new pipeline exposes
cratesDryRun, while the existing1ES.Release.ymlhas nopublishCratesparameter or crates stages. QueueingMXC-Official-ReleasewithpublishCrates: truetherefore cannot perform the documented release. Either integrate these stages into that pipeline or update the PR description to direct operators to the separately registered1ES.Release.Crates.ymlpipeline.
parameters:
- name: cratesDryRun
displayName: 'Dry run — package and verify order but skip ESRP publish'
type: boolean
default: false
Resolves a textual conflict in src/Cargo.toml. Upstream added the learning_mode_core workspace member and its path dependency while this branch added version fields to the dependencies the crates.io release publishes. Both sides are kept. learning_mode_core stays unversioned because it is not in the current 18-crate publish list.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 27 changed files in this pull request and generated 2 comments.
Suppressed comments (2)
docs/crates-release.md:156
- This resume procedure repackages the remaining crates from a new commit rather than the original release tag/artifact. If
mainhas advanced, Cargo verifies against the new local sibling sources while consumers resolve already-published siblings from the old tag, allowing an incompatible mixed closure under one version; even a pipeline-only commit changes Cargo's packaged VCS provenance/checksum. Resume from the original artifact/tag while supplying only the remaining order, rather than tagging a newmaincommit.
2. Edit the `crateOrder` default in `.azure-pipelines/1ES.Release.Crates.yml`,
removing the already-published crates, and merge that change to `main`.
`crateOrder` is an `object` parameter; changing it means editing the
pipeline file.
3. Cut a **new** release tag containing that edit (for example
docs/crates-release.md:62
- This release step is incomplete now that the PR adds literal
version = "0.7.0"requirements for first-party dependencies in the workspace and crate-local manifests. Changing onlyworkspace.package.versionto0.8.0leaves packages requiring^0.7.0siblings, socargo packagewill reject the next release. Include those dependency requirements in the version bump instructions.
1. Bump the version in `src/Cargo.toml`.
| "bwrap_common", | ||
| "seatbelt_common", | ||
| "sandbox_spec", | ||
| "appcontainer_common", |
| - name: cratesDryRun | ||
| displayName: 'Dry run — package and verify order but skip ESRP publish' | ||
| type: boolean | ||
| default: false |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
.azure-pipelines/scripts/crates_release.py:623
- A
RESUME-SUBSETmarker is accepted unconditionally, including whencheck-templateis invoked by the GitHub Versioning Checks workflow. Consequently, a PR intomaincan carry the marker plus a shortened order and this branch returns success, contrary to the documented backstop atdocs/crates-release.md:323-327; the next normal release would silently omit crates. Keep the default CI mode strict and require an explicit allow-resume option only from the release pipeline.
if resume_reason is not None:
unknown = [name for name in actual if name not in expected]
if unknown:
print(f"FAIL {args.template_path} declares a resume subset naming unknown crates: {unknown}")
return 1
if actual != [name for name in expected if name in set(actual)]:
docs/crates-release.md:108
- These instructions describe the workspace version as the only value to bump, but this PR adds explicit
version = "0.7.0"requirements for first-party path dependencies in three manifests. Following the documented 0.8.0 example while changing only[workspace.package].versionleaves^0.7.0requirements that reject the local 0.8.0 siblings during packaging. Document updating those dependency requirements as part of every incompatible version bump.
## How versions are determined
All crates declare `version.workspace = true` in their own `Cargo.toml`, so the
single `version` field in `src/Cargo.toml` (currently `0.7.0`) is the version
that ships. The pipeline does not set or override the version — it packages
whatever `src/Cargo.toml` contains at the tagged commit. To release a new
version:
1. Bump the version in `src/Cargo.toml`.
docs/crates-release.md:403
- This prerequisite is already resolved according to the PR metadata: the pipeline is registered as definition 198954, and the variable group and service connection are authorized. Leaving it under “must be resolved before the first real publish” gives operators stale release readiness information; remove it or replace it with any authorization work that actually remains.
5. **Pipeline registration** — `.azure-pipelines/1ES.Release.Crates.yml` is new
and must be registered as a pipeline in Azure DevOps, and that pipeline must
be authorized to use the `MXC-ESRP-Signing` variable group.
.azure-pipelines/templates/Publish.CratesIo.Job.yml:33
verify-orderdoes not catch every stale copy: it intentionally accepts an ordered subset, so a template that omits a newly added crate passes. The full-list drift check ischeck-template; update this comment so maintainers do not rely on the weaker publish-time guard.
# Static YAML because ${{ each }} expands at compile time. verify-order
# catches a stale copy at run time, before anything is published.
| "sandbox_spec", | ||
| "learning_mode_core", | ||
| "learning_mode_windows", | ||
| "appcontainer_common", |
Packaging ran as one Windows job that added two rustup targets and passed three --target flags to a single cargo package call. The .crate archive is the crate's source and is target-independent, so the extra targets bought verification, not different artifacts. Fan the job across the windows, linux, and macOS pools with the matrix pattern Lint.Job.yml already uses, and package for each agent's own triple. Build scripts now run on the OS they are verifying rather than all on Windows. Only the Windows leg publishes the artifact, so the artifact name the release job consumes is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
The three-target verify list carried this invariant in its comment and went away with it when packaging moved to native per-OS agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated 1 comment.
Suppressed comments (6)
.azure-pipelines/scripts/crates_release.py:100
process_security_environment_specis missing from the release closure even thoughappcontainer_commonhas it as a normal Windows path dependency (src/backends/appcontainer/common/Cargo.toml:30)._validate_release_graphrejects everycheck-template/packagerun with “local dependency is missing from CRATES”; moreover, the dependency still haspublish = false, soappcontainer_commoncould not resolve from crates.io. Add this crate to the publishable closure (including its metadata/order/docs) or remove/vendor the dependency before publishing.
"sandbox_spec",
.azure-pipelines/templates/Package.Crates.Job.yml:34
- This implementation materially differs from the PR description: it creates three native-agent jobs, while
crates_release.py packagepasses no--targetflags. The description instead claims the entire pipeline runs on Windows, onecargo packageinvocation verifies three targets, and the helper validates all targets are installed. Either implement those guarantees or update the release/validation description to reflect the native matrix.
- name: matrix
type: object
default:
- name: windows_x64
os: windows
triplet: x86_64-pc-windows-msvc
- name: linux_x64
os: linux
triplet: x86_64-unknown-linux-gnu
- name: macos_arm64
os: macos
triplet: aarch64-apple-darwin
docs/crates-release.md:114
- The runbook's single version bump does not work for its
0.8.0example: first-party path dependencies are pinned toversion = "0.7.0"insrc/Cargo.toml:110-135and two crate manifests, so Cargo rejects a 0.8 sibling as outside^0.7.0. The repository's version-sync check also requires the npm and C# SDK versions to match. Document all required updates so following the release procedure does not fail during packaging/CI.
1. Bump the version in `src/Cargo.toml`.
2. Commit and push.
3. Cut a release branch named `release/v<major>.<minor>.<patch>[-rc<n>]` (for
example `release/v0.8.0`) from the commit you are releasing, and confirm
the `release/*` ruleset has frozen it — see
[Choosing the release ref](#choosing-the-release-ref).
4. Run the pipeline against that branch.
.azure-pipelines/templates/Publish.CratesIo.Job.yml:33
- This comment is incorrect:
verify-orderdeliberately accepts a subset, so it cannot detect a stale template that merely omits a crate. The newcheck-templatestep is the guard that detects stale copies; naming the wrong guard obscures the release safety model documented elsewhere in this PR.
# Static YAML because ${{ each }} expands at compile time. verify-order
# catches a stale copy at run time, before anything is published.
docs/crates-release.md:403
- This is no longer an unresolved prerequisite according to the PR description: definition 198954 is registered, and both the variable group and service connection are authorized. Leaving it in “known blockers” gives operators an incorrect pre-release checklist; remove it or rewrite it as a verification step with the current resources.
5. **Pipeline registration** — `.azure-pipelines/1ES.Release.Crates.yml` is new
and must be registered as a pipeline in Azure DevOps, and that pipeline must
be authorized to use the `MXC-ESRP-Signing` variable group.
.azure-pipelines/templates/1ES.Build.Stages.yml:100
- The official-build artifact is not consumed by
1ES.Release.Crates.yml; that pipeline checks out its selected release ref and runs this packaging template again. Describe this stage as the opt-in merge-time canary/artifact instead, otherwise maintainers may assume the release uses a previously built immutable artifact.
# Source-only (no binaries), so it does not depend on Build_Binaries. Produces
# the `mxc-crates-package` artifact consumed by 1ES.Release.Crates.yml for ESRP-based
# crates.io publishing. Isolated in its own stage so it never gates npm
# packaging or the integration tests that depend on Package_MXC.
| // `system_dir` is Windows-only, and Windows Sandbox does not exist on the | ||
| // other targets the crates.io release packages for. | ||
| #[cfg(not(windows))] | ||
| let sandbox_exe = std::path::PathBuf::from("WindowsSandbox.exe"); |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated no new comments.
Suppressed comments (5)
.azure-pipelines/scripts/crates_release.py:606
- This returns success for a resume subset in every caller, including the GitHub
Versioning Checksworkflow. Consequently, a PR can merge a shortenedcrateOrderplus the marker intomain, even though the release guide says that CI rejects this state; later releases can silently omit those crates. Make resume subsets opt-in only for the release-ref packaging invocation, while the PR check requires the complete order.
if resume_reason is not None:
.azure-pipelines/scripts/crates_release.py:103
appcontainer_commonhas a path dependency onprocess_security_environment_spec, but that package is absent fromCRATESand still haspublish = false._validate_release_graphwill therefore reject this closure with “local dependency is missing from CRATES” beforecargo packageruns. Publish/include that generated crate as well, or remove the registry dependency from the published closure.
"appcontainer_common",
.azure-pipelines/templates/Package.Crates.Job.yml:38
- The PR description and validation section say packaging is one Windows job with three
--targetflags, but this implementation runs three native OS jobs andcmd_packagepasses no--target. Update the PR description/validation to reflect the actual matrix so reviewers and release operators know which execution path was tested.
- ${{ each item in parameters.matrix }}:
- job: package_crates_${{ item.name }}
docs/crates-release.md:108
- This release instruction is incomplete:
scripts/check-version-sync.jsrequires the npm and C# SDK versions to match, and the first-party path dependency requirements are hard-coded to0.7.0insrc/Cargo.tomland two crate manifests. Following only this step for the documented0.8.0example will fail CI/package validation. List all required version updates here.
1. Bump the version in `src/Cargo.toml`.
docs/crates-release.md:403
- This prerequisite is already resolved according to the PR description: the pipeline is registered as definition 198954, and the variable group/service connection are authorized. Leaving it under “must be resolved” gives release operators stale blocking guidance; remove this item.
5. **Pipeline registration** — `.azure-pipelines/1ES.Release.Crates.yml` is new
and must be registered as a pipeline in Azure DevOps, and that pipeline must
be authorized to use the `MXC-ESRP-Signing` variable group.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
Cargo keeps a path dependency in the published manifest whenever it carries a version, so the version-less form is what lets a dev-dependency on an unpublished crate be stripped at package time. The release validator and the order computation now apply that same rule. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 37 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.azure-pipelines/scripts/crates_release.py:103
appcontainer_commonstill has a versioned Windows path dependency onprocess_security_environment_spec, but that package is absent fromCRATESand its manifest still haspublish = false. Because_survives_publishtreats this dependency as publishable,_validate_release_graphwill reportappcontainer_common -> process_security_environment_spec: local dependency is missing from CRATES, so bothcheck-templateand every packaging job stop beforecargo package. Make that generated crate publishable and add it throughout the release closure, or remove the registry dependency by packaging the bindings into a publishable crate.
"appcontainer_common",
docs/crates-release.md:109
- The documented version-bump procedure is incomplete now that publishable path dependencies have literal
version = "0.7.0"requirements. Bumping only[workspace.package].versionto 0.8.0 leaves the requirements insrc/Cargo.toml,core/wxc_common/Cargo.toml, andbackends/nanvix/runner/Cargo.tomlat^0.7.0; the packaging verification will then reject the 0.8.0 workspace siblings. Include all first-party dependency requirements in the bump procedure (and ideally add a parity check) rather than describing the workspace package field as the only version to change.
1. Bump the version in `src/Cargo.toml`.
2. Commit and push.
.azure-pipelines/templates/Package.Crates.Job.yml:34
- This implementation contradicts the PR description's platform-validation contract. The description says the entire pipeline runs on Windows and one
cargo packagecall receives all three--targetflags, with the helper checking that all targets are installed; this template instead creates three native-OS jobs, andcmd_packagepasses no--target. Update the PR description and validation evidence to describe the native matrix, or restore the single Windows cross-target implementation, so reviewers and release operators know what was actually validated.
- name: matrix
type: object
default:
- name: windows_x64
os: windows
triplet: x86_64-pc-windows-msvc
- name: linux_x64
os: linux
triplet: x86_64-unknown-linux-gnu
- name: macos_arm64
os: macos
triplet: aarch64-apple-darwin
docs/crates-release.md:403
- This is no longer an open prerequisite: the PR description says pipeline definition 198954 is registered and that
MXC-ESRP-Signingis authorized, with successful runs allocating agents. Leaving it under “must be resolved” gives release operators stale setup instructions; remove this item or move it to a completed-prerequisites section.
5. **Pipeline registration** — `.azure-pipelines/1ES.Release.Crates.yml` is new
and must be registered as a pipeline in Azure DevOps, and that pipeline must
be authorized to use the `MXC-ESRP-Signing` variable group.
appcontainer_common takes a normal dependency on this crate under cfg(target_os = "windows"), so cargo keeps the dependency and its version when packaging. While the crate was publish = false, cargo refused to substitute the locally packaged copy, and packaging appcontainer_common failed with "no matching package named process_security_environment_spec". mxc_engine and mxc-sdk failed behind it. The crate's schema carries an MIT header and is already committed to the public repository, and the "not publicly redistributable" note in its README refers to the internal OS tree it was vendored from rather than to the schema text. Nothing found restricts the generated bindings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
The README said the vendored schema "is not publicly redistributable", which reads as a restriction on the schema itself. The restriction is on the internal OS tree it was taken from: the schema text carries an MIT header and has been committed to this public repository since microsoft#739. Add the repository field so the published crate carries a source link. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 39 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
docs/crates-release.md:105
- Bumping only
[workspace.package].versionis insufficient for a minor/major release. The newly added first-party dependency requirements insrc/Cargo.toml(plus the directnanvix_commonpins) remain0.7.0; for the documented0.8.0example, Cargo will reject the packaged 0.8.0 siblings because0.7.0means^0.7.0. Add updating all first-party dependency version requirements to the release steps.
All crates declare `version.workspace = true` in their own `Cargo.toml`, so the
single `version` field in `src/Cargo.toml` (currently `0.7.0`) is the version
that ships. The pipeline does not set or override the version — it packages
whatever `src/Cargo.toml` contains at the tagged commit. To release a new
docs/crates-release.md:10
- The release closure is now 21 crates:
CRATESincludesprocess_security_environment_spec, but this overview still says 20 and the crate list below omits it (with additional “20” references later in this document). Update the count and list so the operator documentation matches what the pipeline packages.
The **1ES.Release.Crates** pipeline (`.azure-pipelines/1ES.Release.Crates.yml`)
packages and publishes the 20-crate release closure from the MXC Rust workspace
in a single pipeline run:
src/backends/learning_mode/windows/Cargo.toml:20
- This comment is now incorrect: the same change makes
process_security_environment_specpublishable and adds it toCRATES. The dependency remains path-only because it is a development dependency that Cargo removes from the published manifest, not because the target crate is unavailable on crates.io.
# Path-only so cargo strips it when publishing; the crate is not on crates.io.
| - mxc_pty | ||
| - mxc_telemetry | ||
| - nanvix_common | ||
| - sandbox_spec |
Making process_security_environment_spec publishable added it to CRATES in crates_release.py, but the crateOrder default in Publish.CratesIo.Job.yml is a second, independent list. The check-template gate on the Windows leg of build 154277340 caught the drift and failed the release, which is what that gate is for. Without this the crate would be packaged and never published, and every crate that depends on it would fail to resolve against a registry that does not have it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 36 out of 39 changed files in this pull request and generated no new comments.
Suppressed comments (6)
.azure-pipelines/scripts/crates_release.py:620
- A
RESUME-SUBSETmarker with the full order currently succeeds, although the release guide states that a marker left onmainfailscheck-template. Besides contradicting the documented backstop, a forgotten marker silently authorizes future order omissions as deliberate resumes. Reject the marker unlessactualis a strict subset ofexpected.
if resume_reason is not None:
docs/crates-release.md:108
- Bumping only
[workspace.package].versionis insufficient for the documented0.8.0release:src/Cargo.tomlnow contains explicitversion = "0.7.0"requirements on the first-party path dependencies, and Cargo will reject local 0.8.0 packages against those^0.7.0constraints. Include updating all first-party dependency requirements (or an automation command that does so) in the release procedure.
All crates declare `version.workspace = true` in their own `Cargo.toml`, so the
single `version` field in `src/Cargo.toml` (currently `0.7.0`) is the version
that ships. The pipeline does not set or override the version — it packages
whatever `src/Cargo.toml` contains at the tagged commit. To release a new
version:
1. Bump the version in `src/Cargo.toml`.
.azure-pipelines/scripts/crates_release.py:545
- This substring check treats any mention of
RESUME-SUBSETas authorization for a partial release—for example,# Do not add a RESUME-SUBSET markerwould activate resume mode. Because resume mode bypasses the exact-order drift gate, recognize only the documented marker syntax instead of any occurrence.
if RESUME_MARKER in raw and not found_default:
resume_reason = raw.split(RESUME_MARKER, 1)[1].lstrip(" :#").strip() or "(no reason given)"
src/backends/learning_mode/windows/Cargo.toml:21
process_security_environment_specis now explicitly publishable and included inCRATES, so this comment is stale. Keeping this dependency path-only makes Cargo strip it from the published manifest, leaving the packagedexamples/lm_capture.rsunable to resolve the crate on Windows. Preserve the versioned workspace dev-dependency instead.
# Path-only so cargo strips it when publishing; the crate is not on crates.io.
process_security_environment_spec = { path = "../../../core/generated/process_security_environment_specification" }
docs/crates-release.md:10
- The release helper and publish template contain 21 crates, including
process_security_environment_spec, but this guide says 20 and omits that crate from the list below. The other “20”/“19” counts in this guide are consequently stale as well; update the operator documentation to reflect the actual closure.
The **1ES.Release.Crates** pipeline (`.azure-pipelines/1ES.Release.Crates.yml`)
packages and publishes the 20-crate release closure from the MXC Rust workspace
in a single pipeline run:
.azure-pipelines/templates/Package.Crates.Job.yml:34
- The PR description says the whole pipeline runs on Windows and one
cargo packageinvocation verifies three--targetvalues in parallel. This template instead creates three native-OS jobs, and the package command supplies no--target. Update the PR’s implementation/validation claims or restore the described single-Windows multi-target design so reviewers and release operators have an accurate security and build model.
- name: matrix
type: object
default:
- name: windows_x64
os: windows
triplet: x86_64-pc-windows-msvc
- name: linux_x64
os: linux
triplet: x86_64-unknown-linux-gnu
- name: macos_arm64
os: macos
triplet: aarch64-apple-darwin
Richie Gomez opened PR 782 to make process_security_environment_spec publishable, which is the same change this branch already carried. He owns the schema and he set the original publish = false, so his wording is the authoritative one and this branch should not carry a second version of it. Take his text verbatim in the crate README and in the provenance file, and drop the comment that justified the flag here. PR 782 is now the decision record, so repeating the reasoning in the manifest would only leave a stale copy of it. The provenance file was missed entirely when this branch first made the crate publishable. It still claimed the schema was not publicly redistributable, which is the sentence PR 782 removes. repository.workspace = true stays. All twenty-one crates in the release closure set it and PSEC was the only one that did not, so without it PSEC would be the lone exception once PR 782 merges. PR 782 does not touch that line, so the two changes merge cleanly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab22cd6f-f3d9-4325-8397-9e998aa058c3
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 40 changed files in this pull request and generated no new comments.
Suppressed comments (7)
.azure-pipelines/templates/Publish.CratesIo.Job.yml:52
- A real release still includes
hyperlight_common, even though this PR documents that crates.io normalizes it to the already-ownedhyperlight-commonname. Because eight crates are published before this entry, clearingdryRuncan irreversibly publish a partial release and then fail here. Block real publishing until the name/ownership issue is resolved, or rename the crate and update the dependency graph/order first.
- hyperlight_common
docs/crates-release.md:108
- This instruction is incomplete for a minor-version release such as the documented 0.8.0 example. The PR adds first-party path dependency requirements pinned to
0.7.0; changing only[workspace.package].versionto0.8.0leaves those requirements incompatible, socargo packagefails. Include updating all first-party dependencyversionrequirements (ideally via an automated version-bump/check command).
1. Bump the version in `src/Cargo.toml`.
src/backends/windows_sandbox/lifecycle/src/vm.rs:144
- This non-Windows fallback undoes the executable-search-order protection described immediately above:
vmand its publiclaunch_managed_vmremain exported off Windows, so reaching that API executes the firstWindowsSandbox.exefound via the host's search path. The unsupported-target implementation should fail immediately, or the host-side lifecycle crate/module should compile empty off Windows, rather than launching an untrusted relative executable.
// `system_dir` is Windows-only, and Windows Sandbox does not exist on the
// other targets the crates.io release packages for.
#[cfg(not(windows))]
let sandbox_exe = std::path::PathBuf::from("WindowsSandbox.exe");
.azure-pipelines/templates/Package.Crates.Job.yml:34
- The PR description says packaging runs wholly on Windows in one
cargo packageinvocation with three--targetarguments, but this template creates three native-agent jobs, and the helper passes no--target. Update either the implementation or the PR's design and validation claims; the stated single-invocation/60-target-cell validation does not describe the pipeline being merged.
- name: windows_x64
os: windows
triplet: x86_64-pc-windows-msvc
- name: linux_x64
os: linux
triplet: x86_64-unknown-linux-gnu
- name: macos_arm64
os: macos
triplet: aarch64-apple-darwin
.azure-pipelines/scripts/crates_release.py:101
- Including
process_security_environment_specmakes this a 21-crate closure, while the PR description anddocs/crates-release.mdrepeatedly say 20 and the documented crate list omits this package. Update the release documentation and PR description so operators know the complete public package set.
"process_security_environment_spec",
.azure-pipelines/templates/1ES.Build.Stages.yml:100
- This comment says the official-build artifact is consumed by
1ES.Release.Crates.yml, but that pipeline runsPackage.Crates.Job.ymlitself and publishes the artifact from its own Windows matrix leg. The official-build option is only a canary, so describing this artifact as release input can cause operators to assume the release uses previously built artifacts.
# Source-only (no binaries), so it does not depend on Build_Binaries. Produces
# the `mxc-crates-package` artifact consumed by 1ES.Release.Crates.yml for ESRP-based
# crates.io publishing. Isolated in its own stage so it never gates npm
# packaging or the integration tests that depend on Package_MXC.
docs/crates-release.md:403
- The PR description says pipeline definition 198954 is already registered and both the variable group and service connection are authorized, so listing registration/authorization as an unresolved prerequisite is stale. Remove this blocker or replace it with an accurate remaining prerequisite.
5. **Pipeline registration** — `.azure-pipelines/1ES.Release.Crates.yml` is new
and must be registered as a pipeline in Azure DevOps, and that pipeline must
be authorized to use the `MXC-ESRP-Signing` variable group.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 40 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.azure-pipelines/scripts/crates_release.py:620
check-templateis also invoked by the GitHub Versioning Checks workflow, but this branch returns success for any marked subset. As a result, a release branch PR can merge a shortenedcrateOrderplusRESUME-SUBSETintomain, even though the operator guide says that PR must fail; later releases would then silently omit those crates. Make resume-subset acceptance an explicit option used only by the release pipeline, while CI requires the complete order.
if resume_reason is not None:
docs/crates-release.md:109
- These instructions are incomplete now that publishable path dependencies carry literal
version = "0.7.0"requirements. Following the documented single-field bump to 0.8.0 leaves^0.7.0constraints that reject the 0.8.0 sibling crates, so release packaging fails. Include updating every publishable first-party path-dependency requirement (ideally with a sync check) in the release procedure.
All crates declare `version.workspace = true` in their own `Cargo.toml`, so the
single `version` field in `src/Cargo.toml` (currently `0.7.0`) is the version
that ships. The pipeline does not set or override the version — it packages
whatever `src/Cargo.toml` contains at the tagged commit. To release a new
version:
1. Bump the version in `src/Cargo.toml`.
2. Commit and push.
docs/crates-release.md:10
- The release closure now contains 21 crates, and
process_security_environment_specappears in bothCRATESandcrateOrder. This guide still says 20 throughout and omits that crate from the list, so the documented release inventory and blocker counts are stale.
The **1ES.Release.Crates** pipeline (`.azure-pipelines/1ES.Release.Crates.yml`)
packages and publishes the 20-crate release closure from the MXC Rust workspace
in a single pipeline run:
src/backends/learning_mode/windows/Cargo.toml:20
- This comment now contradicts this PR:
process_security_environment_specis included in the 21-crate crates.io publish order and its manifest setspublish = true. Retain only the explanation that the versionless dev-dependency is stripped from the published manifest.
# Path-only so cargo strips it when publishing; the crate is not on crates.io.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 40 changed files in this pull request and generated no new comments.
Suppressed comments (8)
.azure-pipelines/scripts/crates_release.py:635
check-templateaccepts anyRESUME-SUBSETunconditionally, so the GitHub versioning check also returns success for a trimmed resume list. That contradicts the documented backstop indocs/crates-release.mdand allows such a list to merge tomain, causing later releases to silently omit crates. Require an explicit allow-resume option that is passed only by release-ref packaging; CI onmainshould reject the marker/subset.
if resume_reason is not None:
unknown = [name for name in actual if name not in expected]
if unknown:
print(f"FAIL {args.template_path} declares a resume subset naming unknown crates: {unknown}")
return 1
if actual != [name for name in expected if name in set(actual)]:
print(f"FAIL {args.template_path} declares a resume subset that is out of dependency order.")
print(f" template : {actual}")
print(f" required : {[n for n in expected if n in set(actual)]}")
return 1
skipped = [name for name in expected if name not in actual]
print(f"RESUME SUBSET declared in {args.template_path}: {resume_reason}")
print(f" publishing {len(actual)} of {len(expected)} crates, in valid dependency order.")
print(f" assumed ALREADY PUBLISHED and skipped: {skipped or '(none)'}")
print(" Remove the RESUME-SUBSET marker and restore the full list on main once the release completes.")
return 0
docs/crates-release.md:42
process_security_environment_specis in the release closure but is missing from this purported complete alphabetical crate list.
- `sandbox_spec`
docs/crates-release.md:276
- The closure has 21 crates now, so this resume example uses the old total.
(e.g. crate 7 of 20 fails for a transient reason), crates 1–6 are already
docs/crates-release.md:394
- With
process_security_environment_specadded, there are 21 names in the closure; if onlyhyperlight_commonis taken, the remaining count is 20.
github.com/hyperlight-dev/hyperlight. It is the only one of the 20 names
that is taken today; the other 19 are unregistered. The crate must be
docs/crates-release.md:399
- The first release now submits 21 new crate versions, not 20, so the rate-limit estimate should use the current closure size.
plus 1 per 10 minutes. A 20-crate first release will be throttled. An
src/backends/learning_mode/windows/Cargo.toml:21
- This path-only dev dependency is stripped from the published manifest, but the packaged
examples/lm_capture.rsimports it. As a result, consumers of the published crate cannot build the documented example (or run all-target checks). The dependency is now part of this crates.io closure, so retain its workspace version.
# Path-only so cargo strips it when publishing; the crate is not on crates.io.
process_security_environment_spec = { path = "../../../core/generated/process_security_environment_specification" }
.azure-pipelines/templates/Publish.CratesIo.Job.yml:33
- This comment is incorrect:
verify-orderintentionally accepts an ordered subset, so it does not catch a stale template that omits a crate. The newcheck-templatestep is the drift backstop.
# Static YAML because ${{ each }} expands at compile time. verify-order
# catches a stale copy at run time, before anything is published.
docs/crates-release.md:9
- The release closure now contains 21 crates (
CRATESandcrateOrderboth includeprocess_security_environment_spec), so the overview count is stale.
This issue also appears in the following locations of the same file:
- line 42
- line 276
- line 393
- line 399
packages and publishes the 20-crate release closure from the MXC Rust workspace
What this does
Adds a dedicated pipeline that packages the
mxc-sdkcrate closure — 21 crates — and publishes them to crates.io through ESRP Release, one crate at a time in leaf-first order. Publishing is manual and gated on a release ref, so nothing reaches crates.io until a release is deliberately cut.Running a release
The pipeline is MXC-Release-Crates, definition 198954: https://microsoft.visualstudio.com/Dart/_build?definitionId=198954
Push a release ref to
microsoft/mxcand pick it in the Run dialog's branch/tag selector.Validate_Release_Refaccepts exactly two shapes and fails the run on anything else:refs/heads/release/*— for examplerelease/v0.8.0refs/tags/v*— for examplev0.8.0The gate carries
isSkippable: false, so it cannot be switched off in the "Stages to run" panel, and bothPackage_Crates_For_ReleaseandPublish_to_CratesIodepend on it. The definition carries no triggers, so a pipeline that publishes to a public registry cannot fire on a push.Two things worth knowing before the first run. The ref must exist on
microsoft/mxc— the Run dialog enumerates that repository only, so a branch pushed to a fork will not appear. And a release branch is not immutable on its own: the gate proves where a run came from, not that the ref cannot move. Freeze it with a GitHub ruleset (Settings → Rules → Rulesets) blocking pushes, force-pushes, and deletion, or use a tag.dryRundefaults to true: it packages the closure and checks the publish order, then skips the publish stage entirely — the run reports that stage asSkippedrather than green, so a rehearsal is distinguishable from a publish at a glance. Set it to false to publish for real. It is the only field in the Run dialog. The ESRP owner and approver are not fields: an email is not a decision the person clicking Run should make, and a typo submits the release to the wrong owner. Both are fixed in the YAML to$(Build.RequestedForEmail), which is what a default run already used. A runtime guard in the gate stage fails the run if that variable resolves empty, which it can for a run queued by a service identity rather than a person.The pipeline needs no crates.io network access: the 1ES pool's CFSClean isolation blocks crates.io, dependency resolution stays on the private
Mxc-Azure-Feed, and ESRP owns the publishing credentials. Operator steps are documented indocs/crates-release.md.How it works
windows-2022,ubuntu-latest, andmacOS-15-arm64— each executing the samecargo packagecall with one-pflag per crate against--registry Mxc-Azure-Feed. A crate that no longer compiles on Linux or macOS therefore fails at package time, before anything is published, instead of after. The publish stage depends on all three legs, so any red platform stops the release. Cargo's verification build stays on, so a mismatched sibling version requirement fails packaging. The registry override works around A bug aboutcargo publish --workspace --registry crates-iorust-lang/cargo#17196, under which just-packaged workspace siblings are otherwise looked up in the wrong source and not found.check-template, copies the release script into the artifact, and publishes it. Linux and macOS package only, so a template drift failure surfaces on Windows while the other two legs stay green.CRATESincrates_release.pyis an unordered set of package names; the order is a leaf-first topological sort of the workspace dependency graph derived fromcargo metadata, with alphabetical tie-breaking. Packaging derives it live; the template'scrateOrderis a pasted copy of the same computation, because${{ each }}expands before any script runs. A pasted copy can drift, and drifting failed silently:verify-orderaccepts an ordered subset on purpose, since that is how a part-published release resumes, so a template missing a newly-added crate passed and the crate was simply never published.check-templatenow recomputes the order on every PR and fails the build unless the template matches exactly. Adding a crate is: add the name, runcrates_release.py order, paste the output — and CI fails if you forget the last step.release-order.json. Each staged.crateis re-checked against that digest before ESRP submission, and staging fails closed if the digest is missing or disagrees.verify-orderaccepts an ordered subset of the packaged closure, which is what makes resuming a partly-published release possible.packageCratesparameter (default false) that runs the same packaging as a merge-time canary; it produces the artifact but never publishes.src/Cargo.tomlsetsrepositoryunder[workspace.package]and pinsversion = "0.7.0"on the first-party path dependencies so they are publishable.Depends on #782
process_security_environment_spechas to be publishable or the closure cannot be packaged at all. Cargo writes a.cratefor apublish = falseworkspace member but does not add it to the temporary registry its siblings resolve against (src/ops/cargo_package/mod.rs), which blocksappcontainer_common,mxc_engine, andmxc-sdk. #782 makes that crate publishable onmain. This branch carries the same flag so the pipeline can be exercised before #782 merges, and matches its provenance wording so the two merge cleanly.Validation
dryRun: true— all three legs green, 21 of 21 crates packaged on each of Windows, Linux, and macOS, andPublish Crates.io PackagesreportedSkipped.check-templatefailed the release against a template missing a newly-added crate. That is the drift the gate exists to catch, caught on a real release run.crates_release.py check-templateandcrates_release.py order— exit 0, 21 crates, template matching the computed order.check-psec-codegen.js— schema matches provenance, 12 files regenerated with the pinnedflatc25.12.19 and no drift, crate compiles.release/*branches andv*tags, rejectsmain,user/*, a barerefs/heads/release, and the case variantsRelease/v0.8.0andV1. The gate uses PowerShell-clikerather than-like, because-likeis case-insensitive and would admit refs therelease/*ruleset does not freeze.Still open
hyperlight_commoncannot publish under that name. It normalizes tohyperlight-common, already taken on crates.io byhyperlight-dev(v0.16.0), and crates.io treats-and_as equivalent. A broadermxc_prefix policy for the whole closure is under discussion, and would supersede a single rename.Rustcontent-type enablement for the MXC client ID, OSPO open-source release registration, and a crates.ioPublishNewrate-limit override all remain to be requested. ESRP does supportRustand crates.io publishing; what is missing is per-client-ID enablement.dryRun: truerun stops after packaging — it deliberately does not execute the publish job, so artifact download,verify-order, staging, and ESRP submission are all still unexercised.isolation_session_bindings,isolation_session_common, andappcontainer_commonexpose nothing off Windows, andnanvix_runnerexposes nothing on macOS: itscfgmirrors the pre-existing gate onwxc_common::microvm_staging, which its core logic depends on and which does not exist there. That is the correct shape for crates.io, where a package must resolve on every platform even when it does nothing there, and it is what the verification proves: the closure builds everywhere, not that every crate is useful everywhere.mxc_telemetryis partially gated the same way, which predates this change.