forked from unom/punktfunk
53 commits since v0.28.1 (36 non-merge). Cut from origin/main8c6099da. THE NUMBER: 0.29.0 is forced, not chosen. The C ABI moved 19 -> 20 (#230 added punktfunk_connection_mgmt_port for the in-band mgmt-port advert), and the Windows MSIX package identity changed with the Azure signing move (#228) — either alone rules out a patch. scripts/ci/pf-version.sh derives the canary base as latest-stable + one minor, so canaries move from 0.29.x to 0.30.x after the tag; no collision either way. Version table measured, not copied forward: wire stays 2 (Welcome grew a trailing u16 older peers never read, with an explicit cipher byte whenever a port rides along so offset 68 keeps meaning cipher), driver protocol 6/min 3 (pf-driver-proto has no diff against the v0.28.1 tag), gamepad channel 3, plugin index schema 1, edition 2024, MSRV 1.85, 27 crate dirs, gamescope +pfhdr7 (patch series untouched), SDK 0.1.4, plugin-kit 0.4.1. api/openapi.json stays stamped 0.28.0 — the mgmt API surface did not change this cycle — and docs-site/public/openapi.json is byte-identical to it, so no re-sync is owed for once. Re-synced once as main moved (b5cace3a->8c6099da, PRs #237–#241): the Hyprland six-fix arc and the Windows mgmt-port completion joined the notes and CHANGELOG; contract surfaces (include/, pf-driver-proto, sdk, plugin-kit, api/) show no diff from the extra commits, so every version-table row survived the re-sync unchanged. Gates run on this tree: cargo fmt --all --check clean; cargo metadata --locked ok; Cargo.lock diff versions-only (36/36 lines); cargo test -p punktfunk-core green including the c_abi harness (the header with the v20 symbol compiles and round-trips); Play whatsnew 444/500 chars (counted as characters, not bytes) and not byte-identical to any prior release's; notes voice scan finds internal names only in the For developers section.