android / android (pull_request) Canceled after 0s
apple / swift (pull_request) Canceled after 1m46s
apple / distribute (pull_request) Canceled after 0s
apple / screenshots (pull_request) Canceled after 0s
ci / rust (pull_request) Canceled after 0s
ci / rust-arm64 (pull_request) Canceled after 0s
ci / web (pull_request) Canceled after 0s
ci / docs-site (pull_request) Canceled after 0s
ci / bun-nix (pull_request) Canceled after 0s
nix / flake (pull_request) Canceled after 0s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Canceled after 1m47s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Canceled after 0s
88 commits since v0.30.0 (64 non-merge). Cut from origin/main8a4eac4c(PR #317 merged; PR #318, the Nix cache signing-key follow-up, is open and NOT in this cut). THE NUMBER: 0.31.0 is a judgement call, not forced. Nothing versioned moved — WIRE_VERSION 2, C ABI 24 with include/punktfunk_core.h byte- identical to the v0.30.0 tag, driver protocol 6 / min 3 (pf-driver-proto has no diff against the tag), gamepad channel 3, plugin index schema 1, host event schema 1, gamescope +pfhdr8 with no new patch files, api/openapi.json still stamped 0.29.0 and unchanged, SDK 0.1.4, plugin-kit 0.4.2. On that table alone this could be 0.30.1. It is a minor because the cycle is feature-shaped and one commit carries a `!`: the Android Compose console is deleted outright and pf-console-ui over Skia/GL becomes the console on all three ABIs (#301, #317); the Android present path moves to ASurfaceControl by default (#290); the Linux desktop-audio capture flips to a host-owned null-audio-sink by default with PUNKTFUNK_STREAM_SINK=stream as a one-release escape (#305); `topology: exclusive` on Hyprland/sway goes from silently-extend to genuinely disabling the operator's outputs, which is the default policy on every auto-detected box (#304, closes #284); a Nix binary cache ships (#313); and the Linux host package grows three new system files (udev rule, WirePlumber policy, ALSA UCM drop-in) that the DualSense audio path depends on (#291, #302, #315). scripts/ci/pf-version.sh already derives the canary base as latest stable + one minor, so canaries have sat at 0.31.x since the v0.30.0 tag and move to 0.32.x after this one. Version table re-measured on8a4eac4c, not carried forward. Two rows carry a warning rather than a change: sdk/ and plugin-kit/ both have real code changes (the mgmt-endpoint follow in config.ts/runner-cli.ts; SyncSettings.minInterval in sync-engine.ts) with package.json unbumped. They version off their own sdk-v*/plugin-kit-v* tags and this commit does not touch them; the CHANGELOG names sdk-v0.1.5 and plugin-kit-v0.4.3 as owed so they are cut deliberately. The release branch also carries one preceding whitespace-only commit: crates/pf-console-ui/src/screens/controllers.rs and crates/punktfunk-host/src/audio/linux/pad_card_volume.rs had landed on main formatted differently from rustfmt 1.96.0 (the pinned toolchain), so ci.yml's Format step was red on the tip this is cut from. `cargo fmt --all` and nothing else. Gates run on this tree (this MacBook, rustc/rustfmt 1.96.0): cargo fmt --all --check clean; cargo metadata --offline ok; Cargo.lock diff versions-only (36/36 lines); cargo test -p punktfunk-core unit suite 272 passed; the android.yml Play notes gate run verbatim — 498/500 characters and not byte-identical to any prior release's; notes voice scan finds no internal names outside the For developers section (the two hits, `nixpkgs` and Flatpak, are things those users configure by name); both openapi copies cmp identical and unchanged since the tag; include/punktfunk_core.h regenerated by the build and git-diff clean. ⚠ NOT run here: the C ABI harness (tests/c_abi.rs) — it links -lopus and this machine has no libopus (`ld: library 'opus' not found`; the Mac Studio has it). The header is byte-identical to v0.30.0's, where the harness passed, and nothing in punktfunk-core's C surface changed; the CI runner is its first execution for this tag. Named in the CHANGELOG's Verification status rather than left to be discovered. No outside contributor is credited by name: every attribution in the 64 bodies is a dated field report or "a reporter", and issue #284 was filed by the maintainer. The Thanks section thanks the field reports without naming anyone.