# Community, Store, Support & AI Services

```mermaid
mindmap
  root((Around the V2 match))
    Community
      Editorial and moderated galleries
      Clubs events and sharing
      Reports blocks and appeals
    Commerce
      Region-aware pricing
      Entitlements refunds and receipts
      Store and progression boundaries
    Support
      Account recovery and tickets
      Ambassadors and Hall of Fame
      Audit-safe operator actions
    Broadcast AI
      Commentary and translation
      Captions and moderation
      Caster face and lip sync
      Never influences rollback
```

All four clusters are deliberately off the rollback simulation. They consume
versioned match or account evidence and produce governed external effects, but
cannot perturb deterministic combat truth.

Everything on this page happens **around** the match, never inside it. When a
fight ends, V2 hands the moment off to a ring of out-of-match surfaces: the
community team's editorial picks and moderated galleries, the per-platform
storefront that prices a cosmetic differently in São Paulo than in San Jose, the
support desk that triages a lost-account ticket, and — the most architecturally
interesting cluster — the **AI services** that turn a recorded set into a
produced broadcast with live commentary, translated chat, captions, and a
lip-synced caster face. The throughline is a hard line: every one of these
surfaces is **off-rollback**. None of them can perturb the deterministic combat
simulation, and the code says so out loud, with `mayInfluenceRollback: false`
and `rollbackPolicy` fields stamped on each service's output.

The shape of what ships matters here, because this group spans the full
implemented-to-spec spectrum. The web surfaces are **versioned JSON data
contracts**, not React apps. The store's region-aware pricing is **genuinely
implemented math** in two separate engines. The AI services are **real
orchestration bridges** whose generative core is an honest provider-gated seam.
And the moderation underneath the galleries composes the shared Kuanyin/Themis
trust-and-safety plane that governs every Oshun product. This is the
feature-side companion to the "Online, Esports & Live Service" group; the
section hub is [../V2_features.md](../V2_features.md).

## What ships, honestly

- **The web surfaces are real but data-shaped.** `apps/v2/web/community`,
  `apps/v2/web/hub`, and `apps/v2/web/support` are not standalone apps — each is
  a single schema-versioned JSON document (`community.json` →
  `v2.web.community.v1`, `hub.json` → `v2.webHub.v1`, `support.json` →
  `v2.web.support.v1`) that the shared Oshun shell renders. They are the
  **shipped data contract**: Player of the Week, the gallery roster, support SLA
  tiers, the ambassador languages, and the Hall of Fame inductees are all
  concrete fields, not lorem ipsum.
- **The store math is implemented twice, for two economies.** Real-money
  region-aware pricing (PPP) is a real function,
  `calculateV2MaatFinanceRegionalPriceMinor` in `@maat/finance`, bridged into V2
  by `@v2/maat-finance-ledger`. The in-game soft-currency economy is a separate,
  fully-implemented C++ engine, `UV2PriceTableLibrary` in
  `V2/ue/Source/V2Gameplay/Private/V2PriceTable.cpp`. Both carry validators and
  contract specs.
- **The AI services are real bridges with a provider-gated core.**
  `iris-commentary-orchestration`, `iris-realtime-translation`,
  `iris-accessibility`, `isis-commentary-lipsync-pipeline`,
  `psyche-commentary-face-animation`, `psyche-caption-streaming`,
  `euterpe-commentary-ducking`, `calliope-commentator-personas`, and
  `psyche-ai-director-hints` all exist under `apps/v2/` with real orchestration,
  latency budgeting, and fallback logic. What is **provider-gated** is the
  generation itself — the commentary text, the synthesized voice, the animated
  face — produced by the shared Iris/Isis/Psyche/Euterpe substrates those
  bridges call, exactly the fail-loud-when-unconfigured seam the platform uses
  everywhere.
- **What is plan, not artifact:** the editorial spotlights, the specific brand
  partners, the newsletter copy. Those are authored/scheduled content the
  services carry, honestly a roadmap and not engine code.

The architecture-side treatment of these same surfaces lives in two companions:
[../architecture/live-ops-store-progression-and-community.md](../architecture/live-ops-store-progression-and-community.md)
(store, economy, community governance) and
[../architecture/esports-companion-and-ai-services.md](../architecture/esports-companion-and-ai-services.md)
(the AI broadcast chain). This page stays on the feature surface and dips into
code only where a claim needs backing.

## Community surfaces

### The web data contracts

`apps/v2/web/community/community.json` is the seed for the out-of-game community
page, and its fields map one-to-one onto the source feature list. `featured`
carries the three editorial picks — `player` (Player of the Week), `crew` (Crew
of the Month), and `replay` (Replay of the Week) — each with a `reward` flair id
like `Flair.PlayerOfTheWeek.2026W22`, so the "featured account gets a flair
cosmetic" promise is a concrete grant token, not prose.
`apps/v2/web/hub/hub.json` is the account-bound player hub: rank, Crown balance,
Battle-Pass tier, faction, a friends panel, a wishlist, a leaderboard slice,
public replays, a moderated gallery strip, two server-validated web micro-games
(`Web Frame Quiz`, `Web Replay Scout`), and a `news` feed whose items are tagged
`confirmed | planned | exploratory` — the same roadmap-honesty taxonomy the
roadmap surface uses.

### Editorial spotlights, galleries & moderation

Each `gallery` entry in `community.json` carries the fields that make a
community gallery safe to ship: a `creator`, a `creatorCode` (the
creator-attribution code that also applies at store checkout),
`moderation: "approved"`, `consent: true`, and a `source`
(`Community Art Gallery`, `PhotoModeCloud`, `TournamentArchive`). Those two
booleans are load-bearing — nothing surfaces in the gallery until it has passed
moderation **and** carries explicit consent.

The moderation pipeline the relationships/creator page defers to lives here, and
it is governed rather than ad-hoc. `@v2/kuanyin-first-line-moderation` is the
primary moderation path — its README is explicit that it **replaces Two Hat,
Community Sift, Hive AI, and AWS Rekognition** with `@kuanyin/precognition` and
`@kuanyin/foundation` as the first-line filter. Public UGC accept-gating (custom
championships, decals, logos, music swaps) runs through
`@v2/themis-originality-shields`, which composes the full Themis originality
family — `@themis/music-shield`, `@themis/visual-shield`, `@themis/text-shield`,
`@themis/video-shield`, and `@themis/design-shield` — so an uploaded decal is
checked for visual originality and an uploaded soundtrack swap for music-rights
collision before it can appear. Crew/faction governance (rule votes, member
reputation, constitution amendments) composes `@themis/community` through
`@v2/themis-community-governance`, and community-health signals (temperature
scoring, raid detection, new-user throttles) run through
`@v2/kuanyin-community-harmony`. Because all of this resolves through the same
audited Themis/Kuanyin path, a community ban and a match-conduct ban are the
same appealable action.

### Newsletter, meetups, Discord & journals

The `newsletter` block lists eight serviced regions (NA, EU, JP, KR, LATAM, SEA,
India, MENA) and a fixed `recap` shape (patch highlights, new content,
tournament results, community moments, roadmap teaser). `meetups` are opt-in and
**privacy-first**: each entry carries a `locationLabel`, a subscribable `.ics`
feed, and `noPii: true`, so the discovery map never leaks an account's location.
`discord` enumerates the eight per-region staffed servers, and `journalPrompts`
seeds the per-account public journal (moderated on the same pipeline as gallery
submissions). Photo-mode tournament submissions and community/jury voting are a
separate bridge, `@v2/photo-mode-tournament-voting-bridge` (§133), which emits a
`v2.photo-mode-tournament-voting-manifest` consumed by `V2PhotoMode`,
`V2ReplayTheater`, `V2CommunityHub`, and `V2CompanionApp`.

## Store & region-aware pricing (PPP)

V2 runs **two distinct price engines**, and conflating them is the easy mistake.
One prices real money (the cosmetic/DLC storefront); the other prices in-game
soft currency (the Koin/Crown vendor economy). Both are implemented; they live
in different languages and answer to different rules.

### Real-money pricing: the PPP ledger

Real-money region-aware pricing is `calculateV2MaatFinanceRegionalPriceMinor` in
`libs/maat/finance/src/v2-persistence-ledger.ts`, bridged into V2 by
`buildV2MaatFinanceLedgerSurface` in
`apps/v2/maat-finance-ledger/src/maat-finance-ledger.ts`. The policy struct
`V2MaatFinanceRegionalPricingPolicy` carries a `baselinePriceMinor`, a
`pppRatioBasisPoints`, a `priceFloorRatioBasisPoints`, and a
`priceCeilingMinor`, and the function is exactly the "ratio, floored, ceilinged"
rule the source describes:

```text
ratioPrice = round(baselinePriceMinor × pppRatioBasisPoints / 10_000)
floorPrice = round(baselinePriceMinor × priceFloorRatioBasisPoints / 10_000)
regionalPrice = min(priceCeilingMinor, max(floorPrice, ratioPrice))
```

The contract spec pins this with a worked policy — `pppRatioBasisPoints: 6500`
(a 0.65 purchasing-power ratio), `priceFloorRatioBasisPoints: 4000` (the **ratio
× 0.4 floor that blocks inversion attacks**, straight from the source), and a
`priceCeilingMinor` that caps the regional price at baseline. The same function
is reused inside `buildV2MaatFinanceLedgerDecision`, which is the spend gate: a
`spend` transaction is rejected with reason `region-price-mismatch` if the
client's `unitPriceMinor` does not equal the freshly-computed regional price (so
a VPN-spoofed or stale price cannot transact), and with
`regulatory-cap-exceeded` if it breaches `regulatoryTransactionCapMinor` or the
running `regulatoryDailySpendCapMinor` — and minor accounts get a stricter
`minorDailySpendCapMinor`. Refunds require a `refundReferenceId` and fall inside
`refundWindowDays`, or they fail `refund-reference-required` /
`refund-window-expired`. The whole decision is **offline-tolerant**: it can
approve against an in-engine ledger cache (`approved-offline-cache`) and
reconcile on the next online sync, which is why `support.json`'s refund ticket
shows a "Maat finance review queued" history line.

### In-game economy: the C++ price table

The soft-currency vendor economy is `UV2PriceTableLibrary::QuotePriceTable` in
`V2/ue/Source/V2Gameplay/Private/V2PriceTable.cpp` — a real `BlueprintPure`
resolver, not a lookup. A quote resolves a base price for the `Buy`/`Sell` kind,
then applies a **regional override** (`FV2PriceTableRegionalOverride` can
override the buy price, the sell price, or apply a `RegionalMultiplier`), then
optional **dynamic pricing** that multiplies the entry's
`Demand × Supply × Event` factors against the request's, clamps the result to
the entry's `Min/Max` bounds, and finally scales by quantity. Every stage
records an itemized `FV2PriceTableIssue` (`RegionalOverrideApplied`,
`DynamicPriceApplied`, `PriceEntryResolved`) so a quote is auditable.
`ValidatePriceTable` is the gate that keeps the catalogue honest — it rejects
duplicate price-entry ids, duplicate `item|currency` pairs, currencies absent
from the catalogue, non-positive prices, a sell price exceeding the buy price,
and multipliers outside `(0, 10]`, each as a **blocking** issue with a
`FailureTag`. This is the engine behind the persistent-world economy and the
Krypt/vendor shops, and it is fully separate from the real-money ledger above —
nothing it prices touches a payment rail.

### The per-platform storefront

Real-money purchases route through each platform's native store. `hub.json`'s
`commerce` block is the surfaced contract: `allowed`, a `region` (e.g. `US`),
`platformPaymentRulesPermit: true`, and a `refundPolicy` pointer (`V2.86.5`).
The platform store is the **exclusive** path for any item that grants gameplay
state on that platform; the non-item flows (coaching marketplace, donations,
esports prize pools) are the TRC-permitted exceptions that route through
Stripe/Adyen, and they are kept ledger-separate from earned currency for
store-compliance reasons. Premium currency (Crowns) buys transparent items —
**no real-money loot boxes** — under the daily spend caps the ledger enforces.

## Customer support, ambassadors & Hall of Fame

`apps/v2/web/support/support.json` is the support contract, and its
`priorityTiers` are the SLA spine: `critical` (lost account / refund dispute /
harassment) at **1h first response / 24h resolution** under 24/7 coverage,
`high` (ban appeal / cheat report / payment failed) at 8h/72h, `normal`
(cosmetic loss / UI bug) at 48h/14d, and `low` (feature request) at 7d.
`regions` pins per-region hours and locale coverage (eight regions, from
`en-US`/`es-MX` in NA to `ar-SA`/`en-AE` in MENA); `knowledgeBase` ships real KB
articles (account recovery, platform refunds, harassment escalation,
rollback-quality troubleshooting); `ambassadors` declares the vetted program
(eight regions, ten languages, a quarterly-review term, an
`Community Ambassador` flair); `coaches` carries the certified-coach roster with
per-coach ratings; and `hallOfFame` enumerates the inducted champions,
record-holders, and community legends. The live ticket list (`tickets`)
demonstrates the routing — `SUP-1025`'s history shows a refund dispute handed to
"Maat finance review," closing the loop back to the PPP ledger.

Support does not stand alone: when an outage or mispriced item harms players,
`@v2/player-compensation-service` issues incident-scoped, evidence-backed,
approval-gated make-goods; `@v2/patch-notes-service` publishes the structured,
required-category change record that pairs with each balance hotfix; and
`@v2/message-of-the-day-service` pushes announcements (events, downtime, patch
notes) to the shipped client **without a patch**, with per-account dismissal —
the same dismissal keys `community.json`'s `announcements` block carries.

## AI services: a produced broadcast

This is V2's integration showcase. A match can be cast by AI in real time, and
the pipeline is a chain of thin `apps/v2/` bridges over shared Oshun substrates
— V2 supplies fighting-game context and consumes a produced broadcast. The
unifying invariant is the rollback boundary.

### The off-rollback boundary

Every AI service stamps its output as gameplay-inert. The commentary plan's
`rollbackBoundary` literally sets `gameplayInertOutput: true`,
`feedsSimulationState: false`, `allowedOutputChannels: ['audio', 'subtitle']`,
and `rejectsRollbackFrameOrigin: true`; `requestV2AICommentaryCue` in
`apps/v2/iris-commentary-orchestration/src/v2-ai-commentary.ts` validates that a
cue is **never** called from inside a rollback frame (`fromRollbackFrame` is a
hard rejection). The translation, caption, lip-sync, face-animation, and ducking
bridges each carry the matching `mayInfluenceRollback: false` / `off-rollback-*`
policy. The one AI service that _does_ touch the deterministic path,
`@v2/psyche-ai-director-hints`, does it safely: in rollback-with-CPU modes it
samples a tendency vector at match load, serializes `tendency-vector + seed`
into the match-start input vector, and then runs rollback-deterministically with
**no further RPCs** — mid-match Psyche updates are queued for the next match
start.

### Real-time commentary

`requestV2AICommentaryCue` composes `createMatchCommentaryStream` from
`@iris/conversation-orchestration` in `off-rollback-only` determinism mode. The
headline number is a **800 ms KO-trigger latency budget**
(`V2_AI_COMMENTARY_KO_TRIGGER_LATENCY_BUDGET_MS = 800`), and
`buildV2AICommentaryLatencyBudget` splits it across the Iris LLM round trip (420
ms), persona TTS render (240 ms), Psyche lip-sync render (100 ms), and a 40 ms
safety margin — and the validator refuses a request whose sub-budgets don't fit
inside the total. When the envelope is missed, the client falls back to a
pre-recorded bank line keyed by the deterministic tuple
`(cueKind, ruleset, commentatorId, seed)`, so a slow generation never leaves
dead air. Streams are scoped
`local-peer | host-peer-canonical | broadcast-canonical`. The commentator roster
itself is validated by `@v2/calliope-commentator-personas`, which loads
`commentator-personas.json` and verifies every persona has cleared `@iris/voice`
clone metadata, signed talent approval, brand metadata, and deterministic
fallback-bank metadata before exposing the Iris commentator ids the orchestrator
uses.

### Post-match experience

`buildV2AIPostMatchExperiencePlan` (section `135`) assembles the after-match
surface. The highlight reel is a **real selection**: candidates are sorted by
score descending (ties broken by earliest frame) and the top five taken, the
plan requiring all five moment kinds — `longest-combo`, `counter-hit-punish`,
`power-play`, `dramatic-comeback`, `ko` — and emitting `mp4`, `gif`, and
`vertical-9:16` share formats with trim/filter/music/caption controls. The
analysis screen pins six panels (damage-by-move, combo breakdown, meter usage,
corner-pressure win rate, mistake-frame timeline, matchup-specific advice) plus
a rolling 10-match strength/weakness summary, and the auto-clip library tags an
AI-suggested caption and title. Every output carries the compliance block:
`machineGeneratedLabel: true`, a per-output opt-out, an EU AI Act
cross-reference (`80.4`), and `manualTrainingDataReview: true` — and post-launch
procedural fighter dialogue is flagged `manualReviewRequired` /
`signedOffBeforeDeployment`, so generation accelerates authoring but never ships
an unreviewed line.

### Translation, captions, face & mix

The rest of the chain makes the broadcast multilingual and accessible.
`buildV2IrisRealtimeTranslationSession` (`@v2/iris-realtime-translation`)
composes `@iris/voice` to translate **spectator chat and commentary** across
four surfaces (spectator-chat, commentary-localization, broadcast-overlay,
companion second-screen), registering per-locale receiver participants and
reporting per-delivery success/fail counts with honest reason codes when a
provider returns failures. `@v2/iris-accessibility` owns the accessibility
semantics and, until Iris owns live captions end to end, drives the real-time
caption engine through `@psyche/caption-streaming` (bottom-center, low-latency,
speaker-aware). `@v2/isis-commentary-lipsync-pipeline` (composing
`@isis/visual-dubbing`) and `@v2/psyche-commentary-face-animation` (composing
`@psyche/avatar-lipsync` + `@psyche/avatar-expressions`) turn commentary audio
into a lip-synced, ARKit-curved caster face, and
`@v2/euterpe-commentary-ducking` (composing `@euterpe/accompany` +
`@euterpe/master`) sidechains the music bus so the VO sits properly in the mix.
Each of these is independently droppable — if the face-animation provider is
absent, the audio/subtitle cue still ships.

## How it connects

These surfaces are the connective tissue between the fight and the player's life
around it. The galleries moderate and sell the cosmetics, CAWs, and arenas
authored in
[./relationships-progression-and-creator-suite.md](./relationships-progression-and-creator-suite.md);
the storefront's PPP ledger and the battle-pass/DLC economy are two halves of
one monetization story, the other half of which — seasons, the battle pass,
Twitch drops, and the read-only companion app — lives in
[./live-service-dlc-battle-pass-and-companion.md](./live-service-dlc-battle-pass-and-companion.md).
The AI broadcast chain feeds the esports/spectator surfaces and the
director-cam, and its full substrate topology (Iris/Isis/Psyche/Euterpe/Nous) is
the subject of the architecture companion
[../architecture/esports-companion-and-ai-services.md](../architecture/esports-companion-and-ai-services.md),
while the store, economy, and community-governance plumbing is detailed in
[../architecture/live-ops-store-progression-and-community.md](../architecture/live-ops-store-progression-and-community.md).
The one constant across all of it: off-rollback, gameplay-inert, audited. The
section hub is [../V2_features.md](../V2_features.md).

## Related

- The feature hub: [../V2_features.md](../V2_features.md)
- [Live Service, DLC, Battle Pass & Companion](./live-service-dlc-battle-pass-and-companion.md)
  — the seasons, battle pass, Twitch drops, and read-only companion that share
  this group's economy and community spine
- [Relationships, Progression & Creator Suite](./relationships-progression-and-creator-suite.md)
  — the UGC and cosmetics the galleries here moderate and the storefront sells
- [Esports, Companion & AI Services](../architecture/esports-companion-and-ai-services.md)
  — the architecture-side AI broadcast chain and substrate topology
- [Live-Ops, Store, Progression & Community](../architecture/live-ops-store-progression-and-community.md)
  — the store, economy, and Kuanyin/Themis governance plumbing
