Back to feed

sledtools/pika branch #132

pika-cloud-purity

Narrow pika-cloud to shared runtime contracts

Target branch: master

Merge Commit: 4debeab0b3e4443d65a1e1c0a2be3bace5f7d027

branch: merged tutorial: ready ci: failed
Open CI Details

Continuous Integration

CI: failed

Compact status on the review page, with full logs on the CI page.

Open CI Details

Latest run #167 failed

4 passed 1 failed

head 6984d74d1bfd01876afb72a07acd6e2e9027a8f9 · queued 2026-03-27 00:36:28 · 5 lane(s)

queued 12s · ran 17m 41s

check-notifications · success check-agent-contracts · success check-pikachat · success check-apple-host-sanity · failed check-fixture · success

Summary

This branch narrows the pika-cloud crate to shared runtime contracts by removing server-specific types (agent control protocol envelopes, runtime lifecycle phases, backup status records, and related constants) from pika-cloud and relocating the ones still needed by pika-server into a new private module managed_runtime_contract. Types that are genuinely shared across crates (AgentProvisionRequest, AgentStartupPhase, IncusProvisionParams, ManagedVmProvisionParams) remain in pika-cloud and are re-exported through the new module, while server-only types like ManagedRuntimeStatus, ManagedRuntimeBackupStatus, ManagedOpenClawLaunchAuth, and the various backup enums now live exclusively in pika-server. All corresponding tests migrate alongside the types they exercise.

Tutorial Steps

Strip server-specific types and constants from pika-cloud

Intent: Remove types, constants, and test code from the shared `pika-cloud` crate that are only consumed by `pika-server`. This includes the entire agent control protocol (command/status/result/error envelopes), runtime lifecycle phases, backup status records, VM backup schema constants, and the `AuthContext` struct. The crate retains only truly shared contracts: `ProviderKind`, `AgentStartupPhase`, `IncusProvisionParams`, `ManagedVmProvisionParams`, `AgentProvisionRequest`, `IncusGuestRunRequest`, and the `INCUS_GUEST_RUN_REQUEST_SCHEMA_VERSION` constant.

Affected files: crates/pika-cloud/src/lib.rs

Evidence
@@ -27,17 +27,7 @@ pub use spec::{
 };
 
 use serde::{Deserialize, Serialize};
-use serde_json::Value;
 
-pub const CONTROL_CMD_KIND: u16 = 24_910;
-pub const CONTROL_STATUS_KIND: u16 = 24_911;
-pub const CONTROL_RESULT_KIND: u16 = 24_912;
-pub const CONTROL_ERROR_KIND: u16 = 24_913;
-
-pub const CMD_SCHEMA_V1: &str = "agent.control.cmd.v1";
-pub const STATUS_SCHEMA_V1: &str = "agent.control.status.v1";
-pub const RESULT_SCHEMA_V1: &str = "agent.control.result.v1";
-pub const ERROR_SCHEMA_V1: &str = "agent.control.error.v1";
@@ -46,31 +36,6 @@ pub enum ProviderKind {
     Incus,
 }
 
-#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
-#[serde(rename_all = "snake_case")]
-pub enum ProtocolKind {
-    Acp,
-}
-
-#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
-#[serde(rename_all = "snake_case")]
-pub enum RuntimeLifecyclePhase {
@@ -83,12 +48,6 @@ pub enum AgentStartupPhase {
     Failed,
 }
 
-#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, Default)]
-pub struct AuthContext {
-    #[serde(skip_serializing_if = "Option::is_none")]
-    pub acting_as_pubkey: Option<String>,
-}
@@ -133,424 +91,17 @@ impl AgentProvisionRequest {
 }
 
 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
-pub struct ManagedRuntimeStatus {
 ... (removed ~400 lines of envelopes, descriptors, and test code)

The bulk of this change is a large deletion from crates/pika-cloud/src/lib.rs. Every type that existed solely to support the server's managed-runtime orchestration layer is removed:

  • Constants: CONTROL_CMD_KIND, CONTROL_STATUS_KIND, CONTROL_RESULT_KIND, CONTROL_ERROR_KIND, CMD_SCHEMA_V1, STATUS_SCHEMA_V1, RESULT_SCHEMA_V1, ERROR_SCHEMA_V1, VM_BACKUP_STATUS_SCHEMA_V1.
  • Enums: ProtocolKind, RuntimeLifecyclePhase, VmBackupFreshness, VmBackupUnitKind, VmRecoveryPointKind.
  • Structs: AuthContext, ManagedRuntimeStatus, VmBackupStatusRecord, ManagedRuntimeBackupStatus, ManagedOpenClawLaunchAuth, ProvisionCommand, ProcessWelcomeCommand, TeardownCommand, GetRuntimeCommand, ListRuntimesCommand, RuntimeDescriptor, and all four AgentControl*Envelope types.
  • Tests: Every round-trip test for the removed types is deleted (command envelope, status envelope, result envelope, error envelope, lifecycle phase variants, provision command minimal fields, backup records, etc.).

The IncusGuestRunRequest struct is kept but gains #[serde(deny_unknown_fields)] for stricter deserialization. The serde_json::Value import is dropped since no remaining type uses arbitrary JSON fields.

What stays in pika-cloud is the minimal surface shared by multiple crates: ProviderKind, AgentStartupPhase, IncusProvisionParams, ManagedVmProvisionParams, AgentProvisionRequest, IncusGuestRunRequest, and the Incus guest schema version constant.

Introduce the managed_runtime_contract module in pika-server

Intent: Create a new private module that owns the server-specific managed-runtime types previously housed in `pika-cloud`. This module re-exports the truly shared types from `pika-cloud` so that the rest of `pika-server` can import everything from one canonical location, and defines the server-only types locally with `pub(crate)` visibility.

Affected files: crates/pika-server/src/managed_runtime_contract.rs, crates/pika-server/src/main.rs

Evidence
@@ -0,0 +1,169 @@
+use serde::{Deserialize, Serialize};
+
+pub(crate) use pika_cloud::{
+    AgentProvisionRequest, AgentStartupPhase, IncusProvisionParams, ManagedVmProvisionParams,
+};
+
+#[cfg(test)]
+const VM_BACKUP_STATUS_SCHEMA_V1: &str = "vm.backup_status.v1";
@@ -5,6 +5,7 @@ mod browser_auth;
 mod customer;
 mod listener;
 mod managed_openclaw_guest;
+mod managed_runtime_contract;
 mod models;

A new file crates/pika-server/src/managed_runtime_contract.rs is created and registered in main.rs.

Re-exports from pika-cloud (line 3-5): The types that are genuinely cross-crate (AgentProvisionRequest, AgentStartupPhase, IncusProvisionParams, ManagedVmProvisionParams) are re-exported with pub(crate) so downstream server modules can import them from this single module.

Locally-defined types: The following types move here with pub(crate) visibility:

TypePurpose
ManagedRuntimeStatusDeserializes VM status responses from the Incus agent, including the guest_service_ready legacy alias
VmBackupFreshnessEnum: Healthy, Stale, Missing, Unavailable
VmBackupUnitKindEnum: DurableHome, PersistentStateVolume
VmRecoveryPointKindEnum: MetadataRecord, VolumeSnapshot
ManagedRuntimeBackupStatusFull backup status record for a VM
ManagedOpenClawLaunchAuthAuth token payload for OpenClaw gateway launches
VmBackupStatusRecord(test-only, #[cfg(test)]) Schema-versioned backup record

The VM_BACKUP_STATUS_SCHEMA_V1 constant is also scoped to #[cfg(test)] since it's only referenced in tests.

Migrated tests: All round-trip and deserialization tests for these types move into this module's #[cfg(test)] block, including managed_runtime_status_accepts_legacy_guest_service_ready_field, agent_provision_request_round_trips_incus_backend, managed_vm_params_preserve_incus_request_shape, agent_provision_request_rejects_removed_legacy_fields, vm_backup_status_record_round_trips, and managed_runtime_backup_status_round_trips.

Rewire pika-server imports to use the new contract module

Intent: Update all import sites in `pika-server` to pull managed-runtime types from `crate::managed_runtime_contract` instead of `pika_cloud`, and simplify the remaining `pika_cloud` import to only the spec/runtime types that are genuinely defined there.

Affected files: crates/pika-server/src/agent_api.rs, crates/pika-server/src/admin.rs, crates/pika-server/src/customer.rs

Evidence
@@ -26,6 +26,12 @@ use crate::managed_openclaw_guest::{
 };
+use crate::managed_runtime_contract::{
+    AgentProvisionRequest, AgentStartupPhase, IncusProvisionParams, ManagedOpenClawLaunchAuth,
+    ManagedRuntimeBackupStatus, ManagedRuntimeStatus,
+    ManagedVmProvisionParams as ManagedRuntimeProvisionParams, VmBackupFreshness, VmBackupUnitKind,
+    VmRecoveryPointKind,
+};
@@ -36,12 +42,9 @@ use crate::nostr_auth::{
 use pika_cloud::{
-    incus_mount_device_config, incus_runtime_config, AgentProvisionRequest, AgentStartupPhase,
-    IncusProvisionParams, IncusRuntimeConfig, IncusRuntimePlan, LifecycleState,
-    ManagedOpenClawLaunchAuth, ManagedRuntimeBackupStatus, ManagedRuntimeStatus,
-    ManagedVmProvisionParams as ManagedRuntimeProvisionParams, MountKind, MountMode,
-    RuntimeArtifacts, RuntimeIdentity, RuntimeMount, RuntimeResources, RuntimeSpec,
-    RuntimeStatusSnapshot, VmBackupFreshness, VmBackupUnitKind, VmRecoveryPointKind, STATUS_PATH,
+    incus_mount_device_config, incus_runtime_config, IncusRuntimeConfig, IncusRuntimePlan,
+    LifecycleState, MountKind, MountMode, RuntimeArtifacts, RuntimeIdentity, RuntimeMount,
+    RuntimeResources, RuntimeSpec, RuntimeStatusSnapshot, STATUS_PATH,
 };
@@ -16,6 +16,7 @@ use crate::agent_api::{
 };
 use crate::browser_auth::BrowserAuthConfig;
+use crate::managed_runtime_contract::AgentStartupPhase;
@@ -358,18 +359,16 @@ fn admin_app_state_label(
-fn admin_startup_phase_label(phase: Option<pika_cloud::AgentStartupPhase>) -> &'static str {
+fn admin_startup_phase_label(phase: Option<AgentStartupPhase>) -> &'static str {
@@ -11,11 +11,13 @@ use crate::agent_api::{
 };
 use crate::browser_auth::BrowserAuthConfig;
+use crate::managed_runtime_contract::{
+    AgentStartupPhase, IncusProvisionParams, ManagedVmProvisionParams,
+};
-use pika_cloud::{IncusProvisionParams, ManagedVmProvisionParams};

Three files in pika-server are updated to reflect the new import topology:

agent_api.rs

The primary consumer of managed-runtime types. A new use crate::managed_runtime_contract::{...} block (line 29-34) imports AgentProvisionRequest, AgentStartupPhase, IncusProvisionParams, ManagedOpenClawLaunchAuth, ManagedRuntimeBackupStatus, ManagedRuntimeStatus, ManagedVmProvisionParams (aliased as ManagedRuntimeProvisionParams), VmBackupFreshness, VmBackupUnitKind, and VmRecoveryPointKind. The pika_cloud import is correspondingly trimmed to only spec/runtime plan types (IncusRuntimeConfig, IncusRuntimePlan, LifecycleState, mount types, RuntimeSpec, STATUS_PATH, etc.).

admin.rs

Adds use crate::managed_runtime_contract::AgentStartupPhase (line 19). The admin_startup_phase_label function switches from fully-qualified pika_cloud::AgentStartupPhase::* paths to bare AgentStartupPhase::* variants, making the match arms more concise.

customer.rs

Adds use crate::managed_runtime_contract::{AgentStartupPhase, IncusProvisionParams, ManagedVmProvisionParams} (lines 14-16) and removes the corresponding use pika_cloud::{...} line. The startup_phase_label function and OpenClawLaunchability::from both switch to the local import. A stale use pika_cloud::AgentStartupPhase in the test module is also removed.

Diff