Skip to content

Release 2.11.4: Cloud Play for fallback regions — full PS3+PS4 catalog restore, Bloodborne launch chain fixed - #50

Merged
forward-technologies merged 17 commits into
masterfrom
release/beta
Aug 14, 2026
Merged

Release 2.11.4: Cloud Play for fallback regions — full PS3+PS4 catalog restore, Bloodborne launch chain fixed#50
forward-technologies merged 17 commits into
masterfrom
release/beta

Conversation

@forward-technologies

Copy link
Copy Markdown
Collaborator

Promotes release/beta to production. This train carries three bodies of work: the *GS streaming-pick fix (#40), @nyakaspeter's regional cloud-play fixes (#43 — thank you!), and our integration/extension work on top. Written in full detail so any reviewer (human or agent) can trace every change and its evidence.

The problem: Bloodborne (and fallback regions generally) could not stream

For accounts in regions without native PlayStation cloud support (HU and others), cloud play was broken at three independent points — fixing any one was not enough, which is why #40 alone (deployed to beta July 12) didn't resolve the tester's report:

  1. Entitlement pick (fixed by Fix cloud launch of Bloodborne (EU): pick *GS streaming skus that lack license_type=4 #40): Bloodborne's PS4GS streaming reservation carries license_type=0 (verified in every store probed: HU/GB/NL). The picker only accepted license_type==4, fell through to the *GD purchase entitlement, and Gaikai rejected it (002.2026 noGameForEntitlementId).
  2. The $0 acquire never ran (fixed by Cloud play fixes for HU region (and possibly other non-US regions) #43 — the missing piece): step 0.5e skipped the acquire for all foreign-catalog titles on 404. Even with the right reservation picked, the account never owned it → Gaikai rejected it as unauthorized. Now only legacy PS3 Classics skip the acquire; modern CUSA/PPSA titles acquire in the account's own store.
  3. Store routing + catalog (fixed by Cloud play fixes for HU region (and possibly other non-US regions) #43, extended here): fallback accounts were forced through the GB storefront, where modern EU products 404 (live-verified: God of War 2018 EU is 200 in HU/en, 404 in GB/en). And the fallback catalog itself returned zero games because Sony restructured APOLLOROOT into category links, which the old pagination filtered out entirely.

Scope extension: not just PS3 — the full fallback catalog

#43 restored the catalog by fetching the APOLLOPS3GAMES/APOLLOPS3 child containers. Live probing showed those are ~95% PS3: the PS4 streaming catalog lives in APOLLOROOT's other children (genre lists, A–Z lists, PSP/PS1/PS2, Remasters). We replaced the hardcoded child fetch with a one-level walk of every child of the regional root, discovered structurally via container_type (no hardcoded child ids, no name patterns — survives Sony reshuffling categories):

master today #43 (PS3 child) this release (full walk)
GB family (HU etc.) 0 titles 264 (250 PS3 / 14 PS4) 786 (536 PS4 + 250 legacy)
US family 0 titles 330 853 (537 PS4 + 316 legacy)

Verified live: the walk's id sets match an independently-written walk exactly (853/853, 786/786, zero duplicates), and every title from #43's PS3-child fix is included (0 missing, both families).

Preservation of #43 (fresh-eyes verified)

A dedicated adversarial review compared our integration against fix/cloud-play, primed to find any place we regressed the contributor's work. Verdict per fix: PS3 catalog preserved (strict superset), account-store routing preserved (byte-identical envelope code; our 404-retry is additive), acquire gating preserved (acquire still attempted exactly per #43), GS pick strengthened (see below), disc-upgrade rescue and duplicate-productId dedupe preserved (their tests run byte-identical and pass).

Hardening applied after three independent review passes

  • Native accounts are untouched: the legacy→US/GB Classics store remap only applies to foreign-catalog sessions. A native NL/JP account resolves every id in its own server-authoritative store, exactly as production does today (a native JP classic doesn't exist in the GB store; the NL store 404s on NL/en). Live A/B on a native account: catalog output byte-identical, 5,039 products, 0 field diffs.
  • Streaming pick stays strict: license_type==4 primary, with a title-matched *GS fallback pass for lt=0 reservations. Swept all 786 live containers in the fallback catalog: identical entitlement chosen vs Cloud play fixes for HU region (and possibly other non-US regions) #43's widened picker on every single title (Bloodborne = the only GS-dependent title; its real container rows are pinned in a unit test). The strict version additionally can never acquire an untitled bundle-sibling's sku.
  • No region can do worse than production today: foreign modern titles retry the resolve via US/GB if the account store 404s; a failed foreign acquire falls through to Gaikai validation (the old behavior) instead of surfacing a possibly-wrong PS+ error (Gaikai independently re-emits the PS+ sentinel, so those dialogs still work).
  • Structural id handling per repo rules: legacy-vs-modern is decided by the title-id segment (CUSA/PPSA between the first - and _), never the region-varying label tail.
  • Walk safety: completeness gates caching (a truncated list — failed page, nested container, dropped child — is served but never cached); one global 200-page budget bounds request amplification; empty-id rows dropped; every incompleteness path logs its reason.
  • Cache schema bumped to v8 (invalidates v5–v7 partial-catalog caches from test builds).

Verification summary

  • 3 adversarial review passes (memory-safety/json-c refcounts; protocol-logic per region; fresh-eyes Cloud play fixes for HU region (and possibly other non-US regions) #43 preservation) — all findings fixed or verified inert; refcounts/buffers/portability traced clean.
  • Live API evidence throughout: container probes across 15+ country/language stores; full-catalog pick-parity sweep (786/786, 0 diffs); walk-vs-independent-walk id-set equality; native-account catalog A/B (byte-identical).
  • Unit suite 126/126, including real-data regression tests for the Bloodborne pick, regional routing, disc rescue, and dedupe.
  • Region testing needs no foreign account: build-arm64/lib/apollo-fallback-test <CC> runs the anonymous fallback walk as any country.
  • Sideloadable test APK built from this exact code: run 30735168430 — awaiting @nyakaspeter's HU retest (Bloodborne, a PS3 classic, a non-owned PS4 title from the newly restored catalog, an owned PS5 title).

Release notes / mechanics

🤖 Generated with Claude Code

forward-technologies and others added 11 commits July 12, 2026 03:11
Some store regions publish a title's game-streaming sku with license_type=0
instead of 4 (e.g. Bloodborne on the GB store: sku -EC02 carries
EP9000-CUSA00207_00-PSRSVD0000000000, packageType PS4GS). Step 0.5d's
streaming pass missed it, the *GD full-game fallback picked the purchase
entitlement instead, 0.5e saw the user's PS+ copy as "already owned" and
skipped the $0 acquire, and Gaikai rejected the GD entitlement with
002.2026 noGameForEntitlementId ("Cloud Session Failed", GitHub issue #6).

Add a packageType "*GS" pass between the license_type==4 pass and the *GD
fallback (title-matched first, same structural suffix match as the GD
picker). Verified against 997 live store containers (853 US catalog + 144
GB titles from the reporter's entitlements dump): exactly one title changes
resolution -- GB Bloodborne, the bug -- and every license_type==4 pick is
untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… wording

The *GS picker never inspects license_type, so drop that claim from its log
line; and actually assert the "unchanged" sentinel the no-match test sets up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…reaming-fallback

Fix cloud launch of Bloodborne (EU): pick *GS streaming skus that lack license_type=4
Five workflow_dispatch workflows, one per platform, each building that platform
(build-only — no store deploy, no Dropbox, no signing/deploy secrets) and
uploading the result as a workflow artifact. Versions come from CMakeLists.txt
via the extract-version action.

- build-artifact-linux.yml    Pylux-Linux-<ver>.AppImage + Pylux-Linux-<ver>.zip
- build-artifact-android.yml  Pylux-Android-<ver>.apk (debug-signed)
- build-artifact-macos.yml    Pylux-macOS-<ver>.zip (ad-hoc .app, arm64)
- build-artifact-ios.yml      Pylux-iOS-<ver>.ipa (UNSIGNED, sideload only)
- build-artifact-windows.yml  Pylux-Windows-<ver>.exe + Pylux-Windows-<ver>.zip

Reuses the deploy/build workflows' build + toolchain steps; drops the
signing/deploy tails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts:
#	lib/src/cloudsession_kamaji.c
#	test/cloudsession_kamaji.c
The public fallback paginated a single container expecting product rows, but
Sony restructured APOLLOROOT into one level of category containers, so
region-unsupported accounts got an empty PS Now catalog. Walking only the PS3
child (as PR #43 proposed) restores 264-330 classics but misses the ~535-title
PS4 streamable catalog that lives in the genre/alphabetical children.

Walk every child of the regional root once instead, deduped by product id, with
per-container completeness so a failed child still blocks caching a partial
list. Live-verified against an independent walk of both store families:
US 853 titles (537 PS4 + 316 legacy), GB/HU 786 (536 PS4 + 250 legacy),
identical id sets, zero duplicates; native-account fetch is byte-identical
before/after. Adds apollo-fallback-test, a region harness that runs the
anonymous walk as any account country.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
forward-technologies and others added 4 commits August 1, 2026 23:37
…mpleteness)

Protocol findings:
- Scope the legacy->US/GB Classics remap in km_resolve_store_locale to
  foreign-catalog (fallback-region) sessions. Native accounts resolve every id
  in their server-authoritative store exactly as before this branch — a native
  JP/NL classic must not be re-routed to a GB container that lacks it.
- Revert km_pick_streaming to the strict license_type==4 primary pass. The
  title-matched *GS fallback already catches reservations published with
  license_type=0 (Bloodborne EU); accepting untitled *GS rows in the primary
  pass risked acquiring a bundle sibling's sku.
- Foreign-catalog safety nets so no region can regress below the old behavior:
  0.5d retries the modern-title resolve once via the US/GB store when the
  account store 404s, and a failed /bin/zsh acquire falls through to Gaikai
  validation instead of surfacing a possibly-wrong PS+ error.
- km_is_legacy_classic_id now examines only the title-id segment between the
  first '-' and '_' (structural, per the data-handling rules) instead of
  substring-matching the whole id including the region-varying label tail.

Fallback-walk findings:
- A container row the walk cannot collect (nested deeper than one level, id
  missing/over-long, child table full) now marks the list incomplete with a
  log line, so a silently truncated catalog is never cached for the TTL.
- Empty-id product rows are dropped (they dodge the dedupe and the contract's
  uniqueness guarantee).
- One global 200-page budget bounds a misbehaving server to ~5x the observed
  live request count instead of children x per-container cap.
- stream_identifier's disc-rescue path reads product_id before storeProductId
  (the latter is normalized only after streamIdentifier is stamped).

Docs: schema example says 8, v6 changelog no longer overclaims storeProductId,
dedupe_contract_product_ids documents the plusCatalog stamp on input rows.

Live re-verified: HU walk 788 titles / US 853, complete, id sets matching an
independent walk; unit suite 126/126.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
They came along with PR #43's branch but are unrelated to the cloud fixes;
they can land separately if wanted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…egions

Cloud Play fixes for fallback regions: full catalog restore + Bloodborne launch (2.11.4)
forward-technologies and others added 2 commits August 1, 2026 23:41
These are real-account working files for the cloud-catalog probe scripts;
a broad git add briefly committed the cached-API baseline captures on
2026-08-02 (purged from history). Ignore them so that cannot recur.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…egions

gitignore local API captures and entitlement dumps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants