Files
vm-control/command-center/src/contracts/map_event_envelope_to_receipt.rs
Vault Sovereign c91e252e91 chore: pre-migration snapshot
Fleet monitoring/control plane: UI, node agent, ops wiring
2025-12-27 01:52:03 +00:00

73 lines
2.0 KiB
Rust

use serde_json::Value;
use time::format_description::well_known::Rfc3339;
use crate::state::EventEnvelope;
use super::receipt_v1::{
genesis_prev_blake3, ReceiptRequest, ReceiptResponse, ReceiptTarget, ReceiptV1,
};
/// Map an existing canonical EventEnvelope into a schema-valid Receipt V1.
pub fn map_event_envelope_to_receipt(envelope: &EventEnvelope) -> ReceiptV1 {
let mut canon = envelope.clone();
canon.canonicalize_in_place();
let created_at = canon
.ts
.format(&Rfc3339)
.expect("EventEnvelope ts should format to RFC3339");
// Payload is already canonicalized by EventEnvelope rules (sorted object keys, arrays preserved).
let payload: Value = canon.payload.clone();
let target = canon
.node_id
.as_ref()
.map(|id| ReceiptTarget {
id: id.to_string(),
name: None,
ip: None,
});
let mut receipt = ReceiptV1 {
receipt_version: "1".to_string(),
created_at,
source: "command-center".to_string(),
action: canon.kind.clone(),
reason: None,
target,
request: ReceiptRequest {
method: "POST".to_string(),
path: "/api/events".to_string(),
body: payload.clone(),
},
response: ReceiptResponse {
status: 200,
ok: true,
data: payload,
raw: String::new(),
},
prev_blake3: genesis_prev_blake3(),
hash_alg: String::new(),
blake3: String::new(),
sha256: String::new(),
plan_file: None,
plan_blake3: None,
plan_sha256: None,
lock_file: None,
lock_started_at: None,
force: None,
cwd: None,
user: None,
hostname: None,
argv: None,
sig_alg: None,
signer_pub: None,
signature: None,
signed_at: None,
};
receipt.compute_hashes().expect("hash computation must succeed");
receipt
}