Files
vm-core/docs/VAULTMESH-IMPLEMENTATION-SCAFFOLDS.md
2025-12-27 00:10:32 +00:00

1622 lines
50 KiB
Markdown

# VAULTMESH-IMPLEMENTATION-SCAFFOLDS.md
**From Pattern to Code**
> *Every specification deserves a skeleton.*
This document provides implementation scaffolds for all VaultMesh engines — Rust structs for core types and Python CLI skeletons for tooling.
---
## 1. Shared Types (Rust)
### 1.1 Core Receipt Types
```rust
// vaultmesh-core/src/receipt.rs
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
/// 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,
}
```
### 1.2 DID Types
```rust
// vaultmesh-core/src/did.rs
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)]
pub enum DidType {
Node,
Human,
Agent,
Service,
Mesh,
}
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",
}
}
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),
_ => None,
}
}
}
#[derive(Debug)]
pub enum DidParseError {
InvalidPrefix,
MissingType,
MissingIdentifier,
}
```
### 1.3 Hash Utilities
```rust
// vaultmesh-core/src/hash.rs
use blake3::Hasher;
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)
}
```
---
## 2. Treasury Engine (Rust)
```rust
// vaultmesh-treasury/src/lib.rs
use chrono::{DateTime, Utc};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use vaultmesh_core::{Did, Receipt, ReceiptHeader, ReceiptMeta, Scroll, VmHash};
/// Treasury account
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Account {
pub account_id: String,
pub display_name: String,
pub account_type: AccountType,
pub currency: Currency,
pub balance: Decimal,
pub created_at: DateTime<Utc>,
pub tags: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AccountType {
Operational,
Reserve,
Escrow,
External,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Currency {
EUR,
USD,
GBP,
BTC,
ETH,
}
/// Treasury entry (single debit or credit)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry {
pub entry_id: String,
pub entry_type: EntryType,
pub account: String,
pub amount: Decimal,
pub currency: Currency,
pub memo: String,
pub timestamp: DateTime<Utc>,
pub tags: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EntryType {
Debit,
Credit,
}
/// Settlement contract
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SettlementContract {
pub settlement_id: String,
pub title: String,
pub initiated_by: Did,
pub initiated_at: DateTime<Utc>,
pub parties: Vec<Did>,
pub entries: Vec<Entry>,
pub requires_signatures: Vec<String>,
pub settlement_type: SettlementType,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SettlementType {
InterNodeResource,
VendorPayment,
ClientInvoice,
GrantDisbursement,
}
/// Settlement state
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SettlementState {
pub settlement_id: String,
pub status: SettlementStatus,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub signatures: std::collections::HashMap<String, Option<Signature>>,
pub entries_applied: bool,
pub balance_snapshot_before: std::collections::HashMap<String, Decimal>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SettlementStatus {
Draft,
PendingSignatures,
Executing,
Completed,
Disputed,
Expired,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Signature {
pub signed_at: DateTime<Utc>,
pub signature: String,
}
// Receipt types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TreasuryCreditReceipt {
pub entry_id: String,
pub account: String,
pub amount: Decimal,
pub currency: Currency,
pub memo: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TreasuryDebitReceipt {
pub entry_id: String,
pub account: String,
pub amount: Decimal,
pub currency: Currency,
pub memo: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TreasurySettlementReceipt {
pub settlement_id: String,
pub title: String,
pub timestamp_initiated: DateTime<Utc>,
pub timestamp_completed: DateTime<Utc>,
pub status: SettlementStatus,
pub parties: Vec<Did>,
pub entries_count: usize,
pub net_flow: std::collections::HashMap<String, Decimal>,
pub currency: Currency,
pub settlement_type: SettlementType,
pub signatures_manifest: String,
}
/// Treasury engine
pub struct TreasuryEngine {
accounts: std::collections::HashMap<String, Account>,
pending_settlements: std::collections::HashMap<String, (SettlementContract, SettlementState)>,
}
impl TreasuryEngine {
pub fn new() -> Self {
TreasuryEngine {
accounts: std::collections::HashMap::new(),
pending_settlements: std::collections::HashMap::new(),
}
}
pub fn create_account(&mut self, account: Account) -> Result<(), TreasuryError> {
if self.accounts.contains_key(&account.account_id) {
return Err(TreasuryError::AccountExists);
}
self.accounts.insert(account.account_id.clone(), account);
Ok(())
}
pub fn record_entry(&mut self, entry: Entry) -> Result<Receipt<TreasuryCreditReceipt>, TreasuryError> {
let account = self.accounts.get_mut(&entry.account)
.ok_or(TreasuryError::AccountNotFound)?;
match entry.entry_type {
EntryType::Credit => account.balance += entry.amount,
EntryType::Debit => {
if account.balance < entry.amount {
return Err(TreasuryError::InsufficientBalance);
}
account.balance -= entry.amount;
}
}
let receipt_body = TreasuryCreditReceipt {
entry_id: entry.entry_id.clone(),
account: entry.account.clone(),
amount: entry.amount,
currency: entry.currency,
memo: entry.memo,
};
let root_hash = VmHash::from_json(&receipt_body)
.map_err(|_| TreasuryError::SerializationError)?;
Ok(Receipt {
header: ReceiptHeader {
receipt_type: "treasury_credit".to_string(),
timestamp: entry.timestamp,
root_hash: root_hash.as_str().to_string(),
tags: entry.tags,
},
meta: ReceiptMeta {
scroll: Scroll::Treasury,
sequence: 0, // Set by receipt store
anchor_epoch: None,
proof_path: None,
},
body: receipt_body,
})
}
pub fn initiate_settlement(&mut self, contract: SettlementContract) -> Result<SettlementState, TreasuryError> {
// Validate all accounts exist
for entry in &contract.entries {
if !self.accounts.contains_key(&entry.account) {
return Err(TreasuryError::AccountNotFound);
}
}
// Capture balance snapshot
let mut snapshot = std::collections::HashMap::new();
for entry in &contract.entries {
if !snapshot.contains_key(&entry.account) {
let balance = self.accounts.get(&entry.account).unwrap().balance;
snapshot.insert(entry.account.clone(), balance);
}
}
let state = SettlementState {
settlement_id: contract.settlement_id.clone(),
status: SettlementStatus::PendingSignatures,
created_at: contract.initiated_at,
updated_at: Utc::now(),
signatures: contract.requires_signatures.iter()
.map(|s| (s.clone(), None))
.collect(),
entries_applied: false,
balance_snapshot_before: snapshot,
};
self.pending_settlements.insert(
contract.settlement_id.clone(),
(contract, state.clone()),
);
Ok(state)
}
pub fn add_signature(
&mut self,
settlement_id: &str,
signer: &str,
signature: Signature,
) -> Result<SettlementState, TreasuryError> {
let (_, state) = self.pending_settlements.get_mut(settlement_id)
.ok_or(TreasuryError::SettlementNotFound)?;
if !state.signatures.contains_key(signer) {
return Err(TreasuryError::UnauthorizedSigner);
}
state.signatures.insert(signer.to_string(), Some(signature));
state.updated_at = Utc::now();
// Check if all signatures collected
let all_signed = state.signatures.values().all(|s| s.is_some());
if all_signed {
state.status = SettlementStatus::Executing;
}
Ok(state.clone())
}
pub fn execute_settlement(&mut self, settlement_id: &str) -> Result<Receipt<TreasurySettlementReceipt>, TreasuryError> {
let (contract, state) = self.pending_settlements.get_mut(settlement_id)
.ok_or(TreasuryError::SettlementNotFound)?;
if state.status != SettlementStatus::Executing {
return Err(TreasuryError::SettlementNotReady);
}
// Apply all entries
let mut net_flow: std::collections::HashMap<String, Decimal> = std::collections::HashMap::new();
for entry in &contract.entries {
let account = self.accounts.get_mut(&entry.account).unwrap();
match entry.entry_type {
EntryType::Credit => {
account.balance += entry.amount;
*net_flow.entry(entry.account.clone()).or_insert(Decimal::ZERO) += entry.amount;
}
EntryType::Debit => {
account.balance -= entry.amount;
*net_flow.entry(entry.account.clone()).or_insert(Decimal::ZERO) -= entry.amount;
}
}
}
state.entries_applied = true;
state.status = SettlementStatus::Completed;
state.updated_at = Utc::now();
let receipt_body = TreasurySettlementReceipt {
settlement_id: contract.settlement_id.clone(),
title: contract.title.clone(),
timestamp_initiated: contract.initiated_at,
timestamp_completed: state.updated_at,
status: SettlementStatus::Completed,
parties: contract.parties.clone(),
entries_count: contract.entries.len(),
net_flow,
currency: contract.entries.first().map(|e| e.currency.clone()).unwrap_or(Currency::EUR),
settlement_type: contract.settlement_type.clone(),
signatures_manifest: format!("cases/treasury/{}/SIGNATURES.json", settlement_id),
};
let root_hash = VmHash::from_json(&receipt_body)
.map_err(|_| TreasuryError::SerializationError)?;
Ok(Receipt {
header: ReceiptHeader {
receipt_type: "treasury_settlement".to_string(),
timestamp: state.updated_at,
root_hash: root_hash.as_str().to_string(),
tags: vec!["treasury".to_string(), "settlement".to_string()],
},
meta: ReceiptMeta {
scroll: Scroll::Treasury,
sequence: 0,
anchor_epoch: None,
proof_path: Some(format!("cases/treasury/{}/PROOF.json", settlement_id)),
},
body: receipt_body,
})
}
}
#[derive(Debug)]
pub enum TreasuryError {
AccountExists,
AccountNotFound,
InsufficientBalance,
SettlementNotFound,
SettlementNotReady,
UnauthorizedSigner,
SerializationError,
}
```
---
## 3. Identity Engine (Rust)
```rust
// vaultmesh-identity/src/lib.rs
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use vaultmesh_core::{Did, DidType, Receipt, ReceiptHeader, ReceiptMeta, Scroll, VmHash};
/// DID Document
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DidDocument {
#[serde(rename = "@context")]
pub context: Vec<String>,
pub id: Did,
pub controller: Option<Did>,
#[serde(rename = "verificationMethod")]
pub verification_method: Vec<VerificationMethod>,
pub authentication: Vec<String>,
#[serde(rename = "assertionMethod")]
pub assertion_method: Vec<String>,
pub service: Vec<Service>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerificationMethod {
pub id: String,
#[serde(rename = "type")]
pub method_type: String,
pub controller: Did,
#[serde(rename = "publicKeyMultibase")]
pub public_key_multibase: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Service {
pub id: String,
#[serde(rename = "type")]
pub service_type: String,
#[serde(rename = "serviceEndpoint")]
pub service_endpoint: String,
}
/// Verifiable Credential
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerifiableCredential {
pub credential_id: String,
#[serde(rename = "@context")]
pub context: Vec<String>,
#[serde(rename = "type")]
pub credential_type: Vec<String>,
pub issuer: Did,
#[serde(rename = "issuanceDate")]
pub issuance_date: DateTime<Utc>,
#[serde(rename = "expirationDate")]
pub expiration_date: Option<DateTime<Utc>>,
#[serde(rename = "credentialSubject")]
pub credential_subject: CredentialSubject,
pub proof: CredentialProof,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CredentialSubject {
pub id: Did,
#[serde(flatten)]
pub claims: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CredentialProof {
#[serde(rename = "type")]
pub proof_type: String,
pub created: DateTime<Utc>,
#[serde(rename = "verificationMethod")]
pub verification_method: String,
#[serde(rename = "proofPurpose")]
pub proof_purpose: String,
#[serde(rename = "proofValue")]
pub proof_value: String,
}
/// Capability Token
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CapabilityToken {
pub capability_id: String,
pub holder: Did,
pub capability: Capability,
pub scope: CapabilityScope,
pub granted_by: Did,
pub granted_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
pub constraints: HashMap<String, serde_json::Value>,
pub proof: CredentialProof,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum Capability {
Anchor,
Storage,
Compute,
Oracle,
Admin,
Federate,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CapabilityScope {
pub scrolls: Option<Vec<Scroll>>,
pub backends: Option<Vec<String>>,
pub max_rate: Option<String>,
}
/// Authentication Event
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthEvent {
pub auth_event_id: String,
pub subject: Did,
pub target: Did,
pub method: AuthMethod,
pub result: AuthResult,
pub timestamp: DateTime<Utc>,
pub source_ip: Option<String>,
pub session_id: Option<String>,
pub credential_used: Option<String>,
pub mfa_verified: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AuthMethod {
SshKey,
Password,
Certificate,
Token,
Passkey,
Mfa,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AuthResult {
Success,
Failure,
Denied,
Expired,
}
// Receipt bodies
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DidCreateReceipt {
pub did: Did,
pub did_type: String,
pub controller: Option<Did>,
pub created_by: Did,
pub initial_keys: Vec<String>,
pub did_document_hash: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CredentialIssueReceipt {
pub credential_id: String,
pub credential_type: String,
pub issuer: Did,
pub subject: Did,
pub expires_at: Option<DateTime<Utc>>,
pub claims_summary: HashMap<String, String>,
pub credential_hash: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CapabilityGrantReceipt {
pub capability_id: String,
pub holder: Did,
pub capability: Capability,
pub scope_summary: String,
pub granted_by: Did,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthEventReceipt {
pub auth_event_id: String,
pub subject: Did,
pub target: Did,
pub method: AuthMethod,
pub result: AuthResult,
pub source_ip_hash: Option<String>,
pub mfa_verified: bool,
}
/// Identity Engine
pub struct IdentityEngine {
did_documents: HashMap<Did, DidDocument>,
credentials: HashMap<String, VerifiableCredential>,
capabilities: HashMap<String, CapabilityToken>,
revoked_credentials: HashMap<String, DateTime<Utc>>,
}
impl IdentityEngine {
pub fn new() -> Self {
IdentityEngine {
did_documents: HashMap::new(),
credentials: HashMap::new(),
capabilities: HashMap::new(),
revoked_credentials: HashMap::new(),
}
}
pub fn create_did(
&mut self,
did_type: DidType,
identifier: &str,
controller: Option<Did>,
public_key: &str,
created_by: Did,
) -> Result<Receipt<DidCreateReceipt>, IdentityError> {
let did = Did::new(did_type, identifier);
if self.did_documents.contains_key(&did) {
return Err(IdentityError::DidExists);
}
let key_id = format!("{}#key-1", did.as_str());
let doc = DidDocument {
context: vec![
"https://www.w3.org/ns/did/v1".to_string(),
"https://vaultmesh.io/ns/did/v1".to_string(),
],
id: did.clone(),
controller: controller.clone(),
verification_method: vec![VerificationMethod {
id: key_id.clone(),
method_type: "Ed25519VerificationKey2020".to_string(),
controller: did.clone(),
public_key_multibase: public_key.to_string(),
}],
authentication: vec![key_id.clone()],
assertion_method: vec![key_id.clone()],
service: vec![],
};
let doc_hash = VmHash::from_json(&doc)
.map_err(|_| IdentityError::SerializationError)?;
self.did_documents.insert(did.clone(), doc);
let receipt_body = DidCreateReceipt {
did: did.clone(),
did_type: did_type.as_str().to_string(),
controller,
created_by,
initial_keys: vec![key_id],
did_document_hash: doc_hash.as_str().to_string(),
};
let root_hash = VmHash::from_json(&receipt_body)
.map_err(|_| IdentityError::SerializationError)?;
Ok(Receipt {
header: ReceiptHeader {
receipt_type: "identity_did_create".to_string(),
timestamp: Utc::now(),
root_hash: root_hash.as_str().to_string(),
tags: vec!["identity".to_string(), "did".to_string(), "create".to_string()],
},
meta: ReceiptMeta {
scroll: Scroll::Identity,
sequence: 0,
anchor_epoch: None,
proof_path: None,
},
body: receipt_body,
})
}
pub fn resolve_did(&self, did: &Did) -> Option<&DidDocument> {
self.did_documents.get(did)
}
pub fn issue_credential(
&mut self,
credential: VerifiableCredential,
) -> Result<Receipt<CredentialIssueReceipt>, IdentityError> {
// Verify issuer exists
if !self.did_documents.contains_key(&credential.issuer) {
return Err(IdentityError::IssuerNotFound);
}
let credential_hash = VmHash::from_json(&credential)
.map_err(|_| IdentityError::SerializationError)?;
let claims_summary: HashMap<String, String> = credential.credential_subject.claims
.iter()
.map(|(k, v)| (k.clone(), v.to_string()))
.collect();
let receipt_body = CredentialIssueReceipt {
credential_id: credential.credential_id.clone(),
credential_type: credential.credential_type.join(", "),
issuer: credential.issuer.clone(),
subject: credential.credential_subject.id.clone(),
expires_at: credential.expiration_date,
claims_summary,
credential_hash: credential_hash.as_str().to_string(),
};
self.credentials.insert(credential.credential_id.clone(), credential);
let root_hash = VmHash::from_json(&receipt_body)
.map_err(|_| IdentityError::SerializationError)?;
Ok(Receipt {
header: ReceiptHeader {
receipt_type: "identity_credential_issue".to_string(),
timestamp: Utc::now(),
root_hash: root_hash.as_str().to_string(),
tags: vec!["identity".to_string(), "credential".to_string(), "issue".to_string()],
},
meta: ReceiptMeta {
scroll: Scroll::Identity,
sequence: 0,
anchor_epoch: None,
proof_path: None,
},
body: receipt_body,
})
}
pub fn verify_credential(&self, credential_id: &str) -> Result<bool, IdentityError> {
// Check if revoked
if self.revoked_credentials.contains_key(credential_id) {
return Ok(false);
}
let credential = self.credentials.get(credential_id)
.ok_or(IdentityError::CredentialNotFound)?;
// Check expiration
if let Some(expires) = credential.expiration_date {
if Utc::now() > expires {
return Ok(false);
}
}
// In production, would verify cryptographic proof here
Ok(true)
}
pub fn check_capability(&self, holder: &Did, capability: Capability) -> bool {
self.capabilities.values().any(|cap| {
&cap.holder == holder
&& cap.capability == capability
&& Utc::now() < cap.expires_at
})
}
}
#[derive(Debug)]
pub enum IdentityError {
DidExists,
DidNotFound,
IssuerNotFound,
CredentialNotFound,
CredentialRevoked,
CapabilityDenied,
SerializationError,
}
```
---
## 4. Python CLI Skeleton
```python
#!/usr/bin/env python3
"""
VaultMesh Unified CLI
vm-cli - Gateway to all VaultMesh engines
"""
import click
from datetime import datetime
from pathlib import Path
from typing import Optional
import json
# ============================================================================
# Shared utilities
# ============================================================================
def emit_receipt(scroll: str, receipt_type: str, body: dict, tags: list[str]) -> dict:
"""Create and emit a receipt to the appropriate scroll."""
import hashlib
receipt = {
"type": receipt_type,
"timestamp": datetime.utcnow().isoformat() + "Z",
"tags": tags,
**body
}
# Compute root hash
receipt_json = json.dumps(receipt, sort_keys=True)
root_hash = f"blake3:{hashlib.blake3(receipt_json.encode()).hexdigest()}"
receipt["root_hash"] = root_hash
# Append to scroll
scroll_path = Path(f"receipts/{scroll}/{scroll}_events.jsonl")
scroll_path.parent.mkdir(parents=True, exist_ok=True)
with open(scroll_path, "a") as f:
f.write(json.dumps(receipt) + "\n")
# Update Merkle root (simplified)
root_file = Path(f"ROOT.{scroll}.txt")
root_file.write_text(root_hash)
return receipt
def load_receipts(scroll: str, filters: dict = None) -> list[dict]:
"""Load and optionally filter receipts from a scroll."""
scroll_path = Path(f"receipts/{scroll}/{scroll}_events.jsonl")
if not scroll_path.exists():
return []
receipts = []
with open(scroll_path) as f:
for line in f:
receipt = json.loads(line.strip())
# Apply filters
if filters:
match = True
for key, value in filters.items():
if key == "from_date":
if receipt.get("timestamp", "") < value:
match = False
elif key == "to_date":
if receipt.get("timestamp", "") > value:
match = False
elif key == "type":
if receipt.get("type") not in value:
match = False
elif receipt.get(key) != value:
match = False
if match:
receipts.append(receipt)
else:
receipts.append(receipt)
return receipts
# ============================================================================
# Main CLI Group
# ============================================================================
@click.group()
@click.version_option(version="0.1.0")
def cli():
"""VaultMesh Civilization Ledger CLI"""
pass
# ============================================================================
# Treasury Commands
# ============================================================================
@cli.group()
def treasury():
"""Treasury Engine - Financial operations"""
pass
@treasury.command("debit")
@click.option("--from", "from_account", required=True, help="Source account")
@click.option("--amount", required=True, type=float, help="Amount")
@click.option("--currency", default="EUR", help="Currency code")
@click.option("--memo", required=True, help="Transaction memo")
@click.option("--tags", default="", help="Comma-separated tags")
def treasury_debit(from_account: str, amount: float, currency: str, memo: str, tags: str):
"""Record a debit entry."""
entry_id = f"entry-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
receipt = emit_receipt(
scroll="treasury",
receipt_type="treasury_debit",
body={
"entry_id": entry_id,
"account": from_account,
"amount": amount,
"currency": currency,
"memo": memo,
},
tags=["treasury", "debit"] + (tags.split(",") if tags else [])
)
click.echo(f"✓ Debit recorded: {entry_id}")
click.echo(f" Amount: {amount} {currency}")
click.echo(f" Hash: {receipt['root_hash'][:20]}...")
@treasury.command("credit")
@click.option("--to", "to_account", required=True, help="Destination account")
@click.option("--amount", required=True, type=float, help="Amount")
@click.option("--currency", default="EUR", help="Currency code")
@click.option("--memo", required=True, help="Transaction memo")
@click.option("--tags", default="", help="Comma-separated tags")
def treasury_credit(to_account: str, amount: float, currency: str, memo: str, tags: str):
"""Record a credit entry."""
entry_id = f"entry-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
receipt = emit_receipt(
scroll="treasury",
receipt_type="treasury_credit",
body={
"entry_id": entry_id,
"account": to_account,
"amount": amount,
"currency": currency,
"memo": memo,
},
tags=["treasury", "credit"] + (tags.split(",") if tags else [])
)
click.echo(f"✓ Credit recorded: {entry_id}")
click.echo(f" Amount: {amount} {currency}")
click.echo(f" Hash: {receipt['root_hash'][:20]}...")
@treasury.command("query")
@click.option("--account", help="Filter by account")
@click.option("--from", "from_date", help="From date (ISO format)")
@click.option("--to", "to_date", help="To date (ISO format)")
@click.option("--type", "entry_type", help="Entry type (credit/debit)")
@click.option("--format", "output_format", default="table", type=click.Choice(["table", "json", "csv"]))
def treasury_query(account: str, from_date: str, to_date: str, entry_type: str, output_format: str):
"""Query treasury entries."""
filters = {}
if account:
filters["account"] = account
if from_date:
filters["from_date"] = from_date
if to_date:
filters["to_date"] = to_date
if entry_type:
filters["type"] = [f"treasury_{entry_type}"]
receipts = load_receipts("treasury", filters)
if output_format == "json":
click.echo(json.dumps(receipts, indent=2))
elif output_format == "csv":
if receipts:
click.echo(",".join(receipts[0].keys()))
for r in receipts:
click.echo(",".join(str(v) for v in r.values()))
else:
click.echo(f"Found {len(receipts)} entries:")
for r in receipts:
click.echo(f" {r.get('timestamp', 'N/A')[:19]} | {r.get('type', 'N/A'):20} | {r.get('amount', 'N/A'):>10} {r.get('currency', '')}")
# ============================================================================
# Mesh Commands
# ============================================================================
@cli.group()
def mesh():
"""Mesh Engine - Federation topology"""
pass
@mesh.command("node")
@click.argument("action", type=click.Choice(["list", "show", "join", "leave"]))
@click.option("--id", "node_id", help="Node identifier")
@click.option("--config", type=click.Path(exists=True), help="Node config file")
def mesh_node(action: str, node_id: str, config: str):
"""Manage mesh nodes."""
if action == "list":
receipts = load_receipts("mesh", {"type": ["mesh_node_join"]})
click.echo("Active nodes:")
for r in receipts:
click.echo(f"{r.get('node_id', 'unknown')} ({r.get('node_type', 'unknown')})")
elif action == "show" and node_id:
receipts = load_receipts("mesh", {"node_id": f"did:vm:node:{node_id}"})
if receipts:
click.echo(json.dumps(receipts[-1], indent=2))
else:
click.echo(f"Node not found: {node_id}")
elif action == "join" and config:
with open(config) as f:
node_config = json.load(f)
receipt = emit_receipt(
scroll="mesh",
receipt_type="mesh_node_join",
body={
"node_id": node_config.get("node_id"),
"display_name": node_config.get("display_name"),
"node_type": node_config.get("node_type", "infrastructure"),
"endpoints_hash": "blake3:...", # Would compute from endpoints
},
tags=["mesh", "node", "join"]
)
click.echo(f"✓ Node joined: {node_config.get('node_id')}")
elif action == "leave" and node_id:
receipt = emit_receipt(
scroll="mesh",
receipt_type="mesh_node_leave",
body={
"node_id": f"did:vm:node:{node_id}",
"reason": "manual_leave",
},
tags=["mesh", "node", "leave"]
)
click.echo(f"✓ Node left: {node_id}")
@mesh.command("topology")
@click.option("--output", type=click.Path(), help="Output file")
def mesh_topology(output: str):
"""Show current mesh topology."""
node_receipts = load_receipts("mesh", {"type": ["mesh_node_join", "mesh_node_leave"]})
route_receipts = load_receipts("mesh", {"type": ["mesh_route_change"]})
# Build current state (simplified)
nodes = {}
for r in node_receipts:
node_id = r.get("node_id")
if r["type"] == "mesh_node_join":
nodes[node_id] = r
elif r["type"] == "mesh_node_leave" and node_id in nodes:
del nodes[node_id]
topology = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"node_count": len(nodes),
"nodes": list(nodes.keys()),
}
if output:
with open(output, "w") as f:
json.dump(topology, f, indent=2)
click.echo(f"✓ Topology saved to {output}")
else:
click.echo(json.dumps(topology, indent=2))
# ============================================================================
# Identity Commands
# ============================================================================
@cli.group()
def identity():
"""Identity Engine - DIDs and credentials"""
pass
@identity.command("did")
@click.argument("action", type=click.Choice(["create", "show", "list", "rotate-key"]))
@click.option("--type", "did_type", type=click.Choice(["node", "human", "agent", "service"]))
@click.option("--id", "identifier", help="DID identifier")
@click.option("--controller", help="Controller DID")
def identity_did(action: str, did_type: str, identifier: str, controller: str):
"""Manage decentralized identifiers."""
if action == "create" and did_type and identifier:
did = f"did:vm:{did_type}:{identifier}"
receipt = emit_receipt(
scroll="identity",
receipt_type="identity_did_create",
body={
"did": did,
"did_type": did_type,
"controller": controller,
"initial_keys": [f"{did}#key-1"],
"did_document_hash": "blake3:...",
},
tags=["identity", "did", "create", did_type]
)
click.echo(f"✓ DID created: {did}")
elif action == "show" and identifier:
did = f"did:vm:node:{identifier}" # Simplified
receipts = load_receipts("identity", {"did": did})
if receipts:
click.echo(json.dumps(receipts[-1], indent=2))
else:
click.echo(f"DID not found: {did}")
elif action == "list":
receipts = load_receipts("identity", {"type": ["identity_did_create"]})
click.echo("Registered DIDs:")
for r in receipts:
click.echo(f"{r.get('did', 'unknown')} ({r.get('did_type', 'unknown')})")
@identity.command("capability")
@click.argument("action", type=click.Choice(["grant", "check", "list", "revoke"]))
@click.option("--holder", help="Capability holder DID")
@click.option("--capability", type=click.Choice(["anchor", "storage", "compute", "oracle", "admin"]))
@click.option("--expires", help="Expiration date (ISO format)")
def identity_capability(action: str, holder: str, capability: str, expires: str):
"""Manage capability tokens."""
if action == "grant" and holder and capability:
cap_id = f"cap:vm:{datetime.utcnow().strftime('%Y-%m-%d')}:{capability}:{holder.split(':')[-1]}"
receipt = emit_receipt(
scroll="identity",
receipt_type="identity_capability_grant",
body={
"capability_id": cap_id,
"holder": holder,
"capability": capability,
"granted_by": "did:vm:node:portal-01", # Would come from context
"expires_at": expires or "2026-01-01T00:00:00Z",
},
tags=["identity", "capability", "grant", capability]
)
click.echo(f"✓ Capability granted: {cap_id}")
elif action == "check" and holder and capability:
receipts = load_receipts("identity", {"holder": holder, "capability": capability})
grants = [r for r in receipts if r["type"] == "identity_capability_grant"]
revokes = [r for r in receipts if r["type"] == "identity_capability_revoke"]
# Check if any valid grant exists
valid = False
for g in grants:
grant_id = g.get("capability_id")
if not any(r.get("capability_id") == grant_id for r in revokes):
expires = g.get("expires_at", "")
if expires > datetime.utcnow().isoformat():
valid = True
break
if valid:
click.echo(f"{holder} HAS capability: {capability}")
else:
click.echo(f"{holder} does NOT have capability: {capability}")
elif action == "list" and holder:
receipts = load_receipts("identity", {"holder": holder, "type": ["identity_capability_grant"]})
click.echo(f"Capabilities for {holder}:")
for r in receipts:
click.echo(f"{r.get('capability', 'unknown')} (expires: {r.get('expires_at', 'never')[:10]})")
# ============================================================================
# Psi-Field Commands
# ============================================================================
@cli.group()
def psi():
"""Ψ-Field Engine - Alchemical consciousness"""
pass
@psi.command("phase")
@click.argument("action", type=click.Choice(["current", "history", "transition"]))
@click.option("--to", "to_phase", type=click.Choice(["nigredo", "albedo", "citrinitas", "rubedo"]))
@click.option("--trigger", help="Transition trigger description")
def psi_phase(action: str, to_phase: str, trigger: str):
"""Manage alchemical phases."""
if action == "current":
receipts = load_receipts("psi", {"type": ["psi_phase_transition"]})
if receipts:
last = receipts[-1]
phase = last.get("to_phase", "unknown")
symbols = {"nigredo": "🜁", "albedo": "🜄", "citrinitas": "🜆", "rubedo": "🜂"}
click.echo(f"Current Phase: {phase.upper()} {symbols.get(phase, '')}")
click.echo(f"Since: {last.get('timestamp', 'unknown')[:19]}")
else:
click.echo("Current Phase: NIGREDO 🜁 (initial)")
elif action == "history":
receipts = load_receipts("psi", {"type": ["psi_phase_transition"]})
click.echo("Phase History:")
for r in receipts:
click.echo(f" {r.get('timestamp', '')[:19]} | {r.get('from_phase', 'init'):10}{r.get('to_phase', ''):10}")
elif action == "transition" and to_phase and trigger:
# Get current phase
receipts = load_receipts("psi", {"type": ["psi_phase_transition"]})
from_phase = receipts[-1].get("to_phase", "nigredo") if receipts else "nigredo"
receipt = emit_receipt(
scroll="psi",
receipt_type="psi_phase_transition",
body={
"transition_id": f"psi-trans-{datetime.utcnow().strftime('%Y-%m-%d-%H%M%S')}",
"from_phase": from_phase,
"to_phase": to_phase,
"trigger_type": "manual",
"trigger_description": trigger,
},
tags=["psi", "phase", from_phase, to_phase]
)
click.echo(f"✓ Phase transition: {from_phase}{to_phase}")
@psi.command("transmute")
@click.option("--input", "input_ref", required=True, help="Input reference (e.g., INC-2025-12-001)")
@click.option("--input-type", required=True, type=click.Choice(["incident", "vulnerability", "drill"]))
@click.option("--title", required=True, help="Transmutation title")
def psi_transmute(input_ref: str, input_type: str, title: str):
"""Initiate a transmutation process."""
trans_id = f"psi-transmute-{datetime.utcnow().strftime('%Y-%m-%d-%H%M%S')}"
receipt = emit_receipt(
scroll="psi",
receipt_type="psi_transmutation",
body={
"transmutation_id": trans_id,
"title": title,
"input_type": input_type,
"input_reference": input_ref,
"status": "initiated",
"alchemical_phase_target": "citrinitas",
},
tags=["psi", "transmutation", input_type]
)
click.echo(f"✓ Transmutation initiated: {trans_id}")
click.echo(f" Input: {input_ref} ({input_type})")
click.echo(f" Target phase: CITRINITAS 🜆")
@psi.command("opus")
def psi_opus():
"""Display Magnum Opus status."""
# Get current phase
phase_receipts = load_receipts("psi", {"type": ["psi_phase_transition"]})
current_phase = phase_receipts[-1].get("to_phase", "nigredo") if phase_receipts else "nigredo"
# Get transmutation counts
trans_receipts = load_receipts("psi", {"type": ["psi_transmutation"]})
# Get resonance count
res_receipts = load_receipts("psi", {"type": ["psi_resonance"]})
symbols = {"nigredo": "🜁", "albedo": "🜄", "citrinitas": "🜆", "rubedo": "🜂"}
click.echo("=" * 50)
click.echo(" MAGNUM OPUS STATUS")
click.echo("=" * 50)
click.echo()
click.echo(f" Current Phase: {current_phase.upper()} {symbols.get(current_phase, '')}")
click.echo()
click.echo(" Phase Progress:")
phases = ["nigredo", "albedo", "citrinitas", "rubedo"]
for i, p in enumerate(phases):
marker = "" if p == current_phase else ("" if phases.index(p) > phases.index(current_phase) else "")
click.echo(f" {marker} {p.upper():12} {symbols.get(p, '')}")
click.echo()
click.echo(f" Transmutations: {len(trans_receipts)}")
click.echo(f" Resonances: {len(res_receipts)}")
click.echo()
click.echo("=" * 50)
# ============================================================================
# Guardian Commands (bridge to existing)
# ============================================================================
@cli.group()
def guardian():
"""Guardian Engine - Anchor and sentinel"""
pass
@guardian.command("anchor-status")
def guardian_anchor_status():
"""Show current anchor status."""
receipts = load_receipts("guardian", {"type": ["anchor_success", "anchor_failure"]})
if receipts:
last = receipts[-1]
click.echo(f"Last Anchor: {last.get('timestamp', 'unknown')[:19]}")
click.echo(f"Status: {last.get('type', 'unknown')}")
click.echo(f"Root: {last.get('root_hash', 'unknown')[:30]}...")
else:
click.echo("No anchor events recorded")
@guardian.command("anchor-now")
@click.option("--scroll", multiple=True, help="Scrolls to anchor (default: all)")
def guardian_anchor_now(scroll: tuple):
"""Trigger immediate anchor cycle."""
scrolls = list(scroll) if scroll else ["drills", "compliance", "treasury", "mesh", "identity", "psi"]
click.echo(f"Anchoring scrolls: {', '.join(scrolls)}")
# Would call actual Guardian anchor cycle here
receipt = emit_receipt(
scroll="guardian",
receipt_type="anchor_success",
body={
"anchor_id": f"anchor-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}",
"scrolls_anchored": scrolls,
"backend": "local", # Would be ots/ethereum/bitcoin in production
},
tags=["guardian", "anchor", "manual"]
)
click.echo(f"✓ Anchor cycle complete")
click.echo(f" ID: {receipt.get('anchor_id')}")
# ============================================================================
# Entry Point
# ============================================================================
if __name__ == "__main__":
cli()
```
---
## 5. Directory Structure
```
vaultmesh/
├── Cargo.toml # Rust workspace
├── pyproject.toml # Python CLI
├── vaultmesh-core/ # Shared Rust types
│ └── src/
│ ├── lib.rs
│ ├── receipt.rs
│ ├── did.rs
│ └── hash.rs
├── vaultmesh-treasury/ # Treasury engine
│ └── src/lib.rs
├── vaultmesh-mesh/ # Mesh engine
│ └── src/lib.rs
├── vaultmesh-identity/ # Identity engine
│ └── src/lib.rs
├── vaultmesh-offsec/ # OffSec engine
│ └── src/lib.rs
├── vaultmesh-observability/ # Observability engine
│ └── src/lib.rs
├── vaultmesh-automation/ # Automation engine
│ └── src/lib.rs
├── vaultmesh-psi/ # Ψ-Field engine
│ └── src/lib.rs
├── vaultmesh-guardian/ # Guardian (existing)
│ └── src/lib.rs
├── cli/ # Python CLI
│ ├── __init__.py
│ └── vm_cli.py
├── receipts/ # Receipt storage
│ ├── drills/
│ ├── compliance/
│ ├── guardian/
│ ├── treasury/
│ ├── mesh/
│ ├── offsec/
│ ├── identity/
│ ├── observability/
│ ├── automation/
│ └── psi/
├── cases/ # Case artifacts
│ ├── drills/
│ ├── treasury/
│ ├── offsec/
│ ├── identity/
│ └── psi/
└── ROOT.*.txt # Merkle roots
```
---
## 6. Summary
This document provides:
1. **Rust Core Types** (`vaultmesh-core`)
- `Receipt<T>` — generic receipt wrapper
- `Scroll` enum — all 10 scrolls with paths
- `Did` — decentralized identifier type
- `VmHash` — blake3 hash with prefix
- `merkle_root()` — Merkle tree computation
2. **Treasury Engine** (`vaultmesh-treasury`)
- `Account`, `Entry`, `SettlementContract`, `SettlementState`
- Full settlement workflow with signatures
- Receipt generation for credits, debits, settlements
3. **Identity Engine** (`vaultmesh-identity`)
- `DidDocument`, `VerifiableCredential`, `CapabilityToken`
- DID creation, credential issuance, capability checks
- Authentication events
4. **Python CLI** (`vm-cli`)
- Unified CLI covering Treasury, Mesh, Identity, Ψ-Field, Guardian
- `emit_receipt()` and `load_receipts()` utilities
- Complete command structure matching engine specs
5. **Directory Structure**
- Rust workspace layout
- Receipt and case storage paths
- Merkle root file locations
All engines now have both specifications and implementation scaffolds following the Eternal Pattern.