# V4 Autonomous Content Agents — Audit (2026-07-14)

Audit of every system in `V4/` that autonomously creates player-facing content,
following the same method and severity bar as the V2 (2026-07-13) and V3
(2026-07-14) autonomous-content audits: read every public function and the
private functions they delegate to, run the adversarial stub-indicator scan,
check that quality/consent/review gates can actually fail, and verify test
coherence (a test that passes against a fabrication is itself a finding).

## Scope — what "autonomous content agent" means in V4

V4 is the multi-cell UE5 game. Its autonomous content surface is:

| System                                     | Location                                                                 | Role                                                                                      |
| ------------------------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| AI-generated end-of-match commentary (§93) | `V4/ue/Plugins/V4Mode_Replay` — `UV4AIGeneratedCommentaryPipeline`       | Personas, highlight reels, mistake/went-well callouts, Psyche voice request               |
| AI commentary extended (§137)              | same class                                                               | Personal voice-clone consent, post-season AI podcasts, native-speaker localization review |
| Live spectator AI commentary (§111)        | `V4/ue/Plugins/V4Mode_Spectator` — `UV4LiveAICommentaryBroadcastService` | Two-host live broadcast lines, 12 VO languages, bias-review policy                        |
| AI Director                                | `V4/ue/Source/V4Gameplay` — `UV4AIDirectorSubsystem`                     | Adaptive PvE difficulty (pressure model, calibration, rubber-band rejection)              |
| Procedural generation                      | `V4/ue/Source/V4Procgen` — `UV4ProcgenSubsystem`                         | Seeded mission layouts, chunk library, daily seeds                                        |
| Roguelike campaign generation              | `V4/ue/Plugins/V4Mode_Roguelike_TacticalCampaign`                        | Run/boon/boss/meta-progression state over procgen                                         |
| Ambient content                            | `V4/ue/Source/V4Crowd`, `V4/ue/Source/V4Schedules`                       | Crowd tiers/flee assignments, NPC schedules                                               |
| Compliance/provenance gates                | `V4/ue/Source/V4OnlineServices` — `UV4ComplianceSubsystem`               | DPIAs, region flags, replay scrub, AI-content disclosure policy                           |

Out of scope: Workshop/Contracts-Author editors (user-generated content tools,
not autonomous), web CMS content, esports tooling.

## Verdict

**Generation logic: real and strong. Trust claims: were fabricated in the two
commentary pipelines — now fixed fail-loud.** The AI Director, Procgen,
roguelike campaign, crowd, and schedule systems are genuine domain code with
tests that assert exact values and gates that can fail. The commentary pipelines
had the same fabrication class the V2/V3 audits found elsewhere:
consent/review/watermark/queue claims manufactured from policy constants instead
of evidence. As in V3, everything that "generates" prose/audio is either honest
deterministic template logic (now labeled as such) or a provider seam
(Calliope/Psyche) that is planned but not executed in-engine — V4 is NOT a SOTA
autonomous _generator_ end-to-end; it is a well-built orchestration/gating layer
around declared provider seams.

## HIGH findings (fixed this audit)

### H1 — Spectator live commentary fabricated bias review + watermark

`UV4LiveAICommentaryBroadcastService::GenerateLiveCommentaryLines` set
`bBiasReviewed` from the _policy's own constants_
(`bReviewPlayerGender && bReviewPlayerRegion && ...` — always true),
`bWatermarked = true` unconditionally (no watermark exists), and derived
`bReadyForBroadcast` from both — so every generated line claimed human bias
review and provenance watermarking that never happened, while the policy itself
declares `bBlockUnreviewedBroadcast = true`. The struct default
`bWatermarked = true` was fail-open. `SpectatorModeSpec` asserted the fabricated
flags.

**Fix (fail-closed evidence seams):** generated lines now start
`bBiasReviewed = false`, `bWatermarked = false`, `bReadyForBroadcast = false`
(struct default flipped too). New `FV4LiveCommentaryBiasReviewRecord` and
`FV4LiveCommentaryWatermarkReceipt` types carry evidence; `ApplyBiasReview`
accepts a record only from a queue in `Policy.ReviewerQueueIds`, with a named
reviewer, all policy-required dimensions reviewed, and an explicit approval;
`ApplyWatermarkReceipt` requires watermark + provenance-manifest ids bound to
the line; `IsLineReadyForBroadcast` blocks unreviewed output whenever
`bBlockUnreviewedBroadcast` is set. Spec rewritten: unreviewed lines blocked,
approved-review + watermark → ready, unapproved/wrong-queue/anonymous records
rejected, watermark-without-review still blocked.

### H2 — Replay end-of-match commentary fabricated generation/queue/consent claims

`UV4AIGeneratedCommentaryPipeline::GenerateEndOfMatchCommentary` returned
`bCalliopeGenerated = true` (no Calliope stack was invoked — the script is
deterministic template text), `bPsycheSynthesisQueued = true` (nothing was
queued; the method is `BlueprintPure`), `bShareable = true`, and
`PsycheVoiceRequest.bConsentChecked` _defaulted to true_ in the struct — a
fail-open consent claim for AI voice synthesis. `ReplayModeSpec` asserted the
fabricated flags ("End-of-match commentary is Calliope-generated", "Psyche voice
synthesis is queued").

**Fix:** new `EV4CommentaryGenerationMethod` records how the script was
produced; the pure generator now returns
`GenerationMethod = DeterministicTemplate`, `bCalliopeGenerated = false`,
`bPsycheSynthesisQueued = false`, `bShareable = false`.
`AttachCalliopeGeneratedScript` flips `bCalliopeGenerated` only with a Calliope
result bound to the request id, the `Calliope.V1.Commentary` stack, a named
model id, and one non-empty script per segment. `MarkPsycheSynthesisQueued`
flips queued/shareable only with a queue receipt (queue id + receipt id)
matching the voice request, and only when the consent gate was actually
evaluated. `bConsentChecked` struct default flipped to false; the generator
still sets it true because it genuinely evaluates the player opt-out before
building the voice request. Spec rewritten to drive the evidence paths
positively and negatively.

## MED findings (fixed this audit)

### M1 — Localization nuance "review plan" pre-approved itself

`V4MakeCommentaryLocalizationReview` built the 12-locale native-speaker review
plan with `bNuanceApproved = true` and `bNoProtectedTraitInference = true`
(struct defaults also true) — verdicts recorded before any native speaker looked
at anything, and `ValidateAICommentaryExtended` + `ReplayModeSpec` asserted the
pre-approval.

**Fix:** plan rows now start unapproved (`bNuanceApproved = false`,
`bNoProtectedTraitInference = false`, defaults flipped); new
`FV4NativeSpeakerNuanceApproval` + `RecordNativeSpeakerNuanceApproval` require a
matching review/locale, a named reviewer, and explicit
approved/no-protected-trait verdicts, and store `ApprovedByReviewerId`.
`ValidateAICommentaryExtended` now checks the plan is honestly pending AND that
the approval seam works (named reviewer flips it; anonymous approval is
rejected). Tests updated to the same shape.

## Findings verified as honest (no fix needed)

- **AI Director** — weighted pressure model (0.42 damage / 0.25 deaths / 0.20
  detection / 0.13 objective), deadband step resolution, percentile skill/parry
  calibration nudges, rubber-band perceptibility rejection (0.25 scalar / 120 ms
  / 1 parry-frame / 45 s caps), PvP hooks compile-disabled via `static_assert`
  over the mode policy table.
  `ValidateLaunchCoverage`/`ValidatePostLaunchRefinement` exercise behavior with
  contrasting performance windows — they can fail. Spec asserts exact steps,
  scalars, and reasons.
- **Procgen** — seeded (`FRandomStream(Seed + Attempt * 7919)`) constraint
  solver with bounded retries, BFS playability validation through
  spawn→objectives→extraction waypoints, blocker placement with rollback when it
  breaks the path, NPC-placement validation with duplicate/coverage checks,
  55-chunk launch library with per-cell constraint tags. Daily seed is
  server-dispatched; note the signature is only checked non-empty client-side
  (verification is a server-boundary concern).
- **Roguelike campaign** — real run-state machine (loadout commits, boon grants,
  boss defeats, meta-progression banking/spending, operator death) over real
  procgen layouts.
- **Crowd/Schedules** — relevance-sorted tier demotion under a measured Mass
  tick budget, exfil flee assignments with real distances; schedule assets and
  components are data-driven with validation.
- **Compliance subsystem** — authored policy-config (DPIA cards, jurisdiction
  notes, region feature flags, residency rules) with validators that check the
  config against jurisdictional requirements and can fail on edit. These are
  _declared_ policies — publishing them (legal portal URLs, annual refresh) is
  an external launch boundary, mirroring V3's honest-red pattern.
- **Podcast recap `bGenerated`** — kept: in the §137 manifest schema
  (`generatedPerCell`) this is an AI-generated-content _classification_ used for
  disclosure (paired with `bWatermarkRequired`/`bHumanReviewRequired`), not a
  claim that audio exists. `OutputAudio` is the planned target path, matching
  the manifest.

## What remains provider-/deploy-boundary (not locally closable)

- Actual Calliope (LLM) script generation and Psyche voice synthesis — the
  engine builds requests and now _refuses to claim_ their results without
  evidence; executing them requires the provider services.
- Real Trust & Safety / native-speaker review queues feeding the new evidence
  records.
- Watermark/provenance embedding in synthesized audio (receipt seam exists).
- The final-polish gate (`scripts/test/final-polish.test.mjs`) is honestly red
  on two pre-existing unchecked external-boundary TODOs (§56.13 voice SFU full
  implementation, §58.1 platform integrations) — unrelated to the content agents
  but part of the honest launch picture.

## Verification

- `node src/v4-ai-generated-commentary-check.mjs` — passed
- `node src/v4-ai-generated-commentary-extended-check.mjs` — passed
- `node src/v4-live-ai-commentary-check.mjs` — passed
- `node src/v4-ai-director-check.mjs --manifest ...DA_AIDirectorLaunch...` —
  passed
- `node src/v4-roguelike-adventure-check.mjs` — passed
- `node src/check-syntax.mjs` — passed (175 files)
- `node --test test/*.test.mjs` — 8/8 commentary/director suites pass; only
  pre-existing `final-polish` red (see above)
- UE C++ compile/automation run is not possible on this macOS box (engine build
  lives on the Linux box); the edits follow existing UE idioms in the same files
  and all repo-side verifier needles (class/method/test names) were kept intact.

## Adversarial scan record

Mandatory grep (stub-comment indicators, `--include` C++/C#) over `V4Procgen`,
`V4Gameplay`, `V4Cinematics`, `V4Crowd`, `V4Schedules`, `V4OnlineServices`,
`V4Mode_Replay`, `V4Mode_Spectator`, `V4Mode_Roguelike_TacticalCampaign`: **zero
actionable hits**. Silent-stub scan: no unseeded randomness in deterministic
paths (all `FRandomStream` seeded), no catch-and-fabricate blocks, no ignored
`_`-params; the constant-vs-constant gates found are exactly the H1/H2/M1 items
above, now evidence-gated.
