Commit Graph
4 Commits
Author SHA1 Message Date
phantomptrandClaude Opus 5.5 8d05f60a7e PS5 Payload SDK v0.44, and scripts/update-ps5-sdk.sh to bump it
Pin v0.44 (sha256 4d06eab7...). Its crt/ and prospero-nid are identical
to v0.43, so the vendored sdk-crt (+ ps5upload.patch) and the portable
prospero-nid stay as they are; the helper, installer and elfldr build to
the same code (only the build-id differs). v0.44 adds LLVM 23 to the
candidate list, so the Makefile comment and Homebrew fallbacks move too.

scripts/update-ps5-sdk.sh (make update-sdk): finds the latest release
(or --tag), checks the zip, rewrites the pin, re-vendors prospero-nid
and crt only when upstream changed them (stops if our crt patch no
longer applies), moves the "SDK vX.Y" doc mentions and installs with
install-ps5-sdk.sh, keeping the old SDK as a backup. --check only
reports. The installer names its backups after the release they hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
2026-10-10 11:14:44 -07:00
phantomptrandClaude Opus 5.5 0d254e5433 6.5.0: Collection, Move to, Android on Android 17, helper on FW 5.50, web UI pairing
New:
- Collection: every game in your folders (local or on a NAS, scanned in
  place), grouped with updates and DLC, what each PS5 has, one-click
  installs, install links, organize / de-duplicate / clean up. Replaces PS
  Game Library (with an importer).
- Send a game folder as one image (.ffpfsc / .ffpkg / .exfat); Convert
  writes .ffpkg and .ffpfs too.
- Files: Move to... (instant or cross-drive, with a fit check) and Set
  permissions (777).
- Offline PSN sign-in from Profile.

Fixed:
- Android 17: local network permission (6.x could not connect).
- FW 5.50: own build of the SDK startup code, so the helper, installer and
  elfldr start.
- Web UI: Send helper (pairs it); no "ready" while unpaired.
- Screenshots decode in a child process (Linux crash loop).
- Installs no longer start queued uploads.
- Cross-drive moves check the copy before removing the original.
- Finished installs show as done after a reload; engine-unreachable
  explained with Restart engine; Health starts the installer.
- Dev: make run-client renders on macOS 27.

Better: "declined" installs explain Sony's code and how far it got;
0x80B21104 explained; Connection failures readable; keep-awake for all
installs; Games cards. Translations, FAQ, README.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VM5Gzyt1uxKyJiWZAgd1w9
2026-10-08 09:31:54 -07:00
PhantomPtrandClaude Opus 5.5 9e5c258ad8 6.0.0: CI fixes, upgrade clean-up, docs and version (#377)
* docs: 6.0.0 changelog, README, FAQ and contributor docs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* Release prep: version 6.0.0

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(ci): keep the leaked test pools reachable for LSan; skip the tiny-file floor under coverage

- ava1-ctest diag/mgmt_fs: the &'static Pool each test leaks for
  AvaTransport::with_pool is now held in a static list, so LeakSanitizer sees
  it (and the sessions on its threads) as reachable instead of reporting
  ~140 KB of indirect leaks the frame-name suppression could never match.
  Verified under clang ASan+LSan in Linux Docker: diag 13/13, mgmt_fs 40/40.
- download.rs tiny-file throughput floor is skipped when cargo-llvm-cov runs
  (CARGO_LLVM_COV set): instrumentation slows every call several times over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): data_rust servers use the clients' fast timing

Five folder-host tests gave the client fast timing (dead after 500 ms) but
left the server on the default (ping every 2 s). On a slow runner a half-second
gap made the client drop healthy lanes and the job stalled until the 36 s
progress limit (both CI runs on #374/#377). The ordered-download tests already
set both ends; these now do too. The app uses one timing on both ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): the C lane socket-buffer test accepts Linux's wmem_max cap

Same cap as the Rust lane test: Linux CI gives the send side 416 KiB, so the
1 MiB floor failed under ASan in CI. 128 KiB is still far above a default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(ci): gcc unused-result in the FTP selftest, serial ctest in make test, sender state on failure

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(ava1): flush a partial bundle after any reader message, not only a record

The last small-file record could arrive while a large file's chunk or root
was still queued behind it: the flush saw a non-empty channel, the next
message was not a record, and the records sat unsent until the receiver
cut the job as stalled (CI-only flake; 7/36 under local parallel load, 0/48 after).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(validate): run the C interop tests serially in make ci too

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(ava1): a resumed file goes in one-group pieces so a flapping link still makes progress

With kills every 2 s, the 4 MiB tail piece was cut before it was durable on every
attempt and the upload retried the same 28 MiB mark until it timed out (1 in 3
locally, CI coverage). Resumed files now send 1 MiB pieces: 5/5 in ~6 s.

Also: make docker-engine uses the repo root as context (as CI); governor
classification asserts are skipped under the sanitizers, where the C is the bottleneck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): single-instance gate tests hold the C-server lock; relay test cap leaves margin

Coverage runs the C tests in parallel; the two gate tests stop the one global C server.
The relay order test's 4 MiB/s cap finished in 5.9 s on CI against its >6 s precondition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): periodic-kill bound widened under coverage; tiny-file floor relaxed on CI runners

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): lane-kill test kills until a resend; periodic-kill liveness race skipped under coverage

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): a hung relay fails its test at the bound instead of hanging the CI job

The dest-ends relay test ran the relay under spawn_blocking: on a hang the timeout
panicked but the runtime then waited forever for the blocking thread (27 min on CI).
It now runs on a plain thread. The engine test steps get a 25-minute bound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): dest-ends relay test in its own binary on small files; relay logs its silent retries

The test hung a CI job twice inside the shared relay binary (behind the 384 MiB relays'
lock) and never reproduced locally or in Linux Docker. It now runs alone, on 4x32 MiB
(still twice the relay buffer), ~3 s. The relay's open-dropped and retry paths now say
so on stderr instead of looping silently. Governor classification asserts also skip
under coverage, where the instrumented sender is the bottleneck.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): the partly-durable relay test caps its first attempt so it can be interrupted

On a fast runner the uncapped relay finished all 160 MiB before the first durable
report was observed. The first attempt now reads A through a 32 MiB/s proxy (~5 s);
the resume runs uncapped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* feat: one-time 6.0 upgrade clean-up that keeps every setting

Host (engine, once per data dir): pre-5.x files no 5.41/6.0 code reads (api_token,
ps5upload.ini, ps5upload_profiles.ini/.json, app-config.json) move to ~/.ps5upload/legacy-5x/.
App (desktop, once): the 1.x/2.x config.json/profiles.json move to legacy-5x/; the cached
ezremote-dpi.elf nothing loads is deleted. Client: the retired upload-streams key is dropped.
Console (once per console, on its first 6.0 helper answer): the FTX2 /data/ps5upload/tx and
/spool folders are deleted; a failure retries later. The health check no longer lists those
folders (its fix would have recreated them). Nothing current is moved or reset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): the download periodic-kill race is skipped under coverage, like its upload twin

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): the tiny-zip floor only catches a stall on CI runners

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(test): 'other calls still answer during launches' is a state check, not a wall-clock bound

Both mgmt_t6 tests asserted a sub-300 ms answer while a slow Sony call ran; on a loaded
runner that separates nothing. They now assert the answer arrived while the slow call
was still in flight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

* fix(ci): reword the 6.0 migration comments for check-no-ftx2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XR8fQMhp7Rdgq2e4U9oDff

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 07:04:11 -07:00
PhantomPtrandClaude Opus 5.5 6f5abad2b5 elfldr that recovers by itself; 75-minute publish builds; 5.37.1 notes (#338)
* feat(elfldr): vendor elfldr with a read deadline, embedded in the engine

elfldr serves one connection at a time and its reads had no deadline,
so a client that went silent without closing (a dropped link, a machine
or console asleep mid-send) left it running but deaf on :9021 — users
had to load elfldr again. Measured on the Phat (FW 5.10): the stock
build answered nothing while a silent connection stayed open; with a
15 s SO_RCVTIMEO it dropped that connection and answered the next
request at once, and a payload sent with 10 s pauses still loaded.

third_party/elfldr is upstream 02cfe91 plus ps5upload.patch (GPLv3,
credited), with the tested ELF checked in so every engine build embeds
it; `make elfldr` rebuilds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(elfldr): the engine swaps a console's stock elfldr for the patched one

GET /api/ps5/elfldr/health tells healthy / stuck / absent from a request
elfldr answers without running anything. POST /api/ps5/elfldr/ensure
replaces the standard elfldr.elf with the embedded patched build when it
answers and isn't the one this engine installed (a reboot or autoloader
brings the stock one back), leaves any other loader on :9021 alone, and
returns once the new one answers. On the Phat: upgraded (pid 685,
answering at once), then 'current'; the helper was untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(publish): give each client build 75 minutes

The Intel macOS build ran past the 45-minute limit for v5.37.0 (about
33 minutes for v5.35.0 and v5.36.0), which cancelled it and skipped
create-release, so v5.37.0 was never published.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(engine): history tests get their own temp dirs

TmpDir named directories by pid and nanoseconds, but macOS time ticks in
microseconds: two tests starting together shared a directory and one
deleted it under the other (a_legacy_host_port_file_is_still_read read
nothing). A counter makes each name unique. The elfldr embed test reads
the embedded bytes directly instead of clearing an env var mid-run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(elfldr): the app keeps the patched elfldr in place and never sends into a stuck one

Before sending the helper, the app checks the console's loader: a stuck
one (took the connection, never answered) is waited out for 20 s — the
patched build clears in 15 — and one that stays stuck is reported
plainly ('load elfldr again') instead of a socket error. Once the helper
is up, the engine swaps the stock elfldr for the patched build: at once
after a fresh helper send (a reboot or wake brings the stock one back),
else at most every 10 minutes per console. Desktop, browser and Android
share the engine routes; strings in all 20 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(changelog): 5.37.1 — elfldr recovers by itself; 5.37.0 folded in

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(elfldr): swap it in when the helper is already up at launch

Only ensurePayloadCurrent asked for the patched elfldr, and a helper
that is already up when the app opens never goes through it — on the
Phat the stock elfldr stayed. The status poll's 'arrives at up' edge
(first sighting included) now asks too, after the same settle as the
log capture and never during a transfer.

Hardware (Phat FW 5.10, web build and Android app): stock elfldr
replaced ~10 s after opening; a silent :9021 connection held while the
helper was shut down — the helper came back through the patched
elfldr; with the stock elfldr wedged, the Android app sent nothing for
150 s (health: stuck), then redeployed and swapped elfldr once released.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(convert): the compress stage pays for reading and writing on one thread

kraken_image::compress runs the encoder on a pool, but one thread reads
the source and writes each compressed block, so the stage takes the
longer of encoding and read+write — not the slower of reading and
encoding, as the estimate assumed. With the Windows Battlefield 6 run's
speeds the model now gives 75 min for a 71-min build.

The estimate also reports the speeds it measured (rates), because the
small read/write samples can be fooled by caches: on a source read an
hour earlier the read sample hit the file cache at 8.6 GB/s and the
estimate came out at 25 min for a 54-min build. Calibrating from past
builds is the follow-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(changelog): build-time estimate, stated as measured

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(docker): 25 minutes for the PR image checks

Both PR gates build the whole image (engine, and the client for the web
UI one) in about 7-10 minutes; the engine gate took 9m55s and the web UI
gate was cancelled at its 10-minute limit on PR #338.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:55:05 -07:00