open-standards/eoc/eoc-rs/crates/eoc-neural/src/lib.rs
Transaction Science a437feb8ab Parallel ingest: 9 issues' worth of work across openpay / smart-byte / eoc
openpay/
  compliance/                     PCI-DSS readiness package (scope-map,
                                  pci-zero-architecture, hsm-kms-guidance,
                                  qsa-checklist), citing PCI-DSS v4.0.1
                                  requirements. (#1)
  examples/pci-zero/              Runnable example demonstrating a deployment
                                  where merchant code never touches a PAN. (#1)
  crates/op-core/                 Tokenized<Card> typestate + NetworkToken
                                  + CardNetwork + Cryptogram. (#2)
  crates/op-rails-card/network_token/
                                  NetworkTokenProvider trait + VTS adapter
                                  + MDES adapter, with deterministic stubs
                                  behind a 'live' feature flag. (#2)
  crates/op-driver-sdk/conformance/network_token.rs
                                  Conformance harness for third-party
                                  NetworkTokenProvider implementations. (#2)
  crates/op-cli/src/ledger/       'openpay ledger as-of' subcommand for
                                  bi-temporal queries. (#3)
  crates/op-orchestrator/src/telemetry.rs
                                  OpenTelemetry span emission per
                                  Payment<S> transition with semantic-
                                  conventions tags. (#3)
  docs/observability/             Grafana dashboard JSON + wiring guide
                                  for the bi-temporal ledger lens. (#3)

smart-byte/
  smart-byte-rs/                  Rust reference implementation: envelope
                                  encode/decode (canonical CBOR + BLAKE3
                                  content addressing), Ed25519 sign +
                                  verify, lockstep BFT commit MVP, Iroh
                                  transport scaffold, CLI. (#4)
  spec/identity_and_key_rotation.md
                                  Adopts KERI SAIDs + key-event log
                                  format; explicitly does not adopt ACDC
                                  chaining wholesale. (#5)
  conformance/v1/                 21 test vectors covering canonicalisation,
                                  SAID computation, signature verification,
                                  lockstep commit, gossip propagation.
                                  CI gate enforces spec/vector coupling. (#6)

eoc/
  eoc-rs/                         Rust + WASM reference implementation:
                                  4-stage cascade (cache -> kv -> graph ->
                                  neural), joule counters via RAPL / NVML /
                                  powermetrics, CLI, wasm-bindgen surface.
                                  18 tests pass. (#7)
  eoc-bench/                      Benchmark harness, MT-Bench and Router
                                  case sets, 'joules per MT-Bench point'
                                  metric, 'eoc-bench run | compare' CLI. (#8)
  standards/sci-for-ai-submission.md
                                  Submission proposal mapping EOC's
                                  receipt schema to GSF SCI-for-AI. (#9)
  cookbook/                       HuggingFace-style cookbook (markdown +
                                  runnable Python) demonstrating EOC's
                                  cascade with HF AI Energy Score. (#9)
  docs/bench-v0.md                Reproducibility doc for eoc-bench.

Workspace state:
- openpay clippy -- -D warnings: clean across all touched crates
- smart-byte-rs cargo test --workspace + clippy: clean
- eoc-rs cargo test --workspace + clippy: clean (18 tests)
- eoc-bench cargo check --workspace + clippy + 15 tests: clean

Rust 1.95.0 edition 2024 pinned at the open-standards root via
rust-toolchain.toml; every workspace inherits.

Closes #1 #2 #3 #4 #5 #6 #7 #8 #9.
2026-05-23 13:24:05 -04:00

108 lines
3 KiB
Rust

//! EOC stage 4 — neural inference.
//!
//! The most expensive stage and the stage of last resort. This crate
//! defines the trait surface and ships an `EchoBackend` for testing.
//! Production deployments wire in real backends (llama.cpp, Ollama,
//! Anthropic API, Triton, vLLM, etc.).
#![forbid(unsafe_code)]
use async_trait::async_trait;
use eoc_cache::Stage;
use eoc_core::{JouleCost, Query, Response, Stage as StageKind};
/// A pluggable neural inference backend.
#[async_trait]
pub trait NeuralBackend: Send + Sync {
/// Run inference for `q` and return a `Response`. Backends are
/// expected to attach the most accurate joule cost they can compute;
/// the cascade will trust whatever value is reported.
async fn infer(&self, q: &Query) -> Response;
}
/// Synthetic backend used for tests and demos. Echoes the prompt back
/// with a configurable joule cost.
pub struct EchoBackend {
/// Estimated cost in micro-joules per inference.
pub estimated_microjoules: u64,
/// Optional prefix added to the echoed payload.
pub prefix: String,
}
impl EchoBackend {
/// Construct an `EchoBackend` with a default prefix and synthetic cost.
pub fn new() -> Self {
Self {
estimated_microjoules: 50_000_000, // 50 J — order-of-magnitude
prefix: "echo: ".to_string(),
}
}
/// Set the estimated cost.
pub fn with_cost(mut self, microjoules: u64) -> Self {
self.estimated_microjoules = microjoules;
self
}
/// Set the prefix.
pub fn with_prefix(mut self, prefix: impl Into<String>) -> Self {
self.prefix = prefix.into();
self
}
}
impl Default for EchoBackend {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl NeuralBackend for EchoBackend {
async fn infer(&self, q: &Query) -> Response {
Response::new(
q.id,
format!("{}{}", self.prefix, q.prompt),
StageKind::Neural,
JouleCost::estimated(self.estimated_microjoules),
)
}
}
/// The neural stage adapter — wraps any `NeuralBackend` as a `Stage`.
///
/// The neural stage *always* returns `Some` — it is the bottom of the
/// cascade and the answerer of last resort.
pub struct NeuralStage {
backend: Box<dyn NeuralBackend>,
}
impl NeuralStage {
/// Wrap a backend.
pub fn new(backend: Box<dyn NeuralBackend>) -> Self {
Self { backend }
}
}
#[async_trait]
impl Stage for NeuralStage {
async fn try_resolve(&self, q: &Query) -> Option<Response> {
Some(self.backend.infer(q).await)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn echo_backend_echoes() {
let backend = EchoBackend::new().with_cost(123).with_prefix("> ");
let stage = NeuralStage::new(Box::new(backend));
let q = Query::new("hello");
let r = stage.try_resolve(&q).await.expect("neural always answers");
assert_eq!(r.payload, "> hello");
assert_eq!(r.stage, StageKind::Neural);
assert_eq!(r.joule_cost.microjoules, 123);
}
}