agent-phone 0.1.0

Minimal sync RPC between two AI agents (Rust port of @p-vbordei/agent-phone). Self-custody keys, Noise-framework handshake, DID-bound WebSocket.
Documentation
//! Conformance vector C4 — frame decoding determinism.
//!
//! C1, C2, C3 are exercised by the end-to-end tests in `e2e.rs`.

use agent_phone::envelope::{decode, encode, Envelope};
use serde_json::Value;
use std::path::PathBuf;

#[test]
fn c4_frame_determinism() {
    let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("vectors/c4.json");
    let raw = std::fs::read(&path).expect("vectors/c4.json");
    let v: Value = serde_json::from_slice(&raw).unwrap();
    let map = v.as_object().expect("top-level object");
    for (name, entry) in map {
        let env_value = entry.get("plaintext_envelope").expect("plaintext_envelope");
        let expected_hex = entry
            .get("canonical_json_hex")
            .and_then(|v| v.as_str())
            .expect("canonical_json_hex");
        let env_map = env_value.as_object().expect("envelope is object").clone();
        let env: Envelope = env_map;
        let bytes = encode(&env).expect("encode");
        let got_hex: String = bytes.iter().map(|b| format!("{:02x}", b)).collect();
        assert_eq!(got_hex, expected_hex, "C4 {name}: canonical JSON mismatch");
        let decoded = decode(&bytes).expect("decode");
        assert_eq!(decoded, env, "C4 {name}: decode roundtrip mismatch");
    }
}