LearnNewsExamplesServices
Frontmatter
id15837
titleDockLayoutAdapter projects empty edge bands — dead in-flow box starves the center zone
stateClosed
labels
bugai
assigneesneo-opus-vega
createdAtJul 24, 2026, 8:32 PM
updatedAtJul 24, 2026, 9:51 PM
githubUrlhttps://github.com/neomjs/neo/issues/15837
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[x] 15657 FM cockpit: vessel-narrow (~314px) layout — rail behavior + zone priority
closedAtJul 24, 2026, 9:51 PM

DockLayoutAdapter projects empty edge bands — dead in-flow box starves the center zone

neo-opus-vega
neo-opus-vega commented on Jul 24, 2026, 8:32 PM

Context

Found while implementing #15657 (FM cockpit vessel-narrow layout). After removing the cockpit's min-content width floors (inline-size containment per the landed own-width discipline), the ~314px vessel window still rendered an empty cockpit: the primary split computed width 0 while its zones' heights split correctly per the committed proportions. Live-DOM probe receipts (2026-07-24, this session):

edgeRow  x51 w262          (row: [split, band, rail])
split    x51 w0   flex:1 1 0%   ← starved to zero
band     x51 w280 flex:0 0 auto position:static  ← the occupant
rail     x331 w14 flex:0 0 auto  ← pushed past the viewport edge

The Problem

DockLayoutAdapter.projectEdgeBand (src/dashboard/DockLayoutAdapter.mjs:663) projects an edge zone's band unconditionally — even when projectTabsNode (:783-785) has railed away every one of its items as autoHidden. The FM cockpit's default document (cockpitDockDocument.mjs) does exactly that: all five right-zone items are auto-hidden, so the band is a tabs container with zero live tab items — and it still occupies inline-size: 17.5rem (280px, resources/scss/src/dashboard/Container.scss .neo-dashboard-dock-edge-band-right) of normal flow at every width:

  • Desktop: a permanently empty 280px gutter between the fleet grid and the right rail — dead space the center owns by the adapter's own philosophy.
  • Narrow (~314px vessel): the band (280) + rail (14) exceed the row (262); the split (flex-basis: 0) receives zero width, both zones vanish, and the rail is pushed to x=331 — outside its own window. This is the "the right-edge rail keeps its share" observation recorded in #15657's measurements, now root-caused.

The adapter's JSDoc states the sizing intent: "bands keep a fixed cross-extent … instead of flexing against the center — an unsized band silently eats workspace geometry the center owns." An empty band eats that geometry too — 280px for nothing.

The Architectural Reality

  • projectEdgeZoneNode (:580-650) pushes the band whenever zones.right (etc.) exists (:603/:611/:619/:635) — existence, not liveness, is the condition.
  • projectTabsNode already computes the live tab flow: items minus context.railedItemIds, activeIndex: null when empty. Emptiness is knowable at projection time from the projected config.
  • Reveals do NOT use the band: a rail-tab click renders through DockRevealOverlay (position: absolute, z 20 — ADR 0029 "overlay, never push"). The band's function is hosting live (pinned / non-auto-hidden) edge panes.
  • Non-empty bands are load-bearing for other consumers: apps/workstation/tour/denseWorkstation.mjs:41 commits left: 'left-tabs', right: 'split-right' with live panes (and a band may be a split node, not tabs). The fix must not touch populated bands.
  • Document mutations re-run projection, so a skipped band re-appears the moment a pin/un-autohide operation makes it non-empty — no dynamic gap.

The Fix

In projectEdgeZoneNode (or a guard inside projectEdgeBand): when the projected band config is a tabs projection whose live item set is empty (all items railed), do not push the band into the row/rows. Split-node bands and any band with ≥1 live tab item project exactly as today.

Witness: extend test/playwright/unit/dashboard/DockLayoutAdapter.spec.mjs — (a) an edge zone whose band items are all autoHidden projects rail-without-band; (b) a partially-railed zone keeps its band; (c) a split-node band is untouched.

Golden impact (reviewed design delta, named up front): removing the desktop dead gutter widens the FM center zone, so FleetCockpitVisual.spec.mjs goldens (cockpit-default-shell, likely fleet-grid-cards / activity-stream-chips) regenerate in this PR. Note: cockpit-default-shell.png is already red on clean dev (1983px drift, control-verified this session; the golden predates post-#15649 merges such as #15680's zero-state rendering) — the regen absorbs both deltas and the PR body must account for them separately.

Acceptance Criteria

  • An edge zone whose band has zero live tab items projects rail-only (no in-flow band box) — unit-witnessed red→green
  • Partially-railed and split-node bands project unchanged — unit-witnessed
  • FM cockpit desktop: the empty right gutter is gone; goldens regenerated as a reviewed design delta with the pre-existing drift accounted separately
  • #15657's 314px probe shows the primary split receiving the row's free width (unblocks its AC1)
  • Workstation dense-document projection unchanged (its bands are populated)

Out of Scope

  • The #15657 vessel-narrow layout itself (containment, banner shrink, bar wrap, narrow restack) — this ticket only unblocks it.
  • The stale cockpit-default-shell golden's other cause (post-#15649 text drift) — absorbed in the regen but not separately repaired here.
  • Any change to reveal-overlay behavior or the committed-document schema.

Decision Record impact

aligned-with ADR 0029 — the auto-hide contract already routes reveals through the absolute overlay; an empty in-flow band contradicts the band-sizing rationale recorded in the adapter itself.

Related

  • Blocks #15657 (vessel-narrow layout — AC1 unreachable while the split starves)
  • #15649 (measurements that recorded the symptom), ADR 0029, #15680 (independent golden-drift co-cause)

Live latest-open sweep: checked latest 20 open issues at 2026-07-24 ~18:31Z; no equivalent found. A2A in-flight claim sweep (last 60 min, all read-states): no competing claim. KB semantic sweep: no coverage.

Origin Session ID: 856622cb-f32e-4ab8-bd11-4d2bb6602f61

Retrieval Hint: "empty edge band starves dock split vessel narrow 280px"

tobiu referenced in commit 2d21cf8 - "fix(dashboard): an all-railed edge band projects rail-only instead of an empty in-flow box (#15837) (#15841)" on Jul 24, 2026, 9:51 PM
tobiu closed this issue on Jul 24, 2026, 9:51 PM