LearnNewsExamplesServices
Frontmatter
id12880
titleSortZone drag landing index overshoots target, scaling with path length
stateClosed
labels
bugaigrid
assigneesneo-fable
createdAtJun 11, 2026, 2:17 AM
updatedAtJun 11, 2026, 9:24 AM
githubUrlhttps://github.com/neomjs/neo/issues/12880
authorneo-fable
commentsCount5
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 11, 2026, 9:24 AM

SortZone drag landing index overshoots target, scaling with path length

neo-fable
neo-fable commented on Jun 11, 2026, 2:17 AM

Context

Split from #12878 (2026-06-11 night, operator grid-polish directive). While live-verifying the locked-region corruption fixes, the characterization rig isolated a second, mechanically independent defect: the landing index of a column drag overshoots the drop position, and the overshoot scales with drag path length. It is deterministic (identical landing across three separate runs of the same dispatch sequence).

The Problem

Live evidence (devindex, 1680×1000, fresh baselines, engine-truth assertions via Neural Link):

Case Drag Drop intent Actual landing Overshoot
1b Total x437 → x500 (short) center idx 1 idx 2 +1
1 Total x437 → x585 (longer) center idx 1–2 idx 5 +3
2 Rank x107 → x350 (within 3-item start region) start idx 2 idx 2 ✓ masked by region clamp (index < maxItems)

The locked-state itself stays correct post-#12878-fix (no membership changes) — this is purely placement accuracy. Small regions look correct only because currentIndex clamps at the region edge; long center drags land visibly wrong.

The Architectural Reality

  • The within-region switch cadence lives in the parent src/draggable/container/SortZone.mjs onDragMove (delta = clientX - ownerX + scrollLeft - offsetX - itemRects[index].left, threshold nextRect.width * 0.55, one switchItems per qualifying move) — i.e. the defect is probably not locked-grid-specific: any dragResortable toolbar (tab headers included) may overshoot on long paths.
  • Hand-simulating the dispatched event sequence against that math predicts landing idx 2 for case 1; the live result is idx 5 — the extra switches need instrumented observation (log currentIndex transitions + delta/offsetX per drag:move), not more code-reading. Two code-reading hypotheses already died on this lane tonight (see #12807's history) — instrument first.
  • Candidate suspects for the instrumentation pass (NOT asserted): offsetX semantics at DragZone level; Mouse-sensor re-fire cadence (Mouse.mjs fallback timer) delivering extra drag:move events that re-qualify against mutated itemRects; switchItems rect bookkeeping for unequal widths.
  • Reproduction recipe (agent-executable, no human eyes): the #12878 rig — preview browser on /apps/devindex/index.html, in-page dispatch mousedown(clientX, buttons:1) → 150ms → document mousemove (Δ≥10, ~60ms cadence) → mouseup, assert toolbar vdom.cn order via Neural Link.

The Fix

  1. Instrument container.SortZone#onDragMove live (rig above): capture per-event clientX, offsetX, delta, currentIndex transitions for cases 1/1b.
  2. Localize the over-switching mechanism from the trace; fix in the parent class (cadence/threshold/offset — whichever the trace convicts).
  3. Verify single-region neutrality: a no-locked-columns toolbar (e.g. tab header) must keep its current behavior for short drags.
  4. Regression spec via the #12807 simulatability substrate once it lands (its lane is active), or the documented rig protocol.

Acceptance Criteria

  • AC1: Instrumented trace of cases 1/1b attached to this ticket (per-event delta/index transitions)
  • AC2: Drop position maps to the visually adjacent landing index for short AND long drags (cases 1, 1b, plus one ≥8-slot drag)
  • AC3: No behavior change for single-region toolbars on short drags (tab-header sanity check)
  • AC4: Regression coverage at L3+ via #12807 substrate or the documented rig protocol

Out of Scope

  • Locked-region membership / lock-state correctness — fixed under #12878 (PR linked there).
  • The #12807 simulatability substrate itself (@neo-opus-ada's claimed lane).

Avoided Traps

  • Third code-reading root-cause without instrumentation — two prior hypotheses on this defect family were refuted by live behavior; the trace comes first.
  • Fixing in the grid subclass — the cadence lives in the parent; a grid-local patch would mask the same defect on tabs/toolbars.

Decision Record impact

none.

Related

Parent context: #12878 (split origin; its fix PR documents the boundary). Verification substrate: #12807 (active, @neo-opus-ada). Multi-body umbrella: #9486. Evidence comments: https://github.com/neomjs/neo/issues/12878#issuecomment-4675823020 (pre-fix matrix) + the post-fix verification comment on #12878.

Release classification: ON the board — operator grid-polish directive covers placement accuracy; visible jank in the flagship grid demo. De-board is the operator's one-word call if he scopes polish to corruption-only.

Origin Session ID: 567191c3-16f6-4235-914c-b51fc94d1514 Retrieval Hint: query_raw_memories("SortZone landing overshoot cadence devindex rig"); the dispatch recipe + rig live in #12878's comments and @neo-fable's standing-lanes memory.

Live latest-open sweep: checked latest 15 open issues at 2026-06-11T00:1xZ; no equivalent (closest: #12878 = the corruption split, #12807 = sim substrate). A2A in-flight sweep: @neo-opus-ada's [lane-claim] covers #12807 sim substrate only — explicit lane boundary agreed (her message MESSAGE:e80c46f5, my confirm MESSAGE:298fa1b3); no claim on this defect.

tobiu referenced in commit b190f60 - "fix(draggable): stabilize SortZone landing index (#12880) (#12882)" on Jun 11, 2026, 3:38 AM
tobiu closed this issue on Jun 11, 2026, 3:38 AM
tobiu referenced in commit e01d19e - "fix(grid): restore locked-grid drag landing accuracy (#12880) (#12891) on Jun 11, 2026, 9:24 AM
tobiu closed this issue on Jun 11, 2026, 9:24 AM