Skip to content

feat: verify Verse8 ad rewards server-side - #84

Merged
imjlk merged 2 commits into
mainfrom
codex/verse8-ads-verification
Jul 16, 2026
Merged

imjlk merged 2 commits into
mainfrom
codex/verse8-ads-verification

Conversation

@imjlk

@imjlk imjlk commented Jul 15, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • integrate Verse8 rewarded and interstitial ads through catalog-backed placement IDs
  • add a server-only consume-once evidence verifier that validates request, placement, player, and verification time while ignoring client and verifier reward values
  • route Verse8 evidence through the Game Services Worker with a target binding override and fail-closed built-in HTTP verifier
  • update starter wiring, target availability, public documentation, and regression coverage

Security boundary

The client callback supplies correlation evidence only. Reward grants remain authoritative in the Game Services backend: the Worker consumes the Verse8 verification record, matches it to the catalog placement and player, and then lets the ledger decide the grant. Verse8 purchases and leaderboards remain unavailable in this PR.

The built-in Worker verifier is enabled only when VERSE8_ADS_VERIFIER_AUTHORIZATION is configured as a secret. A target-specific GAME_SERVICES_VERSE8_EVIDENCE_VERIFIER binding can override it.

Release

A Sampo changeset covers @mpgd/adapter-verse8, @mpgd/catalog, @mpgd/game-services, @mpgd/target-config, and @mpgd/cli. The Verse8 adapter is already registered on npm and Trusted Publishing is configured for the repository release workflow.

Validation

  • pnpm check
  • pnpm test plus the corrected remaining prepared smoke sequence
  • pnpm validate:ads
  • pnpm validate:target-config
  • pnpm validate:effective-config
  • pnpm validate:targets
  • pnpm validate:public
  • pnpm smoke:effective-config
  • pnpm smoke:adapter-effective-config
  • pnpm smoke:game-config
  • pnpm graph:preflight
  • pnpm pack:packages
  • pnpm build:verse8
  • pnpm smoke:target verse8
  • sampo release --dry-run from an isolated main checkout

Summary by CodeRabbit

  • New Features

    • Added Verse8 rewarded and interstitial ad support with platform placement mapping.
    • Added secure, consume-once server verification for rewarded ad claims.
    • Added Verse8 support for ad rewards and ledger processing.
    • Added server configuration options for verifier authorization and endpoint selection.
  • Bug Fixes

    • Prevented unverified Verse8 rewards from being granted.
    • Ensured client-reported reward amounts cannot influence grants.
  • Documentation

    • Updated setup, configuration, adapter, and production verification guidance for Verse8 ads.

@imjlk

imjlk commented Jul 15, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Verse8 gains rewarded and interstitial ad support with placement resolution, client evidence, consume-once server verification, Worker routing, and target-specific configuration. Reward grants require verified server evidence, while purchases and leaderboard submissions remain unsupported for Verse8.

Changes

Verse8 target support

Layer / File(s) Summary
Target contracts and configuration
packages/catalog/*, packages/game-services/*, packages/target-config/*, tools/smoke/*, backend/game-services/*
Verse8 is added to target types, ad configuration, placement mappings, runtime checks, and backend reward safeguards.
Adapter ad flow
adapters/verse8/*, examples/phaser-starter/..., packages/cli/templates/..., README.md
The adapter resolves platform placements, invokes Verse8 ads, maps outcomes, and emits versioned reward evidence.
Consume-once evidence verifier
adapters/verse8/src/server.ts, adapters/verse8/src/server.test.ts, tsconfig.base.json
A server entry point verifies request, placement, user, schema, and verifier-record state through an HTTPS consume endpoint.
Worker routing and integration
apps/game-services-worker/*, docs/GAME_SERVICES_BACKEND.md
Worker bindings and environment settings construct the Verse8 verifier and route rewarded claims to it before ledger decisioning.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GameServicesClient
  participant Verse8PlatformGateway
  participant GameServicesWorker
  participant Verse8AdsVerifier
  participant RewardLedger
  GameServicesClient->>Verse8PlatformGateway: showRewarded placement
  Verse8PlatformGateway->>Verse8PlatformGateway: collect requestId and create evidence
  GameServicesClient->>GameServicesWorker: claimAdReward with evidence
  GameServicesWorker->>Verse8AdsVerifier: consume requestId
  Verse8AdsVerifier-->>GameServicesWorker: verified record
  GameServicesWorker->>RewardLedger: decide catalog-backed grant
Loading

Possibly related PRs

  • imjlk/mpgd-kit#65: Introduced the evidence-verifier boundary extended here for Verse8 Worker routing.
  • imjlk/mpgd-kit#82: Established the Verse8 adapter foundation extended here with ads and reward evidence.

Poem

A bunny saw ads bloom bright,
With proofs tucked safely out of sight.
The server checked each claim with care,
While ledgers granted only fair.
“Hop verified!” the rabbit sings.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately highlights the main change: server-side Verse8 ad reward verification.
Description check ✅ Passed The description covers Summary, Validation, security boundary, and release details; only the template's Notes section is missing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/verse8-ads-verification

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026 •

Copy link
Copy Markdown

@imjlk: Sure, I'll review the changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31619520fc

ℹ️ 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".

Comment thread adapters/verse8/src/server.ts Resolved
Comment thread backend/ad-reward-ledger/src/index.ts Resolved

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/game-services-worker/src/handler.ts (1)

249-261: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not let Verse8 credentials disable the aggregate verifier.

When GAME_SERVICES_EVIDENCE_VERIFIER and VERSE8_ADS_VERIFIER_AUTHORIZATION are both set, Line 251 enters target-specific mode. Android, iOS, and AIT then resolve no binding and fail closed instead of using the aggregate verifier.

Treat built-in Verse8 configuration separately: preserve the aggregate binding for non-Verse8 targets while using the built-in verifier only as the Verse8 fallback.

Also applies to: 269-274

🤖 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 `@apps/game-services-worker/src/handler.ts` around lines 249 - 261, Update the
verifier selection logic around hasTargetSpecificEvidenceVerifierBinding and
createWorkerEvidenceVerifier so built-in VERSE8_ADS_VERIFIER_AUTHORIZATION does
not trigger target-specific mode when GAME_SERVICES_EVIDENCE_VERIFIER is also
configured. Preserve the aggregate binding for Android, iOS, and AIT, while
selecting the built-in verse8Verifier only as the fallback for Verse8 targets.
🤖 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/verse8/src/index.ts`:
- Around line 54-58: Update Verse8PlatformGatewayOptions and the gateway
capability setup so ads are not reported as available when resolveAdPlacementId
is absent. Either make resolveAdPlacementId required or conditionally disable
all ad capabilities when it is undefined, while preserving the existing
unavailable behavior of the show methods.

In `@apps/game-services-worker/wrangler.toml`:
- Around line 26-30: Update the Verse8 rewarded-ad configuration comments near
GAME_SERVICES_VERSE8_EVIDENCE_VERIFIER to state that this binding can enable
grants as an alternative to the VERSE8_ADS_VERIFIER_AUTHORIZATION credential,
and remove the implication that the secret is always required.

In `@docs/GAME_SERVICES_BACKEND.md`:
- Around line 161-167: Update the Verse8 verifier configuration documentation to
consistently use the Worker variable name VERSE8_ADS_VERIFIER_AUTHORIZATION,
including any setup instructions or references in this section. Remove or
replace the incorrect VERSE8_ADS_VERIFIER_AUTH name while preserving the
guidance that the value is the complete server Authorization header.

In `@packages/game-services/src/types.ts`:
- Around line 263-265: Remove Verse8 from the accepted targets in
assertLeaderboardTarget in packages/game-services/src/types.ts, including its
validation message. Also remove Verse8 from the LeaderboardLedgerTarget type and
runtime validation in backend/leaderboard-ledger/src/index.ts; both sites must
reject unsupported Verse8 leaderboard submissions.
- Around line 12-15: The shared GameServicesStoreTarget contract must not treat
Verse8 as a purchase store target. In packages/game-services/src/types.ts at
lines 12-15, remove 'verse8' or split the purchase and rewarded-ad target types
so purchase verification excludes it; in packages/game-services/src/client.ts at
lines 501-503, replace store-target classification for Verse8 with the
ad-specific predicate, preserving Verse8 support only for rewarded-ad flows.

---

Outside diff comments:
In `@apps/game-services-worker/src/handler.ts`:
- Around line 249-261: Update the verifier selection logic around
hasTargetSpecificEvidenceVerifierBinding and createWorkerEvidenceVerifier so
built-in VERSE8_ADS_VERIFIER_AUTHORIZATION does not trigger target-specific mode
when GAME_SERVICES_EVIDENCE_VERIFIER is also configured. Preserve the aggregate
binding for Android, iOS, and AIT, while selecting the built-in verse8Verifier
only as the fallback for Verse8 targets.
🪄 Autofix (Beta)

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

Run ID: e86be4c1-93e2-4328-987c-099500063f07

📥 Commits

Reviewing files that changed from the base of the PR and between 5845206 and 3161952.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (32)
  • .sampo/changesets/verse8-ads-verification.md
  • README.md
  • adapters/verse8/package.json
  • adapters/verse8/src/ads-contract.ts
  • adapters/verse8/src/index.test.ts
  • adapters/verse8/src/index.ts
  • adapters/verse8/src/server.test.ts
  • adapters/verse8/src/server.ts
  • adapters/verse8/test/server-dist-import.mjs
  • apps/game-services-worker/package.json
  • apps/game-services-worker/src/handler.ts
  • apps/game-services-worker/src/index.test.ts
  • apps/game-services-worker/wrangler.toml
  • backend/ad-reward-ledger/src/index.ts
  • backend/leaderboard-ledger/src/index.ts
  • backend/purchase-verifier/src/index.ts
  • docs/GAME_SERVICES_BACKEND.md
  • examples/phaser-starter/src/platform/buildGateways/verse8.ts
  • packages/catalog/placements.json
  • packages/catalog/src/index.ts
  • packages/cli/templates/phaser-game/src/platform/buildGateways/verse8.ts
  • packages/game-services/src/client.ts
  • packages/game-services/src/runtime.ts
  • packages/game-services/src/types.ts
  • packages/target-config/src/effective.ts
  • packages/target-config/targets.json
  • tools/smoke/adapter-effective-config.ts
  • tools/smoke/effective-target-config.ts
  • tools/smoke/game-owned-catalog.ts
  • tools/smoke/target-config-runtime.ts
  • tools/validate-target-config.ts
  • tsconfig.base.json
💤 Files with no reviewable changes (1)
  • tools/validate-target-config.ts

Comment thread adapters/verse8/src/index.ts Resolved
Comment thread apps/game-services-worker/wrangler.toml Resolved
Comment thread docs/GAME_SERVICES_BACKEND.md Resolved
Comment thread packages/game-services/src/types.ts Resolved
Comment thread packages/game-services/src/types.ts Resolved

imjlk commented Jul 16, 2026

Copy link
Copy Markdown
Owner Author

Addressed the actionable review findings in f6277f0:

  • preserve aggregate verification while adding the built-in Verse8 verifier
  • reject Verse8 in the unauthenticated legacy reward path
  • advertise rewarded ads only when a placement resolver is configured
  • document private binding/secret alternatives
  • split purchase, ad-reward, and leaderboard target contracts so unavailable Verse8 operations fail before SDK/backend invocation

The endpoint and environment-name findings were also re-verified. GET /ads/status is the browser-parent polling contract, while the authenticated consume boundary remains POST /ads/verify; the documented secret name already matches the Worker binding.

Validation completed: pnpm check, full pnpm test, graph preflight, target/config validations, adapter and Worker tests, Verse8 build/smoke, packaging, and Sampo dry-run.

@codex review
@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown

@imjlk, thanks for the detailed summary. I'll review commit f6277f0 now, covering the aggregate verification changes, Verse8 rejection in the legacy unauthenticated path, conditional rewarded-ads advertisement, updated documentation, and the split target contracts.

ヽ(・ω・´ﻭ

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/game-services/src/client.ts (1)

533-538: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Explicitly list supported targets for better future-proofing.

Using negation (target !== 'verse8') correctly mirrors the current type definitions, but it can be fragile. If a new unsupported target (e.g., 'tauri') is added to GameServicesLedgerTarget in the future, this function would incorrectly return true for it.

Consider enumerating the supported targets explicitly as done in isGameServicesAdRewardTarget to safely guard against future target expansions.

♻️ Proposed refactor
 function isGameServicesLeaderboardTarget(
   target: GameServicesLedgerTarget,
 ): target is GameServicesLeaderboardTarget {
-  return target !== 'verse8';
+  return target === 'browser' || target === 'android' || target === 'ios' || target === 'ait' || target === 'reddit';
 }
🤖 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/client.ts` around lines 533 - 538, Update
isGameServicesLeaderboardTarget to explicitly return true only for the currently
supported leaderboard target values, matching the allowlist approach used by
isGameServicesAdRewardTarget. Remove the negated exclusion check so future
additions to GameServicesLedgerTarget are not implicitly accepted.
🤖 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.

Nitpick comments:
In `@packages/game-services/src/client.ts`:
- Around line 533-538: Update isGameServicesLeaderboardTarget to explicitly
return true only for the currently supported leaderboard target values, matching
the allowlist approach used by isGameServicesAdRewardTarget. Remove the negated
exclusion check so future additions to GameServicesLedgerTarget are not
implicitly accepted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b851a99c-dee8-4f25-8112-85d19e334b91

📥 Commits

Reviewing files that changed from the base of the PR and between 3161952 and f6277f0.

📒 Files selected for processing (14)
  • adapters/verse8/src/index.test.ts
  • adapters/verse8/src/index.ts
  • adapters/verse8/src/server.test.ts
  • apps/game-services-worker/src/handler.ts
  • apps/game-services-worker/src/index.test.ts
  • apps/game-services-worker/wrangler.toml
  • backend/game-services/src/index.test.ts
  • backend/game-services/src/index.ts
  • docs/GAME_SERVICES_BACKEND.md
  • packages/game-services/src/client.test.ts
  • packages/game-services/src/client.ts
  • packages/game-services/src/types.ts
  • tools/smoke/adapter-effective-config.ts
  • tools/smoke/target-config-runtime.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • adapters/verse8/src/server.test.ts
  • apps/game-services-worker/wrangler.toml
  • docs/GAME_SERVICES_BACKEND.md
  • tools/smoke/target-config-runtime.ts
  • apps/game-services-worker/src/index.test.ts
  • adapters/verse8/src/index.test.ts

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: f6277f0727

ℹ️ 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".

@imjlk
imjlk merged commit eab89e5 into main Jul 16, 2026
6 checks passed
@imjlk
imjlk deleted the codex/verse8-ads-verification branch July 16, 2026 01:32
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.

1 participant