# V2 gRPC Services

`@v2/grpc-services` binds the three V2 AI-services wire contracts under
`libs/proto/src/oshun/v2/` onto one `@grpc/grpc-js` server:

- **`oshun.v2.esports.Esports`** — `RegisterEvent`, `SubmitResult`,
  `GetBracket`, `QualifyForFinals`. Results are replay-hash fact-checked through
  `@veritas/fact-checking` (via `@v2/esports-tools`) before any Crown Points
  credit (`calculateMaatV2CrownPoints` from `@maat/strategy`, round progression
  50 → 800); a winner-record conflict is held for review and never credits.
- **`oshun.v2.director.Director`** — `GetSessionState`, `GetMatchStartSnapshot`,
  `QueueMidMatchUpdate`, backed by `@v2/psyche-ai-director-hints`. The pacing
  decision mirrors `UV2AdaptiveAIBlueprintLibrary::EvaluateAIDirectorDecision`:
  ranked, tournament, multiplayer, or opted-out sessions hard-disable the
  Director. Live hints under rollback are rejected with `FAILED_PRECONDITION`;
  the only rollback-legal output is the hashed match-start snapshot vector.
- **`oshun.v2.ai_commentary.Commentary`** — `RequestCue` and bidirectional
  `StreamCommentary`, backed by `@v2/iris-commentary-orchestration`. Cues
  originating inside a rollback frame are rejected; on provider absence or
  budget miss the cue resolves through the deterministic pre-recorded bank and
  is labeled with an explicit fallback reason — never fabricated as generated.

The generation orchestrator is an injected seam
(`options.commentary.orchestrator`); without it every cue is an honestly-labeled
fallback. The esports event store is process-lifetime in-memory per the house
store pattern; durable persistence belongs to the deploy tier hosting the
server.

Everything served here is off-rollback by contract and can never perturb the
deterministic match simulation.
