docs: refresh README/CLAUDE status; roadmap pairing-hardening + SudoVDA Windows
ci / rust (push) Has been cancelled
ci / rust (push) Has been cancelled
- README: replace the stale M0/M2-in-flight status with reality — M1 hardened, M2 GameStream host live to stock Moonlight, M3 punktfunk/1 validated, M4 Apple first light, web console + unified host; FFmpeg 7/8; Bazzite-deployed. Layout adds web/, packaging/, native_pairing, dualsense. - CLAUDE: protocol-growth item now reflects the unified host + web-console native pairing (done) and flags the next steps; layout updated. - roadmap §7 Windows: de-risked via SudoVDA (the Sunshine Virtual Display Adapter) — no self-signed kernel IDD needed; the virtual-display backend drops XL→M. - roadmap §8 (new) Pairing & trust hardening: mandatory PIN pairing by default (TOFU-open is insecure on a LAN) + delegated pairing approval (an already-paired device approves a new one, no out-of-band PIN). - windows-host.md: SudoVDA path throughout (status, table, phasing, effort M not L). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+51
-14
@@ -1,13 +1,19 @@
|
||||
# punktfunk roadmap — next goals
|
||||
|
||||
Decided 2026-06-10 (research-grounded; see commit history). Sequence:
|
||||
**KDE reliability → client compositor options → mic passthrough → Bazzite COPR RPM (then
|
||||
bootc) → touch → full UHID DualSense → iOS** (+ Windows host, scoped & deferred).
|
||||
Decided 2026-06-10 (research-grounded; see commit history), extended since.
|
||||
|
||||
**Done (2026-06-10):** #1 KDE reliability (Phase 1 + 2), #2 compositor options (full stack incl.
|
||||
macOS client), #4 mic passthrough — all on `main`, live-validated. #3 Bazzite packaging written
|
||||
(`packaging/`); the COPR/bootc build is operator-run. Remaining: #5 touch → UHID DualSense, #6 iOS,
|
||||
and a Windows host (`docs/windows-host.md`).
|
||||
**Done & live (on `main`):** #1 KDE reliability (Phase 1+2), #2 client compositor options (full
|
||||
stack incl. the macOS client), #4 mic passthrough, #5 touch (host path) + **rich UHID DualSense**
|
||||
— input + adaptive-trigger/LED feedback over the new `0xCC`/`0xCD` planes + C ABI, Phase C/D/E
|
||||
live-validated. #3 Bazzite packaging (`packaging/`) **deployed live** on a Bazzite F43 box (builds
|
||||
against FFmpeg 7 **or** 8; gamescope capture → zero-copy NVENC, sub-ms latency; Sunshine replaced).
|
||||
**Unified host:** `serve --native` runs the GameStream host + the punktfunk/1 QUIC host in one
|
||||
process, with native pairing driven from the **web console** (arm → show PIN), not the service log.
|
||||
Advanced DualSense (audio-driven voice-coil) haptics **scoped NO-GO** (`docs/dualsense-haptics.md`).
|
||||
|
||||
**Next:** **§8 pairing & trust hardening** (mandatory PIN by default + delegated approval), the M4
|
||||
client presenter + iOS (§6), and a Windows host (§7 — now **de-risked via SudoVDA**, no custom
|
||||
signed driver needed).
|
||||
|
||||
## 1. Reliable headless KDE/compositor spawning ✅ *(done — Phase 1 + 2)*
|
||||
|
||||
@@ -111,14 +117,45 @@ select = a `pw_stream` with `Direction::Output` + `media.class=Audio/Source`.
|
||||
PunktfunkKit is already platform-shared; iOS needs the `UIViewRepresentable` presenter twin
|
||||
+ touch capture (#5) + UI. tvOS later.
|
||||
|
||||
## 7. Windows as a host *(scoped & deferred — `docs/windows-host.md`)*
|
||||
## 7. Windows as a host *(scoped — `docs/windows-host.md`; de-risked via SudoVDA)*
|
||||
|
||||
Architecturally an "add a backend" job, not a parallel port: `punktfunk-core` (protocol/FEC/
|
||||
crypto/C-ABI) + QUIC + GameStream + mgmt + the `m3`/pipeline orchestration are all platform-agnostic
|
||||
and already `cfg`-isolated (~95% reuse). New `#[cfg(windows)]` backends behind the existing traits:
|
||||
capture (DXGI Desktop Duplication), encode (Media Foundation / NVENC-SDK with a D3D11 context),
|
||||
input (SendInput + ViGEm), audio (WASAPI loopback + a virtual mic). **The blocker** is the
|
||||
virtual-display feature — no user-mode Windows API; it needs a signed kernel-mode **IDD** driver
|
||||
(XL). Recommended start: **Phase 0** — a "basic Windows host" capturing an existing monitor (no
|
||||
virtual display), proving the whole stack with the smallest surface. Deferred because it's large and
|
||||
unbuildable on the Linux dev box; the trait boundaries are already in the right places.
|
||||
capture (DXGI Desktop Duplication / Windows.Graphics.Capture), encode (Media Foundation / NVENC-SDK
|
||||
with a D3D11 context), input (SendInput + ViGEm), audio (WASAPI loopback + a virtual mic).
|
||||
|
||||
**The old blocker is gone.** Rather than author + sign our own kernel IDD for the per-client virtual
|
||||
display, use **SudoVDA** (the Sunshine Virtual Display Adapter) — a pre-built, signed Indirect
|
||||
Display Driver that creates virtual displays at arbitrary WxH@Hz on demand. The `VirtualDisplay`
|
||||
backend becomes *"install + drive SudoVDA's control API"* (M effort), not *"write + WHQL-sign a
|
||||
kernel driver"* (XL). That removes the only hard blocker — the Windows host is now a medium,
|
||||
mostly-mechanical port. Recommended start: **Phase 0** — capture an existing monitor to prove the
|
||||
stack end to end; **Phase 1** wires SudoVDA for the native-resolution output. Deferred only because
|
||||
it's unbuildable on the Linux dev box; the trait boundaries are already in the right places.
|
||||
|
||||
## 8. Pairing & trust hardening *(next)*
|
||||
|
||||
The unified host + web-console pairing (arm a window → display the host PIN → user enters it on the
|
||||
client) is built and live. Two changes harden it from "works" to "secure by default":
|
||||
|
||||
- **Mandatory PIN pairing by default.** Today the punktfunk/1 host can run open (trust-on-first-use)
|
||||
— *not* acceptable on a shared LAN, where any reachable device could connect. The unified host
|
||||
should `require_pairing` out of the box: a client must complete the SPAKE2 PIN ceremony (one online
|
||||
guess, no offline attack) before any session. The operator arms a window and reads the PIN from the
|
||||
web console (already built); an explicit `--open` escape hatch covers trusted single-user setups.
|
||||
The wire is already in place (`M3Options.require_pairing` + the `serve_session` gate); this flips
|
||||
the default and threads it through `serve --native` and the mgmt arm endpoint.
|
||||
- **Delegated pairing approval** — the ergonomic enabler for "mandatory" (pair a new device without
|
||||
fetching the host PIN out of band):
|
||||
1. Device A is already paired (authenticated) to Host X.
|
||||
2. The user tries to connect Device B to Host X.
|
||||
3. Host X pushes a request to the authenticated Device A: *"Allow Device B to pair with Host X?"*
|
||||
4. The user approves/denies on Device A; on approve, Host X admits Device B — binding B's
|
||||
certificate fingerprint — with no PIN typed.
|
||||
|
||||
Needs: a host→client *pairing-approval-request* (B's fingerprint + a human label) delivered to A's
|
||||
live connection (a QUIC side-plane message) or polled via the mgmt API; an approve/deny round-trip
|
||||
carrying an approval token; the host gating B's admission on it. The web console **and** the Apple
|
||||
client render the approval prompt. PIN pairing stays the bootstrap (the first device, or when no
|
||||
paired device is online to approve).
|
||||
|
||||
Reference in New Issue
Block a user