Context
Operator directive (2026-08-31): src/dashboard/dock/projection/LayoutAdapter.mjs violates the one-class-per-file spirit — a single ~1200-line static class now carries multiple classes' worth of concerns, accreted across the dock family cycle.
The Problem
One file/class owns at least: item projection + placeholder creation, header-action row assembly + the reserved-name guard, tab-chrome projection prep, rail/auto-hide collection, edge-band decoration, the whole-stack header overlay (symbol-keyed restoration), and overflow threading. Each is a separable concern with its own change cadence; reviews and diffs on any one concern drag the whole file.
The Fix
Split into per-concern modules under src/dashboard/dock/projection/ (e.g. ItemProjection, HeaderActions, RailCollection, StackHeader), each one class per file, LayoutAdapter retained as the thin composition point. Pure moves with unchanged public statics first; any signature change is its own justified step (a move PR must not redefine custody).
Acceptance Criteria
Related
Parent: #13158. Surfaces accreted via #17944/#17952/#17953/#17956/#17960/#17948.
Origin Session ID: 914dffcd-0057-46a5-a0c6-9ca807fd5c91
Retrieval Hint: "LayoutAdapter decomposition one class per file projection concerns"
— Vega (Fable 5, Claude Code) 🌿
Context
Operator directive (2026-08-31):
src/dashboard/dock/projection/LayoutAdapter.mjsviolates the one-class-per-file spirit — a single ~1200-line static class now carries multiple classes' worth of concerns, accreted across the dock family cycle.The Problem
One file/class owns at least: item projection + placeholder creation, header-action row assembly + the reserved-name guard, tab-chrome projection prep, rail/auto-hide collection, edge-band decoration, the whole-stack header overlay (symbol-keyed restoration), and overflow threading. Each is a separable concern with its own change cadence; reviews and diffs on any one concern drag the whole file.
The Fix
Split into per-concern modules under
src/dashboard/dock/projection/(e.g. ItemProjection, HeaderActions, RailCollection, StackHeader), each one class per file, LayoutAdapter retained as the thin composition point. Pure moves with unchanged public statics first; any signature change is its own justified step (a move PR must not redefine custody).Acceptance Criteria
project,collectAutoHiddenItems,decorateProjectedItem, guard behavior) byte-compatible; existing unit/component suites green unmodified.Related
Parent: #13158. Surfaces accreted via #17944/#17952/#17953/#17956/#17960/#17948.
Origin Session ID: 914dffcd-0057-46a5-a0c6-9ca807fd5c91
Retrieval Hint: "LayoutAdapter decomposition one class per file projection concerns"
— Vega (Fable 5, Claude Code) 🌿