5.5 KiB
State transition bend editing — issue 23
Branch-specific work above attachment source 53d01a3, on
codex/state-bends-ytr83r-20260923.
Issue 23
owns live scope and acceptance. This document records the design; it does not
assert completed verification or integration.
The user asks to edit bends in State-machine connections as in architecture
diagrams. State already renders EdgeRoute.waypoints; its missing capability is
interactive authoring. Bends are positions in one saved diagram. They neither
change transition endpoints/meaning nor belong to every view of the transition.
Interaction decision
Use direct manipulation of an already selected transition: drag an exposed line segment to insert one bend, or drag an authored square handle to move that bend. An initial selection click changes no route. Endpoint circles retain semantic reconnect behavior; the separate attachment action retains its explicit mode. State vertices and action rows retain selection/movement precedence. Clicking a transition label selects it; this task does not introduce label dragging.
The transition menu offers Add bend here when invoked on an eligible segment, or Add bend at the longest interior segment from Actions. Right-clicking an authored square offers Remove bend. Clear bends removes all authored waypoints in this view while retaining both attachment preferences and the label override. Existing transition Delete behavior stays explicit and separate; this design does not add a pin-specific Delete shortcut.
Alternatives considered: an Edit bends mode makes the distinction visible but adds another persistent tool and cancellation/focus state; menu-only editing is discoverable but too slow for repeated shaping. Direct dragging plus explicit menu actions matches the existing architecture workflow without another mode. The menu provides a recovery path when a label or endpoint covers a line hit.
Invariants
- Only an actual visible, unsuspended routed State transition can be edited. Internal transitions render as rows rather than lines. Folded endpoint proxies suspend authored routing. In both cases existing dormant waypoints survive; the UI disables operations instead of deleting metadata.
- Generated elbows, mandatory endpoint leads and computed self-loop detours are routing output, not authored bends. Editing inserts one pin, never the entire computed polyline. The picked rendered-segment index determines insertion among stored pins, including reversed or overlapping traversals.
- Movement requires three screen pixels. Dragged pins snap to the existing five-unit grid. A stationary press or return within three screen pixels restores the exact baseline, including imported off-grid coordinates and absence of a stored route. It creates no history entry.
- Preview uses the actual routing engine and captured baseline. The model stays
unchanged until release. A successful drag replaces only
waypointsin the current route, leaving attachments, label, relation metadata and other views exact, in one existingSetEdgeRoutetransaction. - A gesture belongs to its document, diagram, revision, interaction epoch, selected transition and viewport. Escape, pending edits, tool/context changes, camera/bounds changes, focus loss, pointer exit, outside release and a pan/menu interruption cancel it. A canceled preview must not supply menu pin indices. A delayed drag result must not apply after selecting another object.
- Finite positions, valid indices and the existing 128-pin limit are checked at the command boundary. Exact no-ops are suppressed before execution.
Verification plan
Use real canvas event tests at multiple zooms for insertion/movement, ordered cursor input, cancellation, exact return-to-press, preview invalidation and menu targets. Planner/app tests compare entire Projects and source bundles across Undo/Redo, preserve attachments/label/reference views, and refuse internal, folded, nonfinite, stale, pending and capacity-invalid operations. Exercise right-click during a provisional insertion and selection changes before queued commit admission. Retain existing attachment/reconnect and focused Delete tests.
Then exercise the actual Windows application: add, move, remove and clear bends; check unchanged attachments and independent views; Save/Undo/Redo and reopen; observe menus, guidance, preview and normal close. Bind evidence to an identified source/binary and predeclared complete-Project expectations. Compilation alone does not establish interaction acceptance. Linux remains user-paused.
The first full workspace run exposed a read-only pan regression: canceling model edits on every pending-draft event also canceled the middle-button pan. Keep edit cancellation separate from navigation cancellation; the existing scoped pan regression exercises this distinction. The self-loop test also distinguishes typed-model restoration by Clear from byte-exact source restoration by Undo: source-preserving edits may retain harmless empty-list whitespace, whereas Undo must recover the original source bundle exactly. Failed run receipts are retained; these findings do not assert that the corrected candidate has passed its gates.
Codex-956atf retains issue 16 resize and issue 27 integration ownership. This work uses the existing State model/router and needs composition with those contributions. It does not certify a combined release, change Process/Scenario notation, redesign automatic arrangement or adopt a new routing schema.