# V2 Autonomous Content Agents — Verification Audit — 2026-07-13

**Question audited:** are all the agents that autonomously create content for
`V2/` SOTA and production-ready?

**Method:** main-loop verification (no agent fan-out, per session limits).
Inventory was drawn from `V2/architecture/esports-companion-and-ai-services.md`
and `V2/features/community-store-support-and-ai-services.md`, then every unit
was read in current source, the mandatory adversarial stub grep battery plus the
silent-stub scan was run over all of it, delegation chains were followed into
the shared substrates (`@iris/conversation-orchestration`,
`@iris/conversation-providers-anthropic`, `@psyche/avatar-lipsync`,
`@iris/voice` call-translation, `@hathor/llm-npc`, `@isis/visual-dubbing`), and
every suite plus `tsc --noEmit` was executed on this box today.

## Verdict

**Yes at the code level, with the same honestly-drawn deploy boundary the
architecture docs themselves declare — after this session closed one real
fail-silent defect.** The V2 autonomous content plane is real, adversarially
clean, rollback-sealed in both TypeScript and C++, and fully green in tests and
typecheck. One genuine fabrication path was found and fixed (the realtime
translation bridge accepted the `@iris/voice` `local_default` passthrough
provider, which invents bracket-tagged pseudo-translations with a fake 0.7
confidence, and reported them as successful deliveries). Everything else absent
is a named, fail-loud seam: provider credentials, plan→executor bindings, and
the spec-only gRPC tier.

## 1. The agent inventory (what "the agents" are)

| Layer                 | System                                                                                                                         | Role                                                                                                                        |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| Commentary generation | `@v2/iris-commentary-orchestration` → `@iris/conversation-orchestration` → `@iris/conversation-providers-anthropic` / `-local` | cue plans with 420/240/100/40 ms budget decomposition, rollback-frame rejection, deterministic pre-recorded fallback bank   |
| Personas & voice      | `@v2/calliope-commentator-personas` + `commentator-personas.json` manifest                                                     | 4-artist launch roster; voice-clone clearance, consent/likeness license ids, talent signoff, AI disclosure — all cook-gated |
| Render bridges        | `isis-commentary-lipsync-pipeline`, `psyche-commentary-face-animation`, `euterpe-commentary-ducking`                           | phoneme→viseme frames with coarticulation (computed in-process), −18 LUFS sidechain ducking math, ≤45 ms drift contract     |
| Localization & a11y   | `iris-realtime-translation`, `iris-accessibility`, `psyche-caption-streaming`                                                  | provider-gated chat/commentary translation; caption engine channel plans per surface; cert-gate-blocking a11y bridge        |
| AI Director           | `@v2/psyche-ai-director-hints` + `V2/ue/Plugins/V2AdaptiveAI`                                                                  | first-order-Markov tendency hints off-rollback only; hashed match-start snapshot vector as the sole rollback-legal input    |
| In-engine contracts   | `V2/ue/Plugins/V2AICommentary`                                                                                                 | C++ cue/post-match contracts mirroring the TS budgets, with `IsValidContract` failure reasons and off-rollback flags        |
| Asset generation      | `isis-cosmetic-pipeline`, `isis-venue-capture-pipeline`                                                                        | model-gen/AI-texturing/rigging/bellona-cook plan contracts; generated-asset payloads demand real URIs + content hashes      |
| NPC dialogue          | `hathor-npc-adapter` → `@hathor/llm-npc`                                                                                       | encounter/dialogue/behavior/bark hooks over a provider chain (circuit breaker, ACE/Inworld/Convai), file dialogue cache     |
| Post-match & news     | `buildV2AIPostMatchExperiencePlan` + `@v2/esports-tools` (`@veritas/fact-checking`)                                            | top-3–5 highlight selection over required moment kinds; claims→evidence→consensus verification that holds publication       |
| Authored delivery     | `patch-notes-service`, `message-of-the-day-service`, `live-event-content-delivery-service`                                     | human-authored content with real targeting/normalization/etag logic — delivery services by design, not generators           |

## 2. Verified in current source (this session)

- **The rollback envelope is enforced, not described.** TS: `fromRollbackFrame`
  is rejected by both the V2 cue validator and the Iris stream validator;
  `assertValidLiveRequest` throws on any live hint under rollback; snapshots
  serialize a sorted-key JSON vector with a real `sha256` hash. C++:
  `EvaluateAIDirectorDecision` hard-falls to the static rule-of-the-day for
  ranked/tournament/multiplayer/opt-out before consulting any profile;
  `FV2AICommentaryCueContract::IsValidContract` rejects non-Calliope
  commentators, missing fallback seeds, and non-Iris package bindings.
- **Fallback is deterministic, labeled, and never fabricated as success.** The
  commentary stream returns `source: 'pre-recorded-bank'` plus an explicit
  `fallbackReason` (`missing-orchestrator` / `latency-budget-exceeded` /
  `empty-response` / `error`), selected by a stable hash over
  `(cueKind,ruleset,commentatorId,seed)` under a `Promise.race` latency budget.
- **The generation core is a real provider chain.** The orchestrator seam
  reaches `@iris/conversation-providers-anthropic` (shared LLM service over an
  OpenRouter-compatible HTTP client with typed errors) with
  `@iris/conversation-providers-local` as the on-cap route; `@hathor/llm-npc`
  ships a provider chain with circuit breakers, latency tracking, and fail-loud
  `not configured` errors for ACE/Inworld/Convai.
- **The render math is computed, not asserted.** Face animation invokes
  `createPhonemeSequence → phonemeSequenceToVisemes → generateLipSyncFrames`
  (3.6k-line substrate with real coarticulation blending) in-process; ducking
  computes intensity-based gain with density and loudness compensation — the
  spec now pins the hand-checked value (climax −10, density −1.5, loudness −3 →
  **−14.5 dB**, linear 10^(−14.5/20) ≈ 0.18837).
- **Persona governance is cook-blocking.**
  `assertV2CommentatorPersonasReadyForCook` rejects revoked voice clones and
  missing signoff scopes; the manifest carries consent ids, likeness licenses,
  similarity thresholds, watermarking and abuse monitoring flags per artist.

## 3. Defects found this session (all fixed in this commit)

1. **HIGH — silent pseudo-translation path** (`iris-realtime-translation.ts`):
   the bridge's provider argument was optional; omitting it silently engaged the
   `@iris/voice` `local_default` passthrough, which returns `[lang] text` with a
   fabricated 0.7 confidence as a _successful_ delivery — invisible to the
   session's reason codes, and the specs always injected a mock so tests never
   saw it. **Fix:** provider is now required (`V2IrisRealtimeTranslationError`,
   code `missing_translation_provider`), and any `local_default` delivery is
   flagged with an explicit reason code. Two regression tests added.
2. **LOW — cwd-dependent test** (`calliope-commentator-personas`): the spec
   resolved the repo-root-relative manifest against `process.cwd()`, so the
   suite failed 0/4 when run from the service directory. Fixed with an
   `import.meta.url` repo-root anchor.
3. **LOW — un-runnable fact-checking suite** (`V2/tools/esports`): the vitest
   alias map lacked `@oshun/ai`, whose package entry points at an unbuilt
   `dist/`, so `veritas-esports-fact-checking.spec.ts` failed at import. Fixed
   by aliasing `@oshun/ai` to source; 3/3 suites now green.
4. **LOW — under-pinned assertion** (`euterpe-commentary-ducking` spec): gain
   assertions were range-only (a hardcoded −7 would have passed); now pinned to
   the known-correct −14.5 dB / linear value.

## 4. Adversarial stub scan — zero actionable hits

The mandatory grep battery (excuse comments, placeholder/TODO/dummy/fake
vocabulary) returned **zero hits** across all 15 services plus
`V2/tools/esports`. The silent-stub scan (Math.random in deterministic paths,
fabricated-success catch blocks, ignored `_`-params) surfaced only honest code:
typed error rethrows in the NPC bridge, ENOENT→cache-miss in the dialogue cache,
URL-validation throws in MOTD, and a hostname fallback in fact-checking. The one
genuine fail-silent path found (translation `local_default`) is fixed above.

## 5. Test + typecheck evidence (executed on this box, 2026-07-13)

| Suite                                           | Result                                    |
| ----------------------------------------------- | ----------------------------------------- |
| `@v2/iris-commentary-orchestration`             | 9/9                                       |
| `@iris/conversation-orchestration` (substrate)  | 114/114                                   |
| `@v2/calliope-commentator-personas`             | 4/4 (was 0/4 from service dir)            |
| `@v2/isis-commentary-lipsync-pipeline`          | 3/3                                       |
| `@v2/psyche-commentary-face-animation`          | 4/4                                       |
| `@v2/euterpe-commentary-ducking`                | 5/5 (exact-value pinned)                  |
| `@v2/iris-realtime-translation`                 | 5/5 (2 new guards)                        |
| `@v2/iris-accessibility`                        | 2/2                                       |
| `@v2/psyche-caption-streaming`                  | 3/3                                       |
| `@v2/psyche-ai-director-hints`                  | 4/4                                       |
| `@v2/hathor-npc-adapter`                        | 6/6                                       |
| `@v2/isis-cosmetic-pipeline`                    | 4/4                                       |
| `@v2/isis-venue-capture-pipeline`               | 3/3                                       |
| `@v2/patch-notes-service`                       | 3/3                                       |
| `@v2/message-of-the-day-service`                | 4/4                                       |
| `@v2/live-event-content-delivery-service`       | 3/3                                       |
| `@v2/esports-tools`                             | 7/7 (fact-checking suite was un-runnable) |
| `tsc --noEmit`, all 15 services + esports tools | exit 0 everywhere                         |

## 6. The honest boundary (what "prod ready" does NOT include)

These are deliberately drawn seams, all fail-loud, most declared by the
architecture docs themselves:

1. **Generation providers are deploy-bound.** Live commentary text, persona TTS,
   and face rendering come from the provider tier (per `deps§67`: Anthropic
   Claude for play-by-play, ElevenLabs for TTS, Isis `ai-video` for auto-edit).
   Absent credentials, the plane degrades to the deterministic fallback bank or
   silence with explicit `fallbackReason` — never fabricated output.
2. **The gRPC wire tier — CLOSED 2026-07-14.** The three AI-services contracts
   now ship at `libs/proto/src/oshun/v2/{esports,director,ai_commentary}/` with
   `@v2/grpc-services` binding them to the real engines (veritas fact-checked
   Crown Points credit, rollback-rejecting Director, fallback- labeled
   Commentary streaming); 16 in-process round-trip tests. The other V2 proto
   packages (online, live, progression, community, racing) remain designed-only.
3. **Isis plan→executor binding is a named seam.** The lipsync, cosmetic, and
   venue-capture packages are plan contracts: plans never claim rendered output,
   and rendered/generated payload builders demand a real asset id, URI, and
   content hash. The dubbing/texturing engines exist as substrates
   (`@isis/visual-dubbing` et al.); the dispatch wiring is the deploy step.
4. **UE C++ verified by source-read only on this box** (no UE toolchain on this
   Mac; the compiled UE 5.5 build lives on the Linux sandbox). The TS mirrors of
   the same contracts are fully test-executed.
5. **Editorial content stays human-authored by policy.** MOTD, patch notes,
   community spotlights, and procedural fighter dialogue
   (`seasonScope: 'post-launch-dlc'`, `manualReviewRequired: true`) are
   delivery-plane, not autonomous generation — matching the EU AI Act disclosure
   posture (`"AI commentary is machine-generated presentation content."`,
   cross-ref §80.4).

## 7. Bottom line

- **SOTA:** yes — the V2 plane composes the same substrate stack the V1 audit
  verified as SOTA, and adds the parts that are genuinely hard in a fighting
  game: a rollback envelope sealed in both languages, a real-time latency budget
  with a deterministic provider-free fallback bank, cook-blocking voice and
  likeness governance, and post-match publication held behind
  claims-vs-replay-hash fact checking.
- **Prod-ready:** yes at the library + wiring level — every unit compiles,
  typechecks, and passes its suites today; zero result-faking stubs remain (the
  one found was fixed and regression-tested this session); every absent
  capability is an explicit fail-loud seam owned by a named deploy step.
