bmux_presenter_runtime 0.0.1-alpha.4

Authoritative presentation host and bounded TLS participant transport
docs.rs failed to build bmux_presenter_runtime-0.0.1-alpha.4
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

bmux_presenter_runtime

Application-owned authoritative presentation engine, shared by standalone and BMUX-managed deployments. This crate adds no presentation domain behavior to core. Plugin implementations call Host and expose generated BPDL operations; the protocol messages here are exclusively the standalone TLS transport contract.

Stable integration API

  • Host::new(Deck, Vec<Asset>, HostConfig) validates a bundle and starts a new run.
  • Credential::generate(Scopes, Duration), Host::add_credential, and Host::revoke_credential establish private run-local principals. Store secrets privately. Reconnect always authenticates again; a participant ID is not a secret.
  • Host::authenticate(version, secret, mode) creates a participant; disconnect releases connection resources. Independent views retain state and committed surfaces per private credential across reconnect, with one connected independent view per credential. Issue separate credentials for distinct views. next_action_id returns the next credential sequence number. Multiple devices sharing a credential share ordering.
  • snapshot explicitly bootstraps/resynchronizes any authorized participant, including submit-only. poll returns unchanged cursors or complete bounded snapshots; submit-only has no ongoing polling subscription. No streaming API is assumed. Public read-only audience access requires public_audience: true.
  • submit(Submission { action_id, expected, action }) enforces mode, scope, run/deck/state cursor, rate, payload bounds, and committed surface geometry. Private navigation/demo/effect scopes are independent of speaker-note access.
  • asset distributes only audience-referenced opaque resources in bounded chunks.
  • reload validates the replacement bundle, then calls Owner::prepare_reload(&self, &Deck, &[Asset]) -> Result<Box<dyn Owner>, HostError> on the live owner with the new validated owner-local assets. The returned candidate must be isolated: retain values only for matching (block ID, linked component type, state version), with no mutable handles shared with the active owner. Owner::reconcile_reload(&mut self, OwnerContext) -> Result<Vec<MirrorFrame>, String> rebuilds all shared, connected independent and retained independent geometry on the candidate before publication. It defaults to scene; prepare_reload defaults to Invalid, preserving source compatibility without inventing cloning. reload_with_owner(deck, assets, Box<dyn Owner>) still accepts an app-prepared candidate directly. Any preparation/scene failure preserves the active owner, deck, assets, navigation, cursors and committed surfaces; no effects replay.
  • Host::set_owner(Box<dyn Owner>) -> Result<(), HostError> prepares and validates initial shared and connected independent scenes before installing the owner. Owner::scene(&mut self, OwnerContext) -> Result<Vec<MirrorFrame>, String> defaults to empty and is projection-only: it must never invoke effects. The host calls it on independent join and navigation, not on polling or viewer resize. Reload uses the candidate-only reconcile_reload hook (defaulting to scene). A reload owner must already understand the replacement deck identities; otherwise projection fails and the host retains the old bundle. Callback diagnostics are not exported. MirrorComponent::new validates a borrowed scene and implements the canonical layout/paint/event/revision lifecycle; map input using its exact successfully committed LayoutNode with input_point.
  • Owner is trusted linked Rust. OwnerContext.instance is shared for shared ordering and credential-local for independent instances across reconnect. OwnerUpdate returns a bounded outcome and complete committed public surface batch. Never render private notes into audience surfaces. Generic viewers never activate Rust code.
  • commit_surfaces publishes owner-committed structured BMUX scene captures. MirrorFrame::capture accepts a BMUX Frame plus reconciled ImageScene; MirrorFrame::paint reconstructs through PaintCx, not ANSI. placement and CanvasPlacement::input_point clip/letterbox the fixed owner canvas. Publish input geometry only after successful viewer presentation. Input includes the run/deck/state cursor and committed surface revision.
  • SourceLoader::{load_markdown, prepare} accepts bounded local Markdown or linked decks, reads images beneath an explicit canonical root, normalizes image payloads, and invokes WasmMermaidRenderer (never the native renderer). Supply the embedded renderer and call source preparation outside the live host lock. WASM enforces timeout/memory/concurrency limits without a helper executable. Building this crate requires wasm32-unknown-unknown.
  • transport::{serve_tls, serve_local} accept owned Tokio listeners, shared host, bounded network settings, and watch-channel shutdown. TLS config helpers parse bounded explicit PEM chains/keys/roots. Local plaintext requires loopback on both sides; remote TLS verifies certificate roots and server name.
  • transport::Client::{connect_tls, connect_local, authenticate, request} provides one bounded in-flight exchange, no automatic replay, and poisons interrupted connections. Snapshot decode validates mirror scenes before exposing them.

Delivery and privacy semantics

Action IDs start at 1 and increase per credential, surviving reconnect within a live run. Retained identical submissions return their original success/error; changed retained payloads return ActionConflict. IDs below the high-water mark that have been evicted return OutcomeEvicted, never execute again. After eviction clients must fetch authoritative state and explicitly reconcile external outcomes; this is not durable exactly-once execution. A new host run has fresh identity and requires explicit new actions. Never replay uncertain effects into a new run. Owner calls consume the state revision before execution, even when their outcome is uncertain. Polling/snapshots never invoke effects. The owner must return only public, bounded outcomes; private external diagnostics should stay owner-local.

The audience projection strips notes, source locations, custom configuration, extra metadata, Markdown link destinations/titles/references/autolinks and raw HTML. Markdown stays rich: source-range edits preserve shared renderer syntax for inline styles, lists, tables, code, math and footnotes; unsafe syntax exposed by reparsing fails closed. Inline and block images use only authorized opaque asset IDs; unreferenced assets are not served. Only exact light/dark theme names survive; unknown names reject preparation. The local loader normalizes inline image assets under the same bounded root policy as block images. Standalone transport version 2 explicitly selects these richer projection semantics; version 1 authentication is rejected. Plugin BPDL compatibility must be selected by the owning plugin; these standalone messages are not plugin IPC. Visible authored labels, code, Mermaid content, titles, authors, IDs, and custom names are public content: authors must not put secrets there. Custom configuration is never activated from an audience deck. Notes are a separately scoped field.

Limits cover messages, decks/notes, assets/cache bytes, frame/canvas/image decoded sizes, surfaces, principals, participants, action retention, action size, request rates, connections, handshake/read/write deadlines. Networking retains one request per connection and uses bounded admission rather than unbounded queues. Owner callbacks are synchronous trusted application code and must not block or spawn unbounded work; asynchronous demo lifecycle management belongs to the application.

Validation/handoff

Behavior tests cover auth/modes, private wire projection, shared/independent state, reconnect action dedup and uncertainty, eviction, atomic reload, malformed mirrors, all style bits, clipped placement, real loopback TCP and TLS certificate validation. Follow-up coverage adds rich Markdown privacy/opaque inline images, immutable candidate preparation, compatibility-key retention/reset, shared/live/cached instance reconciliation, unknown theme and oversized asset atomicity, slow peer timeouts and snapshot resync. Existing uncertain-effect reconnect/eviction coverage is retained. Focused rustfmt and source/diff inspection only were run in this lane; all cargo builds, clippy, tests and dependency validation belong to the coordinator. The bmux present command/plugin adapters belong to their assigned integration lane.