Repository navigation
Description
Parent: #1079, in #1076. Needs: #1091. Unblocks: #1098, #1101, #1102.
Goal. Caller-owned values describe a VM's whole configuration: Runtime and LaunchOptions, for what every launch shares; VmConfig, for a VM's machine, root, view, console, network, export and boot; and CaptureConfig, for what a capture adds. VmConfig, CaptureConfig, the identities and the checked leaf values check their own data without reading the host. A runtime identity mismatch gets an error kind of its own.
Notes.
- One error. The new APIs return the crate's
Result, as most existing ones do: callers act on its kinds, and nvx-rs slimming 4.3.3: the error codes are private #1126 makes its codes and constructors private. activation::Viewis new here, besideWorkloadView, which nvx-rs slimming 2.3.1: activation record v2 carries only what the guest applies #1101 removes.
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.
-
SL2.2: What every launch shares is one value.
- Objective: The artifacts, identity and launch-wide options used by every VM are currently spread across storage, platform and launch code.
host::runtimegives callers one reusable value for those inputs while preserving the existing identity semantics, and a runtime identity mismatch gets an error kind of its own. - Contents:
host::runtime:git mvofRuntimeIdentity(new,check,differences),ArtifactIdentity(new,sha256,as_str) andIdentityPart(OpenVmm,Kernel,Initramfs,BootContract,ControlContract,ControlSession) out ofnvx-rs/src/host/store/identity.rs, and ofprobe_hypervisor; newRuntime { openvmm, kernel, initramfs, identity, hypervisor, cpu_profile, windows_breakaway, options };LaunchOptions { guest_shutdown, control_auth_timeout }, without the boot console; andGuestPowerAction: exit (the default, whichhost::vm::stoprelies on), halt or reset. The authentication timeout is how long OpenVMM waits for the host to authenticate.ErrorKind::RuntimeMismatch(new) is new, and today'sruntime-mismatchcode takes it instead ofOther;ErrorKind::Unsupported's docs name the malformed values that the identity checks already refuse with it. - Scope:
- Move
RuntimeIdentity,ArtifactIdentityandIdentityPartfromnvx-rs/src/host/store/identity.rsintohost::runtime, preservingnew,check,differences,sha256andas_str. - Move
probe_hypervisorintohost::runtimewithout changing the Linux, Windows or unsupported-host probes. - Add
Runtimewith the OpenVMM, kernel and initramfs paths, identity, hypervisor, optional CPU profile, Windows breakaway setting andLaunchOptions. - Add
LaunchOptions { guest_shutdown, control_auth_timeout }, where the timeout bounds how long OpenVMM waits for the host to authenticate, andGuestPowerAction::{Exit, Halt, Reset}, with exit as the default. - Add
ErrorKind::RuntimeMismatch, which today'sruntime-mismatcherrors take instead ofOther, and letErrorKind::Unsupported's docs name malformed values, which the identity checks already refuse with it.
- Move
- Not in this PR:
- Reading or hashing artifact files: identities remain caller-supplied labels, and
sha256only validates and formats a digest. - Putting the boot console in
LaunchOptions: console attachment belongs to eachVmConfigin SL2.3a. - Launching, stopping or reattaching a VM: later host APIs consume
Runtimeand apply the shutdown action. - New CPU-profile parsing or hypervisor detection behavior: this PR only stores the profile request and moves the existing probe.
- No new builders, generic validation framework, blanket serde derives or extensible option map: preserve the identities' existing serialization and use only the fixed runtime and launch-option fields.
- Changing an error code's spelling or meaning, a message or the CLI's exit status: only the kind of
runtime-mismatchchanges.
- Reading or hashing artifact files: identities remain caller-supplied labels, and
- Approach: Use
git mvfor the identity implementation and public hypervisor probe. Move the identity cases fromhost/store/tests.rsintohost/runtime/tests.rs; keep the platform implementations and their test support with their platform modules. Add the two small data types beside them, with a direct default forGuestPowerAction::Exit; do not introduce builders, artifact discovery or launch orchestration. Add the kind with its spelling and its code, and change only that code's kind. - Done when:
- The moved identity tests still cover invalid labels, normalized
sha256:identities, contract checks and every differing identity part. - A
Runtimefixture supplies each shared launch field, andGuestPowerAction::default()isExit. - The moved hypervisor probe keeps its current platform behavior.
- A
runtime-mismatcherror has the kindRuntimeMismatch, the code table's test records it, and the CLI still prints the same code.
- The moved identity tests still cover invalid labels, normalized
- Needs: SL0.4, in nvx-rs slimming 1.1.1: the public API is checked, and NVX's programs are hidden from it #1091.
- Estimate: 160 core lines, 5 counted files. Past 320 core lines, stop and ask before continuing.
- Objective: The artifacts, identity and launch-wide options used by every VM are currently spread across storage, platform and launch code.
-
SL2.3a: A VM's machine, root, view and console are one value, checked without touching the host.
- Objective: A caller needs one value for a VM's machine, root, view, export and console, instead of assembling launch-specific plans.
VmConfig::checkrejects malformed values without opening paths or inspecting the host. - Contents:
host::config:VmConfig { processors, memory_mib, root, view, filesystem, console }, to which SL2.3b addsnetworkand the optionalboot;RootConfig::{Blockless, Layered(LayeredRoot)};LayeredRoot { image, format, gpt_first_partition_bound, upper, overlay };UpperConfig::{Scratch { path, journal }, Ram { max_memory_percent }}, the RAM upper's cap, from 1 to 90 and 50 by default; andConsoleAttachment::{Listener, Disconnected}(the console device always exists).VmConfig::checkchecks the whole value without reading the host, and a refused value is anUnsupportederror that names its field.activation::View { hostname, machine_id }is new here, besideWorkloadView, which SL2.5b removes. - Scope:
- Add
host::config::VmConfigwith processors, memory, root, view, filesystem and console fields. - Add blockless and layered roots, including the image path and format, optional GPT first-partition bound, scratch or RAM upper, journal policy and the two existing overlay modes.
- Add
ConsoleAttachment::{Listener, Disconnected}; the console device exists in both cases. - Add
activation::View { hostname, machine_id }beside the existingWorkloadView. - Make
VmConfig::checkvalidate the complete value purely, including a RAM upper cap from 1 through 90 with 50 as its default; a refused value is anUnsupportederror that names its field.
- Add
- Not in this PR:
- Opening image or scratch paths, reading GPT data, probing filesystems or checking host support: configuration checks are host-independent.
- The
networkfield and the optionalbootfield: SL2.3b adds them with their types. - Rendering kernel tokens or OpenVMM arguments: SL2.4a1 through SL2.4c lower the checked value.
- Removing
WorkloadViewor changing the activation-record version: SL2.5b does both. - Adding a third console mode or omitting the console device: the repository needs only listener and disconnected attachments.
- No builders, generic validation framework, blanket serde derives or extensible option map: the fixed fields and direct checks are the complete configuration surface in this PR.
- Approach: Define plain public data types in
host::configand reuseactivation's existing journal, overlay and machine-ID vocabulary. Keepcheckas structural and numeric validation over the value itself; do not add builders, filesystem readers, host probes or separate configurations for cold boots and restores. - Done when:
VmConfig::checkaccepts representative valid blockless and layered configurations.- A RAM upper accepts caps 1 through 90, defaults to 50, and refuses values outside that range.
VmConfig::checkhas a case for each documented refusal of its fields, runs without host I/O, and accepts bothConsoleAttachmentvariants.
- Needs: SL2.2, above.
- Estimate: 290 core lines, 3 counted files. Past 580 core lines, stop and ask before continuing.
- Objective: A caller needs one value for a VM's machine, root, view, export and console, instead of assembling launch-specific plans.
-
SL2.3b: The network and the cold-only settings are part of that value.
- Objective: The same VM configuration must describe its network and distinguish cold-only command-line settings from restore settings. Callers get a checked IPv4 guest address type, while later launch code decides whether the optional address and
Bootfit a cold boot or restore. - Contents:
VmConfiggains itsnetworkfield and its optionalbootfield:NetworkConfig { guest_network, policy }, whose address is optional: NVX's default at a cold boot, the snapshot's at a restore; the checkednet::Ipv4Cidr(new) (new,parse,address,prefix_len, with serde);NicConfig { guest_network };DEFAULT_GUEST_NETWORK, moved fromhost::launch; andBoot { command_line }, required without a snapshot and refused with one. - Scope:
- Add
VmConfig'snetworkfield:NetworkConfig { guest_network, policy }, with an optional checked guest address, andNicConfig { guest_network }. - Add
net::Ipv4Cidrwithnew, parsing, address and prefix accessors, and serde support for the static guest-network form already accepted by the repository. - Move
DEFAULT_GUEST_NETWORKfromnvx-rs/src/host/launch.rsintohost::config. - Add
VmConfig's optionalbootfield,Boot { command_line }, as its cold-only portion; cold boots use the default address when none is supplied, while restores use the snapshot's address.
- Add
- Not in this PR:
- IPv6 guest addresses, DHCP or address discovery: the existing VM network accepts one static IPv4 address with a
/1through/30prefix. - Checking a path, policy file or host network state:
Ipv4Cidrand the configuration checks are value-only. - Enforcing whether
Bootis present for a cold boot or absent for a restore: the laterhost::vm::createsees the snapshot. - Reserving command-line tokens or rendering the kernel command line: SL2.4a2 and SL2.4b do that work.
- Changing network-policy lowering or OpenVMM arguments: this PR only places the existing policy value in the configuration.
- No builders, generic validation framework, blanket serde derives or extensible network option map: add only the fixed fields, direct checks and
Ipv4Cidrserialization this PR names.
- IPv6 guest addresses, DHCP or address discovery: the existing VM network accepts one static IPv4 address with a
- Approach: Extract the existing guest-network validation from
host::launchinto one smallIpv4Cidrvalue and reuse the current address rules. Store the policy and optional address directly inNetworkConfig; do not add an address allocator, network probe or second command-line parser. - Done when:
Ipv4Cidrconstruction, parsing and serde round-trip valid addresses and preserve the address and prefix accessors.Ipv4Cidrrefuses missing or invalid prefixes, IPv6, and the network, gateway and broadcast addresses.- Configuration checks accept both an omitted guest address and an explicit valid address.
VmConfig::checkaccepts representative valid blockless and layered configurations, both with and withoutboot.
- Needs: SL2.3a, above.
- Estimate: 220 core lines, 3 counted files. Past 440 core lines, stop and ask before continuing.
- Objective: The same VM configuration must describe its network and distinguish cold-only command-line settings from restore settings. Callers get a checked IPv4 guest address type, while later launch code decides whether the optional address and
-
SL2.3c: A capture is one value, which names its snapshots.
- Objective: Capture-specific settings are currently embedded in broader template concepts.
CaptureConfigisolates the inputs a capture adds, checks them without host I/O and derives a stable identity that callers can persist as the name of equivalent snapshots. - Contents:
Boot::capture;CaptureConfig { disks, processors, memory, invariants }, withCaptureConfig::check, whose refusals areUnsupportederrors;DiskCapture::Fresh { image, scratch }, on a#[non_exhaustive]enum;Capacity { boot, capacity }(processors 1, 2, 4 or 8; memory capacity aligned to 128 MiB); the caller's opaqueInvariants, withnew().with(..);BlockGeometry { length, logical_block_size, physical_block_size }, moved intohost::configwith the template manifest's validation; andCaptureIdentity(displayable, comparable and serializable) fromCaptureConfig::identity(&VmConfig, &Runtime). - Scope:
- Add
Boot::captureandCaptureConfig { disks, processors, memory, invariants }, with a pureCaptureConfig::checkwhose refusals areUnsupportederrors. - Add non-exhaustive
DiskCapture::Fresh { image, scratch }; this PR supports only the repository's fresh-capture device pair. - Add
Capacity { boot, capacity }: processor boot and capacity are each 1, 2, 4 or 8, and boot does not exceed capacity; memory boot is positive, capacity is at least boot, and capacity is aligned to 128 MiB. - Move
InvariantsandBlockGeometryintohost::config, preserving invariant name, value and count limits and the template manifest's geometry validation. - Add displayable, comparable and serializable
CaptureIdentity, derived byCaptureConfig::identity(&VmConfig, &Runtime)from the supported fresh capture's identifying inputs: runtime identity and contract versions, hypervisor and CPU-profile request, disk geometries, processor and memory boot/capacity, invariants, effective NIC address, console attachment, export presence and boot command line. An omitted cold-boot NIC address equals the explicit default. Exclude paths, per-launch options, restore view and network policy, duplicateVmConfigprocessor/memory fields, and layered-root format, image identity, GPT bound, upper and overlay details; a fresh capture is blockless. Later VM creation still owns the fresh-capture root/export refusals.
- Add
- Not in this PR:
- Additional disk-capture variants or storage generations: the enum is non-exhaustive so later work can add them without this PR designing them.
- Creating snapshot files, reading manifests or driving capture: later snapshot APIs consume the checked configuration.
- Interpreting or matching invariant names and values: they remain opaque caller-owned strings with only syntax and size checks.
- Reading or hashing image, scratch or runtime files for the identity: the identity uses the supplied configuration and runtime identity.
- Moving the NIC, console or export into
CaptureConfig: they remain properties of the capture VM'sVmConfig. - No builders, generic validation framework, blanket serde derives or extensible capture-option map: add only the fixed fields, direct checks and serialization this PR names.
- Approach: Adapt the existing
CaptureClass,Invariantsand geometry checks into smaller configuration-owned values. EncodeCaptureIdentitydeterministically from the checked values and existing identities; do not introduce snapshot storage, file inspection, pluggable identity providers or speculative disk modes. - Done when:
CaptureConfig::checkaccepts valid fresh captures and refuses unsupported processor boot or capacity, processor boot above capacity, zero memory boot, memory capacity below boot, and memory capacity not aligned to 128 MiB.host/template/key/tests.rs'sInvariants::withname, value and maximum-setting cases move tohost/config/tests.rs.host/template/manifest/tests.rs'sBlockGeometryvalidation cases move tohost/config/tests.rs, preserving all three fields.- Equal
VmConfig,RuntimeandCaptureConfiginputs produce equal identities, and each identifying field is covered by a differing-input test.
- Needs: SL2.3b, above.
- Estimate: 250 core lines, 4 counted files. Past 500 core lines, stop and ask before continuing.
- Objective: Capture-specific settings are currently embedded in broader template concepts.
Tests. The runtime and artifact identity tests move with those types, and cover invalid labels, the sha256: form, the contract checks and the differing parts; a runtime-mismatch error has the kind RuntimeMismatch. net::Ipv4Cidr's construction, parsing, accessors, invalid addresses and prefixes, and serde. Each refusal of VmConfig::check and CaptureConfig::check, an Unsupported error, such as a RAM upper's cap outside 1 to 90, a capture's processor count other than 1, 2, 4 or 8, or an unaligned memory capacity; Invariants::with keeps its limit and syntax cases. The value checks accept a valid configuration with or without boot: host::vm::create, which sees the snapshot, pairs them, in #1099 and #1103. CaptureConfig::identity gives equal identities for equal inputs, and covers the configuration, runtime and capture fields that identify a capture. BlockGeometry keeps today's fields and the template manifest's validation.
Done when: every PR above has merged, with dev green.
Activity
[-]nvx-rs slimming 2.1.1: per-domain errors, and one value for a VM's configuration[/-][+]nvx-rs slimming 2.1.1: one value for a VM's configuration[/+]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.
SL2.2 - merged via pull request 1268.
esaurez/slim-2.1.1-sl2.2-20261103at98bb4a43863d321cdc696ce498ed476d88322107.feature/nvx-refactorat6224fb7851bc9fc6bda2a4f803fc4f26abc48b96; merge commitef703702cb4037a828446a6ae095515f98cd9376.SL2.3a - merged via pull request 1269.
esaurez/slim-2.1.1-sl2.3a-20261103at3bd7e0d77a88d6fe401125f05dd945406527b85f.feature/nvx-refactorat4114e87dc907873b95b3d092fb356df5fbcaf230; merge commitb7f56abf7b25eff8739e446888b11120330a23eb.SL2.3b - merged via pull request 1270.
esaurez/slim-2.1.1-sl2.3b-20261103atd9cf939b1d52fe32b7d0b2542d846e9821673d35.feature/nvx-refactorat6d6ddf7f4b5622018a93f393f24f7a9130c5e985; merge commit8ed1f53e3452aaca953be8ade55cc3df5b5bb3e7.SL2.3c - merged via pull request 1275.
esaurez/slim-2.1.1-sl2.3c-20261103atb5c0eb98ac1bf71ee3a6a0d5429978297e21e32b.feature/nvx-refactorat8ed1f53e3452aaca953be8ade55cc3df5b5bb3e7; merge commit1790d3f4caca4b7b774004e0406c50f0dbecf992.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.