diff --git a/docs/evidence/framey-audio-arm64-2026-10-26.json b/docs/evidence/framey-audio-arm64-2026-10-26.json new file mode 100644 index 0000000..cf9e5e7 --- /dev/null +++ b/docs/evidence/framey-audio-arm64-2026-10-26.json @@ -0,0 +1,384 @@ +{ + "schemaVersion": 1, + "timeUtc": "2026-10-26T04:05:15.145624+00:00", + "baseCommit": "56bde24", + "frameOS": "0.5.6", + "decky": { + "version": "v3.3.0", + "sha256": "8ef5dcf36cbbbb6e97201a6baed5d79c4cc44ec27789fc9af1c5b6ae8f0b25b6" + }, + "scope": "Local Chromium opaque Framey panels, production SSH/CDP bridge and actual unmodified official backends in ARM64 Decky; real user audio session, silent test stream only; no worn VR", + "plugins": [ + { + "id": 38, + "name": "Volume Mixer", + "version": "1.2.1-1", + "sha256": "11b259ad234d0e97cfef4e6a2af3f1edfb0908d5482765af56b86b0a4601c5f3" + }, + { + "id": 58, + "name": "Volume Boost", + "version": "0.0.7", + "sha256": "2cc576a7f60751306d690268e227df626e59d3733680ced753de4c116629a9cc" + }, + { + "id": 144, + "name": "Mixer", + "version": "0.1.0", + "sha256": "4b3546170e5fbd5f9afad3b24555498ee51caac7cec9e4c86321b18cdd4b5106" + } + ], + "readOnlySession": { + "timeUtc": "2026-10-26T04:03:54.509107+00:00", + "before": { + "battery": [ + 100 + ], + "uid": 1000, + "arch": "aarch64", + "decky": "failed", + "panel": "inactive", + "volumeMixerLogExists": false, + "defaultSinkVolume": { + "code": 0, + "stdout": "Volume: front-left: 0 / 0% / -inf dB, front-right: 0 / 0% / -inf dB\n balance 0.00\n", + "stderr": "" + }, + "pactlInfoExit": 0, + "pwDumpExit": 0 + }, + "after": { + "battery": [ + 100 + ], + "uid": 1000, + "arch": "aarch64", + "decky": "failed", + "panel": "inactive", + "volumeMixerLogExists": false, + "defaultSinkVolume": { + "code": 0, + "stdout": "Volume: front-left: 0 / 0% / -inf dB, front-right: 0 / 0% / -inf dB\n balance 0.00\n", + "stderr": "" + }, + "pactlInfoExit": 0, + "pwDumpExit": 0 + }, + "calls": [ + { + "id": 38, + "method": "get_sink_inputs", + "args": [ + {} + ], + "legacy": true, + "version": "1.2.1-1", + "sha256": "11b259ad234d0e97cfef4e6a2af3f1edfb0908d5482765af56b86b0a4601c5f3", + "result": { + "success": true, + "streamCount": 1, + "volumes": [ + 1 + ] + } + }, + { + "id": 58, + "method": "get_volume_state", + "args": [ + { + "channel": "left" + } + ], + "legacy": true, + "version": "0.0.7", + "sha256": "2cc576a7f60751306d690268e227df626e59d3733680ced753de4c116629a9cc", + "result": { + "result": { + "result": 0, + "success": true + } + } + }, + { + "id": 58, + "method": "get_volume_state", + "args": [ + { + "channel": "right" + } + ], + "legacy": true, + "version": "0.0.7", + "sha256": "2cc576a7f60751306d690268e227df626e59d3733680ced753de4c116629a9cc", + "result": { + "result": { + "result": 0, + "success": true + } + } + }, + { + "id": 144, + "method": "get_settings", + "args": [], + "legacy": false, + "version": "0.1.0", + "sha256": "4b3546170e5fbd5f9afad3b24555498ee51caac7cec9e4c86321b18cdd4b5106", + "result": { + "result": { + "filters": [], + "boostLimit": 0 + } + } + }, + { + "id": 144, + "method": "get_playbacks", + "args": [], + "legacy": false, + "version": "0.1.0", + "sha256": "4b3546170e5fbd5f9afad3b24555498ee51caac7cec9e4c86321b18cdd4b5106", + "result": { + "count": 6, + "internalAudioNodeCount": 5, + "steamStreamCount": 1 + } + } + ], + "cleanup": { + "baseAbsent": true, + "unitAbsent": true, + "fixedLogAbsent": true + }, + "lockReleased": true + }, + "liveSilentStream": { + "before": { + "battery": [ + 100 + ], + "uid": 1000, + "arch": "aarch64", + "decky": "failed", + "panel": "inactive", + "volumeMixerLogExists": false, + "defaultSinkVolume": { + "code": 0, + "stdout": "Volume: front-left: 0 / 0% / -inf dB, front-right: 0 / 0% / -inf dB\n balance 0.00\n", + "stderr": "" + }, + "pactlInfoExit": 0, + "pwDumpExit": 0 + }, + "after": { + "battery": [ + 100 + ], + "uid": 1000, + "arch": "aarch64", + "decky": "failed", + "panel": "inactive", + "volumeMixerLogExists": false, + "defaultSinkVolume": { + "code": 0, + "stdout": "Volume: front-left: 0 / 0% / -inf dB, front-right: 0 / 0% / -inf dB\n balance 0.00\n", + "stderr": "" + }, + "pactlInfoExit": 0, + "pwDumpExit": 0 + }, + "source": "paplay --raw --format=s16le --rate=48000 --channels=2 --client-name=FrameySilentARM64 --stream-name=\"Framey ARM64 silent verification\" /dev/zero", + "writes": [ + { + "id": 38, + "method": "set_input_volume", + "args": [ + { + "index": 31400, + "volume": 0.5 + } + ], + "result": { + "result": true, + "success": true + }, + "independentReadback": [ + { + "index": 31400, + "name": "FrameySilentARM64", + "volume": { + "front-left": { + "value": 32768, + "value_percent": "50%", + "db": "-18.06 dB" + }, + "front-right": { + "value": 32768, + "value_percent": "50%", + "db": "-18.06 dB" + } + } + } + ] + }, + { + "id": 38, + "method": "set_input_volume", + "args": [ + { + "index": 31400, + "volume": 0.45 + } + ], + "result": { + "result": true, + "success": true + }, + "independentReadback": [ + { + "index": 31400, + "name": "FrameySilentARM64", + "volume": { + "front-left": { + "value": 29491, + "value_percent": "45%", + "db": "-20.81 dB" + }, + "front-right": { + "value": 29491, + "value_percent": "45%", + "db": "-20.81 dB" + } + } + } + ] + }, + { + "id": 144, + "method": "set_volume", + "args": [ + 199, + 37 + ], + "result": true, + "independentReadback": [ + { + "index": 31400, + "name": "FrameySilentARM64", + "volume": { + "front-left": { + "value": 24248, + "value_percent": "37%", + "db": "-25.91 dB" + }, + "front-right": { + "value": 24248, + "value_percent": "37%", + "db": "-25.91 dB" + } + } + } + ] + }, + { + "id": 144, + "method": "set_volume", + "args": [ + 199, + 38 + ], + "result": true, + "independentReadback": [ + { + "index": 31400, + "name": "FrameySilentARM64", + "volume": { + "front-left": { + "value": 24904, + "value_percent": "38%", + "db": "-25.21 dB" + }, + "front-right": { + "value": 24904, + "value_percent": "38%", + "db": "-25.21 dB" + } + } + } + ] + } + ], + "volumeMixerReopen": { + "id": 38, + "method": "get_sink_inputs", + "args": [ + {} + ], + "result": { + "result": [ + { + "name": "FrameySilentARM64", + "index": 31400, + "volume": 0.3800048828125 + } + ], + "success": true + } + }, + "mixerReadAfterChange": { + "id": 144, + "method": "get_playbacks", + "args": [], + "result": [ + { + "id": 199, + "name": "FrameySilentARM64", + "mediaName": "Framey ARM64 silent verification", + "volume": 38 + } + ] + }, + "volumeBoostReads": [ + { + "id": 58, + "method": "get_volume_state", + "args": [ + { + "channel": "left" + } + ], + "result": { + "result": 0, + "success": true + } + } + ], + "cleanup": { + "baseAbsent": true, + "unitAbsent": true, + "fixedLogAbsent": true + }, + "lockReleased": true + }, + "independentCleanupAudit": { + "testPathsAbsent": true, + "units": { + "framey-audio-kp0z857q58-32363fd7": "MainPID=0\nLoadState=not-found\nActiveState=inactive", + "framey-audio-kp0z857q58-c08f3f5d": "MainPID=0\nLoadState=not-found\nActiveState=inactive", + "framey-audio-kp0z857q58-c08f3f5d-silence": "MainPID=0\nLoadState=not-found\nActiveState=inactive" + }, + "silentStreamsAbsent": true + }, + "limitations": [ + "Physical audible output, default-sink writes, boost above 100%, Bluetooth playback controls and worn VR unverified.", + "Mixer also exposes internal Frame PipeWire nodes and Reset; neither was changed or invoked.", + "Private Decky/installed-plugin outer status fixture; real RPC used production framey_panel.call_method over SSH and live Steam CEF, not a deployed headset HTTP endpoint test.", + "Mixer filter save/restart was verified on amd64 in the earlier evidence, not repeated on ARM64." + ], + "catalogRefresh": { + "timeUtc": "2026-10-26T04:11:59.449535+00:00", + "visibleCount": 116, + "idsVersionsDigestsUnchanged": true + } +} diff --git a/docs/evidence/framey-audio-arm64-2026-10-26.md b/docs/evidence/framey-audio-arm64-2026-10-26.md new file mode 100644 index 0000000..8b98197 --- /dev/null +++ b/docs/evidence/framey-audio-arm64-2026-10-26.md @@ -0,0 +1,111 @@ +# Official audio plugins on the ARM64 Frame + +Volume Mixer 1.2.1-1 (38) and Mixer 0.1.0 (144) now qualify as **works for +per-app volume control**. Their exact official, unmodified Python backends ran +in published Decky 3.3.0 ARM64 on Frame OS 0.5.6. Local Chromium rendered the +actual Framey panels and changed only a deliberately created silent playback +stream in the Frame's real user audio session. Independent Pulse readbacks +confirmed the changes. This is useful backend behavior, not initializer-only +or fake-backend evidence. + +Volume Boost 0.0.7 (58) remains **partial**. Its real ARM64 default-sink reads +matched independent `pactl` reads, and its controls rendered. Default-sink writes +were denied throughout the real-Frame run. Its earlier slider/numeric write +checks used an isolated amd64 virtual sink. + +[Digest-pinned observations and cleanup](framey-audio-arm64-2026-10-26.json) +record both runs. No physical audible output or worn-VR result is claimed. + +| Plugin | Real Frame result | Remaining limits | +| --- | --- | --- | +| Volume Mixer | `pulsectl`/`ravel` import; real Pulse session discovery; silent-stream slider click 100 → 50%, ArrowDown → 45%; reopen reads back the 38% subsequently set by Mixer | Bluetooth discovery/playback commands, audible output and worn-VR input unverified. The range input rounds the reopened 0.38000488 backend value to its configured step; no extra write occurred. | +| Volume Boost | `pactl` default sink and stereo channel parsing; both backend reads return 0 and agree with independent 0% / 0% sink reads; local panel shows 0 | No real default-sink writes or boosts; no audible output or worn-VR result. Zero alone is not proof: upstream returns 0 when its command fails. | +| Mixer | `pw-dump`/`wpctl` available; real playbacks/settings reads; exact silent-stream numeric input 37%, ArrowUp → 38%, independently read back | Exposes internal Frame PipeWire nodes as well as apps. Internal-node controls and Reset were not exercised. Filter persistence passed on amd64 earlier, not ARM64. Audible output and worn-VR input unverified. | + +## Runtime and transport + +The normal atomic `/tmp/frame-test.lock` was acquired separately for each run. +An existing owner would abort testing; the lock was never stolen. The headset +was not woken, and no power setting was changed. + +The actual Frame UID is 1000. The legacy plugins' hard-coded +`XDG_RUNTIME_DIR=/run/user/1000` therefore reaches this Frame's existing audio +session. Volume Mixer's bundled pure Python wrappers successfully loaded the +system ARM64 Pulse and D-Bus libraries. No native rebuild was needed. It also +sets `HOME=/home/deck` inside its own plugin process; this test does not establish +that arbitrary Deck paths work on the Frame. + +The upstream `PluginLoader-arm64` release was verified against GitHub's +published SHA-256 and ELF machine 183 before transfer. Two private, bounded, +removable user-service installs used their own Decky plugins/settings bases. +Neither service was enabled. The normal managed Decky service was already +failed, and the normal headset-panel service inactive; both states remained +unchanged. A pre-existing `/tmp/VolumeMixer-decky.log` would have aborted the +run because the upstream plugin truncates that fixed path during import. + +The local relay served actual `ui/headset.html`, vendored React, `framey-host.js` +and digest-checked official frontend bytes in an opaque `allow-scripts` iframe. +Only outer status/install responses were fixtures. Plugin RPC used production +`framey_panel.call_method`, SSH through lxso2, `frame_steam.Page`, the live Steam +CEF `DeckyBackend.call`, and actual Decky plugin subprocesses. Private install +paths were redirected to the temporary base. No second Decky websocket client +was attached. This does not verify the deployed headset HTTP endpoint or a VR +compositor interaction. + +## Safe control check + +The first run was read-only. Independent `pactl info`, default-sink volume and +`pw-dump` commands exited successfully, so empty/zero fallback values were not +accepted on their own. Volume Mixer saw a live Steam stream; Mixer also saw +Frame spatialization, echo-cancellation and ALSA internal nodes. + +For the second run, a separate task-owned transient user service ran: + +```sh +paplay --raw --format=s16le --rate=48000 --channels=2 \ + --client-name=FrameySilentARM64 \ + --stream-name='Framey ARM64 silent verification' /dev/zero +``` + +This sends zero-valued samples to the existing user server. It is an explicit +silent client, not the earlier private null-server fixture. No server, device, +default-route or physical-sink configuration was changed. The relay resolved +its live stream IDs before every write and allowed only this exact application +name, bounded to 80% volume. The spatialization node with a similar prefix was +excluded. All Volume Boost writes, Mixer Reset/settings writes and Bluetooth +commands were denied. Existing streams and internal nodes were never write +targets. This broader real-session check supersedes the earlier suggested +null-server-only ARM64 follow-up; that older fixture could not prove access to +the Frame's real session. + +Every browser-triggered volume RPC was followed by independent +`pactl --format=json list sink-inputs` channel readback. Only the named silent +stream's rows are published. Background streams can appear/disappear naturally; +no whole-session stability claim is made. + +## Cleanup and catalog interpretation + +Both runs removed their private Decky units/bases and the test-created fixed +plugin log. The live run also stopped its transient silent client. Decky's main +process exited during shutdown but left children waiting; those remaining +processes were killed only within the test service's systemd cgroup before +cleanup completed. Both locks were released after cleanup. An independent +fresh-lock audit confirmed all three test units unloaded/inactive with PID 0, +private paths absent, and no named silent stream. Battery was 100 → 100 and +independent default-sink reads stayed 0% / 0% in both runs. + +The canonical store data and generated compatibility table now report +**3 works / 48 partial / 54 broken / 11 N/A**. “Works” describes the tested +per-app control behavior; read each row's remaining limits. Historical +[fake-Frame archive checks](framey-module-lookup-2026-10-26.md) cover transport +with plugin execution stubbed, and the +[earlier local audio checks](framey-audio-backends-2026-10-26.md) cover isolated +amd64 controls/filter persistence. Neither is relabelled as a real ARM64 test. + +## Repository checks + +The full Python suite passed 1,621 tests (16 skips), and the focused Framey +suite passed all 43 tests. `scripts/framey-compatibility-doc.py --check` and +`git diff --check` passed. A fresh official-store fetch at 04:11:59 UTC found +all 116 IDs, versions and digests unchanged. This PR changes catalog/evidence +and generated documentation; it adds no backend shim or plugin patch. diff --git a/docs/evidence/framey-audio-backends-2026-10-26.md b/docs/evidence/framey-audio-backends-2026-10-26.md index ba7e4d7..6f75772 100644 --- a/docs/evidence/framey-audio-backends-2026-10-26.md +++ b/docs/evidence/framey-audio-backends-2026-10-26.md @@ -1,5 +1,9 @@ # Official audio plugins: local real-backend checks +Historical amd64 run. The [later ARM64 Frame check](framey-audio-arm64-2026-10-26.md) +supersedes the ARM64 gaps and follow-up plan below; it promotes the two per-app +mixers to works for their verified scope. Volume Boost remains partial. + Volume Mixer 1.2.1-1 (38), Volume Boost 0.0.7 (58) and Mixer 0.1.0 (144) passed useful audio controls in local Chromium with their **unmodified official Python backends running in actual Decky 3.3.0**. All three remain **partial**: diff --git a/docs/framey-compatibility.md b/docs/framey-compatibility.md index df420d9..0b90498 100644 --- a/docs/framey-compatibility.md +++ b/docs/framey-compatibility.md @@ -4,7 +4,7 @@ Snapshot: 2026-10-25T23:19:48.854504+00:00; 116 current visible official plugins This table and both store views use [`ui/framey-compatibility.json`](../ui/framey-compatibility.json). Results apply only to the exact store ID, version and SHA-256. A changed digest/version is **unverified**. Regenerate this document with `python3 scripts/framey-compatibility-doc.py`; use `--check` in review. -**Works: 1 · Partial: 50 · Broken: 54 · N/A: 11.** +**Works: 3 · Partial: 48 · Broken: 54 · N/A: 11.** - **Works** requires verified useful plugin behavior with its real backend. Read the reason for the verified scope and remaining limits; it does not imply worn-VR verification. - **Partial** means only a subset or a local fixture scope was verified, often just frontend/settings initialization. The remaining backend/device functionality is unverified; read the reason for the exact scope. @@ -27,7 +27,7 @@ Open the browser audit URL in local Chromium, run `runAudit()` and inspect/downl The current published digests are pinned in the JSON; if the store changed, retain/download those exact archives for reproduction. Audit downloads permit larger ZIPs for inspection; production installer limits remain 50 MiB ZIP / 150 MiB unpacked / 30 MiB per member. -After the VR job released the shared lock, this audit acquired it and used a private temporary Decky 3.3.0 ARM64 user service. Read-only ProtonDB `get_setting` and Steam Status `get_settings` calls succeeded through the live Steam CEF websocket. The service and private base were removed and the lock released; normal managed services stayed inactive, battery was 100 → 99, and no power setting was changed. [Redacted results](evidence/framey-official-backend-2026-10-25.json) record exactly what ran. A [2026-10-26 follow-up](evidence/framey-events-backend-2026-10-26.json) verified default Notebook drawing/save/reopen across a real backend restart and Simple Timer start/cancel, countdown/completion events, a visible toast and persisted recents/subtle mode. Only private test settings were written. Simple Timer remains partial because its own expired-timer startup raises a missing `timer_task` error; sound/suspend are unsupported. A [local audio follow-up](evidence/framey-audio-backends-2026-10-26.md) exercised Volume Mixer, Volume Boost and Mixer through real Decky 3.3.0 amd64 backends on private silent virtual audio targets. Sliders, numeric volume entry, independent server readbacks and Mixer filter persistence across a runtime restart passed. These three stay partial: real ARM64 Frame audio dependencies/session mapping remain unverified because the shared headset lock was occupied. A [library context follow-up](evidence/framey-library-context-2026-10-26.md) read 1,106 app overviews, 895 game IDs and the current public Steam ID from real Frame CEF under the shared lock. Local Chromium replayed this detached snapshot to render Deck Settings game selection, Steamback's empty save panel and PlayTime statistics/settings. Steamback and PlayTime used actual Decky 3.3.0 amd64 backends in an isolated container; their ARM64 backends and automatic game hooks remain unverified. Shotty's frontend now starts, but its published backend fails on missing `click`; it stays broken. A [chunked frontend follow-up](evidence/framey-deck-shelves-browser-2026-10-26.md) loaded Deck Shelves 2.0.0 through a managed JavaScript module route and rendered its settings in an opaque local Chromium panel. Its backend was denied; Steam Home shelves and worn VR remain unverified. A [local module lookup follow-up](evidence/framey-module-lookup-2026-10-26.md) supplies a finite registry of Framey-local controls and CSS. TabMaster QAM/docs now render; Steam library-tab editing remains unavailable. Junk-Store loading/error views render, but its real backend cannot execute the extracted startup script, so it stays broken. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. TabMaster/Junk-Store ran in actual isolated amd64 Decky; no ARM64 or worn-VR result is claimed. Beyond the documented checks, official backends remain unexecuted. The separate VR job proves Frame Control/sample compositor rendering, not any official plugin. No worn-VR official-plugin result is claimed. A [local UI follow-up](evidence/framey-ui-fallbacks-2026-10-26.json) rendered Pause Games and Tailscale Control settings with all backend/network actions denied; it does not verify process pausing or Tailscale changes. A [read-only Steam bridge follow-up](evidence/framey-steam-reads-2026-10-26.json) verified actual Frame country, install folders and system information, plus IsThereAnyDeal's country dropdown in local Chromium. The installed-plugin status was fixture-shaped in that relay; plugin backends stayed denied and the deployed headset HTTP endpoint remains unverified. Earlier focused checks cover [ProtonDB](evidence/framey-browser-2026-10-25.md), [Steam Status/cache](evidence/framey-cache-browser-2026-10-25.md), [Storage Cleaner](evidence/framey-api-v1-browser-2026-10-25.md), and [legacy MusicControl](evidence/framey-legacy-2026-10-25.md). +After the VR job released the shared lock, this audit acquired it and used a private temporary Decky 3.3.0 ARM64 user service. Read-only ProtonDB `get_setting` and Steam Status `get_settings` calls succeeded through the live Steam CEF websocket. The service and private base were removed and the lock released; normal managed services stayed inactive, battery was 100 → 99, and no power setting was changed. [Redacted results](evidence/framey-official-backend-2026-10-25.json) record exactly what ran. A [2026-10-26 follow-up](evidence/framey-events-backend-2026-10-26.json) verified default Notebook drawing/save/reopen across a real backend restart and Simple Timer start/cancel, countdown/completion events, a visible toast and persisted recents/subtle mode. Only private test settings were written. Simple Timer remains partial because its own expired-timer startup raises a missing `timer_task` error; sound/suspend are unsupported. A [local audio follow-up](evidence/framey-audio-backends-2026-10-26.md) exercised Volume Mixer, Volume Boost and Mixer through real Decky 3.3.0 amd64 backends on private silent virtual audio targets. Sliders, numeric volume entry, independent server readbacks and Mixer filter persistence across a runtime restart passed. An [ARM64 audio follow-up](evidence/framey-audio-arm64-2026-10-26.md) verified the unmodified official backends in actual Decky 3.3.0 on the Frame user audio session. Volume Mixer and Mixer now qualify as works for per-app volume: Chromium controls changed only a named silent stream, with independent Pulse readbacks. Volume Boost stays partial: default-sink reads matched, but real sink writes were denied. Audible output, Bluetooth playback and worn VR remain unverified. A [library context follow-up](evidence/framey-library-context-2026-10-26.md) read 1,106 app overviews, 895 game IDs and the current public Steam ID from real Frame CEF under the shared lock. Local Chromium replayed this detached snapshot to render Deck Settings game selection, Steamback's empty save panel and PlayTime statistics/settings. Steamback and PlayTime used actual Decky 3.3.0 amd64 backends in an isolated container; their ARM64 backends and automatic game hooks remain unverified. Shotty's frontend now starts, but its published backend fails on missing `click`; it stays broken. A [chunked frontend follow-up](evidence/framey-deck-shelves-browser-2026-10-26.md) loaded Deck Shelves 2.0.0 through a managed JavaScript module route and rendered its settings in an opaque local Chromium panel. Its backend was denied; Steam Home shelves and worn VR remain unverified. A [local module lookup follow-up](evidence/framey-module-lookup-2026-10-26.md) supplies a finite registry of Framey-local controls and CSS. TabMaster QAM/docs now render; Steam library-tab editing remains unavailable. Junk-Store loading/error views render, but its real backend cannot execute the extracted startup script, so it stays broken. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. TabMaster/Junk-Store ran in actual isolated amd64 Decky; no ARM64 or worn-VR result is claimed. Beyond the documented checks, official backends remain unexecuted. The separate VR job proves Frame Control/sample compositor rendering, not any official plugin. No worn-VR official-plugin result is claimed. A [local UI follow-up](evidence/framey-ui-fallbacks-2026-10-26.json) rendered Pause Games and Tailscale Control settings with all backend/network actions denied; it does not verify process pausing or Tailscale changes. A [read-only Steam bridge follow-up](evidence/framey-steam-reads-2026-10-26.json) verified actual Frame country, install folders and system information, plus IsThereAnyDeal's country dropdown in local Chromium. The installed-plugin status was fixture-shaped in that relay; plugin backends stayed denied and the deployed headset HTTP endpoint remains unverified. Earlier focused checks cover [ProtonDB](evidence/framey-browser-2026-10-25.md), [Steam Status/cache](evidence/framey-cache-browser-2026-10-25.md), [Storage Cleaner](evidence/framey-api-v1-browser-2026-10-25.md), and [legacy MusicControl](evidence/framey-legacy-2026-10-25.md). ## Every current plugin @@ -57,7 +57,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say | 35: MoonDeck 1.13.0 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: moondeck/python/externals/yarl/_quoting_c.cpython-313-x86_64-linux-gnu.so. Frontend initializes; native CPython wheels and executables in the published archive are x86_64. | static archive, local browser, fake-Frame | | 36: SteamGridDB 1.8.1 | 1 / 2 | broken | Local module mapping is available; frontend still requires the Steam LibraryContextMenu implementation, which has no target in the isolated Framey panel. | static archive, local browser, fake-Frame | | 37: Discord Status 1.5.0 | 1 / 2 | broken | Detached app overviews are now available, but RunningApps/lifetime observations and Steam artwork helpers still lack a live mapping. Discord activity integration remains unavailable/unverified. | static archive, local browser, fake-Frame, real Frame SSH | -| 38: Volume Mixer 1.2.1-1 | legacy / legacy | partial | Local Chromium discovers and changes a private silent stream through the actual Decky 3.3.0 Linux backend, with independent Pulse readback. Frame ARM64 libraries/audio session and Bluetooth playback controls remain unverified. | static archive, local browser, fake-Frame, isolated Linux backend | +| 38: Volume Mixer 1.2.1-1 | legacy / legacy | works | Per-app stream discovery and slider/keyboard volume changes pass in local Chromium through real Decky 3.3.0 ARM64 on the Frame audio session, with independent Pulse readback of a silent test stream. Bluetooth playback, audible output and worn-VR controls unverified. | static archive, local browser, fake-Frame, isolated Linux backend, real Frame SSH | | 40: Controller Tools 2.0.2 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: ControllerTools/bin/backend. Frontend audit failed: Audit blocks WebSocket. | static archive, local browser, fake-Frame | | 43: Tailscale Control 0.1.3 | legacy / legacy | partial | Settings render locally after the SuspensefulImage fallback. Tailscale daemon/state, connection and exit-node changes unverified; bundled localhost QR asset remains unavailable. No network settings were changed. | static archive, local browser, fake-Frame | | 44: DeckMTP 1.0.5 | legacy / legacy | broken | Plugin contains a non-ARM64 Linux binary: DeckMTP/bin/umtprd. | static archive, local browser, fake-Frame | @@ -68,7 +68,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say | 52: Game Theme Music 1.7.1-1 | 1 / 2 | broken | Frontend audit failed: Cannot read properties of null (reading 'type'). | static archive, local browser, fake-Frame | | 53: Shotty 0.1.0 | legacy / legacy | broken | Library snapshot fixes the frontend allApps crash. Actual published Decky 3.3.0 amd64 backend fails importing click.get_app_dir (ModuleNotFoundError); the archive does not bundle click. Screenshot aggregation/rescue was not run. | static archive, local browser, fake-Frame, real Frame SSH | | 56: MangoPeel 0.0.7 | 1 / 2 | partial | Initializer succeeds; gamescope/MangoHud actions and backend are unverified. | static archive, local browser, fake-Frame | -| 58: Volume Boost 0.0.7 | legacy / legacy | partial | Local Chromium sync/separate sliders, numeric volume entry and cache reopen pass through the actual Decky 3.3.0 backend on a private virtual stereo sink. Frame pactl/default sink, boost above 100% and physical audio remain unverified. | static archive, local browser, fake-Frame, isolated Linux backend | +| 58: Volume Boost 0.0.7 | legacy / legacy | partial | Real Decky 3.3.0 ARM64 default-sink reads match independent Frame pactl channel volumes; controls render locally. Sliders/numeric writes passed on an isolated amd64 virtual sink only. Real default-sink writes, boost above 100%, audible output and worn VR unverified. | static archive, local browser, fake-Frame, isolated Linux backend, real Frame SSH | | 59: Web Browser 1.4.3 | legacy / legacy | broken | Frontend audit failed: deckyFrontendLib.getReactRoot is not a function. | static archive, local browser, fake-Frame | | 60: DeckyFileServer 1.2.0 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: DeckyFileServer/bin/backend. | static archive, local browser, fake-Frame | | 61: TabMaster 2.15.1 | 1 / 2 | partial | Local Chromium rendered the QAM and navigable Overview/Filters documentation with an actual Decky 3.3.0 amd64 backend. Library-tab editing remains unavailable: Steam login/library patches and MobX reactions have no target. ARM64 and worn VR unverified. | static archive, local browser, fake-Frame | @@ -149,7 +149,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say | 141: DeckyClocker 1.0.0 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame | | 142: MuteOnSleep 1.0.1 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame | | 143: Desktop Apps 0.1.0 | 1 / 2 | partial | Initializer succeeds; Flatpak app discovery and Steam shortcut changes unverified. | static archive, local browser, fake-Frame | -| 144: Mixer 0.1.0 | 1 / 2 | partial | Local Chromium numeric stream volume and filter save/reopen pass through the actual Decky 3.3.0 Linux backend; filters survive its restart. Frame pw-dump/wpctl, real audio session and worn VR remain unverified. | static archive, local browser, fake-Frame, isolated Linux backend | +| 144: Mixer 0.1.0 | 1 / 2 | works | Per-app discovery and numeric volume changes pass in local Chromium through real Decky 3.3.0 ARM64 on the Frame audio session, independently read back on a silent test stream. Filters persist on amd64; ARM64 filter persistence, Reset, internal audio nodes, audible output and worn VR unverified. | static archive, local browser, fake-Frame, isolated Linux backend, real Frame SSH | | 145: VARTA 1.0.21 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame | ## API, UI and backend inventory diff --git a/scripts/framey-compatibility-doc.py b/scripts/framey-compatibility-doc.py index e600dda..1b264d5 100644 --- a/scripts/framey-compatibility-doc.py +++ b/scripts/framey-compatibility-doc.py @@ -54,7 +54,7 @@ def render(data): 'A [local audio follow-up](evidence/framey-audio-backends-2026-10-26.md) exercised Volume Mixer, Volume Boost and Mixer ' 'through real Decky 3.3.0 amd64 backends on private silent virtual audio targets. Sliders, numeric volume entry, ' 'independent server readbacks and Mixer filter persistence across a runtime restart passed. ' - 'These three stay partial: real ARM64 Frame audio dependencies/session mapping remain unverified because the shared headset lock was occupied. ' + 'An [ARM64 audio follow-up](evidence/framey-audio-arm64-2026-10-26.md) verified the unmodified official backends in actual Decky 3.3.0 on the Frame user audio session. Volume Mixer and Mixer now qualify as works for per-app volume: Chromium controls changed only a named silent stream, with independent Pulse readbacks. Volume Boost stays partial: default-sink reads matched, but real sink writes were denied. Audible output, Bluetooth playback and worn VR remain unverified. ' 'A [library context follow-up](evidence/framey-library-context-2026-10-26.md) read 1,106 app overviews, 895 game IDs ' 'and the current public Steam ID from real Frame CEF under the shared lock. Local Chromium replayed this detached snapshot ' 'to render Deck Settings game selection, Steamback\'s empty save panel and PlayTime statistics/settings. ' diff --git a/ui/framey-compatibility.json b/ui/framey-compatibility.json index 17b2ee5..7db911d 100644 --- a/ui/framey-compatibility.json +++ b/ui/framey-compatibility.json @@ -2990,14 +2990,15 @@ "https://github.com/ldo/dbussy", "https://github.com/mk-fg/python-pulse-control" ], - "status": "partial", - "reason": "Local Chromium discovers and changes a private silent stream through the actual Decky 3.3.0 Linux backend, with independent Pulse readback. Frame ARM64 libraries/audio session and Bluetooth playback controls remain unverified.", + "status": "works", + "reason": "Per-app stream discovery and slider/keyboard volume changes pass in local Chromium through real Decky 3.3.0 ARM64 on the Frame audio session, with independent Pulse readback of a silent test stream. Bluetooth playback, audible output and worn-VR controls unverified.", "blockInstall": false, "verification": [ "static archive", "local browser", "fake-Frame", - "isolated Linux backend" + "isolated Linux backend", + "real Frame SSH" ], "browser": { "id": 38, @@ -4030,13 +4031,14 @@ "https://github.com/saumya-banthia/volume-boost.git" ], "status": "partial", - "reason": "Local Chromium sync/separate sliders, numeric volume entry and cache reopen pass through the actual Decky 3.3.0 backend on a private virtual stereo sink. Frame pactl/default sink, boost above 100% and physical audio remain unverified.", + "reason": "Real Decky 3.3.0 ARM64 default-sink reads match independent Frame pactl channel volumes; controls render locally. Sliders/numeric writes passed on an isolated amd64 virtual sink only. Real default-sink writes, boost above 100%, audible output and worn VR unverified.", "blockInstall": false, "verification": [ "static archive", "local browser", "fake-Frame", - "isolated Linux backend" + "isolated Linux backend", + "real Frame SSH" ], "browser": { "id": 58, @@ -13272,14 +13274,15 @@ "https://github.com/allmazz/decky-volume-mixer", "https://github.com/allmazz/decky-volume-mixer.git" ], - "status": "partial", - "reason": "Local Chromium numeric stream volume and filter save/reopen pass through the actual Decky 3.3.0 Linux backend; filters survive its restart. Frame pw-dump/wpctl, real audio session and worn VR remain unverified.", + "status": "works", + "reason": "Per-app discovery and numeric volume changes pass in local Chromium through real Decky 3.3.0 ARM64 on the Frame audio session, independently read back on a silent test stream. Filters persist on amd64; ARM64 filter persistence, Reset, internal audio nodes, audible output and worn VR unverified.", "blockInstall": false, "verification": [ "static archive", "local browser", "fake-Frame", - "isolated Linux backend" + "isolated Linux backend", + "real Frame SSH" ], "browser": { "id": 144,