Files
ARCADIA-Studio/harness/diagram-delete-candidate-20260912.md

63 lines
8.8 KiB
Markdown

# Diagram Delete candidate handoff — 2026-09-12
Frozen, uncommitted implementation on `codex/diagram-delete-956atf-20260912`, isolated worktree `C:\Users\User\Documents\Git\ARCADIA-Studio\.local\diagram-delete-20260912`, HEAD/base `5a70181`. Parent owns issue 15 comment 551, review, Windows verification and integration. No Gitea, Git index/commit, compiler/cargo, native application, WSL or VPN operations performed by this worker. Files are ready for parent review/copy; do not interpret this as verified or complete issue 15.
## Candidate behavior
- Architecture OA/SA and persisted state diagrams: focused canvas Delete hides the selected explicit placement through ordinary `execute(Command::Delete(placement))`; semantic object remains. Shift+Delete opens the existing model-removal dialog. Visible architecture edges/ports and state transitions without explicit placements use confirmed model removal for Delete too.
- Captured `diagram_removal::Intent` carries diagram document/revision/epoch, object and explicit placement. App independently checks clean draft/source/behavior, modal/menu/reference state, selected object/placement, current diagram/page/tool and visible projected membership. Keyboard path never calls `apply()`.
- `diagram/focus.rs` supplies actual Iced Focusable ownership around the architecture/state canvas. It draws the existing behavior viewport style (1 px teal border) while keyboard-focused, without changing layout. It registers for standard focus operations; programmatic focus of any other field unfocuses it. It rejects captured/unfocused/disabled keys and resets at context/window boundaries. The old mouse-only DiagramCanvas.keyboard_focus and StateCanvas.focused gates were removed: the wrapper is the single keyboard authority. Standalone Program tests still exercise already-admitted events.
- Canvas Tab uses ordinary Iced next/previous focus operations. A transient traversal flag rejects subsequent keys in the same native event batch before that task runs, while retaining focus for the operation's traversal count.
- Delete requires selection mode and no active pointer/route/port/pan/work gesture. Existing bend Delete takes priority and a selected invalid bend cannot fall through to object removal. Unsupported modifiers are rejected. Diagram background is never a shortcut target.
- A completed allocation work click retires its epoch before retained canvas state necessarily sees redraw. `diagram.rs` clears only an already-retired local work press before Delete; same-epoch/live work presses remain guarded. This avoids consuming the first Delete merely to send stale WorkDrag::Cancel. `diagram/work_drag.rs` and app/allocation_drag.rs are untouched.
- Model confirmation is captured through existing model_menu::Opened plus selected identity/placement and a unique token. Rendered text uses the captured object. ConfirmDelete now requires the token. Cancel/Escape clear the snapshot and advance the canvas epoch. Old tokens cannot confirm a later dialog; changed document/revision/epoch/page/layer/diagram/object selection or placement refuses the command. Existing pointer/model menu deletion still invokes apply as before, then creates the captured confirmation.
- Existing architecture/state menus gain scope-appropriate Delete/Shift+Delete hints. Diagram background and unsupported state-action rows do not claim a removal shortcut.
## Changed files
New:
- `crates/oa-desktop/src/app/diagram_removal.rs` — intent validation, confirmation lifetime, shared keyboard admission predicate.
- `crates/oa-desktop/src/diagram/focus.rs` — actual Iced Focusable wrapper.
- `crates/oa-desktop/src/app/diagram_removal_tests.rs` — 10 mounted App-tree test functions.
Modified:
- `crates/oa-desktop/src/app.rs` — module/fields/messages, tokenized modal handling and focused delegation hunks.
- `crates/oa-desktop/src/app/behavior_lifecycle_tests.rs` — existing ConfirmDelete constructor updated to token signature.
- `crates/oa-desktop/src/app/state_diagram.rs` — delegates the captured removal event.
- `crates/oa-desktop/src/behavior/state_canvas.rs` — admitted Delete events; removes obsolete private focus boolean.
- `crates/oa-desktop/src/behavior/state_edit.rs` — captured removal event/context.
- `crates/oa-desktop/src/behavior/state_menu.rs` — shortcut hints.
- `crates/oa-desktop/src/behavior/state_view.rs` — focused wrapper.
- `crates/oa-desktop/src/diagram.rs` — admitted Delete, bend/gesture priority, retired work-press cleanup; removes obsolete private focus boolean.
- `crates/oa-desktop/src/model_menu.rs` — shortcut hints.
- `crates/oa-desktop/src/views.rs` — captured confirmation text/token and architecture canvas wrapper only. Allocation toolbar region untouched.
## Authored verification, not executed
Reuses production `behavior::canvas_workspace::tests::Mounted`, real App::view/UserInterface/renderer, retained widget cache, ordered input batches and task/widget-operation draining. Tests never seed canvas private gesture or focus booleans.
1. OA/SA real pointer selection → Delete exact placement; other diagram placement and semantic object retained; source/model agreement and complete one-unit Undo/Redo.
2. Shift+Delete captured target; Cancel, Escape, old-token replay versus a new dialog; intended object removal and Undo source round trip.
3. CLEAN Inspector focus by actual widget operation and canvas Tab; Tab+Delete in one native batch cannot remove model; Shift+Delete cannot reach canvas; Home/Delete edits Name while project/source remain accepted and unchanged.
4. Captured emitted removal intent replay after selection, epoch, owner diagram, document or revision change.
5. Window Unfocused, menu open/close, dirty draft, modal, epoch and unsupported modifier refusal, followed by explicit reacquisition.
6. Real route-pin selection → Delete only bend; source round trip; actual edge segment selection → confirmed semantic deletion.
7. Real state-canvas pointer selection → deletes state placement while architecture placement and state semantic object survive; Undo/source round trip.
8. Captured confirmation refuses changed selection/document/epoch/placement/revision.
9. Programmatic canvas focus without preceding mouse entry → Delete works through the single focus owner.
10. OA/SA Allocation work body click → first Delete without intervening redraw hides exact placement once; semantic work/performer preserved; Undo restores source.
Static checks performed: scoped rustfmt --edition 2024 --config skip_children=true on the 13 owned files; `git diff --check` passes. Formatter exit 0 is only a syntax-formatting check. No compilation or tests were run. Parent should run new `diagram_removal_tests` plus existing state/lifecycle, behavior lifecycle, model-menu, architecture and allocation full-tree tests on the combined integrated candidate.
## Explicit remaining gaps / review risks
- Process and scenario occurrence/link/fragment removal remains unimplemented; do not route their selections through architecture/state context or delete referenced reusable actors/functions. Scenario's modeled Delete participant event is untouched.
- Explorer keyboard removal remains unimplemented; existing Actions/pointer menu remains available.
- State action labels (state-action relation identities represented outside projected edges) remain pointer-menu deletion only. No shortcut hint is claimed for them.
- Mounted tests have not executed. Inspector Tab order, route-segment geometry, state selection hit geometry and the allocation no-redraw case are particularly important concrete checks. No screenshot/native UI acceptance has been done.
- Added tests exercise generated modal state and dispatch actual modal action messages through App; they do not locate/click the rendered confirmation buttons or read rendered glyph text. Parent native QA should confirm target wording and Cancel/Confirm accessibility.
- Tool/gesture admission guards are authored, but dedicated new mounted drag/connection/creation/reconnect and stale-invalid-bend cases are not yet authored. Existing relevant regression tests should be retained and broadened if they expose missing coverage.
- Intent validation compares current selection plus document/context lifetime. Switching selection away and back without any context/revision change is not recorded by a distinct selection-generation counter. Immediate changed-selection replay is covered. Parent should judge whether a stronger input-generation token is required for issue acceptance.
- `delete_pending` boolean remains for compatibility with existing guards/tests; production opening always also creates delete_target. Legacy tests that manually set only the boolean do not create a rendered target dialog, though App modal admission still blocks underlying action messages.
All candidate source files are frozen after this handoff. Further edits require parent follow-up.