Repository navigation
feat: add authoritative Microsoft Store PWA IAP - #134
Conversation
|
Warning Review limit reached
Next review available in: 38 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (36)
📝 WalkthroughWalkthroughMicrosoft Store support now includes a dedicated Digital Goods and Payment Request adapter, authoritative Collections verification and consumption, target configuration, CLI submission checks, starter migration, worker bindings, and purchase recovery. ChangesMicrosoft Store IAP
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (5)
README.md (1)
257-264: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the Store-installed runtime requirement.
The Microsoft billing method is available only in a PWA installed from the Microsoft Store on Windows. A normal browser can make
getDigitalGoodsService()unavailable. Add this constraint to the README or make it explicit at the linked commerce guide. (learn.microsoft.com)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 257 - 264, Update the Microsoft Store support documentation around the build and commerce adapter description to state that Microsoft billing requires the PWA to be installed from the Microsoft Store on Windows. Clarify that normal browser execution may not provide getDigitalGoodsService(), and place the constraint in README.md or the linked Microsoft Store commerce guide.tools/smoke/effective-target-config.ts (1)
374-386: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winGuard against a vacuous consumable assertion.
filter(...).every(...)returnstruewhen the filtered list is empty. If the Microsoft Store target later maps no consumable products, this check still passes. Assert that at least one consumable exists.♻️ Proposed guard
if (target === 'microsoft-store') { + const consumables = config.monetization.products.filter( + (product) => product.type === 'consumable', + ); assertEqual( - config.monetization.products.filter((product) => product.type === 'consumable') - .every((product) => product.enabled), + consumables.length > 0 && consumables.every((product) => product.enabled), true, 'microsoft-store consumables should be enabled', );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/smoke/effective-target-config.ts` around lines 374 - 386, Update the microsoft-store validation block to assert that the filtered consumable products collection is non-empty before checking that every consumable is enabled. Preserve the existing all-enabled assertion and its message, using the collection derived from config.monetization.products.packages/game-services/src/microsoft-store-purchase.test.ts (1)
186-234: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the pending verification paths.
The suite covers
MICROSOFT_STORE_PRODUCT_KIND_MISMATCH, the sandbox block, and consume recovery. Three reachable outcomes stay uncovered:
MICROSOFT_STORE_PRODUCT_MAPPING_REQUIRED, whenstoreIdshas no entry for the catalog product.MICROSOFT_STORE_PURCHASE_NOT_PROPAGATED, when the query returnsitems: [].MICROSOFT_STORE_COLLECTIONS_UNAVAILABLE, whenqueryProductrejects.The third case matters most. It asserts that a transport failure produces
pendingand records no ledger entry.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/game-services/src/microsoft-store-purchase.test.ts` around lines 186 - 234, Extend the Microsoft Store purchase verification tests with cases for missing product mapping, an empty query result, and a rejected queryProduct call. Assert the corresponding reasons MICROSOFT_STORE_PRODUCT_MAPPING_REQUIRED, MICROSOFT_STORE_PURCHASE_NOT_PROPAGATED, and MICROSOFT_STORE_COLLECTIONS_UNAVAILABLE; for the transport failure, also assert pending finalization and no ledger event.tools/smoke/cli-microsoft-store-submission.ts (1)
204-232: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for an empty
commerce.productsarray.The parser rejects an empty product list at
packages/cli/src/microsoft-store-submission.tslines 369-371. No smoke case exercises that branch. Add oneexpectConfigErrorcase withproducts: []and the expected messageat least one product.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/smoke/cli-microsoft-store-submission.ts` around lines 204 - 232, Add an expectConfigError smoke case near the existing commerceConfig coverage, configuring Microsoft Store commerce with products: [] and asserting the expected validation message contains “at least one product”.adapters/microsoft-store/src/index.ts (1)
226-253: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the unreachable
failcompletion branch.Line 226 sets
paymentCompletionAttempted = trueimmediately afterresponseis assigned, with noawaitbetween the two statements. Thereforeresponse !== undefined && !paymentCompletionAttemptedat Line 247 can never be true. The branch is dead code and hides the real invariant: the response is always completed with'success'at Line 227.If you intend to keep a fail path for a future reordering, set the flag only after
completePaymentresolves.♻️ Proposed simplification
paymentCompletionAttempted = true; await completePayment(response, 'success');input.onError?.(error); - if (response !== undefined && !paymentCompletionAttempted) { - await completePayment(response, 'fail'); - } if (purchaseToken !== undefined) {Then drop the now-unused
paymentCompletionAttempteddeclaration at Line 211.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@adapters/microsoft-store/src/index.ts` around lines 226 - 253, Remove the unreachable failure-completion branch from the catch block and delete the now-unused paymentCompletionAttempted declaration. Keep completePayment(response, 'success') as the sole completion path, preserving the existing error and pending-purchase returns.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@adapters/microsoft-store/src/index.ts`:
- Around line 370-379: Update the price validation near currencyCode and
numericValue so empty or whitespace-only price.value strings are rejected before
Number coercion; validate the raw value first, then convert and retain the
existing finite and non-negative checks for valid numeric prices.
In `@docs/MICROSOFT_STORE_COMMERCE.md`:
- Around line 47-50: Update the sandbox sentence in the documentation to replace
“needs delegated XSTS authentication” with “requires delegated XSTS
authentication,” leaving the surrounding behavior and error description
unchanged.
In `@packages/cli/templates/phaser-game/mpgd.targets.json`:
- Around line 13-14: Update the microsoft-store target configuration in
mpgd.targets.json by setting authoritativeGameServices to false, while leaving
the adapter and other target settings unchanged.
In `@packages/cli/templates/phaser-game/package.json`:
- Line 63: Publish `@mpgd/adapter-microsoft-store` version 0.1.0 before relying on
the dependency declaration in the Phaser game template, ensuring the CLI’s
replacement of __MPGD_DEPENDENCY_VERSION_ADAPTER_MICROSOFT_STORE__ with ^0.1.0
resolves successfully during installation.
In `@packages/game-services/src/microsoft-store-purchase.ts`:
- Around line 204-221: Ensure credential validation failures are not converted
into transient pending results. In the verification flow around
assertCredentials, move validation outside the catch that handles queryProduct
transport errors, or explicitly propagate TypeError; apply the same correction
in consumeMicrosoftStorePurchase so malformed accessToken, userStoreId, or
sandbox values produce a permanent configuration error rather than
MICROSOFT_STORE_COLLECTIONS_UNAVAILABLE.
---
Nitpick comments:
In `@adapters/microsoft-store/src/index.ts`:
- Around line 226-253: Remove the unreachable failure-completion branch from the
catch block and delete the now-unused paymentCompletionAttempted declaration.
Keep completePayment(response, 'success') as the sole completion path,
preserving the existing error and pending-purchase returns.
In `@packages/game-services/src/microsoft-store-purchase.test.ts`:
- Around line 186-234: Extend the Microsoft Store purchase verification tests
with cases for missing product mapping, an empty query result, and a rejected
queryProduct call. Assert the corresponding reasons
MICROSOFT_STORE_PRODUCT_MAPPING_REQUIRED,
MICROSOFT_STORE_PURCHASE_NOT_PROPAGATED, and
MICROSOFT_STORE_COLLECTIONS_UNAVAILABLE; for the transport failure, also assert
pending finalization and no ledger event.
In `@README.md`:
- Around line 257-264: Update the Microsoft Store support documentation around
the build and commerce adapter description to state that Microsoft billing
requires the PWA to be installed from the Microsoft Store on Windows. Clarify
that normal browser execution may not provide getDigitalGoodsService(), and
place the constraint in README.md or the linked Microsoft Store commerce guide.
In `@tools/smoke/cli-microsoft-store-submission.ts`:
- Around line 204-232: Add an expectConfigError smoke case near the existing
commerceConfig coverage, configuring Microsoft Store commerce with products: []
and asserting the expected validation message contains “at least one product”.
In `@tools/smoke/effective-target-config.ts`:
- Around line 374-386: Update the microsoft-store validation block to assert
that the filtered consumable products collection is non-empty before checking
that every consumable is enabled. Preserve the existing all-enabled assertion
and its message, using the collection derived from config.monetization.products.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 53e1b9ce-e65b-40a8-bea6-61c62a2d483b
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (45)
.sampo/changesets/microsoft-store-iap.mdREADME.mdadapters/microsoft-store/CHANGELOG.mdadapters/microsoft-store/package.jsonadapters/microsoft-store/src/index.test.tsadapters/microsoft-store/src/index.tsadapters/microsoft-store/tsconfig.jsonapps/game-services-worker/src/handler.tsapps/game-services-worker/src/index.test.tsdocs/MICROSOFT_STORE_COMMERCE.mddocs/PUBLIC_RELEASE_CHECKLIST.mdexamples/phaser-starter/mpgd.targets.jsonexamples/phaser-starter/package.jsonexamples/phaser-starter/src/platform/buildGateways/microsoftStore.tsexamples/phaser-starter/vite.shared.tspackages/catalog/catalog.jsonpackages/cli/package.jsonpackages/cli/src/index.tspackages/cli/src/microsoft-store-starter.tspackages/cli/src/microsoft-store-submission.tspackages/cli/src/production-target-readiness.tspackages/cli/templates/phaser-game/README.mdpackages/cli/templates/phaser-game/mpgd.targets.jsonpackages/cli/templates/phaser-game/package.jsonpackages/cli/templates/phaser-game/src/platform/buildGateways/microsoftStore.tspackages/cli/templates/phaser-game/vite.shared.tspackages/game-services/package.jsonpackages/game-services/src/client.test.tspackages/game-services/src/client.tspackages/game-services/src/index.tspackages/game-services/src/microsoft-store-purchase.test.tspackages/game-services/src/microsoft-store-purchase.tspackages/game-services/src/server.tspackages/game-services/src/types.tspackages/platform/src/index.tspackages/target-config/src/effective.tspackages/target-config/targets.jsontools/smoke/adapter-effective-config.tstools/smoke/cli-microsoft-store-starter-onboarding.tstools/smoke/cli-microsoft-store-submission.tstools/smoke/effective-target-config.tstools/smoke/game-owned-catalog.tstools/smoke/platform-capability-conformance.tstools/smoke/target-config-runtime.tstools/target/effective-config.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8ba2bb59c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@coderabbitai review |
|
|
@codex review Please review exact head |
|
Fixed the clean-CI |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d49723ebe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Please re-review exact head |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b3ab0175db
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@coderabbitai review |
|
@codex review Please re-review exact head |
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4cd2c59d27
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Please review the exact current head |
There was a problem hiding this comment.
💡 Codex Review
For a configured target such as microsoft-store-staging with kind: 'web' and adapter: 'microsoft-store', appTargetForPlatformTarget() sets APP_TARGET to microsoft-store while MPGD_CONFIG_TARGET remains the custom target name. This exact-name check therefore skips service-worker registration even though Vite selected the Store gateway; tools/target/build-target.ts:213-223 likewise omits the Store PWA artifacts for that target. Classify Store PWA behavior from the adapter/runtime, or reject custom target names using this adapter, rather than producing a Store gateway artifact without its offline/update boundary.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
adapters/browser/src/microsoft-store.test.ts (1)
274-285: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReuse
memoryRecoveryStoragefor the inline storage fixtures.These three tests re-implement the same
getItem/setItem/removeItemmap adapter.memoryRecoveryStoragealready returns both the backingvaluesmap and the storage object, so the assertions onstoredRecoveryIds/storedRecoveriesstill work throughrecovery.values.♻️ Proposed change for lines 274-285
- const storedRecoveryIds = new Map<string, string>(); - const recoveryIdStorage = { - getItem(key: string) { - return storedRecoveryIds.get(key) ?? null; - }, - setItem(key: string, value: string) { - storedRecoveryIds.set(key, value); - }, - removeItem(key: string) { - storedRecoveryIds.delete(key); - }, - }; + const { values: storedRecoveryIds, storage: recoveryIdStorage } = memoryRecoveryStorage();Also applies to: 410-421, 1058-1068
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@adapters/browser/src/microsoft-store.test.ts` around lines 274 - 285, Replace the duplicated inline recovery storage adapters in the affected tests with the existing memoryRecoveryStorage helper, destructuring its storage object and values map as needed. Update assertions and references from storedRecoveryIds/storedRecoveries to the corresponding recovery.values map while preserving each test’s behavior.packages/game-services/src/microsoft-store-purchase.ts (1)
531-540: 🗄️ Data Integrity & Integration | 🔵 TrivialPlan an expiry for ownership records that survive a failed release.
The rationale in the comment is correct: a stale same-player claim lets that player repurchase, and it stays closed for every other player. Consider the follow-on state. The record key is
[accountBindingHash, storeId]and the value is the owningplayerId. After a failed release, a second game player who links the same Store account cannot claim that product, becauseclaimcompares the stored owner against the newplayerId.Add a TTL or a reconciliation job to the durable
MicrosoftStoreRecoveryOwnershipStoreimplementation, and record a metric for release failures. Document that requirement next to the durability requirement indocs/MICROSOFT_STORE_COMMERCE.mdLines 86-88.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/game-services/src/microsoft-store-purchase.ts` around lines 531 - 540, Extend the durable MicrosoftStoreRecoveryOwnershipStore implementation with expiry or reconciliation for ownership records left behind after release failures, and emit a metric whenever release fails in the finalization flow around recoveryOwnershipStore.release. Document both the cleanup requirement and release-failure metric beside the existing durability requirement in the Microsoft Store commerce documentation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/game-services/src/microsoft-store-purchase.ts`:
- Around line 309-331: The recovery ownership flow conflates denial with service
unavailability. In
packages/game-services/src/microsoft-store-purchase.ts:309-331, widen
claimRecoveryOwnership and hasRecoveryOwnership to return granted, denied, or
unavailable, and have resolveRecoveryOwnership return unavailable when
resolveCredentials, assertCredentials, or createAccountBindingHash fails. In
adapters/browser/src/microsoft-store.ts:241-264, have authorizeRecovery return
that state instead of throwing; update fulfill so recovery records are released
on denied and retained only on unavailable.
In `@packages/target-config/targets.json`:
- Around line 50-53: Update the reddit target configuration’s
features.leaderboard setting to true so it matches reddit’s supported Game
Services leaderboard status; alternatively, remove reddit from the supported
leaderboard target set, but keep the configuration and supported-target
declarations consistent.
---
Nitpick comments:
In `@adapters/browser/src/microsoft-store.test.ts`:
- Around line 274-285: Replace the duplicated inline recovery storage adapters
in the affected tests with the existing memoryRecoveryStorage helper,
destructuring its storage object and values map as needed. Update assertions and
references from storedRecoveryIds/storedRecoveries to the corresponding
recovery.values map while preserving each test’s behavior.
In `@packages/game-services/src/microsoft-store-purchase.ts`:
- Around line 531-540: Extend the durable MicrosoftStoreRecoveryOwnershipStore
implementation with expiry or reconciliation for ownership records left behind
after release failures, and emit a metric whenever release fails in the
finalization flow around recoveryOwnershipStore.release. Document both the
cleanup requirement and release-failure metric beside the existing durability
requirement in the Microsoft Store commerce documentation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bccca8dc-57fb-4512-845b-906d8b628d44
📒 Files selected for processing (18)
.sampo/changesets/microsoft-store-iap.mdadapters/browser/src/microsoft-store.test.tsadapters/browser/src/microsoft-store.tsdocs/MICROSOFT_STORE_COMMERCE.mdexamples/phaser-starter/src/platform/buildGateways/microsoftStore.tspackages/catalog/catalog.jsonpackages/cli/templates/phaser-game/src/platform/buildGateways/microsoftStore.tspackages/game-services/src/client.test.tspackages/game-services/src/client.tspackages/game-services/src/microsoft-store-purchase.test.tspackages/game-services/src/microsoft-store-purchase.tspackages/game-services/src/server.tspackages/game-services/src/types.tspackages/target-config/targets.jsontools/smoke/adapter-effective-config.tstools/smoke/platform-capability-conformance.tstools/smoke/target-config-runtime.tstools/validate-target-config.ts
💤 Files with no reviewable changes (1)
- packages/game-services/src/server.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- packages/game-services/src/client.ts
- packages/catalog/catalog.json
- packages/cli/templates/phaser-game/src/platform/buildGateways/microsoftStore.ts
- tools/smoke/adapter-effective-config.ts
- tools/smoke/target-config-runtime.ts
- tools/smoke/platform-capability-conformance.ts
- .sampo/changesets/microsoft-store-iap.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4ee8d73fae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review exact head @coderabbitai review exact head Exact-head verification: |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='789e0bc51a33d0f9e540ebc782d4a698cf56566f'
previous='4ee8d73fae1faddbd3e27d1381e2d62b4d4d3fef'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\nPREVIOUS=%s\n' "$actual" "$expected" "$previous"
test "$actual" = "$expected"
printf '\n=== Complete PR path list and whitespace validation ===\n'
git diff --name-status main...HEAD
git diff --check main...HEAD
printf '\n=== Incremental path list and patch ===\n'
git diff --name-status "$previous...HEAD"
git diff --unified=90 "$previous...HEAD" -- \
adapters/browser/src/microsoft-store.ts \
adapters/browser/src/microsoft-store.test.ts \
adapters/browser/src/index.ts \
packages/platform/src/index.ts \
packages/target-config/src/runtime.ts \
packages/target-config/src/effective.ts \
packages/target-config/targets.json \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
tools/smoke/target-config-runtime.ts \
tools/smoke/platform-capability-conformance.ts
printf '\n=== Focused outlines ===\n'
ast-grep outline adapters/browser/src/microsoft-store.ts --items all
ast-grep outline adapters/browser/src/index.ts --items all
ast-grep outline packages/target-config/src/runtime.ts --items all --match 'capability|Capability|leaderboard|Leaderboard|availability|Availability'
ast-grep outline packages/game-services/src/microsoft-store-purchase.ts --items all --match 'recovery|Recovery|owner|Owner|claim|Claim|mapping|Mapping|final'
ast-grep outline packages/game-services/src/server.ts --items all --match 'purchase|Purchase|recovery|Recovery|owner|Owner|claim|Claim|ledger|Ledger'
printf '\n=== Requested-boundary references ===\n'
rg -n -C6 \
'remoteLeaderboard|nativeLeaderboard|leaderboard|capabilit|availability|microsoft-store|DigitalGoods|digitalGoods|recoveryOwnership|claimRecoveryOwnership|hasRecoveryOwnership|releaseRecoveryOwnership|historicalProductMappings|historical.*token|inAppOfferToken|storeId|bridge|snapshot' \
adapters/browser/src \
packages/platform/src \
packages/target-config/src \
packages/game-services/src \
tools/smoke \
-g '*.ts' -g '*.json' \
-g '!**/dist/**' -g '!**/node_modules/**'Length of output: 202802 🏁 Script executed: #!/bin/bash
set -euo pipefail
previous='4ee8d73fae1faddbd3e27d1381e2d62b4d4d3fef'
printf '%s\n' '=== Latest incremental patch paths ==='
git diff --name-status "$previous...HEAD"
git diff --unified=55 "$previous...HEAD" -- \
packages/platform/src/index.ts \
adapters/browser/src/index.ts \
adapters/browser/src/microsoft-store.ts \
packages/target-config/src/runtime.ts \
packages/target-config/src/effective.ts \
packages/target-config/targets.json \
tools/smoke/target-config-runtime.ts \
tools/smoke/platform-capability-conformance.ts
printf '%s\n' '=== Platform capability contract ==='
rg -n -C5 \
'interface PlatformCapabilities|remoteLeaderboard|nativeLeaderboard|createBrowserPlatformGateway|capabilities:' \
packages/platform/src/index.ts \
adapters/browser/src/index.ts \
adapters/browser/src/microsoft-store.ts
printf '%s\n' '=== Dynamic target availability calculation ==='
rg -n -C10 \
'remoteLeaderboard|nativeLeaderboard|features\.leaderboard|capabilitySupported|withTargetAvailability|leaderboard:' \
packages/target-config/src/runtime.ts \
packages/target-config/src/effective.ts \
packages/target-config/targets.json
printf '%s\n' '=== Real Microsoft Store gateway construction sites ==='
rg -n -C8 \
'createMicrosoftStoreCommerceAdapter|withMicrosoftStoreCommerceAdapter|remoteLeaderboard|nativeLeaderboard|createBuildGateway' \
examples/phaser-starter/src \
packages/cli/templates/phaser-game/src \
tools/smoke/adapter-effective-config.ts \
tools/smoke/platform-capability-conformance.ts \
tools/smoke/target-config-runtime.ts \
-g '*.ts'
printf '%s\n' '=== Capability and configured-target regression tests ==='
rg -n -C10 \
"reason.*available|capability-unsupported|remoteLeaderboard|nativeLeaderboard|microsoft-store|submitScore" \
tools/smoke/target-config-runtime.ts \
tools/smoke/platform-capability-conformance.ts \
packages/target-config/src \
-g '*.ts'
printf '%s\n' '=== TypeScript/native bridge and snapshot references ==='
rg -n -C6 \
'bridge|Bridge|native.*snapshot|snapshot.*native|capability.*snapshot|PlatformCapabilities' \
adapters \
packages \
tools \
-g '*.ts' \
-g '!**/dist/**' -g '!**/node_modules/**'Length of output: 180849 🏁 Script executed: #!/bin/bash
set -euo pipefail
previous='4ee8d73fae1faddbd3e27d1381e2d62b4d4d3fef'
printf '%s\n' '=== Exact latest patch ==='
git diff --unified=45 "$previous...HEAD" -- \
packages/platform/src/index.ts \
packages/platform/src/capability-conformance.ts \
adapters/browser/src/index.ts \
adapters/browser/src/microsoft-store.ts \
packages/target-config/src/runtime.ts \
packages/target-config/src/effective.ts \
packages/target-config/targets.json \
tools/smoke/target-config-runtime.ts \
tools/smoke/platform-capability-conformance.ts
printf '%s\n' '=== Capability declarations and browser gateway ==='
sed -n '140,175p' packages/platform/src/index.ts
sed -n '313,338p' packages/platform/src/index.ts
rg -n 'function createBrowserPlatformGateway|export function createBrowserPlatformGateway' adapters/browser/src/index.ts
sed -n '1,180p' adapters/browser/src/index.ts
printf '%s\n' '=== Microsoft Store adapter capability wrapper ==='
rg -n 'getCapabilities|remoteLeaderboard|nativeLeaderboard|withMicrosoftStoreCommerceAdapter' \
adapters/browser/src/microsoft-store.ts
sed -n '540,660p' adapters/browser/src/microsoft-store.ts
printf '%s\n' '=== Target availability and Microsoft Store target policy ==='
sed -n '640,720p' packages/target-config/src/runtime.ts
jq '.targets["microsoft-store"]' packages/target-config/targets.json
sed -n '205,285p' tools/smoke/target-config-runtime.ts
sed -n '450,535p' tools/smoke/target-config-runtime.ts
printf '%s\n' '=== Microsoft Store capability conformance fixture ==='
rg -n -C5 'microsoft-store|remoteLeaderboard|nativeLeaderboard' \
tools/smoke/platform-capability-conformance.ts
sed -n '1,180p' packages/platform/src/capability-conformance.ts
printf '%s\n' '=== Ownership store atomic key behavior ==='
sed -n '127,180p' packages/game-services/src/microsoft-store-purchase.ts
sed -n '269,345p' packages/game-services/src/microsoft-store-purchase.ts
sed -n '690,715p' packages/game-services/src/microsoft-store-purchase.tsLength of output: 69411
I found one actionable issue.
If Store commerce is disabled or configuration-required, Set Add a regression that uses the real Microsoft Store gateway with commerce unavailable and remote leaderboard support enabled. Assert all of these results:
The current configured-target smoke does not detect this defect. It uses a synthetic gateway that sets The trusted token mapping and ownership paths are fail-closed in the reviewed code. The ownership key binds the server-derived account-binding hash and resolved Collections Store ID. The ownership store contract requires atomic claims. The capability conformance code also includes
You are interacting with an AI system. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 789e0bc51a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Re-review requested for exact head @codex review Please review the complete recovery-ownership protocol and capability/release snapshot changes at this exact SHA. |
|
Correction: the exact pushed head is @codex review |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='565340f6326eb2793f4657fd3a14ca77a30dcde1'
previous='789e0bc51a33d0f9e540ebc782d4a698cf56566f'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\nPREVIOUS=%s\n' "$actual" "$expected" "$previous"
test "$actual" = "$expected"
printf '\n=== Full PR paths and whitespace validation ===\n'
git diff --name-status main...HEAD
git diff --check main...HEAD
printf '\n=== Changes since the previous review ===\n'
git diff --name-status "$previous...HEAD"
git diff --unified=80 "$previous...HEAD" -- \
adapters/browser/src/microsoft-store.ts \
adapters/browser/src/microsoft-store.test.ts \
adapters/browser/src/index.ts \
packages/platform/src/index.ts \
packages/platform/src/capability-conformance.ts \
packages/target-config/src/runtime.ts \
packages/target-config/src/effective.ts \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
packages/game-services/src/server.test.ts \
tools/smoke/target-config-runtime.ts \
tools/smoke/platform-capability-conformance.ts \
.sampo/changesets/microsoft-store-iap.md \
adapters/browser/CHANGELOG.md
printf '\n=== Focused source outlines ===\n'
ast-grep outline adapters/browser/src/microsoft-store.ts --items all
ast-grep outline packages/game-services/src/microsoft-store-purchase.ts --items all
ast-grep outline packages/target-config/src/runtime.ts --items all --match 'capability|Capability|leaderboard|Leaderboard|availability|Availability'
ast-grep outline packages/platform/src/capability-conformance.ts --items all
printf '\n=== Recovery ownership, remote leaderboard, and snapshot references ===\n'
rg -n -C6 \
'recoveryOwnership|RecoveryOwnership|claimRecoveryOwnership|hasRecoveryOwnership|releaseRecoveryOwnership|owner|reservation|historicalProductMappings|remoteLeaderboard|nativeLeaderboard|commerce\.getAvailability|capabilitySnapshot|snapshot|release|CHANGELOG|changeset' \
adapters/browser/src \
packages/game-services/src \
packages/platform/src \
packages/target-config/src \
tools/smoke \
.sampo/changesets \
-g '*.ts' -g '*.md' \
-g '!**/dist/**' -g '!**/node_modules/**'
printf '\n=== Microsoft Store gateway construction sites ===\n'
rg -n -C5 \
'createMicrosoftStoreCommerceAdapter\s*\(|withMicrosoftStoreCommerceAdapter\s*\(|remoteLeaderboard|createBuildGateway' \
examples \
packages/cli/templates \
tools/smoke \
adapters/browser/src \
-g '*.ts' \
-g '!**/dist/**' -g '!**/node_modules/**'Length of output: 3031 🏁 Script executed: #!/bin/bash
set -euo pipefail
requested='565340f6326eb2793f4657fd3a14ca77a30dcde1'
checked_out='565340f6490afcebe64bed30560ab7f628d015e5'
printf '=== Requested commit availability ===\n'
git cat-file -e "${requested}^{commit}" && printf 'requested commit is available locally\n' || printf 'requested commit is not available locally\n'
printf '\n=== Checked-out commit ===\n'
git show -s --format='commit=%H%nparents=%P%nsubject=%s%ncommitter=%cn <%ce>%ncommitter_date=%cI' "$checked_out"
if git cat-file -e "${requested}^{commit}" 2>/dev/null; then
printf '\n=== Requested commit ===\n'
git show -s --format='commit=%H%nparents=%P%nsubject=%s%ncommitter=%cn <%ce>%ncommitter_date=%cI' "$requested"
printf '\n=== Tree comparison ===\n'
printf 'requested_tree=%s\n' "$(git show -s --format=%T "$requested")"
printf 'checked_out_tree=%s\n' "$(git show -s --format=%T "$checked_out")"
printf '\n=== Commit relationship ===\n'
git merge-base --is-ancestor "$requested" "$checked_out" && printf 'requested is an ancestor of checked-out\n' || true
git merge-base --is-ancestor "$checked_out" "$requested" && printf 'checked-out is an ancestor of requested\n' || true
fiLength of output: 1918
The sandbox checked out The requested commit Please retry the review with the reachable exact SHA. I did not review the different checked-out commit. You are interacting with an AI system. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 565340f649
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Please re-review exact head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='53e93edf170c2756414a15ff8958338b79b05499'
previous='565340f6490afcebe64bed30560ab7f628d015e5'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\nPREVIOUS=%s\n' "$actual" "$expected" "$previous"
test "$actual" = "$expected"
printf '\n=== Commit relationship ===\n'
git merge-base --is-ancestor "$previous" "$actual" && printf 'previous is an ancestor of HEAD\n'
printf '\n=== Full PR and incremental changed paths ===\n'
git diff --name-status main...HEAD
git diff --name-status "$previous...HEAD"
git diff --check main...HEAD
printf '\n=== Incremental focused patch ===\n'
git diff --unified=100 "$previous...HEAD" -- \
adapters/browser/src/microsoft-store.ts \
adapters/browser/src/microsoft-store.test.ts \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
packages/game-services/src/server.test.ts \
packages/cli/src/microsoft-store-submission.ts \
packages/cli/src/microsoft-store-package-generation-input.ts \
packages/cli/src/microsoft-store-package-generation-contract.ts \
tools/smoke/cli-microsoft-store-submission.ts \
tools/smoke/cli-microsoft-store-package-generation.ts \
docs/MICROSOFT_STORE_COMMERCE.md
printf '\n=== Focused source outlines ===\n'
ast-grep outline adapters/browser/src/microsoft-store.ts --items all
ast-grep outline packages/game-services/src/microsoft-store-purchase.ts --items all
ast-grep outline packages/cli/src/microsoft-store-submission.ts --items all
ast-grep outline packages/cli/src/microsoft-store-package-generation-input.ts --items all
printf '\n=== Ownership, commerce-evidence, and consume-response references ===\n'
rg -n -C6 \
'recoveryOwnership|RecoveryOwnership|claimRecoveryOwnership|hasRecoveryOwnership|releaseRecoveryOwnership|purchaseToken|platformTransactionId|itemId|effectiveTarget|commerce|sha256|consume|Collections|response|status|trackingId' \
adapters/browser/src/microsoft-store.ts \
adapters/browser/src/microsoft-store.test.ts \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
packages/game-services/src/server.test.ts \
packages/cli/src/microsoft-store-submission.ts \
packages/cli/src/microsoft-store-package-generation-input.ts \
packages/cli/src/microsoft-store-package-generation-contract.ts \
tools/smoke/cli-microsoft-store-submission.ts \
tools/smoke/cli-microsoft-store-package-generation.ts \
docs/MICROSOFT_STORE_COMMERCE.md \
-g '*.ts' -g '*.md'
printf '\n=== Construction sites and public contracts ===\n'
rg -n -C5 \
'createMicrosoftStorePurchaseBoundary\s*\(|createMicrosoftStoreCommerceAdapter\s*\(|claimRecoveryOwnership\s*\(|MicrosoftStoreRecoveryOwnership' \
. -g '*.ts' -g '*.md' -g '!**/dist/**' -g '!**/node_modules/**'Length of output: 203475 🏁 Script executed: #!/bin/bash
set -euo pipefail
previous='565340f6490afcebe64bed30560ab7f628d015e5'
printf '%s\n' '=== Exact incremental file list ==='
git diff --name-status "$previous...HEAD"
printf '%s\n' '=== Exact incremental patches ==='
git diff --unified=50 "$previous...HEAD" -- \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/cli/src/microsoft-store-submission.ts \
packages/cli/src/microsoft-store-package-generation-input.ts \
packages/cli/src/microsoft-store-package-generation-contract.ts \
tools/smoke/cli-microsoft-store-submission.ts \
tools/smoke/cli-microsoft-store-package-generation.ts \
docs/MICROSOFT_STORE_COMMERCE.md
printf '%s\n' '=== Recovery ownership implementation ==='
nl -ba packages/game-services/src/microsoft-store-purchase.ts | sed -n '300,465p'
nl -ba packages/game-services/src/microsoft-store-purchase.ts | sed -n '480,605p'
nl -ba packages/game-services/src/microsoft-store-purchase.ts | sed -n '625,705p'
nl -ba packages/game-services/src/microsoft-store-purchase.ts | sed -n '787,920p'
printf '%s\n' '=== Ownership and consume regression tests ==='
nl -ba packages/game-services/src/microsoft-store-purchase.test.ts | sed -n '240,370p'
nl -ba packages/game-services/src/microsoft-store-purchase.test.ts | sed -n '450,535p'
rg -n -C8 \
'newQuantity|CONSUME_RESPONSE|providerPurchaseId|historical.*ownership|legacy.*ownership|claimRecoveryOwnership|hasRecoveryOwnership' \
packages/game-services/src/microsoft-store-purchase.test.ts
printf '%s\n' '=== Submission effective-target validation ==='
ast-grep outline packages/cli/src/microsoft-store-submission.ts --items all
ast-grep outline packages/cli/src/microsoft-store-package-generation-input.ts --items all
rg -n -C10 \
'effectiveTarget|commerce|revalid|sha256|snapshot|monetization|inAppOfferToken|storeId' \
packages/cli/src/microsoft-store-submission.ts \
packages/cli/src/microsoft-store-package-generation-input.ts \
packages/cli/src/microsoft-store-package-generation-contract.ts \
tools/smoke/cli-microsoft-store-submission.ts \
tools/smoke/cli-microsoft-store-package-generation.ts
printf '%s\n' '=== Documentation: v8 consume response ==='
rg -n -C8 \
'consume|newQuantity|trackingId|itemId|Collections v8|response' \
docs/MICROSOFT_STORE_COMMERCE.md \
README.mdLength of output: 90667 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Browser authority input and recovery flow ==='
sed -n '70,310p' adapters/browser/src/microsoft-store.ts
sed -n '310,590p' adapters/browser/src/microsoft-store.ts
sed -n '250,390p' adapters/browser/src/microsoft-store.test.ts
sed -n '820,1025p' adapters/browser/src/microsoft-store.test.ts
printf '%s\n' '=== Recovery ownership and consume implementation ==='
sed -n '300,465p' packages/game-services/src/microsoft-store-purchase.ts
sed -n '480,605p' packages/game-services/src/microsoft-store-purchase.ts
sed -n '625,705p' packages/game-services/src/microsoft-store-purchase.ts
sed -n '787,920p' packages/game-services/src/microsoft-store-purchase.ts
printf '%s\n' '=== Tests for provider purchase replacement and consume parsing ==='
sed -n '240,535p' packages/game-services/src/microsoft-store-purchase.test.ts
rg -n -C10 \
'nextConsumeResponse|CONSUME_RESPONSE|newQuantity|itemId|transactionId|trackingId|providerPurchaseId|fresh-generation|stale-generation' \
packages/game-services/src/microsoft-store-purchase.test.ts
printf '%s\n' '=== Complete effective-target validator and generation revalidation ==='
sed -n '250,390p' packages/cli/src/microsoft-store-submission.ts
sed -n '180,330p' packages/cli/src/microsoft-store-package-generation-input.ts
rg -n -C8 \
'contradictory-disabled|effective target|enableCommerceEvidence|changed while it was parsed|microsoft-store' \
tools/smoke/cli-microsoft-store-package-generation.tsLength of output: 104349 🤖 web_search executed:
Length of output: 20750 🤖 web_search executed:
Length of output: 4451 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Remaining effective-target validator and parsing helpers ==='
sed -n '330,430p' packages/cli/src/microsoft-store-submission.ts
sed -n '300,410p' packages/cli/src/microsoft-store-package-generation-input.ts
printf '%s\n' '=== Documentation consume contract ==='
sed -n '35,115p' docs/MICROSOFT_STORE_COMMERCE.md
printf '%s\n' '=== All current tests that force consume response validation ==='
rg -n -C12 \
'malformed|MISMATCH|CONSUME_RESPONSE|newQuantity|trackingId|itemId|transactionId' \
packages/game-services/src/microsoft-store-purchase.test.ts \
apps/game-services-worker/src/index.test.tsLength of output: 47561
I found one actionable issue.
Collections v8 specifies Without this check, a malformed or mismatched successful response can release the ownership claim and mark finalization complete for a different product. Restore this condition: raw.productId !== context.storeIdUpdate the valid fixture to include The provider-purchase ownership binding and effective-target commerce revalidation are otherwise correctly fail-closed. You are interacting with an AI system. |
|
@codex review Please re-review final exact head |
|
Correction: the final exact head is |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='f44b70ba1d0c6da0e10f39e6340bf2d98ae86d88'
previous='53e93edf170c2756414a15ff8958338b79b05499'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\nPREVIOUS=%s\n' "$actual" "$expected" "$previous"
test "$actual" = "$expected"
printf '\n=== Incremental changed paths and whitespace validation ===\n'
git diff --name-status "$previous...HEAD"
git diff --check "$previous...HEAD"
printf '\n=== Focused incremental patch ===\n'
git diff --unified=80 "$previous...HEAD" -- \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
packages/game-services/src/server.test.ts \
apps/game-services-worker/src/handler.ts \
apps/game-services-worker/src/index.test.ts \
docs/MICROSOFT_STORE_COMMERCE.md
printf '\n=== Focused source outline ===\n'
ast-grep outline packages/game-services/src/microsoft-store-purchase.ts --items all
printf '\n=== Finalization, provider generation, listing, and retry references ===\n'
rg -n -C8 \
'finaliz|consume|providerPurchaseId|platformTransactionId|purchaseToken|listPurchases|Collections|stale|generation|alreadyProcessed|productId|trackingId|newQuantity' \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
packages/game-services/src/server.test.ts \
apps/game-services-worker/src/handler.ts \
apps/game-services-worker/src/index.test.ts
printf '\n=== Implementation and targeted regression ranges ===\n'
nl -ba packages/game-services/src/microsoft-store-purchase.ts | sed -n '520,960p'
rg -n -C12 \
'consumed item|no longer|not listed|stale generation|different provider|provider purchase|retry|finaliz' \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.test.ts
printf '\n=== Full-PR whitespace validation ===\n'
git diff --check main...HEADLength of output: 2472
The requested SHA is The sandbox checked out These commits share the You are interacting with an AI system. |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review Please re-review current exact head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='b94bd045fdbaf800fe8393b7bed9c078f6d2fcc7'
previous='f44b70baf56de424e876ccff8d027f93fc34dc1c'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\nPREVIOUS=%s\n' "$actual" "$expected" "$previous"
test "$actual" = "$expected"
git merge-base --is-ancestor "$previous" "$actual"
printf '\n=== Incremental changed paths and whitespace validation ===\n'
git diff --name-status "$previous...HEAD"
git diff --check "$previous...HEAD"
printf '\n=== Incremental patch ===\n'
git diff --unified=100 "$previous...HEAD"
printf '\n=== Microsoft Store purchase boundary outline ===\n'
ast-grep outline packages/game-services/src/microsoft-store-purchase.ts --items all
printf '\n=== Player comparison and recovery ownership control flow ===\n'
rg -n -C12 \
'player|playerId|owner|ownership|claimRecoveryOwnership|hasRecoveryOwnership|releaseRecoveryOwnership|denied|conflict|providerPurchaseId' \
packages/game-services/src/microsoft-store-purchase.ts \
packages/game-services/src/microsoft-store-purchase.test.ts \
packages/game-services/src/server.ts \
packages/game-services/src/server.test.ts \
-g '*.ts'
printf '\n=== Exact modified-file sections ===\n'
git diff --name-only "$previous...HEAD" | while IFS= read -r file; do
case "$file" in
*.ts|*.tsx|*.js|*.jsx)
printf '\n--- %s ---\n' "$file"
nl -ba "$file" | sed -n '1,1000p'
;;
esac
done
printf '\n=== Full PR whitespace validation ===\n'
git diff --check main...HEADLength of output: 231977
The player comparison removal is safe. I found one remaining actionable issue.
A mismatched successful response can therefore release the ownership record and complete finalization for a different Store product. Add this check to the mismatch condition: raw.productId !== context.storeIdUpdate the valid consume fixture to include
You are interacting with an AI system. |
|
Codex Review: Didn't find any major issues. Breezy! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
@mpgd/adapter-browser/microsoft-storesubpath for Store-installed Edge PWAs, including localized catalog data, paid-purchase recovery, and game-owned authority hooksmicrosoft-storea first-class platform, Game Services commerce runtime, and target-config runtime; add CLI submission product mapping validation, legacy starter migration, and starter wiringSecurity model
The browser never grants inventory or consumes a purchase. Digital Goods
purchaseTokenis treated as a non-unique add-on product ID, not a transaction ID or User Store ID. The server resolves Entra credentials, a renewable player-bound User Store ID, and a separate stable opaqueaccountBindingId. That stable ID survives User Store ID renewal and changes only on a real Store-account relink. Verification records its domain-separated hash in ledger evidence, then finalization re-resolves and compares it before consume.Only the dedicated Microsoft Store verifier/finalizer pair may verify Store consumables. Aggregate and insecure development verifier fallbacks fail closed for this target. The client calls PaymentResponse completion only after Store ownership reconciliation and authoritative fulfillment: completed maps to
success, explicit failure tofail, and pending/transport uncertainty tounknown.Checkout remains
configuration-requireduntil the game supplies authoritative services and one trusted account-linking strategy: a Windows host bridge, or service-side Microsoft/Xbox OAuth with delegated X-tokens. Non-RETAIL developer-managed consume fails closed until delegated XSTS support exists.Validation
pnpm check^0.5.1to^0.6.0migrationRelease and merge notes
mainbefore merge if other pending kit PRs land first, then rerun the full suite.@mpgd/adapter-browserpackage, so no initial npm package registration or separate OIDC setup is required.@mpgd/adapter-browserand@mpgd/clialongside the catalog, Game Services, platform, and target-config contracts.main, so the actual release calculation must run on the release branch.Downstream blocker
TtokDoku can enable checkout after Partner Center creates two developer-managed consumable add-ons with distinct Collections Store IDs, and the game service has secure Entra plus stable player-to-Store-account linking. A Store-installed PWA cannot derive that identity from Digital Goods alone, so the game repository remains fail-closed until those values and the account-linking strategy exist.
Summary by CodeRabbit