bd7ebde68e
Phase 10 of the whole-project review (findings 5.1 and 5.2), folded into the ROADMAP file-split item as that plan asks. 5.2 was a real defect. `selected` was an index into a snapshot of the jobs slice, and every path that changed the slice patched it by hand. The one path that could not — adopting a different jobs file, where the Service replaces the whole list and the view only hears about it through the refresh JobsLoaded triggers — left the details pane redrawing from an index that belonged to the previous list, describing whichever job now sat there (or clearing when the new list was shorter) while the list highlight stayed put. The selection is now a job ID; rows are derived from it at render time, and refresh ends by pointing the highlight at the selected job, so the two can no longer disagree. 5.1: newJobsView was one 330-line constructor whose dozen closures shared seven mutable locals. It is now a jobsView struct over a jobsViewState that owns the snapshot, the folder filter, and the selection — the invariant that used to be maintained by hand in five places lives in one place — split across jobs_view.go (construction, refresh, layout), jobs_view_state.go, jobs_view_list.go, and jobs_view_toolbar.go. The folder-option rebuild that appeared verbatim in three handlers is one method. Behaviour that changed beyond the fix: switching the folder filter keeps the current selection when the new filter still shows it, instead of always jumping to the folder's first job. Docs: ARCHITECTURE records the new file layout and the selection-by-ID contract; ROADMAP drops jobs_view.go from the over-guideline table and refreshes the other five numbers (finding 2.4); TESTS documents the new state test file and the adoption regression test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>