Compare commits

..
Author SHA1 Message Date
Alex Southwell 38dbd4cc0b Merge branch 'main' into docs/freeloader-native-accuracy 2026-10-28 21:04:55 +00:00
Alex Southwell 0c0df7a243 Merge pull request #387 from saphid/fix/frame-smoke-skip-exit
Fail Frame smoke when a launch is skipped
2026-10-28 20:51:24 +00:00
SAPHID 04ccdda050 Correct Free Loader native Decky verification summary 2026-10-28 20:44:36 +00:00
SAPHID 6c37fbbd37 Fail Frame smoke when any launch is skipped 2026-10-28 20:35:06 +00:00
Alex Southwell e7b037ce88 Merge pull request #386 from saphid/docs/support-matrix-v0453
Align current support matrix with v0.4.53 evidence
2026-10-28 20:25:46 +00:00
6 changed files with 41 additions and 9 deletions

No files matched your search

@@ -0,0 +1,31 @@
# v0.4.54 candidate hold, 28 October 2026
The local, unpushed `release/v0.4.54` candidate is commit
`3eefedd8d4dd2ce8db7d62d0dd2d7cff1fe2089b`, based on main
`e7b037ce883e45990bf239aee29b05434a39a399`. It changes only the
version in `app/package.json` and `app/package-lock.json`. It has not been
tagged or published. The latest public release remains
[v0.4.53](https://github.com/saphid/frame-control/releases/tag/v0.4.53).
The locked real Frame smoke at 20:28 UTC read SteamVR activity 3 (standby),
proximity 2.3125 and battery 100% on Frame OS build `20261022.6153909`.
ARM64 and Windows/Proton test titles launched. The x86_64 test title did
**not** launch: Steam reported that Steam Linux Runtime 4.0 was found but
not installed. The result has **12 passed, 1 skipped, 0 failed**. Its final
cleanup step passed and its unique lock was released. The private JSON result
is `/tmp/frame-v0454-smoke-results/2026-10-28T202826Z-20261022.6153909.json`
with SHA-256 `d86edaec0b86faf130c21aa3d7113cc1ac5b2ae0869dbd15f811bf3bb5b76b88`.
A separate read-only audit acquired and released a fresh unique headset lock.
It read activity 3, proximity 2.3125 and battery 100%, and found no reserved
smoke title directories or owned test processes. It did not wake the Frame or
send input. Nobody confirmed wearing the Frame, so no wearer-visible or
physical-controller result follows.
**Release decision: hold v0.4.54.** The smoke script at the candidate commit
returned exit 0 even though it recorded a skipped launch. Under the current
release rule, a skip cannot satisfy the smoke gate. The accompanying change
makes a skipped smoke return nonzero while preserving the explicit skipped
step and cleanup record. Exact release-commit CI, release verification, tagged
installer builds, checksums and publisher dry run have not been performed for
this local candidate.
+1 -1
View File
@@ -25,7 +25,7 @@ python3 scripts/framey-audit-browser.py --cache /tmp/framey-archives
Open the browser audit URL in local Chromium, run `runAudit()` and inspect/download `results`. All backend/network actions remain denied.
A [Free Loader duplicate-entry follow-up](evidence/framey-free-loader-duplicates-2026-10-26.md) accepts only byte-identical duplicate ZIP members whose modes differ at most in execute bits. The exact archive passed private local and focused fake-Frame install/remove; its frontend rendered in opaque Chromium and isolated Python settings/empty-deals reads passed with a Decky stub. The earlier full 116-plugin fake-Frame audit blocked this archive before the fix. Actual Decky, feed updates and worn VR remain unverified.
A [Free Loader duplicate-entry follow-up](evidence/framey-free-loader-duplicates-2026-10-26.md) accepts only byte-identical duplicate ZIP members whose modes differ at most in execute bits. The exact archive passed private local and focused fake-Frame install/remove; its frontend rendered in opaque Chromium. The earlier full 116-plugin fake-Frame audit blocked this archive before the fix. A later [native Decky 3.3.0 check](evidence/framey-free-loader-native-2026-10-28.md) verified plugin discovery, default settings, empty local deals and private setting persistence after restart in a network-isolated amd64 container. Live feed updates, notifications, Steam store integration, real Frame ARM64 service and worn VR remain unverified.
A [2026-10-28 static action-limit review](evidence/framey-static-action-limits-2026-10-28.md) hash-checked the exact AutoSuspend and CheatDeck archives. AutoSuspend contains Steam suspend/shutdown paths, and CheatDeck's advertised trainer flow needs a Steam game context menu and launch-option writes. Neither plugin was executed; both retain their broken labels.
+3 -2
View File
@@ -233,8 +233,9 @@ before (if it was, it stays, synced to this checkout as Frame Control always
does). A cleanup that fails counts as a failed step. Results go to
`tests/smoke/results/<time>-<BUILD_ID>.json` (not committed) with a summary on
screen. The summary counts passed, skipped and failed steps separately. It
exits 0 when no step failed (including a skipped optional runtime), 1 if a step
failed, or 2 if the headset isn't reachable.
exits 0 only when every step passed, 1 if a step failed or was skipped, or 2 if
the headset isn't reachable. A skipped x86-64 launch blocks a release smoke
gate even though it remains separately labeled in the result.
Smoke process cleanup runs before and after title removal and during the
initial/final leftover sweeps. It targets only the reserved `fc_smoke_arm64`,
+1 -1
View File
@@ -40,7 +40,7 @@ def render(data):
'python3 scripts/framey-audit-browser.py --cache /tmp/framey-archives',
'```', '',
'Open the browser audit URL in local Chromium, run `runAudit()` and inspect/download `results`. All backend/network actions remain denied.', '',
'A [Free Loader duplicate-entry follow-up](evidence/framey-free-loader-duplicates-2026-10-26.md) accepts only byte-identical duplicate ZIP members whose modes differ at most in execute bits. The exact archive passed private local and focused fake-Frame install/remove; its frontend rendered in opaque Chromium and isolated Python settings/empty-deals reads passed with a Decky stub. The earlier full 116-plugin fake-Frame audit blocked this archive before the fix. Actual Decky, feed updates and worn VR remain unverified.', '',
'A [Free Loader duplicate-entry follow-up](evidence/framey-free-loader-duplicates-2026-10-26.md) accepts only byte-identical duplicate ZIP members whose modes differ at most in execute bits. The exact archive passed private local and focused fake-Frame install/remove; its frontend rendered in opaque Chromium. The earlier full 116-plugin fake-Frame audit blocked this archive before the fix. A later [native Decky 3.3.0 check](evidence/framey-free-loader-native-2026-10-28.md) verified plugin discovery, default settings, empty local deals and private setting persistence after restart in a network-isolated amd64 container. Live feed updates, notifications, Steam store integration, real Frame ARM64 service and worn VR remain unverified.', '',
'A [2026-10-28 static action-limit review](evidence/framey-static-action-limits-2026-10-28.md) hash-checked the exact AutoSuspend and CheatDeck archives. AutoSuspend contains Steam suspend/shutdown paths, and CheatDeck\'s advertised trainer flow needs a Steam game context menu and launch-option writes. Neither plugin was executed; both retain their broken labels.', '',
'A [Network Sentinel user-service check](evidence/framey-network-sentinel-2026-10-28.md) adapts only the exact 1.0.4 digest. In isolated actual Decky 3.3.0 amd64, the pinned plugin-local psutil wheel, private settings RPC and one monitoring-loop sample pass. External ping/DNS, Frame ARM64, panel controls and worn VR remain unverified; this is partial compatibility.', '',
'A [Battery Tracker user-service check](evidence/framey-battery-tracker-2026-10-28.md) adapts only the exact 0.2.0 digest. A locked read-only Frame probe confirmed a Battery-type supply with the required fields; actual Decky 3.3.0 amd64 recorded private Frame-shaped samples and returned history/per-app power. The managed plugin has not run on the real Frame, and panel controls and worn VR remain unverified; this is partial compatibility.', '',
+3 -3
View File
@@ -28,8 +28,8 @@ rechecked around deletion; shared Proton services are never stopped by name.
Usage: python3 tests/smoke/frame_smoke.py [--pair] (or scripts/frame-smoke.sh)
Env: FRAME_ALIAS (default frame), FRAME_SMOKE_RESULTS (default tests/smoke/results)
Exit status: 0 no step failed (optional runtime may skip a launch), 1 a step
failed, 2 the headset isn't reachable.
Exit status: 0 every step passed, 1 a step failed or was skipped, 2 the
headset isn't reachable. A skipped launch is not a release smoke pass.
"""
import argparse
import json
@@ -425,7 +425,7 @@ def run_smoke(args, before):
'passed': passed, 'skipped': skipped, 'failed': failed,
'devkit_utils_there_before': had_utils, 'steps': smoke.steps}, indent=1))
print(f'==> {passed} passed, {skipped} skipped, {failed} failed on build {build}; results in {out}')
return 0 if failed == 0 else 1
return 0 if failed == 0 and skipped == 0 else 1
def main():
+2 -2
View File
@@ -134,7 +134,7 @@ class Safety(unittest.TestCase):
launch.assert_called_once_with(gid)
remove.assert_called_once_with(gid)
def test_optional_runtime_skip_is_counted_separately_in_saved_result(self):
def test_optional_runtime_skip_fails_gate_and_is_counted_in_saved_result(self):
with tempfile.TemporaryDirectory() as root:
output = Path(root) / 'results'
folder = Path(root) / 'titles'
@@ -156,7 +156,7 @@ class Safety(unittest.TestCase):
mock.patch.object(frame_smoke, 'title_cycle', side_effect=cycle), \
mock.patch.object(frame_smoke.tempfile, 'mkdtemp', return_value=str(folder)):
self.assertEqual(frame_smoke.run_smoke(mock.Mock(pair=False),
{'activity': 3, 'proximity': [], 'battery': [100]}), 0)
{'activity': 3, 'proximity': [], 'battery': [100]}), 1)
result = json.loads(next(output.glob('*-fake.json')).read_text())
self.assertEqual((result['passed'], result['skipped'], result['failed']), (6, 1, 0))
self.assertEqual(next(s for s in result['steps'] if s['step'] == 'x86_64: launch')