# Console v2 Walkthrough — Overnight 2026-05-11 03:20 AM

Browser-driven walkthrough on `http://100.105.59.118:5173` (Tartarus + others). Chrome extension dropped mid-walkthrough so this is a partial pass — I captured the load + first project expansion + console messages, plus everything I could pull out of the live API.

## What rendered cleanly

- **Initial load:** zero errors. Console clean except the cosmetic `[recoil] App.tsx: focusedProjectAspect fallback to '9_16' fired` warning (instrumented; by design when no project is focused).
- **Status bar:** `connected` (the system-status 503 fix from earlier tonight is holding — workers veo/imagen/11l counts all 0/0, uptime ticking, panel `gemini-3.1, sonnet-3.7`).
- **Hierarchy panel:** 5 projects listed (afterimage, afterimage-anime, driver-beware, ronin-drm, tartarus). Lazy-loading is fast — expanding tartarus pulled in EP001/EP002/EP999/ep_001 within ~2 seconds.
- **Chat panel:** clean layout. ContextStrip header reads `selected context · binds clicks ↔ chat`, project/focus/selection rows, then the "No project focused" placeholder (gating fix from tonight is working). Once tartarus selected, panel pivots to `Starting Claude… launching ttyd for tartarus` and ttyd takes over.
- **Inspector pane (no take selected):** clean "no take to inspect" empty state.
- **Stage toolbar:** all 5 templates (Takes / Lineage / Memory / Queue / Events) render. Close button visible with `esc` hint.

## Bugs / oddities surfaced

### B-1 — `ep_001` is a phantom episode (DATA bug)
Tartarus expansion shows: `EP001`, `EP002`, `EP999`, **`ep_001`**. The last one is lowercase-`ep_001` instead of `EP001` and appears as a separate node. This is `FALLBACK_FIRED name=episode_id_derived_from_filename_prefix` firing on shot files that don't have a parseable `episode_id`. Either:
- A few shot files have lowercased episode IDs and need normalization
- OR the fallback regex needs to canonicalize case

Either way, the tree is showing a duplicate episode. Path to check: `projects/tartarus/state/visual/shots/*.json` — grep for `episode_id` field values, look for casing inconsistency.

### B-2 — Status bar can flicker to `disconnected` briefly during normal use (CONNECTION poll)
Caught one screenshot during the walkthrough where the pill flipped to red `disconnected` even though both API and Vite responded HTTP 200 on direct curl seconds later. Root cause is probably `useSystemStatus` setting `httpError` true on the first failed poll (e.g. mid-restart, timeout, or transient ECONNRESET), without grace for retry. Suggested fix: don't flip to disconnected until N consecutive failures (N=2 or 3) — single-poll failures shouldn't repaint the chrome.

### B-3 — 110 fails / 5 warns in the BottomBay are from a stale events buffer
The status strip shows `110 fails  5 warns  episodes_synthesized_from_shot_index` — the count is server-side accumulated from API restarts / fallback fires. Not a bug per se, but the most prominent label `episodes_synthesized_from_shot_index` is the same `FALLBACK_FIRED` that's firing every time the projects adapter runs. It's normal-mode output dressed as an alarm. Either:
- Demote synthesized-state fallbacks from `fails` to `info`
- Or filter the bottom bay to show only severity≥warning

### B-4 — `Starting Claude…` placeholder still shows after ttyd has bound (RENDER race)
Even after `/api/ttyd/start` returns `{"port": 7681}` and ttyd actually accepts connections, the chat panel can still display "Starting Claude… launching ttyd for tartarus" for a few seconds. This is because the API blocks up to 15 seconds in `_capture_session_id` waiting for Claude to write a JSONL session file, regardless of whether the port is bindable. The frontend doesn't get the port until that capture finishes. So the user waits 15s for first-load on any project that hasn't had a prior Claude session. Suggested fix: return the port IMMEDIATELY when the ttyd process binds; capture session_id in a background thread and emit it as an SSE event when it arrives.

### B-5 — Project rows show a trailing em-dash with no value (COSMETIC)
Every project label renders as e.g. `▾tartarus—` — that trailing em-dash is the KeeperGlyph placeholder when there are no rollup scores. Looks like data is missing. Should probably be hidden when `count + total = 0`, not rendered as `—`.

### B-6 — `9_16` fallback warning is loud (COSMETIC, known)
`App.tsx:198` (now line 330 after edits) warns on every render where `focusedProjectAspect` is read without a `focusPath`. The warning fires once on initial mount before projects load. Currently set to `console.warn` which Chrome surfaces in yellow. Could be downgraded to `console.debug` or gated on a dev flag.

## What I couldn't test (extension dropped)

- Clicking down to a specific beat → does Lineage open with a real graph?
- Inspector view at 16:9 vs 9:16 — does the split layout work for landscape?
- Keyboard navigation (Cmd+P palette removed today, but ←/→ for take stepping should still work)
- The Queue template — never rendered with real data
- Memory + Events templates — never opened

## Action items derived from walkthrough

| # | Bug | Severity | Where |
|---|-----|----------|-------|
| B-1 | `ep_001` phantom episode | REAL | `projects/tartarus/state/visual/shots/*.json` OR `api/adapters/beats.py:_derive_episode_id` |
| B-2 | Status pill flickers disconnected | REAL | `console-v2/.../lib/use_system_status.ts` |
| B-3 | Synthesized fallbacks shown as "fails" | POLISH | `api/eventbus.py` or bottom bay filter |
| B-4 | 15s session-id capture blocks port return | REAL (UX-impactful) | `api/ttyd_routes.py:_capture_session_id` |
| B-5 | Em-dash placeholder on empty rollup | POLISH | `console-v2/.../nav/NavRow.tsx` or KeeperGlyph |
| B-6 | 9_16 fallback warning is loud | POLISH | `console-v2/.../App.tsx:330` |

None of these are CRITICAL. All real today's work is holding.
