You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
spaced: organize guest backends by OS and prepare Windows bundles - #1736
Consolidate guest implementations into pplx-space-spaced-guest-server, with explicit platform::linux, platform::macos, and platform::windows backends. Linux and macOS share Unix mechanisms; neither is the implicit crate default. Remove the separate Windows crate, share common dependency declarations and retain target-specific feature additions. Existing root exports remain available to embedding callers. macOS retains development capabilities, not qualified guest-image support.
Build both native Windows agent payloads and prepare their bundle descriptors. The Windows spaced.exe CLI reports the workspace version or queries the installed service’s SCM state without start/stop privileges. The CLI calls SCM directly without linking the guest-server crate, preserves explicit state strings and reports contextual errors with their Windows source. Unix commands are preserved in a platform-specific module; Windows CI compiles and tests the CLI. --platform windows reads spaced-svc.exe and spaced.exe and records a distinct recovery contract, restricted to the existing x86-64 Windows backend. Linux remains the default and produces identical descriptor bytes. The schema, logical payload roles, protobufs and SQLite tables are unchanged.
This is CLI and packaging groundwork, not working Windows self-update. The existing host policy still refuses Windows bundles. The Windows runbook records the recovery, storage, workload and CH lifecycle qualification boundaries before admission can be enabled.
Validation
All five update-model tests pass. The real Python publisher feeds the Rust descriptor reader for Linux and Windows with distinct payloads. Windows ARM64 is rejected without creating a descriptor; removing the rejection guard makes that test fail.
All 39 native macOS guest-server tests pass. All-target/all-feature Clippy passes for the guest server, service and CLI on macOS, ARM64 Linux musl and Windows GNU.
Feature-isolation checks pass for 108 crates in 432 configurations. Formatting and architecture checks pass. cargo tree confirms the Windows CLI depends directly on windows-service and no longer reaches the guest-server backend.
Native Windows CI runs the CLI state/PID output test. Local cross-compilation does not establish live SCM behavior; service queries and Windows runtime validation remain with native CI and the Windows qualification in spaced: support Windows guest updates with SCM recovery #1737.
The module move previously passed the SIGINT/SIGTERM subprocess test in an ARM64 Linux container. Full CI is rerun after restacking.
Severity and risk
Severity does not apply: development groundwork. An incorrect target flag can describe the wrong intended recovery ABI; existing host policy continues to reject unsupported contracts. This does not install or start a Windows candidate. Module moves change tracing targets: guest-server module targets gain platform::unix, and pplx_space_spaced_guest_windows targets become pplx_space_spaced_guest_server::platform::windows. Adjust exact-target log filters accordingly. No protobuf, SQL or on-disk update-contract change is introduced.
Stack
Depends on the merged Linux guest-update implementation. #1737 adds Windows recovery, maintenance RPC implementation and runtime qualification.
AI assistance: Codex drafted implementation, validation, documentation and this description.
Automatic approval is disabled by the configured approval policy for this pull request. Review comments and requests for changes continue normally.
Commit: 3dcf3189864a.
No actionable comments were generated in the recent review.
Walkthrough
The guest server now organizes its implementation by platform, and the guest service and CLI use platform-specific entry points. Windows adds a CLI command that queries Service Control Manager status. The bundle publisher and its tests support Windows descriptors alongside Linux descriptors. The workspace removes the separate Windows guest crate.
This change reorganizes the guest server into per-OS backends and adds Windows CLI and bundle-descriptor groundwork. The relocated code is unchanged apart from paths and imports, and existing Linux update gates still refuse Windows bundles. No concrete merge-blocking problem was found. Native Windows runtime behavior remains covered only by CI.
Security architecture risk: Low · up to 3dcf3
Windows bundles remain rejected by existing update checks, and the new Windows CLI requests only read-only service status. No introduced security concern was established in the examined paths. Bundle deployment provenance and Windows recovery qualification remain incomplete.
Retained concerns
No architecture-level concerns identified.
Security review details
Security Blast Radius
observed — The new Windows command operates against the local computer's fixed spaced service and requests only SCM CONNECT and service QUERY_STATUS access. It reports state and optional PID without requesting start/stop privileges or issuing guest workload RPCs; its output does not establish RPC readiness.
Trust Boundaries and Controls
observed — The existing host filesystem boundary requires root-owned parent directories without group/other write permission, rejects symlinked parents, opens leaves with O_NOFOLLOW, and checks regular-file ownership and permissions. RPC inputs do not choose artifact paths. These controls predate this PR; they do not establish the external release provenance of installed payloads.
Resilience and Maintainability Implications
observed — The unchanged guest staging path independently rejects the Windows contract, binds the inactive slot and digest, verifies replay identity, and flushes and verifies both payloads before recording Staged. Partial staging does not replace committed authority. The host pending/recovery path reloads promotion authority and cancels on withdrawal or mismatch before staging; slot verification repeats contract and payload checks.
Pre-merge checks: 6
Check name
Status
Explanation
Title check
The title starts with the lowercase area and a colon, followed by a lowercase summary of the guest-backend organization and Windows bundle work. It has no trailing period, ticket ID, or internal link.
Description Follows The Pr Template
The description includes all four required items: Summary, Validation, Severity and risk, and an AI assistance line naming Codex and its contributions.
Bug Fixes Name A Regression Test
This PR is not an application bug fix. The diff moves the Unix server and CLI implementations and adds Windows CLI and bundle support. The signal-test selector change fixes the test after the module m…
Weakened Safeguards Are Justified
The moved Windows tests and lint checks remain covered by CI. The publisher test retains its assertions, and the nextest selector follows the moved test. The diff does not change review-guidance files…
Agent Tooling Runs No New Commands
The diff does not change agent plugin manifests, skills, guideline files, or files referenced by the plugin manifests.
Public-Safe Content
The diff, title, and description do not contain identified sensitive content covered by this check. The added documentation link points to public Microsoft documentation.
Full details: Bug Fixes Name A Regression Test
Explanation
This PR is not an application bug fix. The diff moves the Unix server and CLI implementations and adds Windows CLI and bundle support. The signal-test selector change fixes the test after the module move.
Full details: Weakened Safeguards Are Justified
Explanation
The moved Windows tests and lint checks remain covered by CI. The publisher test retains its assertions, and the nextest selector follows the moved test. The diff does not change review-guidance files.
Recent review info
Automatic approval policy
Commit: 3dcf3189864a.
Setting
Effective value
Source
Automatic approvals
Disabled
Override 3
Merge risk
Moderate
Global configuration
Security risk
Not set
Global configuration
Matching overrides (numbered as in the resolved configuration):
Any matching disabled override withholds approval, regardless of risk. Otherwise, the strictest explicitly set limit wins for each score. Limits omitted by all matching overrides inherit the global configuration.
Not set means no limit was configured after inheritance. Use @coderabbitai configuration to inspect the resolved settings and their sources.
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.
zibi-pplx
changed the title
spaced: add Windows diagnostic CLI and guest bundle packaging
spaced: organize guest backends by OS and prepare Windows bundles
Nov 9, 2026
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
## Summary
Implement Windows guest-update parity on top of #1736. This PR is in progress: its initial revision brings the existing slot store and journal transitions to Windows, using bounded selector files, verified executable payloads, exclusive writer locking, reparse-point rejection, and NTFS volume flushes for durable publication. Linux retains its symlink layout. No protobuf or SQL changes are introduced.
The remaining implementation in this PR is the independent SCM launcher and bounded trial recovery, guest maintenance RPCs and shared admission, process environment reconfiguration, idle and forced restart handling, image installation and host eligibility, and Cloud Hypervisor lifecycle qualification. Windows updates remain disabled until those pieces are implemented and qualified.
## Validation
Windows GNU and ARM64 Linux musl all-target Clippy pass for the slot-store crate; all 12 existing native macOS slot-store tests pass. Existing recovery tests now compile for Windows, and the native Windows CI job includes the slot-store crate. Native NTFS execution and CH guest-update scenarios have not yet been validated.
## Severity and risk
Severity does not apply: new platform support. The Windows implementation requires a privileged service on a local NTFS volume and preserves only two agent slots. Native crash durability and executable-reuse behavior need runtime qualification before enabling host admission. The supervisor must stay outside the replaceable agent payload and terminate every candidate descendant before rollback.
## Stack
Depends on #1736, which organizes the platform backends and adds Windows bundle packaging. This PR owns the remaining Windows guest-update implementation.
AI assistance: Codex drafted implementation, validation, and this description.
## Summary
Enable manager-owned guest update and restart on qualified Cloud Hypervisor Windows images. Windows uses the existing two-slot journal, maintenance RPCs, version policy and SQLite receipts. SCM runs the selected agent directly; bounded Task Scheduler jobs invoke recovery mode in the committed agent to handle failed startup, expired trials and rollback. No separate launcher executable is shipped.
Share the maintenance state machine across explicit platform backends. Windows supplies NTFS publication, boot identity, reversible process/file admission, environment reconfiguration and Job Object descendant termination. Host selection rejects a bundle for the wrong recovery contract. Cold CH activation captures its endpoint proof after guest readiness because driver initialization replaces the pre-boot vsock listener; mismatched proofs are still rejected during serving.
## Validation
- Native Windows: 10 slot-store and 18 guest-server tests pass, including admission lifetime and configuration ownership.
- A dedicated CH Windows canary passes idle commit, repeated apply without restart, busy deferral, forced parent/child termination, native process/file APIs after replacement, checkpoint, pause/resume, suspend/restore and cold-boot persistence. Its VM cleanup passes.
- A separate typed qualification passes A→B→A→B with explicit rollback and reuse of both slots without replacing the VM. Component checks cover crash restart, missing-confirmation rollback and a candidate with all threads suspended.
- 43 native Linux and 39 macOS guest-server tests, 17 shared model/slot tests, 31 smoke-framework tests, Windows GNU and ARM64 Linux musl Clippy, formatting and architecture checks pass. Feature-isolation checks pass for 108 crates in 432 configurations.
The canary bundles use test-only workspace versions; no production release or automatic rollout is enabled.
## Severity and risk
Severity does not apply: new platform support. Recovery requires a qualified local NTFS image with SYSTEM-owned service/tasks and the installed recovery ABI. Expiry reconciliation can add up to a minute; the manager keeps its existing activation budget. CH cold starts now wait for initial agent readiness before publishing the endpoint proof, including nonblocking Start requests.
Deploy capable hosts before publishing Windows updater templates. Legacy Windows images keep their existing service path and refuse maintenance RPCs. Drain unfinished Windows maintenance before rolling hosts back to a build that does not support the recovery contract. Existing Windows capability limits remain unchanged; this does not enable managed Windows tenant admission or Linux-only guest operations. There are no protobuf or SQL changes.
## Stack
Depends on #1736, which organizes guest platform backends and provides target-aware CLI/bundle packaging.
AI assistance: Codex drafted implementation, tests, documentation and this description.
## Summary
Enable manager-owned guest update and restart on qualified Cloud Hypervisor Windows images. Windows uses the existing two-slot journal, maintenance RPCs, version policy and SQLite receipts. SCM runs the selected agent directly; bounded Task Scheduler jobs invoke recovery mode in the committed agent to handle failed startup, expired trials and rollback. No separate launcher executable is shipped.
Share the maintenance state machine across explicit platform backends. Windows supplies NTFS publication, boot identity, reversible process/file admission, environment reconfiguration and Job Object descendant termination. Host selection rejects a bundle for the wrong recovery contract. Cold CH activation captures its endpoint proof after guest readiness because driver initialization replaces the pre-boot vsock listener; mismatched proofs are still rejected during serving.
## Validation
- Installer syntax and parameter validation pass in PowerShell; missing or false `-EnableOperations` is rejected before source resolution or mutation. The documented bundle command produces a Windows descriptor with synthetic inputs.
- Native Windows: 10 slot-store and 18 guest-server tests pass, including admission lifetime and configuration ownership.
- The typed `node.windows_guest_update` canary on a dedicated CH Windows worker passes idle commit, repeated apply without restart, busy deferral, forced parent/child termination, native process/file APIs after replacement, checkpoint, pause/resume, suspend/restore and cold-boot persistence. Its VM cleanup passes. Its cold-create/status step failed before the endpoint-proof fix with a stale vsock identity and passes after readiness precedes proof capture; its final cold restart exercises the same ordering again.
- A separate typed qualification passes A→B→A→B with explicit rollback and reuse of both slots without replacing the VM. Component checks cover crash restart, missing-confirmation rollback and a candidate with all threads suspended.
- 43 native Linux and 39 macOS guest-server tests, 17 shared model/slot tests, 31 smoke-framework tests, Windows GNU and ARM64 Linux musl Clippy, formatting and architecture checks pass. Feature-isolation checks pass for 108 crates in 432 configurations.
The canary bundles use test-only workspace versions; no production release or automatic rollout is enabled.
## Severity and risk
Severity does not apply: new platform support. Recovery requires a qualified local NTFS image with SYSTEM-owned service/tasks and the installed recovery ABI. Expiry reconciliation can add up to a minute; the manager keeps its existing activation budget. CH cold starts now wait for initial agent readiness before publishing the endpoint proof, including nonblocking Start requests.
Deploy capable hosts before publishing Windows updater templates. Legacy Windows images keep their existing service path and refuse maintenance RPCs. Drain unfinished Windows maintenance before rolling hosts back to a build that does not support the recovery contract. Existing Windows capability limits remain unchanged; this does not enable managed Windows tenant admission or Linux-only guest operations. There are no protobuf or SQL changes.
## Stack
Depends on #1736, which organizes guest platform backends and provides target-aware CLI/bundle packaging.
AI assistance: Codex drafted implementation, tests, documentation and this description.
crates/l50_app/spaced/guest/cli/Cargo.toml:30: the Windows spaced.exe links the whole guest-server backend for one SCM query, and enables a feature that does nothing on Windows. windows.rs only calls query_service_status(), a ServiceManager::open_service(..).query_status() wrapper. Depending on pplx-space-spaced-guest-server pulls the tokio runtime, tonic, the VirtIO transport and the full windows-sys feature set into the CLI payload. service-entrypoint only enables dep:pplx-space-service-host / dep:pplx-space-service-lifecycle, which are declared under cfg(unix), so on Windows it's a no-op. Calling windows-service directly in the CLI, or a small shared helper, would drop both.
crates/l50_app/spaced/guest/cli/src/main.rs:12, windows.rs:28: the Windows CLI's error and output contract is Debug formatting. main returns Result<(), RunError>, so a failure prints Error: Service(Winapi(Os { .. })) instead of going through pplx_space_common_cli::init_logging / unwrap_or_exit like unix.rs:55-59. state={:?} prints the external windows_service::ServiceState Debug name, so the key=value output depends on that crate's variant names. An explicit state-to-string map keeps the output stable.
crates/l40_api/spaced/guest/server/src/platform/linux.rs:1: platform::linux and platform::macos are both pub use super::unix::*.
The linux.rs doc says it holds "systemd, cgroups and identity workers", but those live in the private platform::unix behind cfg(target_os = "linux"), and tracing targets report platform::unix::*. Either move the Linux-only modules under platform/linux/, or drop the comment's claim so readers don't go looking there.
crates/l40_api/spaced/guest/server/Cargo.toml:52,106: about ten dependencies are declared in both the cfg(unix) and cfg(windows) tables (tokio, tonic, tracing, thiserror, uuid, prost-types, futures-util, tokio-stream, tokio-util, guest-protocol), and the specs already differ: futures-util is version = "0.3" on unix and workspace = true on windows. crates/l50_app/spaced/guest/svc/Cargo.toml likewise declares pplx-space-spaced-guest-server with service-entrypoint identically in both tables. Hoisting the shared entries into [dependencies] removes the hand-sync.
crates/l20_domain/spaced/update/src/tests.rs:280: the new --platform windows --arch aarch64 rejection in agent-bundle.py has no test. One extra subprocess case that asserts a non-zero exit, and that artifact.json doesn't exist, would cover it. The Linux byte identity is already guarded, since BundleDescriptor::parse rejects non-canonical bytes and the default path's keys and contract are unchanged.
Verified against the current head. I read the diff in an isolated checkout of the head and traced each claim to the cited lines (feature wiring, Cargo target tables, CLI entry points, publisher and test). I didn't build or run anything locally; CI, including Windows guest checks, is green.
Consolidate Linux, macOS and Windows guest backends under the guest-server crate while preserving embedding exports and platform-specific capabilities. Share common dependency declarations without broadening target-only features. Prepare x86-64 Windows bundle descriptors and keep default Linux descriptor bytes unchanged.
The Windows CLI queries SCM directly with read-only access, avoiding a guest-server dependency. Its state output has explicit stable strings and errors include operation context and the Windows source error. This is packaging and CLI groundwork; Windows maintenance support follows in the next stack commit. No SQL, protobuf or installed update-contract changes.
Validation: model/publisher tests pass, including Windows ARM64 refusal with no descriptor publication; removing that guard makes the regression fail. All-target/all-feature Clippy passes on macOS, ARM64 Linux musl and Windows GNU. All 39 native guest-server tests and feature-isolation checks for 108 crates in 432 configurations pass. Formatting and architecture checks pass. The dependency tree confirms the CLI no longer reaches the guest server. Native Windows CI runs the state-output test. Full CI is required again after restacking.
The Windows CLI calls windows-service directly with CONNECT/QUERY_STATUS access. Removed its guest-server dependency, the unused service-entrypoint feature and the now-unused server query wrappers. cargo tree confirms the reduced dependency graph; binary-size savings have not been measured.
The CLI owns explicit state strings, preserving the existing output, and prints contextual errors with the underlying Windows cause instead of returning Debug-formatted errors from main. It performs a synchronous SCM query and needs no logging runtime. The state/PID output test runs in native Windows CI.
The Linux module comment now describes its actual role as the Linux-facing exports of shared Unix implementation; no additional module move was needed.
Common dependencies are declared once. Target-specific Tokio, tokio-util and tokio-stream features remain target-specific, and futures-util uses the workspace declaration. The service binary declares its shared server dependency once.
Extended the existing publisher test with Windows ARM64 rejection and absence of artifact.json. It passes; removing the rejection guard makes it fail.
Model tests and macOS, ARM64 Linux musl and Windows GNU all-target/all-feature Clippy pass. The Windows maintenance PR is restacked on these changes; no SQL or protobuf changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consolidate guest implementations into
pplx-space-spaced-guest-server, with explicitplatform::linux,platform::macos, andplatform::windowsbackends. Linux and macOS share Unix mechanisms; neither is the implicit crate default. Remove the separate Windows crate, share common dependency declarations and retain target-specific feature additions. Existing root exports remain available to embedding callers. macOS retains development capabilities, not qualified guest-image support.Build both native Windows agent payloads and prepare their bundle descriptors. The Windows
spaced.exeCLI reports the workspace version or queries the installed service’s SCM state without start/stop privileges. The CLI calls SCM directly without linking the guest-server crate, preserves explicit state strings and reports contextual errors with their Windows source. Unix commands are preserved in a platform-specific module; Windows CI compiles and tests the CLI.--platform windowsreadsspaced-svc.exeandspaced.exeand records a distinct recovery contract, restricted to the existing x86-64 Windows backend. Linux remains the default and produces identical descriptor bytes. The schema, logical payload roles, protobufs and SQLite tables are unchanged.This is CLI and packaging groundwork, not working Windows self-update. The existing host policy still refuses Windows bundles. The Windows runbook records the recovery, storage, workload and CH lifecycle qualification boundaries before admission can be enabled.
Validation
cargo treeconfirms the Windows CLI depends directly on windows-service and no longer reaches the guest-server backend.The module move previously passed the SIGINT/SIGTERM subprocess test in an ARM64 Linux container. Full CI is rerun after restacking.
Severity and risk
Severity does not apply: development groundwork. An incorrect target flag can describe the wrong intended recovery ABI; existing host policy continues to reject unsupported contracts. This does not install or start a Windows candidate. Module moves change tracing targets: guest-server module targets gain
platform::unix, andpplx_space_spaced_guest_windowstargets becomepplx_space_spaced_guest_server::platform::windows. Adjust exact-target log filters accordingly. No protobuf, SQL or on-disk update-contract change is introduced.Stack
Depends on the merged Linux guest-update implementation. #1737 adds Windows recovery, maintenance RPC implementation and runtime qualification.
AI assistance: Codex drafted implementation, validation, documentation and this description.
Stack created with Sapling. Best reviewed with ReviewStack.