arcature 2026.2.1

Arcature application framework: a high-level Application facade over the certified Arcature subsystems, with the low-level Axum/Tower escape hatch preserved.
Documentation
//! AP2.1-8 realtime surface — first-class WebSocket + SSE in the facade
//! (PROGRAM.md §AP2.1-8, ADR-0006 §36).
//!
//! Typed wrappers over `axum::extract::ws` and `axum::response::sse` that
//! add the realtime safety core without a proprietary realtime protocol
//! and without a second application model. Raw `axum::extract::ws` /
//! `axum::response::sse` remain first-class escape hatches (AGENTS.md
//! §16); every entry point the wrappers use is a public, documented seam.
//!
//! # What this module owns
//!
//! * [`channel`] — a typed in-process broadcast channel (bounded buffer,
//!   typed lag/closed/full errors, live-subscriber tracking). The fan-out
//!   core shared by WS and SSE.
//! * [`origin`] — a server-side origin policy for upgrade requests (the
//!   safe default rejects all; the application lists its origins).
//! * [`registry`] — a live-connection registry for drain, app-owned (not a
//!   process-global singleton; AGENTS.md §20).
//! * [`shutdown`] — the shared drain signal the WS/SSE endpoints and the
//!   registry use to coordinate graceful shutdown.
//! * [`websocket`] — a typed WebSocket wrapper: explicit authorization
//!   (channel names never implicitly authorize), origin policy,
//!   connection limits, frame/message size limits, bounded-buffer
//!   backpressure, heartbeat, graceful shutdown, tracing spans, typed
//!   protocol errors. Raw `axum::extract::ws` preserved.
//! * [`sse`] — a typed SSE event-stream wrapper: backpressure, graceful
//!   shutdown, tracing, typed outcomes. Raw `axum::response::sse`
//!   preserved.
//! * [`error`] — typed realtime errors; no raw `String`, no
//!   attacker-controlled bytes in `Display`.
//!
//! # What this module does not own
//!
//! No distributed pub/sub platform (Redis/Valkey `PUBLISH`, NATS) — the
//! server owns an explicit in-process broadcast per channel; distributed
//! fanout is deferred (PROGRAM.md §AP2.1-8: "start concrete, traits only at
//! natural seams"). No proprietary realtime protocol, no `X-Arcature-*`
//! headers, no page protocol (AGENTS.md §15). The server does not own
//! client reconnect; the contract is documented per endpoint. No UAG-
//! generated frontend helpers this wave (deferred until the master
//! coordinates the `arcature-build` codegen).
//!
//! # Ownership
//!
//! A [`channel::Broadcast`], a [`registry::Registry`], and a
//! [`shutdown::ShutdownConfig`] are built once and stored in `AppState`
//! (or resolved via a typed service). The realtime module keeps no hidden
//! global channel or connection registry — every value is app-owned and
//! request-explicit (AGENTS.md §20). The shutdown seam is self-contained:
//! the application flips `ShutdownConfig` to draining and calls
//! `Registry::drain`; it does not edit `application::shutdown` this wave.
//!
//! # Security note — attacker-facing
//!
//! Realtime endpoints are attacker-facing (PROGRAM.md §AP2.1-8 / AGENTS.md
//! §11). The wrappers enforce: origin policy (server-verified same-origin
//! default), explicit per-connection authorization (channel names never
//! implicitly authorize), connection limits (no unbounded connections),
//! frame/message size limits (no unbounded frames), bounded-buffer
//! backpressure (no unbounded per-client queueing), malformed-message
//! rejection (typed close, no panic), cleanup on disconnect (guard drop
//! decrements live counts, no orphaned tasks), and graceful drain. No
//! payload bytes appear in tracing spans (observe spec §53/§59).

pub mod channel;
pub mod drain;
pub mod error;
pub mod origin;
pub mod registry;
pub mod shutdown;
pub mod sse;
pub mod websocket;

// Minimal public re-exports (the crate root re-exports the primary surface
// behind the `realtime` feature; submodule paths remain the canonical
// location). Re-exporting here keeps the module self-contained for
// qualified use (`arcature::realtime::Broadcast`).
pub use channel::{Broadcast, ChannelPayload, Subscription};
pub use drain::drain;
pub use error::{ChannelError, ProtocolHint, RealtimeError, admission_status};
pub use origin::{OriginDecision, OriginPolicy, VerifiedOrigin};
pub use registry::{ConnectionGuard, Registry};
pub use shutdown::ShutdownConfig;
pub use sse::{SseEndpoint, SseLimits};
pub use websocket::{AllowAll, Authorizer, WebSocketEndpoint, WsLimits};