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.
- 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
- 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.
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-moqgeneration 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
uinputkeyboard, 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.
| 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 |
You need:
- Rust 1.91 or newer (the repository pins Rust 1.95)
- Tauri v2 system dependencies
- A FIDO2 security key with
hmac-secretsupport - 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 devOn Linux with NVIDIA, prefix with WEBKIT_DISABLE_DMABUF_RENDERER=1.
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.
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-inviteMove 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.
Run the complete repository gate before sharing work:
./scripts/verify-demo-build.shIt 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.
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.