---
phase: 06.2-gap-closure-d-50-d-53-uat-2026-05-13
status: findings-captured
captured: 2026-05-13
operator: decidel
verdict: not approved
prior_cycle: 06.1-gap-closure-d-39-d-46-uat-2026-05-11
---

# Phase 06.2 — UAT Findings (cycle-3, 2026-05-13)

> Re-run of `06.1-HUMAN-UAT.md` after Phase 06.1 plans merged and deploy-staging
> redeployed staging on commit `bd93e7f`. Verdict: **not approved**. Findings
> below drive Phase 06.2 gap-closure scope.

<!-- [doc->REQ-CLI-08] [doc->REQ-CLI-04] [doc->REQ-CLI-06] [doc->REQ-CLI-07] -->

---

## Cycle-3 prior to UAT

Two deploy-blocking CI failures had to be fixed first before staging picked up Phase 06.1:

1. **prediction.test.ts stale assertions** — local vitest passed against a stale
   `packages/game-logic/dist/step.js` carrying the old `FRICTION=0.85` /
   accel/decay model. CI rebuilt `dist/` from source (BNO instant-set/stop
   model from Plan 06.1-02) and the cumulative-vx asserts (`mid.vx>0`,
   `vx ≈ mid.vx * 0.85`, `afterReplay.vx>0`) all failed. Fixed in commit
   `bd93e7f` — three asserts rewritten to match the instant-set contract.

2. **87 commits unpushed** — local `main` was 87 commits ahead of
   `origin/main`. `deploy-staging` workflow fires on `push:main`. No push =
   no redeploy. After push, deploy-staging actually shipped Phase 06.1.

These two are workflow-discipline gotchas, not Phase 06.1 code bugs.
Captured here for cycle-3 post-mortem; no Phase 06.2 plan required.

---

## Operator UAT verdict per test

### Test 1 — Alpha-keyed sprites (D-39 closure) — ✅ PASS

Sprite outlines clean on staging. No solid white box, no magenta halo.
06.1-test-1-alpha.png artifact captured.

### Test 2 — CLI-08 milestone — ❌ FAIL (compound)

Operator findings, verbatim:

1. **Ghost player remains after logout** — `uat_b` sprite continues to render
   in `uat_a`'s view even though `uat_b` is not logged in at all. Server
   does not drop the session on WS disconnect.
2. **No floor tiles or TSides visible** — D-40 visually unclosed on the
   deployed staging build. (Atlas frame `0023-Tile1_000` IS present in
   `/atlas-mvp.json` on staging — verified by curl. So the frame exists but
   `RoomRenderer` never spawns tile sprites for it. Likely `layout.tiles`
   empty or `tileset_sprite_id` mismatch on the wire.)
3. **Background animation OK** — `0064-BKA1` scrolls correctly.
4. **Two sprites at the local player position** — local + duplicate ghost
   `uat_a`. The ghost has a white (remote) nameplate and animates; the
   local one does NOT animate. Server allows two simultaneous sessions per
   account.
5. **Local sprite still does not animate** (carryover from 2026-05-11 UAT
   — D-41 was claimed closed by Plan 06.1-04 but the visual behavior is
   unchanged). Sprite frame freezes on stand; remote sprites animate
   correctly during their movement.
6. **Player position occasionally resets back to spawn** during normal
   movement. Possibly reconciler snap, server-side teleport, or auth-replay
   artifact.
7. **Chat still works** — bidirectional message round-trip OK.

### Test 3 — Anim rate consistency (D-41/D-42) — ⚠️ partial

Remote-vs-local cadence comparison impossible — local sprite never animates
(see Test 2.5). Remote-only observation: animation speed feels correct when
remote players are walking around.

### Test 4 — Camera + nameplate + Fixedsys (D-45/D-46) — ⚠️ partial

Camera behavior seems correct. Can't verify "no black void past room edge"
because there are no floor tiles to delimit the room edge.

- **Cannot verify Fixedsys font load** without DevTools dive (operator did
  not check Network panel; nameplate text rendered but typography hard to
  judge against alternatives).
- **D-45 reopened — nameplate Y too low** — nametag sits low enough to be
  overlapped by the player sprite head. Citation per CLAUDE.md: `text_y =
  sprite.y - 16`. Current Nameplate may be offsetting from sprite center y
  instead of sprite top y, producing a smaller-than-16 px above-head
  margin.

### Test 5 — Walkable-edge block + bg (D6.1-28/29) — ⏸ NOT TESTABLE

No floor tiles → no visible room edge → cannot exercise edge-block. Same
root cause as Test 2.2.

---

## Newly surfaced MVP gap (missed in 06.1 discussion)

**Spawn-in init delay.** Legacy BNO has a player-spawn init delay before
the run animation kicks off. Operator request: mirror this exactly.
Citation lookup needed in `extracted/client-5-8/objects/0042-player/events/
Create.gml` and `Other-7.gml` (alarm 0 or Init). File as `D6.2-12` (spawn
init delay) in the Phase 06.2 plans.

---

## Post-UAT e2e regression (RC1 + RC2 from triage)

After the operator UAT, `deploy-staging` post-deploy Playwright also went
RED with 17/21 tests failing. Triage of the 17 failures groups them under
4 root causes:

- **RC1 — telemetry env-gate** (`GameScene.ts:753`, `PlayerRenderer.ts:199`):
  `__rebno.{roomId, cameraScrollX, loadedTextures, localPlayerX/Y,
  localFrame}` hooks gated by `DEV || MODE==='test'`. Staging build runs
  `MODE='staging'` → entire hook block silenced → ~7 e2e failures.
  **Fixed in commit `cd47745` (local, not yet pushed). Drops the gate.**

- **RC2 — login-contrast missed inviteSuffix**
  (`login-contrast.e2e.test.ts:56` used `page.goto('/')`): 7 login-contrast
  tests timed out on `form#login-form h1` because staging returns 401
  without `?invite=$TOKEN`. **Fixed in commit `cd47745`.**

- **RC3 — `data-game-ready` never set on some tests** (ws-kill-reconnect,
  sprite-state, logout, cli-08 first-pass) — to be re-evaluated after RC1
  re-deploy; some of these likely have RC1 as the actual cause.

- **RC4 — Genuine code regressions** — captured below as Phase 06.2 plans.

---

## Phase 06.2 scope summary

| ID | Finding | Source | Status |
|---|---|---|---|
| D-40 | Floor tiles + TSides not rendering on staging | Test 2.2 | reopened |
| D-41 | Local sprite no-animate | Test 2.5, claimed closed in 06.1-04 | reopened |
| D-45 | Nameplate Y too low — overlaps sprite | Test 4 | reopened |
| D-50 | Server: ghost player remains after WS disconnect | Test 2.1 | new |
| D-51 | Server: duplicate account login allowed | Test 2.4 | new |
| D-52 | Player position occasionally resets to spawn | Test 2.6 | new |
| D-53 | Legacy spawn-in init delay missing | Operator request | new |

**Out of cycle-3 scope** (defer Phase 7 or later): everything from the
Phase 06.1 deferred list still defers.

---

*Cycle-3 UAT captured 2026-05-13. Next: `/gsd-discuss-phase 06.2` to lock
implementation decisions for D-40/D-41/D-45 reopenings + D-50..D-53 new
findings, then `/gsd-plan-phase 06.2`.*
