# Navigation refactor + sidecars — runtime test checklist

**Complete.** 41 checks run, 15 voided when Projects was removed. Three defects found and fixed:
C4 (`d8cf79b`), D7/D8 (`18e732f`), plus an unrelated layout bug found along the way (`1a5c6c8`).
One known issue left unfixed on purpose: D12-edit on mobile.

Provenance: written by the session that did the navigation refactor (`eff24773`, last message
2026-07-30T06:21Z) and never saved before that session was lost. Recovered from its transcript.

**Pre-req:** `master` at `3c3b67c` or later covers **everything**, including the **X** block — the
original note said X needed the `navigation-refactor` branch, but the sidecar work is merged now, so
nav and sidecars are on master together. Restart before testing (`pm2 restart officer`) and
hard-refresh the browser; a stale bundle looks exactly like a failure. Watch the console as you go.

Status key: `[x]` verified working · `[!]` found broken, fixed, re-verified · `[ ]` not yet tested.

---

## C — Chat: session list & routing (`/chat`) — 6/6 ✅

- [x] **C1** Click a chat row → URL changes to `/chat/<id>`.
- [x] **C2** Right-click a row → "Copy link" gives `/chat/<id>` (a real link, not a button).
- [x] **C3** Clicking a row loads that conversation in the right panel.
- [!] **C4** The cwd/folder picker shows the correct folder for the opened chat. **Was broken — fixed.**
- [x] **C5** Refresh while on `/chat/<id>` → lands back in the same chat.
- [x] **C6** Paste a `/chat/<id>` URL into a fresh tab → opens that chat with the right cwd.

### C4: what was wrong

Opening any session from a non-default folder moved the picker to a **subdirectory** of that folder —
three of the four sessions under `~/dockers/officer.dev` jumped to `platform`, the fourth to `Lyrics`.
The list stayed correct; only the picker moved, and everything after it was scoped to the wrong dir.

Two functions in `claude-sessions.ts` derived cwd in opposite directions:

| | line | rule |
|---|---|---|
| `parseSummary` (builds the list) | `:103` | `if (entry.cwd && !cwd)` → **first** cwd wins |
| `parseClaudeTranscript` (opens one) | `:182` | `if (entry.cwd)` → **last** cwd wins, overwritten every entry |

A transcript records a `cwd` on every entry, so the last one is wherever a tool happened to `cd` — not
the session's home. Fixed by taking the first cwd in both, which is also where Claude Code files the
transcript on disk.

Pre-existing, but **surfaced** by the nav work: once rows became real `<Link>`s (`f35c145`), clicking
one is a route change, so the deep-link resolver in `ChatHistory/index.tsx:69` — previously reached only
on refresh or a pasted URL — now runs on every ordinary click, and it calls `setActiveCwd(detail.cwd)`.

## L — Chat: long-transcript lazy-load — 8/8 ✅

- [x] **L1** Open a very long chat → instantly at the newest message (no long scroll or visible jump).
- [x] **L2** Open is fast (only the tail loads, not thousands of messages).
- [x] **L3** Scroll near the top → older messages load (brief spinner at top).
- [x] **L4** After older messages load, the view stays put (doesn't snap to top or bottom).
- [x] **L5** Keep scrolling up → eventually reaches the true first message; loading stops.
- [x] **L6** Send a new message in a resumed chat → appends at the bottom, view follows.
- [x] **L7** A short chat (<20 msgs) behaves normally — all visible, no spinner.
- [x] **L8** "Jump to bottom" appears when scrolled up, and works.

## J — Jobs (`/jobs`) — H1 — 8/8 ✅

- [x] **J1** Click a job row → URL changes to `/jobs/<id>`.
- [x] **J2** The clicked job's detail renders on the right.
- [x] **J3** The active row is highlighted.
- [x] **J4** Right-click a row → "Copy link" gives `/jobs/<id>`.
- [x] **J5** The row's stop/delete button works and does **not** navigate.
- [x] **J6** Refresh on `/jobs/<id>` → same job detail loads.
- [x] **J7** Both panels (Running/Queued **and** History) navigate correctly.
- [x] **J8** Different detail types still render (script terminal / pipeline steps / download).

## D — Dashboards (`/dashboards`) — H2 — 12/13 ✅ (D12-edit on mobile: not fixed, mobile web being retired)

- [x] **D1** Click a row → URL becomes `/dashboards?selected=<id>`.
- [x] **D2** The preview panel shows that dashboard.
- [x] **D3** The clicked row is highlighted.
- [x] **D4** Preview's "open" arrow overlay → `/dashboards/<id>` (full page).
- [x] **D5** "New Dashboard" → create form appears; `?selected=` cleared from the URL.
- [x] **D6** Create a dashboard → navigates to the full `/dashboards/<id>`.
- [!] **D7** Edit (pencil) → edit form appears; does **not** navigate.
- [x] **D8** Save an edit → preview shows the edited dashboard (`?selected=<newid>`).
- [x] **D9** Delete → removed; if it was selected, the preview clears.
- [x] **D10** Edit/delete buttons do **not** trigger navigation (siblings of the link, not nested).
- [x] **D11** A dashboard row **outside** `/dashboards` opens `/dashboards/<id>` directly.
- [~] **D12** Mobile: selecting shows the detail panel; back clears it.
- [x] **D13** Deep-link `/dashboards?selected=<id>` in a fresh tab → preview shows it.

## P — Projects — DROPPED

The Projects feature was removed rather than fixed (see the deletion commit). All 15 P checks are void.

It had the same two defects Dashboards had — edit clearing `?selected=`, and an abandoned edit following
you to the next item — plus the same structure that caused them: the form reachable only through the
empty state. None of it was worth repairing for a feature being retired.

## X — Chat lazy-load × sidecars — 3/3 ✅

- [x] **X1** Open a long chat → **no** spurious "⚠️ some output could not be recovered" banner.
- [x] **X2** Send a new turn → appends correctly below the loaded tail.
- [x] **X3** Scroll up to load history, then send a turn / reconnect → prepended older messages are
      **not** wiped.

## R — Quick regressions — 3/3 ✅

- [x] **R1** Search/filter boxes in Jobs / Dashboards / Projects still filter the list.
- [x] **R2** No new console errors on `/jobs`, `/dashboards`, `/projects`, `/chat`.
- [x] **R3** Browser back/forward moves between selections sensibly (selection is in the URL now).
