# Phase 0 — Kill the Lies (Session 57)

Source: VYNDR work order (Jul 10 2026 live audit × VYNDR-OVERHAUL-SPEC). Every
task is a P0 credibility fix — deletion or rewiring of fake elements. No new
product features.

## 0.1 — Delete the fake NBA game

**Root cause (found):** `scheduleService.fetchScheduleFromEspn` hits the ESPN
scoreboard with NO `?dates=` param and NO date filter. In the off-season ESPN
returns the *nearest* slate (the Jun 13 NYK@SA Finals game), which every
consumer (dashboard legacy section, Slate merge, hasOdds flags) then renders as
tonight's game.

**Fix (backend, at the source):**
- `fetchScheduleFromEspn(sport, date)` appends `?dates=YYYYMMDD` to the ESPN
  scoreboard URL.
- Normalized events are filtered to the requested ET date (`gameTime` converted
  to America/New_York must equal `date`). Events with no parseable date are
  dropped — live-feed-only, no exceptions.
- `getSchedule` passes its `date` through.

**Fix (frontend):** sport-specific empty-state copy on the dashboard when a
sport has zero games (NBA off-season: "NBA returns in October. The model is
watching the MLB + WNBA boards tonight.").

**Acceptance:** `/api/schedule/nba?date=D` never returns an event whose ET date
≠ D. Regression test uses the old NYK@SA fixture (event dated D+1) and asserts
it is filtered out.

## 0.2 — Delete the fake header counters

- `lib/liveTick.js` state trimmed to `{ tick }` — the fake `graded: 247`
  auto-increment, sin-driven `neural %`, and `aPlus/cascades` counters are
  deleted. The tick remains solely as the 1s re-render pulse for the clock.
- `HeartbeatBar` now fetches **real** data from a new endpoint
  `GET /api/snapshot/summary` (public, cache-only Redis reads, registered
  BEFORE `/:sport`): `{ graded, updated_at, sports: {nba,wnba,mlb,soccer} }`.
  - graded = Σ grades in each `snapshot:{sport}:latest` (fallback
    `grades:{sport}`). Real and small beats fake and big.
  - "neural XX%" — deleted entirely, no replacement.
  - SYNC = elapsed since `updated_at` (counts up; amber past 5 min). No
    snapshot data → "SYNC —", no graded count invented.
- Next proxy `web/src/app/api/snapshot/summary/route.ts` (S25 rule).

**Acceptance:** header numbers change only when the snapshot changes; refresh
does not reset them to 247/96%.

## 0.3 — Ticker: real items only

- The MOVE pipeline is already real (`computeLineDeltas`: locked line vs
  current line keyed `nameKey|stat|side`) — kept.
- Nav's hardcoded `TICKER_ITEMS` fallback (fake Wembanyama A+ / "NYK vs SA
  Q3" / fake Tatum MOVE) — deleted. Ticker fallback is now an empty list.
- Spec §3 rule: fewer than 4 real items → the ticker bar does not render.
  The bar sets `--ticker-h` (32px/0px) on `<html>`; layout `main` paddingTop
  and Slate sticky top become `calc(Xpx + var(--ticker-h))` so the header
  collapses cleanly.

## 0.4 — Pull /terminal from nav

- Entire surface is fabricated (Finals-era sample data) → route now
  `redirect('/dashboard')`.
- Sample layouts preserved (unrouted) at
  `web/src/components/intel/TerminalTemplates.tsx` for the §12 content engine.
- Nav PRIMARY = Slate / Scan / Ledger. BottomTabBar: Terminal tab → Explore.
  PWA manifest Terminal shortcut → Ledger. `routes.js`: `/terminal` out of
  OPEN_ROUTES; `#terminal` alias → `/dashboard`.

## 0.5 — Kill ›Query

Duplicate link to /scan (`data-search-trigger`) deleted from Nav.

## Test plan

- Updated: scheduleRoute (date filter + regression), vyndrSystems (liveTick),
  vyndrMobile (tabs/manifest), vyndrAppShell (routes/nav), vyndrCoreScreens
  (terminal redirect), vyndrParityQA (tab list).
- New: snapshot summary route integration test; schedule off-date filter test.
- Full suite green before ship.
