diff --git a/docs/evidence/framey-gamesync-native-2026-10-29.md b/docs/evidence/framey-gamesync-native-2026-10-29.md new file mode 100644 index 0000000..89a7272 --- /dev/null +++ b/docs/evidence/framey-gamesync-native-2026-10-29.md @@ -0,0 +1,24 @@ +# Game Sync 1.0.4 isolated backend check, 29 October 2026 + +The official Decky archive for Game Sync (ID 104) is 2,228,806 bytes with +SHA-256 `65e021ebb37d2ebfbfbe3dbc8af95aef9556cf484730362c6b26c4ecc3e62ccd`. +Its unmodified ZIP is pinned as `tests/fixtures/framey-official/104.zip`. + +`python3 scripts/framey-test-decky-runtime.py --case 104 --output /tmp/framey-gamesync-native-104.json` +passed with the published Decky 3.3.0 x86_64 loader, SHA-256 +`e80d03e641d1766a33a817cb27ab8d2e0a4633685e5d27e4de948a6687526181`. +The disposable container had no external network or host devices, dropped +capabilities and used a private home. The real loader discovered the exact +plugin. Its `get_config` returned defaults with automatic game sync and +capture upload disabled. A private `advanced_mode` setting changed from false +to true and remained true after the loader restarted. The runner removed its +container and image; a separate `docker ps` and image-list audit found no +owned resources. + +The original opaque-iframe browser audit blocked `get_config` before panel +initialization completed, so it did not prove a usable frontend. This native +test confirms only a configuration backend path. No cloud authentication, +rclone download or sync, screenshot deletion, process signal, game event, +real Frame backend, VR visibility or physical controller was exercised. +The published `rclone_manager.py` names an amd64 rclone download, so this +result does not establish ARM64 sync support. Game Sync remains **partial**. diff --git a/docs/framey-compatibility.md b/docs/framey-compatibility.md index 5dcc0fb..6bf5fc8 100644 --- a/docs/framey-compatibility.md +++ b/docs/framey-compatibility.md @@ -118,7 +118,7 @@ The API column shows manifest / actual bundled frontend API. Many manifests say | 101: XIVOmega 1.0.2 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame | | 102: DeckSP 1.1.3 | 1 / 2 | broken | Optional UI-audio lookup succeeds, but the published frontend raises "Cannot access PluginManager before initialization" when Steam MobX reaction lookup is unavailable. JamesDSP installation/audio routing and ARM64 remain unverified. | static archive, local browser, fake-Frame | | 103: Decky Ludusavi 1.2.2 | 1 / 2 | partial | Initializer succeeds; Flatpak Ludusavi discovery and backup/restore unverified. | static archive, local browser, fake-Frame | -| 104: Game Sync 1.0.4 | 1 / 2 | partial | Backend get_config is intentionally rejected by the audit before initialization completes; actual backend compatibility is unknown. | static archive, local browser, fake-Frame | +| 104: Game Sync 1.0.4 | 1 / 2 | partial | Exact official backend discovers under Decky 3.3.0 amd64; default get_config and a private setting read/write survive a loader restart. The isolated browser baseline still stops at its denied get_config call. Cloud login, rclone download/sync, process signals, ARM64, real Frame and VR are unverified. The published updater names an amd64 rclone download, so no ARM64 sync claim follows. | static archive, local browser, fake-Frame, native Decky amd64 configuration | | 105: WiFi Locker 1.0.2 | 1 / 2 | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame | | 106: LetMeReShade 1.8 | 1 / 2 | partial | Initializer succeeds; Deck-model assumptions, shader downloads and game modifications unverified. | static archive, local browser, fake-Frame | | 107: Decky Sunshine 2025.10.27-dddf365 | legacy / legacy | broken | This plugin needs root and is not supported by the Frame user service. | static archive, local browser, fake-Frame | diff --git a/tests/decky-runtime/cases.json b/tests/decky-runtime/cases.json index 14c936d..6f41e6e 100644 --- a/tests/decky-runtime/cases.json +++ b/tests/decky-runtime/cases.json @@ -19,6 +19,11 @@ "shim": null, "probe": "radio-local" }, + { + "id": 104, + "shim": null, + "probe": "game-sync-config" + }, { "id": 63, "shim": null, diff --git a/tests/decky-runtime/check.py b/tests/decky-runtime/check.py index 1758f93..8f78401 100644 --- a/tests/decky-runtime/check.py +++ b/tests/decky-runtime/check.py @@ -267,6 +267,28 @@ def main(): assert current('read_deals') == {} report['result'] = ('discovery, default settings, empty local deals, ' 'private setting write/read and restart persistence passed; feed, notifications and VR unverified') + elif case['probe'] == 'game-sync-config': + # Exercise only private settings. This plugin also exposes + # rclone cloud sync and arbitrary process signals; neither + # belongs in a passive compatibility probe. + settings = current('get_config') + assert settings['sync_on_game_start'] is False, settings + assert settings['sync_on_game_stop'] is False, settings + assert settings['capture_upload'] is False, settings + assert settings['advanced_mode'] is False, settings + assert current('set_config', 'advanced_mode', True) is None + assert current('get_config')['advanced_mode'] is True + os.killpg(backend.pid, signal.SIGTERM) + backend.wait(timeout=8) + backend = subprocess.Popen([str(loader)], env=env, stdout=log, stderr=log, + start_new_session=True) + processes.append(backend) + until_ready(lambda: rpc('loader/get_plugins'), 'restarted Decky discovery') + assert until_ready(lambda: current('get_config')['advanced_mode'], + 'private Game Sync setting after restart') is True + assert not (base/'rclone').exists() + report['result'] = ('discovery, default config and private setting restart persistence passed; ' + 'rclone, cloud authentication, sync, process signals, real Frame and VR unverified') elif case['probe'] == 'radio-local': # The published backend accepts arbitrary URLs and disables # HTTPS verification. Exercise only a loopback fixture inside diff --git a/tests/fixtures/framey-official/104.zip b/tests/fixtures/framey-official/104.zip new file mode 100644 index 0000000..86e5ce1 Binary files /dev/null and b/tests/fixtures/framey-official/104.zip differ diff --git a/tests/fixtures/framey-official/README.md b/tests/fixtures/framey-official/README.md index ee31468..95a9aed 100644 --- a/tests/fixtures/framey-official/README.md +++ b/tests/fixtures/framey-official/README.md @@ -3,7 +3,7 @@ These are unmodified ZIPs downloaded from the official Decky store CDN on 2026-10-25, except `96.zip` and `111.zip` downloaded on 2026-10-26 and `60.zip` on 2026-10-27; `13.zip` and `125.zip` were added from the digest-verified audit cache on 2026-10-27, -and `67.zip` and `114.zip` on 2026-10-28. `24.zip` was added on 2026-10-29. +and `67.zip` and `114.zip` on 2026-10-28. `24.zip` and `104.zip` were added on 2026-10-29. Each ZIP includes its upstream `LICENSE`. They are test data, not plugins shipped or installed by Frame Control. The fake Frame tests serve them from a local fixture so CI does not depend on the store being online. @@ -12,6 +12,7 @@ from a local fixture so CI does not depend on the store being online. | --- | --- | --- | --- | | `13.zip` | Pause Games | 1.0.3 | `4aefdfb0ef25dea9c6d9fd037731c8b99ee8a1be966c2f7d5b0602112ef29f62` | | `24.zip` | RadiYo! | 1.3 | `647111578aa7a5ecd16af8d7fe6c068a6d7ea8737c6dce5ac2d52e84a549ec43` | +| `104.zip` | Game Sync | 1.0.4 | `65e021ebb37d2ebfbfbe3dbc8af95aef9556cf484730362c6b26c4ecc3e62ccd` | | `60.zip` | DeckyFileServer | 1.2.0 | `7dc2ecdcd05aa415d1ac90afaff28ecb17f77809a2bc7a77aee8e92505b976f0` | | `125.zip` | Decky Localsend | 0.4.5 | `e271ccb55eb23f918b99a69f79aec905df4c9b2ef7b23bbf4ec1c2d1a6f0c6b7` | | `114.zip` | Network Sentinel | 1.0.4 | `d3e07f40a0c800e72d15594e03c8c61e9bf3092524a578a0260520e735b971a5` | @@ -64,6 +65,10 @@ checks saved true/false state and matching settings callbacks; effects are inert RadiYo! runs through actual published Decky 3.3.0 legacy RPC in a network-isolated container. Only loopback station fetch, custom-station fetch and redirect are tested. External radio, HTTPS and audio playback remain unverified. +Game Sync runs through actual published Decky 3.3.0 instance RPC in the same +isolation. Only default configuration and a private setting surviving restart +are checked. No rclone, cloud sync, process signal, Frame backend or VR action +is tested. Network Sentinel runs through the same isolated native Decky gate. Its exact archive gets plugin-local psutil and a user-service manifest; the probe checks discovery, private settings and one monitoring-loop sample without external diff --git a/tests/framey_official.py b/tests/framey_official.py index fc6a3db..c6b72ec 100644 --- a/tests/framey_official.py +++ b/tests/framey_official.py @@ -12,6 +12,8 @@ PLUGINS = ( 'folder': 'SDH-PauseGames', 'sha256': '4aefdfb0ef25dea9c6d9fd037731c8b99ee8a1be966c2f7d5b0602112ef29f62'}, {'id': 24, 'name': 'RadiYo!', 'version': '1.3', 'api_version': 'legacy', 'folder': 'radiyo-steam-deck', 'sha256': '647111578aa7a5ecd16af8d7fe6c068a6d7ea8737c6dce5ac2d52e84a549ec43'}, + {'id': 104, 'name': 'Game Sync', 'version': '1.0.4', 'api_version': 1, + 'folder': 'SDH-GameSync', 'sha256': '65e021ebb37d2ebfbfbe3dbc8af95aef9556cf484730362c6b26c4ecc3e62ccd'}, {'id': 60, 'name': 'DeckyFileServer', 'version': '1.2.0', 'api_version': 1, 'folder': 'DeckyFileServer', 'sha256': '7dc2ecdcd05aa415d1ac90afaff28ecb17f77809a2bc7a77aee8e92505b976f0'}, {'id': 125, 'name': 'Decky Localsend', 'version': '0.4.5', 'api_version': 1, diff --git a/tests/test_framey_decky_runtime.py b/tests/test_framey_decky_runtime.py index c0f35e4..71428f7 100644 --- a/tests/test_framey_decky_runtime.py +++ b/tests/test_framey_decky_runtime.py @@ -21,7 +21,7 @@ class RuntimeCoverage(unittest.TestCase): self.assertIn(case['id'], official) self.assertIn(case['probe'], ('mpris', 'screenshots', 'system-monitor', 'timer-lifecycle', 'toggle-settings', 'fileserver', 'localsend', 'network-sentinel', - 'battery-tracker', 'free-loader', 'radio-local')) + 'battery-tracker', 'free-loader', 'radio-local', 'game-sync-config')) def test_new_shim_without_runtime_case_fails_coverage(self): import frame_decky_store diff --git a/ui/framey-compatibility.json b/ui/framey-compatibility.json index 2933325..b8e7f22 100644 --- a/ui/framey-compatibility.json +++ b/ui/framey-compatibility.json @@ -8880,12 +8880,13 @@ "https://github.com/GedasFX/decky-cloud-save" ], "status": "partial", - "reason": "Backend get_config is intentionally rejected by the audit before initialization completes; actual backend compatibility is unknown.", + "reason": "Exact official backend discovers under Decky 3.3.0 amd64; default get_config and a private setting read/write survive a loader restart. The isolated browser baseline still stops at its denied get_config call. Cloud login, rclone download/sync, process signals, ARM64, real Frame and VR are unverified. The published updater names an amd64 rclone download, so no ARM64 sync claim follows.", "blockInstall": false, "verification": [ "static archive", "local browser", - "fake-Frame" + "fake-Frame", + "native Decky amd64 configuration" ], "browser": { "id": 104,