LearnNewsExamplesServices
Frontmatter
id15655
titleDockRail tabs stretch to fill the entire edge
stateClosed
labels
bugdesignaitestingcore
assigneesneo-gpt-emmy
createdAtJul 21, 2026, 10:06 PM
updatedAtJul 22, 2026, 12:10 AM
githubUrlhttps://github.com/neomjs/neo/issues/15655
authorneo-gpt-emmy
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 22, 2026, 12:10 AM

DockRail tabs stretch to fill the entire edge

Closed Backlog/active-chunk-8 bugdesignaitestingcore
neo-gpt-emmy
neo-gpt-emmy commented on Jul 21, 2026, 10:06 PM

Context

Build Week film-floor inspection exposed a framework-level geometry defect behind the oversized right-edge buttons: Neo.dashboard.DockRail stretches every auto-hide tab across an equal share of the rail's main axis. This is not an AgentOS paint choice. The same component projects rails for the standalone dock example, Workstation, AgentOS, and future dashboard consumers.

Live Neural Link evidence on 2026-07-21 measured one 14×1006px right rail with four visible tabs (Perspectives, Add agent, Catch up, Operator). Every button was exactly 6×242px, including large empty click padding, and every button VDOM carried flex: 1 1 0%. The composed reveal overlay was hidden at 0×0 and did not consume rendered space.

The Problem

The rail correctly stretches tabs across the cross axis so each affordance fills the 14px strip, but it also grows tabs across the main axis. Four unrelated labels therefore become four equal-height 242px slabs instead of intrinsic label-sized controls grouped at the start of the rail. On horizontal rails, the same layout path can distribute buttons into equal-width slabs; that rendered edge matrix is not yet measured.

This creates three visible defects:

  • the click target is much larger than the visible label and reads as accidental empty padding;
  • label length no longer determines the affordance's main-axis extent;
  • adding or removing one auto-hidden item resizes every other tab, producing unstable navigation geometry.

The Architectural Reality

  • src/dashboard/DockRail.mjs:203-218 selects a vbox for left/right and an hbox for top/bottom, both with align: 'stretch'. Cross-axis stretch is intentional.
  • src/layout/Flexbox.mjs:148-159 falls back to numeric 1 when an item's flex is absent under align: 'stretch', normalized to 1 1 0%.
  • src/dashboard/DockRail.mjs:333-349 builds tab configs without an explicit flex value, so the generic fallback becomes a main-axis growth policy the rail never intended.
  • resources/scss/src/dashboard/Container.scss:142-164 owns the four-edge strip geometry and writing mode; application skins only color that shared anatomy.
  • A live post-construction flex setter probe did not re-run the parent's child-attribute pass and correctly left the rects unchanged. Verification must use a fresh projection/render, not a hot property poke.

Decision Record impact: aligned-with ADR 0029. The persisted dockZone.v1 model, reveal state machine, and operation grammar remain unchanged.

The Fix

  1. Give every DockRail tab config an explicit intrinsic main-axis flex policy at creation time (expected shape: flex: 'none') while retaining the rail's cross-axis align: 'stretch'.
  2. Pin that construction contract in the focused DockRail unit suite, including tabs inserted later by reconcileTabs().
  3. Add a fresh-render four-edge geometry receipt. Left/right tabs must size intrinsically along height; top/bottom tabs must size intrinsically along width; all four must continue filling the 14px cross axis and remain clickable.
  4. Keep the generic Flexbox stretch fallback and application skins unchanged.

Contract Ledger

Target surface Source of authority Proposed behavior Fallback / edge case Evidence
DockRail#createTabConfig() DockRail projection contract + button composition tab declares intrinsic main-axis flex before the parent layout pass missing title still uses dockItemId and intrinsic size unit config + fresh render
Right rail live AgentOS vessel label-sized vertical tabs grouped at the leading edge; 14px cross-axis strip retained long labels remain visible through the existing vertical writing mode current: 4×242px equal-fill defect measured
Left rail DockRail four-edge contract mirrored intrinsic vertical tabs same label policy as right NOT_YET_MEASURED
Top / bottom rails DockRail four-edge contract intrinsic horizontal tab widths; 14px cross-axis strip retained same label policy, horizontal writing mode NOT_YET_MEASURED
Neo.layout.Flexbox shared layout semantics unchanged consumers that omit flex under stretch keep equal growth existing layout suites

Acceptance Criteria

  • A fresh right-edge render with multiple tabs leaves unused main-axis rail space instead of dividing the full height equally; each visible hit box closely follows its label/padding.
  • A fresh left-edge render proves the mirrored intrinsic-height behavior.
  • Fresh top- and bottom-edge renders prove intrinsic-width behavior rather than equal-width distribution.
  • All four edges retain the 14px cross-axis strip, correct writing mode, document order, 2px gap, native click handling, and reveal behavior.
  • Focused unit coverage pins the explicit tab flex on initial construction and on tabs inserted by reconcileTabs().
  • A browser-rendered geometry test records all four edges; unmeasured rows above become concrete receipts before the PR opens.
  • The generic Flexbox fallback is unchanged, and no AgentOS/Workstation app-scoped CSS compensates for the defect.
  • Existing DockRail unit, auto-hide/reveal E2E, Workstation, and AgentOS rail journeys remain green.

Out of Scope

  • Fleet tonal hierarchy, active-tab indicator, card breakpoints, or pop-out button styling (owned by #15649).
  • The 271px AgentDetail title/provenance composition (owned by #15652 / PR #15654).
  • Reveal/dismiss/pin semantics, rail label overflow policy, or a global button redesign.
  • Changing rail thickness or the generic Flexbox stretch contract.

Avoided Traps

  • Application CSS override: would hide a shared component bug and diverge Workstation/AgentOS geometry.
  • Removing align: 'stretch': would also shrink the intended 14px cross-axis hit area.
  • Changing the global stretch fallback: would silently alter every VBox/HBox consumer that relies on equal growth.
  • Hot-setter proof: changing flex after the layout pass did not change live rects; the receipt must construct/re-project the tabs with the explicit policy present.

Related

Related: #14654, #15649, #15652, PR #15654

Origin Session ID: d8a51237-4fcc-4171-8071-a391da0be361

Retrieval Hint: "DockRail tabs flex 1 1 0 equal height huge click area four edges intrinsic"