# Phase 6: Client Rebuild — MVP Gate (CLI-08 HARD MILESTONE) - Discussion Log

> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

**Date:** 2026-05-09
**Phase:** 06-client-rebuild-mvp-gate-cli-08-hard-milestone
**Areas discussed:** Login + chat HUD + reconnect UX, Prediction & reconciliation policy, Asset pipeline AST-01 shape, Client hosting topology + CLI-08 harness

---

## Gray-area selection

| Option | Description | Selected |
|--------|-------------|----------|
| Login + chat HUD + reconnect UX | Login layout, error messaging, autologin, force-reset overlay, chat focus model, CLI-09 reconnect UX | ✓ |
| Prediction & reconciliation policy | Reconciliation behaviour, remote interp, input cadence | ✓ |
| Asset pipeline AST-01 shape | Tool home, atlas packing, manifest format | ✓ |
| Client hosting topology + CLI-08 harness | Static-bundle host, CI gate vs UAT | ✓ |

**User's choice:** all four areas selected.

---

## Login + chat HUD + reconnect UX

### Login screen presentation

| Option | Description | Selected |
|--------|-------------|----------|
| Full-screen Phaser scene | Dedicated LoginScene with retro pixel-art branding | |
| DOM overlay over Phaser canvas | Plain HTML form over static title backdrop; browser autofill / a11y | |
| Hybrid — DOM form inside Phaser scene | LoginScene backdrop + DOMElement-mounted form | ✓ |

**User's choice:** Hybrid — DOM form inside Phaser scene.
**Notes:** browser password-manager + autofill + accessibility all preserved while keeping retro Phaser feel.

### Cookie-based autologin

| Option | Description | Selected |
|--------|-------------|----------|
| Silent — skip login screen entirely | /api/auth/me on boot → straight to GameScene | |
| Brief spinner on login scene | Show spinner ~500 ms while session validates | ✓ |
| Show login scene, prefilled username, focus password | Username prefilled; pw re-entry each session | |

**User's choice:** Brief spinner on login scene.
**Notes:** visible feedback even on fast paths.

### Chat HUD input model

| Option | Description | Selected |
|--------|-------------|----------|
| Enter toggles chat-mode (modal) | Modal chat overlay; movement keys disabled while typing | |
| Always-typable input box | Input always focused; movement as global hotkeys | |
| Click-to-focus chat, Esc to release | Movement default; click chat box, Esc to release | |

**User's choice:** Free-text — Enter or T toggles chat mode (T is Minecraft default), not a modal — input line and chat text overlays the game scene like Minecraft.
**Notes:** drove Phase 6 D-04 directly. Movement keys freeze on chat-mode; Esc cancels; chat overlay is non-modal.

### CLI-09 reconnect UX

| Option | Description | Selected |
|--------|-------------|----------|
| Dimmed scene + center toast w/ countdown | Dim scene 50%, center toast w/ countdown + auto-retry | |
| Top-banner notification | Yellow banner across top; game stays interactive | ✓ |
| Full overlay modal | Black overlay blocks input; spinner + "Connection lost" | |

**User's choice:** Top-banner notification, with caveat — player can't perform world-mutating actions (item acquisition, message-board posts, etc.) while reconnecting.
**Notes:** on reconnect, server accepts player's new location securely (anti-cheat aware: server is authoritative, client never claims position). Critical clarification: REBNO is exploration-driven; **on fresh sign-in, players always spawn at their home portal** — no cross-session location persistence. Drove Phase 6 D-06 + D-07; amends Phase 4 D-14.

---

## Prediction & reconciliation policy

### Reconciliation policy

| Option | Description | Selected |
|--------|-------------|----------|
| Threshold-gated — lerp small, snap large | <16 px → lerp 100 ms; ≥16 px → hard snap | ✓ |
| Always lerp | Smooth 100–200 ms always; rubber-bands on big corrections | |
| Always snap | Set to server position immediately; jittery on micro-corrections | |

**User's choice:** Threshold-gated.
**Notes:** floor tiles are 44 × 40 px → planner picks concrete threshold ~22 px (half-tile) per Phase 6 D-10.

### Remote-player rendering

| Option | Description | Selected |
|--------|-------------|----------|
| Entity interpolation w/ ~100 ms backbuffer | Render ~100 ms in past, smooth between snapshots | |
| Snapshot interpolation w/ extrapolation on stale | Above + extrapolate forward when snapshot stale | ✓ |
| Direct snap to latest snapshot | Render at server's last-known position | |

**User's choice:** Snapshot interpolation w/ extrapolation on stale.
**Notes:** asked about standardised model for collision-correct extrapolation.

### Extrapolation model (follow-up)

| Option | Description | Selected |
|--------|-------------|----------|
| Client-side velocity + local collision clip | Cheaper; no Phase 4 schema change | |
| Expand wire — server broadcasts remote inputs | Schema bump; client runs deterministic step() locally | ✓ |
| Skip extrapolation — freeze + lerp on next snapshot | Simplest; freeze until next snapshot | |

**User's choice:** Expand wire — server broadcasts remote inputs.
**Notes:** drove Phase 6 D-08 (PROTOCOL_VERSION bump + `PlayerState.input_axes`). Coordinated server-before-client deploy ritual per Phase 4 D-03.

### Input cadence

| Option | Description | Selected |
|--------|-------------|----------|
| Coalesce to 20 Hz | One c2s.input per server tick | |
| Send-on-state-change (event-driven) | Send only on keydown/keyup transitions | ✓ |
| 60 Hz — every Phaser frame | 1 msg per render frame | |

**User's choice:** Send-on-state-change (event-driven).
**Notes:** drove Phase 6 D-09. Server holds last input vector; tick reads stored value; heartbeat-coupled refresh survives dropped keyup packets.

---

## Asset pipeline AST-01 shape

### Tool home

| Option | Description | Selected |
|--------|-------------|----------|
| Standalone tool — tools/asset-pipeline/ | Mirrors extract-gmd / asset-catalog / room-converter | (Claude's discretion) |
| Workspace package — packages/asset-pipeline/ | Pulled into pnpm workspace | |
| apps/client build script | Lives inside client app | |

**User's choice:** Free-text — "agent decides using best judgment".
**Claude's pick:** Standalone tools/asset-pipeline/ — preserves Phase 1 D-17 boundary, reusable for Phase 7 AST-02..04. Drove Phase 6 D-13.

### Atlas packing

| Option | Description | Selected |
|--------|-------------|----------|
| Single multi-sprite atlas via sharp + free-pack | One atlas-mvp.png + Phaser atlas.json | ✓ |
| Per-sprite stripsheets | One PNG per sprite, multiple HTTP requests | |
| Single image per frame (no packing) | BMP→PNG 1:1, hundreds of HTTP requests | |

**User's choice:** Single multi-sprite atlas, with caveat — must optimize for future sprite edits by human devs likely using Aseprite or similar.
**Notes:** drove Phase 6 D-14 + D-15 (Aseprite-export-compatible source format; bootstrap mode emits per-sprite PNG strips + JSON sidecars; build mode packs them).

### Manifest + content-hashing

| Option | Description | Selected |
|--------|-------------|----------|
| Vite-native asset hashing + manifest plugin | Vite handles all hashing | |
| Custom manifest from tools/asset-pipeline | Pipeline emits its own JSON | |
| Hybrid — Vite hashes, custom manifest indexes | Vite hashes; pipeline emits richer index | (Claude's discretion) |

**User's choice:** Free-text — "agent decides using best judgment".
**Claude's pick:** Hybrid. Decouples Phase 7 AST-02..04 (audio + fonts) expansion from Vite internals. Drove Phase 6 D-16.

---

## Client hosting topology + CLI-08 harness

### Hosting

| Option | Description | Selected |
|--------|-------------|----------|
| Same Fly app — served by apps/server | Vite build → apps/server/public/; single domain | ✓ |
| Separate Fly app — rebno-client-staging/-prod | Static-only Fly apps; independent deploy | |
| Tigris bucket + Fly proxy | Push to Tigris; serve via static-origin proxy | |
| Cloudflare Pages / Netlify | Free static; global CDN | |

**User's choice:** Same Fly app — served by apps/server.
**Notes:** drove Phase 6 D-18. Single domain per env eliminates CORS, allows SameSite=Strict cookies. Couples client redeploy to server redeploy — acceptable at MVP scope.

### CLI-08 verification

| Option | Description | Selected |
|--------|-------------|----------|
| Manual UAT on staging + screenshot/video | Operator demo + 06-HUMAN-UAT.md | |
| Automated Playwright two-client CI smoke | Playwright headless on every push + tag | |
| Both — Playwright merge-gate + manual UAT | CI gate + milestone artifact | ✓ |

**User's choice:** Both — Playwright smoke gates merge + manual UAT records milestone.
**Notes:** drove Phase 6 D-19. CI keeps regression risk near zero; manual UAT provides human "we shipped CLI-08" artifact.

---

## Claude's Discretion

User answered every surfaced gray area; deferred two specific sub-questions to best judgment:

- **Asset-pipeline tool home (D-13)** — Claude picked `tools/asset-pipeline/` standalone (Phase 1 D-17 pattern preserved).
- **Manifest format (D-16)** — Claude picked hybrid (Vite hashes + asset-pipeline emits richer manifest).

Open discretion items recorded in CONTEXT.md "Claude's Discretion" subsection (final values land at plan time):
- Remote-player nameplate form-factor (Phaser canvas text vs DOM overlay)
- Divergence threshold concrete value (~22 px recommendation; planner tunes from soak-data histograms)
- Extrapolation horizon concrete value (~250 ms recommendation; planner tunes from RTT distribution)
- `.aseprite` source storage (committed vs gitignored)
- MVP background image pick
- Static-mount path (`apps/server/public/` vs `apps/server/dist/client/`)
- Room-rendering technique (Phaser TilemapLayer vs custom blit)

## Deferred Ideas

Captured verbatim in CONTEXT.md `<deferred>` section. Highlights:

- AST-02..04 (audio + fonts + full manifest) → Phase 7
- Multi-room transitions, full chat, friends/presence, whispers, account recovery, settings menu → Phase 7 PAR-04/PAR-06
- `.bnu` per-user character migration → Phase 7 PAR-05
- Admin UI → Phase 7 PAR-07
- OTel browser SDK / client telemetry → v2
- Independent client deploy cadence → v2
- Phaser 4 migration → ADR 0001 retro window (post-CLI-08, pre-Phase-7-PR-01)
- Pixel-diff verification of MVP room → Phase 7 PAR-03
- Behavioural anti-cheat → out of scope per PROJECT.md

### Reviewed Todos (not folded)

None — `gsd-sdk query todo.match-phase 6` returned 0 matches.

---

# Gap-Closure Discussion (2026-05-10)

**Trigger:** 06-HUMAN-UAT.md operator UAT (decidel, 2026-05-10) failed all 5 tests. User decision: scope all 5 gap-closure items to Phase 6, no Phase 7 advance until CLI-08 truly green.

## Areas discussed

### #3 — Movement fidelity (extracted-GML reverse)

**Question:** Scope of extracted-GML reverse?
**Options:**
- Derive only feel-critical constants (speed, accel, friction, key-buffer)
- Full mover semantics (above + 8-direction sprite swap, animation phase, sub-pixel accumulator)
- Split into 2 plans — numerics first, sprite-state second (after #4 lands)

**User choice:** Split into 2 plans (D-26).
**Important note from user:** Original BNO player character object is named `server` (NOT `player`). Movement work must consult `extracted/client-5-8/objects/0000-server/` events.

### #4 — Real assets (first-pass scope)

**Question:** First-pass asset scope?
**Options:**
- Player sprites + 1 room (Prairie_Flats)
- Player sprites + Prairie_Flats + Online_Lobby
- All extracted sprites + all 10 rooms

**User choice:** Player sprites + 1 room = `BNCentral` (D-27).
**Important note from user:** `0058-BNCentral` is the actual latest online lobby iteration, NOT `0004-Online_Lobby`.

### #2 — Reconnect / cookie auto-login renders blank GameScene

**Question:** Plan shape for fix?
**Options:**
- Investigation plan + fix plan (split)
- Single combined plan (investigate inline + fix)
- Hold pending /gsd-debug session first

**User choice:** Hold pending /gsd-debug session first (D-25). Debug findings feed the fix plan verbatim.

### #5 — Logout UX placement

**Question:** Where lives the logout affordance?
**Options:**
- Esc menu — BNO-style modal with Logout + Resume + Settings (placeholder)
- Top-right always-visible button
- Both — Esc menu primary + top-right kebab secondary

**User choice:** Esc menu — and ALSO fires when game-view is clicked (D-24).

### #1 — Login text contrast

Not discussed (no gray area). Trivial CSS fix per UI-SPEC color tokens. D-23.

## Decisions captured

- D-23: LoginScene contrast fix (one plan, small)
- D-24: Esc menu logout — Esc key + game-view click both trigger
- D-25: /gsd-debug FIRST for reconnect/blank-render, then fix plan
- D-26: Split movement work into Plan A (numerics) and Plan B (sprite-state, after #4)
- D-27: First-pass assets = player sprites (8-dir Stand+Run) + BNCentral room
- D-27a (addendum 2026-05-10, user-supplied): cyan nametag always-on above player head — anchored top-center, follows movement, self + remotes. Belongs in 06-16 (player-render plan). Verify exact cyan/font/size against `0000-server` draw events before locking color (UI-SPEC `#22D3EE` is fallback).

## Sequencing locked

8 new plans (06-10..06-17). See 06-CONTEXT.md `### Sequencing` table.

## Deferred / out-of-scope (continue to defer)

- AST-02 (audio), AST-03 (fonts), AST-04 (full content-hashed manifest spanning audio + fonts) — Phase 7
- Other 9 extracted rooms — Phase 7 PAR-03
- Admin UI, friends list, whispers, message-board, character creation, settings menu — Phase 7
- All other CONTEXT.md `<deferred>` items remain Phase 7 / v2 as previously locked
