# Independent simultaneous-movement core review — 2026-09-23 Scope: frozen local `crates/oa-core/src/diagram_edit.rs`, `tests/group_movement.rs`, and `lib.rs` export, against `harness/multiselect-contract-20260923.md` and base `b8685416f56e53e30bd11ecf93a54cea10ac8458`. This is a static correctness/design review, not a passing build, test execution, GUI or final-feature acceptance claim. No production files were edited and no Cargo command ran. Reviewed file SHA-256 values: - `diagram_edit.rs`: `7F307D64FE09947973871A05BC8D5DCA82B64B65A8E6B3AAED22D6EFC6497962` - `group_movement.rs`: `BADEC10713B9E9961330A1A77710B6D0D75C27B482281B02BEA6868C52B8F994` ## Findings, in priority order **No verified blocking correctness defect in the pure geometry planner.** There is one concrete scaling concern and two nonblocking coverage extensions. The latter are not claims that the implementation currently behaves incorrectly. 1. **P2 — applying the emitted batch performs a full project-identity enumeration for every moved placement.** `diagram_edit.rs:74` emits one `EditNode` per placement. Its existing handler (`session.rs:530–544`) calls `reidentify_tracked`, and `reidentify` invokes `Project::contains` before the same-ID early return (`session.rs:873–879`). `Project::contains` builds the entire `identities()` vector (`model.rs:1761–1781`). Thus applying a group of M placements adds O(M × P) identity enumeration/allocation for P project records, although every placement retains its ID. This is a verified code-path cost, not a measured latency defect. It matters especially if a future preview applies the whole command on every pointer event. The planner itself computes parents once and has no repeated full-project clone. Recommended follow-up: measure representative large nested selections before choosing the preview path; if needed, skip identity remapping for an unchanged placement UUID after the handler's existing-node check, or apply validated geometry records through a preview path without full session execution. Do not widen this into unrelated transaction refactoring. 2. **P3 — new-planner tests do not directly exercise projection-derived ancestry differing from semantic ancestry.** Current nested coverage uses an Activity child (`group_movement.rs:27`, `:148`). `projection::parents` specifically replaces work ancestry with allocation grouping and makes Traceability placements flat (`projection.rs:94–138`). The planner correctly calls that authoritative helper, so no divergent implementation was found. A compact follow-up fixture should select an allocated performer plus a selected work descendant and assert all visually grouped work moves exactly once without changing allocations; an equivalent Traceability fixture should assert an unselected semantic child remains stationary. Existing `release_routing.rs:403–494` covers portions of Allocation grouping through old `MoveNode` and route helpers, but not the new command planner's final whole-model result. 3. **P3 — the new end-to-end preservation fixture uses default attachment/port-anchor data.** The route fixture always has `source_attachment: None` and `target_attachment: None` (`group_movement.rs:7–11`); the typed-port case has no authored `port_anchors` (`:221`). Clone-and-change implementation preserves them by inspection, and label metadata is already exercised. Populate at least one manual edge attachment and one owner-port anchor, then retain the whole-project equality and source round-trip assertion. This would make the contract's authored attachment preservation observable rather than relying exclusively on inspection. ## Correctness traced to authoritative behavior - Admission checks the diagram, nonempty set, every exact placement membership, and finite delta before the zero-motion return (`diagram_edit.rs:18–36`). A foreign or missing selected placement cannot disappear into a partial move, including zero delta. Typed visual-target admission, visibility and stale document/revision checks remain adapter responsibilities; the helper intentionally receives placement IDs only. - The closure in `:38–50` traverses `projection::parents` with a deduplicating visited set. It is equivalent to the existing `descendant_nodes` ancestry relation for accepted project snapshots, includes folded placements because folding is not used to filter `parents`, and cannot double-translate overlapping selected roots. It correctly preserves Traceability's flat projection and Allocation's visual parenting by delegation. - Route derivation in `:51–52` uses the original view and the complete union of displacement entries. `translated_routes` resolves actual endpoint owner placements, including ports, requires both owners to move by equal delta, handles State Entry/Exit containing boundaries, and clones changed routes (`projection.rs:169–224`; `projection/state.rs:119–144`). One-ended routes remain exact; label offsets and attachment fractions are retained. This addresses the independent-root failure of sequential `MoveNode` calls. - Each placement clone changes only x/y (`diagram_edit.rs:55–78`). Bounds match existing validation: finite values within `MAX_COORDINATE`, positive bounded dimensions (`validation.rs:820–840`). Translated route pins are checked before returning a batch. Partial command construction cannot mutate the immutable input or escape on error. - `EditNode` with the unchanged ID retains provenance; `SetEdgeRoute` updates its existing entry in place, retaining unrelated route ordering (`session.rs:749–755`). Batch execution prepares one candidate, validates the final state, and publishes one history entry only if the candidate changed (`session.rs:172–198`, `:250–269`, `:386–395`). The planner's returned command-selection ID is the last changed record rather than the user's primary; its doc comment correctly warns adapters not to adopt it as primary selection. - Desktop `Document::execute` performs source update before committing (`document.rs:322–335`), so using this existing command path preserves model/source atomicity. The planner does not itself enforce source-draft or focus guards and should not be treated as doing so. Existing `Document::commit` suppresses unchanged source bundles (`:399–406`); the new zero-motion test directly proves only the core Session contract, not a desktop gesture/source-draft integration. ## Test review and evidence limits The main sibling test (`group_movement.rs:71`) independently assigns three exact expected positions and the internal route pin, then compares the entire Project. It proves intent independently of `translate_placements`, rather than comparing a preview and commit that share the same bug. It also includes a useful negative control showing sequential old moves retain the original internal pin, one Undo/Redo, JSON round-trip, and source-update/recompile preservation with a comment. The typed-port test independently constructs its complete expected Project (`:221`). The folded-overlap test partly compares two planner outputs, but also independently asserts the hidden child's exact position and unchanged routes (`:148`). The invalid-input test covers unknown diagram, empty/mixed/missing membership, nonfinite/overflow deltas, translated route overflow, no mutation, and zero history (`:183`). The State boundary test checks independent expected route coordinates when the boundary moves and unchanged pins when it does not (`:269`); it is intentionally narrower than a whole-project comparison. The input immutability assertions are inherently weak by themselves because the helper takes `&Project`; their value is secondary to the complete expected-result assertions. No test-run result was inferred from reading test source. No GUI adapter, mixed target-set admission, allocation reassignment, Process/Scenario reorder, stale input, preview latency, or full feature completion was reviewed or accepted here. Overall: the frozen foundation implements the selected pure-geometry contract coherently. Retain the pending performance check and targeted coverage extensions while proceeding to adapter work; neither a successful compile nor this review alone establishes interaction acceptance.