Files
punktfunk/docs/releases
enricobuehlerandClaude Opus 5 b2cf4e908c
audit / bun-audit (sdk) (push) Successful in 17s
audit / bun-audit (web) (push) Successful in 17s
audit / docs-site-audit (push) Successful in 17s
audit / pnpm-audit (push) Successful in 11s
audit / bun-audit (plugin-kit) (push) Successful in 3m15s
audit / cargo-audit (push) Successful in 3m24s
android-screenshots / screenshots (push) Successful in 3m40s
apple / swift (push) Successful in 5m0s
audit / license-gate (push) Successful in 7m24s
decky / build-publish (push) Successful in 37s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 1m17s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 2m3s
arch / build-publish (push) Successful in 19m5s
linux-client-screenshots / screenshots (push) Successful in 10m39s
sbom / sbom (push) Successful in 1m16s
docker / deploy-docs (push) Successful in 11s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 24s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 24s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 8s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 7s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 5s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 19s
docker / builders-arm64cross (push) Successful in 5s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 23s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m23s
windows-host / package (push) Successful in 14m34s
windows-host / winget-source (push) Successful in 17s
android / android (push) Successful in 10m16s
web-screenshots / screenshots (push) Successful in 10m52s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 16m56s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 2m36s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 2m51s
deb / build-publish (push) Successful in 13m51s
deb / build-publish-host (push) Successful in 5m27s
deb / build-publish-client-arm64 (push) Successful in 4m9s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 27m37s
release / apple (push) Successful in 28m45s
apple / screenshots (push) Successful in 21m19s
ci / docs-site (push) Successful in 1m4s
ci / web (push) Successful in 2m46s
ci / rust-arm64 (push) Successful in 3m41s
ci / rust (push) Successful in 3m54s
flatpak / build-publish (push) Successful in 4m24s
chore(release): bump workspace version to 0.22.0
256 commits since v0.21.0. Minor, not patch: the headline is settings profiles —
named bundles of overrides bound per host, landing on all five clients at once
(Linux, Windows, Apple, Android) with one settings surface editing either layer,
marked-and-resettable override rows, per-profile colours, host bindings, one-off
"Connect with", and pinned host+profile cards. With them: the punktfunk:// link
grammar (one parser, one 44-case vector file run by the Rust, Swift and Kotlin
suites), double-clickable shortcuts, and `punktfunk` — one headless front-end
over the brain layer, which wakes a sleeping host the way a card click does.

Also: opt-in HDR on the gamescope path plus the cursor-in-the-node patch that
makes those sessions zero-copy; Vulkan Video 10-bit so AMD/Intel HDR keeps the
good path; a zero-copy NVENC HDR leg; host OS detection with marks on every
client and the console; PUNKTFUNK_HOST_NAME, PUNKTFUNK_MAX_FPS and
PUNKTFUNK_VDISPLAY_HZ_MULT; monitor enumeration on Windows; and the release-
integrity work (per-asset SHA256 sidecars, a signed sysext feed, one stable
driver publisher identity, fail-closed signing guards on a v* tag).

Wire protocol stays at 2, the embeddable C ABI at 13 and the Windows virtual-
display driver protocol at 6 — 0.18-0.22 hosts and clients keep mixing freely.
The Windows virtual-GAMEPAD channel protocol goes 2 -> 3 and fails closed both
ways: it carries the fix for a LocalService principal being able to take over a
pad's shared input section and forge HID input into the interactive desktop, so
the host and its drivers must ship together. The installer ships both.

Additive elsewhere: an advisory mDNS `os=` TXT key, HostInfo.os/os_name,
MonitorsResponse.pin_supported, an eighth field on the Android JNI discovery
record, and appended-last StoredHost fields per the frozen app-widget contract.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 01:39:58 +02:00
..

Release notes

One file per stable release: docs/releases/vX.Y.Z.md. Its contents become the Gitea release body verbatim and are the source of the Discord #releases announcement.

Why this exists

Releases used to be created by CI with an empty body; the notes were pasted in by hand afterward. That left a window where the release — and anything announcing it — carried no notes. Now the notes are authored before the tag is pushed, as part of the version bump, so the release is born complete and the announcement always has something to say.

The flow

  1. Write the notes. Add docs/releases/vX.Y.Z.md in the same commit (or PR) as the version bump. Copy TEMPLATE.md and fill it in. This file is the single source of truth for the body.
  2. Tag & push. git tag -a vX.Y.Z … && git push origin vX.Y.Z fans out to the build workflows. Whichever one wins the create race seeds the release body from this file (scripts/ci/gitea-release.shensure_release, and its PowerShell twin). The release page shows the notes immediately.
  3. Wait for green. Let every platform's CI finish and go green.
  4. Announce. Dispatch the announce workflow (.gitea/workflows/announce.yml) with the tag. It re-asserts this file over the live release (so any late edit wins) and posts an embed to Discord #releases. Pressing "go" is the quality gate — a half-built release is never announced. Stable-only; a -rc tag is refused unless allow_prerelease=true.

Editing the notes after the tag is fine: update this file, then re-run step 4 (or PATCH the body via the API) — the announce step always re-syncs from the file, so the file stays authoritative even across a tag re-point.

Canary / -rc builds have no file here on purpose: they get no curated body and are not announced.

Voice & format

Write for the people who USE Punktfunk to stream their games and desktops — not for the people who build it. A non-engineer should finish knowing what's new and whether it affects them; an engineer should never be confused or forced to decode internals. (See any recent vX.Y.Z.md for the target.)

  1. Lead with the benefit. Each entry = what the user can now do, what now works, or what stopped going wrong — in their words. Implementation is not the story.
  2. No internal vocabulary in the body. No protocol/message names, code type names, hex codes or hardware IDs, crate/component names, or API symbols. Translate any essential detail to plain language. Name things users recognize (iPad, Apple Pencil, Steam Deck, Android TV, the Windows sign-in screen) — not subsystems.
  3. Group as New / Improved / Fixed, each a bold one-line lead-in + a tight plain explanation. Skimmable. The lead-in text before the first ## is what the Discord announcement shows, so make it a real, plain-language summary.
  4. Be specific and honest — no vague "various improvements"; a reader should know exactly what changed.
  5. Compatibility line up top, in plain terms: can they update one side at a time? does their existing setup keep working? No version numbers in the lead.
  6. All protocol / ABI / driver / embedder detail goes in ONE ## Under the hood (for developers) section at the very bottom — the only place internal names and version numbers belong, clearly optional. The old dense engineering style survives only there.

The short annotated-tag message stays separate and short (a headline + a paragraph); it is the tag object's message, not this file.