Repository navigation
Description
Parent: #1089, in #1076. Needs: #1111, #1116, #1127. Unblocks: #1129. No PR of this group merges before the API-ready commit.
Goal. NVXC v2 carries every control path and streams execs, entirely in NVXC's private modules: Ready with the protocol version; PING; MAPS; capture and activate; EXEC; windowed STDIN with an explicit end; uncapped STDOUT and STDERR; EXIT; CANCEL, STOP and BUSY. nvx-init's guest loop, which the managed agent shares, and the fake OpenVMM serve it; every host path uses it; and the CLI streams through it, with Ctrl-C sending CANCEL.
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.
-
SL4.4a: NVXC v2's frames have a codec.
- Objective: NVXC v1 buffers execution input and caps collected output, so it cannot carry interactive or unbounded exec streams. This PR defines and tests v2's complete frame codec while leaving all current peers on v1.
- Contents: In NVXC's private modules (
protocol::appand friends), beside v1: Ready with the protocol version; EXEC unchanged (arguments, working directory, environment, timeout); STDIN with an explicit end, acknowledged as written, under a 64 KiB window per exec; STDOUT and STDERR with no total cap; EXIT; CANCEL, STOP and BUSY. PING, MAPS, the capture request and the activate exchange take v2's framing too, with their payloads and order unchanged. - Scope:
- The NVXC codec in its private modules, beside the existing v1 codec, and its round-trip tests.
- Ready with the protocol version, and unchanged EXEC arguments, working directory, environment and timeout.
- STDIN data, explicit stdin end and write acknowledgement, with a 64 KiB outstanding window per exec.
- STDOUT and STDERR chunks without a total cap, plus EXIT, CANCEL, STOP and BUSY.
- PING, MAPS, capture and activate frames with their existing payloads and ordering.
- Not in this PR:
- Serving v2 in nvx-init, nvx-managed-agent or the fake VMM: SL4.4b adds those handlers.
- Switching host sessions or the CLI to v2: SL4.4c performs that migration.
- Deleting v1, FEATURES or
GuestFeatures: SL4.4d removes them after every caller switches. - Changing EXEC's payload, capture payloads, activation payloads or restore ordering: v2 changes framing and streaming only.
- Protocol negotiation, generations, build identifiers, conformance suites or timing counters: this internal protocol needs none.
- Approach: Add a small v2 frame enum and encoder/decoder beside v1 in NVXC's private modules, reusing the existing EXEC, MAPS, capture and activation payload codecs. Encode the stdin window explicitly in frame semantics; do not build a shared streaming engine, negotiation layer or compatibility framework.
- Done when:
- Ready round-trips the current protocol version.
- Every v2 request, stream and response frame round-trips through the codec.
- Codec tests preserve EXEC, MAPS, capture and activate payload contents and order.
- Needs: SL6.12, in nvx-rs slimming 4.3.4: NVXC, the host's platform layer and the guest's space are private #1127.
- Estimate: 200 core lines, 3 counted files. Past 400 core lines, stop and ask before continuing.
-
SL4.4b: nvx-init and the fake VMM serve NVXC v2.
- Objective: The v2 codec has no serving peer until the guest loops and the fake OpenVMM implement its streaming rules. This PR makes both servers behave alike while retaining their v1 handlers for the host migration.
- Contents: The guest loop on nvx-init's exec core, which the managed agent shares: one exec at a time, and BUSY for a second EXEC; CANCEL and STOP during an exec; the guest stops reading a child's pipes while its send queue is full, and writes stdin to the child as the window allows. The fake OpenVMM serves the same v2 messages and streaming, so the CLI's integration tests can switch to v2 in SL4.4c. nvx-init also serves PING, MAPS through its
MappingTable, the capture request and the activate exchange over v2, in the same capture and restore order. Both still serve v1 until SL4.4d, and the fake's FEATURES handling andGuestFeaturesstate belong only to its v1 handler. - Scope:
- The shared nvx-init and managed-agent guest loop, plus the fake OpenVMM and its sibling
tests.rs; the PR explains the flagged fake changes. - One running exec, BUSY for a second EXEC, and CANCEL and STOP while an exec runs.
- Explicit stdin end and acknowledgements only after bytes enter the child's pipe, with at most 64 KiB outstanding.
- Backpressure that stops reading child stdout and stderr while the outgoing send queue is full.
- PING,
MappingTable-backed MAPS, capture and activation over v2 in their existing order; v1 remains served.
- The shared nvx-init and managed-agent guest loop, plus the fake OpenVMM and its sibling
- Not in this PR:
- Switching the host or the CLI's integration tests to require v2: SL4.4c does that.
- Deleting either server's v1 handler, FEATURES handling or
GuestFeaturesstate: SL4.4d deletes them. - More than one concurrent exec: the protocol serves one and returns BUSY for another.
- A total stdout or stderr limit, output dropping or reading through a full send queue: v2 applies backpressure instead.
- Changing capture or restore sequencing: only their framing changes.
- Approach: Adapt nvx-init's existing plain-process exec core to a small v2 dispatch loop, then mirror its observable protocol behavior in the fake OpenVMM. Reuse
MappingTablefor MAPS and existing capture and activation handlers; do not create a second exec engine or generalized multiplexer. - Done when:
- A second EXEC gets BUSY, while CANCEL and STOP work during the active exec.
- Stdin ends explicitly, acknowledgements follow pipe writes and no more than 64 KiB remains unacknowledged.
- The guest does not read child output while its send queue is full.
- The fake OpenVMM's tests cover explicit stdin end, write acknowledgements and the 64 KiB window, output beyond the old cap, CANCEL and STOP.
- PING, MAPS, capture and activation work over v2, while both servers still accept v1.
- Needs: SL4.4a, above; SL7.6b, in nvx-rs slimming 3.3.2: the managed agent's direct mode runs on nvx-init's exec core #1116.
- Estimate: 450 core lines, 5 counted files. Past 600 core lines, stop and ask before continuing.
-
SL4.4c: NVX's host speaks v2, and the CLI streams execs.
- Objective: With v2 available on both serving peers, NVX's host and CLI can stop using FEATURES and stream exec input and output. Every host control path, including capture and restore, moves together so the returned restore session is immediately usable.
- Contents: The host's NVXC session (
host::session) requires v2 and checks Ready's protocol version, and every host path uses it without FEATURES: PING, MAPS,ControlSession::capture, and the restore driver, which sends the activate message on each v2 session, then MAPS and Start, and returns the live v2 session. The session streams stdin, stdout and stderr (send_stdin,close_stdin), and sends STOP during an exec.sandbox execandsandbox runin the CLI use it; Ctrl-C sends CANCEL. A restore's own network policy needs no NVXC frame: OpenVMM installs it, and the activation record carries what the guest applies. - Scope:
- The host's NVXC session (
host::session) and restore driver, plus the CLI'ssandbox exec,sandbox runand fake-backed integration tests. - Ready's protocol version is required and checked; FEATURES is not sent on any host path.
- PING, MAPS, capture and restore use v2, including activation on each session, MAPS and Start after
Done, and the returned live v2 session. send_stdinandclose_stdin, with explicit stdin end and no more than 64 KiB unacknowledged per exec; streamed stdout and stderr without the old total cap; and STOP during an exec.sandbox execandsandbox runstream through the session, and Ctrl-C sends CANCEL.
- The host's NVXC session (
- Not in this PR:
- Deleting v1 codecs or server handlers, FEATURES constants or
GuestFeatures: SL4.4d performs that deletion. - Changing EXEC arguments, environment, working directory or timeout: the payload stays unchanged.
- Adding a network-policy NVXC frame: OpenVMM installs the restore policy and activation carries guest-applied state.
- Multiple simultaneous execs on one session: a second EXEC remains BUSY.
- Signal forwarding beyond Ctrl-C cancellation and STOP: v2 defines no general signal frame.
- Deleting v1 codecs or server handlers, FEATURES constants or
- Approach: Replace the host session's v1 frame calls with the v2 codec and expose only the two stdin operations needed by CLI callers. Reuse the existing restore driver and CLI execution paths; do not add FEATURES fallback, version negotiation, buffered whole-output compatibility or a separate streaming subsystem.
- Done when:
- The host accepts the current Ready protocol version and refuses another.
send_stdinandclose_stdinhonor write acknowledgements and never leave more than 64 KiB unacknowledged; STOP and output beyond the old 1 MiB cap work through the host session.sandbox execandsandbox runstream stdin, stdout and stderr, and Ctrl-C sends CANCEL.- Capture and restore complete over v2, including reconnection, MAPS and Start.
- An exec runs on the live v2 session returned by the restore driver.
- Needs: SL4.4b, above; SL3.9, in nvx-rs slimming 3.1.6: a managed
sandbox run, and one exec at a time #1111; SL3.4b, in nvx-rs slimming 3.1.6: a managedsandbox run, and one exec at a time #1111. - Estimate: 300 core lines, 5 counted files. Past 600 core lines, stop and ask before continuing.
Tests. Codec round trips of every v2 frame and the Ready version check. The guest loop covers BUSY, CANCEL, STOP, explicit stdin end, acknowledgements after writes, the 64 KiB window and send-queue backpressure. The fake-backed CLI tests cover v2 streaming, output past the old cap, cancellation and STOP. Host and CLI tests cover send_stdin, close_stdin, streamed output, sandbox exec, sandbox run and Ctrl-C. PING, MAPS, capture and restore work over v2, including reconnect and the live session. V1 remains until #1129.
Done when: every PR above has merged, with dev green.
Activity
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.
SL4.4a - no completed first-iteration handoff recorded. Inspect any preserved partial/prior work before implementing the issue's scope.
SL4.4b - no completed first-iteration handoff recorded. Inspect any preserved partial/prior work before implementing the issue's scope.
SL4.4c - 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.
protocol: add NVXC v2's frame codec beside v1
protocol: add NVXC v2's frame codec beside v1
protocol: add NVXC v2's frame codec beside v1
testing: serve NVXC v2 in the fake OpenVMM
guest: serve NVXC v2 in the loop of nvx-init and the managed agent
testing: serve NVXC v2 in the fake OpenVMM
guest: serve NVXC v2 in the loop of nvx-init and the managed agent
testing: serve NVXC v2 in the fake OpenVMM
host: speak NVXC v2, and stream execs in the CLI
scripts: expect sandbox-lifecycle's output past NVXC v1's cap
host: speak NVXC v2, and stream execs in the CLI
scripts: expect sandbox-lifecycle's output past NVXC v1's cap
6 remaining items
testing: serve NVXC v2 in the fake OpenVMM
guest: serve NVXC v2 in the loop of nvx-init and the managed agent
testing: serve NVXC v2 in the fake OpenVMM
guest: poll descriptors for writing as well as reading
guest: serve NVXC v2 in the loop of nvx-init and the managed agent
testing: serve NVXC v2 in the fake OpenVMM
host: speak NVXC v2, and stream execs in the CLI
scripts: expect sandbox-lifecycle's output past NVXC v1's cap
host: speak NVXC v2, and stream execs in the CLI
scripts: expect sandbox-lifecycle's output past NVXC v1's cap
host: speak NVXC v2, and stream execs in the CLI
scripts: expect sandbox-lifecycle's output past NVXC v1's cap
ppenna commentedon Nov 12, 2026
Completed on
feature/nvx-refactor. Every slice of this group has merged:sandbox execandsandbox runstream standard input and output, and Ctrl-C sends CANCEL.The push CI run at
5715bb6d709, which contains all of them, passed: https://github.com/microsoft/nvx/actions/runs/43291454483NVXC v1 and FEATURES leave in #1129 (SL4.4d, #1545).