Files
ARCADIA-Studio/harness/edge-attachments-20260922.md

104 lines
6.2 KiB
Markdown

# Connection attachment editing — issue 33
Branch-specific work from `3f9e6a18af96b5cd10940da4093be8da28b9c835` on
`codex/edge-anchors-ytr83r-20260922`, owned by Codex-ytr83r/root.
[Live scope and handoff](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/33)
remain in Gitea. This is not an integrated release checkpoint.
The user needs to move where a connection touches an element without changing
the relationship. The existing ordinary route editor offered bends and labels;
unported ends were selected from four side midpoints. SA semantic ports already
had per-placement anchors. State endpoint handles instead performed semantic
reconnect. These are different operations and remain distinct.
## Decision and alternatives
Store optional `source_attachment` and `target_attachment` values on `EdgeRoute`.
Each contains a side and normalized fraction, interpreted against the actual
projected shape. No additional semantic object, ID or reference is introduced.
The precise format, geometry, Port precedence, folding, reconnect and reset rules
are in [the normative language contract](../docs/language.rst); REST uses the
same data and existing `SetEdgeRoute` transaction.
Compared alternatives:
- Absolute endpoint coordinates are easy to store but become detached from the
owner after movement/resizing and duplicate derived geometry.
- Reusing semantic Port anchors would invent ports for OA/state relationships
and conflate each connection's presentation with a shared port's identity.
- Binding an attachment to an additional semantic endpoint/placement reference
would preserve the old owner's identity after reconnect, but needs stale
reference cleanup and a dormant preference lifecycle without a current user
need. The selected rule retains the edge-end preference across reconnect,
just as authored bends are retained; it is documented, not inferred silently.
Fractions remain precise in source/API; pointer edits snap to hundredths.
Automatic absence and authored values are distinct. Press/release without a
drag, Escape, stale context, focus/camera/layout change and outside release do
not author a preference. Returning within three screen pixels of the press
restores the exact initial optional value, including its original precision.
Successful editing changes one field in one route in one view in one history
operation. Per-end reset preserves the other end, bends and label.
Ordinary diagrams expose eligible selected-end handles and explicit source/target
menu choice for overlapping handles. State menus expose separately labelled
Adjust attachment and Reconnect actions; selecting a transition still retains
the existing reconnect gesture. Ports keep their existing movement policy.
This work does not adopt or alter the separate #16 resize/port-capacity policy.
## Review-driven corrections and evaluators
Independent contract review identified projection-filtered Port markers as an
unsafe authority: eligibility and routing now consult semantic endpoint identity.
Attachment metadata participates in the route-preview cache key. Inset contours
use actual lead lengths for path costs and pin fractions; shape scan-line
intersections are shared by routing and pointer gestures. Side choice uses the
nearest cardinal bounding segment, avoiding coincident circle scan-line points
that otherwise retain the wrong exit direction. Hysteresis is capped by symbol
size so small circles can change sides at low zoom; an explicit regression
covers midpoint, overshoot and near-corner intent.
The first frozen gate exposed a remaining overshoot case: distances measured
from far outside a small symbol converged, keeping the previous perpendicular
side. Measuring side intent at the cursor clamped to the bounding box preserves
the intended side under overshoot. The failed gate is retained separately.
Valid Port-to-Port Item traces also omit projected port IDs; routing now resolves
the semantic port before looking up its visible, owner-qualified marker. An
actual trace regression checks moved anchors and unchanged trace metadata.
Coincident authored self ends previously threatened an empty candidate list.
They retain their positions and receive an explicit loop warning. A critic then
showed a fixed invented detour point could collide with a neighboring card even
though the opposite side was clear. Computed detours now consider both directions
and multiple bounded extents, preferring clear candidates. These points never
become persisted hard pins. Geometry tests exercise blockers on either side.
Cross-review found ordinary attachment drags survived camera/focus/layout
changes and outside release. They now carry a viewport stamp and cancel on those
changes, with an actual pointer-event cancellation matrix. The same review
reconciled return-to-press behavior across ordinary and State canvases.
Meaningful evaluators are `oa-core` integration tests `attachment_geometry`,
`attachment_lifecycle`, `attachment_trace_ports`, `attachment_workshop`,
`edge_attachments` and the existing routing/port/state suites; desktop ordinary
attachment and State pointer/planner tests; server `http::edge_attachments`
conditional transactions, exact source exports and restart. Tests compare complete
projects/source where applicable, not just attachment fields. Native acceptance
uses the [fixture and workflow plan](experiments/edge-attachments-20260922/native-plan.md).
Final test/native results and exact tested commit belong in the publication
handoff, not an unverified claim in this decision record.
## Applicability and integration limits
Process topology uses generated cards and qualified contextual addresses.
Scenario endpoints derive from lifelines, activations, lifecycle and time/order
notation. Neither renderer consumes ordinary `Diagram.routes`; their visual
editing requires separate notation-aware contracts. This change does not claim
to implement arbitrary attachment dragging there, or to resolve automatic
arrangement (#32) or State bend editing (#23).
The base includes ordinary Text work, not the separately published Scenario
spacing/inspector branches or the latest transition lifecycle branch. Integration
owner #27 must compose actual pushed commits and verify the combined result.
Linux/WSL verification remains paused by the user.