fix: complete the docs/→design/ and openapi→api/ rename references
The file moves (docs/ → design/, docs/api/openapi.json → api/openapi.json) landed
in d01a8fd, but the matching reference updates did not — so mgmt.rs's drift-test
`include_str!("../../../docs/api/openapi.json")` pointed at a path that no longer
exists and the host failed to build. This restores it and updates every reference:
- mgmt.rs include_str! → ../../../api/openapi.json (fixes the build)
- web/orval.config.ts codegen target, web/Dockerfile, .dockerignore
- deb/rpm/Arch packaging install paths
- CLAUDE.md, the .gitea CI workflows, code doc-comments, design-doc cross-links
docs-site route URLs (/docs/...) untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -276,7 +276,7 @@ pub mod frame {
|
||||
/// These were hand-duplicated as `OFF_*`/`SHM_*` constants in `inject/{gamepad,dualsense}_windows.rs`
|
||||
/// and (as bare literals — `*view.add(140)`) in the standalone `xusb-driver`/`dualsense-driver`
|
||||
/// workspaces, guarded only by "must match" comments — the top ABI-drift hazard the audit flagged
|
||||
/// (`docs/windows-host-rewrite.md` §2.7). Owning them here with `Pod` derives + `offset_of!`
|
||||
/// (`design/windows-host-rewrite.md` §2.7). Owning them here with `Pod` derives + `offset_of!`
|
||||
/// asserts makes a one-sided edit a compile error.
|
||||
///
|
||||
/// The host creates the section (privileged, permissive DACL so the restricted WUDFHost token can
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Input-desktop watcher (Windows) — the authoritative "normal vs secure desktop" signal for the
|
||||
//! two-process secure-desktop design (docs/windows-secure-desktop.md).
|
||||
//! two-process secure-desktop design (design/windows-secure-desktop.md).
|
||||
//!
|
||||
//! Windows switches the *input desktop* to "Winlogon" (the secure desktop) for UAC elevation, the
|
||||
//! lock screen and the login screen, and back to "Default" for the normal session. WGC captures only
|
||||
|
||||
@@ -562,7 +562,7 @@ impl IddPushCapturer {
|
||||
|
||||
/// Block (bounded) until the driver has ATTACHED to the host ring (`DRV_STATUS_OPENED`) **and published
|
||||
/// a first frame**, else fail so the caller can fall back to DDA (audit §5.1 +
|
||||
/// `docs/windows-host-rewrite.md` §2.5 — the GB1 game-capture fix).
|
||||
/// `design/windows-host-rewrite.md` §2.5 — the GB1 game-capture fix).
|
||||
///
|
||||
/// Requiring the first frame — not just the attach — catches the *reconnect-into-a-broken-state* case:
|
||||
/// a fullscreen game can leave the virtual display in a format/size that the driver's `publish()` guard
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Host-side WGC helper relay (Windows two-process secure-desktop design,
|
||||
//! docs/windows-secure-desktop.md — step 4).
|
||||
//! design/windows-secure-desktop.md — step 4).
|
||||
//!
|
||||
//! WGC won't activate under the SYSTEM account, so the SYSTEM host can't capture the normal desktop
|
||||
//! itself. Instead it spawns `punktfunk-host wgc-helper` in the **interactive user session** (so WGC works)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//! environment before the host starts, and **for the knobs captured here the environment is constant for the
|
||||
//! process lifetime**, so a lazily-parsed global is equivalent to "parsed once at startup".
|
||||
//!
|
||||
//! **Goal-1 stages 1–2** (`docs/windows-host-rewrite.md` §2.2): stage 1 stood this up; stage 2 migrated the
|
||||
//! **Goal-1 stages 1–2** (`design/windows-host-rewrite.md` §2.2): stage 1 stood this up; stage 2 migrated the
|
||||
//! genuinely-constant operator/dispatch knobs onto it (the dispatch-disagreement bug class: `idd_push`,
|
||||
//! `capture_backend`, `encoder_pref`, `render_adapter`, `no_wgc`, the vdisplay backend select — plus the
|
||||
//! plan-named `secure_dda`/`idd_depth`/`zerocopy`/`ten_bit` and the multi-site `perf`/`compositor`/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Pairing crypto primitives (control plane only — distinct from `punktfunk_core`'s AES-GCM
|
||||
//! data-plane sealing). GameStream pairing uses: AES-128-**ECB** with **no padding**,
|
||||
//! SHA-256 (host appversion major ≥ 7), and RSA-PKCS1v15-SHA256 signatures. See the
|
||||
//! `serverinfo + pairing` section of `docs/research/gamestream-protocol-research.json`.
|
||||
//! `serverinfo + pairing` section of `design/research/gamestream-protocol-research.json`.
|
||||
|
||||
use aes::cipher::generic_array::GenericArray;
|
||||
use aes::cipher::{BlockDecrypt, BlockEncrypt, KeyInit};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! GameStream (P1) control plane — what a stock Moonlight/Artemis client talks to around
|
||||
//! the media streams: mDNS discovery, the nvhttp serverinfo + pairing HTTP(S) API, RTSP,
|
||||
//! and the ENet control stream. `tokio`/`axum` live here (control plane, I/O-bound — never
|
||||
//! the per-frame hot path; that is `punktfunk_core`'s P1 wire codec). See `docs/gamestream-host-plan.md`.
|
||||
//! the per-frame hot path; that is `punktfunk_core`'s P1 wire codec). See `design/gamestream-host-plan.md`.
|
||||
//!
|
||||
//! Status: P1.1 — mDNS `_nvstream._tcp` advertisement + `/serverinfo`. Pairing, RTSP, and
|
||||
//! the media streams follow (see the GameStream host task list / plan).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! The 4-phase GameStream pairing state machine (over HTTP), keyed by `uniqueid`. Proves
|
||||
//! both sides know the PIN (via the SHA-256(salt||pin) AES-ECB key) and own their certs
|
||||
//! (RSA signatures), then pins the client cert. The final `pairchallenge` happens over
|
||||
//! HTTPS (handled in `nvhttp`). Byte-exact spec: `docs/research/…-research.json`.
|
||||
//! HTTPS (handled in `nvhttp`). Byte-exact spec: `design/research/…-research.json`.
|
||||
|
||||
use super::cert::ServerIdentity;
|
||||
use super::crypto;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! `RTP_PACKET(12, big-endian) + reserved[4] + NV_VIDEO_PACKET(16, little-endian) + payload`
|
||||
//! and the frame's bitstream is prefixed with an 8-byte `video_short_frame_header_t`, then
|
||||
//! striped into ≤4 FEC blocks of ≤255 shards. Byte-exact spec:
|
||||
//! `docs/research/gamestream-protocol-research.json` (video plane).
|
||||
//! `design/research/gamestream-protocol-research.json` (video plane).
|
||||
//!
|
||||
//! FEC (P1.5): each block carries `m = ⌈k·pct/100⌉` Reed–Solomon parity shards generated by
|
||||
//! `punktfunk_core::fec::Gf8Coder` (the nanors-compatible Cauchy GF(2⁸) coder). Crucially, RS runs
|
||||
|
||||
@@ -109,7 +109,7 @@ pub(super) struct SwDeviceProfile<'a> {
|
||||
/// `profile.instance`). The returned `HSWDEVICE` owns it — `SwDeviceClose` removes it on drop, so the
|
||||
/// pad appears/disappears with the session and nothing persists.
|
||||
///
|
||||
/// **Game-detection identity** (see `docs/windows-dualsense-game-detection.md`). `HIDD_ATTRIBUTES`
|
||||
/// **Game-detection identity** (see `design/windows-dualsense-game-detection.md`). `HIDD_ATTRIBUTES`
|
||||
/// alone (VID/PID via the IOCTL) satisfies SDL/HIDAPI/RawInput, but a native PS5 path (libScePad-
|
||||
/// style raw HID) classifies the *connection type* by walking from the HID child to its parent
|
||||
/// (`CM_Get_Parent`) and string-matching `"USB"`/`"BTHENUM"` in that parent's
|
||||
|
||||
@@ -389,7 +389,7 @@ fn real_main() -> Result<()> {
|
||||
}
|
||||
// USER-session WGC helper (Windows two-process secure-desktop design): capture the EXISTING
|
||||
// SudoVDA via WGC + NVENC, stream AUs on stdout to the SYSTEM host. Spawned by the host
|
||||
// (CreateProcessAsUser), not run by hand. See docs/windows-secure-desktop.md.
|
||||
// (CreateProcessAsUser), not run by hand. See design/windows-secure-desktop.md.
|
||||
#[cfg(target_os = "windows")]
|
||||
Some("wgc-helper") => {
|
||||
let get = |flag: &str| {
|
||||
@@ -704,7 +704,7 @@ SPIKE OPTIONS:
|
||||
|
||||
NOTES:
|
||||
'portal' needs headless Sway + xdg-desktop-portal-wlr running in this session
|
||||
(see docs/linux-setup.md). 'synthetic' needs no capture session and always runs.
|
||||
(see design/linux-setup.md). 'synthetic' needs no capture session and always runs.
|
||||
Encoded AUs are written to a playable file AND (unless --no-loopback) fed through a
|
||||
punktfunk_core host→client loopback that reassembles and byte-verifies each one.
|
||||
Both 'serve' and 'punktfunk1-host' advertise the native service over mDNS
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! The API is versioned under `/api/v1` and described by an OpenAPI 3.1 document generated
|
||||
//! at compile time with `utoipa` — `punktfunk-host openapi` prints it for client codegen, the
|
||||
//! running server serves it at `/api/v1/openapi.json` plus interactive docs at `/api/docs`,
|
||||
//! and a copy is checked in at `docs/api/openapi.json` (a test fails if it drifts, like the
|
||||
//! and a copy is checked in at `api/openapi.json` (a test fails if it drifts, like the
|
||||
//! cbindgen header).
|
||||
//!
|
||||
//! Security: binds loopback by default, serves HTTPS with the host's identity cert, and requires
|
||||
@@ -164,7 +164,7 @@ fn api_router_parts() -> (Router<Arc<MgmtState>>, utoipa::openapi::OpenApi) {
|
||||
}
|
||||
|
||||
/// The OpenAPI document as pretty JSON — what `punktfunk-host openapi` prints and what is
|
||||
/// checked in at `docs/api/openapi.json` for client codegen.
|
||||
/// checked in at `api/openapi.json` for client codegen.
|
||||
pub fn openapi_json() -> String {
|
||||
let (_, api) = api_router_parts();
|
||||
let mut json = api.to_pretty_json().expect("serialize OpenAPI document");
|
||||
@@ -1663,14 +1663,14 @@ mod tests {
|
||||
serde_json::json!([{}])
|
||||
);
|
||||
|
||||
let checked_in = include_str!("../../../docs/api/openapi.json");
|
||||
let checked_in = include_str!("../../../api/openapi.json");
|
||||
// Compare content, not line-ending style: the generated `json` is LF (serde_json), but git
|
||||
// may check the file out CRLF on Windows.
|
||||
assert_eq!(
|
||||
json.trim().replace('\r', ""),
|
||||
checked_in.trim().replace('\r', ""),
|
||||
"docs/api/openapi.json is stale — regenerate with: \
|
||||
cargo run -p punktfunk-host -- openapi > docs/api/openapi.json"
|
||||
"api/openapi.json is stale — regenerate with: \
|
||||
cargo run -p punktfunk-host -- openapi > api/openapi.json"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2221,7 +2221,7 @@ fn virtual_stream(ctx: SessionContext) -> Result<()> {
|
||||
// Windows two-process secure-desktop path: when the host runs as SYSTEM (required for the secure
|
||||
// desktop + SendInput), WGC can't activate in-process, so we capture the normal desktop via a
|
||||
// helper spawned in the user session and relay its AUs. (Single-process WGC/DDA is used as the
|
||||
// user, and stays the path on Linux.) See docs/windows-secure-desktop.md.
|
||||
// user, and stays the path on Linux.) See design/windows-secure-desktop.md.
|
||||
#[cfg(target_os = "windows")]
|
||||
if plan.topology == crate::session_plan::SessionTopology::TwoProcessRelay {
|
||||
return virtual_stream_relay(ctx);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! `SessionPlan` — the per-session capture / topology / encoder decision, resolved **once** from
|
||||
//! [`HostConfig`](crate::config) (+ the handshake-negotiated bit depth) into a typed, logged value.
|
||||
//!
|
||||
//! **Goal-1 stage 3** (`docs/windows-host-rewrite.md` §2.2): before this, the Windows session decision was
|
||||
//! **Goal-1 stage 3** (`design/windows-host-rewrite.md` §2.2): before this, the Windows session decision was
|
||||
//! re-derived at three call sites — the capture backend inside `capture::capture_virtual_output`, the
|
||||
//! process topology in `punktfunk1::should_use_helper`, and the encode backend in
|
||||
//! `encode::windows_resolved_backend` — each reading [`config`](crate::config) independently, with no
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//! Raw C-ABI FFI (winmm/kernel32/dwmapi/avrt) rather than the `windows` crate so it builds without
|
||||
//! pulling new windows-rs features. No-op on non-Windows. Per-thread effects (MMCSS, execution
|
||||
//! state) auto-revert at thread exit (= session end); the process-wide bits revert at process exit.
|
||||
//! See `docs/host-latency-plan.md` Tier 3A.
|
||||
//! See `design/host-latency-plan.md` Tier 3A.
|
||||
|
||||
// Every `unsafe` block in this file carries a `// SAFETY:` proof; enforce it (unsafe-proof program).
|
||||
#![deny(clippy::undocumented_unsafe_blocks)]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//!
|
||||
//! Control surface: a device-interface-GUID + `CreateFileW` + `DeviceIoControl` IOCTL protocol, with
|
||||
//! the wire contract OWNED by [`pf_driver_proto::control`] (versioned + `#[repr(C)] Pod` structs,
|
||||
//! NOT the SudoVDA ABI). No DLL, no named pipe. See `docs/windows-host-rewrite.md`.
|
||||
//! NOT the SudoVDA ABI). No DLL, no named pipe. See `design/windows-host-rewrite.md`.
|
||||
//!
|
||||
//! This is a faithful clone of [`super::sudovda`] (the shipping fallback) repointed at the new driver:
|
||||
//! same reference-counted/lingering monitor lifecycle, same CCD isolation + active-mode forcing — those
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! USER-session WGC helper (Windows) — part of the two-process secure-desktop design
|
||||
//! (docs/windows-secure-desktop.md).
|
||||
//! (design/windows-secure-desktop.md).
|
||||
//!
|
||||
//! WGC won't activate under the SYSTEM account, but the host must run as SYSTEM for the secure
|
||||
//! desktop. So the SYSTEM host spawns THIS helper in the interactive user session
|
||||
|
||||
Reference in New Issue
Block a user