burstdocs
DEVELOPERS / Core concepts

BurstMedia engineering plan

Status: proposed implementation sequence, 2026-10-29. The public site is an informational surface; media delivery is not implemented. Read with SPEC.md. This plan extends the original STBS-only proposal to free content and shared BurstPay commerce.

Product and ownership

Publish video, music, podcasts, images and downloadable multimedia collections. A release binds immutable resources, accessible descriptions/captions, rights, a license and an access mode. Free public, free signed-in, private, preview and paid are distinct modes; discovery visibility never grants private source access. Anonymous delivery requires explicit publication and a narrowly scoped public policy, without granting an anonymous caller general space access.

SurfaceResponsibility
goburst.mediaPublic discovery, creator information and eventually public release pages/playback
goburst.appExisting OIDC account, creator studio, purchases, private library and operations
goburst.devAPI, player integration, deployment and engineering documentation
goburst.networkEcosystem and network architecture
DesktopShared web UI in a proposed Tauri wrapper; capabilities restricted to required native commands

Start browser-first. Add installable PWA behavior after playback works. Add signed desktop builds when OS-specific playback, system-browser login, deep links and secure credential storage pass acceptance. Desktop uses a public OIDC client with PKCE or a reviewed one-use account handoff; it must not copy browser cookies or embed client secrets. Keep remote creator content outside privileged desktop IPC. Online authority remains required for protected playback initially; offline licenses are separate future work.

Technology and delivery path

Use the existing Go control host for media metadata, sessions and authorization, with separate bounded processing workers and a streaming delivery gateway. Reuse the current JavaScript/CSS interface and self-hosted fonts. PostgreSQL is the proposed production metadata store, SQLite the local option. Existing authority transactions serialize operations; benchmark that constraint before claiming concurrent production scale. Keep media bytes, transcoding and provider HTTP calls outside long metadata transactions.

Start HLS with fragmented MP4/CMAF, H.264/AAC video, AAC audio and WebVTT captions. Use native HLS when available and hls.js otherwise; detect support and offer an explicit unsupported state. Offer authorized originals and image derivatives separately. Propose 360p/720p/1080p profiles capped at source size and 4-second segments; benchmark before fixing the ladder. Pin FFmpeg builds, record codec/profile versions and run ffprobe/FFmpeg inside the bounded worker. Validate actual output, duration and checksums; reject playlist references or attachments that could cause external fetches. No ambient worker egress.

Flow: encrypted upload → asset validation → durable job → fenced worker → verified encrypted renditions → immutable release → session authorization → bounded gateway streaming → durable usage → BurstPay reconciliation.

The existing object-read implementation is not automatically a seekable streaming store. First prove bounded memory and authenticated chunk/range reads; add an adapter before exposing large media. Keep encrypted replicas/caches distinct from explicitly trusted plaintext-serving gateways. No public plaintext cache for paid objects. Gateway sessions map only to approved rendition resources; rewrite manifest references, including keys and initialization segments, into guarded routes.

Serve paid playback initially on goburst.app with its existing host-only session. goburst.media links there. Later anonymous/public playback can use explicitly public delivery routes; embedded paid playback needs a separate reviewed ticket/origin design. Do not widen cookies across domains. The current static-site CSP intentionally cannot play remote media; update media-src/connect-src only when real delivery is integrated.

Shared commerce contract

BurstMedia owns releases, license acceptance, access eligibility, entitlements and delivery sessions. BurstPay owns offers/quotes, provider attempts, orders, refunds, ledger and payouts. Preserve media-specific quote commitments and STBS escrow semantics through a versioned payment adapter. Do not build a second ledger or let payment override policy.

Current blockers found in code: checkout in burst/internal/control/commerce.go loads a dataset request; stripeWebhook routes all verified payments to datasets.ApplyPayment. burstpay.NewOrder requires a product request but has no typed product binding. Extend these with a validated product kind, release/license/version commitment and product settlement dispatcher. Preserve existing dataset behavior and tests. Payment application, entitlement update and outbox must share one host transaction; delayed/duplicate refunds must never resurrect access.

ModelSequence and dependency
Free publication and previewsFirst vertical slice; no wallet or payment configuration
One-time purchase/rental and bundlesShared BurstPay; Stripe test acceptance first, STBS after finality indexer acceptance
Subscriptions/membershipsExplicit paid periods, expiry, cancellation and renewal failure policy
TipsSeparate receipt; never silently grant a content license
Metered consumptionTrusted usage, versioned rates, spending caps and invoice reconciliation
Advertising/sponsorshipLater: inventory, consent, fraud controls and independently reconciled impressions
Creator revenue splitsVersioned recipient shares, deterministic rounding, refunds and provider-supported payouts

Operator-owned test sales can use existing Stripe foundations. Third-party creator cash payouts need seller onboarding and Connect (or another explicit payout provider); current gross ledger credits are not withdrawable proceeds. Fiat and STBS remain separate assets and ledgers. No automatic exchange rate or conversion.

Metering that can support money

Separate operational telemetry, estimated audience analytics and billable facts. Client play/pause/heartbeat events help QoE but never independently generate invoices, ad revenue or rewards. Server bytes mean bytes handed to the transport, not proof a human watched them.

MeterTrusted boundaryBilling treatment
Storage byte-hoursDurable object inventory over timeCreator hosting cost; distinguish replicas from logical bytes
Processing millisecondsWorker result with fenced attempt/profileCount physical retries as operational cost; charge logical successful job once unless terms explicitly differ
Egress bytesGateway write accountingOperational cost includes retransmission; viewer charges use the explicit logical-range rule below
Unique prepared segment bytesDurable reservation before responseConservative quota only; not proof of delivery
Playback secondsClient reports plus server diagnosticsAnalytics estimate initially; no watch-time billing
Payment and revenueVerified BurstPay settlement/refundPer currency, order and immutable fee/split version

Each usage fact binds tenant, producer, session, release/rendition revision, resource, range, logical operation ID, unit, quantity, occurrence time, price revision and correction reference. Producer identities are authenticated. Never store bearer session secrets in metrics labels. Persist immutable facts and a deduplicated outbox; enforce unique producer/meter/event identities and reject conflicting replays. Keep financial dimensions out of high-cardinality Prometheus labels; use indexed usage tables/rollups.

Reserve bounded byte/spend quota before each response window. Record actual gateway writes afterward; a crash leaves an unresolved reservation, not invented delivered bytes. Reconcile it conservatively for quota and hold disputed usage out of invoices. Stop new billable windows when durable accounting fails or unreported-usage caps are reached. A single whole-file reservation is insufficient for long downloads. Do not write every packet into the control authority transaction.

Proposed viewer-byte billing counts the union of authorized byte intervals per logical playback, resource version and billing period, so overlapping ranges/retries do not double-charge. A new logical playback can be billed separately only under disclosed terms. Gateway-generated attempt IDs record transport attempts; server-issued playback IDs define logical deduplication. Price changes never alter an active price snapshot. Define UTC periods, late-event cutoff, retention covering reconciliation, invoice finalization and append-only corrections before activation. Provider ingestion is asynchronous; reconcile provider totals against internal rollups.

Performance budgets and capacity

These are proposed acceptance targets, not measured results: warm session creation p95 ≤150 ms; warm segment time-to-first-byte p95 ≤100 ms in-region; playback startup p95 ≤2 seconds on a controlled 20 Mbps/50 ms RTT link; rebuffer ratio <1%; active authorization staleness ≤60 seconds. Report cold startup separately. Long downloads need periodic authority checks and cancellation by that deadline. Missing fresh authority denies further protected delivery.

First load gate: 100 concurrent 3 Mbps viewers for 30 minutes, including seeking, slow readers, invalid sessions and revocation. This is 300 Mbps payload and approximately 135 GB/hour decimal egress before overhead. At 1,000 viewers it becomes 3 Gbps and 1.35 TB/hour. Record hardware, rendition mix, cache hit rate, DB wait/lock time, CPU, RSS, queue depth, errors and p50/p95/p99. Memory must scale with configured stream buffers/concurrency rather than object size. Derive cost per watched hour from egress, storage, processing and payment fees before setting prices.

Keep payment providers and Ethereum off the segment request path. Begin with one regional gateway and bounded caches. Scale gateways only after shared quota, revocation and usage consistency pass multi-instance tests. Adopt a broker or analytical store only when measured outbox/rollup load needs it.

Build sequence and acceptance

PhaseConcrete resultRequired evidence
0Module, scoped records, access modes and shared payment bindingSQLite/PostgreSQL parity, current authority on retries, tenant denial, immutable versions, existing commerce regression
1Upload → actual transcode → free authenticated playback/downloadReal FFmpeg fixture, hostile/truncated input rejection, sandbox bounds, fenced crash recovery, durable outputs, browser seek/caption playback
2Durable meters and quotasDuplicate/overlapping range tests, abort/crash reconciliation, accounting outage denial, cap concurrency and 100-viewer load report
3One-time purchase → entitlement → playback → refundProduct-dispatched Stripe test flow; STBS separately proves indexer finality/reorg/replay/refund; no private source bypass
4Creator studio, public releases, library and desktopKeyboard/mobile/browser matrix, real OIDC, anonymous public boundaries, signed desktop/package/update acceptance
5Subscriptions, creator payouts and advanced monetizationPaid-period renewal failure, provider reconciliation, recipient/refund splits, seller onboarding and invoice corrections
6Production acceptanceBackup/restore with deletion replay, custody rotation, queue/disk exhaustion, recovery drills and recorded capacity/cost

Every phase must introduce an executable gate and record actual results before completion. Proposed gate names: scripts/test-media.sh for domain/integration, scripts/test-media-processing.sh for real sandbox work, and scripts/load-media.sh for reproducible capacity. These commands do not exist yet. Existing scripts/test-commerce.sh remains the shared regression gate.

Next implementation: phase 0 plus phase 1 free playback. It exercises the hardest delivery path before charging anyone. Economic activation requires explicit fee/refund/seller configuration; free playback development can proceed independently.

Technology references

Built from burstmedia/PLAN.md in the Burst Kit workspace. Check implementation status before deployment.

Search the documentation