open-standards/openpay/crates/op-orchestrator/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

102 lines
4.7 KiB
Rust

//! # `op-orchestrator` — Cross-rail payment orchestration
//!
//! Coordinates the OpenPay stack into an end-to-end flow:
//!
//! ```text
//! PaymentIntent
//! │
//! ▼
//! ┌──────────────────────────────────────────┐
//! │ 1. Idempotency check (in-process cache) │
//! ├──────────────────────────────────────────┤
//! │ 2. Fraud scoring (op-fraud) │
//! ├──────────────────────────────────────────┤
//! │ 3. Routing (Router trait) │
//! │ decide rail order and retry budget │
//! ├──────────────────────────────────────────┤
//! │ 4. Attempt loop │
//! │ • call rail (op-rails-card / a2a) │
//! │ • classify outcome (Final/Retry/ │
//! │ Fallback) │
//! │ • on Fallback: next rail w/ SAME │
//! │ idempotency key │
//! │ • on Retry: backoff + same rail │
//! │ • circuit breaker per (rail, psp) │
//! ├──────────────────────────────────────────┤
//! │ 5. Persist terminal state │
//! │ future-replay of the same intent │
//! │ key returns the same outcome │
//! └──────────────────────────────────────────┘
//! │
//! ▼
//! OrchestrationOutcome
//! ```
//!
//! ## Why this lives outside the rail crates
//!
//! Each rail crate (`op-rails-card`, `op-rails-a2a`) knows how to
//! talk to its own backends. They do **not** know about cross-rail
//! fallback, fraud gating, or idempotency. Mixing those concerns
//! into the rail crates would create a circular dependency (fraud
//! needs to score a generic payment, not a card-specific one) and
//! would prevent operators from swapping in their own rail drivers
//! while reusing the orchestrator.
//!
//! ## Design rationale verified against industry practice
//!
//! - **Idempotency keys (UUIDv4/v7)** — Adyen / Stripe convention.
//! Same key carries across retries AND rail fallbacks. 7-day
//! minimum TTL per Adyen docs.
//! - **State machine** — payment is a workflow, not a record.
//! Stripe's interview prompt; valid transitions enforced.
//! - **Exponential backoff with jitter** — industry standard for
//! non-idempotent operations after timeouts.
//! - **Circuit breaker** — 5 consecutive failures → open for 60s
//! cooldown → half-open probe → close on success. Standard
//! resilience pattern.
//! - **No floats for money** — already enforced by `op-core::Money`
//! (i64 minor units).
//!
//! ## What this crate does NOT do
//!
//! - **No async runtime.** The orchestrator is sync, like the
//! acquirer traits it sits on top of. Async is an
//! integration concern; wrap with `tokio::task::spawn_blocking`
//! if needed.
//! - **No persistent idempotency store.** The default
//! [`InMemoryIdempotencyStore`] is for tests and short-lived
//! processes. Production deployments plug in their own
//! [`IdempotencyStore`] backed by Redis / Postgres / Spanner.
//! - **No webhook fanout.** Terminal outcomes are returned
//! synchronously; emitting webhooks is the caller's job.
//! - **No ledger.** The orchestrator returns outcomes; persisting
//! them into a double-entry ledger is downstream.
#![deny(unsafe_code)]
#![warn(missing_docs)]
pub mod adapters;
pub mod circuit_breaker;
pub mod engine;
pub mod error;
pub mod idempotency;
pub mod intent;
pub mod outcome;
pub mod router;
pub mod signals;
pub mod telemetry;
pub use adapters::{A2aAdapter, CardAdapter, CryptoAdapter, MerchantBankProfile};
pub use circuit_breaker::{CircuitBreaker, CircuitState, InMemoryCircuitBreaker};
pub use engine::{BackoffPolicy, Orchestrator, OrchestratorConfig};
pub use error::{Error, Result};
pub use idempotency::{
IdempotencyKey, IdempotencyRecord, IdempotencyStore, InMemoryIdempotencyStore,
};
pub use intent::{PaymentIntent, RoutingHints};
pub use outcome::{Attempt, AttemptOutcome, OrchestrationOutcome, TerminalStatus};
pub use router::{PolicyRouter, RailChoice, Router, RoutingDecision};
pub use signals::{
AttemptResultClass, NoOpRailTelemetry, NoOpRoutingSignals, RailTelemetry, RoutingSignals,
SignalCombiner, noop_signals, noop_telemetry,
};