Keep worker notes and proof logs out of the repository

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
saphidandClaude Opus 5.5 committed 2026-09-28 23:38:54 +10:00
1 parent 1b5f540a66
commit 3b36feff52
10 files changed
-515

No files matched your search

-6
View File
@@ -1,6 +0,0 @@
/proof-cache/
/amazon.html
/aptoide-terms.html
/itch-game.html
/meta.html
/uptodown-terms.html
-64
View File
@@ -1,64 +0,0 @@
# APK search
- Scope: dynamic source aggregator, additive server APIs, Android search view; no device calls.
- Source metadata stays unknown when missing. Unknown-package names only group with other unknown packages (avoids ambiguous package attribution).
- Queries use daemon workers with at most one in-flight request per source; deadlines don't wait for stuck workers.
- Independent review delegated to parent per task brief; no workers launched.
## Implementation
- `ui/apk_sources/search.py`: discovers KIND modules, parallel daemon queries (12 s deadline), bounded per-source workers, grouped offers, fit/rank/filter logic, persisted source enablement, repo adapter and install adapter.
- `ui/server.py`: GET `/api/sources`, GET `/api/search?q=&vr=true|false&installable=true|false&source=`, POST `/api/sources/install` and POST `/api/sources` with actions `add`, `remove`, `enable`.
- `ui/index.html`: unified Find apps in Android tab, source/VR/Flat/Installable chips, offer picker, metadata, jobs, Sources panel. Old catalogue DOM remains hidden for existing report/icon code; only the unified search is visible.
- `_demo.py` is discovered only with `FRAME_APK_SEARCH_DEMO=1`; it cannot download. `tests/search_preview.py` serves the real UI/search endpoints and rejects all device endpoints and writes.
## Evidence
- `python3 -m unittest discover -s tests`: 179 tests passed on Python 3.9.6, exit 0. Log `/tmp/apk-search-suite.log`.
- `node --check /tmp/apk-search-evidence/ui.js`: exit 0; script extracted from index.html.
- `git diff --check`: exit 0.
- Python 3.9 grammar parse: search.py, _demo.py, server.py, test_apk_search.py and search_preview.py passed; actual suite interpreter also Python 3.9.6.
- Started `FRAME_APK_SEARCH_DEMO=1 python3 tests/search_preview.py` locally; used T3 preview at http://127.0.0.1:8795/#android (1280x800).
- Browser assertions: two grouped apps, source picker updates install choice, VR excludes flat, Flat excludes VR, source filter keeps one offer, search query narrows results, pending install disables its button after re-render. Passed.
- Inspected screenshots: `/tmp/apk-search-evidence/search.png`, `/tmp/apk-search-evidence/sources.png`. Other panels show intentional device-access errors in the preview.
- Tests cover dynamic module discovery, grouping (including ambiguous names), ranking, fit, timeout/failure isolation, persistent enablement, endpoint validation, repo callbacks, background install with mocked frame_android.install, conditional artwork, and OBB support/refusal.
## Parent integration / unverified
- No source modules from sibling branches are present yet. Real network listings/downloads, signatures, merged repo persistence and physical installation were not exercised. No SSH/device installation performed.
- Assumes future `frame_android.install_obb(package, paths)`; reconcile with vr-library worker's actual signature. Artwork is passed only when install explicitly declares that parameter. OBB-required apps fail before APK installation when helper is absent.
- `app/package.json` currently copies ui with only `*.py` / `*.html`; parent must include `apk_sources/**/*.py` in packaged resources when integrating source workers. Kept package config outside this worker's scope.
- No cross-provider reviewer launched: task explicitly forbids delegation and assigns integration/review to the parent.
- Source metadata unknowns do not imply compatibility or verification. Unknown-package entries only group with other unknown-package entries with the same normalized name.
## Store redesign (follow-up)
- Read `/tmp/vrapk/p5-redesign.md` and common ground rules in full. Consulted Human Interface Craft, especially purpose/information, hierarchy, progressive disclosure and familiar navigation.
- Discover now owns the Android tab's full width; device controls/reports remain under On your Frame. Artwork cards, a featured app, browse rows, debounced search, friendly filters/count/empty state and skeletons replace the technical listing.
- Details use a native dialog with banner/icon, creator, description, screenshots with keyboard/arrow controls, badges, primary installation action and friendly source choices. Technical identifiers and compatibility facts are collapsed.
- Sources use a separate native settings dialog with aligned switches, source initials, descriptions, trust labels and repository form. A failed source produces a quiet human-readable notice.
- `_images.py` registers only source-entry artwork, returns opaque handles, permits HTTP(S) raster images only, rejects private/link-local/reserved IPs (including redirected targets), connects to the validated IP with TLS hostname checking, limits images to 8 MiB and bounds its memory cache to 64 MiB / registry to 4096 handles. Browser requests are same-origin `/source-image/<opaque handle>`; arbitrary URLs are never accepted by the HTTP endpoint.
- New GET `/api/sources/details?source=&id=` supplies richer details. Search decorates offers with `artwork` and a plain-language `verdict`.
- Optional source metadata is documented in search.py: `images: {icon, banner, screenshots}`, developer, description, popularity, open_source, requires_meta_services, frame_tested. Only explicit `frame_tested=True` earns Works on the Frame. Installability alone says Ready to try. No fabricated popularity labels when a source provides no ranking data.
- Background jobs accept an optional progress reporter; source installs report Downloading and Installing. The UI displays a percentage only if supplied by a job. Current shared download() interface provides no byte progress, so real sources show truthful indeterminate stages, not fabricated percentages.
- Demo listings include real recorded public artwork plus clearly documented illustrative listing metadata. Preview installer alone simulates percentages and completion; it never calls frame_android.install or SSH. Repo toggles in preview use an isolated temporary settings file.
### Visual review and evidence
- Iteration 1: inspected browse and detail screenshots; found too much vertical space above the app rows and description. Reduced hero/banner heights and header spacing.
- Iteration 2: inspected wide and narrow layouts; moved desktop search beside the heading, placed a full popular row before the short VR row, compacted the disconnected-headset notice for browsing, aligned settings switches, preserved radio focus after detail refresh and improved progress text contrast.
- Final visual inspection: 1440x1050 desktop and 390x844 narrow viewport, two narrow columns (172px each), document width 380px inside a 390px viewport (no horizontal overflow).
- Final PNGs in `/tmp/apk-search-evidence/v2/`: browse-home.png, search-results.png, app-details.png, install-progress.png, sources-sheet.png, empty-state.png, narrow-window.png. Iteration screenshots retained there too.
- Browser checks via T3 preview at http://127.0.0.1:8795/#android: six grouped apps; no package/API/ABI/engine/demo jargon in browse; typing `world` yields three apps after debounce; app details contain three screenshots and two source choices; source selection updates installation target and keeps keyboard focus; disabling itch.io removes its notice and persists for subsequent searches; simulated install displays Downloading 43%, then completion and Open in Steam; empty search renders illustrated recovery; narrow two-column layout has no horizontal overflow.
- `FRAME_APK_SEARCH_DEMO=1 python3 tests/search_preview.py` started the local server used above. Real device endpoints rejected.
- `python3 -m unittest discover -s tests`: 188 tests passed on Python 3.9.6, exit 0. Final log `/tmp/apk-search-evidence/v2/unittest.log`.
- `node --check /tmp/apk-search-evidence/v2/ui.js`: exit 0 (inline script extracted from final index.html).
- Python 3.9 grammar parse: seven changed/new Python files passed. `git diff --check`: exit 0.
### Still unverified / parent integration
- Real source modules, real repository add/remove writes, real downloads and physical headset launch/install are not tested. No SSH or device installation performed.
- Image fetch transport tested with mocks; preview serves recorded images through the actual HTTP image endpoint/cache. Live asset files were fetched separately to create fixtures; live proxy TLS/redirect behavior across provider CDNs remains unverified.
- Percentages in install-progress.png are explicitly simulated by the preview harness. Real provider byte-progress integration needs an extension to the shared download interface; stage reporting works now.
- Source workers must provide `images` and creator/description metadata for rich listings; fallback gradients/initials work without them. Frame-tested/popularity signals must be backed by source evidence, not inferred from installability.
- The earlier packaging (`apk_sources/**/*.py`) and install_obb signature integration notes still apply. No Electron build or cross-provider review run; parent owns integration/review and this brief prohibits delegation.
-69
View File
@@ -1,69 +0,0 @@
# more-sources
Scope: only this worktree/branch; no delegation, SSH, installation, push, PR or
issue writes. Parent performs integration and independent review per brief.
Decisions: implement GitHub curated public APK releases and itch.io RSS page
links. itch robots exclude keyed download pages used by /tmp/vrapk/itchdl.py;
no bypass. Topic results are not automatically trusted. Curated Open Brush and
SuperTux prereleases must be explicitly allowed; discovered during fixture tests.
No shared files changed. Default GitHub search makes no network request.
Evidence (2026-09-28):
- Read all six prerequisite files and the full brief.
- Fetched itch terms, root/author robots and OpenXR RSS with FrameControl UA.
- Anonymous GitHub returned 403 rate-limit; authenticated gh API reads succeeded.
- GitHub fixtures record upstream Khronos, Open Brush and SuperTux releases.
- `python3 .claude/prove-more-sources.py`: GitHub search/download succeeded,
published SHA-256 matched; `python3 ui/frame_android.py info` exited 0.
Overall script exit 1 because subsequent itch RSS request returned HTTP 429.
A second invocation had the same outcome; no further live itch retries.
- Download: `.claude/proof-cache/f24bbe8ba6f6339fca658628868ba8189cbc33390d6ac508f69d76fb67b5fa34.apk`.
Package org.khronos.openxr.hello_xr.vulkan; 1.1.63/1063; API 24; arm64;
OpenXR. No runtime compatibility claim.
- Initial whole suite: 174 tests, 1 failed (prerelease handling). After explicit
curated prerelease support: 174 tests passed, exit 0. Final rerun below.
Unverified: live itch search completion (429), itch download/info (disallowed
flow), Open Brush/SuperTux downloads, topic live adapter search (API fixture
capture succeeded), headset runtime, UI integration, independent provider
review (explicit implementation brief prohibits delegation and assigns review
to parent). No claim that any reviewer/model participated.
Research HTML and local downloaded APKs are local evidence only, not committed.
Recorded fixtures retain public source data, not credentials. The proof script
uses gh's token in memory and overrides cache into this worktree.
Final verification:
- Python version: 3.9.6.
- `python3 -m unittest discover -s tests > .claude/tests-more-sources.log 2>&1`:
174 tests passed in 5.569s, real exit 0.
- `git diff --check`: exit 0.
- Final artifact: docs/apk-sources.md plus two source modules, a private HTTPS
helper, curated JSON, recorded fixtures and tests. Evidence scripts/logs stay
in .claude; research HTML and APK cache are explicitly ignored there.
## Artwork follow-up
Added curated icon/images metadata and plain-language summaries. Icons use
publisher repository assets pinned to inspected commits. Open Brush's banner
is its README image; three screenshots are from its README-linked Steam page.
SuperTux's banner/screenshot is the upstream gameplay preview in the port's
README, not a Quest capture. hello_xr has its actual Vulkan launcher icon and
repository social banner; no real screenshot was found in its repository or
README, so screenshots stays empty rather than mislabeling branding.
Topic search uses owner.avatar_url and the requested GitHub social-preview
pattern, retaining curated artwork when a curated app is discovered by topic.
Unknown repository details use GitHub's owner.png avatar endpoint and the same
social banner without an extra API request. Existing itch cover behavior is
unchanged; tests now assert icon/banner equality and empty screenshots because
the recorded RSS provides no separate screenshots.
Validation: all nine distinct curated artwork URLs returned HTTP 200, image
Content-Type and image magic. Of six topic artwork URLs, five returned images
and LWJGL's social preview returned HTTP 429. Recorded in
`tests/fixtures/more_sources/artwork-check.json`; no repeated retry.
`python3 -m unittest discover -s tests`: 176 passed in 5.879s, real exit 0.
`git diff --check`: exit 0. No UI rendering/headset testing or independent
review; parent retains integration/review, and delegation remains prohibited.
-55
View File
@@ -1,55 +0,0 @@
# SideQuest implementation notes
2026-09-28. Worktree steam-frame-sidequest, branch sidequest. No delegation,
Frame mutations, installs, launches, pushes or issue edits.
- Read shared source interface, APK/VR docs, catalogue README and Python backend.
- SideQuest robots: crawl delay 3; disallow /search/, /user/*, /sideload/*.
- Current /terms Angular text (main-4MMXZRXL.js): Prohibited Activities (i)
prohibits scraping; (xi) limits access to provided/authorised technologies;
(xii) forbids bypass. Public API address is not permission for a third-party
integration. Page-only source; no automated store downloads or metadata crawl.
- api.sidequestvr.com/robots.txt returned HTTP 403. First shared JS chunk also
returned 403. No attempt to bypass either response.
- Public SideQuest desktop source cloned inside .claude/research for inspection.
/install-from-key takes a website-issued token and returns apps[].urls[] with
provider APK/OBB/Github Release/Mod and link_url. Do not reproduce token flow.
- Two SSH read-only attempts to frame timed out (exit 255). Exact host-side
/sdcard mapping cannot be claimed. internal/<package> is private app data,
not evidence of an OBB mapping. Use the running container's /sdcard path for
OBB writes, without launching it; backup only documented internal/<package>.
- Scope: OBB helper/CLI, private-data backup/restore helper/CLI, compliant
SideQuest page-only source. No search UI, artwork installer or install edits.
- Cross-provider review not launched: task explicitly forbids delegation;
parent brief reserves integration and review for the parent.
## Implementation and verification
- Added ui/frame_android_data.py and frame/android/app-data.py; additive wrappers
and CLI branches only in frame_android.py (install/_install unchanged).
- OBB transfers to an already-running named container, SHA-256 check before
per-file rename. No claimed host sdcard mapping or device persistence.
- Backup/restore covers private internal/<package> only, requires a stopped
instance, uses podman unshare, validates archive paths/types/package/instance,
preserves numeric owners/modes, retains the prior data directory on restore.
- SideQuest adapter intentionally raises a page-only SourceError on search and
download; details gives a numeric listing page with unknown facts, images
schema and downloadable=False. Needs aggregate search to surface the error.
- docs/sidequest.md contains source links, feature comparison, command examples,
terms/robots findings and outstanding device/API questions.
- Fixture tests/fixtures/sidequest-policy.json records observed policy excerpts;
no API response is fabricated.
- `python3 -m unittest discover -s tests`: final run 181 tests, OK (exit 0).
Includes real local shell execution of the OBB checksum/publish sequence,
rejecting a changed input without replacing the previous file; archive
round-trip/retained previous save, 0600 backup, malformed archive rejection.
No test contacts the network or Frame.
- `ast.parse(..., feature_version=(3,9))`: four implementation files passed.
Runtime python3 is Xcode Python 3.9.
- `python3 ui/frame_android.py install-obb` and `... backup-data`: both exit 1
with the intended required-arguments error, without contacting Frame.
- `git diff --check`: passed before commit.
- No SideQuest game downloaded and no `info <download>` run: terms blocked that
requested E2E. No Frame app was installed or launched; no live OBB, namespace
ownership or restore acceptance test. Independent review reserved for parent,
per this task's explicit no-delegation instruction.
-80
View File
@@ -1,80 +0,0 @@
# User repositories
Scope: ui/apk_sources/fdroid.py, fixture tests and docs/apk-repos.md. No headset access.
No delegation or independent reviewer launched: task explicitly forbids delegation;
parent integrates and reviews. Existing catalogue API stays unchanged.
Decisions:
- Support F-Droid signed v2 and v1, HTTPS only, RSA PKCS#1 CMS/JAR verification.
- Pin operator certificate fingerprints. Without a supplied fingerprint, verify
the complete signature chain of hashes on first use, then persist that signer.
- Reuse frame_catalog._IndexReader and _reduce_index; keep authenticated source
cache separate from legacy unauthenticated catalogue cache to avoid laundering trust.
- Sources list compatible builds (Android <=30, arm64 or no native code), as
existing catalogue reducer does. This is compatibility filtering, not a runtime guarantee.
- No Obtainium export import or new unsigned JSON format in this source.
Research: downloaded F-Droid API/setup docs, Obtainium and SideQuest READMEs,
Izzy repo page and entry.jar via HTTPS. Izzy's published fingerprint matched
pure-Python CMS validation: 3BF0D6ABFEAE2F401707B6D966BE743BF0EEE49C2561B9BA39073711F628937A.
## Final verification
All commands below ran in /Users/saphid/projects/steam-frame-userrepo on user-repos.
- `python3 --version`: Python 3.9.6.
- `python3 -m unittest discover -s tests -p test_fdroid_sources.py`: initially
13 tests, OK, exit 0. Added a cache-corruption test afterward.
- Final `python3 -m unittest discover -s tests`: 180 tests in 6.866s, OK,
exit 0 (includes 14 source tests and existing catalogue/version tests).
- `python3 ui/apk_sources/fdroid.py add 'https://apt.izzysoft.de/fdroid/repo?fingerprint=3BF0D6ABFEAE2F401707B6D966BE743BF0EEE49C2561B9BA39073711F628937A' --name 'IzzyOnDroid verification'`: exit 0;
saved fdroid-user-57e98c13877f14fdea65 with the published pin.
- `python3 ui/apk_sources/fdroid.py search fdroid-user-57e98c13877f14fdea65 'tinymusicplayer'`:
exit 0; com.martinmimigames.tinymusicplayer, version 1.3 / code 4,
GPL-3.0-only, 16,520 bytes.
- `python3 ui/apk_sources/fdroid.py download fdroid-user-57e98c13877f14fdea65 com.martinmimigames.tinymusicplayer`:
exit 0, verified true. Independent hashlib readback matched
d7bcb24d101b04beb3394b695b24be4e2c3d6ed702f1d0e06bc4dd707f64d86a.
- Direct `_fetch` + `_jar` calls on F-Droid main/archive entry.jar: exit 0;
both matched the published 43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab pin.
- `.claude/user-repos-proof.json` retains live CLI results and APK readback.
Live APK remains in the per-user apk-sources cache; the added source remains
in the per-user apk-repos.json, as requested for the real add/search/download run.
Not verified: headset installation/runtime, native UI/server integration (sibling
worker), real v1-only server (offline signed fixture covers fallback), executing
the fdroidserver publishing instructions, full F-Droid main/archive index/APK
downloads (their live signed entry jars were checked). No independent reviewer
was run because this task forbids delegation and assigns review to the parent.
Known limits / follow-up questions: only one RSA-2048–8192 JAR signer supported;
no ECDSA/DSA/PSS or section-only SF signatures; no index timestamp rollback or
expiry policy, automated key rotation or cross-process settings-write locking.
The settings API serializes threads and publishes atomically. Should a later
change add explicit rollback policy and broader JAR algorithms? Parent may
choose UI wording for TOFU; this source already returns trust_on_first_use.
## Artwork follow-up
Added `images: {icon, banner, screenshots}`, matching top-level `icon`,
`developer` from authorName, and HTML/entity-aware one-line summaries. Artwork
prefers en-US per field, then the first populated locale. Phone screenshots
precede seven-inch screenshots, with at most six unique URLs. v2 supports both
`screenshots.phone/sevenInch` and the older phoneScreenshots/sevenInchScreenshots
field names. v1 localized filenames are resolved under package/locale, with
legacy top-level icons resolved under icons/. Missing art remains null/empty.
No frame_catalog edit was necessary: this source already rereads raw metadata
after using the shared compatibility reducer. Incremented the source cache
schema so old entries refresh immediately rather than hiding artwork for a day.
Tests exercise v1/v2 metadata, cache round-trips and migration, locale fallback,
missing fields, legacy icon paths, screenshot bounds and summary cleanup.
Follow-up verification (Python 3.9.6, branch user-repos):
- `python3 -m unittest discover -s tests -p test_fdroid_sources.py`: 19 tests,
0.046s, OK, exit 0.
- `python3 -m unittest discover -s tests`: 185 tests, 5.081s, OK, exit 0.
- `git diff --check`: exit 0.
No live image fetch or redesigned store rendering was exercised; these remain
with the parent/UI integration. No independent review or delegation performed,
as explicitly requested. No new open implementation questions.
-126
View File
@@ -1,126 +0,0 @@
# vr-library implementation notes
Scope: `/tmp/vrapk/p1.md` plus parent updates mandating all-entrypoint artwork,
SteamGridDB, designed fallback art, settings/backfill and two visual iterations.
Worktree `/Users/saphid/projects/steam-frame-vrlib`, branch `vr-library`.
No delegation, push, PR or issue edits. Parent owns independent review and integration.
## Implementation
- Initial commit `c06b328`: shared artwork, collection handling, launcher
supervision, APK icon fallback and tests. Follow-up replaces its bitmap
artwork implementation with Steam Chromium canvas + Motiva Sans.
- `ui/frame_steamgriddb.py`: optional API provider, exact title (or trailing VR)
match, highest-scored returned static/non-NSFW artwork, separate portrait
and wide requests. No key means no requests/warnings. Saved settings are
atomic 0600 on POSIX; API never returns the key; auth redirects disabled.
- Precedence: provider, source slots/banner/feature graphic/screenshots, APK
icon/generated art. All five outputs have fixed Steam sizes. Host Python
stays stdlib-only and Python 3.9 compatible; Frame renders consistently
regardless of host OS. Package filters include both new JS resources.
- `frame/android/library_artwork.js`: dominant-colour gradient, blurred icon
backdrop, large icon/shadow, real font, no title in hero, transparent logo.
Removes only opaque near-black matte connected to icon corners. Native
icons remain original; opaque foreground app tiles have rounded corners.
- `apply_library` is mandatory for APK and native-title installs. CLI, upload,
catalogue, versions, web install and source install seam share it. Native
devkit executable/runtime is preserved. Failed initial art application
removes a newly created shortcut; no success with incomplete art.
- Refresh CLI/API/settings button repairs installed Android entries without
reinstalling/stopping, uses cached source art, queries SGDB again if enabled,
repairs missing shortcuts, and reports batch errors independently.
- Details: name/icon/VR flag, sort-as, Android/Android VR collections or native
Sideloaded, Installation details note preserving other notes. No supported
arbitrary description/store-page/developer/achievement metadata found.
Notes are keyed by sanitized name (Steam limitation: equal-name collisions).
- Device discovery: custom-art type 4 is broken on this Steam client: it logs
Unknown asset type and overwrites wide art with the icon. Use types 0–3 and
SetShortcutIcon separately. Confirmed actual cache after correction.
- Launcher retains its supervising shell under Steam, traps TERM/INT/HUP,
stops only its own container, kills its child group, preserves exit status.
Lock/pre-existing container guards prevent duplicate session cleanup.
- VR attribution discovery: Lepton uses SteamAppId for both stable context and
Android SteamVR identity. New shortcut.id + LEPTON_ENV_SteamAppId separates
them using Lepton's existing passthrough; container/data paths unchanged.
On-device source mounting.sh applies LEPTON_ENV_* after its regular setenv.
## Visual critique and iterations
Evidence `/tmp/vrlib-evidence/design-v1`, `design-v2`, `design-v3` (15 PNGs each).
Open Saber Plus/SuperTux icons came from authorized APKs. AntennaPod is a
preview only using the official F-Droid icon; it was not installed/launched.
1. v1: real typography/gradient already improves over old bitmap output, but
Open Saber has a black square matte, and SuperTux palette looks muddy.
2. v2: removed connected black matte; rounded the opaque AntennaPod foreground.
Inspected all three posters. SuperTux still muted; title line balance weak.
3. v3: lifted sampled saturation and balanced two-line labels. Inspected all
three posters plus final all-slot sheet. Large recognisable artwork, readable
typography, richer colours, textless hero and transparent title logo. Icon
source resolution still limits detail; source/SGDB art remains preferable.
Final sheet `/tmp/vrlib-evidence/artwork-preview-final.png` is an artwork
preview, NOT a Steam UI screenshot. Rows: portrait, wide, hero, logo/icon.
## Device verification (2026-09-28, build 20260925.6191901, SteamVR 2.18.1)
Steam was initially unavailable (old notes/evidence), then recovered. Both
APKs were reinstalled and refreshed successfully with zero library warnings:
- Open Saber Plus: org.godotengine.open_saber_plus, instance 2802929330,
shortcut 3346865537, game ID 14374678025558032384.
- SuperTux: org.supertux.supertux2, instance 2811892472,
shortcut 2883168793, game ID 12383115674816348160.
`steam-cache-final.log`: both actual Steam cache sets are 600x900, 920x430,
3840x1240, 1280x480, with app icon 256x256. `steam-details-targets.json`:
both correct names/sort-as, Android + Android VR, existing Played preserved.
Native managed note readback result 1 (success), saved as steam-notes-final.json.
Open Saber first session: Steam tracked it for 32 seconds; process and
container remained alive until only SteamClient TerminateApp was called.
After identity fix, a second session remained alive at 22 seconds (Android
PID 992), SteamVR identified steam.app.3346865537, and screenshot shows the
actual game scene instead of blank Resume tile. Steam Stop removed tracked
process and container within ~5 seconds. No direct podman-stop fallback was
used for this verification. Same data paths; existing game play count shown
in capture, but no separate save-file sentinel added to the real game.
Evidence: opensaber-identity-session.log, opensaber-identity-headset.png,
opensaber-running.log, opensaber-steam-stop.log, opensaber-headset-running.png.
SuperTux: Steam Play tracked the wrapper for ~17 seconds. SDLClipboardHandler
crashes with NullPointerException on missing ClipboardManager during activity
creation. Lepton and supervisor then cleaned up; it never reached a VR scene.
Steam Stop was issued after the crash, so sustained SuperTux Stop is NOT proven.
Evidence: supertux-running.log, supertux-lepton.log, supertux-shot.json.
Other test activity appeared on the device during checks (other Android
container and Gravitas). Neither was stopped or modified. Final Open Saber
preflight had no Android containers; other desktop overlays later appeared
in its headset capture. No global VR standby/dashboard settings changed.
Direct Steam UI Page.captureScreenshot timed out; no library UI screenshot.
## Automated verification and limits
- Whole suite: `python3 -m unittest discover -s tests`, Python 3.9.6. Final
result: **206 tests OK, 10.294 seconds, exit 0**. Log:
`/tmp/vrlib-evidence/tests-final.log`.
- Offline entrypoint tests exercise real shared install/render/configure flow
with SSH/API mocked: CLI, upload, catalogue, versions, web download, source
seam, native title and refresh. Provider ranking/failure/settings tests.
- Node contract test runs actual renderer against explicitly synthetic canvas,
validates all PNG dimensions and hero/logo text placement. This canvas is
also used by fakeframe; transparent fixture images are not visual evidence.
- Launcher tests assert stable context plus shortcut passthrough, signals,
normal exit, duplicate guard and saved-data sentinel. Earlier real Linux
setsid/flock fixture run: 3 tests OK (linux-launcher-tests.log).
- `bash -n`, Node syntax checks, Python AST feature_version=(3,9), diff checks.
- Docker E2E not run: `docker info --format '{{.ServerVersion}}'` exits 1;
daemon socket /var/run/docker.sock does not exist.
- Authenticated SGDB lookup/download unverified (no key configured).
- Windows/Linux packaged binaries not built/launched; filters tested.
- Native devkit art uses shared tested seam; no additional native title was
installed on device. Sibling source-search endpoint not in this worktree:
only its public installer contract is tested.
- Independent review not spawned: explicit brief forbids delegation and assigns
parent review/integration. No other provider/model participation claimed.
-36
View File
@@ -1,36 +0,0 @@
org.khronos.openxr.hello_xr.vulkan · 1.1.63 (code 1063)
Minimum: Android 7.0 (API 24)
ABIs: arm64-v8a, armeabi-v7a, x86, x86_64
Lepton can install this APK. Features may still need services Lepton lacks.
VR app
Uses OpenXR (good).
GitHub search: [{"source": "github", "id": "KhronosGroup/OpenXR-SDK-Source", "package": null, "name": "hello_xr", "summary": "Khronos OpenXR sample (Vulkan and OpenGL ES)", "icon": null, "images": {"icon": null, "banner": null, "screenshots": []}, "page": "https://github.com/KhronosGroup/OpenXR-SDK-Source", "version": null, "version_code": null, "min_sdk": null, "abis": null, "vr": true, "size": null, "free": true, "license": "Apache-2.0", "updated": null, "downloadable": true}]
GitHub download: {"apk": "/Users/saphid/projects/steam-frame-moresrc/.claude/proof-cache/f24bbe8ba6f6339fca658628868ba8189cbc33390d6ac508f69d76fb67b5fa34.apk", "obb": [], "sha256": "f24bbe8ba6f6339fca658628868ba8189cbc33390d6ac508f69d76fb67b5fa34", "verified": true}
info exit: 0
Traceback (most recent call last):
File "/Users/saphid/projects/steam-frame-moresrc/ui/apk_sources/_web.py", line 47, in read
with open_url(url, hosts, headers) as r:
File "/Users/saphid/projects/steam-frame-moresrc/ui/apk_sources/_web.py", line 37, in open_url
return urllib.request.build_opener(Redirect(hosts)).open(
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 523, in open
response = meth(req, response)
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 632, in http_response
response = self.parent.error(
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 561, in error
return self._call_chain(*args)
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 494, in _call_chain
result = func(*args)
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/urllib/request.py", line 641, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 429: Too Many Requests
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/saphid/projects/steam-frame-moresrc/.claude/prove-more-sources.py", line 18, in <module>
entries = itch.search(itch.sources()[0], 'off nominal')
File "/Users/saphid/projects/steam-frame-moresrc/ui/apk_sources/itch.py", line 58, in search
for entry in _parse(source, _web.read(url, ('itch.io',))):
File "/Users/saphid/projects/steam-frame-moresrc/ui/apk_sources/_web.py", line 62, in read
raise SourceError('Source refused access or reached its rate limit; try later (GitHub accepts FRAME_GITHUB_TOKEN)') from e
apk_sources.SourceError: Source refused access or reached its rate limit; try later (GitHub accepts FRAME_GITHUB_TOKEN)
-24
View File
@@ -1,24 +0,0 @@
import json, os, subprocess, sys
from pathlib import Path
sys.path.insert(0, str(Path.cwd() / 'ui'))
from apk_sources import github, itch, _web
proof = Path.cwd() / '.claude' / 'proof-cache'
proof.mkdir(exist_ok=True)
_web.cache = lambda: str(proof)
token = subprocess.run(['gh', 'auth', 'token'], capture_output=True, text=True, check=True).stdout.strip()
os.environ['FRAME_GITHUB_TOKEN'] = token
s = github.sources()[0]
entries = github.search(s, 'hello')
print('GitHub search:', json.dumps(entries))
r = github.download(s, entries[0]['id'])
print('GitHub download:', json.dumps(r))
p = subprocess.run(['python3', 'ui/frame_android.py', 'info', r['apk']])
print('info exit:', p.returncode)
assert p.returncode == 0
entries = itch.search(itch.sources()[0], 'off nominal')
print('itch.io search:', json.dumps(entries))
assert entries and entries[0]['downloadable'] is False
try:
itch.download(itch.sources()[0], entries[0]['id'])
except Exception as e:
print('itch.io download correctly refused:', e)
-5
View File
@@ -1,5 +0,0 @@
................................................................................................................................................................................
----------------------------------------------------------------------
Ran 176 tests in 5.879s
OK
-50
View File
@@ -1,50 +0,0 @@
{
"add": {
"id": "fdroid-user-57e98c13877f14fdea65",
"kind": "fdroid",
"name": "IzzyOnDroid verification",
"url": "https://apt.izzysoft.de/fdroid/repo/",
"builtin": false,
"enabled": true,
"trust": "user",
"fingerprint": "3bf0d6abfeae2f401707b6d966be743bf0eee49c2561b9ba39073711f628937a",
"trust_on_first_use": false
},
"search": [
{
"source": "fdroid-user-57e98c13877f14fdea65",
"id": "com.martinmimigames.tinymusicplayer",
"package": "com.martinmimigames.tinymusicplayer",
"name": "Tiny Music Player",
"summary": "Android 1.0+ minimal (",
"icon": "https://apt.izzysoft.de/fdroid/repo/com.martinmimigames.tinymusicplayer/en-US/icon.png",
"page": "https://martinmimigames.github.io/projects/tiny-music-player/index.html",
"vr": null,
"free": true,
"license": "GPL-3.0-only",
"downloadable": true,
"version": "1.3",
"version_code": 4,
"min_sdk": 1,
"abis": [],
"size": 16520,
"updated": "2023-02-04"
}
],
"download": {
"apk": "/Users/saphid/Library/Caches/Frame Control/apk-sources/d7bcb24d101b04beb3394b695b24be4e2c3d6ed702f1d0e06bc4dd707f64d86a.apk",
"obb": [],
"sha256": "d7bcb24d101b04beb3394b695b24be4e2c3d6ed702f1d0e06bc4dd707f64d86a",
"verified": true
},
"independent_readback": {
"size": 16520,
"sha256": "d7bcb24d101b04beb3394b695b24be4e2c3d6ed702f1d0e06bc4dd707f64d86a"
},
"python": "3.9.6",
"suite": "python3 -m unittest discover -s tests: 180 tests, 6.866s, OK, exit 0",
"builtins_entry_signatures": {
"fdroid": "43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab",
"fdroid-archive": "43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab"
}
}