Skip to main content

clawft_kernel/workload_runtime/
host_seed.rs

1//! Governed Seed operations outside the cog lifecycle: firmware upgrade
2//! and `writes_gated` recovery, each gated as `workload.install` with kind
3//! `seed-firmware` and chained with the backup summary.
4
5use serde_json::json;
6
7use super::host::WorkloadHost;
8use super::seed::{SEED_ID, SeedApiRuntime};
9use super::seed_ops::{KIND_SEED_FIRMWARE, SeedBackup, UpgradeOutcome};
10use super::types::{RuntimeError, VerifiedWorkload};
11use crate::chain;
12
13impl WorkloadHost {
14    /// Governed, backed-up Seed firmware upgrade to the operator-pinned
15    /// `target_version`: gated as `workload.install` of
16    /// `seed-firmware@<target_version>` (so the decision names the version),
17    /// applied only if that is the version the Seed has pending, outcome
18    /// chained.
19    pub async fn upgrade_seed_firmware(
20        &self,
21        seed: &SeedApiRuntime,
22        backup: &SeedBackup,
23        target_version: &str,
24    ) -> Result<UpgradeOutcome, RuntimeError> {
25        let w = VerifiedWorkload::store_pin("cognitum", "seed-firmware", target_version, None)?;
26        self.check("workload.install", &w, KIND_SEED_FIRMWARE, false)?;
27        let r = seed.upgrade_firmware(backup, target_version).await;
28        let mut payload = json!({
29            "runtime": SEED_ID, "phase": "firmware-upgrade", "backup": backup.audit(),
30            "from_version": backup.firmware(), "target_version": target_version,
31        });
32        if let Ok(o) = &r {
33            payload["result"] = json!(format!("{o:?}"));
34        }
35        self.outcome(chain::EVENT_KIND_WORKLOAD_INSTALL, payload, &r);
36        r
37    }
38
39    /// Governed `writes_gated` recovery (truncate-confirm after a backup).
40    pub async fn recover_seed_writes(
41        &self,
42        seed: &SeedApiRuntime,
43        backup: &SeedBackup,
44    ) -> Result<(), RuntimeError> {
45        // Gated against the firmware the backup was taken at.
46        let w = VerifiedWorkload::store_pin("cognitum", "seed-firmware", backup.firmware(), None)?;
47        self.check("workload.install", &w, KIND_SEED_FIRMWARE, false)?;
48        let r = seed.recover_writes_gated(backup).await;
49        let payload = json!({
50            "runtime": SEED_ID, "phase": "writes-gated-recovery", "backup": backup.audit(),
51        });
52        self.outcome(chain::EVENT_KIND_WORKLOAD_INSTALL, payload, &r);
53        r
54    }
55}