Context
Epic #13158 (QT-parity docking polish), the auto-hide/pin gap. The model seam is DELIVERED — #13254 (PR #13256, merged) landed the persisted autoHidden item field, the setItemAutoHidden semantic operation, and the pin/auto-hide coherence (setItemPinned(…, true) clears autoHidden). This leaf is the UI consumer of that seam: the visible collapsed-to-sidebar affordance QT docking treats as table stakes.
The Problem
DockZoneModel can now persist autoHidden: true, but nothing renders it — DockLayoutAdapter projects every item as a full split/tab child regardless of autoHidden, and there's no reveal-on-hover/click or pin control. An auto-hidden item is currently invisible to the user.
The Fix (UI consumer of the #13254 model seam)
- Collapsed edge-rail render —
DockLayoutAdapter projects an autoHidden: true item as a thin edge rail (icon/title tab on the owning edge zone), not a full pane.
- Runtime-only reveal — hovering/clicking the rail overlays the item's content transiently. The reveal/hover/open geometry is runtime-only, never persisted (JSON-first guardrail —
HarnessDockZoneModel.md §Serializable vs Runtime).
- Pin affordance — a pin control toggles
setItemPinned(itemId, true) — which, per the merged model coherence, clears autoHidden and restores the item to a full pane.
Contract question (claimer settles at claim time, per #13158)
- The rail projection mode — a new
DockLayoutAdapter branch for autoHidden items vs an edge-zone decoration.
- The reveal mechanism — a runtime-only overlay riding the existing reactive
DockPreview-style pattern (visual-only, no parallel pointer system), or a container collapse.
- The pin-affordance location + how it rides the existing preview→operation descriptor path.
Binding guardrails (ADR 0020 §4)
- JSON-first — no
DOMRect/hover/reveal/open geometry in any serialized layout; reveal state stays runtime-only and converts to setItemPinned/setItemAutoHidden on commit.
- No parallel drag/pointer system — reuse the existing overlay/operation pipeline.
- No public performance claims before the Harness Endurance Benchmark (#13032).
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
DockLayoutAdapter projection |
this ticket + HarnessDockZoneModel.md |
An autoHidden: true item projects as a collapsed edge rail, not a full split/tab child |
autoHidden absent/false → unchanged full-pane projection |
HarnessDockZoneModel.md §Split Projection note |
unit: an autoHidden item yields a rail config; a visible item yields a pane |
| Runtime reveal state |
ADR 0020 §4 (JSON-first) |
Hover/click overlays content transiently; runtime-only, never serialized |
Reveal state lost on layout save/restore (by design) |
inline + §Serializable vs Runtime |
test: a saved-layout round-trip carries no reveal/hover geometry |
| Pin affordance |
merged #13254 model coherence |
Pin control toggles setItemPinned(itemId, true); the item leaves the rail and restores to a full pane |
non-pinnable item (pinnable === false) → pin control disabled |
operation table |
test: pinning an auto-hidden item clears autoHidden + re-projects as a pane |
Acceptance Criteria
- An
autoHidden: true item renders as a collapsed edge rail (not a full pane).
- Hovering/clicking the rail reveals content transiently; the reveal state is never persisted (round-trip carries no hover/reveal geometry).
- A pin affordance toggles
setItemPinned(…, true), clearing autoHidden and restoring the full pane.
- Focused unit coverage on the projection + the no-persisted-reveal guardrail; vega's
examples/dashboard/dock/ (#13247/#13278) gains a Slice demonstrating auto-hide (coordinate the slice boundary).
Dependencies
- #13254 / PR #13256 (MERGED) — the model seam (
autoHidden + setItemAutoHidden + pin coherence) this leaf consumes.
Out of Scope
- Named perspectives + grouped tab-drag (sibling #13158 leaves).
- Any change to the persisted
dockZone.v1 model (the seam is complete; this is render + runtime only).
Related
- Epic #13158 (QT-parity docking polish). Model seam: #13254 (merged). Verification surface: #13247 / #13278 (@neo-opus-vega's standalone dock example). Substrate:
src/dashboard/DockLayoutAdapter.mjs, src/dashboard/DockZoneModel.mjs, apps/agentos/view/DockPreview.mjs. Guardrails: ADR 0020.
Evidence: L2 (unit on the rail projection + the no-persisted-reveal guardrail) → L3 (visual verification via vega's #13247/#13278 example) required for the UI affordance.
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-grace (Grace).
Context
Epic #13158 (QT-parity docking polish), the auto-hide/pin gap. The model seam is DELIVERED — #13254 (PR #13256, merged) landed the persisted
autoHiddenitem field, thesetItemAutoHiddensemantic operation, and the pin/auto-hide coherence (setItemPinned(…, true)clearsautoHidden). This leaf is the UI consumer of that seam: the visible collapsed-to-sidebar affordance QT docking treats as table stakes.The Problem
DockZoneModelcan now persistautoHidden: true, but nothing renders it —DockLayoutAdapterprojects every item as a full split/tab child regardless ofautoHidden, and there's no reveal-on-hover/click or pin control. An auto-hidden item is currently invisible to the user.The Fix (UI consumer of the #13254 model seam)
DockLayoutAdapterprojects anautoHidden: trueitem as a thin edge rail (icon/title tab on the owning edge zone), not a full pane.HarnessDockZoneModel.md§Serializable vs Runtime).setItemPinned(itemId, true)— which, per the merged model coherence, clearsautoHiddenand restores the item to a full pane.Contract question (claimer settles at claim time, per #13158)
DockLayoutAdapterbranch forautoHiddenitems vs an edge-zone decoration.DockPreview-style pattern (visual-only, no parallel pointer system), or a container collapse.Binding guardrails (ADR 0020 §4)
DOMRect/hover/reveal/open geometry in any serialized layout; reveal state stays runtime-only and converts tosetItemPinned/setItemAutoHiddenon commit.Contract Ledger Matrix
DockLayoutAdapterprojectionHarnessDockZoneModel.mdautoHidden: trueitem projects as a collapsed edge rail, not a full split/tab childautoHiddenabsent/false → unchanged full-pane projectionHarnessDockZoneModel.md§Split Projection notesetItemPinned(itemId, true); the item leaves the rail and restores to a full panepinnable === false) → pin control disabledautoHidden+ re-projects as a paneAcceptance Criteria
autoHidden: trueitem renders as a collapsed edge rail (not a full pane).setItemPinned(…, true), clearingautoHiddenand restoring the full pane.examples/dashboard/dock/(#13247/#13278) gains a Slice demonstrating auto-hide (coordinate the slice boundary).Dependencies
autoHidden+setItemAutoHidden+ pin coherence) this leaf consumes.Out of Scope
dockZone.v1model (the seam is complete; this is render + runtime only).Related
src/dashboard/DockLayoutAdapter.mjs,src/dashboard/DockZoneModel.mjs,apps/agentos/view/DockPreview.mjs. Guardrails: ADR 0020.Evidence: L2 (unit on the rail projection + the no-persisted-reveal guardrail) → L3 (visual verification via vega's #13247/#13278 example) required for the UI affordance.
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-grace (Grace).