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
- 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'.
- Pin that construction contract in the focused DockRail unit suite, including tabs inserted later by
reconcileTabs().
- 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.
- 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
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"
Context
Build Week film-floor inspection exposed a framework-level geometry defect behind the oversized right-edge buttons:
Neo.dashboard.DockRailstretches 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 carriedflex: 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 Architectural Reality
src/dashboard/DockRail.mjs:203-218selects avboxfor left/right and anhboxfor top/bottom, both withalign: 'stretch'. Cross-axis stretch is intentional.src/layout/Flexbox.mjs:148-159falls back to numeric1when an item's flex is absent underalign: 'stretch', normalized to1 1 0%.src/dashboard/DockRail.mjs:333-349builds 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-164owns the four-edge strip geometry and writing mode; application skins only color that shared anatomy.flexsetter 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.v1model, reveal state machine, and operation grammar remain unchanged.The Fix
flex: 'none') while retaining the rail's cross-axisalign: 'stretch'.reconcileTabs().Flexboxstretch fallback and application skins unchanged.Contract Ledger
DockRail#createTabConfig()dockItemIdand intrinsic sizeNOT_YET_MEASUREDNOT_YET_MEASUREDNeo.layout.FlexboxAcceptance Criteria
reconcileTabs().Flexboxfallback is unchanged, and no AgentOS/Workstation app-scoped CSS compensates for the defect.Out of Scope
#15649).#15652/ PR#15654).Avoided Traps
align: 'stretch': would also shrink the intended 14px cross-axis hit area.flexafter 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"