keep_host_audio shipped in 0.32.0 wired end to end — the setting, the CLIENT_CAP_KEEP_HOST_AUDIO ask, the host's capture policy — but only three surfaces ever offered it: the Linux GTK client, the Windows client, and the desktop console. Apple and Android carried no reference to it at all, so the one place a phone or an Apple TV would look for "why did my PC go quiet" had nothing to find.
Reported from the field: the option could not be found on the Apple client, with the (correct) guess that other clients were missing it too.
There is no shared settings schema — each client hand-mirrors trust::Settings — so this row simply never got mirrored.
What changed
Apple gains the full tier-P treatment: a keepHostAudio defaults key, the EffectiveSettings field, the StreamProfile overlay (so a per-host profile can keep the study PC's headphones live while the TV profile mutes them), the Audio-section row, and the bit itself OR'd into the connect's clientCaps beside the presenter caps.
Android gains the same across Settings, Profiles — including the KNOWN key set, without which the key reads as unknown carry-through — the settings row, the console JSON both ways, and a new keepHostAudio argument threaded through nativeConnect into the JNI caps expression.
pf-console-ui had parked RowId::KeepHostAudio in desktop_only with a comment saying "until the Android session advertises the bit". It does now, so the gate comes off and the order-sensitive split test loses its entry. Without this the Android console would still have hidden the row after the client was wired.
The C ABI never exported the constant. client_caps is a passthrough byte, so nothing needs a version bump — but cbindgen had no rename entry and emitted a bare CLIENT_CAP_KEEP_HOST_AUDIO into every embedder's namespace, the exact pollution R21 exists to prevent. It now carries the PUNKTFUNK_ prefix its AUDIO_HIRES sibling has, plus the compile-time drift assert.
Captions are the Linux client's wording verbatim, and the row sits between audio quality and the microphone on all four clients, because a setting that reads differently per platform is the same bug in a smaller font. The docs line claiming "Linux, Windows and the desktop console" now says everywhere.
Verification
Check
Result
swift build (Apple)
clean
Apple unit tests
384 passed, 0 failed
:app:compileDebugKotlin
BUILD SUCCESSFUL
:kit:cargoNdkClippy
clean — covers pf-console-ui + punktfunk-client-android under the Android target
CHANGELOG deliberately untouched — this repo writes it at release time.
Follow-up worth considering
The root cause is structural: with no shared settings schema, every new client setting is ~6 manual edits per client and any miss is silent until a user reports it. That is the pending settings-schema programme, out of scope here.
`keep_host_audio` shipped in 0.32.0 wired end to end — the setting, the `CLIENT_CAP_KEEP_HOST_AUDIO` ask, the host's capture policy — but only three surfaces ever offered it: the Linux GTK client, the Windows client, and the desktop console. **Apple and Android carried no reference to it at all**, so the one place a phone or an Apple TV would look for "why did my PC go quiet" had nothing to find.
Reported from the field: the option could not be found on the Apple client, with the (correct) guess that other clients were missing it too.
There is no shared settings schema — each client hand-mirrors `trust::Settings` — so this row simply never got mirrored.
## What changed
**Apple** gains the full tier-P treatment: a `keepHostAudio` defaults key, the `EffectiveSettings` field, the `StreamProfile` overlay (so a per-host profile can keep the study PC's headphones live while the TV profile mutes them), the Audio-section row, and the bit itself OR'd into the connect's `clientCaps` beside the presenter caps.
**Android** gains the same across `Settings`, `Profiles` — including the `KNOWN` key set, without which the key reads as unknown carry-through — the settings row, the console JSON both ways, and a new `keepHostAudio` argument threaded through `nativeConnect` into the JNI caps expression.
**`pf-console-ui`** had parked `RowId::KeepHostAudio` in `desktop_only` with a comment saying *"until the Android session advertises the bit"*. It does now, so the gate comes off and the order-sensitive split test loses its entry. Without this the Android console would still have hidden the row after the client was wired.
**The C ABI** never exported the constant. `client_caps` is a passthrough byte, so nothing needs a version bump — but cbindgen had no rename entry and emitted a bare `CLIENT_CAP_KEEP_HOST_AUDIO` into every embedder's namespace, the exact pollution R21 exists to prevent. It now carries the `PUNKTFUNK_` prefix its `AUDIO_HIRES` sibling has, plus the compile-time drift assert.
Captions are the Linux client's wording verbatim, and the row sits between audio quality and the microphone on all four clients, because a setting that reads differently per platform is the same bug in a smaller font. The docs line claiming "Linux, Windows and the desktop console" now says everywhere.
## Verification
| Check | Result |
|---|---|
| `swift build` (Apple) | clean |
| Apple unit tests | 384 passed, 0 failed |
| `:app:compileDebugKotlin` | BUILD SUCCESSFUL |
| `:kit:cargoNdkClippy` | clean — covers `pf-console-ui` + `punktfunk-client-android` under the Android target |
| `pf-console-ui` tests (Linux container) | 205 passed, 0 failed, incl. `platform_row_split_hides_only_the_other_platforms_concepts` |
| `cargo fmt --all --check` | clean |
CHANGELOG deliberately untouched — this repo writes it at release time.
## Follow-up worth considering
The root cause is structural: with no shared settings schema, every new client setting is ~6 manual edits per client and any miss is silent until a user reports it. That is the pending settings-schema programme, out of scope here.
`keep_host_audio` shipped in 0.32.0 wired end to end — the setting, the
`CLIENT_CAP_KEEP_HOST_AUDIO` ask, the host's capture policy — but only three
surfaces ever offered it: the Linux GTK client, the Windows client, and the
desktop console. Apple and Android carried no reference to it at all, so the
one place a phone or an Apple TV would look for "why did my PC go quiet" had
nothing to find. There is no shared settings schema; each client hand-mirrors
`trust::Settings`, and this row simply never got mirrored.
Apple gains the full tier-P treatment: a `keepHostAudio` defaults key, the
`EffectiveSettings` field, the `StreamProfile` overlay (so a per-host profile
can keep the study PC's headphones live while the TV profile mutes them), the
Audio-section row, and the bit itself OR'd into the connect's `clientCaps`
beside the presenter caps. Android gains the same across `Settings`,
`Profiles` — including the `KNOWN` key set, without which the key reads as
unknown carry-through — the settings row, the console JSON both ways, and a
new `keepHostAudio` argument threaded through `nativeConnect` into the JNI
caps expression.
`pf-console-ui` had parked `RowId::KeepHostAudio` in `desktop_only` with a
comment saying "until the Android session advertises the bit". It does now, so
the gate comes off and the order-sensitive split test loses its entry.
The C ABI never exported the constant: `client_caps` is a passthrough byte, so
nothing needed a version bump, but cbindgen had no rename entry and emitted a
bare `CLIENT_CAP_KEEP_HOST_AUDIO` into every embedder's namespace — the exact
pollution R21 exists to prevent. It now carries the `PUNKTFUNK_` prefix its
`AUDIO_HIRES` sibling has, plus the compile-time drift assert.
Captions are the Linux client's wording verbatim, and the row sits between
audio quality and the microphone on all four clients, because a setting that
reads differently per platform is the same bug in a smaller font. The docs
line claiming "Linux, Windows and the desktop console" now says everywhere.
Verified: swift build + 384 Apple tests; `:app:compileDebugKotlin`;
`:kit:cargoNdkClippy` over pf-console-ui and the Android native crate; and all
205 pf-console-ui tests on Linux in a container, the split test among them.
`check-docs-drift.sh` matches on the `PUNKTFUNK_*` shape, which cannot tell an
environment variable from a cbindgen-exported ABI constant — so exporting
`PUNKTFUNK_CLIENT_CAP_KEEP_HOST_AUDIO` read as a new undocumented knob and
turned the job red. Every sibling is already listed for exactly this reason:
the four other `CLIENT_CAP_*`, all eight `HOST_CAP_*`, all eight
`VIDEO_CAP_*`. This one goes beside them, in sort order.
It is not documentation debt being waved through. The bit's user-facing half
is the "Keep host audio playing" row, already written up in client-settings.md
and pointed at from the `PUNKTFUNK_AUDIO_OUTPUT_MODE` table; the embedder's
half is the doc comment cbindgen carries into the header. There is no
configuration surface here to document, because there is no variable.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
keep_host_audioshipped in 0.32.0 wired end to end — the setting, theCLIENT_CAP_KEEP_HOST_AUDIOask, the host's capture policy — but only three surfaces ever offered it: the Linux GTK client, the Windows client, and the desktop console. Apple and Android carried no reference to it at all, so the one place a phone or an Apple TV would look for "why did my PC go quiet" had nothing to find.Reported from the field: the option could not be found on the Apple client, with the (correct) guess that other clients were missing it too.
There is no shared settings schema — each client hand-mirrors
trust::Settings— so this row simply never got mirrored.What changed
Apple gains the full tier-P treatment: a
keepHostAudiodefaults key, theEffectiveSettingsfield, theStreamProfileoverlay (so a per-host profile can keep the study PC's headphones live while the TV profile mutes them), the Audio-section row, and the bit itself OR'd into the connect'sclientCapsbeside the presenter caps.Android gains the same across
Settings,Profiles— including theKNOWNkey set, without which the key reads as unknown carry-through — the settings row, the console JSON both ways, and a newkeepHostAudioargument threaded throughnativeConnectinto the JNI caps expression.pf-console-uihad parkedRowId::KeepHostAudioindesktop_onlywith a comment saying "until the Android session advertises the bit". It does now, so the gate comes off and the order-sensitive split test loses its entry. Without this the Android console would still have hidden the row after the client was wired.The C ABI never exported the constant.
client_capsis a passthrough byte, so nothing needs a version bump — but cbindgen had no rename entry and emitted a bareCLIENT_CAP_KEEP_HOST_AUDIOinto every embedder's namespace, the exact pollution R21 exists to prevent. It now carries thePUNKTFUNK_prefix itsAUDIO_HIRESsibling has, plus the compile-time drift assert.Captions are the Linux client's wording verbatim, and the row sits between audio quality and the microphone on all four clients, because a setting that reads differently per platform is the same bug in a smaller font. The docs line claiming "Linux, Windows and the desktop console" now says everywhere.
Verification
swift build(Apple):app:compileDebugKotlin:kit:cargoNdkClippypf-console-ui+punktfunk-client-androidunder the Android targetpf-console-uitests (Linux container)platform_row_split_hides_only_the_other_platforms_conceptscargo fmt --all --checkCHANGELOG deliberately untouched — this repo writes it at release time.
Follow-up worth considering
The root cause is structural: with no shared settings schema, every new client setting is ~6 manual edits per client and any miss is silent until a user reports it. That is the pending settings-schema programme, out of scope here.