Context
Operator directive (2026-07-10, live session): the drag → drop-target → animated re-layout loop is PRIO 0 for the docking epic — Qt-ADS is the designated capability floor (ADR 0029 §1 already names it "the capability bar"), and a committed dock operation that snaps instead of gliding reads as below that floor on sight. Gap confirmed by tree audit this session: none of the 46 #13158 decomposition leaves owns the commit-animation mechanism; the Demo-A showcase AC ("every shipped v1 op appears with animated transitions", #14589) presumes a mechanism that does not exist.
The Problem
Today every committed operation — human drop, rail restore click, NL execute_dock_operation, tour beat — flows through the reducer-container loop (applyDockZoneOperation → onDockZoneDocumentChange → DockLayoutAdapter.project() → re-render) and the projected tree swaps instantly. The dock feels like a page refresh, not a layout choreography. The drag preview tier animates (the DockPreview affordances transition at 120ms), but the commit — the moment that matters — does not. This is the single biggest visible-quality gap between the shipped substrate and the Qt-ADS floor.
The Architectural Reality
- The sanctioned mutation path is ADR 0029 §2.1's reducer-container pattern: interaction surfaces emit descriptors; the reducer commits; the view-sync re-projects. Animation must ride the view-sync seam (
onDockZoneDocumentChange → re-projection) as a presentation-only layer — document truth never waits on motion.
- FLIP (First-Last-Invert-Play) is the right class of mechanism: capture pre-op geometry of surviving panes (First), let the re-projection land (Last), invert via CSS transforms, play the transition. Surviving-instance identity matters:
reconcileTabs()-style instance preservation (the DockRail precedent) and the update-collision bookkeeping fix (#14911/PR #14923) are the substrate that makes FLIP correlation possible.
- Placement (structural pre-flight, sibling fast-path): a new
src/dashboard/ module beside DockLayoutAdapter/DockSplitter (e.g. DockFlipAnimator.mjs) + an opt-in hook at the workspace re-projection call site. Main-thread DOM measurement rides the existing Neo.main.DomAccess rect surfaces (get_dom_rect class) — no parallel measurement system.
- Reduced-motion:
prefers-reduced-motion: reduce renders the instant path (tree line I2's compliance bar); the tour runner's record mode already refuses to capture under reduced motion, so takes always show the choreography.
The Fix
One PR: the FLIP layer + workspace integration + motion proof:
DockFlipAnimator (or equivalent) — captures First rects for surviving projected nodes keyed by stable identity (item ids / node ids), applies invert transforms post-projection, plays with the design language's easing (the Demo-A artifact fixes 240–280ms standard-decelerate), cleans up on transition end; fail-safe = instant landing (animation errors must never wedge layout).
- Opt-in wiring at the workspace view-sync seam (
examples/dashboard/dock MainContainer + the dockdemo childapp both adopt it) — one config, zero reducer coupling.
- Reduced-motion instant path + destroy-safety mid-transition (the
#14923 corpse class must not return via animation clones).
- Motion evidence:
observe_motion assertions on the demo path (no-jank per the #14589 AC); unit specs for rect-correlation and fail-safe behavior.
Acceptance Criteria
Out of Scope
- Drag-preview affordance visuals + the human-drag showcase beat (sibling leaf, filed alongside).
- Cross-window FLIP continuity (detach/reattach animation across OS windows — later leaf, after the E/C tranches).
- Any reducer/document-schema change (presentation tier only).
Avoided Traps
- Animating via vdom-diff side effects or per-scene CSS hacks in the demo: demo-local transitions would fake the story for the camera while human drops still snap — the exact mechanically-false-story class review keeps convicting. One mechanism serves both.
- Coupling correctness to motion: step settledness (tour runner) and document truth stay synchronous; animation is fire-and-forget presentation.
Decision Record impact
aligned-with ADR 0029 — rides the §2.1 view-sync seam; no authority change.
Related: parent #13158 · consumers #14589 / examples/dashboard/dock · substrate #14906 (instance-preserving reconcile), #14923 (destroy bookkeeping) · sibling: the human-drag showcase/polish leaf (filed with this one) · boundary #14913 (cross-zone drop regression, claimed).
Live latest-open sweep: checked latest 20 open issues at 2026-07-10T04:4xZ; no equivalent (nearest: #14913 regression, #14789 fusion demo). A2A in-flight claim sweep: herd window scanned same-turn; no overlapping claim (Grace's #14913 claim = the cross-zone drop regression, different scope).
Origin Session ID: 54156254-a1a8-40b3-ba22-86e7d2a1bf81
Retrieval Hint: "FLIP animated dock re-layout committed operation view-sync presentation-only"
Context
Operator directive (2026-07-10, live session): the drag → drop-target → animated re-layout loop is PRIO 0 for the docking epic — Qt-ADS is the designated capability floor (ADR 0029 §1 already names it "the capability bar"), and a committed dock operation that snaps instead of gliding reads as below that floor on sight. Gap confirmed by tree audit this session: none of the 46
#13158decomposition leaves owns the commit-animation mechanism; the Demo-A showcase AC ("every shipped v1 op appears with animated transitions",#14589) presumes a mechanism that does not exist.The Problem
Today every committed operation — human drop, rail restore click, NL
execute_dock_operation, tour beat — flows through the reducer-container loop (applyDockZoneOperation→onDockZoneDocumentChange→DockLayoutAdapter.project()→ re-render) and the projected tree swaps instantly. The dock feels like a page refresh, not a layout choreography. The drag preview tier animates (theDockPreviewaffordances transition at 120ms), but the commit — the moment that matters — does not. This is the single biggest visible-quality gap between the shipped substrate and the Qt-ADS floor.The Architectural Reality
onDockZoneDocumentChange→ re-projection) as a presentation-only layer — document truth never waits on motion.reconcileTabs()-style instance preservation (theDockRailprecedent) and the update-collision bookkeeping fix (#14911/PR#14923) are the substrate that makes FLIP correlation possible.src/dashboard/module besideDockLayoutAdapter/DockSplitter(e.g.DockFlipAnimator.mjs) + an opt-in hook at the workspace re-projection call site. Main-thread DOM measurement rides the existingNeo.main.DomAccessrect surfaces (get_dom_rectclass) — no parallel measurement system.prefers-reduced-motion: reducerenders the instant path (tree line I2's compliance bar); the tour runner'srecordmode already refuses to capture under reduced motion, so takes always show the choreography.The Fix
One PR: the FLIP layer + workspace integration + motion proof:
DockFlipAnimator(or equivalent) — captures First rects for surviving projected nodes keyed by stable identity (item ids / node ids), applies invert transforms post-projection, plays with the design language's easing (the Demo-A artifact fixes 240–280ms standard-decelerate), cleans up on transition end; fail-safe = instant landing (animation errors must never wedge layout).examples/dashboard/dockMainContainer + the dockdemo childapp both adopt it) — one config, zero reducer coupling.#14923corpse class must not return via animation clones).observe_motionassertions on the demo path (no-jank per the#14589AC); unit specs for rect-correlation and fail-safe behavior.Acceptance Criteria
prefers-reduced-motionrenders the instant path; the tourrecordprecondition still guarantees motion-on for takes.#14911regression via animation).observe_motionno-jank evidence on the Demo-A tour path; unit coverage for correlation + fail-safe.#14589(its animated-transitions AC binds to this mechanism) and by human drops inexamples/dashboard/dock.Out of Scope
Avoided Traps
Decision Record impact
aligned-with ADR 0029— rides the §2.1 view-sync seam; no authority change.Related: parent
#13158· consumers#14589/examples/dashboard/dock· substrate#14906(instance-preserving reconcile),#14923(destroy bookkeeping) · sibling: the human-drag showcase/polish leaf (filed with this one) · boundary#14913(cross-zone drop regression, claimed).Live latest-open sweep: checked latest 20 open issues at 2026-07-10T04:4xZ; no equivalent (nearest:
#14913regression,#14789fusion demo). A2A in-flight claim sweep: herd window scanned same-turn; no overlapping claim (Grace's#14913claim = the cross-zone drop regression, different scope).Origin Session ID: 54156254-a1a8-40b3-ba22-86e7d2a1bf81 Retrieval Hint: "FLIP animated dock re-layout committed operation view-sync presentation-only"