diff --git a/packages/editor/src/components/tools/item/move-tool.tsx b/packages/editor/src/components/tools/item/move-tool.tsx
index 193df651..b7eddca1 100644
--- a/packages/editor/src/components/tools/item/move-tool.tsx
+++ b/packages/editor/src/components/tools/item/move-tool.tsx
@@ -102,6 +102,17 @@ export const MoveTool: React.FC<{
const movingNode = useEditor((state) => state.movingNode)
if (!movingNode) return null
+
+ // Registry-first dispatch. Any kind registered via @pascal-app/nodes
+ // gets the imperative MoveRegistryNodeTool (smooth, framerate-locked
+ // motion via sceneRegistry — see plan: "Validated patterns from the
+ // spike"). The legacy per-kind movers below are short-circuited for
+ // any kind in the registry — that's how Phase 5 will progressively
+ // delete them as kinds migrate.
+ if (nodeRegistry.has(movingNode.type)) {
+ return
+ }
+
if (movingNode.type === 'building')
return
if (movingNode.type === 'door') return
@@ -119,13 +130,5 @@ export const MoveTool: React.FC<{
return
if (movingNode.type === 'stair' || movingNode.type === 'stair-segment')
return
- // Registry-driven kinds (any NodeDefinition with `capabilities.movable`)
- // get a generic position+rotation mover. Phase 4 may consolidate this
- // with the per-kind movers above when they all collapse to the same
- // shape. Must come BEFORE the MoveItemContent fallback because that
- // assumes the node is an ItemNode.
- if (nodeRegistry.has(movingNode.type)) {
- return
- }
return
}