Repository navigation
Description
Parent: #1087, in #1076. Needs: #1091, #1102, #1105, #1119. Unblocks: #1121, #1123, #1130, #1131, #1132. No PR of this group merges before the API-ready commit.
Goal. Before the deletions, retained code stops using what leaves: strict snapshot reads use host::sys; the artifact modules and snapshot key import host::runtime; and PreparedLaunch takes Inherited from its low-level owner. Retained tests stop using old launch helpers. The old capture steps go; guest::snapshot's repair and the time ABI's capture and restore surface become private. nvx-ingress start spawns its announcer with std::process::Command and the private OS helpers, so Announcer, PROGRAM and StartError go before the process modules.
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.
-
SL6.0a: Strict snapshot reads survive the stores' removal.
- Objective: Strict snapshot manifest reads currently depend on file helpers and refusal classification owned by the store that later PRs delete. They move to the host's platform layer, preserving the size bound and regular-file checks, and retained readers use their new owner.
- Contents:
open_regularandread_at_most, with their regular-file check, leavehost::store::regularfor the host's platform layer (host::platform), which stays and already holds the host's file helpers; the store keeps aliases, andSnapshotManifest::readuses the new module. It needs no seal or planner. - Scope:
- Move
open_regular,read_at_most,is_refused, the private refusal type and their regular-file support fromnvx-rs/src/host/store/regular.rstohost::platform. - Keep
open_regular_inin the store, but have it build link and non-regular-file refusals with the moved support. - Keep temporary aliases in
host::store::regularfor store and clone callers until nvx-rs slimming 4.2.2: the old clone path, template store and sandbox store are gone #1121 deletes them. - Change
SnapshotManifest::readinnvx-rs/src/host/template/manifest.rsto usehost::platformdirectly. - Preserve the current maximum-length error and the refusal of directories and other non-regular files.
- Move
- Not in this PR:
- Sealing files, planning paths or adding identity checks: the manifest reader needs none of them.
- Moving
open_regular_in,identity_of,was_removedor unrelated store helpers: no retained caller listed for this PR needs them. - Changing the manifest format, length limit or error semantics.
- Reworking store callers to use the new owner: the aliases keep them working until their deletion.
- Approach: Move the producers, their private refusal type, classification and regular-file support together into
host::platform, without introducing a file abstraction or planner. Letopen_regular_incall the moved support, retain aliases at the old path for temporary callers, and update only the retained manifest reader directly. - Done when:
SnapshotManifest::readreads throughhost::platformand still accepts a bounded regular manifest.- Manifest tests still reject a non-regular path and a manifest over
MAX_MANIFEST_LEN. - The old clone path still recognizes errors from the moved helpers as refusals.
- The remaining store callers compile through the temporary aliases.
- Needs: SL2.12b, in nvx-rs slimming 2.3.2: snapshots have one strict format, and a capture finishes into it #1102.
- Estimate: 150 core lines, 4 counted files. Past 300 core lines, stop and ask before continuing.
-
SL6.0b: Retained modules no longer import legacy identity or handle paths.
- Objective: Retained artifact, snapshot-key and prepared-launch code imports identities and inherited handles through modules that later PRs delete. Each import switches to the low-level module that owns the same type, with no behavior change.
- Contents: The artifact modules (
artifacts/{mod, dir, identity}.rs) and the snapshot key importhost::runtime, andPreparedLaunchtakesInheritedfrom its low-level owner, not the supervisor. - Scope:
- Change
nvx-rs/src/host/artifacts/{mod,dir,identity}.rsto importArtifactIdentityandRuntimeIdentityfromhost::runtime. - Change
nvx-rs/src/host/template/key.rsto import its retained identity types fromhost::runtime. - Change
nvx-rs/src/host/sandbox/prepared.rssoPreparedLaunchtakesInheritedfrom its low-level owner instead ofhost::supervisor. - Keep artifact discovery, identity comparison, snapshot-key construction and prepared-launch behavior unchanged.
- Change
- Not in this PR:
- Renaming identity or inherited-handle types, or changing their representation.
- Refactoring artifact discovery, snapshot keys or launch preparation beyond the listed imports.
- Moving more supervisor or store APIs to
host::runtime: no retained caller in this PR needs them. - Deleting the store or supervisor modules; nvx-rs slimming 4.2.2: the old clone path, template store and sandbox store are gone #1121 does that after their consumers are detached.
- Approach: Replace the five imports with the types' retained owners and make only compiler-forced path edits. Do not add a compatibility module, conversion layer or new trait; these are the same types at their established low-level location.
- Done when:
- The artifact module tests pass without importing identities from
host::store. - Snapshot-key tests pass without a store identity import.
- Prepared-launch tests pass without importing
Inheritedfromhost::supervisor.
- The artifact module tests pass without importing identities from
- Needs: SL2.12a, in nvx-rs slimming 2.3.2: snapshots have one strict format, and a capture finishes into it #1102.
- Estimate: 30 core lines, 5 counted files. Past 60 core lines, stop and ask before continuing.
-
SL6.0c: The tests that stay no longer use the old launch helpers.
- Objective: Tests that remain after the old store and launch paths disappear still use their helpers. The retained fake VMM, process, Windows junction and spawn-lock cases become independent of those helpers while preserving the behaviors they test.
- Contents: The fake VMM's own integration cases,
runs_boot_or_restore_a_microvm_on_the_terminalandruns_find_absolute_policy_paths_in_relative_share_roots, leavetests/fake_openvmm.rs, with their helpers, fortests/fake_openvmm_behavior.rs: they spawn the fake withstd::process::Commandand name aggregate children by literal, so they use no supervisor, store, instance or old aggregate renderer. The instance's cases stay for SL6.1 to retire. The retained process, Windows junction and spawn-lock tests replacespawn_commandwith a test-only spawn that keeps the OS spawn lock's synchronization. They keep their assertions of--restore-network-policy; the Windows spawn-lock tests stay in the Windows platform'stests.rs. - Scope:
- Move the fake VMM's
runs_boot_or_restore_a_microvm_on_the_terminalandruns_find_absolute_policy_paths_in_relative_share_rootscases and their helpers fromnvx-rs/tests/fake_openvmm.rstonvx-rs/tests/fake_openvmm_behavior.rs. - Have those two cases use
std::process::Commandand literal aggregate-child names, with no store, supervisor, instance or aggregate-renderer dependency. - Replace
spawn_commandonly in retained process, Windows junction and spawn-lock tests with a test-only spawn that holds the OS spawn lock over process creation. - Keep the retained assertions for
--restore-network-policy, and keep the Windows spawn-lock cases in the Windows platform'stests.rs.
- Move the fake VMM's
- Not in this PR:
- Moving or rewriting the instance's integration cases: SL6.1 retires them with
host::instance. - Changing production spawning, locking or aggregate naming; this PR changes tests only.
- Building a reusable test launcher or aggregate-name abstraction: the retained cases need one direct spawn and literal names.
- Adding new fake VMM behaviors or launch scenarios beyond the two named cases.
- Moving or rewriting the instance's integration cases: SL6.1 retires them with
- Approach: Split the two retained fake VMM behaviors from the instance suite, then use direct standard-library spawning. Put the narrow test-only spawn around the existing OS lock beside its callers, in
host::testsand the Windows platform'stestsmodule; do not keep it in a production file or preservespawn_commandthrough another abstraction. - Done when:
- The two named fake VMM cases run from
tests/fake_openvmm_behavior.rsand use none of the old launch helpers. - Retained process and Windows junction tests call no
spawn_command. - Windows spawn-lock tests still exercise synchronization and run from the Windows platform's
tests.rs. - The retained cases still assert
--restore-network-policy.
- The two named fake VMM cases run from
- Needs: nothing.
- Estimate: 0 core lines (tests), no counted files.
-
SL6.11c: The old capture steps are gone.
- Objective: The one-call guest snapshot path has replaced the old capture-step API, while repair and restore-only time details remain unnecessarily public. The obsolete steps disappear and the remaining implementation details become private to
guest::snapshot. - Contents: Delete the activation's old capture steps:
AdmissionFence,CapturePreparation(prepare),CaptureBarrier(cancel),Restored(into_parts) andCaptureError(into_cause);guest::snapshot::{repair, Repair}become private.TimeAbi::{capture, restore_finish}and the surface that only they use become private toguest::snapshot:CaptureRequest,CaptureOutcome,Restore(withnetwork),RestoreNetwork,RestoreFinish,MemoryRange,CpuSetandScratchPolicy, with all their methods, such asCaptureRequest::finish,Restore::take_seedandRestoreFinish::new_cpus. - Scope:
- Delete
AdmissionFence,CapturePreparation::prepare,CaptureBarrier::cancel,Restored::into_partsandCaptureError::into_causefrom the activation code. - Make
guest::snapshot::{repair, Repair}private while keeping the repair implementation and its internal tests. - Make
TimeAbi::{capture, restore_finish}private toguest::snapshot. - Privatize
CaptureRequest,CaptureOutcome,Restorewithnetwork,RestoreNetwork,RestoreFinish,MemoryRange,CpuSetandScratchPolicy, including their methods.
- Delete
- Not in this PR:
- Changing
guest::snapshot::capture, its failure disposition or its one-call capture and repair behavior. - Redesigning repair or time synchronization after making their implementation surface private.
- Deleting
TimeAbimethods used outside snapshot capture and restore. - Adding replacement public capture-step types or compatibility aliases; no retained caller needs them.
- Changing
- Approach: Delete the named obsolete items, narrow visibility on the exact repair and time surface, and update only internal paths forced by privacy. Keep the existing capture and repair implementation in place; do not introduce a facade, replacement state machine or generalized private API.
- Done when:
- Tests whose sole subject is a deleted capture step or public repair are retired.
guest::snapshot::capturetests and repair's internal tests pass.- Capture and restore smoke tests pass through the one-call path.
- The named repair and time items are no longer public outside
guest::snapshot.
- Needs: SL5.2, in nvx-rs slimming 4.1.2: the test adapter is gone #1119; SL7.4b, in nvx-rs slimming 2.4.2: activation holds no fence, and a capture is one guest call #1105.
- Estimate: 30 core lines, 4 counted files. Past 60 core lines, stop and ask before continuing.
- Objective: The one-call guest snapshot path has replaced the old capture-step API, while repair and restore-only time details remain unnecessarily public. The obsolete steps disappear and the remaining implementation details become private to
-
SL6.13c:
nvx-ingress startspawns its announcer itself.- Objective:
nvx-ingress startis the last user of the announcer spawner, which depends on process modules scheduled for deletion. The program performs the same shared port search and detached launch itself, then the obsolete library spawner is removed and the program-only module is hidden. - Contents:
nvx-ingress startbinds the announcer's privileged source port with the sharedbind_privilegedsearch, and spawnsnvx-ingress inherit GATEWAYthroughstd::process::Commandand the private OS layer's helpers, with the launch thatAnnouncer::startgives it today: the socket as its standard input, a session of its own, and every signal's default disposition, none blocked. It exits once the program runs, and fails when the program does not start, as today. The sharedbind_privilegedstays for the program; no copy is added. ThenAnnouncer,PROGRAMandStartErrorgo, andguest::ingressholds only the program, so the module becomes hidden; itsmainwas already hidden by SL1.5. - Scope:
- Change
nvx-ingress startto bind the highest free privileged UDP source port from 1023 down to 512 through the existing sharedbind_privilegedsearch. - Spawn
nvx-ingress inherit GATEWAYwithstd::process::Commandand the private OS layer's helpers, using the bound socket as standard input. - Give the child a session of its own, reset every signal to its default disposition and leave none blocked, matching today's launch.
- Return success once the program runs and failure when it does not start; delete
Announcer,PROGRAM,StartErrorand their tests. - Keep the shared privileged-port search for the program, add no copy, and hide
guest::ingress, whose only public item is its already-hiddenmain.
- Change
- Not in this PR:
- Waiting for the announcer's first scan or announcement: today's start returns once the program runs.
- Adding retries beyond the existing descending search for ports already in use.
- Changing
inherit, announcement contents, gateway parsing or test mode. - Creating a general guest process wrapper or a private copy of the privileged-port search.
- Changing nvx-init's separate announcer ownership.
- Approach: Inline the existing start sequence in the program's
startpath: reusebind_privileged, configure one standard-library command with the private OS helpers, and wait only for exec success. Delete the old spawner and hide the program-only module rather than extracting another wrapper or copying the port search. - Done when:
nvx-ingress startbinds a privileged source port and startsnvx-ingress inheritwith that socket as standard input.- Tests show the child has its own session, default signal dispositions and no blocked signals.
startexits with 0 after a successful launch and with 1 when the program cannot start.Announcer,PROGRAMandStartErrorare absent, andguest::ingressis hidden with only its hiddenmainpublic.
- Needs: SL7.3, in nvx-rs slimming 2.4.2: activation holds no fence, and a capture is one guest call #1105; SL1.5, 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, 3 counted files. Past 160 core lines, stop and ask before continuing.
- Objective:
Tests. The strict reader, artifact, snapshot-key and prepared-launch tests pass. Tests whose only subject is a deleted capture step retire; capture, repair and smoke tests pass. The fake OpenVMM's cases and retained process, Windows junction and spawn-lock tests call no helper that later groups remove. nvx-ingress start binds a privileged source port, starts nvx-ingress inherit in its own session with the socket as standard input, and keeps its exit behavior; the tests of Announcer retire.
Done when: every PR above has merged, with dev green; retained code reaches no store or supervisor path; tests that stay call no old launch helper; the old capture surface is not public; and guest::ingress is gone.
Activity
nvx-rs: move retained tests off old launch helpers
nvx-rs: detach retained CLI store test spawns
esaurez commentedon Nov 10, 2026
Workstream source/progress checkpoint - 2026-11-10 UTC
Checked boxes below mean merged scope, not merely an implemented first iteration. Implementation branches are source checkpoints, not automatic qualification, Ready or merge approval. Some starting inputs are frozen/anonymous commits rather than standalone branches; their exact SHAs and known merged producer refs are recorded explicitly.
SL6.0a - First implementation committed; not merged.
esaurez/slim-4.2.1-sl6.0a-20261108; exact head6231b87645443fc514f4dfe9ea7b378928cbb474.esaurez/slim-2.3.2-sl2.12b-20261107; exact commit1a6f6ffef2839359307f23fdf015b4b98b9b26ff.SL6.0b - First implementation committed; not merged.
esaurez/slim-4.2.1-sl6.0b-20261108; exact headb9d3c3ae0512ad97d67b2328d2ff50646dc2b9dd.489ce50efc93fe253d145557482c6c93e384391b.SL6.0c - merged via pull request 1294.
esaurez/slim-4.2.1-sl6.0c-20261105atbb0b9f75f83e3a96333ab92d405a771fa010d2aa.feature/nvx-refactorat6224fb7851bc9fc6bda2a4f803fc4f26abc48b96; merge commit3d243e59873998f6f6b28cfa403e81c5d224a51a.SL6.13c - First implementation committed; not merged.
esaurez/slim-4.2.1-sl6.13c-20261108; exact headfb5b5693b4d57055c1997afb1b24e2343f7e83ba.esaurez/slim-2.4.2-sl7.3-20261107; exact commitd4bcd5d5fb64bcc1639d95a715a246aa81293641.SL6.11c - no completed first-iteration handoff recorded. Inspect any preserved partial/prior work before implementing the issue's scope.
The original technical scope remains authoritative, supplemented only by any portable technical clarification in this issue. No machine-specific execution policy is part of this checkpoint.
ppenna commentedon Nov 12, 2026
Added slices: SL6.0d and SL6.0e. While preparing SL6.1 (#1121), we found code that stays and still uses what SL6.1 deletes. Each moves that code off
host::store,host::instanceorhost::supervisorfirst. They are kept-code pull requests under the size rules, with no behavior change.host::store's file helpers.write_private,sync_dirandcreate_newmove tohost::platform.finish_capture(host/snapshot/capture.rs),host/cli/store/files.rs,host/cli/snapshots.rsandhost/cli/snapshots/capture.rsuse them there, along with theregularaliases' replacements.store/files.rs, which re-exports the moved helpers until SL6.1 deletes the store, so a split would be harder to follow.generate_capabilitybecomes crate-private inhost::vm; integration tests draw their own random capability.StopOutcome, and creates its state directory throughplatform::create_store_dir, with the same messages.This group closes once SL6.0d, SL6.0e and SL6.11c merge.
host: write private files through the platform layer
host: keep vm and the CLI's sandbox lifecycle off the old store
host: write private files through the platform layer
host: keep vm and the CLI's sandbox lifecycle off the old store
host: write private files through the platform layer
host: keep vm and the CLI's sandbox lifecycle off the old store
ppenna commentedon Nov 12, 2026
Added slice: SL6.0f, "the CLI checks the command line it launches". This is a preparatory kept-code PR, found while preparing SL6.3 (#1122).
sandbox startandsandbox runstill check the user's command line throughSandboxLaunchandSandboxPlan(check_command_lineinhost/cli/sandbox/lifecycle/start.rs).runstill useshost::sandbox'sexport_command_line_fragment, andSANDBOX_COMMAND_LINE_MAX_SIZE, which is built fromhost::sandbox::OPENVMM_COMMAND_LINE_RESERVE. SL6.3 deletes all three.run's export fragment and size limit move offhost::sandbox. Behavior and messages are unchanged, with tests.This group now closes once SL6.0d (#1518), SL6.0e (#1519), SL6.0f and SL6.11c (#1504) merge.
8 remaining items
cli: check the command line that a sandbox launches
cli: check the command line that a sandbox launches
ppenna commentedon Nov 12, 2026
Completed. Every slice of this group has merged into
feature/nvx-refactor:1bfc832a13aandb73500866e0.nvx-ingress startspawns its announcer itself: guest: let nvx-ingress start spawn its announcer itself (SL6.13c) #1494.host::platform's file helpers: host: write private files through the platform layer (SL6.0d) #1518,a4f04f63f2a;vmand the CLI's sandbox lifecycle stop using the store's identities: host: keep vm and the CLI's sandbox lifecycle off the old store (SL6.0e) #1519,a732c108b8a;230a1b0877d.Passing CI that contains all of them: the push run on
feature/nvx-refactorat230a1b0877d, https://github.com/microsoft/nvx/actions/runs/43201313792, including the microVM jobs on KVM, MSHV and WHP.nvx-rs: move retained tests off old launch helpers
nvx-rs: detach retained CLI store test spawns
host: write private files through the platform layer
host: keep vm and the CLI's sandbox lifecycle off the old store
cli: check the command line that a sandbox launches
nvx-rs: move retained tests off old launch helpers
nvx-rs: detach retained CLI store test spawns
host: write private files through the platform layer
host: keep vm and the CLI's sandbox lifecycle off the old store
cli: check the command line that a sandbox launches