Repository navigation
protocol: make NVXC private to nvx (SL6.12) - #1525
Pedro Henrique Penna (ppenna) merged 4 commits into
Conversation
This pull request changes existing testsIt modifies or removes 342 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
... and 288 more, which the job's summary lists. End-to-end tests
Test doubles
Test policy
Relocated unchanged: 0; added: 21. Compared the merge base |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues were identified for the NVXC and host-session visibility changes.
No open issues 🎉
What changed in this PR
This PR implements SL6.12 of the library-slimming workstream: NVXC and its host session become crate-private before the protocol’s v2 changes. Public NVXS transport and mapping codecs remain available, with no wire-format or session-behavior changes.
Changes:
- Restricts NVXC items to crate visibility and gates them by their CLI, guest, or testing users.
- Moves managed-lifecycle coverage into session unit tests and adapts public examples and VM lifecycle tests to use transport directly.
- Updates API snapshots, documentation, test commands, and the acceptance matrix to reflect the private boundary.
| File | Description |
|---|---|
scripts/test-layout-allowlist.json |
Updates allowances for remaining session hooks. |
scripts/test_microvm_tests.py |
Checks the moved test’s Cargo command and diagnostics. |
scripts/nvx_tools/sandbox_lifecycle_tests.py |
Updates the lifecycle test path in documentation. |
scripts/nvx_tools/microvm_tests.py |
Runs the managed-lifecycle unit test with cli. |
nvx-rs/tests/vm_lifecycle.rs |
Encodes lifecycle frames locally through public transport. |
nvx-rs/src/testing/fake_openvmm/tests.rs |
Gates feature assertions by their dependencies. |
nvx-rs/src/testing/fake_openvmm.rs |
Removes a rustdoc link to a private type. |
nvx-rs/src/protocol/tests.rs |
Gates codec tests and houses test-only definitions. |
nvx-rs/src/protocol/mod.rs |
Makes NVXC exports private and feature-gated. |
nvx-rs/src/protocol/maps.rs |
Describes NVXC without linking private constants. |
nvx-rs/src/protocol/features.rs |
Privatizes and gates guest feature definitions. |
nvx-rs/src/protocol/exec.rs |
Privatizes and gates EXEC payloads and codecs. |
nvx-rs/src/protocol/app.rs |
Privatizes and gates application frames and payload helpers. |
nvx-rs/src/lib.rs |
Documents the public transport/private NVXC boundary. |
nvx-rs/src/host/transport/tests.rs |
Gates tests that compare transport with the private session. |
nvx-rs/src/host/session/tests/managed_lifecycle.rs |
Houses the moved lifecycle test with crate-local imports. |
nvx-rs/src/host/session/tests.rs |
Registers the moved test and gates feature-dependent cases. |
nvx-rs/src/host/session.rs |
Makes session APIs crate-private and marks retained hooks. |
nvx-rs/src/host/restore/tests.rs |
Gates live session tests behind cli. |
nvx-rs/src/host/mod.rs |
Makes the session module crate-private and CLI-only. |
nvx-rs/src/host/cli/session/tests.rs |
Adjusts private imports and feature-dependent test gates. |
nvx-rs/src/guest/sys/tests.rs |
Gates re-exports used by dispatch tests. |
nvx-rs/src/guest/sys/spawn/tests.rs |
Gates capability constants used by dispatch tests. |
nvx-rs/src/guest/managed_agent/tests.rs |
Gates the loopback harness and shared test lock. |
nvx-rs/src/guest/managed_agent/seam/tests.rs |
Gates helpers used by CLI-dependent guest tests. |
nvx-rs/src/guest/managed_agent/dispatch.rs |
Requires cli for tests using the host encoder. |
nvx-rs/README.md |
Updates module descriptions and lifecycle-test documentation. |
nvx-rs/public-api/windows.txt |
Removes NVXC and host-session API entries. |
nvx-rs/public-api/linux.txt |
Removes NVXC and host-session API entries. |
nvx-rs/examples/host-workflows.rs |
Uses public connections and classifies transport errors. |
nvx-rs/examples/external-launch.rs |
Connects to the console through public transport. |
doc/usage.md |
Documents the relocated lifecycle unit test. |
doc/project-structure.md |
Removes managed lifecycle from the integration-test listing. |
doc/contribute.md |
Updates the managed-lifecycle test location. |
doc/ci.md |
Documents the unit-test path and required feature. |
doc/adversarial-testing.md |
Updates lifecycle test naming and prebuild command. |
doc/acceptance-case-matrix.md |
Tracks the moved test and shifted doctest location. |
Review effort: Balanced
5bffcd7 to
ba716d4
Compare
38d4409 to
8c402ea
Compare
host-workflows' capture and restore asked their guest for a snapshot and activated a restore through ControlSession, the host's session of NVXC, NVX's own control protocol, which they reached at its public path, nvx::host::session, with session::connect. external-launch also connected to the boot console of its VM with session::connect. The examples say that a caller speaks its own protocol with its guest, and SL6.12 (#1127) makes NVXC and the host's session private to nvx: a caller of the library connects through the transport that nvx gives every caller. host-workflows' capture and restore now connect with transport::connect_verified, which checks that the VM's own process serves the endpoint, and attach with HostConnection::attach, the host's role of the NVXS session. The callbacks take that connection, on which the caller sends and receives its own protocol's messages, and fail with nvx::Error. failed() classifies a connection's failure as the restore expects it, as it did the session's: a VM that exited; a lost connection, whose broker closed or reset the session, whose stream ended inside a record, or whose transport broke; an expired deadline; an endpoint that another process serves; a malformed exchange; or I/O. external-launch connects to its boot console with transport::connect_verified and the VM process's reference, which session::connect built from the same process ID and start time and the host's boot. Evidence: cargo clippy --all-targets --all-features -- -D warnings compiles both examples on Windows. Part of #1127 (SL6.12). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tests/vm_lifecycle.rs drives a cold VM through the public API alone,
and asks its guest, nvx-init, whether it is ready and to end the VM in
the guest's protocol, NVXC, whose frames it built and read with
nvx::protocol::{encode_app, decode_app} and the APP_* kinds. SL6.12
(#1127) makes NVXC private to nvx, as NVX's own protocol, so a caller
of the public API that runs nvx-init speaks NVXC on its own, over the
HostConnection that vm::reattach returns, as this test's caller does.
The test now encodes the empty NVXC frames that it sends, PING and
STOP, and the acknowledgements that it expects, READY and STOPPED,
itself: the magic, the version, the kind, zero flags, the request's
ID, a zero status, and a zero length, as tests/vectors/nvxc-v1.txt
pins them. It compares each answer with the whole acknowledgement
frame, which checks the magic, version, flags, kind, request ID,
status and empty payload that decode_app and its assertion checked.
It stays a test of the public API, which the case matrix's vm-lifecycle
row names, so the scenario that runs it is unchanged.
Evidence: cargo clippy --test vm_lifecycle -- -D warnings passes on
Windows; the frame matches the NVXC PING frame of the DATA_PING record
in tests/vectors/nvxc-v1.txt.
Part of #1127 (SL6.12).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
nvx::host::session, the host's session of NVXC, NVX's own control protocol, was public API of nvx, though only NVX's programs use it: the CLI, with the sessions of nvx-rs sandbox and its snapshot capture, and the restore driver, which the cli feature builds. SL6.12 (#1127) makes it private where it is, before NVXC v2 changes it. The module becomes crate-private and cli-gated, and its items pub(crate). The CLI's own session sends PING, FEATURES, EXEC and STOP through send_request and read_response, so nothing in NVX calls the session's ping, features, start_exec, cancel_exec or stop any more. They keep cfg_attr(not(test), expect(dead_code)) hooks, which name SL4.4c, whose sandbox exec and run ping, exec, cancel and stop through the session, and, for features, SL4.4d, which deletes FEATURES; the allowlist's seams of session.rs go from 1 to 5. capture's hook and activate's cfg go, since the module is the CLI's alone, and APP_CAPTURE and encode_capture_payload, which only the session's capture sends, follow it from host to cli. tests/managed_lifecycle.rs, which drove the managed lifecycle of a real guest through nvx::host::session, moves with git mv to the session's tests, as host::session::tests::managed_lifecycle, unchanged but for its imports, which use crate paths, and its cfg, which its module declaration holds. The managed-lifecycle scenario runs it with `cargo test --features cli --lib -- --ignored --exact` and its path. The tests that reach the session from outside it follow its gate: two transport tests, which compare connect_verified with the session's legacy connect, with their exchange helper; the live restored-init tests of host::restore; and the managed agent's loopback test, whose host is the session. The public-API snapshots drop host::session's items, and only those. The README and the docs describe the session as private, and the managed-lifecycle test where it now lives. Evidence, on Windows with Rust 1.95.0: cargo clippy -D warnings passes for --all-targets --all-features, --lib, --lib --no-default-features, serde alone, --lib --bins with cli, and with testing alone, and for x86_64-unknown-linux-gnu --all-targets --all-features and x86_64-unknown-linux-musl with guest alone and --all-targets; cargo doc -D warnings, public_api.py and check_test_layout.py pass; cargo test --all-features --lib passes for host::session, host::transport, host::restore, host::cli::session, host::cli::snapshots and host::restore_driver (110 passed, 4 ignored), and cargo test --lib passes for host::transport and host::restore with the default features; python -m unittest test_microvm_tests -k managed_lifecycle passes. Part of #1127 (SL6.12). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
nvx::protocol re-exported NVXC, NVX's own control protocol, as public API of nvx: its application frames (AppFrame, encode_app, decode_app and the APP_* kinds), the refusal categories and ExitCategory, the EXEC payloads with their codecs, flags and limits, and GuestFeatures. Only NVX's programs speak NVXC: the CLI and its restore driver, nvx-init and the managed agent, and the fake OpenVMM. SL6.12 (#1127) makes it crate-private where it is, before NVXC v2 changes it. Every NVXC item becomes pub(crate) and is gated by the features of the code that uses it, so that no feature set builds an item that it does not use: cli for the host's encoders and checks, guest on Linux x86-64 for the guest's decoders and the managed agent, and testing for the fake OpenVMM's decoder. The exec and features modules compile with any of them. protocol re-exports each item under the gate of its users, and no longer re-exports what only the codec itself reads. The capture and activate messages, whose expect(dead_code) hooks covered the builds without their users, take the same gates, so app.rs holds no test hook any more and its allowlist entry goes. GuestFeatures's REQUIRED and contains, MAX_CWD_BYTES and MAX_TIMEOUT_MS, which no feature set uses, move into protocol's tests, which alone read them. protocol::exec is crate-visible, for the CLI session's tests that read the EXEC flags. The tests of NVXC are gated by the features of the code that they test, with their bodies unchanged, so that every build compiles them where their code is built, and every one of them runs in the all-features tests on Linux: protocol's NVXC tests take the gates of the codecs that they check; the managed agent's dispatch tests, which drive the agent with the host's EXEC encoder, and the test helpers that only they use, take cli; and tests of the host's session, the CLI's session and the fake OpenVMM that use a guest or testing constant take that feature. The managed lifecycle test spells the three refusal categories that it expects, since the cli feature alone, with which its scenario runs it, does not build the guest's constants. The public-API snapshots drop the 93 NVXC items of each platform, and only those: NVXS, the outer records and the mapping table's payloads and tokens stay. protocol's docs, the crate's, the README and the items that linked NVXC no longer present it as public API. Part of #1127 (SL6.12). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8c402ea to
0e927f7
Compare
f03c21c
into
feature/nvx-refactor
Part of #1127 (SL6.12, "NVXC is private"). Parent #1088, umbrella #1076.
It needs no other PR: no item that stays public exposes an NVXC type (
nvx::execandguest::{exec, spawn, process, cgroup, entry}use none), so neither #1506 (SL6.11a) nor SL6.11b has to come first.What and why
NVXC is NVX's own control protocol, and only NVX's programs speak it: the CLI with its restore driver, nvx-init and the managed agent, and the fake OpenVMM. Yet
nvx::protocolre-exported its frames, refusal categories, EXEC payloads, limits andGuestFeatures, andnvx::host::sessionits host session, as public API ofnvx. As SL6.12's Scope says, this PR makes them crate-private where they are, gated by the features of their users, before v2 changes NVXC. No frame, payload, wire value or session behavior changes, nothing moves to another module or file, and v1 and FEATURES stay.host::sessionis private to the CLI (host: make the control session private to the CLI). It becomes#[cfg(feature = "cli")] pub(crate) mod session, and its itemspub(crate):ControlSessionwithsend_requestandread_response,ExecEvent,SessionErrorandconnect. It is crate-visible rather than private tohostbecause the managed agent's loopback test drives it.APP_CAPTUREandencode_capture_payload, which only the session's capture sends, follow it fromhosttocli.NVXC is crate-private (
protocol: make NVXC private to the programs that speak it). Every item ofprotocol::{app, exec, features}becomespub(crate), and each item and re-export is gated by the features of the code that uses it, so that no feature set builds an item that it doesn't use. Below, guest isall(feature = "guest", target_os = "linux", target_arch = "x86_64"), where the managed agent builds.cli: the host's encoders,Workload,WorkloadEnvironmentandencode_exec_payload,encode_capture_payloadandencode_activate_payload.AppFrame,GuestExecPayloadwithdecode_guest_exec_payload,decode_capture_payloadanddecode_activate_payload.testing: the fake OpenVMM's decoder,ExecPayloadwithdecode_exec_payload.cliortesting:ExitCategory.testingor guest: the refusal categoriesBUSY,CWD_FAILED,INVALID_REQUEST,LAUNCH_FAILEDandMAPPINGS_INCOMPLETE.clior guest:APP_CAPTURE,APP_ACTIVATEand the re-export ofAPP_HEADER_LEN.encode_appanddecode_app, the otherAPP_*kinds,MAPPING_FAILED,UNSUPPORTED_OPERATION,MAX_OUTPUT_BYTES,GuestFeatures, and theexecandfeaturesmodules.protocolno longer re-exports what only the codec itself reads:APP_MAGIC,APP_VERSION, theEXEC_*flags and the other limits.protocol::execis crate-visible, for the CLI session's tests that read the EXEC flags. The capture and activate messages, whoseexpect(dead_code)hooks covered the builds without their users, take the same gates, soprotocol/app.rsholds no test hook any more.What no feature set uses moves into
protocol's tests, as the orchestrator decided for Pedro Henrique Penna (@ppenna):GuestFeatures::{REQUIRED, contains},MAX_CWD_BYTESandMAX_TIMEOUT_MS, with their values unchanged, since only those tests read them.The public callers that used NVXC speak for themselves.
examples: connect to VMs through the public transport:host-workflows' capture and restore connect withtransport::connect_verified, attach withHostConnection::attach, and hand that connection to their callbacks, on which a caller speaks its own protocol with its guest.failed()classifies annvx::Erroras it classified the session's errors.external-launchconnects to its boot console the same way.tests: encode the VM lifecycle's PING and STOP frames in the test:tests/vm_lifecycle.rsstays a public-API integration test, as the orchestrator decided. It encodes the empty PING and STOP frames that it sends and the READY and STOPPED acknowledgements that it expects, astests/vectors/nvxc-v1.txtpins them, and compares each answer with the whole frame. Its comment says why:nvxcarries whatever protocol a caller speaks with its guest over theHostConnection, and leaves the protocol to the caller.tests/managed_lifecycle.rsbecomes a unit test of its owner,host::session::tests::managed_lifecycleinnvx-rs/src/host/session/tests/managed_lifecycle.rs, moved withgit mv. Only its imports (crate::paths), its cfg (now its module declaration's) and three refusal categories, which it now spells because theclifeature alone doesn't build the guest's constants, change. Themanaged-lifecyclescenario runs it withcargo test --features cli --lib -- --ignored --nocapture --exact host::session::tests::managed_lifecycle::a_managed_guest_runs_request_scoped_workloads_until_it_stops.The public-API snapshots drop 129 items on each platform, and add none: 93 of NVXC and 36 of
host::session. NVXS, the outer records,protocol::mapswith its limits,MAPS_TOKENandMappingTablestay listed.Docs.
protocol's module docs, the crate's andhost's rustdoc andnvx-rs/README.md(thenvx::protocolrow and section; thenvx::host::platform,reportrow and section, which lose the session; the transport, loopback-test and managed-lifecycle-test text) stop presenting NVXC and the session as public API.doc/usage.md,doc/ci.md,doc/contribute.md,doc/adversarial-testing.mdanddoc/project-structure.mdname the managed lifecycle test where it now lives.fake_openvmm's andmaps' docs no longer link NVXC items.The case matrix stays true. The
managed-lifecyclescenario's row, kept, says where its test now lives and how the scenario runs it. The two rows that namenvx-rs/src/lib.rs - (line 61)as coverage name(line 62), where the crate docs' doc test now starts. No inventoried test is added or removed, so no count changes, and SL5.2'scheck_matrix.pypasses.Seams
Five methods of
ControlSessionkeep#[cfg_attr(not(test), expect(dead_code, reason = "..."))], as #1076's rules allow, since the CLI's own session sends PING, FEATURES, EXEC and STOP throughsend_requestandread_response:pingstart_execcancel_execstopfeaturesscripts/test-layout-allowlist.json:nvx-rs/src/host/session.rsgoes from 1 seam (capture's hook, which goes) to these 5, and the entry ofnvx-rs/src/protocol/app.rs(6) goes, since gates replace its hooks.Size
Measured: 0 core lines and 0 counted files, as the Estimate says. Every edit of production Rust (
protocol/{app,exec,features,mod,maps}.rs,host/{session,mod}.rs,guest/managed_agent/dispatch.rs,testing/fake_openvmm.rs,lib.rs) makes items crate-private, gates them by the features of their users, adds the imports andexpect(dead_code)hooks that this forces, or edits docs; a script that lists the added lines of these files outside comments and attributes finds onlypub(crate)items,uselines, re-export lists and rustfmt's rewrapping of two declarations. Moving the four items that only tests read intoprotocol/tests.rsis thetestgate's equivalent. The examples count as docs (as in #1488 and #1508),scripts/nvx_tools/microvm_tests.pyandsandbox_lifecycle_tests.pydrive the microVM scenarios, whichcheck_test_changes.pyclassifies as end-to-end tests, andscripts/test-layout-allowlist.jsonis test policy.Judgment calls, approved by the orchestrator for Pedro Henrique Penna (@ppenna)
cfg(any(test, ...))hooks on about 75 production items. Every test still runs in Linux's all-featurescargo test. The guest decoders' tests leave the Windows build, and the dispatch tests leave the musl guest job, since that code is guest-only orcli-only.tests/vm_lifecycle.rsstays a public-API integration test that encodes its own PING and STOP frames.managed-lifecyclescenario runs the moved test withcargo test --features cli --lib -- --ignored --exact <path>.GuestFeatures::{REQUIRED, contains},MAX_CWD_BYTESandMAX_TIMEOUT_MSmove intoprotocol/tests.rs.Validation
The gates that
local_gates.py --filesselects, run from this branch's own action definitions, with Rust 1.95.0 andNVX_BUNDLE=skip:cargo fmt --all --checkcargo clippy --locked -- -D warningswith--all-targets --all-features,--lib,--lib --no-default-features, serde alone,--lib --bins --features cli,--lib --bins --no-default-features --features testingcargo clippy --all-targets -- -D warningsfor thex86_64-unknown-linux-gnutarget with all features, and forx86_64-unknown-linux-muslwith--no-default-features --features guest, on each of the four commits (git rebase -x)cargo test --locked --all-features/cargo test --locked/cargo build --locked --lib --no-default-features/cargo test --locked --lib --no-default-featuresRUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps --all-features;cargo +1.89 check --locked --all-targets --all-featurespython scripts/public_api.py(both snapshots)host::sessioncargo check --all-targets --all-features --target aarch64-apple-darwincheck_test_layout.py,check_markdown_links.py,ruff check,ruff format --check,compileall,pyright(Linux and Windows)python -m unittest scripts/test_*.py ...,test_adversarial.py,test_hosts.py,nvx.py test-microvm --help--helpworkscheck_matrix.pyagainst99d2022085fcargo clippy --locked --all-targets -- -D warningswith all features, the defaults, no features, serde,cli,testing,guest, the defaults withguest,cli,guest,testing,guestandcli,testingcargo test --locked:--all-features, the defaults,--lib --no-default-features,--lib --features cli,--lib --no-default-features --features testing,--lib --no-default-features --features guestcargo docwith-D warnings;cargo +1.89 check --all-targets --all-features; the bundled-artifacts testnvx.py check-guest-binaries --toolchain 1.95.0,build-guest-binaries,test-guest-binaries(musl)NVX_AUTO_DOWNLOAD=0 nvx.py test-microvm --backend kvm --scenario managed-lifecycle --scenario vm-lifecycle, with the guest kernel, Alpine initramfs, Ubuntu layer, scratch template and OpenVMM (14dc4116, SHA-256 checked against its provenance) of CI run 43153762018 at07c508c7, which no guest, protocol or OpenVMM change separates from this base; its guest binaries are the base's, since this PR changes only the visibility and gates of the guest's code, which the musl rows checka_cold_vm_is_reattached_from_saved_values_and_stoppedAfter #1520 merged, the branch was rebased with
git rebase --onto origin/feature/nvx-refactor 5bffcd7fontobaf560d1, without conflicts, andgit range-diffshows its four commits unchanged. Rerun on the rebased head, everything passed: on Windows,cargo fmt --check,cargo clippy --all-targets -- -D warningswith all features, the defaults, no features, serde,cli,testingandcli,testing, and for the Linux gnu (all features) and musl (guest) targets;cargo test --libwith all features, the defaults,cliand no features (1168 / 853 / 1139 / 246 passed);public_api.py,check_matrix.pyandcheck_test_layout.py; and the whole Linux/MSHV matrix above (all features: 2360 passed).check_test_changes.pyreports the same changes.A code-review subagent reviewed the whole diff and found no significant issues. Left to CI: the WHP microVM scenarios (this PR changes no Windows runtime path), the rest of the microVM matrix, benchmarks, and Specula's CI wiring test, which imports
fcntl, so runs only on Linux, and which this PR doesn't touch.Changes to existing tests
python scripts/check_test_changes.py --base origin/feature/nvx-refactorreports 342 changes to existing tests, 21 added test items, and none relocated unchanged; this PR carries thetests-modifiedlabel. Each change and its reason:Gates, bodies unchanged (option A). Each test that reaches a now-gated item takes the gate of the code that it tests (guest as above):
guest::managed_agent::dispatch::tests, with::runtimecli, onmod testsindispatch.rsguest::managed_agent::tests::PROCESS_TEST_LOCK;guest::managed_agent::seam::tests::{TestSystem::with_direct, start_as_privileged, start_with_failing_credentials};guest::sys::spawn::tests::{CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_SETGID, CAP_SETUID}and their re-export inguest::sys::testscliguest::managed_agent::tests::loopback, with::testscli(washost)host::session::testsclihost::session::tests::exec_sends_the_working_directory_and_reports_its_refusaltestingor guestCWD_FAILEDhost::session::tests::features_report_what_the_guest_provideshost::session::tests::managed_lifecycle(moved fromtests/managed_lifecycle.rs)cli, andany(target_os = "linux", windows)from the old file's inner cfghost::restore::tests::live_initclihost::transport::tests:verified_and_legacy_connections_wait_for_the_owned_endpoint_and_keep_nat,another_process_serving_the_endpoint_is_refused, the helperexchangecliconnect_verifiedwith the session'sconnecthost::cli::session::tests:features_of_a_guest_that_predates_them_are_none,protocol_violations_keep_the_messages_of_pythontestingor guesttesting::fake_openvmm::tests::the_current_guest_advertises_every_required_featurecliand guestGuestFeatures::REQUIREDand the guest agents' setsprotocol::testsThe imports of
guest::sys::tests,host::cli::session::tests,host::transport::testsandprotocol::testssplit along the same gates.protocol::tests, by gate:cli:exec_payload_distinguishes_explicit_environments,exec_payload_enforces_agent_limits, helpersprogram,strings;cli,testingor guest:decoders_reject_malformed_input,exec_limits_support_linux_paths,frames_match_their_vectors,guest_maps_decoder_accepts_non_utf8_linux_paths,host_maps_encoding_round_trips_through_the_guest_decoder,maps_payloads_are_split_to_fit_the_limit,maps_payloads_enforce_agent_limits,record_definitions_keep_their_wire_values, helperframe_kind(they read NVXC's header, kinds or limits);cliandtesting:exec_payload_carries_every_32_bit_timeout,exec_payload_carries_the_working_directory_natively,exec_requests_are_refused_where_the_guest_agent_refuses_them,exit_categories_match_the_guest_agent,feature_definitions_keep_their_wire_values,features_match_their_vectors,guest_features_use_distinct_bits,layered_sandboxes_need_per_execution_environments_and_mapping_tables, helperextended;activate_requests_refuse_truncated_or_malformed_payloads,capture_requests_refuse_unknown_or_mis_sized_flags,guest_exec_decoder_accepts_what_the_c_agent_accepted,guest_exec_decoder_refuses_what_the_c_agent_refused, helperraw_extended;testing:both_agent_modes_announce_the_host_mapping_table,decoders_never_panic,exec_decoders_refuse_strings_with_the_same_messages,guest_exec_decoder_accepts_linux_bytes_and_the_c_cwd_boundary,the_guest_decodes_every_exec_payload_that_the_host_decodes, helpernear_vectors, theproptest!block;cliand guest:activate_requests_round_trip_records_and_workload_identity,activate_workload_ids_match_guest_credential_bounds,capture_requests_round_trip_both_kill_flags,host_exec_encoding_round_trips_through_the_guest_decoder,the_host_requires_every_feature;cli, guest andtesting:exec_payloads_match_their_vectors,guest_features_report_what_a_guest_lacks;testingor guest:exec_extension_keeps_its_wire_values,host_mapping_table_keeps_its_wire_values.Rewritten:
tests/vm_lifecycle.rs'sacknowledgedhelper, its imports anda_cold_vm_is_reattached_from_saved_values_and_stoppedencode the frames themselves, as above; the vm-lifecycle scenario passes.Moved:
tests/managed_lifecycle.rstohost::session::tests::managed_lifecycle(its inner attributes and imports are reported removed), with its imports and three spelled refusal categories; the managed-lifecycle scenario passes.End-to-end:
scripts/nvx_tools/microvm_tests.py'sMANAGED_LIFECYCLE_TESTandmanaged_lifecycle_test_commandname the moved test and run it with--features cli --lib -- --ignored --nocapture --exact, andscripts/test_microvm_tests.py'stest_managed_lifecycle_runs_the_nvx_rs_test_and_checks_what_it_leaves,test_managed_lifecycle_requires_cargoandtest_managed_lifecycle_fails_with_the_test_and_with_the_reportexpect that command.Removed hooks: the test hooks of
protocol::app'sAPP_CAPTURE,APP_ACTIVATE,encode_capture_payload,decode_capture_payload,encode_activate_payloadanddecode_activate_payload, and ofControlSession::capture, give way to gates.Test policy: the allowlist loosens
nvx-rs/src/host/session.rsfrom 1 to 5 seams (Seams, above) and dropsnvx-rs/src/protocol/app.rs.Added: the 21 added items include the moved test's module declaration,
vm_lifecycle's frame constants and encoder,managed_lifecycle's refusal categories, the items that moved intoprotocol's tests, and the imports that split by gate.No test is retired.