open-standards/jouleclaw/jouleclaw-rs/crates/jouleclaw-wire/tests/r9_wire.rs
Transaction Science 8f9a42e4d4 jouleclaw Phase 2: cascade + loader-gguf + pack + history + wire
Five crates ported / designed. All 235 tests pass; 0 errors;
0 warnings outside the loader-gguf NEON-intrinsics module (suppressed
with a documented #![allow(unsafe_op_in_unsafe_fn)] — proper fix is
wrapping each intrinsic call in unsafe { }, tracked as kernel-quality
maintenance, not standards work).

jouleclaw-cascade
  Ported from pattern-lang/joule-cascade (~7044 LOC, 17 files).
  L0 (Cache), tier dispatch, 7-axis Synthesis coordinate router, cost
  model, calibration ledger (in-memory + disk), history, verification,
  body + body_safety policy gates, active-entity tracking, l2_service
  trait surface. Two tests that depended on joule-l1's lawful-primitive
  impl (which requires pattern-lang's pattern-core + cortex-ir +
  synthesizer — OpenIE IP) were removed; the L1 trait surface lives
  here and consumers plug their own lawful lexicon in.

jouleclaw-loader-gguf
  Ported from pattern-lang/joule-loader-gguf (~11605 LOC, 17 files).
  GGUF v3 parser with mmap, Llama and Gemma / Gemma 4 decoders,
  Q4_0 / Q5_K / Q8_0 / Q8_0 grouped quants, in-place KV cache,
  matmul_q8_0 with NEON intrinsics on Apple Silicon, safetensors
  reader, tokenizer + Gemma tokenizer, sample, dequant.

jouleclaw-pack (NEW)
  The .jc.toml sidecar — JouleClaw's standard-defining contribution.
  A model on disk (GGUF / safetensors / MLX) tells you tensor shapes
  and quant schemes. It does NOT tell you what one forward pass
  actually costs in joules on real hardware. The .jc.toml is a
  declared-cost contract that travels with the model:

    - per-tensor precision (FP16/BF16/FP8/INT8/NVFP4/NF4/Q4_K/...)
    - page-alignment status (mmap-zero-copy possible? on which UMA?)
    - measured J/op on a reference hardware matrix with explicit
      Provenance (HwShunt / ModelBased / Estimator)
    - drift_factor tolerance per measurement; the runtime trips
      PackError::CostDrift when measured > declared * drift_factor
      and down-weights the backend in subsequent auction rounds

  Without a declared-cost contract, "energy-optimized inference" is
  marketing. With one, it is an engineering claim any third party
  can verify against the published reference-hardware corpus.

  5 lib tests pass. ModelFormat, Precision, Alignment, MeasurementOp,
  Pack, TensorContract, Measurement, hash_model(), verify_measurement().

jouleclaw-history
  Ported from pattern-lang/joule-history (~2026 LOC, 6 files).
  Persistent resolution history: disk + in-memory + tiered
  (hot/warm/cold) + semantic. One Rust-2024 edition fix in
  tiered.rs (binding-mode pattern: |(_, &seq)| seq -> |(_, seq)| *seq).

jouleclaw-wire
  Ported from pattern-lang/joule-wire (~1129 LOC, 2 files).
  L4 wire tier — the remote frontier escape hatch. RPC client +
  transport, invoked only when the local cascade returns Unresolvable.

Phase 3 next: HAL from efficient-genai, backend-{apple,reference,
cuda,metal,rocm,vulkan}, runtime (port joule-runtime — chat/embed/
generate/streaming/PLD/drafter — needs backends to compile).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-26 11:55:46 -04:00

420 lines
15 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! R9 tests — wire protocol round-trips, error handling, and the
//! federation end-to-end.
use jouleclaw_cascade::*;
use jouleclaw_history::InMemoryHistory;
use jouleclaw_wire::*;
// ============================================================
// Round-trip
// ============================================================
#[test]
fn round_trip_request() {
let msg = WireMessage::Request(WireRequest {
query_key: [0xab; 32],
max_joules: 1e-3,
request_id: 42,
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
match decoded {
WireMessage::Request(r) => {
assert_eq!(r.query_key, [0xab; 32]);
assert_eq!(r.max_joules, 1e-3);
assert_eq!(r.request_id, 42);
}
other => panic!("expected Request, got {:?}", other),
}
}
#[test]
fn round_trip_quote() {
let msg = WireMessage::Quote(WireQuote {
query_key: [0x33; 32],
request_id: 17,
joules_charged: 5e-7,
confidence: 0.95,
origin_tier: TierId::L1(L1Primitive::Execute),
expiry_secs: 1_700_000_000,
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
match decoded {
WireMessage::Quote(q) => {
assert_eq!(q.query_key, [0x33; 32]);
assert_eq!(q.request_id, 17);
assert_eq!(q.joules_charged, 5e-7);
assert!((q.confidence - 0.95).abs() < 1e-6);
assert_eq!(q.origin_tier, TierId::L1(L1Primitive::Execute));
assert_eq!(q.expiry_secs, 1_700_000_000);
}
other => panic!("expected Quote, got {:?}", other),
}
}
#[test]
fn round_trip_response_text() {
let msg = WireMessage::Response(WireResponse {
query_key: [0x77; 32],
request_id: 100,
joules_charged: 1e-7,
confidence: 0.9,
origin_tier: TierId::L4(L4ModelId(0)),
expiry_secs: 0,
output: AnswerOutput::Text("Paris".into()),
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
match decoded {
WireMessage::Response(r) => {
assert_eq!(r.output, AnswerOutput::Text("Paris".into()));
assert_eq!(r.origin_tier, TierId::L4(L4ModelId(0)));
}
other => panic!("expected Response, got {:?}", other),
}
}
#[test]
fn round_trip_response_structured() {
let msg = WireMessage::Response(WireResponse {
query_key: [0; 32],
request_id: 1,
joules_charged: 1e-6,
confidence: 1.0,
origin_tier: TierId::L1(L1Primitive::Regex),
expiry_secs: 0,
output: AnswerOutput::Structured(vec![1, 2, 3, 4, 5]),
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
if let WireMessage::Response(r) = decoded {
assert_eq!(r.output, AnswerOutput::Structured(vec![1, 2, 3, 4, 5]));
} else {
panic!("wrong kind");
}
}
#[test]
fn round_trip_response_refused_inapplicable() {
let msg = WireMessage::Response(WireResponse {
query_key: [0; 32],
request_id: 1,
joules_charged: 0.0,
confidence: 0.0,
origin_tier: TierId::L0,
expiry_secs: 0,
output: AnswerOutput::Refused(RefusalReason::Inapplicable),
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
if let WireMessage::Response(r) = decoded {
assert_eq!(r.output, AnswerOutput::Refused(RefusalReason::Inapplicable));
}
}
#[test]
fn round_trip_response_refused_tier_specific() {
let msg = WireMessage::Response(WireResponse {
query_key: [0; 32],
request_id: 1,
joules_charged: 0.0,
confidence: 0.0,
origin_tier: TierId::L0,
expiry_secs: 0,
output: AnswerOutput::Refused(RefusalReason::TierSpecific("nope".into())),
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
if let WireMessage::Response(r) = decoded {
assert_eq!(r.output,
AnswerOutput::Refused(RefusalReason::TierSpecific("nope".into())));
}
}
#[test]
fn round_trip_error() {
let msg = WireMessage::Error(WireError {
request_id: 999,
code: ErrorCode::BudgetExceeded,
message: "remote node ran out of budget".into(),
});
let bytes = encode(&msg);
let decoded = decode(&bytes).unwrap();
match decoded {
WireMessage::Error(e) => {
assert_eq!(e.request_id, 999);
assert_eq!(e.code, ErrorCode::BudgetExceeded);
assert_eq!(e.message, "remote node ran out of budget");
}
other => panic!("expected Error, got {:?}", other),
}
}
// ============================================================
// Error handling
// ============================================================
#[test]
fn bad_magic_detected() {
let bad = b"NOTJOULE000000000000000000000000000000";
let result = decode(bad);
assert!(matches!(result, Err(DecodeError::BadMagic)));
}
#[test]
fn truncated_input_returns_clean_error() {
let msg = WireMessage::Request(WireRequest {
query_key: [0; 32], max_joules: 1.0, request_id: 1,
});
let bytes = encode(&msg);
// Truncate to half.
let truncated = &bytes[..bytes.len() / 2];
let result = decode(truncated);
assert!(matches!(result, Err(DecodeError::Truncated { .. })));
}
#[test]
fn unknown_kind_returns_clean_error() {
// Build a syntactically valid envelope with bogus kind 99.
let mut bytes = Vec::new();
bytes.extend_from_slice(MAGIC);
bytes.push(99); // unknown kind
bytes.extend_from_slice(&0u64.to_be_bytes()); // payload_len 0
bytes.extend_from_slice(&[0u8; SIGNATURE_LEN]);
let result = decode(&bytes);
assert!(matches!(result, Err(DecodeError::UnknownKind(99))));
}
// ============================================================
// Server-side: serve_request against a history layer
// ============================================================
fn text(s: &str) -> Query {
Query {
input: QueryInput::Text(s.to_string()),
budget: JouleBudget::standard(),
quality: QualityFloor::any(),
context: ContextRef::fresh(),
deadline: None,
}
}
fn answer(text: &str, tier: TierId, joules: f64, conf: f32) -> Answer {
Answer {
output: AnswerOutput::Text(text.to_string()),
tier_used: tier,
joules_spent: joules,
confidence: conf,
trace: ExecutionTrace::default(),
verification: jouleclaw_cascade::verification::VerificationStatus::Resolved,
}
}
#[test]
fn serve_request_returns_cached_answer() {
let mut history = InMemoryHistory::new();
let q = text("capital of France?");
let a = answer("Paris", TierId::L4(L4ModelId(0)), 0.5, 0.9);
history.record(&q, &a).unwrap();
let request = WireMessage::Request(WireRequest {
query_key: key_for(&q),
max_joules: 1.0,
request_id: 7,
});
let request_bytes = encode(&request);
let response_bytes = serve_request(&request_bytes, &mut history);
let response = decode(&response_bytes).unwrap();
match response {
WireMessage::Response(r) => {
assert_eq!(r.request_id, 7);
assert_eq!(r.output, AnswerOutput::Text("Paris".into()));
assert_eq!(r.origin_tier, TierId::L4(L4ModelId(0)));
assert!((r.confidence - 0.9).abs() < 1e-6);
}
other => panic!("expected Response, got {:?}", other),
}
}
#[test]
fn serve_request_returns_not_found_for_missing_key() {
let mut history = InMemoryHistory::new();
let request = WireMessage::Request(WireRequest {
query_key: [0xff; 32],
max_joules: 1.0,
request_id: 99,
});
let request_bytes = encode(&request);
let response_bytes = serve_request(&request_bytes, &mut history);
let response = decode(&response_bytes).unwrap();
match response {
WireMessage::Error(e) => {
assert_eq!(e.code, ErrorCode::NotFound);
assert_eq!(e.request_id, 99);
}
other => panic!("expected NotFound Error, got {:?}", other),
}
}
// ============================================================
// Federation end-to-end
// ============================================================
/// A transport that wraps a server's history layer in a closure.
/// Each `round_trip` calls `serve_request` against the server's
/// history. Models two nodes sharing a backing store.
struct InProcessTransport {
server_history: std::sync::Arc<std::sync::Mutex<InMemoryHistory>>,
/// Count of how many round-trips happened — observability for tests.
pub call_count: std::sync::Arc<std::sync::atomic::AtomicU64>,
}
impl Transport for InProcessTransport {
fn round_trip(&mut self, request: &[u8]) -> Result<Vec<u8>, String> {
self.call_count.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
let mut h = self.server_history.lock().unwrap();
Ok(serve_request(request, &mut *h))
}
}
/// A mock L4 tier — used to seed the server's history.
struct MockL4;
impl Tier for MockL4 {
fn id(&self) -> TierId { TierId::L4(L4ModelId(0)) }
fn estimate_cost(&self, _q: &Query) -> Option<TierEstimate> {
Some(TierEstimate {
joules: 0.5,
latency: std::time::Duration::from_millis(100),
confidence_floor: 0.9,
})
}
fn try_answer(&mut self, _q: &Query, _b: f64) -> Result<Answer, AnswerError> {
Ok(Answer {
output: AnswerOutput::Text("Paris".into()),
tier_used: self.id(),
joules_spent: 0.5,
confidence: 0.9,
trace: ExecutionTrace::default(),
verification: jouleclaw_cascade::verification::VerificationStatus::Resolved,
})
}
}
#[test]
fn federation_two_runtimes_share_answers_via_wire() {
// Server side: a Runtime that has answered the query via L4.
let server_history = std::sync::Arc::new(std::sync::Mutex::new(InMemoryHistory::new()));
{
let mut server_cascade = Cascade::new();
server_cascade.register(Box::new(MockL4));
let history_clone: Box<dyn HistoryLayer> = Box::new(server_history.lock().unwrap().clone_for_test());
// We can't pass an Arc<Mutex> to the runtime directly; for the
// test we seed the server history manually by running a query
// through a server Runtime and then mirroring the answer.
let mut rt = Runtime::new_with_history(server_cascade, history_clone);
let q = text("capital of France?");
let a = rt.answer(q.clone()).unwrap();
// Manually record into the shared history.
server_history.lock().unwrap().record(&q, &a).unwrap();
}
// Client side: a Runtime with an RpcTier that reaches into the
// server's history.
let call_count = std::sync::Arc::new(std::sync::atomic::AtomicU64::new(0));
let transport = InProcessTransport {
server_history: server_history.clone(),
call_count: call_count.clone(),
};
let rpc = RpcTier::new(Box::new(transport));
let mut client_cascade = Cascade::new();
client_cascade.register(Box::new(rpc));
client_cascade.register(Box::new(MockL4)); // local fallback
let mut client_rt = Runtime::new(client_cascade);
let a = client_rt.answer(text("capital of France?")).unwrap();
// The RpcTier should have answered the query at low cost,
// skipping the local L4.
assert_eq!(a.tier_used, TierId::L0,
"RpcTier should report as L0; got {:?}", a.tier_used);
assert_eq!(a.output, AnswerOutput::Text("Paris".into()));
// Cost: local RPC overhead (~1 µJ) + remote charged (~100 nJ).
// Should be far less than 500 mJ (L4 cost).
assert!(a.joules_spent < 1e-3,
"federated cache hit should be <<L4 cost; got {:.3e}", a.joules_spent);
assert_eq!(call_count.load(std::sync::atomic::Ordering::SeqCst), 1,
"exactly one RPC round-trip should have occurred");
}
// Helper: clone the in-memory history for testing.
trait CloneForTest {
fn clone_for_test(&self) -> Self;
}
impl CloneForTest for InMemoryHistory {
fn clone_for_test(&self) -> Self {
// Simple clone — entries and stats are not visible directly,
// so we just create a fresh one (the test re-seeds anyway).
InMemoryHistory::new()
}
}
// ============================================================
// Demo
// ============================================================
#[test]
fn r9_wire_demo() {
println!("\n=== R9: federated cascade via metered wire protocol ===\n");
// Same setup as the federation test but with verbose printing.
let server_history = std::sync::Arc::new(std::sync::Mutex::new(InMemoryHistory::new()));
{
let q = text("capital of France?");
let a = answer("Paris", TierId::L4(L4ModelId(0)), 0.5, 0.9);
server_history.lock().unwrap().record(&q, &a).unwrap();
println!("Server seeded with one answer (cost 500 mJ at L4):");
println!(" query: \"capital of France?\" → \"Paris\"");
}
let call_count = std::sync::Arc::new(std::sync::atomic::AtomicU64::new(0));
let transport = InProcessTransport {
server_history: server_history.clone(),
call_count: call_count.clone(),
};
let rpc = RpcTier::new(Box::new(transport));
let mut client_cascade = Cascade::new();
client_cascade.register(Box::new(rpc));
client_cascade.register(Box::new(MockL4));
let mut client_rt = Runtime::new(client_cascade);
println!("\nClient queries: \"capital of France?\"");
let a = client_rt.answer(text("capital of France?")).unwrap();
println!(" tier_used: {:?}", a.tier_used);
println!(" answer: {:?}", a.output);
println!(" client cost: {:.3e} J (vs L4 cost 5.000e-1 J)", a.joules_spent);
println!(" speedup: ~{:.0}× cheaper than local L4",
0.5 / a.joules_spent.max(1e-12));
println!(" rpc calls: {}", call_count.load(std::sync::atomic::Ordering::SeqCst));
// Wire bytes for reference.
let request = encode(&WireMessage::Request(WireRequest {
query_key: key_for(&text("capital of France?")),
max_joules: 1.0, request_id: 1,
}));
println!("\nA request envelope is {} bytes on the wire", request.len());
println!(" 16 header (magic+version+kind+payload_len)");
println!(" 48 payload (32 key + 8 max_joules + 8 request_id)");
println!(" 64 signature placeholder (reserved for crypto)");
println!();
println!("This is the seam where federation works:");
println!("• Server pays L4 cost once; bills clients per-RPC.");
println!("• Client pays local RPC overhead + the server's quote.");
println!("• Every message carries its origin tier, confidence,");
println!(" joules charged, and expiry — receivers know what");
println!(" they're buying.");
}