Initialize repository snapshot

This commit is contained in:
Vault Sovereign
2025-12-27 00:10:32 +00:00
commit 110d644e10
281 changed files with 40331 additions and 0 deletions

10
vaultmesh-core/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "vaultmesh-core"
version = "0.1.0"
edition = "2021"
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
blake3 = "1"

130
vaultmesh-core/src/did.rs Normal file
View File

@@ -0,0 +1,130 @@
use serde::{Deserialize, Serialize};
/// VaultMesh DID
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct Did(String);
impl Did {
pub fn new(did_type: DidType, identifier: &str) -> Self {
Did(format!("did:vm:{}:{}", did_type.as_str(), identifier))
}
pub fn parse(s: &str) -> Result<Self, DidParseError> {
if !s.starts_with("did:vm:") {
return Err(DidParseError::InvalidPrefix);
}
Ok(Did(s.to_string()))
}
pub fn did_type(&self) -> Option<DidType> {
let parts: Vec<&str> = self.0.split(':').collect();
if parts.len() >= 3 {
DidType::from_str(parts[2])
} else {
None
}
}
pub fn identifier(&self) -> Option<&str> {
let parts: Vec<&str> = self.0.split(':').collect();
if parts.len() >= 4 {
Some(parts[3])
} else {
None
}
}
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DidType {
Node,
Human,
Agent,
Service,
Mesh,
Portal,
Guardian,
Skill,
}
impl DidType {
pub fn as_str(&self) -> &'static str {
match self {
DidType::Node => "node",
DidType::Human => "human",
DidType::Agent => "agent",
DidType::Service => "service",
DidType::Mesh => "mesh",
DidType::Portal => "portal",
DidType::Guardian => "guardian",
DidType::Skill => "skill",
}
}
pub fn from_str(s: &str) -> Option<Self> {
match s {
"node" => Some(DidType::Node),
"human" => Some(DidType::Human),
"agent" => Some(DidType::Agent),
"service" => Some(DidType::Service),
"mesh" => Some(DidType::Mesh),
"portal" => Some(DidType::Portal),
"guardian" => Some(DidType::Guardian),
"skill" => Some(DidType::Skill),
_ => None,
}
}
}
#[derive(Debug)]
pub enum DidParseError {
InvalidPrefix,
MissingType,
MissingIdentifier,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_did_new() {
let did = Did::new(DidType::Human, "alice");
assert_eq!(did.as_str(), "did:vm:human:alice");
}
#[test]
fn test_did_parse_valid() {
let did = Did::parse("did:vm:guardian:local").unwrap();
assert_eq!(did.did_type(), Some(DidType::Guardian));
assert_eq!(did.identifier(), Some("local"));
}
#[test]
fn test_did_parse_invalid_prefix() {
let result = Did::parse("did:web:example.com");
assert!(matches!(result, Err(DidParseError::InvalidPrefix)));
}
#[test]
fn test_did_type_roundtrip() {
for did_type in [
DidType::Node, DidType::Human, DidType::Agent,
DidType::Service, DidType::Mesh, DidType::Portal,
DidType::Guardian, DidType::Skill,
] {
let s = did_type.as_str();
let parsed = DidType::from_str(s);
assert_eq!(parsed, Some(did_type));
}
}
#[test]
fn test_did_type_unknown() {
assert_eq!(DidType::from_str("unknown"), None);
}
}

147
vaultmesh-core/src/hash.rs Normal file
View File

@@ -0,0 +1,147 @@
use serde::{Deserialize, Serialize};
/// VaultMesh hash with algorithm prefix
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct VmHash(String);
impl VmHash {
/// Create hash from bytes using Blake3
pub fn blake3(data: &[u8]) -> Self {
let hash = blake3::hash(data);
VmHash(format!("blake3:{}", hash.to_hex()))
}
/// Create hash from JSON-serializable value
pub fn from_json<T: Serialize>(value: &T) -> Result<Self, serde_json::Error> {
let json = serde_json::to_vec(value)?;
Ok(Self::blake3(&json))
}
/// Create hash from file contents
pub fn from_file(path: &std::path::Path) -> std::io::Result<Self> {
let contents = std::fs::read(path)?;
Ok(Self::blake3(&contents))
}
/// Get the raw hex value without prefix
pub fn hex(&self) -> &str {
self.0.strip_prefix("blake3:").unwrap_or(&self.0)
}
/// Get full prefixed value
pub fn as_str(&self) -> &str {
&self.0
}
}
/// Compute Merkle root from list of hashes
pub fn merkle_root(hashes: &[VmHash]) -> VmHash {
if hashes.is_empty() {
return VmHash::blake3(b"empty");
}
if hashes.len() == 1 {
return hashes[0].clone();
}
let mut current_level: Vec<VmHash> = hashes.to_vec();
while current_level.len() > 1 {
let mut next_level = Vec::new();
for chunk in current_level.chunks(2) {
let combined = if chunk.len() == 2 {
format!("{}{}", chunk[0].hex(), chunk[1].hex())
} else {
format!("{}{}", chunk[0].hex(), chunk[0].hex())
};
next_level.push(VmHash::blake3(combined.as_bytes()));
}
current_level = next_level;
}
current_level.remove(0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vmhash_blake3_deterministic() {
let data = b"test data";
let h1 = VmHash::blake3(data);
let h2 = VmHash::blake3(data);
assert_eq!(h1, h2);
assert!(h1.as_str().starts_with("blake3:"));
}
#[test]
fn test_vmhash_different_inputs() {
let h1 = VmHash::blake3(b"hello");
let h2 = VmHash::blake3(b"world");
assert_ne!(h1, h2);
}
#[test]
fn test_vmhash_from_json() {
#[derive(Serialize)]
struct TestStruct { value: i32 }
let obj = TestStruct { value: 42 };
let hash = VmHash::from_json(&obj).unwrap();
assert!(hash.as_str().starts_with("blake3:"));
assert_eq!(hash.hex().len(), 64); // 256 bits = 64 hex chars
}
#[test]
fn test_vmhash_hex_extraction() {
let hash = VmHash::blake3(b"test");
let hex = hash.hex();
assert_eq!(hex.len(), 64);
assert!(!hex.contains("blake3:"));
}
#[test]
fn test_merkle_root_empty() {
let hashes: Vec<VmHash> = vec![];
let root = merkle_root(&hashes);
let expected = VmHash::blake3(b"empty");
assert_eq!(root, expected);
}
#[test]
fn test_merkle_root_single() {
let h = VmHash::blake3(b"single");
let root = merkle_root(&[h.clone()]);
assert_eq!(root, h);
}
#[test]
fn test_merkle_root_pair() {
let h1 = VmHash::blake3(b"left");
let h2 = VmHash::blake3(b"right");
let root = merkle_root(&[h1.clone(), h2.clone()]);
// Verify it's not just one of the inputs
assert_ne!(root, h1);
assert_ne!(root, h2);
// Verify determinism
let root2 = merkle_root(&[h1, h2]);
assert_eq!(root, root2);
}
#[test]
fn test_merkle_root_odd_count() {
let h1 = VmHash::blake3(b"one");
let h2 = VmHash::blake3(b"two");
let h3 = VmHash::blake3(b"three");
let root = merkle_root(&[h1.clone(), h2.clone(), h3.clone()]);
// Should be deterministic
let root2 = merkle_root(&[h1, h2, h3]);
assert_eq!(root, root2);
}
}

View File

@@ -0,0 +1,7 @@
pub mod receipt;
pub mod did;
pub mod hash;
pub use receipt::{Receipt, ReceiptHeader, ReceiptMeta, Scroll};
pub use did::{Did, DidType, DidParseError};
pub use hash::{VmHash, merkle_root};

View File

@@ -0,0 +1,79 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
/// Universal receipt header present in all receipts
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReceiptHeader {
pub receipt_type: String,
pub timestamp: DateTime<Utc>,
pub root_hash: String,
pub tags: Vec<String>,
}
/// Receipt metadata for tracking and querying
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReceiptMeta {
pub scroll: Scroll,
pub sequence: u64,
pub anchor_epoch: Option<u64>,
pub proof_path: Option<String>,
}
/// Scroll identifiers
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum Scroll {
Drills,
Compliance,
Guardian,
Treasury,
Mesh,
OffSec,
Identity,
Observability,
Automation,
PsiField,
}
impl Scroll {
pub fn jsonl_path(&self) -> &'static str {
match self {
Scroll::Drills => "receipts/drills/drill_runs.jsonl",
Scroll::Compliance => "receipts/compliance/oracle_answers.jsonl",
Scroll::Guardian => "receipts/guardian/anchor_events.jsonl",
Scroll::Treasury => "receipts/treasury/treasury_events.jsonl",
Scroll::Mesh => "receipts/mesh/mesh_events.jsonl",
Scroll::OffSec => "receipts/offsec/offsec_events.jsonl",
Scroll::Identity => "receipts/identity/identity_events.jsonl",
Scroll::Observability => "receipts/observability/observability_events.jsonl",
Scroll::Automation => "receipts/automation/automation_events.jsonl",
Scroll::PsiField => "receipts/psi/psi_events.jsonl",
}
}
pub fn root_file(&self) -> &'static str {
match self {
Scroll::Drills => "ROOT.drills.txt",
Scroll::Compliance => "ROOT.compliance.txt",
Scroll::Guardian => "ROOT.guardian.txt",
Scroll::Treasury => "ROOT.treasury.txt",
Scroll::Mesh => "ROOT.mesh.txt",
Scroll::OffSec => "ROOT.offsec.txt",
Scroll::Identity => "ROOT.identity.txt",
Scroll::Observability => "ROOT.observability.txt",
Scroll::Automation => "ROOT.automation.txt",
Scroll::PsiField => "ROOT.psi.txt",
}
}
}
/// Generic receipt wrapper
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Receipt<T> {
#[serde(flatten)]
pub header: ReceiptHeader,
#[serde(flatten)]
pub meta: ReceiptMeta,
#[serde(flatten)]
pub body: T,
}