Files
ARCADIA-Studio/harness/multiselect-state-20260923.md
T

15 KiB
Raw Blame History

State multiple selection — branch evidence

This contribution continues issue 29 above the delivered ordinary saved-view head 7e348d967d1787c052a145b7448636613a6a7054. It is not a combined release or completion of the full multiple-selection requirement. Integration remains with the owner in issue 27.

Source commits on codex/multiselect-state-9e8r6t-20260923:

  • 2a3b9ba822a49ead233c4b5f98412a07c1c1da12: State adapter and independent evaluator, exact source of the full desktop result.
  • 3480b54201a5f361cca0bcd0d45dd6546a7a7bc9: box the optional exact menu target to keep the menu event small. Three files change; matching/selection behavior is unchanged.

The scoped Windows gates and native workflow below pass. Portable evidence is included with this contribution; combined integration and release acceptance remain separate.

Behavior and implementation

State views share the transient typed selection model with ordinary saved views. Shift-click and contextual Add/Remove preserve exact placement, transition-edge and action/internal-transition row identities. A row includes its owner placement and relation, so replacing a placement or reassigning a relation cannot silently bind an old selection to another occurrence. Primary inspection uses State's own placement field; row inspection does not promote the owner placement or reusable work target. Properties edit only the primary item.

Placement groups move through one simultaneous core plan and one document command. Preview applies only the returned node/route changes to a cloned diagram, not a full Project clone or a sequence of singleton moves. State movement retains fractional unsnapped displacement; ordinary saved views retain their ten-unit grid and State bend editing its five-unit grid. Composite descendants and boundary-projected entry/exit symbols use their authored anchors and move once; hard pins translate only when all required endpoint/boundary owners move. Authored attachment/label metadata stays unchanged even when derived paths and label positions rerender.

Pressing a selected member defers primary changes until the gesture outcome. A stationary release collapses to that item; movement beyond threshold remains a group gesture even after returning to the start. Escape, focus loss, changed viewport/tool/selection/document context, or suspended editing retires captured gestures. Mixed row/edge/placement groups refuse movement and Hide as a whole. Group menus expose captured-set actions, without singleton destructive fallbacks. Placement-only Hide removes just selected placements in one history entry; model elements, relations, reusable work and other views survive.

State reserves fixed selection-feedback and unplaced-picker space so selecting, hiding and Undo do not resize/refit the canvas. Mounted checks exercise those transitions and focus ownership. Singleton transition routing remains available with the new selection path: bend snapping/commit/cancel, endpoint stationary/cancel/commit and Shift priority have dedicated production-input checks.

Stale envelopes and queued legacy singleton State Select/Move/Remove events under a group are rejected before shared App navigation/reveal/allocation side effects. Dirty forms/source, active tools, read-only context and busy I/O preserve their established edit ownership.

No schema, persistence field, public REST command or new core geometry command is introduced. Important seams for integration are app.rs early admission/reconciliation, app/multiselect.rs, State context menu target transport, State canvas input/preview, and fixed State controls. Preserve the integration branch's newer Scenario/source/Properties logic. The independent example may need the newer Diagram.layout: None field when composed with the integration owner's schema extension.

Review and evaluators

State design, fresh independent review, and native evaluator design record the contract and falsifiers. The independent critic did not author the adapter or evaluator. Two verified findings were fixed: fractional-delta inference from a nonzero checker anchor, and late queued-singleton refusal mutating shared App state. The reviewer rechecked both corrections statically; parent tests supply execution evidence.

The deterministic native example constructs a composite A, unrelated B, fixed C, nested region/leaf, projected entry/exit points, internal and external hard routes, shared work, another State view, and SA/trace records. Its checker independently enumerates the expected complete Project for unchanged/moved/Hide modes. A is at the authored origin so its saved position preserves the actual f32 group delta, including nonbinary fractions. This verifies resulting model invariants, not exact pointer-to-world fidelity. It rejects malformed source and unrelated changes; eleven tests include genuine command results and corruption falsifiers.

Completed Windows checks

Environment: Rust/Cargo 1.98.1, stable-x86_64-pc-windows-gnullvm, LLVM MinGW 20260826, one Cargo job, incremental compilation disabled. Linux/WSL checks remain user-paused.

Capture Source Result
core-2 2a3b9ba 11 State native-evaluator tests passed
desktop-2 2a3b9ba 1,286 passed, 0 failed, 6 existing ignored; includes 29 added cases
lint-2 3480b54 strict core/desktop Clippy, all targets, passed
format-1 3480b54 workspace formatting check passed
desktop-3 3480b54 122 focused State/menu tests passed; 1,170 filtered out
native-build-1 3480b54 matching State evaluator build passed
windows-build-1 3480b54 matching Windows GUI build passed

Full desktop compile took 13m20s; execution 607.72s. Core-2 and desktop-2 share 733 unchanged inputs (map SHA-256 9cf85879dfb0bb5ec3b15c66b23df316e6bfe8451b6cf0c895bf7b9b5fbdde4a). Lint-2 and format-1 share 735 unchanged inputs (map 4215d0ca0319282768f1acdf05c2c094ea7432e17ed3a715df73aa05cef851bf). Parent compared complete inventories and exact Git blobs at both source commits. Recorded run HEAD alone does not identify the originally uncommitted bytes: the first source commit preserves the earlier three menu-field blobs from the verified desktop capsule, followed by the boxing correction, without replacing the working files.

The revised 735-input scope adds two existing literal compile-time fixtures outside the usual source directories: harness/experiments/edge-attachments-20260922/native-fixture.arcadia and harness/experiments/textual-authoring-20260911/alarm-response.arcadia. An audit covered 71 Rust literal include references with no unsupported pattern. The historical 733-input desktop/core-example captures contain their actual compile-time dependencies; historical all-target lint lacks the core attachment fixture and does not establish full all-target source identity.

Commands (with the described toolchain environment):

cargo test -p oa-core --example state_multiselect_native --message-format=json -- --test-threads=1
cargo test -p oa-desktop --message-format=json -- --test-threads=1
cargo test -p oa-desktop --message-format=json -- state_ model_menu --test-threads=1
cargo clippy -p oa-core -p oa-desktop --all-targets --message-format=json -- -D warnings
cargo fmt --all -- --check

Final focused compilation took 9m26s and test execution 30.85s. The 122 tests cover the changed State/menu paths; the complete earlier suite remains tied to 2a3b9ba rather than relabeled as final-source execution. Both native binaries use the identical final 735-input map.

Native Windows observation

The exact recorded GUI and checker ran against an immutable generated fixture and a separate working source copy. The GUI image is 117,615,104 bytes, SHA-256 01cc30dac3a71e847415c86e2e08b0da45989aac260a82bbb00f048c3eb8a448. Run 1 closed normally with exit 0; stdout/stderr are empty, and both binaries and the fixture remained unchanged. The archive retains 35 app-window observations (main window 1442×932, plus related transient images), ten successful complete-Project snapshots, and their helpers and build receipts.

Observed sequence:

  1. Open and save the State source baseline. Select composite A, context-add its exact entry-action row, and drag the selected State. The mixed set is refused; row-primary Properties still describe the StateAction and reusable work remains separate. Saving gives the unchanged complete Project. A stationary State click collapses to A without geometry changes.
  2. Context-add B. The two placement outlines and primary-only Properties disclosure appear without a viewport jump. Drag nonprimary A by 47×29 screen pixels at the displayed 79% zoom. Both roots, A's descendants and eligible internal pins move; B stays primary and C stays fixed. The saved checker infers exact shared displacement (59.72580337524414, 36.85209274291992) and matches the independently expected complete Project.
  3. Save, one Undo, save, one Redo, save. All three checks pass; Undo restores baseline bytes and Redo restores the moved bytes across all nine source files.
  4. Undo back to baseline, save, open B's selected-member menu. It reports two selected, offers group Hide and disables aggregate model deletion. Hide removes A/B placements, clears their transient membership, retains model-tree elements and the inner region/leaf, and leaves C's screen position unchanged. The unplaced picker lists A and B. One Undo/Redo with saves restores the exact baseline/hidden source byte groups.
  5. Reopen the saved project through the native file dialog, then save again. A/B remain hidden, the selection is empty, and the complete Project and nine source files exactly equal the earlier hidden state. Reopening fits the surviving content (71%); camera state is transient and this is not a claim of persisted viewport equality.

Only views/diagram_state_view.arcadia changes for either movement or Hide. The nine required history snapshots form three distinct exact-byte groups; the additional row-mixed-unchanged snapshot also equals baseline. The checker conserves all other model/source records, including the other State/SA views, shared work, trace/refinement relations, route attachments and labels. Hide deliberately removes only selected placements: the extreme authored entry/exit anchors become exposed when their displayed State boundary is absent; they extend beyond the current viewport until Fit/reopen. No authored anchor changes are introduced to conceal that derived geometry.

Native limitations: contextual Add exercises actual user operations but does not inject held Shift; mounted/input tests cover modifier lifetimes. No minimum-window/DPI, SA native trial, aggregate semantic deletion or combined-release claim is made. The fixture has 13 model-check findings visible in the UI; this finite geometry/identity evaluator requires valid source and exact expected Project, not a completeness-warning-free engineering model.

A fresh independent native review inspected representative actual screenshots, all ten checker receipts, the source snapshots and outer package pins. It found no new blocker for this bounded State delivery and confirmed the scope distinctions above; it did not rerun archive verifiers or Git comparison. The review also noted visible overlap between the fixture's multiline A→B label, its secondary summary and nearby row area before and after movement. This report does not claim flawless State label layout. The picker was inspected for recovery choices, but selecting a choice to restore a placement was not exercised; recovery through Undo was exercised.

The native trial exposed issue 35: picker Escape dismissal. Capture 24 opens the picker, 25 shows Escape leaving it open, and 26 shows successful outside-click dismissal. A fresh code review identifies existing shared Iced picker behavior, not a State multiselect regression; the creation/source-modal Escape priority also needs verification before a shared fix. This recoverable usability defect remains open, not silently treated as accepted behavior.

Automation recovery is retained: the first reopen attempt navigated the file dialog into views instead of opening the project; one dialog capture returned no monitor found, then fresh window selection/activation recovered it. Captures 32/33 have intent-based filenames but still show the open dialog. Successful explicit-path reopen is capture 34; save is 35. No failed attempt is counted as a successful reopen.

Portable evidence

  • Checks: nine closed captures, including two failed gates, with three exact source-capsule pairs and both historical helpers.
  • Native: run 1 screenshots, ten complete-Project checks, three-group source history, fixture and executable provenance.
  • Source identity: exact 733/735-input relationships to the two source commits; optional renewed Git-blob comparison.
  • Invalid first-capture incident: original bytes and the single known mismatch, never an accepted gate.

Run with Python 3.10+ from the repository root:

python -B harness/experiments/state-multiselect-20260923/checks/verify.py
python -B harness/experiments/state-multiselect-20260923/native/verify.py
python -B harness/experiments/state-multiselect-20260923/source/verify.py --repo .
python -B harness/experiments/state-multiselect-20260923/incidents/core-1/verify.py

These commands verify archived bytes/relationships and optional source identity, not new execution or authentication. To reproduce the native trial, build both packages at 3480b54, run state_multiselect_native generate NEW_FIXTURE_DIRECTORY, copy its source directory, open that copy's project.arcadia in the GUI, and use state_multiselect_native check unchanged|moved|hide BASELINE_JSON SAVED_PROJECT_ARCADIA at the corresponding stages. The checker requires the MinGW runtime environment on Windows.

Historical failures and scope

Keep the first desktop compile failure (a test helper shadowed by a local placement UUID) and first strict lint failure (large enum variant) with their actual exit 101. Neither is a pass. Core-1 recorded eleven passing tests but is an invalid capture: concurrent formatting changed model_menu.rs, yielding a false unchanged-input flag and one map/archive mismatch. Its exact seven raw files and helper belong in a separately pinned incident, never the strict accepted-capture package. Stable core-2 supplies the actual accepted result. No historical receipt is repaired or relabeled.

Process, Allocation and Scenario group adapters and aggregate semantic deletion are still required for issue 29. Unsupported groups currently receive whole-set refusals. The Process candidate and bounded permutation experiment are exploratory evidence only, not implemented functionality. Full combined release, minimum-window/DPI behavior and Linux acceptance are not claimed here.