northroot-proof-engine 0.3.2

Core proof computation and validation library for PoSH (Proof of Shape) and PoX (Proof of Execution)
Documentation
use serde::{Deserialize, Serialize};

// ---------- Common ----------
pub type Sha256 = String;   // "sha256:<64hex>"
pub type IsoTime = String;  // RFC3339 (UTC, ms)
pub type Uri = String;
pub type Did = String;      // e.g., "did:key:..."

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Signature {
    pub alg: String, // "ed25519"
    pub kid: String,
    pub sig: String, // base64url
}

// ---------- PoSH ----------
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MethodShapeManifest {
    pub schema_version: String, // "method.v1"
    pub method_id: String,
    pub version: String,        // semver
    pub method_shape_root: Sha256,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub method_dag_hash: Option<Sha256>,
    pub runtime: RuntimePins,
    #[serde(default)]
    pub checker_refs: Vec<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub default_policy_id: Option<String>,
    pub publisher_sig: Signature,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RuntimePins {
    pub image_digest: Sha256,       // OCI/WASM
    pub method_fingerprint: String, // "git:<commit>"
}

// ---------- PoX: Trace ----------
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Trace {
    pub schema_version: String, // "trace.v2"
    pub trace_id: String,
    pub method_ref: MethodRef,
    pub data_shape_hash: Sha256,
    pub policy_id: String,
    pub identity_route: Did,
    pub content_route: Uri,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub execution_route: Option<ExecutionRoute>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MethodRef {
    pub method_id: String,
    pub version: String,
    pub method_shape_root: Sha256,
    pub image_digest: Sha256,
    pub method_fingerprint: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionRoute {
    pub provider: String,       // "aws" | "gcp" | "azure" | "onprem"
    #[serde(skip_serializing_if = "Option::is_none")]
    pub account: Option<String>,
    pub region: String,
    pub runtime_digest: Sha256,
}

// ---------- PoX: Span Commitment ----------
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpanCommitment {
    pub schema_version: String, // "proof.v2"
    pub trace_id: String,
    pub span_id: String,

    pub method_ref: MethodRef,
    pub data_shape_hash: Sha256,

    pub span_shape_hash: Sha256,

    pub inputs: Vec<ArtifactRef>,
    pub outputs: Vec<ArtifactRef>,

    pub start_time: IsoTime,
    pub end_time: IsoTime,
    pub status: SpanStatus,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub meta: Option<SpanMeta>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum SpanStatus {
    OK,
    ERROR,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArtifactRef {
    pub name: String,
    pub content_hash: Sha256,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub uri: Option<Uri>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpanMeta {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub lamport: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub parents: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub order_index: Option<u64>,
}

// Transport envelope for posting proofs
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignedSpan {
    pub commitment: SpanCommitment,
    pub signature: Signature, // ed25519 over sha256(canonical(commitment))
}

// ---------- PoX: Trace Roots ----------
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TraceRoots {
    pub trace_id: String,
    pub span_commitments: Vec<Sha256>, // hashes of canonical SpanCommitment
    pub trace_set_root: Sha256,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub identity_root: Option<Sha256>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub trace_seq_root: Option<Sha256>,
    pub method_shape_root: Sha256, // carried from method_ref
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tier01_status: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub server_sig: Option<Signature>,
}