Skip to content

host: make image staging and artifact discovery private to the CLI (SL6.4) - #1533

Merged
Pedro Henrique Penna (ppenna) merged 2 commits into
feature/nvx-refactorfrom
agents/slim-sl6-4-staging-private
Nov 12, 2026
Merged

Pedro Henrique Penna (ppenna) merged 2 commits into
feature/nvx-refactorfrom
agents/slim-sl6-4-staging-private

Conversation

@ppenna

@ppenna Pedro Henrique Penna (ppenna) commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1124 (SL6.4, "Image staging and artifact discovery are private to the CLI"). Parent #1088, umbrella #1076.

Stacked on #1532 (SL6.6b, in #1122), which deletes the items that this PR would otherwise leave without a caller, so that this one stays visibility-only. It needs SL6.3 (#1530) and SL6.6a (#1524) too, which have merged. Until #1532 merges, this PR's base is its branch.

What and why

Image staging and artifact discovery are the CLI's behavior, but their seals, bindings, checked files, artifact inventory and layouts were public API of nvx. This PR does SL6.4's Scope: it makes them private to the CLI where they are, without changing image formats, discovery, environment variables, checks or launch behavior. Two commits:

  1. tests: check image staging through the CLI and the owners' unit tests (71815e2a): the integration tests that reached these modules through public paths become unit tests of their owners, or drive the binary, with the same cases (Test changes, below). It changes no production code, so it passes on its own, before the visibility changes.
  2. host: make image staging and artifact discovery private to the CLI (508170fb):
    • host::artifacts and host::seal become pub(crate) modules. host::sandbox::{distro, scratch, layer} become pub(crate) and cli-gated, and host::sandbox no longer re-exports LAYER_ROLES, LayerRole and SandboxLayer. The crate root's Artifacts went in SL6.6b.
    • Their items become pub(crate) and are gated by the feature or platform of their users: ArtifactDir, ArtifactPaths, GuestPaths, Layout, Guest (with scratch_template_name), MANIFEST_NAME, the artifacts' names, openvmm_executable and absolute by cli; FileSeal and its types (SealScheme, FileKind, SealTime, FileId) by any(feature = "cli", windows), since the Windows platform module names jobs by FileSeal::of's file ID outside the CLI, and SEAL_VERSION by the hosts whose seal records it, Linux with cli and Windows; FileSeal::{scheme, kind, length, difference} and seal::open_guarded by cli. Three items stay ungated for their users outside the CLI: seal::open_read (host::snapshot), host::artifacts::require_existing (the public host::sandbox::require_file) and host::sandbox::block_geometry (host::vm, host::snapshot, the CLI).
    • DistroBinding keeps its serde form, which nvx-rs sandbox provision records, and so do ScratchBinding and FileSeal; the policy verdict, DISTRO_POLICY_REVISION, the scratch claim (CLAIM_RELEASE_WAIT) and the checked files don't change.
    • The root description keeps the image's format and the expected EROFS UUID or GPT disk GUID: RootImage and LayeredRoot don't change. The CLI's discovery (--root, or the release or checkout that holds the executable, in the repository and release layouts), NVX_OPENVMM and NVX_AUTO_DOWNLOAD keep their behavior: the CLI reads them through its own constants. The guest inventory names the same kernel, initramfs, distro files and scratch template for each guest.
    • examples/external-launch.rs calls std::path::absolute, which the now-private nvx::host::artifacts::absolute wraps, for its four paths. The crate's docs, host's and host::sandbox's present the modules as private.
    • The public API snapshots lose 132 lines on each platform, every item of host::artifacts, host::seal and host::sandbox::{distro, layer, scratch}, and the three re-exports. Nothing is added, and no path of these items remains, nvx::Artifacts included.
  • The README (nvx-rs/README.md): the module table drops the host::artifacts and host::seal rows and their sections, the host::sandbox row and section say that the distro, scratch and layer modules are the CLI's, and Distro bindings, Images by path and the security checklist's paragraph name the moved tests.
  • The case matrix: seven coverage references follow the two checklist tests to the unit tests of host::sandbox::{distro, scratch}; no row's fate changes, and check_matrix.py passes.

Size

Measured against 008035d2893 (SL6.6b's head), by #1076's rules, with #1124's note that privatizing counts as a move. This PR is visibility-only: 0 core lines and no counted files, as estimated.

Core lines Counted files
Estimate (#1124) 0 0
Measured 0 0
  • nvx-rs/src: 0 core lines, no counted file. Every changed line of the 13 production files there only makes items crate-private, gates them by cli or by the platform that uses them, edits the imports that this forces (such as layer::SandboxLayer in place of the dropped re-export), or is the docs; rustfmt rewraps the signature of DistroBinding::check, which pub(crate) lengthens.
  • examples/external-launch.rs: 0 core lines, no counted file. Examples count as docs, as decided for SL5.1a. Its four calls of the now-private nvx::host::artifacts::absolute call std::path::absolute, which that function wraps, and its import no longer names artifacts.
  • 27 files change: +514 and −573 lines, tests, docs and snapshots included.

Old tests of the area

  • Moved to their owners' unit tests, with the same assertions: security_checklist::a_staged_image_that_was_replaced_fails_its_check to host::sandbox::distro::tests, and security_checklist::a_scratch_image_is_claimed_by_one_launch_and_checked_again_after_a_release to host::sandbox::scratch::tests, where they make their private directories with host::vm::create_private_dir instead of the checklist's helper.
  • Rewritten to drive the binary or read what it records, checking the same behavior (Test changes).
  • Kept: every unit test of host::artifacts, host::seal and host::sandbox::{distro, layer, scratch}, now built with cli, as their modules are; the CLI's tests of artifacts, of NVX_OPENVMM (cli::artifacts::artifacts_list_every_guest_in_order, cli::a_relative_openvmm_override_is_relative_to_the_working_directory, and the sandbox and one-shot runs that name it) and of NVX_AUTO_DOWNLOAD (cli::download).
  • Retired: none here; SL6.6b retired the tests of what it deleted.

Test changes

python scripts/check_test_changes.py --base 008035d2893 lists 140 changes to existing tests and 6 added items, hence tests-modified:

  • Gated, unchanged (127): the tests and helpers of the modules that become cli-gated now build only with cli: the tests modules of host::artifacts, host::seal and host::sandbox::{distro, layer, scratch}, and, in host::sandbox::options::tests and host::sandbox::tests::specification, the tests that build layers (distro_manifest_binds_the_layer, systemd_entrypoints_and_images_are_refused_independently, sandbox_allows_non_systemd_sbin_init, the_entrypoint_check_needs_no_manifest_and_precedes_the_distro_verification, sandbox_rejects_systemd_from_bound_distro_metadata, distro_manifests_are_strict_json, layer_values_are_role_path_uuid and the proptest canonical_layer_uuids_round_trip), with their helpers (Layer, distro_sha256, UUID). CI's cargo test --all-features runs them all, as before.
  • Moved (2): the two checklist tests above.
  • Imports (5): host::sandbox::options::tests, host::sandbox::tests::specification, tests/cli/artifacts.rs, tests/cli/lifecycle.rs and tests/security_checklist.rs stop importing the private items.
  • tests/cli.rs:
    • an_interrupted_start_keeps_its_claim_until_recovery_confirms_exit checked the claim by checking the recorded ScratchBinding against the image. It now runs nvx-rs sandbox run on the same images: while the interrupted VM holds the claim, the run fails with scratch-claimed ("another sandbox claims the ext4 scratch image …"), and once recovery confirms the exit, the same run succeeds.
    • run_boots_each_guest_with_its_default_memory iterated Guest::ALL; it now names each guest of nvx.py, its initramfs and its default RAM (alpine 128 MiB, ubuntu and azurelinux 512 MiB).
  • tests/cli/artifacts.rs: artifacts_list_every_guest_in_order expects the literal names, alpine, ubuntu, azurelinux, instead of Guest::ALL's.
  • tests/cli/lifecycle.rs: the helper assert_bindings and lifecycle_of_a_sandbox_whose_upper_is_in_ram compared the recorded bindings with bindings that the test made with DistroBinding::verify and ScratchBinding::bind. They now check the recorded serde form from outside, with the new helpers assert_distro_binding and assert_seal: the version, format, identity, the image's seal (version, scheme, kind and length), the manifest's absence and the policy verdict, and the scratch binding's fields and seal. The device, file IDs and times that the test can't read portably are covered by the new unit test below and by each start's check.
  • tests/security_checklist.rs: a_launch_takes_a_new_private_log_and_keeps_every_entry_that_it_did_not_create compared the device and file ID of FileSeal::of for the log's handle and its path; it now compares them with a test-local file_id, which reads what FileSeal::of read: st_dev and st_ino on Linux, and on Windows the volume serial number and file ID of FILE_ID_INFO, or of BY_HANDLE_FILE_INFORMATION where that has none.
  • Added (6): the unit test host::cli::sandbox::tests::provision_records_the_bindings_that_verification_and_the_scratch_binding_make, which runs sandbox provision in process, for a scratch and a RAM upper, and checks that the recorded distro binding equals the one that DistroBinding::verify makes, that the scratch binding equals the one that ScratchBinding::bind makes, and that the RAM upper records none; the helpers SEAL_SCHEME, assert_seal and assert_distro_binding of tests/cli/lifecycle.rs; and the Linux and Windows file_id of the checklist.

Validation

local_gates.py --files (from dev) selects test-changes, markdown-links, test-layout, the check-nvx-rs steps, nvx-cli on both systems and the microVM tests; I ran them from this branch's action definitions, with Rust 1.95.0, locally on Windows, on nvx-mshv-test (Azure Linux 3, kernel 6.18, linux-mshv, virtual machine) and on nvx-kvm-test (Azure Linux 3, kernel 6.6, linux-kvm, virtual machine), in temporary worktrees.

The checks first ran on fee70396c43 and, after a code review's two fixes (SEAL_VERSION's gate, which the macOS check showed unused there, and the checklist's file_id fallback), on 0abb5ff4270, on a local base of SL6.3's and SL6.6a's pre-merge heads. After both merged, SL6.6b and this branch were rebased onto 671a192d0a5 with no conflicts, and git range-diff shows = for every commit. On this head, 508170fbefd:

Check Windows (local) Linux (MSHV, kernel 6.18)
cargo fmt --all --check passed passed
Clippy -D warnings: --all-targets --all-features, --lib, --lib --no-default-features, serde, cli and testing alone passed, natively and for --target x86_64-unknown-linux-gnu passed
Guest Clippy, --target x86_64-unknown-linux-musl --no-default-features --features guest -D warnings passed
cargo check --all-targets --all-features --target aarch64-apple-darwin passed; its one warning, in host/snapshot/tests.rs, is the base's
cargo test --locked --all-features passed: lib 1046 passed, 15 ignored; every integration test (cli 111 passed, 2 ignored) and the doc tests, nvx-rs/src/lib.rs - (line 57) included. Under the load of a second suite, cli::exec_lock::a_retry_that_waits_for_the_lifecycle_lock_past_the_deadline_is_busy once found no round fast enough ("no round delayed a retry of the exec past its deadline"); it passed on its rerun and on SL6.6b's, and this PR doesn't touch it passed: lib 1880 passed, 57 ignored; every integration and doc test
cargo test --locked, cargo build --locked --lib --no-default-features, cargo test --locked --lib --no-default-features passed passed
RUSTDOCFLAGS=-D warnings cargo doc --locked --no-deps --all-features passed passed
MSRV: cargo +1.89 check --locked --all-targets --all-features passed passed
python scripts/public_api.py passed passed
check-guest-binaries, build-guest-binaries, test-guest-binaries passed (1116 and 33 tests)
check_test_layout.py, check_markdown_links.py, check_matrix.py <worktree> 99d2022085f passed
  • The public sandbox scenarios on MSHV: python3 scripts/nvx.py test-microvm --backend mshv with managed-exec-config, sandbox-gpt-layer, sandbox-lifecycle, sandbox-proxy-only, sandbox-ram-upper, snapshot-core, snapshot-tiers and vm-lifecycle, with NVX_AUTO_DOWNLOAD=0, this head's nvx-rs and the artifacts of CI run 43203015701 (OpenVMM at the pin, 14dc4116ec7, its provenance and SHA-256 checked, and the kernel, Alpine and Ubuntu distro artifacts with the scratch template): all 8 passed, as on 0abb5ff4270. The CLI found its artifacts and OpenVMM in the checkout, and staged, verified, claimed and restored the images as before.
  • nvx-kvm-test (kernel 6.6): on fee70396c43, every check-nvx-rs step passed but for the lib's 28 guest:: tests and 7 guest-binary tests that fail there on the base too, by name; on 0abb5ff4270, Clippy with every feature and with cli, the integration tests with every feature (207 passed) and the lib's tests of host::sandbox, host::cli, host::seal and host::artifacts (331 passed) passed.
  • Each commit passes Clippy with -D warnings, with every feature, with cli and without default features, on Windows and for Linux, and the first commit, tests only, passes the tests that it changes on its own (Windows: the lib's host::sandbox, host::cli::sandbox, host::seal and host::artifacts tests, cli and security_checklist).
  • The validate-nvx unittest list passed on Windows (1824 tests, 73 skipped); this PR changes no script.

Left to CI: the microVM scenarios on KVM and WHP, and openvmm-ci, for the unchanged pin.

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

This pull request changes existing tests

It modifies or removes 140 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests.

Test code

Change What Before After
modified attributes the inner attributes of host::artifacts::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/artifacts/tests.rs:1 nvx-rs/src/host/artifacts/tests.rs:1
modified attributes the inner attributes of host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:1 nvx-rs/src/host/sandbox/distro/tests.rs:1
modified attributes the inner attributes of host::sandbox::layer::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/sandbox/layer/tests.rs:1 nvx-rs/src/host/sandbox/layer/tests.rs:1
modified attributes the inner attributes of host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/scratch/tests.rs:1 nvx-rs/src/host/sandbox/scratch/tests.rs:1
modified attributes the inner attributes of host::seal::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/seal/tests.rs:1 nvx-rs/src/host/seal/tests.rs:1
modified helper const COMPATIBLE_MANIFEST in host::artifacts::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/artifacts/tests.rs:13 nvx-rs/src/host/artifacts/tests.rs:13
modified helper fn release in host::artifacts::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/artifacts/tests.rs:18 nvx-rs/src/host/artifacts/tests.rs:18
modified helper fn checkout in host::artifacts::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/artifacts/tests.rs:32 nvx-rs/src/host/artifacts/tests.rs:32
modified helper fn identity_of in host::artifacts::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/artifacts/tests.rs:294 nvx-rs/src/host/artifacts/tests.rs:294
modified helper fn record_provenance in host::artifacts::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/artifacts/tests.rs:303 nvx-rs/src/host/artifacts/tests.rs:303
modified helper const UUID in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:18 nvx-rs/src/host/sandbox/distro/tests.rs:19
modified helper const METADATA_ONLY in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:22 nvx-rs/src/host/sandbox/distro/tests.rs:23
modified helper struct Staged in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:28 nvx-rs/src/host/sandbox/distro/tests.rs:29
modified helper impl Staged in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:33 nvx-rs/src/host/sandbox/distro/tests.rs:34
modified helper fn new in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:35 nvx-rs/src/host/sandbox/distro/tests.rs:36
modified helper fn image in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:47 nvx-rs/src/host/sandbox/distro/tests.rs:48
modified helper fn manifest in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:52 nvx-rs/src/host/sandbox/distro/tests.rs:53
modified helper fn other in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:57 nvx-rs/src/host/sandbox/distro/tests.rs:58
modified helper fn layer_with in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:62 nvx-rs/src/host/sandbox/distro/tests.rs:63
modified helper fn layer in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:67 nvx-rs/src/host/sandbox/distro/tests.rs:68
modified helper fn write_manifest in host::sandbox::distro::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/distro/tests.rs:72 nvx-rs/src/host/sandbox/distro/tests.rs:73
modified helper fn shown in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:89 nvx-rs/src/host/sandbox/distro/tests.rs:90
modified helper fn seal_of in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:94 nvx-rs/src/host/sandbox/distro/tests.rs:95
modified helper fn failure in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:99 nvx-rs/src/host/sandbox/distro/tests.rs:100
modified helper fn replace_with_copy in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:106 nvx-rs/src/host/sandbox/distro/tests.rs:107
modified helper fn touch in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:119 nvx-rs/src/host/sandbox/distro/tests.rs:120
modified helper fn inheritable in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and target_os = "linux" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and target_os = "linux" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:131 nvx-rs/src/host/sandbox/distro/tests.rs:132
modified helper fn inheritable in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test and windows hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test and windows did) nvx-rs/src/host/sandbox/distro/tests.rs:141 nvx-rs/src/host/sandbox/distro/tests.rs:142
modified helper fn physical_block_size in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:277 nvx-rs/src/host/sandbox/distro/tests.rs:278
modified helper fn stale_after in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:404 nvx-rs/src/host/sandbox/distro/tests.rs:405
modified helper fn link_to_itself in host::sandbox::distro::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/distro/tests.rs:752 nvx-rs/src/host/sandbox/distro/tests.rs:753
modified helper fn message in host::sandbox::layer::tests (it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/sandbox/layer/tests.rs:3 nvx-rs/src/host/sandbox/layer/tests.rs:3
modified helper struct Layer in host::sandbox::options::tests (moved, and it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/sandbox/options/tests.rs:63 nvx-rs/src/host/sandbox/options/tests.rs:67
modified helper impl Layer in host::sandbox::options::tests (moved, and it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/sandbox/options/tests.rs:68 nvx-rs/src/host/sandbox/options/tests.rs:73
modified helper fn new in host::sandbox::options::tests, impl Layer`` (it now compiles where feature = "cli" and `feature = "host"` and `test` hold, not where `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/options/tests.rs:69 nvx-rs/src/host/sandbox/options/tests.rs:74
modified helper fn path in host::sandbox::options::tests, impl Layer`` (it now compiles where feature = "cli" and `feature = "host"` and `test` hold, not where `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/options/tests.rs:75 nvx-rs/src/host/sandbox/options/tests.rs:80
modified helper fn layer in host::sandbox::options::tests, impl Layer`` (it now compiles where feature = "cli" and `feature = "host"` and `test` hold, not where `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/options/tests.rs:80 nvx-rs/src/host/sandbox/options/tests.rs:85
modified helper fn preflight in host::sandbox::options::tests, impl Layer`` (it now compiles where feature = "cli" and `feature = "host"` and `test` hold, not where `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/options/tests.rs:90 nvx-rs/src/host/sandbox/options/tests.rs:95
modified helper fn manifest in host::sandbox::options::tests, impl Layer`` (it now compiles where feature = "cli" and `feature = "host"` and `test` hold, not where `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/options/tests.rs:95 nvx-rs/src/host/sandbox/options/tests.rs:100
modified helper fn distro_sha256 in host::sandbox::options::tests (moved, and it now compiles where feature = "cli" and feature = "host" and test hold, not where feature = "host" and test did) nvx-rs/src/host/sandbox/options/tests.rs:100 nvx-rs/src/host/sandbox/options/tests.rs:106
modified helper const CONTENT in host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/scratch/tests.rs:15 nvx-rs/src/host/sandbox/scratch/tests.rs:15
modified helper const WRITE_ONLY in host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and target_os = "linux" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and target_os = "linux" and test did) nvx-rs/src/host/sandbox/scratch/tests.rs:21 nvx-rs/src/host/sandbox/scratch/tests.rs:21
modified helper const WRITE_ONLY in host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test and windows hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test and windows did) nvx-rs/src/host/sandbox/scratch/tests.rs:28 nvx-rs/src/host/sandbox/scratch/tests.rs:28
modified helper fn open_write_only in host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and target_os = "linux" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and target_os = "linux" and test did) nvx-rs/src/host/sandbox/scratch/tests.rs:32 nvx-rs/src/host/sandbox/scratch/tests.rs:32
modified helper struct Staged in host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/scratch/tests.rs:42 nvx-rs/src/host/sandbox/scratch/tests.rs:42
modified helper impl Staged in host::sandbox::scratch::tests (it now compiles where any ( target_os = "linux" , windows ) and feature = "cli" and feature = "host" and test hold, not where any ( target_os = "linux" , windows ) and feature = "host" and test did) nvx-rs/src/host/sandbox/scratch/tests.rs:47 nvx-rs/src/host/sandbox/scratch/tests.rs:47
modified helper fn new in host::sandbox::scratch::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/scratch/tests.rs:49 nvx-rs/src/host/sandbox/scratch/tests.rs:49
modified helper fn image in host::sandbox::scratch::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/scratch/tests.rs:58 nvx-rs/src/host/sandbox/scratch/tests.rs:58
modified helper fn other in host::sandbox::scratch::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/scratch/tests.rs:63 nvx-rs/src/host/sandbox/scratch/tests.rs:63
modified helper fn normalized in host::sandbox::scratch::tests, impl Staged`` (it now compiles where any ( target_os = "linux" , windows ) and `feature = "cli"` and `feature = "host"` and `test` hold, not where `any ( target_os = "linux" , windows )` and `feature = "host"` and `test` did) nvx-rs/src/host/sandbox/scratch/tests.rs:68 nvx-rs/src/host/sandbox/scratch/tests.rs:68

... and 90 more, which the job's summary lists.

Relocated unchanged: 0; added: 6. Compared the merge base fc5d450d0bda with 3276e7727358.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues were identified for the changes narrowing the public API around CLI-owned image staging and artifact discovery.

No open issues 🎉

What changed in this PR

Implements SL6.4 of #1124, narrowing nvx’s public API so image staging and artifact discovery remain CLI-owned implementation details. This builds on #1532’s removal of unused helpers while preserving discovery, image checks, serialized bindings, and launch behavior.

Changes:

  • Makes artifact, seal, distro, scratch, and layer APIs crate-private, with feature gates that retain shared library functionality.
  • Moves private-API tests to their owning modules and adapts integration tests to exercise the CLI or inspect recorded data.
  • Updates documentation, the external-launch example, coverage references, and both platform API snapshots.
File Description
nvx-rs/​tests/​security_checklist.rs Moves image checks out; uses test-local file identity helpers.
nvx-rs/​tests/​cli/​lifecycle.rs Checks recorded bindings without importing private types.
nvx-rs/​tests/​cli/​artifacts.rs Asserts guest names through CLI output.
nvx-rs/​tests/​cli.rs Exercises scratch claims through the CLI and specifies guest defaults.
nvx-rs/​src/​lib.rs Removes artifact layouts from the public host description.
nvx-rs/​src/​host/​seal/​windows.rs Gates guarded-open functionality behind cli.
nvx-rs/​src/​host/​seal.rs Privatizes seal types and gates functionality by its users.
nvx-rs/​src/​host/​sandbox/​tests/​specification.rs Gates layer grammar tests behind cli.
nvx-rs/​src/​host/​sandbox/​scratch/​tests.rs Receives the scratch-claim security checklist test.
nvx-rs/​src/​host/​sandbox/​scratch.rs Makes scratch bindings and checked files crate-private.
nvx-rs/​src/​host/​sandbox/​options/​tests.rs Gates distro-dependent tests and adjusts imports.
nvx-rs/​src/​host/​sandbox/​mod.rs Privatizes image modules and removes layer re-exports.
nvx-rs/​src/​host/​sandbox/​layer.rs Makes layer types and parsing APIs crate-private.
nvx-rs/​src/​host/​sandbox/​distro/​tests.rs Receives the staged-image replacement checklist test.
nvx-rs/​src/​host/​sandbox/​distro.rs Makes distro bindings, policy values, and checks crate-private.
nvx-rs/​src/​host/​mod.rs Privatizes artifact and seal modules; updates documentation.
nvx-rs/​src/​host/​cli/​sandbox/​tests.rs Checks exact provisioned bindings for scratch and RAM uppers.
nvx-rs/​src/​host/​cli/​sandbox/​options.rs Imports SandboxLayer from its owning module.
nvx-rs/​src/​host/​artifacts/​require.rs Gates CLI-only artifact checks while retaining shared validation.
nvx-rs/​src/​host/​artifacts/​mod.rs Privatizes and gates discovery helpers, constants, and tests.
nvx-rs/​src/​host/​artifacts/​guest.rs Makes the guest inventory crate-private.
nvx-rs/​src/​host/​artifacts/​dir.rs Makes artifact layouts, paths, and directory APIs crate-private.
nvx-rs/​README.md Documents CLI ownership and revised test locations.
nvx-rs/​public-api/​windows.txt Removes privatized APIs from the Windows snapshot.
nvx-rs/​public-api/​linux.txt Removes privatized APIs from the Linux snapshot.
nvx-rs/​examples/​external-launch.rs Uses std::path::absolute instead of the private wrapper.
doc/​acceptance-case-matrix.md Points coverage references to the relocated tests.

Review effort: Balanced

@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-6b-unused-discovery branch from 008035d to 7e7ef6e Compare November 12, 2026 13:42
Base automatically changed from agents/slim-sl6-6b-unused-discovery to feature/nvx-refactor November 12, 2026 14:05
SL6.4 (#1124) makes host::seal, host::sandbox's distro, scratch and
layer modules and host::artifacts private to the CLI. Integration tests
reached them through their public paths, which they cannot once those
are private, so each case moves beside its owner or drives the nvx-rs
binary, with the same assertions:

- The security checklist's checks of a staged image and of a scratch
  image's claim, which only the CLI makes,
  a_staged_image_that_was_replaced_fails_its_check and
  a_scratch_image_is_claimed_by_one_launch_and_checked_again_after_a_release,
  move unchanged to the unit tests of host::sandbox::distro and
  host::sandbox::scratch, where they stage their images in a private
  directory as the checklist did.
- The checklist's
  a_launch_takes_a_new_private_log_and_keeps_every_entry_that_it_did_not_create
  compares the identities of the created log and of the file at its
  path with a test-local file_id, the device and inode on Linux and the
  FILE_ID_INFO on Windows, as the seal holds them, in place of
  FileSeal.
- lifecycle.rs compared the bindings that provision recorded with
  DistroBinding::verify and ScratchBinding::bind. A unit test of the
  CLI's sandbox command,
  provision_records_the_bindings_that_verification_and_the_scratch_binding_make,
  provisions a sandbox of each upper in process and makes that exact
  comparison. assert_bindings, and the RAM upper's lifecycle test, check
  what the test can tell of the images from outside: the bindings'
  versions, format, identity, policy verdict, absent manifest, schemes,
  kinds and lengths; each start checks the rest against the images.
- an_interrupted_start_keeps_its_claim_until_recovery_confirms_exit
  checked the scratch claim with ScratchBinding::check: a sandbox run on
  the same images now finds the image claimed while the orphaned
  OpenVMM runs, with scratch-claimed, and claims it once recovery
  confirmed the exit, as a_running_sandbox_claims_its_scratch_image
  does.
- run_boots_each_guest_with_its_default_memory and
  artifacts_list_every_guest_in_order spell the guests, their initramfs
  images and default memory, and their order, instead of reading Guest,
  whose own unit test checks the same values.

The case matrix names the moved checklist tests where they now are.

Part of #1124 (SL6.4).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
host::seal, host::sandbox's distro, scratch and layer modules, and
host::artifacts were public API of nvx, although only NVX's CLI stages
images and locates artifacts: the seals of checked files, the bindings
of distro layers and scratch images, their checks and claims, the
layer of a sandbox, and the artifact directories, guests and names of
nvx.py. They become crate-private where they are, gated by the
features of their users, with no change of behavior:

- host::sandbox's distro, scratch and layer modules, and the dir, guest
  and identity modules and the other items of host::artifacts, become
  pub(crate) and cli-gated, and host::sandbox no longer re-exports
  LAYER_ROLES, LayerRole and SandboxLayer. require_existing stays in
  host::artifacts for host::sandbox::require_file, which is public until
  SL6.7b.
- host::seal becomes pub(crate). host::snapshot opens snapshot files
  with open_read, and on Windows the platform layer names a log's job
  after the identity of FileSeal::of, so those stay with host; the
  seal's types take any(cli, windows), and what only the CLI's checks
  read, open_guarded, scheme, kind, length and difference, takes cli.
- The CLI imports SandboxLayer from host::sandbox::layer, and the
  external-launch example resolves its paths with std::path::absolute
  rather than the private host::artifacts::absolute.

Their unit tests, and the tests of host::sandbox's options and
specifications that use a layer or a binding, take cli, so they run in
the all-features tests. The image format and the identity that the
guest expects stay public in protocol::root's RootImage. NVX_OPENVMM,
NVX_AUTO_DOWNLOAD, the layouts, downloads, checks and claims are
unchanged.

The public API snapshots lose 132 lines on each platform, all under
nvx::host::artifacts, nvx::host::seal and nvx::host::sandbox's distro,
scratch and layer, with the three re-exports, and gain none. The
crate's, host's and host::sandbox's docs and the README present these
modules as private to the CLI, drop the README's sections and rows of
host::artifacts and host::seal, whose details the CLI's sections hold,
and the security checklist's paragraph names the unit tests that check
staged images and scratch claims.

Part of #1124 (SL6.4).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ppenna
Pedro Henrique Penna (ppenna) marked this pull request as ready for review November 12, 2026 14:09
@ppenna
Pedro Henrique Penna (ppenna) force-pushed the agents/slim-sl6-4-staging-private branch from 508170f to 3276e77 Compare November 12, 2026 14:10
@ppenna

Copy link
Copy Markdown
Contributor Author

Restacked onto feature/nvx-refactor at fc5d450d0bd, after #1532 merged: old head 508170fbefd, new head 3276e772735. The rebase had no conflicts, and git range-diff shows = for both commits.

@ppenna
Pedro Henrique Penna (ppenna) merged commit 8ae0617 into feature/nvx-refactor Nov 12, 2026
85 of 87 checks passed
@ppenna
Pedro Henrique Penna (ppenna) deleted the agents/slim-sl6-4-staging-private branch November 12, 2026 14:33
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 12, 2026
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches,
  Cargo's alone, with CI's guest image keys on the guest inputs, which
  it lists as GuestRustBuildConstants selects them; its three
  provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive.

Distribution links them, adds the guest binaries and the crate's own
license to its licensing paragraph, says what the crate holds, and
documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules and what each binary calls, guest_binaries.py and
guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/
hold. The Ubuntu and Azure Linux guests name the package's guest
inputs, link the release packages, and point to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 12, 2026
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches:
  Cargo's target directories and registry, the guest routine's fresh
  target directory, which keeps RUSTC_WRAPPER, the sccache cache of
  the self-hosted runners, and CI's guest image keys on the guest
  inputs, which it lists as GuestRustBuildConstants selects them; its
  three provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive.

Distribution links them, adds the guest binaries and the crate's own
license to its licensing paragraph, says what the crate holds, and
documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules and what each binary calls, guest_binaries.py and
guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/
hold. The Ubuntu and Azure Linux guests name the package's guest
inputs, link the release packages, and point to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 13, 2026
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches:
  Cargo's target directories and registry, the guest routine's fresh
  target directory, which keeps RUSTC_WRAPPER, the sccache cache of
  the self-hosted runners, and CI's guest image keys on the guest
  inputs, which it lists as GuestRustBuildConstants selects them; its
  three provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive,
  with a link to Continuous integration's Release packages section,
  which describes the package jobs.

Distribution links them, leaves the package jobs' mechanics to that
section of Continuous integration, adds the guest binaries and the
crate's own license to its licensing paragraph, says what the crate
holds, and documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules, with what is private to the crate since SL6.5a2, SL6.7b,
SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy
compiler and sandbox launch profile, the error codes, the guest's
space, the platform layer), and what each binary calls,
guest_binaries.py and guest_artifact_reuse.py, and what build/,
.cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests
name the package's guest inputs, link the release packages, and point
to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 13, 2026
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches:
  Cargo's target directories and registry, the guest routine's fresh
  target directory, which keeps RUSTC_WRAPPER, the sccache cache of
  the self-hosted runners, and CI's guest image keys on the guest
  inputs, which it lists as GuestRustBuildConstants selects them; its
  three provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive,
  with a link to Continuous integration's Release packages section,
  which describes the package jobs.

Distribution links them, leaves the package jobs' mechanics to that
section of Continuous integration, adds the guest binaries and the
crate's own license to its licensing paragraph, says what the crate
holds, and documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules, with what is private to the crate since SL6.5a2, SL6.7b,
SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy
compiler and sandbox launch profile, the error codes, the guest's
space, the platform layer), and what each binary calls,
guest_binaries.py and guest_artifact_reuse.py, and what build/,
.cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests
name the package's guest inputs, link the release packages, and point
to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 13, 2026
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches:
  Cargo's target directories and registry, the guest routine's fresh
  target directory, which keeps RUSTC_WRAPPER, the sccache cache of
  the self-hosted runners, and CI's guest image keys on the guest
  inputs, which it lists as GuestRustBuildConstants selects them; its
  three provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive,
  with a link to Continuous integration's Release packages section,
  which describes the package jobs.

Distribution links them, leaves the package jobs' mechanics to that
section of Continuous integration, adds the guest binaries and the
crate's own license to its licensing paragraph, says what the crate
holds, and documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules, with what is private to the crate since SL6.5a2, SL6.7b,
SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy
compiler and sandbox launch profile, the error codes, the guest's
space, the platform layer), and what each binary calls,
guest_binaries.py and guest_artifact_reuse.py, and what build/,
.cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests
name the package's guest inputs, link the release packages, and point
to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna) added a commit that referenced this pull request Nov 13, 2026
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches:
  Cargo's target directories and registry, the guest routine's fresh
  target directory, which keeps RUSTC_WRAPPER, the sccache cache of
  the self-hosted runners, and CI's guest image keys on the guest
  inputs, which it lists as GuestRustBuildConstants selects them; its
  three provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive,
  with a link to Continuous integration's Release packages section,
  which describes the package jobs.

Distribution links them, leaves the package jobs' mechanics to that
section of Continuous integration, adds the guest binaries and the
crate's own license to its licensing paragraph, says what the crate
holds, and documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules, with what is private to the crate since SL6.5a2, SL6.7b,
SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy
compiler and sandbox launch profile, the error codes, the guest's
space, the platform layer), and what each binary calls,
guest_binaries.py and guest_artifact_reuse.py, and what build/,
.cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests
name the package's guest inputs, link the release packages, and point
to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat-nvx-refactor tests-modified Changes existing tests, test data, or test wiring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants