From d5e62f643d462b7070f27c2c47b11b4aa9982094 Mon Sep 17 00:00:00 2001 From: SAPHID Date: Mon, 26 Oct 2026 07:26:21 +0000 Subject: [PATCH 1/2] Framey: tolerate missing Steam React root in legacy panels --- .../evidence/framey-web-browser-2026-10-26.md | 30 +++++++++++++++++++ docs/framey-compatibility.md | 4 +-- scripts/framey-compatibility-doc.py | 1 + tests/page/framey_actions.mjs | 3 ++ ui/framey-compatibility.json | 16 ++++++++-- ui/framey-host.js | 5 +++- 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 docs/evidence/framey-web-browser-2026-10-26.md diff --git a/docs/evidence/framey-web-browser-2026-10-26.md b/docs/evidence/framey-web-browser-2026-10-26.md new file mode 100644 index 0000000..14a7053 --- /dev/null +++ b/docs/evidence/framey-web-browser-2026-10-26.md @@ -0,0 +1,30 @@ +# Official Web Browser 1.4.3 frontend follow-up + +The exact official Decky store archive for ID 59 is 91,859 bytes and matched +SHA-256 `1192864fddc5d72550346b8dff02c21d71f0c40a06ac41c4e67bb6220d267f9d`. +Its legacy bundle calls `deckyFrontendLib.getReactRoot` when attempting to patch +Steam's main menu and search bar. The prior full-catalog audit recorded +`getReactRoot is not a function` and initializer failure. + +Framey's isolated iframe has no Steam React root. The host now exposes +`getReactRoot()` with a **null** result, consistent with its existing inert +`findInReactTree()` lookup. It never returns a fabricated Steam tree or permits +patching the user's Steam UI. The focused Node host test checks this contract. + +A focused local Chromium run used the verified archive through +`scripts/framey-audit-browser.py`, with every backend method, fetch and +WebSocket denied. The exact frontend reported `ready=true` with no initializer +error after 2.5 seconds, and again during a longer ten-second observation. +It attempted `set_main_tab` and `load`; the audit denied both. Console output +reported that no Steam window or main-menu root was available. The panel did +not show a usable browser view in the audited state. + +Static inspection of this archive's published Python backend shows +`set_main_tab()` requesting a Steam GamepadUI CDP tab, then returning a key and +port for its own WebSocket server. That Steam tab and browser injection path +are outside Framey's isolated panel. No real plugin backend was executed, no +browser tab or navigation was verified, and no real Frame or worn-VR check was +performed for this change. The catalog retains **broken** for this digest; its +reason and focused observation now distinguish successful initialization from +the unresolved core browser dependency. The full 116-plugin browser baseline +still refers to its earlier host commit; this is a one-plugin follow-up. diff --git a/docs/framey-compatibility.md b/docs/framey-compatibility.md index 28f0290..012de74 100644 --- a/docs/framey-compatibility.md +++ b/docs/framey-compatibility.md @@ -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. 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 [running-context follow-up](evidence/framey-running-context-2026-10-26.md) supplies detached running-app/main-app reads and relays actual Steam lifetime callbacks while a panel is open. Real Frame checks verified an empty list, registration/cleanup and the exact Discord Status ARM64 backend reporting no IPC connection. Nonempty games and transitions were synthetic fixtures; real game events, Discord activity and worn VR remain unverified. Discord Status moves to partial; no new works claim is made. 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 [running-context follow-up](evidence/framey-running-context-2026-10-26.md) supplies detached running-app/main-app reads and relays actual Steam lifetime callbacks while a panel is open. Real Frame checks verified an empty list, registration/cleanup and the exact Discord Status ARM64 backend reporting no IPC connection. Nonempty games and transitions were synthetic fixtures; real game events, Discord activity and worn VR remain unverified. Discord Status moves to partial; no new works claim is made. 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. A [Web Browser frontend follow-up](evidence/framey-web-browser-2026-10-26.md) verified its exact archive now initializes with an inert null Steam React-root lookup. Its GamepadUI CDP/browser backend path remains unavailable, so it stays broken. 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 @@ -69,7 +69,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say | 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 | 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 | +| 59: Web Browser 1.4.3 | legacy / legacy | broken | The exact frontend now initializes with a null Steam React-root lookup. The browser itself still requires Steam GamepadUI CDP injection and a backend WebSocket unavailable in Framey; no working browser tab was verified. | static archive, local browser, fake-Frame, focused local browser | | 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 | | 62: TS3 QuickAccess 1.2.0 | legacy / legacy | broken | Plugin contains a non-ARM64 Linux binary: ts3-qs4sd/bin/ts3-qs4sd.so. | static archive, local browser, fake-Frame | diff --git a/scripts/framey-compatibility-doc.py b/scripts/framey-compatibility-doc.py index 857c58a..fd5d62c 100644 --- a/scripts/framey-compatibility-doc.py +++ b/scripts/framey-compatibility-doc.py @@ -72,6 +72,7 @@ def render(data): '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. ' + 'A [Web Browser frontend follow-up](evidence/framey-web-browser-2026-10-26.md) verified its exact archive now initializes with an inert null Steam React-root lookup. Its GamepadUI CDP/browser backend path remains unavailable, so it stays broken. ' '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 ' diff --git a/tests/page/framey_actions.mjs b/tests/page/framey_actions.mjs index 4ed994f..b5b7150 100644 --- a/tests/page/framey_actions.mjs +++ b/tests/page/framey_actions.mjs @@ -24,6 +24,9 @@ const context=vm.createContext({window,document:{getElementById:id=>{ navigator:{language:'en'}, parent,DOMException,addEventListener:(type,handler)=>listeners.push({type,handler}), setTimeout:()=>1,clearTimeout(){}}); vm.runInContext(testSource,context); +// No Steam React tree exists inside the isolated Framey iframe. +assert.equal(window.DFL.getReactRoot({}),null); +assert.equal(window.DFL.findInReactTree(window.DFL.getReactRoot(null),()=>true),null); // Official @decky/rollup bundles use the automatic JSX runtime, including keyed lists. const jsx=window.SP_JSX.jsx('p',{id:'message',children:'Saved'},'message-key'); assert.equal(jsx.type,'p'); diff --git a/ui/framey-compatibility.json b/ui/framey-compatibility.json index 4e327d0..6031829 100644 --- a/ui/framey-compatibility.json +++ b/ui/framey-compatibility.json @@ -4184,12 +4184,13 @@ "https://github.com/jessebofill/DeckWebBrowser.git" ], "status": "broken", - "reason": "Frontend audit failed: deckyFrontendLib.getReactRoot is not a function.", + "reason": "The exact frontend now initializes with a null Steam React-root lookup. The browser itself still requires Steam GamepadUI CDP injection and a backend WebSocket unavailable in Framey; no working browser tab was verified.", "blockInstall": false, "verification": [ "static archive", "local browser", - "fake-Frame" + "fake-Frame", + "focused local browser" ], "browser": { "id": 59, @@ -4241,6 +4242,17 @@ "sha256": "1192864fddc5d72550346b8dff02c21d71f0c40a06ac41c4e67bb6220d267f9d", "archiveValidation": "accepted", "result": "installed-removed" + }, + "focusedBrowser": { + "hostChange": "DFL.getReactRoot returns null without exposing a Steam tree", + "ready": true, + "error": null, + "methods": [ + "set_main_tab", + "load" + ], + "backendAndNetwork": "denied", + "scope": "initializer only; no usable browser tab or real backend verified" } }, { diff --git a/ui/framey-host.js b/ui/framey-host.js index 810d2c1..34a232a 100644 --- a/ui/framey-host.js +++ b/ui/framey-host.js @@ -366,7 +366,10 @@ showModal, showContextMenu:showModal, // Steam app, library, and store patches have no target inside this panel. afterPatch:noPatch, beforePatch:noPatch, replacePatch:noPatch, createReactTreePatcher:noPatch, - findInReactTree: () => null, findModule, findModuleChild, findModuleDetailsByExport, + // The isolated panel has no Steam React root. Legacy plugins can inspect + // this null result and keep their own controls without patching Steam UI. + getReactRoot: () => null, findInReactTree: () => null, + findModule, findModuleChild, findModuleDetailsByExport, findModuleByExport:(filter, minExports)=>findModuleDetailsByExport(filter,minExports)[0], findModuleExport:(filter, minExports)=>findModuleDetailsByExport(filter,minExports)[1], createModuleMapping, findAllModules:filter=>[...createModuleMapping(filter).values()], From c91cfff797410047f9f190e88a61569777f22843 Mon Sep 17 00:00:00 2001 From: SAPHID Date: Mon, 26 Oct 2026 07:28:07 +0000 Subject: [PATCH 2/2] docs: record exact Framey unworn regression gate --- docs/evidence/framey-web-browser-2026-10-26.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/evidence/framey-web-browser-2026-10-26.md b/docs/evidence/framey-web-browser-2026-10-26.md index 14a7053..6c7a247 100644 --- a/docs/evidence/framey-web-browser-2026-10-26.md +++ b/docs/evidence/framey-web-browser-2026-10-26.md @@ -28,3 +28,21 @@ performed for this change. The catalog retains **broken** for this digest; its reason and focused observation now distinguish successful initialization from the unresolved core browser dependency. The full 116-plugin browser baseline still refers to its earlier host commit; this is a one-plugin follow-up. + +## Unworn Framey regression gate + +The exact code commit `d5e62f643d462b7070f27c2c47b11b4aa9982094` ran +`scripts/framey-vr-check.py --exercise` under its own shared-lock owner at +07:26 UTC. Preflight found SteamVR activity 3 (standby), proximity 6.25 and +battery 100%. The real Decky sample setting saved `enabled=true`, survived a +fresh iframe, and the quick action read the saved value. A trusted synthetic +OpenVR pointer, slider value 50, CDP text entry after focus and changed stereo +compositor hashes passed. The mirror capture SHA-256 was +`4f0d977fab7c144a3490b12ebefddacf3126db585057eb022006ffdf844a7498`. +The command exited 0 with `passed=true`; original power settings (`false` and +`5.000000`) were read back, battery ended at 99%, the recovery timer was +removed, cleanup errors were empty and only its own lock was released. The +private full report is `/tmp/framey-web-browser-vr-d5e62f6/result.json` on the +test host. This verifies the sample-panel regression path, not the official +Web Browser plugin or a worn headset. Synthetic native scroll still did not +move.