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

130 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.