Files
ARCADIA-Studio/harness/release-state-gesture-design.md
T

7.9 KiB
Raw Blame History

Direct state editing — bounded design, 2026-09-05

Originally a read-only proposal. Implemented in the isolated state-integration checkout through e0b2210; current verification and outstanding acceptance are in STATE.md. The old file/line seams below describe the pre-implementation baseline. State layouts now use the typed context and commands proposed here; full scenario and process direct editing remain separate release work.

Decision and first task

Reuse Diagram/NodePlacement and existing atomic commands. Prefer a typed ProjectionKind::StateMachine { machine: Id } over desktop-only coordinates or a second persisted behavior-layout store. Existing projection strings remain valid. Use the existing constructor syntax: projection { StateMachine { machine @operating_modes; }; };. The context references a same-layer machine and scopes placements to its machine, regions and vertices. Explicit creation initializes existing contents in one transaction; rendering must not dirty a model. Missing placements remain legal and discoverable through an elements-not-shown action.

Retain active behavior diagram identity independently of semantic selection; selecting a root Event must not switch machines. Diagram context/layout are model content; active tool, pointer and zoom remain editor state. Context participates in reference remapping/deletion, language reference controls and OpenAPI.

The first native task is: create a region and Initial/State; drag a child and a composite; draw a transition; reconnect its endpoint; edit its guard; undo/redo; save/reopen and inspect the equivalent source/API records. This is the minimum vertical slice, not acceptance of all behavior editing.

Existing seams and implementation contract

  • behavior.rs:56,118,494: selection-derived context, selection-only canvas.
  • behavior/state_scene.rs:24,163: computed vertical geometry; retain its state symbols, internal-transition rows and typed routing, but consume persisted shared node geometry. Generic projection drops equal-anchored/self edges and includes relationships unsuitable for a state diagram.
  • behavior/states.rs:73,191: reuse existing typed transition controls and candidate validation. Reconnection edits a clone of the original relation.
  • model.rs:1235,1247, projection.rs:104,184, session.rs:562: reuse placement identity, semantic nesting/folding and grouped movement.

Events carry diagram identity explicitly: CreateAt(diagram, parent, kind, position), Move(diagram, node, position), Connect(diagram, source, target), Reconnect(diagram, relation, endpoint, vertex), EditTransition(diagram, relation). They lower to existing CreateElement+CreateNode Batch, MoveNode, CreateRelation/EditRelation commands. No alternate mutation API is required. Gesture state is Idle/Move/Connect/Reconnect with transient preview and a captured revision. Release commits once; Escape, stale revision or context change cancels. Allocate creation IDs once per accepted plan. Drawing/hit testing/preview consume one scene. Extend app.rs:864's draft guard to every mutation gesture.

Required invariants

Creation targets the explicitly highlighted semantic Region. Region creation targets a machine or stable State/Mode. Dragging never reparents. Moving a container moves all descendant placements once, including folded descendants, only in that diagram. Child movement preserves ownership and siblings. Resize constraints preserve child/header space and movement cannot misleadingly suggest ownership by another region. Entry/Exit remain region-owned boundary symbols.

Reconnect preserves relation UUID, alias, name, prose, triggers/effects and artifact references; validate the full replacement so the old relation is not double-counted for cardinality. Do not silently change transition kind or erase incompatible data. Internal remains a row/self contract; External self-loops and Local edges remain distinct. Cross-immediate-region transitions can be valid; cross-machine endpoints reject. Existing history, boundary and orthogonal rules in state_validation.rs remain authoritative.

Reject invalid drafts without losing them. New tools must not discard unfinished behavior drafts. Preserve semantic selection after movement and same-card reselection. Context references remap with UUID changes; machine deletion removes its dedicated views without deleting cross-layer counterparts. Source-created unplaced elements remain discoverable; cross-machine reparenting must also handle incompatible placements atomically or reject with an actionable diagnostic.

Partition and evidence gates

Core/context owns model.rs, projection.rs, references.rs, validation.rs and focused tests. After type freeze, representation owns language.rs, source-project reference handling, reST/OpenAPI and round-trip/API tests. Desktop gestures own new behavior/state_canvas.rs and state_scene.rs. Lead integrates behavior.rs, states.rs, app.rs and diagram context controls. Avoid a general graph framework.

Test pointer events at non-100% zoom, one history entry per gesture, exact identities, grouped movement limited to one view, atomic rejection, context lifecycle and source/JSON/REST equality. Native trial at 1440x900 and 1100x700 uses two regions, a nested composite and guarded transitions. Try invalid edges into Initial, invalid history reconnection, Escape mid-drag, a folded composite, root-Event selection and save/reopen. Record task completion, discoverability, ownership clarity and recoverability; no such native result is claimed here.

Current-interface review (2026-09-06)

Independent core and desktop maps confirm the payload projection remains the smallest persisted boundary. Preserve unit-variant JSON strings; the new value is {"StateMachine":{"machine":"UUID"}}. A machine context is required for empty and partial views; inferring it from placements cannot represent an empty diagram, while an optional unrelated Diagram context adds invalid combinations. Use one narrow state-view membership predicate and preserve existing projections' legal hidden placements. Dedicated views disappear with their machine; moving elements across machines must repair incompatible views/routes in the same Batch or reject atomically.

The shared router now owns route pins, label placement and grouped translation. An executed probe found that merely retaining an External self-transition yields an 18 px out-and-back stub. Add genuine self-loop and state-symbol endpoint geometry in the shared routing/projection path; Entry/Exit snapping must precede draw/hit testing. Internal transitions remain rows, and folded descendants must not create false visible self-transitions. Probe: D:/CodexBuilds/Capella2-source-document-contract/examples/state_projection_boundary_probe.rs.

Before adding gestures, close existing behavior draft gaps: Start/Edit must not overwrite an unresolved form, Submit must retain it until Document source/model commit succeeds, and Save/Close/navigation must account for behavior drafts. Canvas events carry the existing document/diagram/revision/epoch context and recheck it before acceptance. Generic MoveNode message delivery selects the current active diagram and is insufficient for delayed behavior gestures.

Keep Select, State/symbol, Region, Transition and Fit in a compact toolbar. Create inside an explicitly highlighted eligible owner, place missing ancestry in the same command batch, and expose unplaced semantic elements. Retain the behavior view independently of selection, including root Events. Reconnect clones the relation and changes one endpoint; preserve all other data and reject invalid cardinalities. Keep form editing in a bounded panel so the canvas remains usable at 1100×700. These are decision-ready interfaces; no implementation or native gesture acceptance is claimed by this design record. The implemented contract and subsequent acceptance evidence are in release-state-editing.md; production316dc55 closes the direct state slice, while scenario/process work remains.