vios_app 0.1.1

Small JSON vaults: Argon2id + AES-GCM, with optional AAD binding.
Documentation
// src/vault/vault_structs.rs

//! Core data structures for Vault memory and metadata.
//!
//! These structs define the serialized contents of a `.vault` file, including:
//! - Emotional fingerprinting (tone, intent, REEM™ code)
//! - Cryptographic authorship (CIA™ hash, device fingerprint)
//! - Encrypted memory payload (user reflections or structured logs)

use chrono::Utc;
use serde::{Deserialize, Serialize};
use std::{error::Error, fs};

/// Describes the origin, emotional state, and cryptographic identity of the Vault.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct VaultMetadata {
    /// Name of the user or AI creating the Vault.
    #[serde(default)]
    pub creator_name: String,

    /// UTC timestamp of creation (ISO 8601).
    #[serde(default)]
    pub created_at: String,

    /// Device or system fingerprint for provenance tracking.
    #[serde(default)]
    pub system_fingerprint: String,

    /// Optional tone label (e.g., calm, anxious, confident).
    #[serde(default)]
    pub tone_classification: Option<String>,

    /// Optional intent label (e.g., reflect, confess, create).
    #[serde(default)]
    pub intent_classification: Option<String>,

    /// Optional REEM™ emotional code for memory encoding.
    #[serde(default)]
    pub reem_code: Option<String>,

    /// Optional CIA™ hash for authorship verification.
    #[serde(default)]
    pub cia_hash: Option<String>,
}

/// Represents a decrypted Vault, containing emotional metadata and raw memory content.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct VaultPayload {
    /// Authorship + emotional context for the Vault.
    pub metadata: VaultMetadata,

    /// User-generated content (plaintext memory, script, or reflection).
    pub content: String,

    /// Top-level author field for backward compatibility with older payloads.
    /// This is `#[serde(default)]` so legacy fixtures without it still deserialize.
    #[serde(default)]
    pub creator_name: String,
}

impl VaultPayload {
    /// Load a `.echo` file and generate a VaultPayload with auto-filled metadata.
    pub fn from_echo_file(path: &str) -> Result<Self, Box<dyn Error>> {
        let content = fs::read_to_string(path)?;
        let who = whoami::realname();
        let created = Utc::now().to_rfc3339();
        let fingerprint = whoami::fallible::hostname().unwrap_or_default();

        let metadata = VaultMetadata {
            creator_name: who.clone(),
            created_at: created,
            system_fingerprint: fingerprint,
            ..Default::default()
        };

        Ok(Self {
            metadata,
            content,
            // mirror into legacy top-level for compatibility
            creator_name: who,
        })
    }

    /// Generate a canonical Vault filename from the creation timestamp.
    pub fn generate_vault_filename(&self) -> String {
        let ts = if !self.metadata.created_at.is_empty() {
            self.metadata.created_at.clone()
        } else {
            Utc::now().to_rfc3339()
        };
        let safe_ts = ts.replace(':', "-");
        format!("vault_{safe_ts}.vault")
    }
}