Surfaced in the 3rd Lowy review of #623.
store.canvasMaximized() (defined in useViewState.ts) is read by:
ChromeBar (dock vs overlay)
TerminalCanvas (which Show branch to render — tiled vs maximized)
PillTree (opacity recede + leading minimap-icon affordance)
CanvasTile (corner rounding gate)
…and written by two sites (CanvasTile maximize button, PillTree's minimap-icon-as-restore). Both go through store.toggleCanvasMaximized, so the writer-side is centralized today.
The smell: there's no single owner of "canvas display mode." Each reader independently decides what maximized means for its own concern. If the mode ever grows a third state (e.g. PiP, picture-in-picture for an agent run), or the rules ever depend on a second axis (e.g. mobile auto-maximize), every reader needs an audit.
Possible directions (not blocking — defer):
- Status quo — keep readers independent, rely on the single-writer invariant. Document it (done in
useViewState.ts comment).
- Mode enum — replace the boolean with a
viewMode: "canvas" | "maximized" | <future> so readers match() exhaustively. Catches "did I update every site?" at compile time.
- Posture orchestrator — extract
useViewPosture() that returns { chromeStyle, tileBranch, pillTreeOpacity, ... } for each reader; the boolean stays internal. Trades coupling for indirection.
Risk × likelihood × effect (per Lowy framework): low × possible × low — not blocking the canvas-only-ux PR. File for visibility.
Surfaced in the 3rd Lowy review of #623.
store.canvasMaximized()(defined inuseViewState.ts) is read by:ChromeBar(dock vs overlay)TerminalCanvas(which Show branch to render — tiled vs maximized)PillTree(opacity recede + leading minimap-icon affordance)CanvasTile(corner rounding gate)…and written by two sites (
CanvasTilemaximize button,PillTree's minimap-icon-as-restore). Both go throughstore.toggleCanvasMaximized, so the writer-side is centralized today.The smell: there's no single owner of "canvas display mode." Each reader independently decides what maximized means for its own concern. If the mode ever grows a third state (e.g. PiP, picture-in-picture for an agent run), or the rules ever depend on a second axis (e.g. mobile auto-maximize), every reader needs an audit.
Possible directions (not blocking — defer):
useViewState.tscomment).viewMode: "canvas" | "maximized" | <future>so readersmatch()exhaustively. Catches "did I update every site?" at compile time.useViewPosture()that returns{ chromeStyle, tileBranch, pillTreeOpacity, ... }for each reader; the boolean stays internal. Trades coupling for indirection.Risk × likelihood × effect (per Lowy framework): low × possible × low — not blocking the canvas-only-ux PR. File for visibility.