Repository navigation
Description
Parent: #1077, in #1076. Needs: #1091. Unblocks: #1093, #1095, #1096, #1097, #1106, #1113, #1115, #1118, #1127.
Goal. The repository is one Cargo workspace, with nvx-rs and empty shells for nvx-sys, nvx-control, nvx-guest-tools, nvx-init, nvx-cli, nvx-testing and nvx-api-tests. nvx-sys declares the dependencies of its first moves; nvx-control has its host and guest features; and the shells declare their final path dependencies as the target crates become available, except that nvx-api-tests stays dependency-free until SL5.1a in #1118. nvx-cli is a library shell until the real binary moves; its nvx-testing development dependency is added in SL0.2d, so later source moves do not edit its manifest. The build output stays in nvx-rs/target, so CI, the scripts and the packages keep finding artifacts at their existing paths.
Notes.
- The test adapter stays outside the workspace (the workspace's
excludelists it), with its own lockfile and target directory, until nvx-rs slimming 4.1.2: the test adapter is gone #1119 deletes it.
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.
-
SL0.1: One Cargo workspace, with the build output where it was.
- Objective: The repository becomes one Cargo workspace without moving the artifact paths used by CI, scripts and release packages. The excluded runtime adapter keeps its independent lockfile and target directory, while every build inventory starts following workspace-level inputs.
- Contents: A root workspace whose member is
nvx-rs. The test adapter stays outside it (the workspace'sexcludelists it), with its own lockfile and, through its own.cargo/config.toml, its own target directory, until SL5.2 deletes it.[profile.guest], the lints and the lockfile move to the root. A root.cargo/config.tomlkeeps the build output innvx-rs/target, so CI, the scripts and the packages keep finding artifacts at their existing paths; CI, the scripts and the Dockerfile run Cargo inside the repository, where that configuration applies.GuestRustBuildConstants' three input selectors (SOURCE_FILES,SOURCE_DIRECTORIESandSOURCE_PATTERN) and itsSOURCE_PATHS,ReleaseBuildConstants.PROJECT_SOURCE_PATHS(scripts/nvx_tools/build_constants.py), and both of the Dockerfile's source-copy stages, take the root's manifest, lockfile and.cargo, andcrates/, whichcrates/.gitkeepkeeps in a clean checkout until SL0.2a adds its first crate. - Scope:
- Add the root
Cargo.tomlworkspace withnvx-rsas its member andtests/runtime-adapterinexclude; move[profile.guest], workspace lints andCargo.lockto the root. - Add root
.cargo/config.tomlwithtarget-dir = "nvx-rs/target", and givetests/runtime-adapterits own.cargo/config.tomlfor its existing target directory. - Update
GuestRustBuildConstants' input selectors and source paths, plusReleaseBuildConstants.PROJECT_SOURCE_PATHS, for the root manifest, lockfile,.cargoandcrates/;SOURCE_PATTERNkeeps excludingtests.rsandtests/under bothnvx-rs/src/andcrates/*/src/. - Update both Rust source-copy stages in
docker/Dockerfileto copy the root workspace inputs andcrates/while retainingnvx-rs/. - Add
crates/.gitkeep, so a clean checkout has thecrates/that the inventories and both Docker stages name before SL0.2a adds the first package.
- Add the root
- Not in this PR:
- Adding
crates/*as workspace members or creating any new crate; SL0.2a through SL0.2d do that. - Moving Rust source modules, binaries or package manifests out of
nvx-rs; later groups own those moves. - Moving build output to the root
target/; existing consumers requirenvx-rs/target. - Bringing
tests/runtime-adapterinto the workspace or sharing its lockfile and target directory; it remains independent until SL5.2. - Changing Cargo profiles, lint levels or build behavior beyond relocating their existing definitions.
- Changing where CI, the scripts or the Dockerfile run Cargo; they already run inside the checkout, and SL0.2a adds the check action's
--workspaceflags.
- Adding
- Approach: Use Cargo's root workspace and one root configuration; do not add wrapper scripts or artifact-copy steps. Run Cargo with a working directory inside the checkout so
nvx-rs/targetremains effective. Update the existing fixed inventories and Docker copies directly, includingcrates/before it contains members. - Done when:
- Cargo commands from CI, scripts and both Docker build stages still place and find workspace artifacts under
nvx-rs/target. - The runtime adapter builds and runs with its own lockfile and existing target directory outside the workspace.
- Tests show all three guest input selectors,
SOURCE_PATHSandPROJECT_SOURCE_PATHSinclude the root workspace inputs andcrates/, while guest inputs exclude every crate'stests.rsandtests/; the layout check accepts the root workspace manifest as a crate. - A clean checkout contains tracked
crates/.gitkeep, so both Docker source-copy stages can copy the root inputs,nvx-rs/andcrates/.
- Cargo commands from CI, scripts and both Docker build stages still place and find workspace artifacts under
- Needs: SL0.0a, in nvx-rs slimming 1.1.1: the public API is checked, and NVX's programs are hidden from it #1091; SL0.0b, in nvx-rs slimming 1.1.1: the public API is checked, and NVX's programs are hidden from it #1091.
- Estimate: 80 core lines, 5 counted files. Past 160 core lines, stop and ask before continuing.
-
SL0.2a: The OS crate exists, and CI checks every crate in
crates/.- Objective: The workspace gains its first shared crate and CI begins checking the workspace rather than only
nvx.nvx-sysstarts as a dependency-ready shell, so the later OS-layer moves can land without another workspace or CI conversion. - Contents: The workspace takes
crates/*, andcrates/nvx-sysis an empty shell that declares the dependencies of its first moves and replacescrates/.gitkeep. The check action builds, lints and tests--workspace. - Scope:
- Change the root workspace membership from only
nvx-rstonvx-rspluscrates/*. - Add
crates/nvx-sys/Cargo.tomland its empty library shell, with the dependencies required by the first OS-layer moves. - Remove
crates/.gitkeep, whichcrates/nvx-sysreplaces; SL0.1's Docker stages already copycrates/. - Update
.github/actions/check-nvx-rs/action.ymlso formatting, builds, lints and tests cover--workspaceon Linux and Windows.
- Change the root workspace membership from only
- Not in this PR:
- Moving any OS implementation into
nvx-sys; nvx-rs slimming 1.1.3: the guest's and the host's OS layers live innvx-sys#1093 and nvx-rs slimming 1.1.4: the time core thatnvxandnvx-timeshare lives innvx-sys#1094 perform those moves. - Adding public APIs, compatibility re-exports or a stability promise to
nvx-sys; the shell contains no behavior. - Creating the other six crates (
nvx-control,nvx-guest-tools,nvx-init,nvx-cli,nvx-testingandnvx-api-tests); SL0.2b through SL0.2d add them. - Publishing
nvx-sysimmediately; SL0.3a1 adds it to the publisher when it has content. - Changing the excluded runtime adapter or adding it to workspace checks.
- Editing
docker/Dockerfile; SL0.1 already copiescrates/.
- Moving any OS implementation into
- Approach: Add the minimal manifest and library root that Cargo requires, using the workspace's version, edition and lints where applicable. Declare only dependencies already known to be needed by the first moves. Extend the existing check action with
--workspace; do not add per-crate jobs or a crate generator. - Done when:
- Cargo workspace metadata lists
nvx-rsand the emptynvx-syspackage, while excluding the runtime adapter. - The check action formats, builds, lints and tests the whole workspace on Linux and Windows.
- The Docker Rust stages see the
nvx-sysmanifest through SL0.1'scrates/copy. nvx-syscompiles as an empty library with the dependencies needed by its first moves.
- Cargo workspace metadata lists
- Needs: SL0.1, above.
- Estimate: 40 core lines, 4 counted files. Past 80 core lines, stop and ask before continuing.
- Objective: The workspace gains its first shared crate and CI begins checking the workspace rather than only
-
SL0.2b: The control and guest-tool crates exist.
- Objective: The workspace gains stable destinations for the control protocol and guest binaries before their code moves. Their manifests establish publication and platform behavior now, avoiding manifest churn in the move PRs.
- Contents: Empty shells:
nvx-control,publish = false, with a host feature and a guest feature;nvx-guest-tools, empty on Windows, which nothing publishes until it has content (SL1.1a). - Scope:
- Add the empty
crates/nvx-controlpackage withpublish = falseand separatehostandguestfeatures. - Add the empty
crates/nvx-guest-toolspackage, configured to compile as an empty shell on Windows. - Keep
nvx-guest-toolsout of the publisher's active ordered list until SL1.1a gives it content. - Let the existing
crates/*workspace membership and--workspacechecks discover both packages.
- Add the empty
- Not in this PR:
- Defining the control protocol or moving host and guest control code; later PRs populate
nvx-control. - Moving guest binaries or their modules into
nvx-guest-tools; SL1.1a and later move them. - Publishing
nvx-control; it is repository-internal by design. - Publishing an empty
nvx-guest-toolscrate or adding it to nightly publication; SL1.1a does that after its first move. - Adding Windows guest-tool behavior; the package intentionally has no Windows implementation.
- Defining the control protocol or moving host and guest control code; later PRs populate
- Approach: Create only the two manifests and minimal source roots. Express the two control features directly in its manifest and use ordinary conditional compilation for the guest-tool shell on Windows. Reuse workspace discovery and checks; do not add build scripts, feature abstractions or placeholder APIs.
- Done when:
- Workspace metadata lists
nvx-controlas unpublished withhostandguestfeatures. - Workspace metadata lists
nvx-guest-tools, but the nightly publisher still lists onlynvx. - Both empty shells pass the workspace checks, including an empty
nvx-guest-toolsbuild on Windows.
- Workspace metadata lists
- Needs: SL0.2a, above.
- Estimate: 40 core lines, 4 counted files. Past 80 core lines, stop and ask before continuing.
-
SL0.2c: The init and CLI crates exist.
- Objective: The init and CLI packages exist with dependencies whose target crates are available. The CLI stays a library shell until its real binary moves, so exactly one package owns the executable and the later move need not edit the CLI manifest.
- Contents: Empty shells,
publish = false:nvx-init, empty on Windows, andnvx-cli, whosenvxdependency enableshostandcliuntil SL3.1f. Declare final dependencies whose target crates exist, includingnvx-control; addnvx-cli's development dependency onnvx-testingin SL0.2d. The CLI has no binary target or placeholder command yet. SL3.1d moves the real source tocrates/nvx-cli/src/bin/nvx-rs.rs, where Cargo discovers it without changing the CLI manifest. - Scope:
- Add the empty, unpublished
crates/nvx-initpackage, configured to compile as an empty shell on Windows. - Add the empty, unpublished
crates/nvx-clilibrary package without a[[bin]]declaration or a placeholder executable; retain Cargo's binary auto-discovery for the later source move. - Declare the final planned dependencies whose target crates exist, including
nvx-control; defer thenvx-testingdevelopment dependency to SL0.2d. - For now, make
nvx-cli's dependency onnvxenable the existinghostandclifeatures, until SL3.1f removes that bridge. - Make only the three library lint/build/test commands with
--no-default-featuresselect-p nvx, not--workspace, so dependent packages cannot silently enable its features. Retain workspace-wide coverage elsewhere and extend the existing action test with a real Cargo feature-isolation regression. - Keep the workspace default-feature lint and test commands, and also add standalone
clippy -p nvx --lib -- -D warningsandtest -p nvxcommands with the existing locked/toolchain arguments. This preserves the ordinary library configuration withoutcli, as well as coverage of every workspace package.
- Add the empty, unpublished
- Not in this PR:
- Moving PID 1, helper programs or guest space code into
nvx-init; later PRs own those moves. - Moving the CLI implementation, store or command modules into
nvx-cli; later PRs populate the shell. - Changing
nvx'shostorclifeatures; the shell consumes their current form until SL3.1f. - Publishing either crate; both remain repository-built packages.
- Adding Windows behavior to
nvx-init; its shell is intentionally empty there.
- Moving PID 1, helper programs or guest space code into
- Approach: Add minimal library manifests and source roots using existing workspace dependencies and features. Do not declare a missing binary, disable binary auto-discovery, or add forwarding modules, placeholder commands or build scripts. Keep the original package as the sole owner of
nvx-rsuntil SL3.1d moves the real source. - Done when:
- Workspace metadata lists unpublished
nvx-initand library-onlynvx-clipackages with the planned dependencies whose target crates exist. nvx-clienablesnvx'shostandclifeatures, declares no binary yet, and exactly one package ownsnvx-rs.- A real Cargo regression shows that the three isolated no-default-feature commands compile
nvxwithout features despite the new dependent; the remaining checks still cover the workspace. - The additional isolated default-feature lint and test commands check
nvxwithout dependency-enabledcli; the original workspace default-feature runs are retained. The regression verifies actual compiled feature sets for both configurations. - Both shells pass workspace checks, with
nvx-initempty on Windows.
- Workspace metadata lists unpublished
- Needs: SL0.2b, above.
- Estimate: 30 core lines, 4 counted files. Past 60 core lines, stop and ask before continuing.
-
SL0.2d: The test crates exist.
- Objective: The workspace gains dedicated packages for shared test support and public-API tests before those tests move. Establish the known test-support path dependencies without adding behavior; the API-test shell stays dependency-free until its tests arrive in SL5.1a.
- Contents: Empty, unversioned shells,
publish = false:nvx-testingdepends onnvxwithdefault-features = falseand onnvx-control, without explicitly enabling features on either dependency.nvx-api-testsdeclares no dependencies until SL5.1a in nvx-rs slimming 4.1.1: public-API tests, and smoke tests on real VMs #1118. Oncenvx-testingexists, add its planned development dependency tonvx-cli. - Scope:
- Add the empty, unpublished
crates/nvx-testingpackage with path dependencies onnvx(default-features = false) andnvx-control; neither dependency explicitly enables features. Registry dependencies move with the fake implementation in SL6.9, and the move that first needs a feature enables it. - Add the empty, unpublished
crates/nvx-api-testspackage with no dependencies. SL5.1a adds itsnvxdependency andnvx-testingdevelopment dependency with the feature-set tests. - Add
nvx-testingas the planned development dependency ofnvx-cli, now that the target package exists; do not add placeholder test APIs. - Let the existing
crates/*membership and--workspacechecks discover and validate both packages.
- Add the empty, unpublished
- Not in this PR:
- Moving the fake OpenVMM or integration-test helpers into
nvx-testing; later PRs populate it. - Adding public-API build matrices, examples, checklists or the test-case fate matrix; SL5.1a owns those tests.
- Moving or rewriting runtime-adapter tests; the adapter remains outside the workspace.
- Publishing either test crate; both are repository-only packages.
- Adding placeholder test APIs merely to exercise dependencies; no caller needs them yet.
- Moving the fake OpenVMM or integration-test helpers into
- Approach: Create minimal library manifests and documented source roots, with no versions, edition 2024 and workspace lints. Declare only the two test-support path dependencies above and the CLI development dependency; leave the API-test shell dependency-free. Rely on workspace discovery and the existing workspace check action; do not add test harnesses, fixtures, generators or forwarding modules.
- Done when:
- Workspace metadata lists unpublished
nvx-testingandnvx-api-testspackages. - Metadata shows
nvx-testing's two path dependencies, no explicitly enabled dependency features and disabled default features for itsnvxdependency;nvx-api-testsdeclares no dependencies. - Workspace metadata resolves
nvx-cli's development dependency to the newnvx-testingpackage. - Both empty packages pass the workspace formatting, lint, build and test commands.
- Workspace metadata lists unpublished
- Needs: SL0.2b and SL0.2c, above; the latter supplies
nvx-clifor its development dependency. - Estimate: 20 core lines, 2 counted files. Past 40 core lines, stop and ask before continuing.
Tests. CI builds, lints and tests --workspace, except the three library commands that check nvx without default features: those use -p nvx to prevent dependency feature unification from invalidating the check. Two additional -p nvx commands preserve its default-feature lint and test coverage without replacing the workspace runs. Checks show that CI, the scripts and the Dockerfile's build stages run Cargo inside the repository, and still find the workspace's artifacts in nvx-rs/target. The test adapter, with its own lockfile and .cargo/config.toml, builds in its existing target directory and still runs. The guest build's input selectors, SOURCE_PATHS, PROJECT_SOURCE_PATHS and both of the Dockerfile's source-copy stages take the root's manifest, lockfile and .cargo, then crates/.
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). Its root workspace and the new crates' empty shells have no use.