mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-26 13:00:33 +01:00
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4e632b218 | ||
|
|
340ca88359 | ||
|
|
e62589417b | ||
|
|
03b3796d8d | ||
|
|
93da4e466f | ||
|
|
05093ea4d4 | ||
|
|
232b253e7a | ||
|
|
de8abe32c6 | ||
|
|
42492e7879 | ||
|
|
f50139fe6a | ||
|
|
698a643eb7 | ||
|
|
d0cef31656 | ||
|
|
4ac59f1a44 | ||
|
|
c91cfff797 | ||
|
|
d5e62f643d | ||
|
|
f3f574666f | ||
|
|
40ece4fef0 | ||
|
|
f52c020310 | ||
|
|
efe0c508f4 | ||
|
|
1af2bb45d9 |
No files matched your search
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "frame-control",
|
||||
"version": "0.4.42",
|
||||
"version": "0.4.43",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "frame-control",
|
||||
"version": "0.4.42",
|
||||
"version": "0.4.43",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"electron": "^44.4.5",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "frame-control",
|
||||
"productName": "Frame Control",
|
||||
"version": "0.4.42",
|
||||
"version": "0.4.43",
|
||||
"description": "Desktop app for managing a Valve Steam Frame over SSH",
|
||||
"private": true,
|
||||
"main": "main.js",
|
||||
|
||||
@@ -76,3 +76,26 @@ missing/stale receipts are rejected before CEF after plugin replacement, and a
|
||||
reopened panel can poll and close with the new receipt. Rejected stale closes
|
||||
retain the tested finite-lease cleanup. This authorization-only follow-up did
|
||||
not repeat the device checks above; their recorded hardware scope is unchanged.
|
||||
|
||||
## Post-merge unworn panel exercise
|
||||
|
||||
On merged main `daee952873255b86018cce1d2a4d3bd070ec4341`,
|
||||
`scripts/framey-vr-check.py --exercise --output /tmp/framey-post304-exercise`
|
||||
acquired its own `/tmp/frame-test.lock` before any headset read. At 05:54 UTC,
|
||||
preflight found SteamVR activity 3 (standby), proximity 6.25 and battery 99%.
|
||||
The temporary sample panel passed the real Decky setting save and fresh-iframe
|
||||
reopen, a trusted synthetic OpenVR pointer, quick action, slider value 50 and
|
||||
CDP text entry after OpenVR focus. Stereo compositor SHA-256 changed from
|
||||
`50fcab1ee25e6d9398106cc0c24ec6616e07bcf4573b52be1774c715b756060b`
|
||||
to `98241806fb1f775e7f4c5ef0b0564bfd3c552ee896ff225b4d0cb5b7b53f70d1`;
|
||||
the `/dev/video99` mirror capture hash was
|
||||
`c284c05f86b60362168c1d1f58fe775974b70ac54bbfd57834802b892eb4509e`.
|
||||
The command exited 0 with `passed=true`. The original power values (`false` and
|
||||
`5.000000`) were read back, battery remained 99%, the recovery timer was removed,
|
||||
cleanup errors were empty and the run released only its own lock. The private
|
||||
full report is `/tmp/framey-post304-exercise/result.json` on the test host.
|
||||
|
||||
This exercise covered the sample panel path after the running-context merge. It
|
||||
did not observe a nonempty running-game list, a game lifetime callback, Discord
|
||||
activity, a worn display or physical controller input. Synthetic native scroll
|
||||
again did not move (`scrollTop=0`, no wheel event).
|
||||
@@ -0,0 +1,184 @@
|
||||
{
|
||||
"checkedAtUtc": "2026-10-26T07:22:08.822239+00:00",
|
||||
"plugin": {
|
||||
"id": 84,
|
||||
"name": "Junk-Store",
|
||||
"version": "1.1.13",
|
||||
"sha256": "f7ad2a0103c85bf308929b2e96ec9aeeb0d76bcc6ae97eb1e4b5f31ffba0cbb1",
|
||||
"license": "BSD-3-Clause",
|
||||
"sourceModified": false
|
||||
},
|
||||
"installer": {
|
||||
"beforeScriptMode": "0644",
|
||||
"afterScriptMode": "0744",
|
||||
"policy": "Add owner execute for a shebang or ZIP-declared executable; do not restore archive privilege/write bits. Existing installs require update or reinstall."
|
||||
},
|
||||
"isolatedBackend": {
|
||||
"runtime": "published Decky 3.3.0 amd64",
|
||||
"loaderSha256": "e80d03e641d1766a33a817cb27ab8d2e0a4633685e5d27e4de948a6687526181",
|
||||
"isolation": [
|
||||
"unprivileged",
|
||||
"no network",
|
||||
"no devices",
|
||||
"no capabilities",
|
||||
"read-only root",
|
||||
"private tmpfs home and tmp"
|
||||
],
|
||||
"beforeInit": {
|
||||
"result": {
|
||||
"Type": "Error",
|
||||
"Content": {
|
||||
"Message": "Error parsing json result Expecting value: line 1 column 1 (char 0)",
|
||||
"Data": "",
|
||||
"ActionName": "init",
|
||||
"ActionSet": "init"
|
||||
}
|
||||
},
|
||||
"success": true
|
||||
},
|
||||
"afterInit": {
|
||||
"result": {
|
||||
"Type": "Success",
|
||||
"Content": {
|
||||
"Message": "Initialized"
|
||||
}
|
||||
},
|
||||
"success": true
|
||||
},
|
||||
"beforeInitActions": {
|
||||
"result": {
|
||||
"Type": "Error",
|
||||
"Content": {
|
||||
"Message": "Error parsing json result Expecting value: line 1 column 1 (char 0)",
|
||||
"Data": "",
|
||||
"ActionName": "InitActions",
|
||||
"ActionSet": "init"
|
||||
}
|
||||
},
|
||||
"success": true
|
||||
},
|
||||
"afterInitActions": {
|
||||
"outerSuccess": true,
|
||||
"innerType": "ActionSet",
|
||||
"setName": "MainMenu",
|
||||
"actionCount": 4
|
||||
}
|
||||
},
|
||||
"realFrame": {
|
||||
"os": "Frame OS 0.5.6",
|
||||
"arch": "aarch64",
|
||||
"uid": 1000,
|
||||
"decky": {
|
||||
"version": "v3.3.0",
|
||||
"sha256": "8ef5dcf36cbbbb6e97201a6baed5d79c4cc44ec27789fc9af1c5b6ae8f0b25b6"
|
||||
},
|
||||
"transport": "existing trusted SSH via lxso2",
|
||||
"sharedLock": true,
|
||||
"service": "private removable user service; not enabled; RuntimeMaxSec=600",
|
||||
"installedWithProductionApply": true,
|
||||
"scriptMode": "0o744",
|
||||
"legendaryInstalled": false,
|
||||
"backendMethods": [
|
||||
"execute_action",
|
||||
"get_websocket_port"
|
||||
],
|
||||
"staticActions": [
|
||||
"JunkStoreActions/GetContent",
|
||||
"JunkStoreActions/GetEpicActions",
|
||||
"MainMenu/GetContent",
|
||||
"MainMenu/JunkStoreInit",
|
||||
"init/InitActions"
|
||||
],
|
||||
"websocketPort": 8765,
|
||||
"websocketCommandsSent": false,
|
||||
"librarySnapshotCounts": {
|
||||
"apps": 1106,
|
||||
"games": 895
|
||||
},
|
||||
"explicitInitActionInvoked": false,
|
||||
"normalDeckyBeforeAfter": [
|
||||
"inactive",
|
||||
"inactive"
|
||||
],
|
||||
"normalPanelBeforeAfter": [
|
||||
"inactive",
|
||||
"inactive"
|
||||
],
|
||||
"batteryBeforeAfter": [
|
||||
[
|
||||
99
|
||||
],
|
||||
[
|
||||
100
|
||||
]
|
||||
],
|
||||
"powerSettingChanged": false,
|
||||
"cleanup": {
|
||||
"baseAbsent": true,
|
||||
"unitAbsent": true
|
||||
},
|
||||
"lockReleased": true
|
||||
},
|
||||
"localBrowser": {
|
||||
"runtime": "local Chromium, real headset.html/framey-host.js, vendored React, official frontend in opaque iframe",
|
||||
"backend": "production receipt-bound bridge to actual ARM64 backend",
|
||||
"steamLibrary": "production receipt-bound GetLibrarySnapshot; only counts retained",
|
||||
"outerStatusInstallResponses": "fixtures",
|
||||
"passed": [
|
||||
"Custom Stores main menu and Games/News/About navigation items render",
|
||||
"Games route opens static Epic tab",
|
||||
"Back returns to main menu",
|
||||
"close/reopen returns to main menu"
|
||||
],
|
||||
"remainingFailure": "About: Cannot read properties of undefined (reading 'installed'); detached app overview lacks local_per_client_data.installed",
|
||||
"deniedActions": [
|
||||
"fetch_rss_feed",
|
||||
"EpicActions/GetContent"
|
||||
],
|
||||
"denialIsNotBackendFailure": true
|
||||
},
|
||||
"cleanupAudit": {
|
||||
"attempts": 3,
|
||||
"allPrivateBasesAbsent": true,
|
||||
"allPrivateUnitsAbsent": true,
|
||||
"allArchivesAbsent": true,
|
||||
"allServicesInactive": true,
|
||||
"freshAuditLockReleased": true
|
||||
},
|
||||
"verification": {
|
||||
"python": {
|
||||
"run": 1628,
|
||||
"skipped": 16,
|
||||
"failures": 0
|
||||
},
|
||||
"site": {
|
||||
"passed": 18
|
||||
},
|
||||
"focusedStore": {
|
||||
"passed": 19
|
||||
},
|
||||
"fakeFrame": {
|
||||
"blocked": 56,
|
||||
"installed-removed": 60
|
||||
},
|
||||
"officialStore": {
|
||||
"plugins": 116,
|
||||
"errors": 0,
|
||||
"identitySetUnchanged": true,
|
||||
"checkedAtUtc": "2026-10-26T07:22:17.371046+00:00"
|
||||
},
|
||||
"staticEntrypointArchives": 28
|
||||
},
|
||||
"unverified": [
|
||||
"Legendary dependency installation",
|
||||
"Epic login",
|
||||
"game listing",
|
||||
"game downloads or launch",
|
||||
"RSS feed",
|
||||
"Steam shortcut mutation",
|
||||
"optional websocket operations",
|
||||
"deployed headset HTTP endpoint",
|
||||
"worn VR"
|
||||
],
|
||||
"status": "partial"
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
# Executable script entrypoints: Junk-Store
|
||||
|
||||
Junk-Store 1.1.13 (official ID 84) moves **broken → partial**. The exact unmodified
|
||||
BSD-3-Clause archive is pinned in the [redacted results](framey-script-entrypoints-2026-10-26.json).
|
||||
No ARM64 rebuild or upstream plugin source patch was needed.
|
||||
|
||||
Python ZIP extraction drops execute permissions. This archive also publishes its
|
||||
shebang scripts as 0644, relying on upstream Decky's recursive permission setup.
|
||||
Framey's user service disables that setup. Direct script calls therefore fail.
|
||||
The installer now adds **owner execute only** to shebang scripts or ZIP-declared
|
||||
executables. It does not restore archive privilege/write bits, grant group/other
|
||||
execute, or change unmarked data permissions. Archive validation and installation
|
||||
blocks remain in place. Existing installations need update/reinstall for repair.
|
||||
|
||||
The upstream comparison is Decky 3.3.0's
|
||||
[permission setup](https://github.com/SteamDeckHomebrew/decky-loader/blob/v3.3.0/backend/decky_loader/browser.py)
|
||||
and [Linux implementation](https://github.com/SteamDeckHomebrew/decky-loader/blob/v3.3.0/backend/decky_loader/localplatform/localplatformlinux.py).
|
||||
Static inspection found 28 accepted official archives with shebang or declared
|
||||
executable members. This is shared installer coverage, not 28 functional claims.
|
||||
|
||||
## Before and after in an isolated real backend
|
||||
|
||||
Both runs used the exact official plugin and published Decky 3.3.0 amd64, with no
|
||||
network/devices/capabilities, a read-only root and private temporary home/tmp.
|
||||
The only difference was the production installer before/after this change.
|
||||
|
||||
| Check | Before | After |
|
||||
| --- | --- | --- |
|
||||
| `scripts/get-json.py` | 0644 | 0744 |
|
||||
| `execute_action(init, init)` | inner `Type:Error`, empty output / JSON parse error | `Type:Success`, `Initialized` |
|
||||
| `execute_action(init, InitActions)` | inner `Type:Error` | `Type:ActionSet`, `MainMenu`, four actions |
|
||||
|
||||
The legacy wrapper reports `success:true` even for the failing inner error.
|
||||
Startup log text alone is also insufficient: the baseline emits initialized/started
|
||||
messages despite those errors. Both private containers were removed.
|
||||
|
||||
## Real ARM64 Frame and local Chromium
|
||||
|
||||
Under the shared headset lock, the patched production installer installed the
|
||||
official archive into a private, bounded, removable Decky 3.3.0 ARM64 user service
|
||||
on Frame OS 0.5.6. The service was not enabled. Legendary was absent before and
|
||||
after; no dependency installer, login, download, launch or websocket command ran.
|
||||
|
||||
The production receipt-bound bridge called the actual backend through live Steam
|
||||
CEF. Static action sets, main-menu content and the Epic action set returned real
|
||||
results. `get_websocket_port` returned 8765. Explicit `init/init` success was tested
|
||||
in the isolated amd64 backend; it was not explicitly invoked in the final Frame run.
|
||||
|
||||
Local Chromium ran the actual Framey host and official frontend in an opaque
|
||||
iframe, relaying only allowed static calls to that ARM64 backend. Main menu,
|
||||
Games → static Epic tab, Back and fresh close/reopen passed. Steam library reads
|
||||
used the production receipt-bound bridge; only counts were retained. Outer
|
||||
status/install responses were fixtures, and the deployed headset HTTP endpoint
|
||||
was not tested.
|
||||
|
||||
The About route still crashes on missing `local_per_client_data.installed` in
|
||||
the detached app overview. Epic game-list and RSS calls were deliberately denied;
|
||||
their loading/error views do not demonstrate backend failure. Dependency
|
||||
installation, login, game operations, RSS, Steam shortcut mutation and worn VR
|
||||
remain unverified. This supports **partial**, not works.
|
||||
|
||||
Three temporary attempts were cleaned, including an initial Steam reinjection
|
||||
readiness failure and a test-relay omission of the library endpoint. A fresh
|
||||
shared-lock audit found all three services inactive/unloaded (PID 0), with their
|
||||
private bases, unit files and archives absent. Normal managed Decky/panel services
|
||||
stayed inactive; final battery was 99 → 100 while charging. No power-setting action
|
||||
ran. The audit lock was released, and local relays/browser tabs were closed.
|
||||
|
||||
## Verification
|
||||
|
||||
- Python suite: 1,628 tests, 16 skipped, no failures; store suite: 19 passed.
|
||||
- Site suite: 18 passed. Two new regression tests failed before the fix.
|
||||
- All 116 official plugins: fake-Frame 60 installed/removed, 56 expected blocks;
|
||||
no actual plugin backends run by this harness. Disposable project cleaned.
|
||||
- Fresh official-store audit: 116 plugins, zero errors; ID/version/digest set
|
||||
matches the catalog. Other plugin statuses are unchanged.
|
||||
@@ -0,0 +1,405 @@
|
||||
{
|
||||
"baseCommit": "daee952873255b86018cce1d2a4d3bd070ec4341",
|
||||
"plugin": {
|
||||
"id": 58,
|
||||
"name": "Volume Boost",
|
||||
"version": "0.0.7",
|
||||
"sha256": "2cc576a7f60751306d690268e227df626e59d3733680ced753de4c116629a9cc"
|
||||
},
|
||||
"runtime": {
|
||||
"version": "v3.3.0",
|
||||
"sha256": "8ef5dcf36cbbbb6e97201a6baed5d79c4cc44ec27789fc9af1c5b6ae8f0b25b6",
|
||||
"os": "Frame OS 0.5.6",
|
||||
"arch": "aarch64"
|
||||
},
|
||||
"verificationLimits": {
|
||||
"fakeFrame": "Prior exact archive HTTP/SSH install/receipt/removal; plugin execution stubbed, not repeated",
|
||||
"localBrowser": "Actual headset.html, React and Framey host, exact unmodified official frontend in opaque iframe; direct RPC relay to actual ARM64 backend",
|
||||
"realFrameSSH": "Production receipt-bound framey_panel.call_method over SSH and live Steam CEF DeckyBackend.call into actual Decky 3.3.0 ARM64 plugin; default speaker sink remained muted throughout",
|
||||
"wornVR": "Not tested",
|
||||
"audibleOutput": "Not tested; gain writes and readbacks only",
|
||||
"deployedHTTP": "Not tested; outer status/install/check responses were fixtures, methods used production call_method with exact current receipt"
|
||||
},
|
||||
"catalogRefresh": {
|
||||
"checkedAtUtc": "2026-10-26T06:10:58.537029+00:00",
|
||||
"plugins": 116,
|
||||
"changedIdsVersionsDigests": 0
|
||||
},
|
||||
"runs": [
|
||||
{
|
||||
"timeUtc": "2026-10-26T06:07:19.370988+00:00",
|
||||
"locale": "LC_ALL=C for the private Decky service",
|
||||
"originalSink": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 0,
|
||||
"front-right": 0
|
||||
}
|
||||
},
|
||||
"writes": [
|
||||
{
|
||||
"request": {
|
||||
"value": 125,
|
||||
"channel": "both"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 81920,
|
||||
"front-right": 81920
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 125,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 125,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"value": 75,
|
||||
"channel": "both"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 49152,
|
||||
"front-right": 49152
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 75,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 75,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"value": 74,
|
||||
"channel": "both"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 48496,
|
||||
"front-right": 48496
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 74,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 74,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"value": 33,
|
||||
"channel": "left"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 21626,
|
||||
"front-right": 0
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 33,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"value": 67,
|
||||
"channel": "right"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 0,
|
||||
"front-right": 43909
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 67,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"value": 33,
|
||||
"channel": "right"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 0,
|
||||
"front-right": 21626
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 33,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
}
|
||||
],
|
||||
"reads": [
|
||||
{
|
||||
"id": 58,
|
||||
"method": "get_volume_state",
|
||||
"args": [
|
||||
{
|
||||
"channel": "left"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 58,
|
||||
"method": "get_volume_state",
|
||||
"args": [
|
||||
{
|
||||
"channel": "left"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"reopen": "Fresh query/session, ready; UI returned to actual restored zero; no write on mount",
|
||||
"before": {
|
||||
"battery": [
|
||||
100
|
||||
],
|
||||
"uid": 1000,
|
||||
"arch": "aarch64",
|
||||
"decky": "inactive",
|
||||
"panel": "inactive"
|
||||
},
|
||||
"after": {
|
||||
"battery": [
|
||||
100
|
||||
],
|
||||
"uid": 1000,
|
||||
"arch": "aarch64",
|
||||
"decky": "inactive",
|
||||
"panel": "inactive"
|
||||
},
|
||||
"cleanup": {
|
||||
"baseAbsent": true,
|
||||
"unitAbsent": true
|
||||
},
|
||||
"exactSinkRestored": true,
|
||||
"lockReleased": true
|
||||
},
|
||||
{
|
||||
"timeUtc": "2026-10-26T06:12:04.889613+00:00",
|
||||
"locale": "Inherited user-service environment, matching production unit; no LANG or LC_ALL override",
|
||||
"originalSink": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 0,
|
||||
"front-right": 0
|
||||
}
|
||||
},
|
||||
"writes": [
|
||||
{
|
||||
"request": {
|
||||
"value": 150,
|
||||
"channel": "both"
|
||||
},
|
||||
"result": {
|
||||
"result": true,
|
||||
"success": true
|
||||
},
|
||||
"independentPulseReadback": {
|
||||
"mute": true,
|
||||
"volumes": {
|
||||
"front-left": 98304,
|
||||
"front-right": 98304
|
||||
}
|
||||
},
|
||||
"backendReadback": {
|
||||
"left": {
|
||||
"result": 150,
|
||||
"success": true
|
||||
},
|
||||
"right": {
|
||||
"result": 150,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
"guardArmedBeforeWrite": true,
|
||||
"exactOriginalRestored": true
|
||||
}
|
||||
],
|
||||
"reads": [
|
||||
{
|
||||
"id": 58,
|
||||
"method": "get_volume_state",
|
||||
"args": [
|
||||
{
|
||||
"channel": "left"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 58,
|
||||
"method": "get_volume_state",
|
||||
"args": [
|
||||
{
|
||||
"channel": "left"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"result": 0,
|
||||
"success": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"reopen": "Fresh query/session, ready; UI returned to actual restored zero; no write on mount",
|
||||
"before": {
|
||||
"battery": [
|
||||
100
|
||||
],
|
||||
"uid": 1000,
|
||||
"arch": "aarch64",
|
||||
"decky": "inactive",
|
||||
"panel": "inactive"
|
||||
},
|
||||
"after": {
|
||||
"battery": [
|
||||
100
|
||||
],
|
||||
"uid": 1000,
|
||||
"arch": "aarch64",
|
||||
"decky": "inactive",
|
||||
"panel": "inactive"
|
||||
},
|
||||
"cleanup": {
|
||||
"baseAbsent": true,
|
||||
"unitAbsent": true
|
||||
},
|
||||
"exactSinkRestored": true,
|
||||
"lockReleased": true
|
||||
}
|
||||
],
|
||||
"guard": {
|
||||
"scope": "Private test helper only; not a shipped feature or plugin patch",
|
||||
"timeoutSeconds": 60,
|
||||
"runtimeMaxSec": 120,
|
||||
"sequence": [
|
||||
"Capture exact default sink identity, native per-channel volume integers and original mute",
|
||||
"Persist recovery state; start bounded device-side systemd watchdog before mute/write",
|
||||
"Require stereo front-left/front-right and mute readback before plugin call",
|
||||
"Only official get_volume_state/set_volume_state; value 0..150, known channels",
|
||||
"Read native Pulse volume and mute independently; read both channels through actual plugin",
|
||||
"Restore exact native volume while muted, verify, then restore original mute and verify exact snapshot",
|
||||
"Remove recovery state, stop only own watchdog; cleanup own service/base and release matching lock"
|
||||
],
|
||||
"automaticTimeoutExercised": false,
|
||||
"explicitRestoreExercised": true
|
||||
},
|
||||
"freshCleanupAudit": {
|
||||
"exactSinkRestored": true,
|
||||
"baseAbsent": true,
|
||||
"unitAbsent": true,
|
||||
"services": {
|
||||
"framey-boost-kp0z857q58-b4126054.service": "MainPID=0\nLoadState=not-found\nActiveState=inactive\n",
|
||||
"framey-boost-kp0z857q58-b4126054-guard.service": "MainPID=0\nLoadState=not-found\nActiveState=inactive\n"
|
||||
},
|
||||
"battery": [
|
||||
100
|
||||
]
|
||||
},
|
||||
"remaining": [
|
||||
"Audible sound/quality, perceived loudness and physical speaker gain are unverified",
|
||||
"Worn VR, headset controller input and Bluetooth sinks are unverified",
|
||||
"No default route change, playback or power-setting action was invoked",
|
||||
"Decky startup reinjects its frontend and can restart Steam CEF; normal managed services stayed inactive"
|
||||
],
|
||||
"repositoryChecks": {
|
||||
"python": "1,626 tests, 16 skips, no failures",
|
||||
"site": "18 passed",
|
||||
"catalogDocCheck": "passed",
|
||||
"diffCheck": "passed"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
# Volume Boost sink controls on the ARM64 Frame
|
||||
|
||||
Volume Boost 0.0.7 (official store ID 58) now qualifies as **works for sink
|
||||
controls**. The exact official, unmodified Python backend ran in Decky 3.3.0
|
||||
ARM64 on Frame OS 0.5.6. Local Chromium rendered its official frontend through
|
||||
Framey's existing legacy bridge. Actual control changes reached the Frame's
|
||||
default speaker sink, including above-100% gain, with independent Pulse
|
||||
readbacks. The sink stayed muted; no audible-output or worn-VR claim is made.
|
||||
|
||||
[Digest-pinned observations and cleanup](framey-volume-boost-arm64-2026-10-26.json)
|
||||
record both runs. This supersedes the Volume Boost read-only limitation in the
|
||||
[previous ARM64 audio check](framey-audio-arm64-2026-10-26.md). No plugin patch,
|
||||
native rebuild or new compatibility shim was necessary. Volume Boost's backend
|
||||
uses Python and the Frame's existing ARM64 `pactl`; its hard-coded UID 1000
|
||||
matches the actual Frame user.
|
||||
|
||||
| Local Chromium action | Actual ARM64 result, independently read back |
|
||||
| --- | --- |
|
||||
| Linked numeric input 125% | Native Pulse channel values 81920 / 81920; plugin reads 125 / 125 |
|
||||
| Linked slider click, then ArrowDown | 75% then 74%; native values 49152 / 49152 then 48496 / 48496 |
|
||||
| Unlink, set left to 33% | Native values 21626 / 0; plugin reads 33 / 0 |
|
||||
| Set right to 67% | Native values 0 / 43909; plugin reads 0 / 67 |
|
||||
| Re-link | Official frontend issues a right-only 33% write; native values 0 / 21626 |
|
||||
| Close and reopen | New document/session, ready; backend reads and displayed linked value return to the restored 0%; no mount write |
|
||||
| Repeat linked numeric 150% with inherited service locale | Native values 98304 / 98304; plugin reads 150 / 150; reopen again reads restored zero |
|
||||
|
||||
The test restores the original sink state after **each** write. Therefore the
|
||||
separate-channel checks intentionally begin from 0% / 0%, rather than from the
|
||||
previous UI value. A right-only re-link request is the published plugin's
|
||||
behavior. These checks verify channel selection and preservation of the other
|
||||
channel; they do not claim a continuous unmuted listening session. Pulse's
|
||||
integer conversion truncates fractional native values; the evidence retains
|
||||
those integers rather than replacing them with rounded percentages.
|
||||
|
||||
## Runtime and transport
|
||||
|
||||
Each run separately acquired the atomic `/tmp/frame-test.lock`; neither stole
|
||||
an existing lock. A unique private Decky user service used its own plugin,
|
||||
settings and runtime directories, was never enabled, and had an eight-minute
|
||||
runtime limit. The upstream ARM64 loader matched GitHub's published SHA-256
|
||||
and ELF machine 183. The plugin ZIP matched the official digest.
|
||||
|
||||
The local relay served actual `ui/headset.html`, vendored React and
|
||||
`framey-host.js`, with exact official frontend bytes in an opaque
|
||||
`allow-scripts` iframe. Outer status/install/check responses were fixtures.
|
||||
Plugin calls used production `framey_panel.call_method`, including the current
|
||||
store receipt, SSH through lxso2, live Steam CEF and `DeckyBackend.call` into the
|
||||
actual plugin subprocess. Only the temporary install paths were redirected.
|
||||
This does not verify the deployed headset HTTP endpoint or a VR compositor.
|
||||
|
||||
The first private service explicitly used `LC_ALL=C`. The second inherited the
|
||||
user-service locale without a `LANG` or `LC_ALL` override, matching the
|
||||
production service configuration, and repeated actual reads, a 150% write and
|
||||
reopen. Zero alone was not accepted as success: upstream returns zero on
|
||||
command failure. Every write returned true, both backend channel reads agreed,
|
||||
and independent native Pulse readbacks confirmed nonzero changes.
|
||||
|
||||
## Bounded muted writes and restoration
|
||||
|
||||
The default sink was already muted at native channel values 0 / 0. Before each
|
||||
plugin write, a private device-side helper captured the exact sink identity,
|
||||
channel values and mute state; persisted recovery state; and started a bounded
|
||||
60-second systemd watchdog. It then required a successful mute readback before
|
||||
allowing the plugin call. The relay allowed only `get_volume_state` and
|
||||
`set_volume_state`, known channels and values from 0 through 150.
|
||||
|
||||
After the call, independent `pactl --format=json list sinks` and both plugin
|
||||
reads checked the result. In `finally`, the helper restored exact native
|
||||
channel values while muted, checked them, restored the original mute state,
|
||||
and verified the entire snapshot before removing recovery state and stopping
|
||||
its watchdog. No default route, playback, existing stream or power setting was
|
||||
changed. Automatic watchdog expiry was armed but not deliberately exercised;
|
||||
explicit restoration passed after all seven writes.
|
||||
|
||||
Both private Decky services/bases were removed and their locks released.
|
||||
Fresh-lock cleanup audits found their Decky and guard units unloaded/inactive
|
||||
with PID 0, paths absent, and the exact original sink/mute restored. Battery
|
||||
stayed 100 → 100; normal managed Decky and headset-panel services stayed
|
||||
inactive. Decky startup reinjects its frontend and can restart Steam CEF.
|
||||
|
||||
## Catalog and verification limits
|
||||
|
||||
The canonical store catalog and generated table report **4 works / 48 partial /
|
||||
53 broken / 11 N/A**. A fresh full official-store fetch at 06:10:58 UTC found
|
||||
all 116 IDs, versions and digests unchanged. Historical fake-Frame checks cover
|
||||
this exact archive's install/receipt/removal with backend execution stubbed;
|
||||
that test was not repeated or relabelled as real-backend evidence.
|
||||
|
||||
Audible gain, sound quality, physical speaker output, Bluetooth sinks,
|
||||
headset-controller input and worn VR remain unverified. The store row includes
|
||||
these limits. This change records new real-backend evidence and updates its
|
||||
compatibility classification; it changes no shipped audio implementation.
|
||||
|
||||
The full server suite completed 1,626 tests with no failures (16 skips); all
|
||||
18 site tests passed. Generated-document consistency and `git diff --check`
|
||||
also passed. No implementation change followed those tests.
|
||||
@@ -0,0 +1,48 @@
|
||||
# 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.
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,62 @@
|
||||
# v0.4.42 tagged release, 26 October 2026
|
||||
|
||||
The annotated `v0.4.42` tag dereferences to main merge commit
|
||||
`98909cb54374a7bd7ec1f665f50eda20fa196f32` from PR #302. The app and
|
||||
lockfile both report 0.4.42. The [tagged release workflow](https://github.com/saphid/frame-control/actions/runs/40276685171)
|
||||
passed its draft, Linux, Windows, Apple Silicon Mac, Intel Mac and checksum jobs.
|
||||
The Linux job launched its built AppImage under isolated Xvfb. CI does not prove
|
||||
a physical Windows or Mac launch.
|
||||
|
||||
## Real Frame, exact tag
|
||||
|
||||
From an exact tag checkout, `scripts/frame-smoke.sh` acquired its own unique
|
||||
owner in `/tmp/frame-test.lock` before reading the headset. Preflight found
|
||||
SteamVR activity 3 (standby), proximity 6.25 and battery 100%. On Frame OS 0.5.6
|
||||
build `20261022.6153909`, it recorded **12 passed / 1 skipped / 0 failed** and
|
||||
exited 0. ARM64 and Proton test executables launched. The x86_64 title was
|
||||
installed and removed, but its launch was skipped because optional Steam Linux
|
||||
Runtime 4 was absent. Test title/process cleanup passed and only the run's lock
|
||||
was released. The private result is
|
||||
`tests/smoke/results/2026-10-26T055940Z-20261022.6153909.json` in the exact tag
|
||||
checkout.
|
||||
|
||||
The separate [unworn Framey candidate exercise](v0442-candidate-2026-10-26.md)
|
||||
passed real sample setting save/reopen, synthetic OpenVR pointer delivery and
|
||||
stereo compositor change, with power restored and cleanup complete. It was run
|
||||
on the release branch's code before the evidence-only final commit. No person
|
||||
wore the Frame. Neither run verifies official plugin VR panels, physical
|
||||
controller usability, native scrolling, VR keyboard or optical comfort. The
|
||||
hourly worn check remains enabled.
|
||||
|
||||
## Installer, checksum and updater checks
|
||||
|
||||
The draft held ten installers plus `SHA256SUMS`, each with a GitHub SHA-256
|
||||
digest. `scripts/publish-release.sh --dry-run v0.4.42` checked the exact remote
|
||||
tag and every installer digest, regenerated the checksum list from those
|
||||
metadata digests, and matched the uploaded `SHA256SUMS` digest. A fresh
|
||||
checksum-list download independently matched
|
||||
`e5c85f5a46d789dccafae5259bd00b9b048dd10ca4f2a6cdc52d1f432a6db989`.
|
||||
|
||||
A fresh Linux x86_64 AppImage download matched
|
||||
`16fc9fbe448bccbe59aa4206bc171c6bfc741973d2b4da0a79652a5c11d837b3`.
|
||||
`scripts/check-appimage-launch.py` launched those exact bytes under isolated
|
||||
Xvfb: the bundled server answered HTTP 200 with `FrameControl/1` and then
|
||||
stopped. Fresh Mac ZIP downloads matched GitHub digests: arm64
|
||||
`394d6088e732a19289b7b92366dd247f14f7293a345d57ed5c4e9c83a50abad3`
|
||||
and x64 `66d4606e38210d02af59dc87e4d1216282ad9e968056d7096f247fcc51e72395`.
|
||||
Both bundles report version 0.4.42; their main Mach-O CPU types are arm64 and
|
||||
x86_64 respectively. Neither tagged Mac ZIP was launched on a physical Mac.
|
||||
|
||||
`scripts/publish-release.sh v0.4.42` published
|
||||
[v0.4.42](https://github.com/saphid/frame-control/releases/tag/v0.4.42) at
|
||||
2026-10-26 06:02:20 UTC. GitHub's latest-release API read back `draft=false`,
|
||||
`prerelease=false`, the expected tag, ten installers, `SHA256SUMS` and
|
||||
`update.json`. A fresh public latest-download of `update.json` parsed as
|
||||
version 0.4.42 with the stable release page and ten SHA-256 installer digests.
|
||||
The tag contains #299, #300, #301 and #303 through #302's release merge.
|
||||
#304 merged after the tag and is not in this release.
|
||||
|
||||
The exact-version official Decky table for v0.4.42 is **3 works / 48 partial /
|
||||
54 broken / 11 N/A**. The two additional works labels are restricted to tested
|
||||
per-app silent-stream volume control. Audible playback and official-plugin
|
||||
worn VR remain unverified.
|
||||
@@ -0,0 +1,7 @@
|
||||
# v0.4.43 candidate Frame gate, 26 October 2026
|
||||
|
||||
The combined code head `232b253e7a9400aa9829f9fea6a5d2011dd2a8f3` (PR #309 after merging main with PR #308) ran `scripts/frame-smoke.sh` under its own `/tmp/frame-test.lock` owner at 07:57 UTC. Its locked preflight found SteamVR activity 3 (standby), proximity 6.25 and battery 99%. On Frame OS 0.5.6 build `20261022.6153909`, it recorded **12 passed / 1 skipped / 0 failed**. The ARM64 and Proton executables launched; x86_64 launch was skipped because Steam Linux Runtime 4 is absent. It removed its test titles, exited 0 and released its lock. The private detailed result is `/tmp/frame-smoke-pr309/2026-10-26T075752Z-20261022.6153909.json` on the test host. A fresh, separately owned read-only lock then found activity 3 and battery 99%, and was released. PR #310 subsequently changed only the Windows wireless CI smoke test; the release branch merged that test change and bumped the app version, with no further headset runtime code change after this Frame smoke.
|
||||
|
||||
PR #308's panel code commit `d5e62f643d462b7070f27c2c47b11b4aa9982094` previously passed the temporary Framey sample `scripts/framey-vr-check.py --exercise` machine check, with cleanup and power restoration; see [Web Browser follow-up](framey-web-browser-2026-10-26.md). That test used synthetic OpenVR input and a repository sample, not the official Web Browser plugin or a person wearing the headset. No wake or VR input exercise ran on this combined code head because wearer confirmation was absent. The current smoke made no worn visual, physical-controller, audible-output or official-plugin VR claim.
|
||||
|
||||
This is candidate evidence, not a published-release result. Publication still needs all exact-head PR and release checks, ten tagged installers with matching `SHA256SUMS`, package validation, the publisher dry run, and public updater readback. The exact-version official Decky catalog in this candidate is **4 works / 49 partial / 52 broken / 11 N/A**. Volume Boost's works claim covers tested muted sink controls; Junk-Store remains partial, and Web Browser remains broken.
|
||||
@@ -1,10 +1,10 @@
|
||||
# Official Decky store compatibility with Framey
|
||||
|
||||
Snapshot: 2026-10-25T23:19:48.854504+00:00; 116 current visible official plugins from https://plugins.deckbrew.xyz/plugins.
|
||||
Snapshot: 2026-10-26T06:10:58.537029+00:00; 116 current visible official plugins from https://plugins.deckbrew.xyz/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: 3 · Partial: 49 · Broken: 53 · N/A: 11.**
|
||||
**Works: 4 · Partial: 49 · Broken: 52 · 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. 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. That run left Volume Boost partial because sink writes were denied. A [Volume Boost follow-up](evidence/framey-volume-boost-arm64-2026-10-26.md) now verifies linked/separate channel controls, re-link and reopen through the actual ARM64 backend. Independent Pulse reads confirmed 125%/150% gain writes while the default sink stayed muted; exact original volume/mute was restored. Volume Boost qualifies as works for sink controls. 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. That pass exposed Junk-Store executable-script extraction failures; the follow-up below repairs them. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. That pass tested TabMaster/Junk-Store in actual isolated amd64 Decky, without ARM64 or worn-VR coverage. A [script entrypoint follow-up](evidence/framey-script-entrypoints-2026-10-26.md) grants owner execute to shebang scripts and ZIP-declared executables without copying archive privilege/write bits. Junk-Store now passes static menu/backend calls in actual Decky 3.3.0 ARM64 and local Chromium Games/Epic navigation, back and reopen. It moves to partial: About still crashes on missing installed-app metadata, Legendary is absent, and login/game operations remain unverified. Existing installations require update/reinstall to repair permissions. 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 followLine truncated
|
||||
|
||||
## Every current plugin
|
||||
|
||||
@@ -68,8 +68,8 @@ 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 | 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 |
|
||||
| 58: Volume Boost 0.0.7 | legacy / legacy | works | Default-sink controls pass in local Chromium through real Decky 3.3.0 ARM64: linked slider/keyboard and numeric writes, separate channels, re-link and reopen, with independent Pulse readback including 125%/150% while muted. Exact original volume/mute restored. Audible output, Bluetooth sinks 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 | 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 |
|
||||
@@ -91,7 +91,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say
|
||||
| 80: MagicBlack 2.0.2 | 1 / 2 | N/A | Not supported on Frame: Targets a global Steam Deck screen-black overlay; the isolated panel cannot black out the Frame compositor. | static archive, local browser, fake-Frame |
|
||||
| 81: IsThereAnyDeal for Deck 1.1.1 | legacy / legacy | partial | Country settings render and select the real Frame Steam country through the read-only bridge. Settings writes, deal lookups and Steam page integration remain unverified; plugin backend calls were denied. | static archive, local browser, fake-Frame, real Frame SSH |
|
||||
| 82: MagicPods 2.0.21 | 1 / 2 | broken | Plugin contains a non-ARM64 Linux binary: MagicPodsDecky/bin/magicpodscore. Frontend audit failed: Audit blocks WebSocket. | static archive, local browser, fake-Frame |
|
||||
| 84: Junk-Store 1.1.13 | legacy / legacy | broken | Local CSS lookup fixes the loading view crash. Actual Decky 3.3.0 amd64 startup/static InitActions return a script execution/JSON error; the published scripts are not executable after extraction. Store install/login/game launch and ARM64 remain unverified. | static archive, local browser, fake-Frame |
|
||||
| 84: Junk-Store 1.1.13 | legacy / legacy | partial | Executable script extraction repaired. Official Decky 3.3.0 ARM64 static menu/backend calls and local Chromium Games/Epic navigation, back and reopen pass. About still fails on missing installed-app metadata; Legendary is absent. Dependency install, login, game operations, RSS and worn VR remain unverified. Existing installs need update/reinstall. | static archive, local browser, fake-Frame, isolated Linux backend, real Frame SSH |
|
||||
| 85: Decky-Undervolt 1.0.8 | 1 / 2 | N/A | Not supported on Frame: RyzenAdj Curve Optimizer requires an AMD CPU; Frame is ARM64. | static archive, local browser, fake-Frame |
|
||||
| 87: ScreenSaver 1.1.2 | legacy / legacy | partial | Initializer succeeds; global screen overlay and idle/suspend integration have no verified VR target. | static archive, local browser, fake-Frame |
|
||||
| 88: steamdeck-input-disabler 1.0.2 | legacy / legacy | N/A | Not supported on Frame: Targets the built-in Steam Deck USB gamepad; Frame has different controllers. | static archive, local browser, fake-Frame |
|
||||
|
||||
@@ -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. '
|
||||
'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. '
|
||||
'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. That run left Volume Boost partial because sink writes were denied. A [Volume Boost follow-up](evidence/framey-volume-boost-arm64-2026-10-26.md) now verifies linked/separate channel controls, re-link and reopen through the actual ARM64 backend. Independent Pulse reads confirmed 125%/150% gain writes while the default sink stayed muted; exact original volume/mute was restored. Volume Boost qualifies as works for sink controls. 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 '
|
||||
@@ -64,7 +64,7 @@ def render(data):
|
||||
'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. '
|
||||
'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. That pass exposed Junk-Store executable-script extraction failures; the follow-up below repairs them. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. That pass tested TabMaster/Junk-Store in actual isolated amd64 Decky, without ARM64 or worn-VR coverage. A [script entrypoint follow-up](evidence/framey-script-entrypoints-2026-10-26.md) grants owner execute to shebang scripts and ZIP-declared executables without copying archive privilege/write bits. Junk-Store now passes static menu/backend calls in actual Decky 3.3.0 ARM64 and local Chromium Games/Epic navigation, back and reopen. It moves to partial: About still crashes on missing installed-app metadata, Legendary is absent, and login/game operations remain unverified. Existing installations require update/reinstall to repair permissions. 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 '
|
||||
@@ -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 '
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -138,6 +138,31 @@ class StoreTransaction(unittest.TestCase):
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertTrue(external.exists())
|
||||
|
||||
def test_installed_script_entrypoints_execute_without_zip_exec_bits(self):
|
||||
data, _ = archive(extra=('Example/scripts/start.py',
|
||||
b'#!/bin/sh\nprintf "Framey script: %s\\n" "$1"\n'))
|
||||
result = self.apply('install', data)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
script = self.folder / 'scripts/start.py'
|
||||
self.assertTrue(script.stat().st_mode & 0o100)
|
||||
self.assertFalse(script.stat().st_mode & 0o6111 & ~0o100)
|
||||
ran = subprocess.run([str(script), 'ready'], text=True, capture_output=True, timeout=5)
|
||||
self.assertEqual(ran.returncode, 0, ran.stderr)
|
||||
self.assertEqual(ran.stdout, 'Framey script: ready\n')
|
||||
self.assertFalse((self.folder / 'plugin.json').stat().st_mode & 0o111)
|
||||
self.assertFalse((self.folder / 'dist/index.js').stat().st_mode & 0o111)
|
||||
|
||||
def test_declared_executable_is_owner_only_without_privilege_bits(self):
|
||||
info = zipfile.ZipInfo('Example/bin/entrypoint')
|
||||
info.create_system = 3
|
||||
info.external_attr = 0o104777 << 16
|
||||
data, _ = archive(extra=(info, b'entrypoint payload'))
|
||||
result = self.apply('install', data)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
executable = self.folder / 'bin/entrypoint'
|
||||
self.assertEqual(executable.stat().st_mode & 0o6111, 0o100)
|
||||
self.assertEqual(executable.read_bytes(), b'entrypoint payload')
|
||||
|
||||
def test_remove_while_service_is_stopped_does_not_restart_it(self):
|
||||
data, _ = archive()
|
||||
self.assertEqual(self.apply('install', data).returncode, 0)
|
||||
|
||||
@@ -192,6 +192,12 @@ class Probe(unittest.TestCase):
|
||||
@unittest.skipUnless(wireless.frame_host.WINDOWS, 'Live read-only Windows inventory runs on Windows CI')
|
||||
def test_live_windows_inventory(self):
|
||||
r = wireless.diagnose()
|
||||
# Shared Windows runners can spend the entire probe budget starting
|
||||
# PowerShell. Retry only that transient timeout; a second failure must
|
||||
# still fail this live inventory gate.
|
||||
if (r['state'] == 'unavailable' and
|
||||
r.get('message') == 'Windows wireless inventory timed out. No settings were changed.'):
|
||||
r = wireless.diagnose()
|
||||
self.assertIn(r['state'], ('ok', 'partial'), r)
|
||||
self.assertEqual(r['sources']['adapters'], 'ok', r['sources'])
|
||||
self.assertTrue(r['devices'], 'Windows runner should expose at least its virtual network interface')
|
||||
|
||||
@@ -177,6 +177,16 @@ try:
|
||||
seen.add(f.filename)
|
||||
stage.mkdir(mode=0o700)
|
||||
z.extractall(stage)
|
||||
# zipfile drops execute bits. Legacy plugins also publish shebang
|
||||
# entrypoints as 0644 because Decky's installer chmods recursively.
|
||||
# Grant only owner execute for scripts or declared executables;
|
||||
# never restore archive privilege/write bits or mark other data executable.
|
||||
for member in files:
|
||||
if member.is_dir(): continue
|
||||
entry=stage/member.filename
|
||||
with entry.open('rb') as source: script=source.read(2)==b'#!'
|
||||
if script or (member.external_attr>>16)&0o111:
|
||||
entry.chmod(entry.stat().st_mode|0o100)
|
||||
unpacked=stage/folder
|
||||
if not unpacked.is_dir(): raise RuntimeError('Missing plugin folder')
|
||||
# Recheck under the transaction lock. Another store operation may
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"checkedAtUtc": "2026-10-25T23:19:48.854504+00:00",
|
||||
"checkedAtUtc": "2026-10-26T06:10:58.537029+00:00",
|
||||
"source": "https://plugins.deckbrew.xyz/plugins",
|
||||
"hostCommit": "779f9c5",
|
||||
"method": "Exact SHA-256 verified archives. All frontends attempted in opaque-iframe Chromium for 1.2 s with backend calls and network denied; ready means initializer only. Backend calls were denied in the baseline browser audit. Scoped live backend follow-ups are recorded separately in docs/framey-compatibility.md.",
|
||||
@@ -4055,8 +4055,8 @@
|
||||
"https://github.com/saumya-banthia/volume-boost",
|
||||
"https://github.com/saumya-banthia/volume-boost.git"
|
||||
],
|
||||
"status": "partial",
|
||||
"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.",
|
||||
"status": "works",
|
||||
"reason": "Default-sink controls pass in local Chromium through real Decky 3.3.0 ARM64: linked slider/keyboard and numeric writes, separate channels, re-link and reopen, with independent Pulse readback including 125%/150% while muted. Exact original volume/mute restored. Audible output, Bluetooth sinks and worn VR unverified.",
|
||||
"blockInstall": false,
|
||||
"verification": [
|
||||
"static archive",
|
||||
@@ -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"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -6505,13 +6517,15 @@
|
||||
"https://github.com/ebenbruyns/junkstore",
|
||||
"https://github.com/ebenbruyns/junkstore.git"
|
||||
],
|
||||
"status": "broken",
|
||||
"reason": "Local CSS lookup fixes the loading view crash. Actual Decky 3.3.0 amd64 startup/static InitActions return a script execution/JSON error; the published scripts are not executable after extraction. Store install/login/game launch and ARM64 remain unverified.",
|
||||
"status": "partial",
|
||||
"reason": "Executable script extraction repaired. Official Decky 3.3.0 ARM64 static menu/backend calls and local Chromium Games/Epic navigation, back and reopen pass. About still fails on missing installed-app metadata; Legendary is absent. Dependency install, login, game operations, RSS and worn VR remain unverified. Existing installs need update/reinstall.",
|
||||
"blockInstall": false,
|
||||
"verification": [
|
||||
"static archive",
|
||||
"local browser",
|
||||
"fake-Frame"
|
||||
"fake-Frame",
|
||||
"isolated Linux backend",
|
||||
"real Frame SSH"
|
||||
],
|
||||
"browser": {
|
||||
"id": 84,
|
||||
@@ -6543,6 +6557,25 @@
|
||||
"sha256": "f7ad2a0103c85bf308929b2e96ec9aeeb0d76bcc6ae97eb1e4b5f31ffba0cbb1",
|
||||
"archiveValidation": "accepted",
|
||||
"result": "installed-removed"
|
||||
},
|
||||
"localBackend": {
|
||||
"runtime": "Decky 3.3.0 amd64",
|
||||
"evidence": "docs/evidence/framey-script-entrypoints-2026-10-26.json",
|
||||
"before": "init and InitActions return inner Type:Error",
|
||||
"after": "init Type:Success; InitActions Type:ActionSet/MainMenu"
|
||||
},
|
||||
"realFrame": {
|
||||
"runtime": "Decky 3.3.0 ARM64",
|
||||
"evidence": "docs/evidence/framey-script-entrypoints-2026-10-26.json",
|
||||
"staticActions": [
|
||||
"JunkStoreActions/GetContent",
|
||||
"JunkStoreActions/GetEpicActions",
|
||||
"MainMenu/GetContent",
|
||||
"MainMenu/JunkStoreInit",
|
||||
"init/InitActions"
|
||||
],
|
||||
"browser": "main menu; Games/Epic static tab; back; close/reopen",
|
||||
"remainingFailure": "About: Cannot read properties of undefined (reading 'installed'); detached app overview lacks local_per_client_data.installed"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
+4
-1
@@ -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()],
|
||||
|
||||
Reference in new issue
Block a user