Files
punktfunk/Cargo.toml
enricobuehler 92de6a8ce3 chore(release): bump workspace version to 0.32.0
90 commits since v0.31.4 (63 non-merge), cut at db0f4f1e.

**The C ABI steps 25 -> 26.** `punktfunk_connect_opts` closes the
`punktfunk_connect_ex*` ladder: eleven generations each added a field by minting
a new exported symbol plus a 20-something-parameter forwarding shim, and the
replacement takes every option in ONE size-prefixed `PunktfunkConnectOpts`.
Every `ex` keeps its symbol and behaviour, so this is an added surface, not a
changed one. Layout is locked padding-free on both pointer widths (96/68 B) by
const asserts AND by the C harness compiling the same sizes.

The minor bump was already right before the ABI moved: ABR Phase 4 redefines
every control-plane bitrate as the TOTAL WIRE BUDGET rather than the encoder
rate, deliberately without a capability handshake. `include/punktfunk_core.h`
documents the 10-bit SDR ask as "0.32" and says "every pre-0.32 client sets the
two bits together", so the tree had pre-decided the number.

Version table, re-derived at HEAD rather than read off the diff:
  * wire 2 -- unchanged. Three additive, ignorable additions: USER_FLAG_REPEAT,
    CLIENT_CAP_KEEP_HOST_AUDIO, and Welcome::host_caps2 (trailing, absent -> 0)
    carrying HOST_CAP2_REPEAT_MARK
  * C ABI 25 -> 26 (above)
  * crate dirs 27, 39 members, edition 2024, MSRV 1.85 -- unchanged
  * driver proto 6, gamepad channel 3, plugin index 1, host event schema 1,
    gamescope +pfhdr8, SDK 0.1.6 -- all unchanged; pf-driver-proto and
    punktfunk-host/src/events.rs show no diff at all
  * api/openapi.json 0.31.4 -> 0.32.0, content-identical (info.version is the
    whole diff); both copies re-stamped and byte-identical to each other
  * @punktfunk/plugin-kit stays 0.4.4 ON PURPOSE: plugin-kit/src/wire.ts changes
    exactly one line and it is a doc comment in the launch.kind table.
    `launcher_ui` is a bare string validated host-side, so nothing to republish.

The CHANGELOG's `heroic-console` entry was filed under v0.31.4, but ae13b29a
landed AFTER that tag -- so that frozen section described a change v0.31.4 does
not contain. Moved into the v0.32.0 section verbatim.

Seven behavioural breaking changes, none of them a version step, all listed in
CHANGELOG.md: the wire-budget redefinition; FLOOR_KBPS 5000 -> 2000; DSCP
defaults to AUTO (local peers only); GameStream video AND control encryption
default on (both graduated after their own on-glass pass on .173, and
`PUNKTFUNK_GS_ENCRYPT=video` is the new middle rung); PyroWave forces Automatic
bitrate; the console pairing routes move behind the console password (the
security review's critical finding -- a console session cookie alone reached
code execution); deep links auto-dial by stable record id only.

Release notes rewritten to the ISO 24495-1/-5 plain-language rules: sentences
under 30 words, paragraphs under 6 sentences, bold bullet lead-ins, an explicit
overview, a table of contents, and acronyms defined on first use. The plugin's
own text auditor reports 0 findings on the Play notes and 2 on the release
notes, both of which are the words NVIDIA and AMD -- company names, not
acronyms, deliberately left unexpanded.

`cargo audit` stays GREEN: h2 0.4.18 -> 0.4.19 closed RUSTSEC-2026-0258, left
open deliberately at the v0.31.1 cut. Only two allowed `unmaintained` warnings
remain (audiopus_sys, paste).

The Play whatsnew leads with the Android black screen, which is the one fault a
phone or TV user in this cycle could not work around.

Gates on the cut (the Mac): cargo fmt --all --check; cargo metadata --offline;
lock diff versions-only 36/36; cargo test -p punktfunk-core --lib --features
quic 503 passed / 0 failed; the C ABI harness PASSED (abi_version=26); the
regenerated header is not stale; check-docs-drift.sh; check-docs-links.sh; the
Play notes gate 412/500 chars and unique against 15 files; both openapi copies
cmp identical; repo voice scan clean; cargo audit green.
2026-08-27 19:28:32 +02:00

128 lines
6.2 KiB
TOML

[workspace]
resolver = "2"
members = [
"crates/punktfunk-core",
"crates/punktfunk-host",
"crates/punktfunk-host/vendor/usbip-sim",
# The capability-carrying PyroWave encode worker. A SEPARATE binary by design — never a
# hardlink of, or a subcommand of, punktfunk-host (design/gpu-priority-capability-worker.md).
"crates/punktfunk-encode-worker",
"crates/punktfunk-tray",
"crates/pf-bitstream",
"crates/pf-bitstream/vendor/cros-codecs",
"crates/pf-client-core",
"crates/pf-clipboard",
"crates/pf-presenter",
"crates/pf-console-ui",
"crates/pf-driver-proto",
"crates/pf-paths",
"crates/pf-update",
"crates/pf-update-check",
"crates/pf-host-config",
"crates/pf-gpu",
"crates/pf-zerocopy",
"crates/pf-frame",
"crates/pf-win-display",
"crates/pf-encode",
"crates/pf-capture",
"crates/pf-inject",
"crates/pf-vdisplay",
"crates/pf-vkdecode",
"crates/pf-dxvadec",
"crates/pf-vaadec",
"crates/pyrowave-sys",
"crates/libvpl-sys",
"clients/probe",
"clients/cli",
"clients/linux",
"clients/session",
"clients/windows",
"clients/android/native",
"tools/cursor-probe",
"tools/display-disturb",
"tools/latency-probe",
"tools/loss-harness",
]
# Standalone PoC (built on its own; pulls usbip/tokio/libusb we don't want in the workspace).
# The vendored `ndk` is a [patch.crates-io] source, not a member: it only compiles for the
# `*-linux-android` targets, so workspace membership would break host `cargo build --workspace`.
exclude = [
"packaging/linux/steam-deck-gadget/usbip-poc",
"clients/android/native/vendor/ndk",
# Bring-your-own-hardware measurement tools. `hid-descriptor-dump` pulls `hidapi`, a C library
# wanting libudev on Linux; `win-input-matrix` is Windows-only and asks the live input stacks
# what they can see. Neither belongs in `cargo build --workspace` or on a CI leg with no pad.
"tools/hid-descriptor-dump",
"tools/win-input-matrix",
]
# ndk 0.9.0 verbatim from crates.io plus ONE visibility change (and two warning fixes — an
# unnecessary `std::` qualification and a feature-gated `Result` import): `MediaCodec::as_ptr` made public
# (upstream keeps it private and exposes no frame-rendered binding), so the Android client can
# call `AMediaCodec_setOnFrameRenderedCallback` via ndk-sys for the HUD's `display` stage
# (design/stats-unification.md). Drop the patch when upstream exposes the pointer or the callback.
[patch.crates-io]
ndk = { path = "clients/android/native/vendor/ndk" }
[workspace.package]
version = "0.32.0"
edition = "2024"
rust-version = "1.85"
license = "MIT OR Apache-2.0"
authors = ["unom"]
repository = "https://git.unom.io/unom/punktfunk"
# The `unsafe` discipline the `packaging/windows/drivers/*` crates already run, extended to the
# workspace. `unsafe fn` marks a CONTRACT the caller must uphold; it is not a licence for the whole
# body to skip checking. Without this lint an `unsafe fn` body is unchecked end to end, so a 600-line
# function hides which handful of lines are actually the unsafe ones — exactly the reviewer-hostile
# shape we are working down. (This is the Rust 2024 default; adopting it early also pays off the
# edition migration.)
#
# `deny`, not `warn`. `warn` was never actually a softer setting: CI runs `cargo clippy … -D
# warnings`, which promotes it to a hard error anyway — that is how adopting this lint turned main
# red on every platform for a day without the level in this file ever saying `deny`. A level that
# lies about its own severity is worse than a strict one, so this now states what CI already does,
# and the exemptions are written down per file instead of hiding in a 689-warning wall nobody reads.
#
# THE EXEMPTIONS. Fourteen GPU/FFI backend files carry `#![allow(unsafe_op_in_unsafe_fn)]` with a
# one-line reason each. They are not "not done yet" — they are where this lint stops paying:
# their bodies are ash/CUDA/AMF/libav calls almost line for line (measured: 64% of the sites are a
# single third-party FFI call, and of the 44 `unsafe fn`s in them only 4 have a body containing no
# unsafe operation at all). Narrowing them means one `unsafe {}` per line plus, since pf-encode also
# denies `clippy::undocumented_unsafe_blocks`, one hand-written SAFETY comment per line that could
# only ever restate "an ash call on a live device" — the precise noise that made `unsafe` stop
# meaning anything here before (see the header of `pf-win-display/src/win_display.rs`).
#
# Everything else in the workspace is at zero and enforced. Removing one of those allows, file by
# file, is real work with a real payoff; blanket-narrowing all fourteen is not. Prefer DELETING an
# `unsafe fn` marker over wrapping its body: keep the marker only where a caller can actually break
# something (a raw pointer, a borrowed HANDLE, a GPU object that must not be in flight).
[workspace.lints.rust]
unsafe_op_in_unsafe_fn = "deny"
# The companion lint: every `unsafe {}` / `unsafe impl` carries a `// SAFETY:` proof. Hoisted here
# from ~85 per-file `#![deny(...)]` attributes so a NEW crate (or a new module in an old one) is
# covered on creation rather than on remembering — the per-file form left pf-vkhdr-layer,
# wdk-probe, and half of pf-clipboard uncovered for months. NOTE: this table reaches only crates
# with `[lints] workspace = true`; `packaging/windows/drivers` and `packaging/windows/pf-vkhdr-layer`
# are SEPARATE workspaces and restate it (any "workspace-wide" claim must be made three times or it
# is false). Of the members, only the two vendored snapshots (pf-bitstream/vendor/cros-codecs,
# punktfunk-host/vendor/usbip-sim) stay out, deliberately — upstream code stays pristine.
[workspace.lints.clippy]
undocumented_unsafe_blocks = "deny"
[profile.release]
opt-level = 3
lto = "thin"
codegen-units = 1
# NOTE: deliberately NOT `panic = "abort"`. punktfunk-core ships as a cdylib/staticlib into
# third-party apps (Swift/Kotlin/C) and its C ABI catches panics at the boundary
# (`catch_unwind` → `PunktfunkStatus::Panic`). `panic = "abort"` would make that guard a
# no-op and let a stray panic abort the embedding application. Unwinding keeps the
# documented isolation guarantee real.
# The per-frame hot path must stay fast even in dev builds.
[profile.dev.package."*"]
opt-level = 2