package reconcile import "encoding/json" // Storage operations (slice 5 Phase B) flow through the SAME reversibility gate as guest // ops — no new gate, no new crypto. They are HOST/TARGET-scoped (no guest), so the op binds // on the STORAGE TARGET IDENTITY rather than a vmid. // // Scoping decision (documented): the scoped resource id is carried in the op's // target.guest_id (and the Intent.GuestID) as the storage target's NAME — the operator- // facing handle and the hub manifest key. VMID is 0 (host-scoped; no queue routing by // guest). So a signature for "wipe target A" (guest_id="A") cannot authorize "wipe target // B" (guest_id="B") — the gate's op-to-action binding rejects it (binding_mismatch), // exactly as it does for the wrong guest on a guest op. // // Benign storage ops (re-mount, slice 5) use IntentForStorageMount and pass the gate // unsigned. Destructive storage ops (detach/wipe/decommission, inert until slice 10) use // IntentForStorageDestructive and require a verified, role-scoped, target-bound operator // signature — else pending_signature. // IntentForStorageMount builds the benign re-mount intent for a known target (additive, no // data loss → benign by classification). targetID is the storage target name. func IntentForStorageMount(hostID, targetID string) Intent { return Intent{ Class: ClassStorageMount, HostID: hostID, GuestID: targetID, // storage target identity (host-scoped op) VMID: 0, Provenance: Provenance{}, // never hub-sourced Source: SourceDesiredDelta, } } // IntentForStorageDestructive builds a destructive storage intent (detach/wipe via // ClassStorageWipe, or ClassDecommission). It carries the target identity in GuestID and the // canonical params for op-to-action binding. Provenance is the zero value — a destructive // storage op is NOT made benign by hub-supplied evidence (only agent-internal provenance // could, and storage detach/wipe carries none here). func IntentForStorageDestructive(class OpClass, hostID, targetID string, params json.RawMessage, source SourceKind) Intent { return Intent{ Class: class, HostID: hostID, GuestID: targetID, VMID: 0, ParamsJSON: params, Provenance: Provenance{}, Source: source, } }