# V5 Remediation — 2026-06-12

Follow-up to the completion-state audit in
`V5/docs/audit/v5-verification-2026-05-31.md`. That audit reverted 195
fabricated `[x]` marks but deferred several artifacts and task groups for
per-item judgment. This pass corrects the two remaining fabricated-attestation
artifacts (the launch-readiness manifest and the self-authored vendor
contracts), makes the validators that codified those fabrications fail-closed,
replaces the hardcoded always-healthy service reporting with honest
dependency-backed health, and finishes the deferred per-task re-marks in
`V5_TODOS.md`.

Checkbox movement in `V5_TODOS.md`: **905 `[x]` / 0 `[~]` / 194 `[ ]`** before →
**875 `[x]` / 8 `[~]` / 216 `[ ]`** after (30 marks corrected: 22 → `[ ]`, 8 →
`[~]`; zero marks were promoted to `[x]`). Every re-mark carries an inline dated
reason.

## 1. Launch-readiness manifest — fabrication removed

`V5/release/launch-readiness-manifest.json` previously asserted a shippable
game: 17/17 blocking gates passed, `releaseBlocked: false`, 5 cells complete, 23
advertised modes complete and non-skeleton, 16 language packs locked with QA
passes, 9 platform certifications passed, all compliance flows tested, a 99.72%
crash-free rate over 125,000 PS5 sessions, green feel-test nightlies, a zero-hit
stub scan, passing packet-loss runs, 6 matchmaking regions validated, a passed
external accessibility audit, and passed legal/privacy/ratings reviews. None of
that ever happened — there is no packaged game, no platform hardware, no
sessions, no nightly pipeline, and no external engagements.

Corrected to the honest state (`schemaVersion` 1 → 2, with a dated
`correctionNote`):

- `summary`: `passedGates` 17 → **0**, `releaseBlocked` false → **true**,
  `cellsComplete` 5 → 0, `advertisedModesComplete` 23 → 0, `languagePacksLocked`
  16 → 0, `platformsCertPassed` 9 → 0.
- `greenBuildId` → `null`; all 17 gates `passed` → `pending`.
- Cells/modes: `shipState` → `pending`; modes honestly report
  `skeletonMode: true` (all 29 `V5Mode_*` plugins register no modules — audit
  category 5); unverifiable booleans → `null`.
- Platforms: every `certPassed` → `false`, `memoryWithinBudget`/
  `certEvidencePath` → `null`.
- Fabricated observations → `null`: crash-free rate/cohort, feel-test build id,
  packet-loss passes, memory budget, matchmaking simulated pings.
- `adversarialStubScan.zeroHits` → `false` (the 05-31 audit found hits).
- `accessibilityAudit.externalConsultant`: invented vendor → `[VENDOR TBD]`,
  `passed` → `null`; compliance reviews → `null`.
- Matchmaking gate title corrected from "simulated ping over 80 ms" to
  "simulated ping of up to 80 ms" (a >80 ms validation criterion was backwards;
  matchmaking must be validated at pings up to the 80 ms budget).

`V5/tools/release/validate-launch-readiness.py` was rewritten in step: it
previously **required** the fabricated values (e.g.
`require(summary["releaseBlocked"] is False)`). It now validates internal
consistency of the honest state (summary counters must equal what the
per-section rows actually say) and **fails closed**: a gate may only claim
`passed` with real backing observations and on-disk evidence, and
`releaseBlocked: false` requires every blocking gate passed plus a real green
build id. Run output: `0/17 gates passed, releaseBlocked=True` — exit 0.

`V5/ue/Source/V5Tests/Private/Tests/V5TestsAutomation.cpp`
(`FV5LaunchReadinessManifestTest`) was corrected the same way: it had hardcoded
the fabricated expectations (17/17, not blocked, 9 cert passes); it now asserts
schema v2 and the same summary-vs-rows consistency and fail-closed rules. Cell
coverage assertions remain at the 5 launch cells, consistent with the cell-count
glossary note below.

## 2. Legal contracts and engagements — invented counterparty removed

The four documents under `V5/legal/contracts/` (a11y SOW, NDA, DPA, and the
IP-clearance SOW) presented themselves as executed contracts with "AccessForge
Accessibility Audit Cooperative" (an invented vendor) and "external IP-clearance
counsel" (never engaged). All four now carry a
`DRAFT TEMPLATE — no external engagement executed; counterparty TBD` header, a
dated correction blockquote, `[VENDOR TBD]` counterparties, and
`[DATE TBD upon execution]` dates.

- `V5/legal/accessibility-consultant-engagement.json`: `status` `completed` →
  `not_engaged`; all dates and `auditOutcome` fields → `null`; release gate
  fail-closed (`signedAuditReceived: false`,
  `releaseBlockedUntilSignedReport: true`); dated `correctionNote`.
- `V5/legal/ip-clearance-manifest.json`: `legalTeam.status` `engaged` →
  `template-drafted-not-engaged`; `correctionNote` records that the
  clearance-bucket dispositions are internal self-reviews (backed by the
  validator's banned-term scans), not external legal clearance.
- `V5/docs/accessibility/external-consultant-audit.md`: status → DRAFT TEMPLATE;
  added a note that `UV5_Accessibility_QA::BuildExternalAuditEngagement`'s
  `Status = Engaged` / `bStatementOfWorkExecuted` / `bConsultantOnboarded`
  fields are hardcoded struct defaults (audit category 2) and must not be read
  as evidence that a consultant exists.
- `V5/tools/legal/validate-ip-clearance.py`: previously required
  `status == "engaged"`, codifying the fabricated engagement. Now fail-closed:
  while the SOW on disk is a draft template (`DRAFT TEMPLATE` / `[VENDOR TBD]`),
  the manifest must report `template-drafted-not-engaged`; `engaged` is only
  accepted once an executed SOW exists. Run: passes against the honest state.

`V5_TODOS.md` already had §82 (legal/IP clearance) and §72's "Engage external
accessibility consultant" reverted to `[ ]` by the 05-31 audit; no remaining
`[x]` claims an executed external audit or contract (verified by scan).

## 3. Online services — honest health reporting (fail-loud seam)

The 05-31 audit found that every production `service.ts` hardcoded
`serviceHealthy: true`, making the 503 outage contract dead code in production —
fabricated always-healthy reporting for services with no backing infrastructure.

- `apps/v5/service-shared/src/runtime.ts` + `types.ts`: added
  `BackingDependencyStatus`, `resolveBackingDependencies()` (checks the
  catalog-declared env var for each declared dependency — Postgres, Redis, and
  optionally ClickHouse / the EAC signing key), and `resolveServiceHealthy()`.
  `buildHealth()` now reports `status: 'ok' | 'not_configured'` with
  per-dependency detail instead of a hardcoded `'ok'`. A service with no
  configured backing now honestly serves the 503 outage contract (fail loud)
  rather than fabricating success.
- All 16 `apps/v5/*/src/service.ts`: `serviceHealthy: true` →
  `serviceHealthy: resolveServiceHealthy(serviceDefinition)`. The only remaining
  `serviceHealthy: true/false` literals are in the contract-test harness
  (`executeContractCase`), which deliberately exercises both branches — a test
  double at the dependency boundary, not production fabrication.
- `service-shared/dist` rebuilt. All 17 vitest suites pass without installs (run
  with the repo-root vitest binary): service-shared 17 tests + 16 service
  contract suites, all green.

## 4. V5_TODOS.md re-marks (each individually verified, inline dated reasons)

- **§71 Online Services Backend**: the 16 "Implement `apps/v5/<x>`" rows were
  `[x]` on the strength of 16 byte-identical wrappers over one shared runtime
  (audit category 6). 14 → `[ ]`; `anti-cheat` and `compliance-dsar` → `[~]`
  (their signal-detection / DSAR-CCPA-DSA-COPPA rule logic in the shared runtime
  is audit-verified real, but no vendor integration, storage, or fulfillment
  exists). "Multi-region failover" → `[~]` (k8s manifests exist; nothing is
  deployed, so nothing can fail over). Kept `[x]`: per-service Docker images,
  Kubernetes deployment manifests, and contract tests — verified individually:
  real per-service multi-stage Dockerfiles (correct ports/package filters), real
  Deployment/Service/failover YAML, and real passing per-service vitest contract
  suites.
- **§74/§75/§76**: companion-app-dependent bullets (DSAR via companion app,
  appeal flow via companion app, save export/import via companion app) → `[ ]` —
  no buildable companion app exists (§78, audit category 7).
- **§78 Companion App**: web-companion bullets → `[~]` (a real Next.js page +
  content lib + tests exist in `apps/v5/web` but render static fixtures with no
  account-linked state); push notifications / DSAR export / appeal flow → `[ ]`
  (no transport or flows on any surface).
- **§123 / §142**: companion Mind Palace editor and AR mode → `[ ]` (same §78
  basis).
- **§90**: "(sim ping > 80ms)" → "(sim ping up to 80 ms)" (criterion was
  backwards).
- **Banner** (top of file): extended with a dated line pointing at this
  remediation log.

Verified as already honest — no action needed:

- Audit category 4 synthetic content: "Author 30,000+ animation clips" (§33),
  "Author 60000 lines of VO" (§59), 12,000 dialogue nodes (§11), 1,200
  talk-radio lines (§28/§49), 3,000+ generic NPCs (§87), §88 mission rows — all
  already `[ ]` from the 05-31 audit disposition.
- §42 "Implement `UV5_Online_AuthService` (OAuth + JWT)" stays `[x]`: the
  audit's "fake `jwt.v5.*` template" finding was fixed post-audit by commit
  `e0f0e344a3` (real FIPS 180-4 SHA-256 / RFC 2104 HMAC / RFC 7519 HS256 / RFC
  7636 PKCE in `V5JwtCrypto.{h,cpp}`, verified against published reference
  vectors on the on-box UE 5.5.4). All other §42 client bullets remain `[ ]` (no
  network I/O).

## 5. Documentation corrections (features / architecture)

- **Cell-count clarity**: both subsystem glossaries (`V5_features.md`,
  `V5_ARCHITECTURE.md`) now state that V5 ships **5 launch ruleset cells** while
  the code's `EV5Cell` enum carries **7** values (5 launch + `Steampunk` DLC
  cell [P3, §139] + the cross-cell `MindPalace` meta-layer), and that per-cell
  datasets/tests must size against `GetAllV5Cells()` (7) — the 2026-05-31 audit
  traced 4 automation failures to exactly this mismatch.
- **Marketplace phase**: the paid-mod "Modder Marketplace" passages in
  `V5_features.md` (Workshop & Mods) and `V5_ARCHITECTURE.md` (Live-Service &
  DLC; Creator Suite) were labeled "Year-1"; re-labeled **[P3] Full-Vision
  Stretch (post-Year-1)** per `V5_TODOS.md` §138, the phase source of truth
  (manifest filename retained as historical).
- **Companion-app honesty**: the `V5_features.md` companion-app section now
  carries a dated status note: `V5/companion/` holds design-token mockups only
  (one static `.swift`, one static `.kt`; no Xcode project, `Package.swift`,
  `build.gradle`, or `AndroidManifest.xml`), and the web companion renders
  static fixtures.

## 6. Docs validator — qualified §-reference support

`V5/tools/validate-v5-docs.py` failed on the committed (separate-effort)
decision doc `V5/docs/decisions/0020-server-binary-distribution.md`, which
references `V1_V7_PLAN_SET_AUDIT_2026-06-12 §6.2` and
`` `V5/docs/planning/capacity-and-load-plan.md` (§2.2) `` — references
explicitly qualified by another document, which the validator misread as
(nonexistent) `V5_TODOS.md` sections. Rather than editing that doc, the
validator now resolves a §-reference qualified by an immediately preceding
document identifier (backticked path or bare doc name that resolves to a real
`.md` file) against **that document's** numbered headings — and still fails
closed when the section does not exist there (verified: `§99.9` /`§77.7` against
real docs flag; unqualified behavior unchanged). Both 0020 references verify
against real sections in their target docs.

## 7. Verification record (2026-06-12)

- `python3 V5/tools/validate-v5-docs.py` → `V5 docs validation passed` (exit 0)
- `python3 V5/tools/validate-cells.py` → `V5 cell validation passed` (exit 0)
- `python3 V5/tools/legal/validate-ip-clearance.py` →
  `V5 IP clearance validation passed` (exit 0)
- `python3 V5/tools/release/validate-launch-readiness.py` →
  `V5 launch readiness validation passed: 0/17 gates passed, releaseBlocked=True`
  (exit 0)
- Vitest (no installs; repo-root binary): 17/17 suites green — `service-shared`
  (17 tests) and all 16 service contract suites.
- All touched JSON files parse (`launch-readiness-manifest.json`,
  `accessibility-consultant-engagement.json`, `ip-clearance-manifest.json`).
- `git diff` over `V5_TODOS.md` introduces zero new `[x]` marks.

Out of scope here (unchanged): `V5/docs/planning/*` and
`V5/docs/decisions/0020-*` (separate completed effort); UE builds, package
installs, and Playwright runs (not run per remediation constraints).
