PatrickFanella 18903fb9fe
template-check / checks (application) (push) Successful in 5m59s
template-check / checks (qualification) (push) Successful in 9m43s
template-check / checks (race) (push) Successful in 6m40s
template-check / verify (push) Successful in 4s
template-check / Build frontend and deploy NUC (push) Successful in 30s
Merge pull request 'feat: preview saved command migration from canonical snapshots' (#355) from feat/command-migration-preview into main
Reviewed-on: #355
2026-11-08 14:40:54 -06:00
2026-06-10 17:49:44 -05:00
2026-06-10 17:49:44 -05:00
2026-06-10 17:49:44 -05:00

Over-Laid

Overlaid: a tally lamp mark, a rounded overlay card offset over a second card with a lit red circle in its top corner, beside the name Overlaid

An OBS operator desk with Twitch chat automation, broadcast overlays, and a Newsroom for preparing and running reaction streams.

Over-Laid brings stream controls, bot commands, editorial preparation, and show notes into one dashboard. It runs as a self-hosted application; the same codebase includes account-owned workspaces for managed installations.

Development status — October 19, 2026: the operator desk, Newsroom rebuild, and account/tenant foundations are implemented. Durable Twitch chat dispatch and sending are available through explicit configuration. Retained moderation is available through an explicit configuration opt-in, with saved operator/nuke requests, automatic-rule integration and persisted downgrade guards. The broader multi-platform service and first named self-hosted release remain unfinished. See current capabilities and limits for the distinction between implementation, activation, and live acceptance.

Getting started · Documentation · Newsroom guide · Roadmap · Contributing

What you can do

  • Operate a stream: check readiness, switch OBS scenes, control inputs and scene items, run quick actions/sequences, and manage BRB screens from the desk.
  • Review an OBS fallback: configure a missing-input rule, replay its evidence, explicitly approve a scene or override, and recover its original receipt in a managed self-host workspace.
  • Use OBS browser sources: alerts, chat, goals, ticker, now-playing, camera frame, starting/BRB/ending screens, Newsroom cards, and a setup inspector. Every overlay has an offline ?demo=1 preview.
  • Manage Twitch chat: custom commands and replies, timers, counters, quotes, API variables, moderation rules, nuke planning, and channel-point reward workflows.
  • Prepare and run a reaction show: collect audience links and questions, triage a moderator queue, arrange the reaction deck and segments, keep shelves for later, coordinate reviews, and save play-note snapshots.
  • Publish show material deliberately: export notes and chapters, preview confirmed Discord deliveries, and publish independently revocable public episode pages or shared shelves.
  • Keep workspace data scoped: account sessions, member roles, encrypted provider credentials, retention, exports, and deletion controls for PostgreSQL-backed installations.

Twitch and OBS controls need their respective connections and permissions. Newsroom enrichment, related coverage, playlist metadata, and Discord delivery require optional providers described in the Newsroom guide. AI analysis and fresh Newsroom chat entries start disabled.

Newsroom is part of the app

Open /dashboard/newsroom for the editorial desk and /overlay/newsroom for its broadcast card. Newsroom uses Over-Laid's existing accounts, workspace storage, Twitch connection, and overlay credentials. Its chat actions are editable entries in Chat → Bot commands; there is one shared command registry and dispatcher.

The workflow includes named shows and recordings, review claims and conflict drafts, story bundles, preparation templates, archived-show search, carry-forward shelves, audience questions, raffles, and saved show exports. The optional browser extension adds links using a separate revocable add token. Pinned upstream provenance records the source and MIT attribution.

Try it locally

For the container path, install Git, Docker, and Docker Compose. The images build the application, so a host Go/Node toolchain is only needed for native development and verification.

git clone https://git.subcult.tv/subculture-collective/overlaid.git
cd overlaid
cp .env.example .env

Edit the private .env before starting:

  1. Set different POSTGRES_PASSWORD and OVERLAID_DATABASE_PASSWORD values. Use URL-safe values, and update the password embedded in DATABASE_URL to match the runtime password. Keep the overlaid_app runtime user in that URL.
  2. Leave DEPLOYMENT_MODE=selfhost, EXPOSURE_MODE=local, and both TWITCH_CHAT_*_MODE settings at legacy for a first local evaluation.
  3. Before connecting Twitch or saving provider keys, generate a private vault key with openssl rand -base64 32, set VAULT_ACTIVE_KEY=v1, and set VAULT_KEYS=v1:<generated-key>. Keep the key with your private backups.

Then start the stack:

docker compose up --build -d
docker compose ps

Open the dashboard, Newsroom demo, or an overlay demo. The default API port is 8080; PostgreSQL is published on 55432. Repository access is required if your Git host restricts this repository.

Fresh PostgreSQL volumes apply all checked-in migrations and create a separate non-owner runtime login. Existing volumes require the migration and recovery procedure; rebuilding an image does not migrate an existing database.

Compose publishes host ports, so use local evaluation settings only on a trusted machine/network. Before LAN or public use, follow the getting-started guide for credentials, HTTPS, and origin configuration. Sharing the repository does not require exposing a running instance or distributing credentials.

Find your way around

Page Purpose
/dashboard On-air controls, session tally, preflight, and recent events
/dashboard/scenes OBS scenes, inputs/items, approved missing-input fallbacks, quick actions, sequences, and rehearsals
/dashboard/chat General bot commands, timers, counters, quotes, moderation, and rewards
/dashboard/newsroom Editorial queue, reaction deck, shelves, shows, and notes
/dashboard/overlays Previews, browser-source URLs, display settings, and setup
/dashboard/health Readiness, recovery tools, EventSub diagnostics, and build information
/dashboard/settings Shared configuration, automation profiles, and integration settings
/dashboard/sessions Stream/rehearsal sessions, reports, exports, and history
/dashboard/account Workspace access, membership, credentials, retention, exports, and deletion

Public application routes include /privacy, /terms, and /status. Shared shelves and episodes use their own revocable capability URLs. /version is an API route exposing non-secret build metadata.

Overlay routes are /overlay/alerts, /overlay/chat, /overlay/goals, /overlay/now-playing, /overlay/ticker, /overlay/camera, /overlay/starting, /overlay/brb, /overlay/ending, /overlay/newsroom, and /overlay/debug. See the overlay reference for sizes and parameters. Use the Overlays page to copy a live source URL with its read-only credential; never put the operator secret in an OBS URL.

Deployment and integration status

Area Current boundary
Self-hosting One bootstrap workspace, operator-header authentication, optional PostgreSQL. Without PostgreSQL, only the file-backed subset is available.
Managed accounts PostgreSQL, forced row-level security, vault keyring, sessions, membership, plans, and lifecycle controls are implemented. Hosted requests require account authorization; the global operator secret does not grant access.
OBS fallback Managed self-host PostgreSQL, configured OBS, migration 0049 and a real configure-member session enable a versioned missing-input rule with explicit one-use scene approval. Hosted/file mode keep this execution path disabled. Operation and safe qualification distinguish fixtures from real OBS acceptance.
Twitch chat Legacy dispatch/sending remain the defaults. Retained dispatch and sending require explicit modes and separate restricted worker/pacing connections. See retained sender setup. Managed shutdown drains accepted audits before releasing product/controller ownership; see runtime cleanup.
Bot identities Broadcaster, tenant-owned, and explicitly delegated shared-identity custody/authorization are implemented. Shared execution uses a separate restricted pool; live identity/badge acceptance remains separate.
Conduit foundation An explicit read-only inspector validates app identity and reports one selected conduit’s shard metadata with bounded reads and fixed private-data exclusions. The explicit acquisition adapter supplies validated ephemeral app credentials with one-attempt uncertainty; a separate administrative custody store retains encrypted service credentials with revision checks and metadata-only receipts; the native overlaid-app-admin CLI lists metadata/receipts and revokes an exact revision. A separately restricted custodied inspector reads a selected conduit using an exact stored app revision, without client-secret access; the native overlaid-conduit-inspect CLI reports that observation for an explicit stored binding. Its explicit subscription mode observes selected-conduit subscription metadata through restricted custody while excluding private conditions and granting no route ownership. An explicit durable issuance API records one-use provider attempts and atomically installs successful results; unresolved attempts retain ownership and cannot replay. The native overlaid-app-admin issuance --request UUID command reads original status metadata without provider access. The separate overlaid-app-issue CLI explicitly prepares and executes original requests using private configuration. A separate conduit creation transport validates app identity around one non-replayable POST and returns fixed uncertainty or acknowledgement metadata; its standalone transport owns no durable state. The durable creation ledger adds separate metadata-only ownership, fixed original deadlines and one-use claims, with retained uncertainty. The explicit custody-bound creation API composes separate pools with fresh credential checks and the original committed claim; it has no application startup caller. The separate overlaid-conduit-create CLI explicitly prepares, reads status and executes original requests using dedicated private configuration. The inspector’s read-only inventory mode reports complete app-wide IDs/counts without selecting a conduit or changing uncertain ownership. A separate WebSocket shard assignment adapter validates one bounded non-replayable PATCH acknowledgement; the separate assignment ledger now retains original metadata and one-use claims without credentials or provider calls. The explicit custody-bound assignment API composes all three stores behind a required session guard, with fresh current credential and historical owner checks. The explicit initial session owner owns one socket and supplies that scoped guard with an original welcome deadline and bounded private notification sink. The explicit retained stream bridge admits the three reviewed stream kinds atomically across up to sixteen configured workspace scopes per subscription, binding input to its original active socket callback and holding every required local owner lease through commit. Application lease composition, chat ingress, reconnect handoff, persistent subscription mapping and runtime activation remain incomplete. Unresolved-issuance resolution, durable recovery, shard/subscription reconciliation and runtime activation remain separate.
Retained stream observations An authenticated read API exposes the latest retained lifecycle occurrence and channel metadata with original timestamps, current connection/entitlement/retention checks and no provider fetch or write. These are historical observations; Channel-update subscriptions share the retained lifecycle socket and automation opt-in; Newsroom → Shows and recordings displays these saved observations with original times, scoped refresh and a labeled demo. Engine/variable consumption remains separate.
Retained stream lifecycle Optional TWITCH_STREAM_DISPATCH_MODE=retained routes the existing Twitch online/offline callback through durable source/job admission and the fenced Newsroom worker. It requires retained chat ingestion, migration 0033 and a separate stream worker login. Default legacy keeps direct lifecycle handling. The cutover runbook covers controller ownership, readiness, persisted writer fences and stop/preserve rollback; live provider and load qualification remain.
Retained moderation Source-bound admission, pacing, typed execution, automatic-rule binding, ownership handoff, and shutdown are implemented for explicit construction. The operator/batch store, single-action HTTP/UI status and retained nuke HTTP preview/admission/status are implemented, including sealed snapshots and atomic radiation with zero-target occurrences that create no jobs. The Chat page saves exact nuke previews and unresolved request keys through tab reload, uses lookup-only status checks and reports mixed outcomes or radiation-only configuration separately. Explicit TWITCH_MODERATION_MODE=retained coordinates startup, readiness and persisted downgrade fences through the existing controller; legacy remains the default. Live/provider and broader load qualification remain.
Other platforms and product phases Kick, Discord bot operation, YouTube Live, the versioned automation engine, expanded media/loyalty, and billing remain roadmap work. Newsroom's Discord webhook export is a separate implemented integration.

Local tests, hosted CI, deployment, and live Twitch/OBS/provider acceptance are separate evidence. Finite simulated workloads do not establish full thousand-channel delivery capacity or a production release. Follow the current roadmap and architecture decisions for the remaining scope.

Development

The versioned engine is under development. Its managed foundations include immutable versions, captured predicate/variable evaluation, reproducible weighted/no-repeat random flow, effect-free retained operator rehearsal, immutable metadata traces and explicit operator run/cooldown admission. Managed installations expose the session-bound workspace metadata API for these operations, including bounded automation/version discovery and saved-trace metadata discovery for an original operator occurrence. The OBS missing-input consumer owns its narrow versioned rule, approval and shared OBS mutation path; general graph execution remains under development.

An explicit captured chat-text rehearsal now composes pure flow traversal with syntax-2 rendering and strict chat text/batch bounds. The managed operator API exposes a separate read using the original retained database clock, explicit syntax 2 and an exact expected version. Missing user/provider values and randomness refuse completely. Existing dashboard flow and saved traces retain opaque arguments; this API sends no messages.

An explicit retained chat-effect source store prepares one immutable run-bound plan with original deadline and stable step IDs. Its private text follows member/run/connection/retention deletion; hash-only markers prevent recreation after deletion. An explicit atomic admission store can now commit all prepared effects to the existing outbound ledger and jobs, preserving original deadlines and no-recreation markers. A read-only original-request lookup returns bounded delivery metadata without retrying or repairing work; authenticated clients can use the lookup-chat-admission automation endpoint. An explicit application admission operation now binds new work to the existing retained controller and live tenant runtime. The authenticated admit-chat-plan endpoint can submit an already prepared plan through that owner; preparation and read-only plan lookup are available through the account API; the dashboard rehearsal panel can prepare a plan and recover it by original request. The same panel can queue a reviewed plan for delivery and check its outcomes by original request.

Prepare → Automations provides an advanced JSON version desk with scoped drafts, validation, publication, current-version selection, bounded saved-root and draft-to-current comparison and unresolved-write recovery. Its operator rehearsal panel prepares stable retained requests, admits metadata explicitly and inspects original/current effect-free flow. The separate trace controls save fixed metadata and recover an uncertain save through reads of its original identity. An explicit source-bound history view lists earlier saved selections and opens their verified metadata without changing recovery handles. The graphical flow editor, trusted stream limits, effect execution and source migration remain open under Phase #25.

The saved-command migration preview reads the canonical Chat registry and compares selected ticker/alert responses with syntax 2 using supplied sample values. It preserves saved aliases and policy metadata, refuses stale selections and identifies Newsroom actions as separate editorial work. Preview does not change command execution or select an engine version.

The backend uses Go 1.26 (go 1.26.0 in the module); the frontend uses React 19, TypeScript, Vite 7, and Tailwind 4. The web build image uses Node 24; web/package.json selects pnpm 10.33.0. PostgreSQL 17 and Docker Compose provide the container setup. See stack and configuration.

make verify

This installs locked frontend dependencies, checks formatting/types, vets Go, runs backend/frontend tests, builds binaries/assets, validates Compose, and checks the preserved Open Pilot template. PostgreSQL integration tests skip unless OVERLAID_TEST_DATABASE_URL points to a disposable database.

For the complete database/race gate with an owned disposable PostgreSQL container:

GOTOOLCHAIN=go1.26.0 bash scripts/ci-postgres.sh

The gate runs at most two Go packages concurrently against its shared fixture. Hosted CI runs three required phases: application runs make verify except six large HTTP qualification fixtures, race runs the remaining uncached application races and River spike races, and qualification runs those six fixtures normally and with the race detector. The phases run serially with separate disposable databases; all must pass before the verify check or frontend delivery can succeed. Run a phase locally by passing its name to the script; no argument runs the complete unpartitioned gate. Each package invocation keeps its 15-minute watchdog, each hosted job keeps its 35-minute bound, and operation deadlines stay unchanged.

The fixture defaults to a bounded 2 GiB tmpfs with a 256 MiB WAL checkpoint target; select OVERLAID_CI_POSTGRES_STORAGE=volume for a disk-backed comparison. It cleans up its own container/volumes. These checks do not qualify power-loss durability. Contributing describes native development and verification.

Operations and documentation

/healthz is cheap process liveness. /readyz must be checked by its JSON result: HTTP 200 can still report degraded readiness. make build includes over-laid-probe; monitoring guidance explains selecting required checks.

Security and license

Keep .env, tokens, vault keys, add/share URLs, and backups private. Use placeholders when sharing configuration. Report vulnerabilities through the private process in SECURITY.md.

Over-Laid is GPL-3.0-only; see LICENSE. It was created from subculture-collective/project-template. Vendored/rebuilt components retain their own notices in Newsroom provenance and River provenance. Copied overlay brand assets have a separate provenance record.

Automatic frontend delivery connects verified main CI to the existing NUC web service. Backend and managed-runtime release/qualification gates retain their separate procedures.

Languages
Go 75.4%
TypeScript 21%
PLpgSQL 2.5%
CSS 0.6%
Shell 0.2%
Other 0.2%