# Navigation refactor + sidecars — runtime test checklist **56 checks.** Each line is a single yes/no. Reference them as "J3 works, D5 needs fix". 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/`. - [x] **C2** Right-click a row → "Copy link" gives `/chat/` (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/` → lands back in the same chat. - [x] **C6** Paste a `/chat/` 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 ``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 — 0/8 - [ ] **L1** Open a very long chat → instantly at the newest message (no long scroll or visible jump). - [ ] **L2** Open is fast (only the tail loads, not thousands of messages). - [ ] **L3** Scroll near the top → older messages load (brief spinner at top). - [ ] **L4** After older messages load, the view stays put (doesn't snap to top or bottom). - [ ] **L5** Keep scrolling up → eventually reaches the true first message; loading stops. - [ ] **L6** Send a new message in a resumed chat → appends at the bottom, view follows. - [ ] **L7** A short chat (<20 msgs) behaves normally — all visible, no spinner. - [ ] **L8** "Jump to bottom" appears when scrolled up, and works. ## J — Jobs (`/jobs`) — H1 — 0/8 - [ ] **J1** Click a job row → URL changes to `/jobs/`. - [ ] **J2** The clicked job's detail renders on the right. - [ ] **J3** The active row is highlighted. - [ ] **J4** Right-click a row → "Copy link" gives `/jobs/`. - [ ] **J5** The row's stop/delete button works and does **not** navigate. - [ ] **J6** Refresh on `/jobs/` → same job detail loads. - [ ] **J7** Both panels (Running/Queued **and** History) navigate correctly. - [ ] **J8** Different detail types still render (script terminal / pipeline steps / download). ## D — Dashboards (`/dashboards`) — H2 — 0/13 (highest risk: never runtime-tested) - [ ] **D1** Click a row → URL becomes `/dashboards?selected=`. - [ ] **D2** The preview panel shows that dashboard. - [ ] **D3** The clicked row is highlighted. - [ ] **D4** Preview's "open" arrow overlay → `/dashboards/` (full page). - [ ] **D5** "New Dashboard" → create form appears; `?selected=` cleared from the URL. - [ ] **D6** Create a dashboard → navigates to the full `/dashboards/`. - [ ] **D7** Edit (pencil) → edit form appears; does **not** navigate. - [ ] **D8** Save an edit → preview shows the edited dashboard (`?selected=`). - [ ] **D9** Delete → removed; if it was selected, the preview clears. - [ ] **D10** Edit/delete buttons do **not** trigger navigation (siblings of the link, not nested). - [ ] **D11** A dashboard row **outside** `/dashboards` opens `/dashboards/` directly. - [ ] **D12** Mobile: selecting shows the detail panel; back clears it. - [ ] **D13** Deep-link `/dashboards?selected=` in a fresh tab → preview shows it. ## P — Projects (`/projects`) — H3 — 0/15 (mirror of D, also never runtime-tested) - [ ] **P1** Click a row → URL becomes `/projects?selected=`. - [ ] **P2** The preview shows that project. - [ ] **P3** The clicked row is highlighted. - [ ] **P4** Preview "open" arrow → `/projects/` (full page). - [ ] **P5** "New Project" → create form; `?selected=` cleared. - [ ] **P6** Create a project → navigates to `/projects/`. - [ ] **P7** Edit (pencil) → edit form; no navigation. - [ ] **P8** Save an edit → preview shows the edited project (`?selected=`). - [ ] **P9** Delete → removed; clears preview if selected. - [ ] **P10** Publish (rocket) → opens the publish dialog; does **not** navigate. - [ ] **P11** Publish/edit/delete buttons don't trigger navigation. - [ ] **P12** A project row **outside** `/projects` opens `/projects/` directly. - [ ] **P13** `/projects/new` → lands on `/projects` in create mode. - [ ] **P14** Mobile: select shows detail; back clears it. - [ ] **P15** Deep-link `/projects?selected=` → preview shows it. ## X — Chat lazy-load × sidecars — 0/3 - [ ] **X1** Open a long chat → **no** spurious "⚠️ some output could not be recovered" banner. - [ ] **X2** Send a new turn → appends correctly below the loaded tail. - [ ] **X3** Scroll up to load history, then send a turn / reconnect → prepended older messages are **not** wiped. ## R — Quick regressions — 0/3 - [ ] **R1** Search/filter boxes in Jobs / Dashboards / Projects still filter the list. - [ ] **R2** No new console errors on `/jobs`, `/dashboards`, `/projects`, `/chat`. - [ ] **R3** Browser back/forward moves between selections sensibly (selection is in the URL now).