Skip to content

Repository files navigation

goq.sh

Your key is the address. Plug in, tap, play.

goq turns one Linux machine into a personal Steam streaming appliance. You dedicate that machine to your games, plug in nothing but power and network, and play from another computer with a controller. The goal is the latency of sitting at the machine, not the latency of a screen-sharing tool.

goq is not a multi-tenant streaming service and not a desktop-sharing tool. It streams a private Gamescope session that exists only for your games: the host needs no monitor, no desktop environment, and no interactive login. Native MoQ admits three viewers by default, up to a hard ceiling of eight. Every viewer may watch according to its grants, while exactly one viewer at a time may hold slot-0 input focus. Legacy control/media clients remain strictly exclusive.

The two programs

  • Sigil is the host: a pure Rust daemon for a bare-metal, physically headless Linux machine. Gamescope owns the private game display, PipeWire provides capture, and hardware H.264 plus Opus leave the machine over iroh, so the client reaches the host by its cryptographic identity rather than an IP address.
  • Portal is the client: an installed Tauri desktop application with a native iroh endpoint, WebCodecs video decode, AudioWorklet playback, and controller-first navigation.
Sigil · bare-metal Linux host          Portal · installed desktop client
  Gamescope headless session             native iroh endpoint
    -> PipeWire video/audio                -> binary Tauri channels
    -> hardware H.264 + Opus               -> WebCodecs video + audio out
    -> iroh / MoQ media objects          controller, keyboard, mouse
  uinput virtual devices        <----      -> iroh input protocol

Design principles

  • Latency over history. Every capture, encode, transport, decode, and input queue is bounded. Stale video is dropped or cancelled rather than buffered, so a slow receiver never accumulates a playable backlog. Media travels as bounded MoQ groups: one GOP is one group, and a newer independently decodable group cancels its predecessor.
  • Input is independent and focused. Controller, keyboard, and relative mouse travel on their own iroh connection, unaffected by media backpressure. Session focus is a revocable token rather than a viewing right. Every handoff first invalidates the former focus generation, then releases held keys and emits a neutral gamepad state before a successor can inject.
  • Fail closed. Portal derives its stable iroh identity from a FIDO2 key with hmac-secret. A signed, short-lived, peer-bound invitation from Sigil enrolls each bounded viewer once, with independently granted view, pointer/keyboard, and gamepad permissions and durable replay protection. Every ordinary launch after that is PIN -> tap -> play.
  • Strict product boundary. Sigil never depends on Tauri or a webview. Portal never bundles capture, encoding, a daemon, or host input injection.

Status

goq is pre-release. The reference host is an AMD machine running Bazzite; H.264 at 1280x800/60 is the known-safe measured benchmark, while production capture accepts any even native mode within the protocol's bounded pixel limits.

Working today:

  • The pure Rust Sigil daemon: Gamescope PipeWire capture at the display's native mode, AMD GstVA H.264 encoding, and bounded PipeWire/Opus audio.
  • Authenticated session admission over a control connection, then a shared, authenticated upstream iroh-moq generation with a strictly validated catalog. Multiple viewers share one video/audio producer and one adaptive actuator; earlier custom media protocols remain exclusive compatibility fallbacks.
  • Adaptive bitrate and motion-sensitive resolution on the opt-in in-process encoder backend: session-authenticated receiver feedback, hysteresis, and changes that commit only on exact encoder readback or a target-size IDR.
  • Portal playback through bounded binary Tauri channels into WebCodecs and an AudioWorklet, with per-stage queue, drop, and latency diagnostics.
  • Linux uinput keyboard, relative mouse, and an Xbox-style virtual gamepad, with strict device preflight and end-of-session neutralization.
  • One-time FIDO-bound enrollment, replay protection, and controller-usable onboarding in Portal, with bounded multi-peer authorization and live view or input revocation.
  • A deterministic, checksum-bound Bazzite runtime package with serialized install/upgrade and tamper-checked rollback, plus the foundation of a controller-first Decky Loader management plugin over a redacted local appliance-status contract.

The streaming-hardening roadmap, where the remaining work is hardware acceptance on the reference host, is tracked as MoQ recovery hardening, adaptive bitrate, motion-sensitive resolution, and automatic codec selection. The remaining public-alpha acceptance gates (headless cold boot, physical controller gameplay, sustained A/V measurement, and the signed public release path) are tracked in issues #4 to #6.

Repository layout

Path Contents
crates/sigil-protocol Bounded, versioned handshakes, media/audio headers, input messages, limits, ALPNs
crates/sigil-host The sigil daemon and the sigil-probe diagnostic
src-tauri/ Portal's native side: iroh transport, FIDO2 identity, binary channels
portal/ Portal frontend: WebCodecs decode, audio playback, controller navigation
decky/ Decky Loader management plugin for the Sigil appliance
website/ The static goq.sh site, published via a Cloudflare Worker
scripts/ Build, packaging, verification, and host provisioning tooling
docs/ Runbooks and contracts for provisioning, releases, and hardware acceptance

Getting started

You need:

  • Rust 1.91 or newer (the repository pins Rust 1.95)
  • Tauri v2 system dependencies
  • A FIDO2 security key with hmac-secret support
  • For a host: a dedicated AMD Linux machine (Bazzite is the packaged target)

Building Sigil with the optional Linux in-process-gstreamer feature additionally needs the GStreamer core, app, and video development libraries; the matching runtime libraries and plugins must be installed on the host.

Run Portal against a Sigil host during development:

source ~/.cargo/env
cargo tauri dev

On Linux with NVIDIA, prefix with WEBKIT_DISABLE_DMABUF_RENDERER=1.

Provision a host

Activate an installed dedicated AMD host with the portable Sigil host activation guide. To evaluate a candidate machine first, run scripts/bazzite-inventory.sh for a read-only hardware report; add --smoke to exercise a bounded 1280x800/60 VA-API encode, or --cold-boot on the first login after a physically headless boot for a strict readiness gate.

Enroll a Portal

On Portal's first launch, enter the security-key PIN and choose show portal id. On the Sigil host, create an invitation for that exact peer:

sigil invitation create \
  --config ~/.config/sigil-spark/host.toml \
  --peer PORTAL_PEER_ID \
  --pointer-keyboard \
  --gamepad \
  --output ~/portal.goq-invite

Move the owner-only invitation file to the client and open it with Portal. Sigil consumes it once; every later launch is PIN -> tap -> play. Repeat with a distinct invitation for each viewer. A view-only invitation creates a spectator with no focus action; pointer/keyboard or gamepad grants make a viewer eligible to request slot-0 focus but do not grant possession. To move Portal to a different Sigil host, revoke the enrollment on the old host and use client -> reset enrollment. A new invitation never silently replaces a working enrollment.

Verification

Run the complete repository gate before sharing work:

./scripts/verify-demo-build.sh

It covers Rust format, tests, and clippy, the Linux cross-build when available, frontend syntax and tests, ShellCheck, package tests, a three-viewer native-MoQ loopback proof, and a separate legacy-exclusive proof. The explicit eight-viewer release stress gate remains a local resource test, and neither loopback mode substitutes for exact-candidate hardware UAT. Website and installer changes go through ./scripts/verify-website.sh. Hardware acceptance evidence lives under docs/hardware-uat/, separate from local tests.

Releases

Sigil is machine setup, not a desktop download: the public bootstrap is https://goq.sh/install-sigil, and it intentionally fails closed until the Minisign publisher trust root and the first signed release exist. Its release assets carry a single frozen build-target suffix, linux-glibc2.17-x86_64, pinned by release/sigil-target-contract.txt; that name describes the binary ABI (glibc 2.17, x86-64), not a distribution, so one build runs across the supported AMD hosts. Portal is a compiled, signed desktop application, never a shell install; the only published target is macOS arm64, which is ad-hoc signed rather than Apple-notarized, so macOS blocks its first launch until you allow it under System Settings, Privacy and Security. macOS x86_64, Linux x86_64, and Windows x86_64 are built and attested every release as unpublished preview artifacts. The packaging, signing, and publication ceremonies are documented in public release delivery and the Portal release runbook. The operator path from the committed unconfigured trust pins to a first published release is release credential bring-up.

License

MIT

About

games over quic

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages