fix(ui): port source-aware toolbar drops

Plan retail shortcut drops from a complete post-lift snapshot so fresh inventory items use cyclic-right displacement while toolbar aliases restore to their vacated slot. Apply local mutations atomically, preserve raw shortcut fields, emit exact Remove/Add ordering, and retire AP-102 after the live ACE gate.

Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-11 09:26:57 +02:00
parent b5b230c860
commit 3281e0acb4
8 changed files with 462 additions and 23 deletions

View file

@ -474,9 +474,9 @@ same slot after a clean reconnect.
- [ ] Add a pure `ShortcutDropPlanner` keyed by source kind: toolbar reorder,
inventory fresh add, occupied target, inventory-button target,
off-bar removal, and full-stack merge replacement.
- [ ] For an inventory-to-occupied-slot drop, place the displaced shortcut at
- [x] For an inventory-to-occupied-slot drop, place the displaced shortcut at
retail's first-empty-to-the-right slot, never at the inventory grid index.
- [ ] Validate the complete mutation before changing state, apply it atomically, and
- [x] Validate the complete mutation before changing state, apply it atomically, and
emit exact Remove/Add wire ordering. Use pending/confirm/rollback only where the
protocol actually exposes rejection; never leave a partially mutated bar.
- [ ] On full-stack merge, rekey every matching object shortcut and preserve the
@ -487,9 +487,21 @@ explicit neutral/accept/reject result instead of a Boolean. Inventory and
paperdoll enforce retail's `(DropItemFlags & 0xE) == 0` physical-item gate, so a
toolbar alias released on either surface only leaves its remove-on-lift shortcut
removal in place; it cannot move, unwield, or wield the underlying object. The
remaining source-aware occupied-toolbar transaction and raw-field preservation
stay in Wave 4.2/4.3. Live gate passed with an equipped helmet: dropping its
toolbar alias onto inventory removed only the shortcut and left the helmet worn.
raw-field preservation landed in Wave 4.2. Live gate passed with an equipped
helmet: dropping its toolbar alias onto inventory removed only the shortcut and
left the helmet worn.
**Wave 4.3b implementation (2026-07-11):** a pure Core `ShortcutDropPlanner`
now plans the complete post-lift mutation before state changes. Fresh inventory
drops use the exact cyclic-right search; aliases use only the vacated toolbar
source; duplicate-object removal, wraparound, a full bar, visually empty non-object
records, exact wire order, and raw full-stack rekeying have conformance fixtures.
`ToolbarController` applies the validated local transaction atomically, then emits
its ordered Remove/Add events. AP-102 is retired; 4,646 tests pass. The live
inventory-to-occupied displacement plus toolbar-reorder gate passed 2026-07-11.
Inventory-button placement and
the upstream full-stack-merge notice owner remain part of the unchecked umbrella
items above rather than being implied complete by this slice.
### 4.4 Finish toolbar controls