LearnNewsExamplesServices
Frontmatter
id15137
titleMake preserved-identity DockFlip moves clip-safe and immediate
stateClosed
labels
bugaitestingregressioncore
assigneesneo-gpt-emmy
createdAtJul 13, 2026, 11:27 PM
updatedAt7:09 AM
githubUrlhttps://github.com/neomjs/neo/issues/15137
authorneo-gpt-emmy
commentsCount0
parentIssue13158
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAt7:09 AM
milestonev13.2

Make preserved-identity DockFlip moves clip-safe and immediate

Closed Backlog/active-chunk-5 bugaitestingregressioncore
neo-gpt-emmy
neo-gpt-emmy commented on Jul 13, 2026, 11:27 PM

Context

The visual verification pass on #15099 / PR #15133 separated two defects that looked like one flicker:

  1. the projection transaction broke silent=true inside Neo.tab.Container.removeAt(), allowing tab titles to change before the common-parent body move;
  2. after repairing that ownership breach, one brief blank-looking frame remains at the start of the FLIP inversion.

The first defect belongs to PR #15133. This ticket isolates the remaining motion problem instead of expanding that PR into a shared animation redesign.

Empirical evidence from the repaired tree:

  • three independent live runs sampled 979–997 requestAnimationFrame frames with zero active-header/empty-body intervals and zero page errors;
  • destination content was mounted and coherent before DockFlip.play() began;
  • sequential playback still showed one frame where the transformed pane was outside the destination tab body's visible clip;
  • the same-identity path also spent roughly 116–141 ms in stage A waiting for captured markers to detach, even though atomic DOM permanence deliberately keeps those exact nodes connected.

The Problem

Neo.main.addon.DockFlip currently models a projection swap as outgoing marker nodes detaching and replacement marker nodes appearing. Neo's native atomic cross-parent move has a second, stronger reality: the same pane DOM nodes survive and are reparented.

On that preserved-identity path:

  • stage A burns several frames waiting for a detach that must not happen;
  • inversion applies the old cross-parent geometry to an element already inside its destination .neo-tab-body-container;
  • that body owns overflow: hidden, so the transformed pane can sit outside its final clip for a frame while its header remains visible.

The document and pane identities are correct; the presentation briefly tells a false story.

The Architectural Reality

  • src/main/addon/DockFlip.mjs#captureFirst/play owns presentation-only First/Last/Invert/Play motion.
  • src/container/Base.mjs#insert and the tab/body adapters own same-window DOM permanence through silent source removal plus one closest-common-parent update.
  • resources/scss/src/tab/Container.scss intentionally clips tab bodies; globally disabling that clip is not a safe motion solution.
  • src/dashboard/DockMotionSignal.mjs remains the sole counted lifecycle signal.
  • Closed #14929 established FLIP as the committed-operation motion layer. This ticket repairs its preserved-identity path; it does not move authority into Demo C.

The Fix

Teach DockFlip to distinguish replacement-node swaps from preserved-identity cross-parent moves.

  1. If the post-projection marker set is exactly the captured connected identities, bypass the detach wait and measure Last immediately.
  2. Give cross-clipping moves a presentation path that remains visible from First to Last. Prefer a host-owned overlay/staging projection or another bounded mechanism that preserves the real tab-body clip; do not make every tab body globally overflow-visible.
  3. Retain the current direct transform path for moves whose First geometry remains visible within the destination clipping context.
  4. Keep entering/replacement-node behavior, reduced-motion collapse, token timing, and DockMotionSignal ownership unchanged.
  5. Restore every temporary node/style on success, rejection, interruption, and destroy.

Contract Ledger

Target surface Source of authority Proposed behavior Fallback Docs Evidence
DockFlip.play() identity branch captured marker node identities same connected set skips detach polling replacement/ambiguous set uses bounded existing poll method JSDoc focused unit timing oracle
cross-parent visual projection First/Last rects + nearest clipping context pane remains visible for every painted frame unsafe/failed staging lands final geometry instantly method JSDoc sequential-frame + mounted browser proof
tab-body clipping resources/scss/src/tab/Container.scss normal overflow: hidden contract remains intact no global override none computed-style assertion
motion lifecycle Neo.dashboard.DockMotionSignal one counted signal covers the real motion interval fail-safe clears existing owner existing class contract zero leaked signal/style assertions
reduced motion dashboard motion tokens instant landing, no staging residue exact 0ms remains meaningful existing token docs unit + browser assertion

Decision Record impact

none — this is aligned with the presentation-only FLIP contract from closed #14929 and the native atomic-move contract.

Acceptance Criteria

  • A preserved marker set skips stage-A detach polling; a replacement marker set retains the bounded wait.
  • Split and return operations expose no painted frame where a visible active tab header has fully clipped/blank pane content.
  • The moved pane component id and DOM node identity remain unchanged.
  • Normal tab-body overflow: hidden remains unchanged before, during, and after motion unless a narrower host-owned staging layer proves necessary.
  • No global overflow: visible selector is introduced.
  • Reduced motion lands instantly with no temporary node, style, class, timer, or signal residue.
  • Success, rejection, destroy, and post-invert failure paths restore all temporary presentation state.
  • Focused DockFlip unit coverage pins both identity branches and cleanup.
  • Mounted Demo C evidence includes a sequential-frame oracle for the split and return beats, not only DOM-presence checks.

Out of Scope

Changing dock documents or reducers; replacing Demo C's tab chrome (owned by #15136); generic keyed VDOM reconciliation; cross-window choreography; changing the motion vocabulary.

Avoided Traps

  • Global overflow override: a live-only experiment interfered with the tour completion contract and changes normal tab semantics.
  • Calling this a video-only artifact: random-access WebM seeking amplified the symptom, but sequential playback retained the one clipped motion frame.
  • Changing the transfer again: repaired live traces prove content is coherent before DockFlip starts.
  • Using a screenplay delay: timing cannot repair an invalid clipping geometry.

Related

Related: #13158 · #14929 · #15099 · #15136 · PR #15133

Live latest-open sweep: checked latest 20 open issues at 2026-07-13T21:27:12.827Z; no equivalent found. The nearest ticket, #15136, explicitly excludes FLIP geometry motion. A2A all-state recency sweep: latest 30 messages checked immediately before creation; no overlapping claim or intent.

Origin Session ID: f95e01ff-ba36-409a-98af-573263fab247

Retrieval Hint: DockFlip preserved identity connected markers tab body clipping blank frame stage A detach wait

tobiu referenced in commit 09a0c39 - "fix(dashboard): keep preserved dock motion clip-safe (#15137) (#15143)" on 7:09 AM
tobiu closed this issue on 7:09 AM