Repository navigation
Description
Parent: #1083, in #1076. Needs: #1092, #1093. Unblocks: #1107, #1112, #1125.
Goal. The CLI moves out of nvx into nvx-cli, and behaves as before. First, the crate-private helpers that it uses become #[doc(hidden)] pub without the cli feature; then the nvx-rs binary moves, and then nvx-rs/src/host/cli/. The CLI reaches what phase 4 moves into nvx-cli through local alias modules, so those later moves don't edit its users.
Notes.
- The move counts only edited lines. The CLI's
crate::imports becomenvx::. - The exposed helpers are temporary. Their docs say so: phase 4 moves or deletes them, and SL6.8c removes the last of them from
nvx.
PRs, in order. Each PR has one goal, leaves dev green, and names in its description each old test of its area as kept, rewritten or retired, with each change that check_test_changes.py reports. Its tests follow the repository's test layout: a module's unit tests, and the code that only they use, sit in its tests.rs or tests/ and move with it. The estimates count core lines (code, not comments, docs or tests) and counted files; each PR records its measured values. Each PR does what its Scope says and no more: a case, input or layout that its Scope doesn't name, and whatever "Not in this PR" lists, is out of scope. Address every review comment within the scope, and ask before acting on one that asks for more. A PR whose measured core lines pass the stop that its Estimate names (twice the estimate, at most 600) stops and asks before continuing.
-
SL3.1a: The network parsers that the CLI uses are public, without the
clifeature.- Objective: The CLI cannot move to nvx-cli while the network parsers and strict policy-document reader it calls remain crate-private or available only with
cli. This PR exposes only those existing entry points so the later move compiles without changing their behavior. - Contents: The parsers of loopback forwards, proxy endpoints and native rules, and
policy::json::read_documentwith itsReadError, become#[doc(hidden)] pub, as does thepolicy::jsonmodule, and theircfg(feature = "cli")gates go (nvx-rs/src/host/network/{loopback, proxy, rule}.rs,policy/json.rsandpolicy/mod.rs). SL6.7b moves the policy-file reader, withpolicy::json, into nvx-cli; once nvx-cli has its own option parsers (SL3.10c), SL6.8c removes the loopback, proxy-endpoint and native-rule parsers fromnvx. - Scope:
nvx-rs/src/host/network/loopback.rs,proxy.rsandrule.rs: make the CLI's loopback-forward, proxy-endpoint and native-rule parsers#[doc(hidden)] puband remove theircligates.nvx-rs/src/host/network/policy/json.rsandpolicy/mod.rs: expose thejsonmodule,read_documentandReadErroras#[doc(hidden)] pubwithout theclifeature.- Keep the existing parser and strict JSON-reader tests in
nvx, and run them whenhostis enabled withoutcli.
- Not in this PR:
- Changing accepted network syntax, policy JSON validation, errors or normalization; this PR changes visibility and feature gates only.
- Moving the policy-file reader to nvx-cli; SL6.7b does that after its remaining library users are gone.
- Writing nvx-cli's own option parsers or deleting these exports; SL3.10c adds the parsers and SL6.8c removes the temporary exports.
- Exposing other network internals such as lowering, address parsing or policy compilation; no CLI caller needs them.
- Approach: Change the existing items' visibility, add
#[doc(hidden)], and remove only thecliconditions that guard them or their tests. Do not add wrappers, duplicate parsers, reorganize the network modules or alter parsing code. - Done when:
- The loopback-forward, proxy-endpoint and native-rule parser tests pass with
hostand withoutcli. - The strict JSON reader's duplicate-key and malformed-document tests pass with
hostand withoutcli. - The exposed items are reachable through
nvx::host::networkonly where the CLI move needs them.
- The loopback-forward, proxy-endpoint and native-rule parser tests pass with
- Needs: nothing.
- Estimate: 30 core lines, 5 counted files. Past 60 core lines, stop and ask before continuing.
- Objective: The CLI cannot move to nvx-cli while the network parsers and strict policy-document reader it calls remain crate-private or available only with
-
SL3.1b: The sandbox and artifact helpers that the CLI uses are public, without the
clifeature.- Objective: The CLI's one-shot launch, sandbox option and artifact calls are private or gated by
cli, so nvx-cli cannot keep using them after the move. This PR temporarily exposes those existing helpers without changing launch or artifact behavior. - Contents: The one-shot launch (
one_shot_openvmm_arguments,one_shot_kernel_command_line,PreparedLaunch::one_shotand the boot-token delivery),guest_gateway,parse_decimal,has_kernel_separator,require_artifactandREPO_BUILD_DIRbecome#[doc(hidden)] pub, and theircligates go (nvx-rs/src/host/sandbox/{mod, plan, prepared}.rsandnvx-rs/src/host/artifacts/{mod, require}.rs). Later PRs move or delete them, and SL6.8c removes the last of them fromnvx. - Scope:
nvx-rs/src/host/sandbox/mod.rs,plan.rsandprepared.rs: exposeparse_decimal,has_kernel_separator,guest_gateway, the two one-shot renderers,PreparedLaunch::one_shotand boot-token delivery as#[doc(hidden)] pub.nvx-rs/src/host/artifacts/mod.rsandrequire.rs: exposerequire_artifactandREPO_BUILD_DIRas#[doc(hidden)] pub.- Remove the exposed items'
cligates, while keeping their existing one-shot launch, parsing and artifact tests innvx.
- Not in this PR:
- Changing OpenVMM arguments, kernel command-line tokens, boot-token delivery or one-shot launch semantics; callers must behave as before.
- Moving or redesigning sandbox launch code and artifact discovery; later PRs move or delete these helpers after their library users leave.
- Adding a general numeric parser, command-line framework or artifact abstraction; the CLI needs only the named existing functions and constant.
- Exposing other sandbox planners, checked-image helpers or artifact internals; no moved CLI call requires them.
- Approach: Adjust visibility and feature conditions on the existing definitions and re-exports. Keep their signatures and implementations intact, mark the temporary API
#[doc(hidden)], and do not introduce forwarding modules or copies. - Done when:
- The one-shot launch tests still check the same OpenVMM arguments, kernel command line and boot-token delivery without
cli. - The decimal, kernel-separator, guest-gateway and artifact requirement tests pass with
hostand withoutcli. - nvx-cli can import exactly the named helpers from
nvx.
- The one-shot launch tests still check the same OpenVMM arguments, kernel command line and boot-token delivery without
- Needs: nothing.
- Estimate: 50 core lines, 5 counted files. Past 100 core lines, stop and ask before continuing.
- Objective: The CLI's one-shot launch, sandbox option and artifact calls are private or gated by
-
SL3.1c: The process helpers and path rules that the CLI uses are public, without the
clifeature.- Objective: The moved CLI still needs timed child waits, termination, killing, the supervisor's child and host path rules. This PR temporarily makes those existing items reachable from nvx-cli without requiring the
clifeature. - Contents: The timed wait, termination and kill of
nvx-rs/src/host/spawn.rs, the supervisor'schild, andhost::paths, whichnvx-rs/src/host/mod.rsdeclares crate-private, become#[doc(hidden)] pub, and theircligates go. Later PRs move or delete them, and SL6.8c removes the last of them fromnvx. - Scope:
nvx-rs/src/host/spawn.rs: make the CLI-used timed wait, terminate and kill methods#[doc(hidden)] pub, and remove theircligates.nvx-rs/src/host/supervisor/launch.rs: expose the launched supervisor'schildaccessor as#[doc(hidden)] pubwithout itscligate.nvx-rs/src/host/mod.rsandpaths.rs: makehost::pathsand the path functions used by the CLI#[doc(hidden)] pub.- Keep the existing process and
host::pathstests innvx, available withhostand withoutcli.
- Not in this PR:
- Changing wait deadlines, process signaling, verified-process rules or supervisor behavior; this PR changes access only.
- Moving path rules or process helpers into nvx-cli; later PRs do so after their remaining library users are gone.
- Adding async process APIs, recursive path policy, new canonicalization cases or cross-platform fallbacks; no moved CLI caller needs them.
- Exposing the rest of
spawnor supervisor internals; only the named CLI calls become public.
- Approach: Promote the existing methods and module along their current paths, mark them
#[doc(hidden)], and remove only theircliconditions. Do not wrap process handles, duplicate path code or refactor the supervisor. - Done when:
- Timed wait, terminate and kill tests retain their current results with
hostand withoutcli. host::pathstests retain their current absolute-path, resolution and platform behavior withoutcli.- The moved CLI can reach the supervisor's child and only the process and path helpers it already calls.
- Timed wait, terminate and kill tests retain their current results with
- Needs: nothing.
- Estimate: 30 core lines, 4 counted files. Past 60 core lines, stop and ask before continuing.
- Objective: The moved CLI still needs timed child waits, termination, killing, the supervisor's child and host path rules. This PR temporarily makes those existing items reachable from nvx-cli without requiring the
-
SL3.1d:
nvx-rsis built from nvx-cli.- Objective: The
nvx-rsexecutable must belong to nvx-cli before the CLI implementation moves there. This PR moves the binary and its integration tests, and redirects every repository build to the new package while preserving the executable's path and behavior. - Contents:
git mvofnvx-rs/src/bin/nvx-rs.rstocrates/nvx-cli/src/bin/nvx-rs.rs; it still callsnvx::host::cli. Cargo discovers the binary by its file name without editingnvx-cli's manifest. Remove the old declaration fromnvxin the same change, so exactly one package owns the executable. CI and the scripts build it with-p nvx-cli(ci.yml,nvx_rs.py,scripts/setup/setup-linux.shandscripts/setup/setup-windows-whp.ps1), and it lands innvx-rs/targetas before. The CLI's integration tests (nvx-rs/tests/cli.rsandnvx-rs/tests/cli/) move with it: they keepCARGO_BIN_EXE_nvx-rs, and takenvx-fake-openvmmfrom the workspace build instead ofCARGO_BIN_EXE_nvx-fake-openvmm. The CLI's tests of the restore's network policy and of a restrictive umask move with them, and CI's two jobs that build the binary and record its provenance follow. - Scope:
- Move
nvx-rs/src/bin/nvx-rs.rstocrates/nvx-cli/src/bin/nvx-rs.rsfor Cargo auto-discovery; it continues to callnvx::host::cli::main. Remove the old binary declaration without editingnvx-cli's manifest. - Move
nvx-rs/tests/cli.rsandnvx-rs/tests/cli/intocrates/nvx-cli/tests/, including the restore-network-policy and restrictive-umask scenarios. - Keep
CARGO_BIN_EXE_nvx-rs; obtainnvx-fake-openvmmfrom the workspace build rather than a same-package Cargo variable. - Update
.github/workflows/ci.yml,scripts/nvx_tools/nvx_rs.py,scripts/setup/setup-linux.shandscripts/setup/setup-windows-whp.ps1to build-p nvx-cli. - Keep Cargo output at
nvx-rs/target, and update both CI binary-and-provenance jobs to read and publish the same paths.
- Move
- Not in this PR:
- Moving
nvx-rs/src/host/cli/; SL3.1e moves the implementation after the binary's package is established. - Changing CLI commands, output, errors, arguments or exit statuses; this is a package move.
- Renaming the executable, its environment variables, provenance file or target directory; scripts and packages rely on the current names.
- Moving or rewriting
nvx-fake-openvmm; its workspace executable is only located differently by these tests. - Cleaning up CI or setup scripts beyond the package selector and paths forced by the move.
- Moving
- Approach: Use
git mvfor the binary and integration-test tree, retaining Cargo auto-discovery in the CLI package and removing the old declaration. Change only the forced package selection and fake executable lookup; rely on the workspace target-directory configuration instead of adding copy steps, new build scripts or test harnesses. - Done when:
- CI and both setup scripts build
nvx-rswith-p nvx-cliand find it undernvx-rs/target. - Cargo metadata lists exactly one
nvx-rsbinary, owned bynvx-cli, and the CLI manifest is unchanged by the move. - The moved integration tests find
nvx-rsthroughCARGO_BIN_EXE_nvx-rsand the workspace-built fake OpenVMM. - The moved command scenarios, including restore network policy and restrictive umasks, pass as before.
- Both CI jobs record and upload the binary and provenance from their existing output paths.
- CI and both setup scripts build
- Needs: SL0.2c, in nvx-rs slimming 1.1.2: one Cargo workspace, and the new crates' empty shells #1092.
- Estimate: 40 core lines, 5 counted files. Past 80 core lines, stop and ask before continuing.
- Objective: The
-
SL3.1e: The CLI's code lives in nvx-cli, and behaves as before.
- Objective: The CLI implementation still lives inside the
nvxlibrary after its executable has moved. This PR moves that implementation into nvx-cli without changing commands, using short-lived local aliases for helpers that move later. - Contents:
git mvofnvx-rs/src/host/cli/(6.4K core lines), with whatdevadded to it:run --restore-network-policyand the scratch template's download. Itscrate::imports becomenvx::, except for NVXC, the helpers that phase 4 moves into nvx-cli, and the old error: it reaches those through local modules (nvxc,images,paths,artifacts,egress,mountsanderrors) that re-export them fromnvxuntil then.pathsgives a freeverify, which every CLI caller uses instead of the method. - Scope:
- Move
nvx-rs/src/host/cli/intocrates/nvx-cli/src/, includingrun --restore-network-policy, the scratch template's download support, and everytests.rsandtests/below it, whose test-only code (Syntax::assert_lists,Curl::plain) stays in them. - Replace moved code's
crate::references withnvx::references where the called API remains innvx. - Add local
nvxc,images,paths,artifacts,egress,mountsanderrorsmodules that re-export the currentnvxitems until later moves replace them. - In the local
pathsmodule, expose a freeverifyfunction and switch every moved CLI caller from the old method to it. - Keep the existing command modules, command dispatch, output, errors and unit-test cases otherwise unchanged.
- Move
- Not in this PR:
- Rewriting commands onto the new launch or store interfaces; later groups switch dependency-closed command sets.
- Copying helper implementations into nvx-cli; aliases prevent duplicate implementations until each helper can move.
- Changing command-line syntax, output compatibility, error codes, download behavior or sandbox behavior.
- Renaming, reorganizing or cleaning up the moved CLI modules beyond import edits forced by the new crate.
- Moving the aliased helpers now; their remaining
nvxusers prevent a move in this PR.
- Approach: Use
git mvfor the CLI tree, then make mechanical import edits. Keep each temporary local module as a thin re-export, with only the freepaths::verifyadapter required by later path moves; do not create a facade framework or duplicate code. - Done when:
- All moved CLI unit tests pass from nvx-cli with their existing cases and expectations.
nvx-rsdispatches every existing command through the implementation now owned by nvx-cli.- The moved code reaches temporary dependencies only through the seven local alias modules.
- Every moved path-verification caller uses the local free
verifyfunction.
- Needs: SL3.1a, above; SL3.1b, above; SL3.1c, above; SL3.1d, above; SL0.3d, in nvx-rs slimming 1.1.3: the guest's and the host's OS layers live in
nvx-sys#1093. - Estimate: 150 core lines, 3 counted files. Past 300 core lines, stop and ask before continuing.
- Objective: The CLI implementation still lives inside the
Tests. SL3.1a–SL3.1c keep the library tests of the items that they expose in nvx (such as the network parsers', the strict JSON reader's, the one-shot launch's and host::paths' tests), now run without the cli feature. SL3.1d's build and script checks build nvx-rs with -p nvx-cli into nvx-rs/target, and SL3.1d moves the CLI's integration-test root and modules (nvx-rs/tests/cli.rs and nvx-rs/tests/cli/**) with the binary: they pass as before, find nvx-rs through CARGO_BIN_EXE_nvx-rs, and take nvx-fake-openvmm from the workspace build. SL3.1e moves the CLI's unit tests (nvx-rs/src/host/cli/**) to nvx-cli, where they pass as before.
Done when: every PR above has merged, with dev green.
Activity
esaurez commentedon Nov 3, 2026
Closing as not planned: the plan in #1076 changed.
nvxstays the only crate, with no Cargo workspace and no new crates. NVX's own programs, its control protocol and the OS layers stay innvx, private to it, and CI checks the public API against committed snapshots (#1091). The CLI stays underhost::cli, and #1083 switches it to the new interface in place.