12 Work items list shows the previous org's items after an org/workspace switch (stale lazy tree)
Type: Bug — stale CLIENT ISLAND after a tenant-context switch (implementation defect; the planning-contract gap is logged as notes.html mistake #85).
Parent: None — root sibling, dotted id 12. Both related epics are done, so per the log-bug parent rule the bug is logged parentless at the root: Epic 2 Issue tracking core (MOTIR-68 — owns the /items list where the defect lives) and Epic 6 Search, reporting & admin (MOTIR-326 — owns the org/workspace switcher, Story 6.10.5). Numbering: epics occupy dotted ids 1–10, existing root bugs are 9/10/11, so the next free integer is 12.
Discovered in: Manual dogfooding (out-of-band). On the Work items page (/items), switching the active org (or workspace) does not refresh the list — it keeps showing the PREVIOUS tenant's work items until a hard reload.
Root cause / fix (VERIFIED, debug-first — not the surface claim):
The reported "the page won't refresh" is a false surface read — router.refresh() is in fact already called on switch (app/(authed)/_components/OrgControl.tsx:60-69; the workspace switcher does the same). The real defect is a client island that router.refresh() cannot reach.
- The default unfiltered Tree view of
/itemsrenders the lazyIssueTreeTable('use client'). It seeds the project's root issues into client state once at mount:useState(() => ({ [ROOTS]: { rows: initialLevel.rows, … } }))—app/(authed)/items/_components/IssueTreeTable.tsx:92-100. - Switching org (
switchOrganizationAction,app/(authed)/_actions.ts:102-130) re-points theworkspace_idcookie androuter.refresh()re-runs the server tree:IssuesPage→getActiveProject()resolves the NEW project (app/(authed)/items/page.tsx:57;lib/projects/index.ts:56→lib/workspaces/index.ts:30), andIssueTreeSectionre-reads the new project's roots (IssueTreeSection.tsx:180) and passes them down as theinitialLevelprop. - But the island is not remounted, so the new prop is ignored: its React key is
serializeSort(sort)(IssueTreeSection.tsx:184) and the page<Suspense>key isview:sort:filter:page(page.tsx:210) — neither includesprojectId/workspaceId. A context switch keeps view/sort/filter/page constant → both keys unchanged → React reuses the instance → theuseStateinitializer never re-runs → the ROOTS level keeps the OLD tenant's rows. - The island's only external refresh hook is the
issuesChangedAttick fromCreateIssueProvider(IssueTreeTable.tsx:152-159), added to fixbug-issue-list-not-refreshed-after-create. The switch actions do NOT bump that tick, so the effect-refetch path doesn't fire either.
Net: after an org/workspace switch the Tree shows the previous tenant's items until F5. (This is the same class as the create bug fixed a few lines above the stale seed, and root bug MOTIR-756 "sprint complete … not refreshed".) The filtered/static tree and the List view re-render from server props on each refresh and are likely fine — but they share the same projectId-less <Suspense> key, so verify them in the same pass.
Reproduce: Sign in to a multi-org/multi-workspace account, open /items (default Tree view, no filter) in org A. Switch to org B via the org control (or switch workspace). The list still shows org A's roots; a hard reload corrects it.
Fix direction: Remount the lazy tree on tenant/project identity — add projectId (or workspaceId) to the IssueTreeTable key at IssueTreeSection.tsx:184 (e.g. key={${projectId}:${serializeSort(sort)}}), mirroring the existing remount-on-sort, and/or to the <Suspense> key at page.tsx:210. Belt-and-braces: have switchOrganizationAction/switchWorkspaceAction bump an issuesChangedAt-style tick every server-prop-seeded island watches. Add the missing E2E: switch workspace/org on /items and assert the list ROWS change — tests/e2e/shell-flows.spec.ts currently only asserts the sidebar project-switcher label, never the items list. Write the failing repro test first (run.md code+tests rule).
Resolution: Open — the fix ships as a separate type: code subtask (a root-level epic-direct subtask, since the cause spans Epic 2's list + Epic 6's switcher, both done). Per notes.html mistake #85, the fix should generalise the page-state-after-mutation contract to tenant-context switches.