LearnNewsExamplesServices
Frontmatter
id14959
titleDock drop-indicator menu: candidate-set producer extension + DockDropIndicators + the cold-open drag beat
stateClosed
labels
enhancementai
assigneesneo-fable-clio
createdAtJul 10, 2026, 1:53 PM
updatedAtJul 10, 2026, 11:56 PM
githubUrlhttps://github.com/neomjs/neo/issues/14959
authorneo-fable-clio
commentsCount0
parentIssue13158
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 10, 2026, 9:33 PM

Dock drop-indicator menu: candidate-set producer extension + DockDropIndicators + the cold-open drag beat

Closed Backlog/active-chunk-5 enhancementai
neo-fable-clio
neo-fable-clio commented on Jul 10, 2026, 1:53 PM

Context

Split from #14930 (scope replacement, not addition): the parent leaf proved to be two PR-sized tiers — the design tier (the §06 authority section + the DockPreview FM/motion-contract polish, delivered by PR #14955, which now resolves the narrowed #14930) and this leaf: the implementation tier that builds the indicator experience the authority specifies. Operator PRIO-0 lineage (2026-07-10): the drag → visible-options → drop loop is the felt Qt-parity floor.

The Problem

The §06 authority decides the interaction model — the indicator-overlay menu as the primary drag affordance — but nothing renders it yet: DockPreviewProducer computes ONE affordance from pointer position, no component renders an option menu, and no showcase films a human drag.

The Architectural Reality

  • Producer extension (src/dashboard/DockPreviewProducer.mjs): expose the full valid-candidate set for the hovered area (the per-pointer-position single affordance derives from it today) — presentation-tier surface change; the reducer contract and previewToOperation stay untouched. Gated on PR #14933 (open), which owns the producer file in flight.
  • DockDropIndicators (new src/dashboard/ sibling, structural fast-path): renders the candidate set as the §06 menu — 5-position cross on the hovered area + container edge chips; hovering an indicator drives the existing DockPreview target-region highlight; drop commits through previewToOperation unchanged; Escape cancels (absorbs tree line C5, single-window). Real child components on the composition bar (the #14906 precedent), FM tokens, motion via --dock-transition-*.
  • The cold-open camera beat: ~15s of human drag with the menu lit on the Demo-A surface, before the tour ("now watch an agent do it") — consumes the two pieces above.

The Fix

One PR per slice as they unblock: producer extension (post-#14933), the indicator component + its unit contract specs, the beat staging on the dockdemo surface. The §06 artifact section is the binding authority for every visual/interaction decision — deltas amend the artifact first.

Acceptance Criteria

  • Producer exposes the full candidate set for a hovered area; existing single-affordance callers unchanged.
  • DockDropIndicators renders cross + edge chips from the candidate set; hover previews the exact target region (accept/reject policy-honest); Escape cancels mid-drag.
  • Real-component composition (no raw-vdom synthesis); FM tokens; --dock-transition-* motion; reduced-motion compliant.
  • The Demo-A cold-open beat films the experience; recordable per the tour contract.
  • Unit contract specs; the live gesture tier rides the #14591 animation half.
  • Cross-family review before merge.

Out of Scope

  • The design authority + DockPreview polish (delivered: PR #14955 → the narrowed #14930).
  • Grouped-drag proxy (E-tranche) · cross-window drag scenes (#14772) · the non-FLIP transition classes (#14949, Grace).

Decision Record impact

aligned-with ADR 0029 — presentation tier over the §2.1 seams; the §06 artifact section is the design authority of record.

Related: parent #13158 · split-from #14930 · authority PR #14955 · gates: PR #14933 (producer file) · siblings #14949 (Grace), #14929 (FLIP) · consumer #14591 animation half.

Contract Ledger — neo.harness.dockCandidates.v1 (backfilled per PR #14974 review cycle 1)

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
CANDIDATES_SCHEMA + isValidCandidateSet (src/dashboard/dockPreviewContract.mjs) §06 of the dock-choreography artifact (PR #14955) + ADR 0029 §2.3 purity rules Fail-closed COMPLETENESS gate: exactly 5 unique cross positions + (when root present) exactly 4 unique chips; every candidate wraps an individually valid dockPreview.v1 carrying the set's itemId, targeting the hovered zone (cross) / root (chips), with placement matching its visual position as a full direction/kind/AXIS tuple per the §06 grammar (crossPlacementMatchesPosition — split kinds must carry vertical from top/bottom, horizontal from left/right; axis hardening per #14983 / PR #14990) Any partial/duplicated/mismatched/lying menu → false → the indicator layer hides (never renders a menu misrepresenting the drop) JSDoc on the module (Anchor & Echo) Unit: producer emissions on BOTH grammar axes = positive controls + 12 negative probes incl. the review falsifiers (one-entry center→edge-left; the four perpendicular-axis split tuples)
DockPreviewProducer.produceCandidates() Same grammar as produce() — ONE shared buildPreview assembly path Emits the full menu for the hovered zone; root chips omitted when no root supplied OR hovered zone IS the root No zone under pointer / no itemId → null JSDoc Unit: grammar parity (candidate ≡ pointer preview, deep-equal), fail-closed paths
DockDropIndicators (consumer) Commit-free, pointer-transparent contract (class JSDoc) Renders/selects candidates geometrically; never converts or commits Invalid set / missing hostRect → cls-hidden JSDoc Unit: 9 component specs; e2e: the real-pointer §06 journey (DemoADragMenuNL.spec.mjs)
Drop commit path (DemoAWorkspace.onDockCrossZoneDrop) previewToOperation UNCHANGED (ticket AC) Release-point re-hit-test (release truth, never cached hover); candidate must carry the gesture's itemId; else pointer-inference fallback; Escape-suppressed → nothing No candidate + no geometry → no commit JSDoc Unit: 3 drop-truth pins (incl. the (999,999) stale-selection falsifier); e2e: commit + Escape journeys

Live latest-open sweep: latest-20 checked immediately before create; no equivalent (nearest #14949 = the non-FLIP motion classes, disjoint). A2A herd window: no competing claim on the indicator tier.

Origin Session ID: 748f9b8f-20cd-4360-9a29-c3084d059052 Retrieval Hint: "dock drop indicator menu candidate set cross edge chips cold open drag beat"

tobiu referenced in commit 9fa53b7 - "feat(dashboard): the drop-indicator menu — candidate-set producer + DockDropIndicators + the Demo-A §06 experience (#14959) (#14974) on Jul 10, 2026, 9:33 PM
tobiu closed this issue on Jul 10, 2026, 9:33 PM