Repository navigation
Description
Parent: #1088, in #1076. Needs: #1105, #1121, #1123. Unblocks: #1128, #1130, #1131, #1132. No PR of this group merges before the API-ready commit.
Goal. NVXC, the host's platform layer and the guest's space become private where they are. Every NVXC item that protocol re-exports (the frames and their constants, the refusal categories, the EXEC payloads with their codecs, flags and limits, and GuestFeatures) and host::session become crate-private and gated by cli, guest or testing, before v2. host::platform becomes crate-private after its outside users are gone. guest::{root, view, gpt}, the mapper and the apply family become crate-private and guest-gated; the snapshot and public docs stop using the space. MappingTable and the mapping values stay public.
Notes.
- Integration tests follow visibility. NVXC, platform and space tests that reached public paths become unit tests of their owners or drive a binary.
- The fake OpenVMM stays hidden.
testing::fake_openvmmhas only its hiddenmainpublic.
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.12: NVXC is private.
- Objective: NVXC is NVX's own control protocol: only the CLI, nvx-init, the managed agent and the fake OpenVMM speak it, but its frames, payloads and host session are public API of
nvx. Once the old stores and the test adapter are gone, this PR makes it crate-private where it is, before v2 changes it. - Contents: NVXC becomes crate-private where it is, gated by the features of its users (
cli,guestandtesting): every re-export of the protocol root fromapp,execandfeatures(the frames:AppFrame,encode_app,decode_appand theAPP_*constants; the refusal categoriesBUSY,CWD_FAILED,INVALID_REQUEST,LAUNCH_FAILED,MAPPING_FAILED,MAPPINGS_INCOMPLETEandUNSUPPORTED_OPERATION, andExitCategory; the EXEC payloadsWorkload,WorkloadEnvironment,ExecPayloadandGuestExecPayload, with their codecs, theirEXEC_*flags and their limitsMAX_ARGUMENTS,MAX_ARGUMENT_BYTES,MAX_CWD_BYTES,MAX_GUEST_CWD_BYTES,MAX_ENVIRONMENT,MAX_OUTPUT_BYTESandMAX_TIMEOUT_MS;GuestFeatures), andhost::session(ControlSessionwithsend_requestandread_response,ExecEvent, and what remains ofSessionErrorandconnect), which becomes a private module.protocol::maps, with its own limits, NVXS and the outer records stay public, andprotocol's module docs stop presenting NVXC as its public content. The integration tests that use NVXC's items (tests/managed_lifecycle.rs, if the case matrix kept it, and the fake OpenVMM's tests that build EXEC payloads) become unit tests of their owners, or drive a binary. It comes before v2, so v2 is crate-private from its first line. - Scope:
- Every re-export of the protocol root from
appandfeaturesbecomespub(crate):AppFrame,encode_app,decode_app, everyAPP_*constant, the refusal categories (BUSY,CWD_FAILED,INVALID_REQUEST,LAUNCH_FAILED,MAPPING_FAILED,MAPPINGS_INCOMPLETE,UNSUPPORTED_OPERATION),ExitCategoryandGuestFeatures. - So does every re-export from
exec: the EXEC payloads and their codecs, theEXEC_*flags, and the limitsMAX_ARGUMENTS,MAX_ARGUMENT_BYTES,MAX_CWD_BYTES,MAX_GUEST_CWD_BYTES,MAX_ENVIRONMENT,MAX_OUTPUT_BYTESandMAX_TIMEOUT_MS; the mapping table's limits stay public. host::sessionbecomes a private module:ControlSessionwithsend_requestandread_response,ExecEvent, and what remains ofSessionErrorandconnect.- Each item is gated by the features of the code that uses it (
cli,guestortesting), so that no feature set builds unused code. - The integration tests that use NVXC's items become unit tests of their owners, or drive a binary, asserting the same behavior.
- The API snapshot drops the NVXC items, and
protocol's module docs stop presenting frames, EXEC payloads and guest features as its public content.
- Every re-export of the protocol root from
- Not in this PR:
- Changing NVXC's frames, payloads, wire values or session behavior: the next protocol version comes in its own PRs.
- Making the mapping table's codec, NVXS, the outer records, the root, view, export and share codecs, or
MAPS_TOKENprivate: every init reads them. - Moving NVXC into another module or file: it stays where it is.
- Deleting v1 or FEATURES: a later PR deletes them.
- Approach: Narrow the visibility of the re-exports and of
host::session, then follow the compiler: gate what a feature set leaves unused, and move each integration test that reaches NVXC's internals into its owner'stestsmodule. Regenerate the API snapshot, and check that its diff removes only NVXC items. - Done when:
- NVXC's frame, payload and session tests pass unchanged where they now live.
- Every feature set that CI builds passes without warnings.
- The API snapshot lists no item from
protocol::{app, exec, features}, constants included, and no host session item; NVXS, the outer records and the mapping table stay listed.
- Needs: SL6.1, in nvx-rs slimming 4.2.2: the old clone path, template store and sandbox store are gone #1121.
- Estimate: 0 core lines (visibility), no counted files.
- Objective: NVXC is NVX's own control protocol: only the CLI, nvx-init, the managed agent and the fake OpenVMM speak it, but its frames, payloads and host session are public API of
-
SL6.14: The host's platform layer is private.
- Objective:
host::platformis the host's OS layer, which the library and the CLI use, but it is a public module ofnvx. Its public parts moved tohost::vm,host::transportandhost::runtimewith the new interface, and its last outside users are gone, so this PR makes it crate-private where it is. - Contents:
host::platformbecomes a crate-private module where it is:SUPPORTED,create_private_dir,file_identity,process_start_timeand any alias that phase 2 left forTransportorprobe_hypervisorbecomepub(crate). Its outside users are gone: the test adapter (SL5.2), the stores' tests (SL6.1) and the NVXC tests (SL6.12); an integration test that still uses it becomes a unit test of its owner.host::vm::create_private_dir,host::transportandhost::runtimekeep the public forms. - Scope:
host::platformbecomes a private module, and its items (SUPPORTED,create_private_dir,file_identity,process_start_time, and any alias that remains ofTransportorprobe_hypervisor) becomepub(crate).- Code that used the old public paths uses the crate paths.
- An integration test that still uses the platform layer becomes a unit test of its owner, asserting the same thing.
- The API snapshot drops
host::platform.
- Not in this PR:
- Changing the platform layer's behavior, or moving or splitting its files.
- Changing the public forms in
host::vm,host::transportorhost::runtime. - Making other host modules private: their own PRs do that.
- Approach: Make the module private, change its
pubitems topub(crate)as theunreachable_publint asks, and follow the compiler. Regenerate the API snapshot, and check that its diff removes onlyhost::platform's items. - Done when:
- The platform layer's tests pass unchanged on Linux and Windows.
- The API snapshot has no
host::platformitem on either platform. - Every feature set that CI builds passes without warnings.
- Needs: SL6.12, above.
- Estimate: 0 core lines (visibility), no counted files.
- Objective:
-
SL6.13b: The guest's space is private.
- Objective: The guest's root assembly, view, mapper, GPT helper and activation application are nvx-init's internal reference implementation, not shared library APIs. This PR makes that space private where it is, while leaving the mapping account and values public and removing space use from snapshot and activation documentation.
- Contents:
guest::{root, view, gpt}, the mapper (guest::mappings::mapperwith its kernel seam) and the activation'sapplyfamily (apply,Applied,RootTemplate,ApplyError,AppliedTeardownError,NetworkError) become crate-private andguest-gated where they are; nvx-init and the managed agent use them there. The docs and examples ofsnapshotandactivationstop using the space and say it is nvx-init's internal reference code.Pathsandwindow_directoriesstay where they are; the snapshot can use crate-private items.guest::mappings' values andMappingTablestay public. The API snapshot drops the space. - Scope:
guest::{root, view, gpt}become crate-private andguest-gated where they are.guest::mappings::mapper, including its kernel seam, becomes crate-private;guest::mappings' values andMappingTablestay public.- The activation apply family (
apply,Applied,RootTemplate,ApplyError,AppliedTeardownError,NetworkError) becomes crate-private andguest-gated. - nvx-init and the managed agent continue to use the space at its existing paths.
- Snapshot and activation docs and examples stop using the space and describe it as nvx-init's internal reference code.
- Not in this PR:
- Changing root assembly, overlay, runtime mount, view, mapping, network or activation behavior.
- Moving or renaming the space modules,
Pathsorwindow_directories. - Making
MappingTableor mapping values private: other space implementations consume those public values. - Adding a public space trait, plugin interface or second reference implementation.
- Cleaning up privileged code or broadening supported roots, filesystems, devices or platforms.
- Approach: Narrow the existing space modules and apply family to crate visibility, retain their
guestgates, and update internal imports directly. Keep the mapper split from the public mapping account at its existing seam. Remove space use from snapshot and activation docs and examples, regenerate the API snapshot, and do not move shared path lookups. - Done when:
- Root assembly, view, mapper, GPT and activation-apply unit tests pass at their existing owners.
- nvx-init handles EROFS and GPT roots, uppers, views, exports, mappings and restore activation as before.
- Snapshot and activation docs and examples compile without using the private space.
- The API snapshot lists no space implementation and still lists
MappingTableand the mapping values.
- Needs: SL6.11b, in nvx-rs slimming 4.2.4: the exec engine, the process modules and the old layered init are gone #1123; SL7.4b, in nvx-rs slimming 2.4.2: activation holds no fence, and a capture is one guest call #1105.
- Estimate: 0 core lines (visibility), no counted files.
Tests. NVXC's codec and session tests pass in their owner modules; the fake OpenVMM's cases still drive its binary. Platform tests pass on Linux and Windows. The space's unit and privileged tests stay with it. Docs and examples of snapshot and activation compile without the space. Every feature set builds without warnings, and the API snapshot lists none of NVXC, host::platform or the space.
Done when: every PR above has merged, with dev green.
Activity
[-]nvx-rs slimming 4.3.4: the fake VMM, NVXC and the guest's space live in their crates[/-][+]nvx-rs slimming 4.3.4: NVXC, the host's platform layer and the guest's space are private[/+]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.12 - no completed first-iteration handoff recorded. Inspect any preserved partial/prior work before implementing the issue's scope.
SL6.13b - no completed first-iteration handoff recorded. Inspect any preserved partial/prior work before implementing the issue's scope.
SL6.14 - 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.
examples: connect to VMs through the public transport
tests: encode the VM lifecycle's PING and STOP frames in the test
host: make the control session private to the CLI
protocol: make NVXC private to the programs that speak it
examples: connect to VMs through the public transport
tests: encode the VM lifecycle's PING and STOP frames in the test
host: make the control session private to the CLI
protocol: make NVXC private to the programs that speak it
examples: take Transport from host::transport
tests: read the one-shot fake's start time as ProcessRef documents it
host: make the platform layer private to the crate
28 remaining items
tests: encode the VM lifecycle's PING and STOP frames in the test
host: make the control session private to the CLI
protocol: make NVXC private to the programs that speak it
tests: read the one-shot fake's start time as ProcessRef documents it
host: make the platform layer private to the crate
guest: delete the space items that only tests use
guest: make the guest's space private to the crate
examples: connect to VMs through the public transport
tests: encode the VM lifecycle's PING and STOP frames in the test
host: make the control session private to the CLI
protocol: make NVXC private to the programs that speak it
tests: read the one-shot fake's start time as ProcessRef documents it
host: make the platform layer private to the crate
guest: delete the space items that only tests use
guest: make the guest's space private to the crate