Expand description
Sync-first runtime layer for batpak-family operation kits.
This crate is intentionally small at birth. It establishes the runtime layer boundary over batpak core without importing operation dialect, network, protocol-profile, or rendering semantics.
§Quick start
Build a Core, register one operation, invoke it synchronously.
use syncbat::{Core, EffectClass, Handler, HandlerError, HandlerResult, OperationDescriptor};
/// Echoes the input bytes back unchanged.
struct EchoHandler;
impl Handler for EchoHandler {
fn handle(
&mut self,
input: &[u8],
_cx: &mut syncbat::Ctx<'_>,
) -> HandlerResult {
Ok(input.to_vec())
}
}
const ECHO: OperationDescriptor = OperationDescriptor::new(
"echo",
EffectClass::Inspect,
"echo.request",
"echo.ack",
"receipt.echo.v1",
);
let mut builder = Core::builder();
builder.register(ECHO.clone(), EchoHandler).expect("register");
// `build()` fails closed without a receipt sink so receipts are never
// silently dropped; this example records none, so opt out explicitly.
builder.without_receipts();
let mut core = builder.build().expect("build");
let result = core.invoke("echo", b"hi".to_vec()).expect("invoke");
assert_eq!(result.output(), b"hi");§Runtime safety defaults
The runtime fails closed where silence would lose evidence:
CoreBuilder::buildrefuses to build without a receipt sink, because a sinkless core silently drops every runtime receipt. State the sinkless intent explicitly withCoreBuilder::without_receipts(used above), or configure one withCoreBuilder::receipt_sink.- Receipt input/output hashing defaults to
ReceiptHashPolicy::Blake3, so every recorded receipt binds to the exact bytes that produced it;ReceiptHashPolicy::Deferredis the explicit opt-out for a layer that hashes the bytes itself. - Capability tokens are enforced at checkout: a dispatched operation that
declares a required token the
Corewas not granted fails closed. Grant tokens withCoreBuilder::grant_capability/CoreBuilder::grant_capabilities. (Effect-axis tokens auto-declared by the effect builders are ambient and need no explicit grant.) - Every effect axis is an enforced boundary: an operation reaches an effect
only through the matching
Ctxcapability handle, which records it into the observed row in the same step, andcheckoutfails closed when the observed row is not a subset of the declared row.use_host_controlis a declared + subset-checked target axis like the read/append/query axes (observed host controls must be a subset of the declared targets), andemit_receiptstamps its opaque payload as observed evidence into the invocation’s single banked receipt only after the backend mediates the emission.
§Operation names
Operation names follow a stable grammar checked once by
OperationName::new. Downstream code never re-parses; passing a
plain &str to Core::invoke is fine, but pre-validating into
OperationName documents intent and removes per-call grammar
checks.
use syncbat::OperationName;
let name = OperationName::new("bank.commit").expect("grammar");
assert_eq!(name.as_str(), "bank.commit");
assert!(OperationName::new("bad..name").is_err());Re-exports§
pub use admission::AdmissionDecision;pub use admission::AdmissionGuard;pub use builder::CoreBuilder;pub use core::Checkout;pub use core::CheckoutFrame;pub use core::CheckoutResult;pub use core::Core;pub use core::CoreFactory;pub use core::Ctx;pub use effect::append_target;pub use effect::EffectIdentity;pub use effect::EffectIdentityError;pub use effect::EventAppendHandle;pub use effect::EventReadHandle;pub use effect::HostControlHandle;pub use effect::ObservedEffectViolation;pub use effect::OperationEffectRow;pub use effect::ProjectionReadHandle;pub use effect::ReceiptEmitHandle;pub use effect_backend::EffectBackend;pub use effect_backend::EffectError;pub use effect_backend::TypedEffectEvent;pub use error::BuildError;pub use error::ReceiptSinkHandlerCause;pub use error::RuntimeError;pub use handler::Handler;pub use handler::HandlerError;pub use handler::HandlerResult;pub use module::Module;pub use operation::DescriptorValidationError;pub use operation::EffectClass;pub use operation::OperationDescriptor;pub use operation::OperationInput;pub use operation::OperationOutput;pub use operation::OperationRegisterItem;pub use operation::MAX_DESCRIPTOR_REF_BYTES;pub use operation::MAX_OPERATION_NAME_BYTES;pub use operation_name::OperationName;pub use operation_name::OperationNameError;pub use operation_status::OperationStatusFactV1;pub use operation_status::OperationStatusLifecycle;pub use operation_status::OperationStatusView;pub use operation_status::SYNCBAT_OPERATION_STATUS_EVENT_KIND;pub use operation_status_sink::operation_status_entity;pub use operation_status_sink::OperationStatusSink;pub use operation_status_sink::OperationStatusSinkError;pub use operation_status_sink::StoreOperationStatusSink;pub use receipt::BatpakReceiptFields;pub use receipt::ReceiptEnvelope;pub use receipt::ReceiptExtensionDrawer;pub use receipt::ReceiptHash;pub use receipt::ReceiptHashPolicy;pub use receipt::ReceiptHasher;pub use receipt::ReceiptMetadata;pub use receipt::ReceiptOutcome;pub use receipt::ReceiptSink;pub use receipt::ReceiptSinkError;pub use receipt::RecordedReceipt;pub use receipt::SYNCBAT_RECEIPT_EVENT_KIND;pub use register::CacheRegister;pub use register::Register;pub use register::RegisterValidationError;pub use register_store::rebuild_register_from_store;pub use register_store::RegisterOperationActionV1;pub use register_store::RegisterOperationRowV1;pub use register_store::StoreRegisterCatalog;pub use register_store::StoreRegisterCatalogError;pub use register_store::SYNCBAT_REGISTER_EVENT_KIND;pub use store_effect::StoreEffectBackend;pub use store_sink::StoreReceiptSink;pub use store_sink::StoreReceiptSinkError;pub use subscription_runtime::cursor_invalid_error;pub use subscription_runtime::cursor_mismatch_error;pub use subscription_runtime::unknown_subscription_error;pub use subscription_runtime::CompositeSubscriptionRuntime;pub use subscription_runtime::EntityStreamCursorV1;pub use subscription_runtime::EntityStreamEnvelopeV1;pub use subscription_runtime::EntityStreamRouteBinding;pub use subscription_runtime::EntityStreamSession;pub use subscription_runtime::EventStreamCursorV1;pub use subscription_runtime::EventStreamEnvelopeV1;pub use subscription_runtime::EventStreamSession;pub use subscription_runtime::EventSubscriptionRuntime;pub use subscription_runtime::OperationStatusRouteBinding;pub use subscription_runtime::OperationStatusStreamCursorV1;pub use subscription_runtime::OperationStatusStreamEnvelopeV1;pub use subscription_runtime::OperationStatusStreamSession;pub use subscription_runtime::ProjectionStreamCursorV1;pub use subscription_runtime::ProjectionStreamEnvelopeV1;pub use subscription_runtime::ProjectionStreamSession;pub use subscription_runtime::ReceiptStreamCursorV1;pub use subscription_runtime::ReceiptStreamEnvelopeV1;pub use subscription_runtime::ReceiptStreamRouteBinding;pub use subscription_runtime::ReceiptStreamSession;pub use subscription_runtime::RuntimeCursor;pub use subscription_runtime::SessionControl;pub use subscription_runtime::SessionDelivery;pub use subscription_runtime::SessionEnd;pub use subscription_runtime::SessionError;pub use subscription_runtime::SessionEventDelivery;pub use subscription_runtime::SessionPoll;pub use subscription_runtime::SessionWatermarkDelivery;pub use subscription_runtime::SubscriptionId;pub use subscription_runtime::SubscriptionRegistry;pub use subscription_runtime::SubscriptionRoute;pub use subscription_runtime::SubscriptionRuntimeConfig;pub use subscription_runtime::SubscriptionRuntimeError;pub use subscription_runtime::SubscriptionSession;pub use subscription_runtime::SubscriptionSessionFactory;pub use subscription_runtime::SubscriptionStore;pub use subscription_runtime::TypedProjectionProjector;pub use subscription_runtime::CURSOR_V1_LEN;pub use subscription_runtime::ENTITY_STREAM_CURSOR_V1_LEN;pub use subscription_runtime::MAX_SUBSCRIPTION_ID_BYTES;pub use subscription_runtime::OPERATION_STATUS_CURSOR_V1_LEN;pub use subscription_runtime::PROJECTION_CURSOR_V1_LEN;pub use subscription_runtime::RECEIPT_STREAM_CURSOR_V1_LEN;pub use subscription_runtime::SOURCE_KIND_ENTITY_STREAM;pub use subscription_runtime::SOURCE_KIND_EVENT_CATEGORY;pub use subscription_runtime::SOURCE_KIND_OPERATION_STATUS;pub use subscription_runtime::SOURCE_KIND_PROJECTION;pub use subscription_runtime::SOURCE_KIND_RECEIPT_STREAM;
Modules§
- admission
- Pre-handler admission guard seam.
- builder
- Builder for the synchronous runtime composition root.
- core
- Synchronous runtime composition root.
- effect
- Declared and observed operation effect rows.
- effect_
backend - The runtime-owned capability backend that makes operation effects real.
- error
- Error types for the syncbat runtime shell.
- handler
- Synchronous byte-oriented handler contracts.
- module
- Data-oriented module descriptors.
- operation
- Generic operation metadata for syncbat handlers.
- operation_
name - Single validating constructor for syncbat operation names.
- operation_
status - Durable operation-status facts and event-sourced view state.
- operation_
status_ sink - Store-backed sink for durable operation-status facts.
- receipt
- Generic receipt envelope types for syncbat operation runs.
- register
- Durable-facing operation catalog and cache projection.
- register_
store - Batpak-backed durable register catalog rows.
- store_
effect - Batpak-backed
EffectBackendfor syncbat operation effects. - store_
sink - Batpak-backed receipt sink for syncbat receipt envelopes.
- subscription_
runtime - Store-backed subscription runtime (Packet C).
Enums§
- Syncbat
Receipt Namespace - Marker type for syncbat-owned receipt extensions.
Constants§
- SYNCBAT_
EXTENSION_ NAMESPACE - Receipt-extension namespace owned by the syncbat runtime layer.
Functions§
- receipt_
extension_ key - Construct a syncbat receipt-extension key.
- receipt_
extension_ value - Wrap already-encoded bytes as a syncbat receipt-extension value.
Type Aliases§
- Syncbat
Receipt Extension Key - Validated syncbat-owned receipt-extension key.
- Syncbat
Receipt Extension Value - Encoded syncbat-owned receipt-extension value.
Attribute Macros§
- operation
#[operation(...)]— generate a syncbat operation descriptor + optional registration fns. Re-exported assyncbat::operation; users never name this crate. (Moved here from the formersyncbat-macroscrate — the family has one proc-macro crate.)