openlatch-client 0.1.5

The open-source security layer for AI agents — client forwarder
//! Hand-written extensions for generated types.
//!
//! Generated types provide data structure + serde. This module adds:
//! - Constructor methods (VerdictResponse::allow, VerdictResponse::approve)
//! - Helper functions (new_event_id, current_timestamp, os_string, arch_string)

use super::{Verdict, VerdictResponse};

impl VerdictResponse {
    /// Constructs an `allow` verdict response for PreToolUse and UserPromptSubmit events.
    pub fn allow(event_id: String, latency_ms: f64) -> Self {
        Self {
            schema_version: "1.0".to_string(),
            verdict: Verdict::Allow,
            event_id,
            latency_ms,
            reason: None,
            severity: None,
            threat_category: None,
            rule_id: None,
            details_url: None,
        }
    }

    /// Constructs an `approve` verdict response for Stop events.
    pub fn approve(event_id: String, latency_ms: f64) -> Self {
        Self {
            schema_version: "1.0".to_string(),
            verdict: Verdict::Approve,
            event_id,
            latency_ms,
            reason: None,
            severity: None,
            threat_category: None,
            rule_id: None,
            details_url: None,
        }
    }
}

/// Generates a new UUIDv7 event ID.
///
/// UUIDv7 IDs encode a millisecond-precision Unix timestamp in the most significant bits,
/// making them monotonically ordered when compared lexicographically. This satisfies EVNT-01.
pub fn new_event_id() -> String {
    format!("evt_{}", uuid::Uuid::now_v7())
}

/// Returns the current UTC timestamp as an RFC 3339 string with Z suffix.
///
/// Example output: `"2026-04-07T12:00:00Z"`
///
/// # PERFORMANCE: Pure in-memory — no I/O, no allocation beyond the returned String.
pub fn current_timestamp() -> String {
    chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true)
}

/// Returns the current UTC time as a `chrono::DateTime<Utc>` — the exact
/// type the generated `EventEnvelope.time` field expects for the CloudEvents
/// `time` attribute. Equivalent to `chrono::Utc::now()` but colocated with
/// the other envelope helpers so call sites can grab everything from one
/// module.
pub fn current_time_utc() -> chrono::DateTime<chrono::Utc> {
    chrono::Utc::now()
}

/// Returns the current OS name as reported by the Rust standard library.
///
/// Examples: `"linux"`, `"macos"`, `"windows"`
pub fn os_string() -> &'static str {
    std::env::consts::OS
}

/// Returns the current CPU architecture as reported by the Rust standard library.
///
/// Examples: `"x86_64"`, `"aarch64"`
pub fn arch_string() -> &'static str {
    std::env::consts::ARCH
}