Skip to content

nvx-rs slimming 1.1.4: the time core that nvx and nvx-time share lives in nvx-sys #1094

Closed as not planned

Description

Parent: #1077, in #1076. Needs: #1093. Unblocks: #1095, #1131, #1132.

Goal. The time core no longer depends on nvx: it takes the generation ID and the seed as owned, zeroized bytes, and parsed command-line values, and owns its constants. It then moves into an internal, unstable nvx-sys module, which nvx and nvx-time share. nvx::guest::time keeps its public surface at the same paths (TimeAbi, ColdBoot, TimeError, Violation, CaptureRequest, CaptureOutcome, Restore, RestoreNetwork, RestoreFinish, MemoryRange, CpuSet and ScratchPolicy), with TimeAbi a thin wrapper over the core; #1120 later makes the capture and restore part private.

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.

  1. SL0.3e1: The time core's entropy and generation inputs don't depend on nvx.

    • Objective: The time core cannot move while its calls and decoded packets own nvx's private generation and seed types. Giving the core owned, zeroizing byte values removes those links, while nvx converts at its public facade and keeps the same caller-facing types.
    • Contents: The time ABI's calls and decoders take the generation ID and the seed as owned, zeroized byte values instead of GenerationId and reseed::Seed, whose copy_from and bytes are crate-private; nvx's facade converts. The decoded restore packet owns those bytes, and the optional network settings of restore packet 6 (RestoreNetwork).
    • Scope:
      • Time ABI calls and decoders take owned generation-ID and seed byte values instead of GenerationId and guest::reseed::Seed.
      • The owned byte values zeroize on drop, and formatting never reveals seed bytes.
      • Decoded restore data owns its generation and seed bytes rather than borrowing or copying through crate-private methods.
      • Restore packet version 6 continues to decode and own its optional RestoreNetwork settings.
      • nvx::guest::time converts between its public GenerationId and Seed values and the core's byte values.
    • Not in this PR:
      • Moving the time core to nvx-sys: SL0.3e3 performs the move after all links are cut.
      • Changing restore-packet versions, fields, validation or network semantics: versions 5 and 6 remain as they are.
      • Making GenerationId or Seed internals public merely to cross the crate boundary.
      • Changing TimeAbi, capture, restore or reseed behavior, or redesigning their public APIs.
    • Approach: Introduce the smallest owned fixed-size byte holders at the time-core boundary, with drop-time zeroization and redacted formatting. Convert in the existing nvx facade and decoder call sites; do not publish private accessors, introduce a serialization layer or change the packet representation.
    • Done when:
      • Tests show generation and seed byte holders are owned and zeroized on drop.
      • Debug and display formatting cannot contain the seed's bytes.
      • A decoded restore packet retains its generation, seed and optional version-6 network settings after the input buffer is gone.
      • The public nvx facade still accepts and returns its existing GenerationId and Seed types.
    • Needs: SL0.3b, in nvx-rs slimming 1.1.3: the guest's and the host's OS layers live in nvx-sys #1093.
    • Estimate: 150 core lines, 4 counted files. Past 300 core lines, stop and ask before continuing.
  2. SL0.3e2: The time core's command-line inputs and ABI constants don't depend on nvx.

    • Objective: The time core still depends on nvx for command-line tokenization and ABI constants. Passing parsed values and giving the core its own version and status constants removes those final links without changing command-line interpretation, packet compatibility or public constant values.
    • Contents: The core takes parsed command-line values instead of protocol::cmdline's tokenizer, and the restore packets' versions (5, and 6 with the network settings) and the TIME_* statuses as its own constants, at time ABI 2, which nvx re-exports where they are public. The command-line test model, and the time tests' use of the managed agent's isolator, move with the core or to their owners.
    • Scope:
      • The time core accepts the parsed values it needs instead of calling protocol::cmdline or owning its tokenizer.
      • The core owns restore-packet versions 5 and 6, time ABI version 2, and the existing TIME_* status constants.
      • nvx re-exports the core constants where they are public today, with equal values.
      • protocol::cmdline::tests::model moves with the core or stays with its tokenizer owner; no crate imports that cfg(test) module across the boundary.
      • Time tests using the managed agent's isolator receive local subprocess isolation or stay beside that owner.
    • Not in this PR:
      • Changing accepted kernel tokens, report-only selection, forbidden-clock checks or diagnostic text.
      • Adding a second command-line tokenizer or a generic parsed-command-line framework: the existing owner parses and passes values.
      • Changing time ABI, restore-packet or status numbers, including versions 5 and 6.
      • Moving the time implementation to nvx-sys: SL0.3e3 moves the dependency-closed core.
    • Approach: Keep command-line parsing in its existing owner and pass a small value set into the core. Relocate the literal ABI, packet and status constants to the core and alias or re-export them from nvx. Move only the focused test model and isolation helper needed by these tests; build no parser or configuration abstraction.
    • Done when:
      • TimeAbi::new still selects report-only mode only from nvx_time_abi=report-only.
      • Parsed command-line tests retain today's checks, including refusal of a forbidden clock.
      • nvx's public restore-packet versions and TIME_* statuses equal the core's constants.
      • The command-line model and isolated time tests run without importing private test code across crates.
    • Needs: SL0.3e1, above.
    • Estimate: 150 core lines, 4 counted files. Past 300 core lines, stop and ask before continuing.
  3. SL0.3e3: The time implementation that nvx and nvx-time share lives in nvx-sys.

    • Objective: With its nvx dependencies removed, the time implementation can become the shared implementation for nvx and nvx-time. Moving it into an internal nvx-sys module leaves nvx::guest::time as a thin facade at the same public paths.
    • Contents: git mv of the now dependency-closed time core: the ABI's calls, checks, decoders, state, system and the daemon's internals, with their test support, into an internal, unstable nvx-sys module. nvx-sys doesn't depend on nvx, directly or transitively, through normal or dev-dependencies. nvx::guest::time keeps its public surface at the same paths (TimeAbi, ColdBoot, TimeError, Violation, CaptureRequest, CaptureOutcome, Restore, RestoreNetwork, RestoreFinish, MemoryRange, CpuSet and ScratchPolicy), with TimeAbi a thin wrapper over the core. The core carries the host-clock correction and the network restore packet that dev added.
    • Scope:
      • git mv of the time ABI calls, checks, decoders, state, system code and daemon internals with their adjacent tests.rs files into nvx-sys, and move the allowlist seam entry for guest/time/system.rs to its new path.
      • nvx::guest::time keeps TimeAbi, ColdBoot, TimeError, Violation, CaptureRequest, CaptureOutcome, Restore, RestoreNetwork, RestoreFinish, MemoryRange, CpuSet and ScratchPolicy at their existing paths.
      • TimeAbi becomes a thin nvx wrapper; its facade tests stay in nvx and use system::tests::{FakeOps, sample_input, sample_tsc} only through nvx-sys's test-support feature.
      • The moved core includes the held host-clock correction and restore packet 6 network settings.
      • nvx-sys has no direct or transitive dependency on nvx, including dev-dependencies.
    • Not in this PR:
      • Changing the public time types, methods, packet formats, status values or command-line behavior: SL0.3e1 and SL0.3e2 only prepared the move.
      • Making the nvx-sys time module a stable public API; consumers use the nvx facade or the planned internal sharing.
      • Making capture and restore types private: nvx-rs slimming 4.2.1: the code that stays stops using what leaves #1120 performs that later API reduction.
      • Reorganizing, renaming or cleaning up the time implementation beyond imports, visibility, wrappers and test ownership forced by git mv.
    • Approach: Move the now dependency-closed files with git mv, keep their internal module structure and tests, and implement nvx's existing surface as direct wrappers and re-exports where appropriate. Use the existing test-support boundary; do not duplicate the core, expose it as a new supported API or redesign TimeAbi.
    • Done when:
      • Time ABI tests pass through the nvx facade at the same public paths and retain capture, restore, violation and report-only behavior.
      • Core tests cover host-clock correction, versions 5 and 6, and version-6 network settings after the move.
      • nvx-sys's normal and dev dependency graphs do not reach nvx.
      • TimeAbi contains only facade conversion and delegation needed to call the moved core.
    • Needs: SL0.3e2, above.
    • Estimate: 150 core lines, 4 counted files. Past 300 core lines, stop and ask before continuing.

Tests. The time ABI's tests pass through nvx's facade, at the same paths. The owned generation and seed bytes are zeroized on drop, the seed's bytes never appear in any formatting, and the decoded restore packet owns them. TimeAbi::new still selects report-only mode from the nvx_time_abi=report-only kernel token, and the core's parsed command-line input keeps today's checks, a forbidden clock included. nvx's public restore-packet version and TIME_* statuses equal the core's constants. The command-line test model moves with the core, and the time tests that used the managed agent's isolator get subprocess isolation of their own. nvx-sys doesn't depend on nvx, directly or transitively, through normal or dev-dependencies.

Done when: every PR above has merged, with dev green.

Activity

  1. esaurez commented on Nov 3, 2026

    @esaurez
    ContributorAuthor

    Closing as not planned: the plan in #1076 changed. nvx stays the only crate, with no Cargo workspace and no new crates. NVX's own programs, its control protocol and the OS layers stay in nvx, private to it, and CI checks the public API against committed snapshots (#1091). The time core stays in guest::time's private modules, where nvx-time already reaches it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions