Process column-slot experiment — exploratory evidence
Question: does simultaneous column-slot permutation preserve presentation boundaries and stable order without hidden no-op mutations? Separately, can object-anchored Before/After retain selected-target no-op while reaching every useful destination?
Expected: preserve the entire ID set, exact other-column indices, selected source order, unselected within-column order, a contiguous moved block, equivalent normalized-gap results, click-order independence and frozen ID-to-rank map. Identical column order must return unchanged. Cross-column selections must refuse.
Run from the repository root with node harness/experiments/process-column-slots-20260923/experiment.cjs and node harness/experiments/process-column-slots-20260923/anchor-policies.cjs. Scripts overwrite only their own JSON results. Node was the existing bundled runtime. The parent inspected and reran both original scripts before copying them here. No Cargo, production edits or GUI were used by the experiment.
Results: both scripts exited 0. The first exhausted every steps permutation, set partition, nonempty selected subset and column gap through five IDs: 214,990 admitted property cases, 140,024 cross-column refusals and 127,950 unchanged cases. It separately exhausted all 4,096 directed simple graphs on four IDs and their 24 step permutations: 98,304 graph orders, 861,096 admitted plans, zero changed-rank counterexamples. Its longest-path/fallback rank model follows the documented algorithm but does not execute Rust. The no-source-change assertion uses a sentinel JSON envelope and suppresses serialization for unchanged results; it does not prove the application source writer or history implementation.
Concrete counterexample to global splicing: [a,u,b,v,c], column [a,b,c], selection {b,c}, after a is unchanged. Column-slot permutation preserves the exact original array; global splicing would write [a,b,c,u,v]. Moving that block before a produces [b,u,c,v,a]: u and v retain exact indices. Consequently, preserving all globally unselected relative order is intentionally not a requirement (a moves relative to u and v).
Anchor-policy follow-up: all nonempty subsets for column lengths 1..10 (2,036 cases, 18,324 unselected Before/After anchors) reached every remainder-list gap using an unselected neighbor. Raw normalization differs from selected-anchor no-op in 17,004 selected-anchor cases. Example: [a,b,c,d], selection {b,d}, Before d normalizes to [a,c,b,d]; the object-anchor policy keeps [a,b,c,d]. The changed result is still reachable through After c. The APIs are distinct: normalization does not automatically supersede selected-target no-op. Prefer retaining the latter for object-anchored UI if that is the chosen interaction; every changed result remains reachable. When all are selected, the sole destination is inherently unchanged.
The selected-anchor no-op guard belongs before invoking a block planner: noncontiguous selected items can legitimately remain noncontiguous after that no-op. The block-contiguity postcondition applies to planned moves, not every selected-target gesture.
Legacy exchange-only ordering assigns successive ranks, and cycle-blocked fallback assigns unique ranks. Multi-member sets spanning these ranks refuse. Four-node enumeration cannot exercise a changed multiple-member group beside a cycle: two cycle nodes leave only two peers, whose entire block has nowhere to move. Independent review identified this limit; an added five-node case checks [a,u,b,v,c], cycle u→v→u, selection {b,c} before a, exact result [b,u,c,v,a], and unchanged full ranks. Production should still validate the complete recomputed rank map. The experiment freezes graph edges; it does not rederive legacy OrderedPath adjacency. Valid legacy columns contain one node, so admitted moves are no-op and multiple-member groups refuse under this candidate.
The same independent reviewer confirmed the rank model agrees with current Rust, found no planner counterexample under its assumptions, and noted that anchor reachability does not execute a selected-target guard or test actual pointer hit regions. Existing singleton reorder globally splices steps, so routing it through this planner would intentionally change invisible cross-column source ordering; the candidate must make that migration explicit.
Limitations and next Rust checks: these scripts assume valid unique step IDs, valid complete rank maps, visible local occurrence selection, and valid destination bounds. Rust must reject duplicate/missing/wrong-owner IDs, qualified/link mixtures, stale snapshots and dirty drafts before side effects. Explicitly choose raw-gap versus object-anchor input; keep before-first/after-last reachable. Verify production layout with different card heights and expansion, preview/commit plan identity, OA/SA source roundtrip, unchanged semantics outside steps, one Undo/Redo, no history for no-op, source limits/refusal, and native slot feedback. Deletion mode switching and aggregate removal were not investigated by these movement scripts.
Artifacts are exploratory evidence. They do not establish State acceptance or Process implementation acceptance.