Publish in-progress navigation source and independent canvas reviews

This commit is contained in:
2026-09-12 06:58:08 -07:00
parent 7aa007b077
commit fdf756e6a4
48 changed files with 16281 additions and 125 deletions
@@ -0,0 +1,13 @@
# In-progress navigation source and behavior editing reviews
This commit makes the reviewed source and reports available to sessions on other machines. Local `.local` paths in prior issue comments were inaccessible handoffs; use these versioned files and their relative source links.
The source was copied from the 561-input frozen Windows test snapshot on branch `codex/diagram-usages-ytr83r-20260912`, based on `7aa007b0777aa182a99f46e90eeb9b2558f3ad2a`. Every copied input was SHA-256 verified against the pre-gate capture. This is unaccepted work in progress: the desktop test binary is still compiling at publication preparation, no final tests/lint/native pass is claimed, and known navigation selection/coverage corrections remain. The reports are proposals and independent source reviews, not acceptance results. Linux/WSL remains deferred.
- [Nested activation review for issue21](issue21-activation-analysis-20260912.md): peer956 retains implementation ownership.
- [Free behavior canvas proposal](free-behavior-canvas-design-20260912.md).
- [Independent canvas design critique](free-behavior-canvas-critique-20260912.md).
- [Remaining navigation coverage and selection review](diagram-navigation-remaining-coverage-20260912.md).
- [Frozen source input manifest](frozen-inputs.json).
The experiment, reviews, source paths, and runtime evidence from this machine must be published before they are used as cross-machine handoffs. In-thread delegated agents share the local workspace; independently running Gitea peers do not. Live ownership, plans, and results remain in Gitea issues.
@@ -0,0 +1,93 @@
# Remaining diagram navigation coverage: verified correction seams
Read-only review, 2026-09-12. Scope: #14/#17 in `.local/diagram-usages-ytr83r-20260912`; current frozen, uncommitted working sources, not a release acceptance claim. No production changes, compilation, tests, UI interaction, or Gitea writes were performed by this review. Root owns integration and verification. Paths below are relative to that worktree.
## Decision
Both gaps are actual representations omitted by the current query. Preserve the current render/projection rules, and add explicit target identities plus presentation highlighting. A caller-preview arrow is not identified by the underlying relation ID alone. An allocation grouping's selected semantic object must remain the Allocation relation, independently of the work placement used for focus/highlight.
Issue requirements: [#14](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/14) requests textual-symbol diagram references and jumps to the corresponding element; [#17](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/17) requests equivalent tree navigation. Peer boundaries were read directly in [#3 comment 616](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/3#issuecomment-616) and [comment 627](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/3#issuecomment-627). Peer confirms the direct-relation/visible-ancestor predicate below, requires separate semantic versus placement identity for Delete, and requires retiring gesture/context lifetimes even for equal-valued navigation. Peer test evidence is not evidence for this worktree.
## A. SequenceLink arrows in caller previews
### Verified representation
- `crates/oa-desktop/src/behavior/topology.rs:904`: `sequence_links` returns actual SequenceLink relations whose two contributions belong to the requested process/chain.
- `topology.rs:914` (`GraphNode`), especially `:922`: `preview_links` stores only `(OccurrenceEndpoint, OccurrenceEndpoint)`. The relation ID is lost, unlike `GraphEdge.id` at `:942`.
- `topology.rs:1094` and `:1128`: each SequenceReference obtains the same bounded qualified preview tiles used by painting, then includes the reused definition's links only when both exact endpoints with `references = [caller_reference_id]` occur in the visible preview set. The normal bound is four tiles; expanded references allow 512. It does not add arrows for every deeper nested definition merely because nested tiles have been expanded.
- `crates/oa-desktop/src/behavior/topology/contextual.rs:253`: preview traversal resolves qualified endpoints through `TopologyIndex`; it preserves each caller path and applies the visibility limit.
- `topology.rs:1568`: the painter draws every retained preview link from the source tile's right center to the target tile's left center. Tile rectangles are then painted opaquely at `:1581`. Therefore the arrow's visible portion can be smaller than its raw line segment. These are real painted arrows, distinct from `Graph.ordered_paths`, whose explicit contract says they are projected adjacency without persisted relation IDs.
- `topology.rs:926`: `endpoint_rect` has a whole-reference proxy fallback. A usages query must continue rejecting that fallback, as existing `usages.rs:81` does for qualified tiles.
- `crates/oa-desktop/src/behavior/topology/usages.rs:89` and `:123`: current relation lookup considers `graph.edges`; it never scans `node.preview_links`. Thus a real caller arrow is absent even when the same relation has a normal link usage on its definition surface.
- `crates/oa-desktop/src/behavior/topology/direct.rs:540`: edge hit testing is also restricted to `Graph.edges`. `:105` and `:111` implement occurrence context, not qualified relation selection. `topology/view.rs:179` copies that occurrence context into `graph.selected_preview`; `topology.rs:1583` highlights tiles with it. Reusing that context to mean an edge would conflate authoring semantics.
- `crates/oa-core/src/validation.rs:2437` forbids SequenceLink self endpoints; `:2453` requires contributions directly owned by the same process/chain. Navigation should nevertheless reject missing/degenerate geometry, rather than using an enclosing box fallback.
### Minimal correction
1. Replace the preview endpoint pair with a small record retaining actual relation ID and the same two qualified endpoints. Populate it from the existing filtered relation loop. Do not add traversal, widen preview limits, or change which arrows are painted.
2. Add a target such as `ProcessPreviewLink { relation, source: OccurrenceEndpoint, target: OccurrenceEndpoint }`. The enclosing `Surface::Process(owner)` plus these fields distinguishes repeated caller instances, parallel relations, and retargeting. The existing unqualified `ProcessLink(Id)` remains appropriate for normal graph edges.
3. Share the record's exact arrow geometry between painting and usages. A midpoint of the raw segment may fall under an opaque tile; use a visible segment/gap for focus. A small helper can subtract the preview tile rectangles from the straight segment and choose a remaining segment. Require some visible nondegenerate geometry; never manufacture a row from endpoint membership alone when no arrow is emitted. This helper may be tested without changing routing or the visual layout.
4. Query the actual retained records, with `subject == record.relation`. The chooser label must include the caller path, and its role should distinguish a preview sequence link. Do not emit links for ordered-path adjacency, arbitrary nested source links, or referenced work merely because it is an endpoint.
5. Add dedicated transient preview-link presentation selection, then paint exactly that record with a selected stroke. Keep `App.selected = relation`, and clear occurrence selection for this target. Do not put an edge into `selected_context`, which is validated as an occurrence and feeds contribution operations. New canvas authoring/hit-test behavior is not necessary for the navigation fix.
6. Revalidation uses the existing one-surface query and exact target equality. Both endpoints must still resolve and the same record must still be emitted under the current expansion snapshot. Reopening after a changed accepted revision may refresh; the stale Choose event must not jump. Existing asynchronous snapshot behavior remains sufficient: no draft, camera, or selection state needs to cross the worker boundary.
### Independent expectations
- A definition's link rendered in two caller invocations yields two distinct caller targets plus its normal definition target. Choosing either keeps semantic selection equal to the relation ID while highlighting and centering the correct qualified arrow.
- A link touching the fifth hidden tile has no default caller row. Expanding only the first invocation adds that invocation's arrow, not its sibling's. Collapsing or retargeting invalidates the old target.
- Deeper expanded tiles alone do not cause usages for deeper links that the existing painter never emits. Ordered adjacency without an actual SequenceLink remains absent.
- Parallel relations retain distinct relation identities even if current preview geometry overlaps. Reverse/cross-row links focus a visible line segment, not an opaque tile interior.
- Update `topology/usages/tests.rs`'s current `process_contextual_purpose_is_a_visible_reference_but_preview_arrows_are_not_links` expectation specifically for retained preview records; preserve its exclusion of other unrepresented links.
- Exercise actual App update with open/completion/choose, old token/revision/document, reference retargeting, modal/draft protection, repeat choice, and preserved Project/SourceBundle/revision/dirty/history. Assert exact qualified selection and bounds, not merely that the destination page opened.
## B. Allocation relations represented by grouping
### Verified representation
- `crates/oa-core/src/projection.rs:81`, `parents`: Allocation projection computes actual placement parents using the effective allocation summary and nearest placed coherent work ancestors, with performer fallback. This is visual containment, separate from semantic ownership.
- `projection.rs:274` projects compatible placed nodes. Around `:300`, a collapsed ancestor or cycle prevents a descendant from entering visible `view.nodes`. Around `:331`, the resulting node records `visual_parent`; `:350` encloses containers with projected header geometry.
- `projection.rs:393`: Allocation relations are intentionally suppressed as arrows in Allocation projection. Looking only at projected edges cannot find their grouping representation.
- `projection.rs:331` and `crates/oa-core/src/validation.rs:2812`: allocation summary is explicitly aggregate display information, never an inherited Allocation relation. A summary node without a direct incoming Allocation is marked for dashed presentation. This does not authorize generating a relation usage.
- `crates/oa-desktop/src/diagram.rs:1015` derives visible containers from `visual_parent`; `:1021` paints containers before edges/children. `:1129` repaints container headers above traversing relationships. `:1452` paints nodes; selection is based on `element.id == selected`. Summary styling is separate, including `node_header` at `:1509`.
- `crates/oa-desktop/src/app.rs:718` (`selected_architecture_placement`) derives a placement from `App.selected`; `refresh_draft` immediately recomputes `selected_node` from it. `app/diagram_usages.rs:380` currently writes `selected_node`, but calls `refresh_draft` at `:395`. Setting relation semantic selection plus `selected_node = work_placement` alone therefore does not preserve focus, and the current renderer would not highlight that work. The same architecture seam applies to ports: `Target::Port` sets semantic selection to the port and owner placement separately, then draft refresh cannot find a node whose element is the port and clears `selected_node`. Root identified the existing `port_navigation_selects_port_and_exact_visible_owner_without_editing_geometry` expectation as affected while the frozen gate runs; this review did not execute it. State rows initially set `behavior.diagram.placement` (`app/diagram_usages.rs:330`), but the rest of `refresh_draft` (`app.rs:734`) recomputes that field using the same selected-node/element comparison when `state_context` resolves. Thus relation selection can clear that exact placement too. The renderer can still paint a row from selected relation identity; placement reset alone does not prove a visible row-highlight failure. Preserve and verify both semantic selection and the intended exact presentation identity.
### Confirmed predicate and minimal correction
For an actual direct `RelationKind::Allocation` r, in a saved Allocation projection only:
1. Obtain actual visible projected nodes whose element IDs are r.source (performer) and r.target (work).
2. Walk the target work placement's `visual_parent` chain through visible projected placements with a visited set.
3. Emit a grouping usage only if that chain contains the source performer placement. Retain the actual relation ID and the exact work and performer placement IDs.
This is precisely the peer-approved comment 616/627 predicate. It is not inferred from `allocation_summary`, two visible endpoints, a decomposition parent, or arbitrary semantic containment. Do not change core allocation validation, `parents`, drag/reparent commands, persistence, or peer Delete behavior.
Use an explicit target such as `AllocationGrouping { relation, work_placement, performer_placement }`, with role `allocation grouping` and the projected work's bounded labelled-header rectangle. Reuse the existing bounded node-header camera policy. This target makes the distinction reviewable; neither `Placement(work)` nor an unrelated `StateRow` target expresses it correctly.
Keep selected semantic identity equal to the queried relation. Add a separately validated presentation focus/highlight for the exact work placement, surviving `refresh_draft`; pass it to the architecture renderer independently of the semantic selection. Prefer a typed focus carrying document, revision, diagram, relation, placement, and navigation epoch, so normal selection/document changes cannot reuse stale focus. An alternative is deriving highlight from selected relation and projected grouping each paint; that avoids stored focus but needs proof it preserves exact placement when multiple representations exist. Do not silently change selection to work to reuse the current stroke logic. Use the same separation for architecture ports, while preserving state-view placement semantics. Do not blindly restore `selected_node` after refresh: coordinate its edit/Delete meaning first. Independent App tests should assert the exact validated visual marker (port owner, grouping work, or state row) and unchanged semantic target, rather than requiring an overloaded global edit-selection field.
Coordinate this presentation focus with the peer's Delete capture: removal continues to capture the selected relation as semantic target; focus placement is separate context, never a replacement semantic target. Explicit later user selection of work can of course change the target. Preserve `app/diagram_usages.rs:382`'s unconditional canvas epoch increment, menu closure, bend/connection reset, and every pending-draft guard, including navigation returning to equal values. Extend deferred reveal to validate the same grouping target; its temporary pending tuple is consumed after layout and should not double as persistent highlight state.
### Independent expectations
- A visible direct allocation with the performer's placement on the actual work ancestor chain produces one grouping row and focuses that exact work header, even when the performer is not its immediate visual parent.
- Hidden/folded work, hidden performer, wrong projection, endpoints that are merely both visible, a mismatching visual-parent chain, and aggregate-only summary produce no direct Allocation usage.
- A direct child allocation underneath a summary container remains discoverable if its target is visible and its performer occurs in the chain. No extra relation is invented for the summary container.
- Choosing preserves the complete model/source/history and leaves `App.selected == relation`; highlighting work does not make a subsequent Delete capture target work. Test this against peer's integrated removal contract, not by assuming current adapter state alone proves it.
- Fold/delete/retarget/diagram replacement invalidates an old grouping target. Repeat navigation retires old canvas/context tickets even when destination/selection values compare equal. Both initial and deferred camera reveal reject stale document/revision/epoch.
## Integration boundary and source identity
Suggested bounded production seams: `diagram_usage.rs` target/query/label; `behavior/topology.rs` preview record/geometry/paint; topology `usages.rs` query/reveal and `view.rs` selection wiring; minimal topology presentation-state field; App adapter and architecture canvas presentation-focus wiring. Root coordinates shared App/view changes and peer Delete compatibility. No model/schema/dependency or allocation-authoring changes are required.
Verified SHA-256 snapshots (raw file bytes):
| File | SHA-256 |
| --- | --- |
| `behavior/topology.rs` | `dff564d2dca68af02874878cabdabdcb7f717bff67b221d376ccb6734a2e16ae` |
| `behavior/topology/usages.rs` | `d1ff2f16695d560bd2676825eb6c11d82b0c259cc84d6804dc2dbd1a8dadc42c` |
| `diagram_usage.rs` | `11ed6c844148eba6a122c675168561e9e9dc4e88399ae4fc0facfb82d79bdd89` |
| `app/diagram_usages.rs` | `2374a9323bf422c8cb1af7832aa2c3ce3294a894f1fc710ba165c557b26d8c8b` |
| `oa-core/src/projection.rs` | `69ed12bace2cc5024e151752a174ab14034ac2d05eb741fcf13e9a27521c059b` |
| `oa-core/src/validation.rs` | `7c1b4ae5e4ebba13e99af9158ccde138dfc5e9a7afb580e76fba72d0b64ba74e` |
Line references describe these inspected working files. Root's in-progress checks cover the frozen implementation before these proposed corrections, not the proposal. Root should implement after the freeze, run focused query/App tests plus required project checks, and inspect actual repeated-call arrow and allocation-grouping navigation with semantic selection/Delete capture before accepting coverage.
@@ -0,0 +1,104 @@
# Independent critique: freely editable behavior canvases
2026-09-12. Reviewer `/root/diagram_usage_workflows`, delegated by Codex-ytr83r. Read-only review of current issues #2/#20/#22, the proposal in [free-behavior-canvas-design-20260912.md](free-behavior-canvas-design-20260912.md), and primary code in `.local/diagram-usages-ytr83r-20260912`, branch `codex/diagram-usages-ytr83r-20260912`, base `7aa007b0777aa182a99f46e90eeb9b2558f3ad2a` plus root's uncommitted navigation changes. No production edit, build, GUI operation, or Gitea mutation. This is design evidence, not native acceptance. Root owns synthesis; peers retain #16 resize and #21 activation rendering ownership.
## Actionable conclusions
1. **Conditionally adopt the existing Diagram identity/lifecycle, not the entire proposed implementation shape at once.** Owner-bound Process and Scenario projections fit saved views and avoid a second navigation/source/API aggregate. Use a single tagged behavior-layout payload, or an equally strict validated representation, rather than unrelated optional process/scenario blocks. Preserve the existing architecture/state storage contract. Do not make moving every desktop geometry algorithm into core a prerequisite for the first useful slice.
2. **Resolve the projection/gesture contract with a bounded numeric experiment before committing to the scenario schema.** Absolute desired anchors are a credible candidate; stored and resolved geometry legitimately differ already in architecture/state. What remains undefined is conflict resolution, the inverse from a requested drag/resize to authored changes, and what a text-only user sees after reorder. The table below makes this uncertainty falsifiable. This is a policy prerequisite, not a categorical rejection of desired coordinates or permission to postpone the feature indefinitely.
3. **Include legacy ordered process paths in the route contract.** Requiring an explicit SequenceLink before bending an already drawn legacy arrow fails the user's bend request for those existing models. Add a typed derived-path address and a defined lifecycle. Never manufacture semantic links as an elbow-drag side effect.
4. **Retain relation identity in qualified previews before saving their routes.** Current preview links retain only endpoint pairs. Parallel links would collide if those pairs became the persistence key. A qualified route must identify both the full caller path and the relation. The same leaf reached through different paths must remain independently editable.
5. **Do not implement first-edit capture as a screenshot-to-model copy.** It must seed valid authored inputs whose projected result equals the preview, preserve omitted/invisible records, and allocate view/placement identities once. Peer #16 already supplies a concrete counterexample to copying rendered dimensions back as authored dimensions. Complete capture also needs a size/performance bound and a stable policy for missing or collapsed appearances.
6. **Specify reference transformations and source comment keys before UI fan-out.** Owner deletion/change, reidentify, caller-target changes, source reorder, legacy-to-explicit conversion, and hidden routes are not incidental cleanup. They determine whether manual work survives normal editing. Two views of one owner must be part of the first identity tests.
## Requirements and verified evidence
The current user clarification in [#2 comment608](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/2#issuecomment-608) rejects the camera-repair milestone as satisfying free behavior editing. [#20](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/20) requires spreading lifelines to make call names readable, moving arrows, resizing, and replacing strange controls. [#22 comment606](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/22#issuecomment-606) specifically adds process connection bends. Earlier sequence-constraint discussion does not erase these requirements. Cosmetic manipulation should preserve semantics; graphical/text/API parity follows the user-owned project specification. Always-present canvas and ordinary Properties are the agreed direction, not permission for canvas keyboard actions behind a focused text field.
Verified local constraints:
- [model.rs:1431](../../../crates/oa-core/src/model.rs#L1431): ProjectionKind is Copy and currently has only a StateMachine owner variant. Diagram contains common metadata, view options, ID-keyed NodePlacements and relation/trace EdgeRoutes. Keeping owner IDs in ProjectionKind while storing layout separately avoids a needless Copy-breaking change.
- [validation.rs:645](../../../crates/oa-core/src/validation.rs#L645): routes must refer to existing relations/traces, are unique per edge, have bounded finite waypoints and normalized label fractions. [validation.rs:774](../../../crates/oa-core/src/validation.rs#L774) enforces one placement per semantic element per diagram. Repeated qualified appearances therefore cannot simply be extra ordinary nodes referencing the same leaf.
- [topology.rs:914](../../../crates/oa-desktop/src/behavior/topology.rs#L914): GraphNode previews carry OccurrenceEndpoints; preview_links are only endpoint pairs. OrderedPath explicitly has source/target/points and no relation ID. [topology.rs:1128](../../../crates/oa-desktop/src/behavior/topology.rs#L1128) drops each preview relation's ID while constructing those pairs.
- [topology.rs:1000](../../../crates/oa-desktop/src/behavior/topology.rs#L1000): Graph rebuilds a TopologyIndex, derives rank from explicit links plus ordered adjacency, then constructs geometry. The rank traversal filters the adjacency list for each queued node. This is a concrete existing repeated-scan risk; adding stored layouts should not multiply this by every saved view on every pointer move.
- [behavior.rs:1393](../../../crates/oa-desktop/src/behavior.rs#L1393): scenario rows follow steps/branches and recursively accumulate geometry. Fragment and branch boxes have different anchor conventions. A message y, frame rectangle and branch extent need a deliberate canonical relationship.
- The separate [#21 read-only activation analysis](issue21-activation-analysis-20260912.md) verifies self-message receive geometry below its row anchor and existing lifetime/branch attachment concerns. This foundation must expose send/receive anchors to the activation owner; it must not implement a competing activation engine.
## Storage alternatives against the actual criteria
| Candidate | Manual freedom and identity | Source/API/lifecycle cost | Main falsifier | Recommendation |
| --- | --- | --- | --- | --- |
| Shared Diagram plus independent optional process_layout/scenario_layout | Expressive; keeps saved-view identity | Small additive syntax, but many invalid combinations and duplicated authority | Scenario projection with process layout or generic unrelated nodes passes unnoticed; two records claim one direct appearance | Avoid this public contract unless strict cross-field validation is explicit and exhaustive |
| Shared Diagram plus tagged BehaviorLayout, projection retains owner ID | Expressive; common metadata/navigation/history retained; domain records typed | Moderate schema/parser/walker work; owner/tag compatibility still needs validation | Tag/owner mismatch, same address in generic and qualified records, incompatible fields retained after projection change | Preferred bounded shape; constructor/accessor invariants plus parser/API validation |
| Behavior layout stored inside a payload-carrying projection enum | Stronger type coupling possible | Changes Copy assumptions and a widely matched enum; can make common projection queries expensive | Large ripple before first persisted move; geometry cloning during inexpensive kind checks | Viable only if implementation evidence makes it simpler; not needed merely for type purity |
| Separate top-level BehaviorView collection | Clean discriminated domain structure | Duplicates naming, identities, references, source ownership, REST inventory, selection, recovery, where-used and view deletion | A process view cannot participate in ordinary diagram navigation/export/history without a second branch everywhere | Keep as fallback if common Diagram validation becomes unmanageable, not first choice |
| Session-only map or spacing sliders | Quick visible result | Cannot provide durable source/REST/reopen parity | Save/reopen loses edits; an individual bend or position remains impossible | Rejected as production feature; candidate preview remains transient |
Minimal recommended boundary: common Diagram ID/metadata; Process/Scenario owner tags; ordinary direct-process nodes and explicit relation routes; typed extra addresses only where the existing representation cannot express identity. A tagged Process payload can hold qualified placements and derived adjacency routes. A tagged Scenario payload can hold lifeline/event/frame/message geometry. Empty ordinary nodes/routes should be required where they have no defined scenario meaning. Do not relax the global one-element-per-diagram invariant just to fit qualified appearances.
Define whether an empty qualified path is illegal or canonicalizes to the ordinary direct occurrence. Allowing both forms creates two geometry authorities. Prefer rejecting the empty path in the qualified-only collection. Presentation records keyed by semantic addresses need not invent global UUIDs, but any new placement UUIDs must join identity/reidentify/alias/serialization walkers consistently. Neither indexes nor displayed labels are persistent addresses.
## Numeric experiment for constrained scenario geometry
These are deliberately simplified independent examples, not production metric claims. Let origin=0, minimum gap=10, A and B each have height20, order=[A,B], displayed tops A=100/B=200. Compare (D) absolute desired tops plus the illustrative monotone projection `resolved[i] = max(desired[i], previous_bottom + 10)` and (G) nonnegative gap-before stored on each occurrence, initially gap(A)=100/gap(B)=80. Neither example algorithm is adopted by this report.
| Operation | D with no inverse adjustment | G with no inverse adjustment | What the experiment must decide/prove |
| --- | --- | --- | --- |
| Move A to50 | A50/B200 | A50/B150 | Ordinary move should be able to preserve B at200; G needs gap(B)=130. Test a planner that changes only necessary dependent records. |
| Move A to250, preserve order | A250/B280; B's desired200 remains displaced | A250/B350 | Both preserve semantics, but select different whitespace policies. Preview must show B's actual final position. A feasible requested layout A250/B280 must be expressible in both (G gap(B)=10). |
| Move B upward to110 | B resolves130; stored110 differs | Requested negative/too-small gap needs defined clamp or rejection | Report a concrete constraint and preview actual B130; never commit one pixel result and reopen another. Explicitly distinguish desired values from resolved inspector values. |
| Increase A height20→80 | A100/B200 remains feasible | A100/B260 | Resize must be able to preserve B at200 when feasible (G gap(B)=20). Inactive dimensions and unaffected coordinates should not drift accidentally. |
| Increase A height20→120 | A100/B230 | A100/B300 | Minimum-gap conflict now exists. Show which rows move and why; preserve authored inactive axes. A source/API resize must produce the same projection as the GUI candidate. |
| Source reorder to[B,A] | B200/A230, A desired100 displaced | B80/A200 if each gap travels with its occurrence | Both are deterministic yet materially different. Specify whether whitespace belongs to an occurrence, a predecessor pair, or a sequence boundary. No passive rewrite or semantics-from-y. |
| Delete A | B200 | B80 | This is a lifecycle choice, not a numerical accident. Preserve surviving absolute position or deliberately remove preceding whitespace; GUI/source/API must agree. |
The test harness should enumerate small feasible integer layouts and check every requested feasible result has an authored representation and a stable projector result. Test repeat projection idempotence, no hidden model/source mutation, and planner preview = committed projection = source round trip = JSON/REST round trip. Measure changed records as well as output positions; equality from calling the same solver twice is insufficient. Independently assert the expected selected coordinate, semantic order and unchanged unaffected positions.
Additional discriminating probes:
- Nested fragment F spans y80..400, operand starts120, A160 and B260. Resize only F's bottom to300, then to220. Define header, padding, operand and child containment constraints. The first feasible result must preserve authored children. The second must report/preview specific container growth, constrained bound or chosen child movement; silently clipping children or reparenting them is invalid. Repeat moving F with and without an explicitly named group-move action, specifying absolute versus translated child coordinates.
- Self-call send at200/receive at224, reply later at320: move the call to250 and change its loop height independently. Send, receive, activation start and reply attachment must consume the same anchor outputs. A single `message.y` is sufficient only if the receive-offset convention is explicitly part of projection/route geometry. Interior waypoints must not accidentally change the semantic receiver or activation interval.
- A delayed-created lifeline must attach its header to its creation receive anchor after message movement; deletion must end the lane at the deletion receive anchor. Moving a header horizontally never changes sender/receiver. Hidden branch paths must retain stored values without entering a contradictory visible ordering.
- Repeated messages with one exchange and distinct occurrence IDs get independent y/bends/label offsets. An opaque ScenarioUse does not create layout for callee events merely because bindings refer to them.
- Text reorder with conflicting desired anchors must return a deterministic inspectable layout diagnostic containing the affected occurrence addresses and reason. Decide whether the UI displays desired and resolved values, offers an explicit Normalize Layout transaction, or exposes the conflict otherwise. Valid semantics must not be silently rewritten to match pixels.
Recommendation: implement both tiny pure candidate projectors/inverse planners outside production architecture and run these probes. Start with absolute anchors as the likely better fit for exact coordinates and preserving unaffected positions, but select it only after the nested/lifetime probes and inverse-resize counterexample pass. Gap-before remains a meaningful comparison, not an automatic-only caricature: a planner can translate requested absolute positions into gaps. Record measured complexity and source diff size. Bound this experiment to the policy uncertainty rather than broad renderer extraction.
## Reference lifecycle and source contract that cannot remain implicit
| Case | Required independent oracle |
| --- | --- |
| Two saved views of one owner | Change only view V1's layout; V2 and semantics remain byte-for-byte equal. All context stamps, camera caches, navigation and recovery include diagram ID. |
| Reuse same callee twice; nested reuse twice | Route/resize `[caller1,nested1]/leaf` only; caller2 and the callee definition remain unchanged. Parallel callee relations retain separate routes despite equal endpoints. |
| Delete/reidentify caller or occurrence | Reidentify transforms every address component and source comment key; delete removes or explicitly invalidates dependent records in the same validated transaction. Never retarget by name. Undo restores exact keys and geometry. |
| Change a caller's referenced process | Reject incompatible old paths or remove them through an explicit reported transformation. Reuse of a UUID elsewhere must not silently activate an unrelated stale record. |
| Legacy order A,B,C → A,C,B | Derived route(A,B) stops applying; route(A,C) is a different key. Define whether obsolete records are removed, retained dormant, or diagnosed. If retained, state whether reintroducing adjacency restores them. The decision must be bounded and tested. |
| Convert legacy paths to explicit links | Define an atomic presentation route migration by exact endpoint correspondence, with ambiguity handling for parallel links. No automatic semantic conversion during bend edits. |
| Filter/collapse temporarily hides a route/node | Preserve authored records. Partial current visibility must never become a destructive replacement snapshot. Reopen/reexpand restores the same geometry. |
| Change diagram owner/projection/layer | Reject incompatible retained fields, or require an explicit complete conversion in one transaction. No silent geometry loss or unrelated node acceptance. |
| Invalid source/API payload | Reject duplicate typed keys, owner/tag mismatch, scenario event of another owner, empty/invalid qualified path, wrong route subject kind, NaN/infinity/out-of-bounds geometry, and over-budget path/point collections with precise field diagnostics. |
The current version7 strict parsing/serde and validation gates require a coordinated schema version decision, not unversioned optional-field accretion. Old sources should open clean without synthesized diagrams or formatted rewrites. An older reader must reject unsupported new constructs rather than discard manual geometry. Source format/parse, JSON, REST conditional transactions, reference walkers, copy/transition, multi-file ownership and comments all need compatible changes.
Nested comments must be matched by the full typed key: a scenario occurrence, qualified endpoint, qualified relation, or derived ordered-path pair plus its domain. Array index and terminal occurrence alone are insufficient after reorder/reidentify. Same-named aliases in included files must resolve by IDs. Explicit reset of one geometry record must not discard sibling comments or materialize invisible records.
## First edit, scalability, and proportionate implementation
First accepted gesture should create the view and required authored records in one normal transaction. Pointer-down/preview may reserve deterministic candidate IDs, but render, selection and cancel create no source changes. Undo removes the first view creation; redo restores the same IDs and geometry. If a first resize begins from derived geometry, preserve the authored-versus-resolved contract established by #16 instead of serializing every projected width/height.
Complete direct-surface capture protects untouched objects against later seed-layout movement, but has costs: an O(model-size) first edit, larger source diffs, new identity allocation and potential dependence on transient filters. Sparse capture is smaller but leaves untouched nodes dependent on changing ranks/row generation. A bounded compromise is a stable initial placement plan plus explicit overrides, provided that this does not introduce two unexplained coordinate authorities. The first slice should compare total records and diff size on a realistic long model before selecting capture policy. Do not claim that “currently rendered” means a stable semantic set until filter/expansion/default-view rules are fixed.
Keep stored geometry projection pure and reuse geometry primitives. It is not necessary to relocate the entire Scene/Graph renderer before proving persistence. An adapter can resolve typed authored records into current Scene/Graph positions, attachment anchors and routed paths; both preview and committed render must consume that result. Any behavior constraint or inverse planner needed by REST should be UI-free. Do not duplicate a second projector for source/API or retain competing automatic geometry paths that overwrite saved positions late in rendering.
The existing process rank scan can approach V×E work; repeated TopologyIndex rebuilding and qualification resolution add cost. Cache immutable owner/topology indexes per model revision, rebuild affected geometry once per candidate, and bound visible expansion separately from stored-record validation. Validate stored keys without enumerating every possible recursive appearance. Limit total records, aggregate path length/depth and points as well as points per route. A saved view must not force eager expansion of the Cartesian product of nested uses. Stress tests should record first-edit latency, per-pointer candidate work, lookup/reopen work and source size on the same fixture, with an explicit target budget agreed for the actual hardware rather than invented acceptance milliseconds.
## Minimum independent acceptance before broad adoption
1. One owner-bound process view moves a direct occurrence off its rank column, resizes it, bends both an explicit link and an existing legacy path, and moves a label. Links, steps and represented work do not change. Preview/commit/reopen are numerically equal and one Undo restores source/model.
2. Two-lifeline scenario independently spaces headers and positions/routes two occurrences of the same exchange, preserving sender/receiver, message kind, reply_to, steps and lifetimes. Long labels become inspectable through ordinary controls. The numeric source-reorder/resize policy probes above pass.
3. First edit, cancel, zero movement, stale revision, document/view switch, dirty-source navigation, focus loss and modal entry have explicit nonmutation or atomic commit outcomes. Actual App input paths must be exercised later, not only pure command constructors.
4. Two saved views and two qualified appearances retain independent geometry, full target identity and source comments across save/reopen, REST, reidentify, collapse, delete and Undo. An exact usage jump reaches the saved appearance without changing geometry.
5. Nested fragments, operands, self messages and delayed creation/deletion use explicit attachment outputs. Peer #21 activation rendering is reviewed against those outputs; this task neither overwrites its fix nor claims its native acceptance.
6. Actual native workflows at the minimum supported window demonstrate immediate canvas manipulation, visible resize/bend handles, Properties focus, discoverable semantic Reorder, and stable viewport origin. A screenshot or small fixture alone does not establish all process/scenario kinds or large-model usability.
Adopt the common saved-view direction and a bounded end-to-end slice now; settle the numeric projection/inverse and address-lifecycle rules before multiplying UI controls and schema cases. Revisit the common Diagram choice only if the typed payload/validation slice demonstrates more duplication than a separate aggregate, not because domain-specific geometry exists.
@@ -0,0 +1,185 @@
# Freely editable process and scenario canvases — design investigation
2026-09-12. Read-only investigation by delegated reviewer `/root/diagram_membership_map` for Codex-ytr83r. Source inspected in `C:/Users/User/Documents/Git/ARCADIA-Studio/.local/diagram-usages-ytr83r-20260912`, branch `codex/diagram-usages-ytr83r-20260912`, base `7aa007b0777aa182a99f46e90eeb9b2558f3ad2a` plus root's uncommitted navigation/prerequisite integration. This is a proposal, not an implemented feature or an acceptance result. No source modifications, build, GUI operation, or Gitea claim was performed. Root owns compilation and native inspection; peer Codex-956atf owns #16 resize foundation and #3/#15 work.
## Required outcome and evidence boundary
The user's [#2 clarification608](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/2#issuecomment-608) explicitly rejects the camera/repair preview as satisfying free behavior editing. Process and scenario diagrams must support ordinary direct manipulation comparable to architecture/state diagrams. The earlier comment250 about sequence constraints does not authorize retaining rigid automatic-only layouts after that clarification.
Concrete requirements are [#20](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/20): spread lifelines to expose labels, move arrows, resize objects, replace strange draggable rectangles with understandable controls; [#22](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/22), including comment606: process movement, resizing, and connection bends; [#24](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/24): replace the Details-menu interaction; [#25](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/25): canvas available without an activation button. The user-owned specification also requires graphical/text parity, an unambiguous reST specification, REST automation, readable source, and maintainable architecture. Cosmetic movement is not authorization to change behavioral ordering.
The [peer resize foundation at full commit f7d84faf30cdb5e3695c2dc16ee0a5f2eac91e71](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/src/commit/f7d84faf30cdb5e3695c2dc16ee0a5f2eac91e71/harness/diagram-resize-foundation-20260912.md) was read, including its executed falsifiers and unresolved questions. Its verified contract is eight handles, fixed opposite edges, unchanged authored child placements/semantic ownership, one Undo transaction, preservation of inactive authored fields, and exact projected preview/reopen equality. It rejects copying every visible dimension back into storage: stored224×160 projects224×232, copying224×232 can project232×232, while preserving authored height permits214×232. It also rejects a universal preferred minimum on an inactive axis. Those are resize-planner requirements, not reasons to omit handles. Process/scenario persistence is explicitly a separate dependency. No new resize-gesture implementation is claimed here.
Existing [native Capella benchmark](../../../harness/release-capella-scenario-benchmark-20260910.md#L1) demonstrates point creation, a drag-created LOOP/operand, and distinct occurrence/definition identities at1010×760. It does not establish resize, message movement, routing, or nested activation behavior. Root's current native capture attempts timed out, so no new native evidence is claimed.
## Current implementation: the missing persistence boundary
| Surface | Actual geometry and interaction | Consequence |
| --- | --- | --- |
| Persisted architecture/state | [`Diagram`, `NodePlacement`, `EdgeRoute`][model] provide stable view/placement identities, absolute coordinates, authored size, routes and labels. `ProjectionKind` has StateMachine but no Process/Scenario owner variant. | Existing source/history/API mechanisms are reusable. Adding process/scenario enum labels alone cannot make their desktop renderers consume saved geometry. |
| Process | [`Graph::expanded_qualified`][graph] derives columns from SequenceLinks/legacy order and places every contribution at `x=24+rank*420`, initial size270×104. Reuse cards get automatic preview height; expansion chooses4 or up to512 tiles. [`State`][topology-state] stores ephemeral camera/expansion/draft state, no persisted layout. | Every render reconstructs positions and routes. No user-authored movement survives because no such geometry exists in the model. Source owner `steps` determines included occurrences, not coordinates. |
| Process input | [`direct::Graph::input`][process-input] selects from node bodies. A separate [`handle`][process-handle] starts `Press::Reorder`; release publishes Reorder, not Move. The planner rejects cross-column reorder because links define columns. Reconnect handles alter semantic links; there is no bendpoint drag. | The strange rectangle is a semantic reorder affordance, not a misplaced implementation of free movement. Renaming it or making it larger cannot satisfy #22. |
| Qualified process reuse | [`contextual::preview`][context-preview] and `GraphNode.preview` retain caller paths plus occurrence IDs. Direct ContextualLinks retain relation IDs; preview links currently reduce callee links to endpoint pairs. | Two appearances of one callee occurrence must have independent layout. Saving by represented work ID or callee occurrence ID alone will alias them. Preview routes need the complete caller path plus callee relation ID before they can be authored. |
| Scenario | [`Scene::sequence`][scene] gathers direct lifelines, places them at automatic x positions (160+i*240), creates fixed204×70 headers, and [`occurrences`][scene-occurrences] walks semantic sequences/operands to build fixed row spacing, boxes, arrows and frames. Lines are keyed by exchange **occurrence** ID. [`Presentation`][presentation] stores only identity, viewport, focus/shelf and camera. | Lifeline spacing, event y, box/frame dimensions and route bends are not model data. Reopening cannot restore manual layout. Repeated messages using one exchange still require separate presentation. |
| Scenario input | [`Scene::reorder_handle`][scenario-handle] creates a22×24 rectangle at x6 beside the selected row. [`scenario::reorder`][scenario-reorder] changes `SetSteps` within the current owner/operand only. | The existing drag is an ordered-list edit. It does not represent free line movement, independent whitespace, or shape sizing. |
| Scenario lifetime/activation | [`scenario_lifecycle`][lifecycle] derives birth/death/call semantics, with rendering consuming occurrence rows/sequence bounds. ScenarioUse is currently an opaque card; bindings do not produce inlined callee rows. | Geometry must consume semantic lifetimes and ordering; it must not derive new semantic call/death relations from drawn coordinates. Nested activation #21 remains a separate semantic/rendering dependency. |
| Shared shell | [`controls`][controls] has Details and Canvas buttons; `keyboard_enabled` and `Scope::input_owner` gate draft/modal contexts. [`host`][host] overlays a300px editor over the viewport. | Replace the activation/Details UX, but preserve actual keyboard ownership and stale-context protections. Always-active pointer editing is compatible with text inputs owning their keyboard. |
The authoritative existing presentation specification is [language.rst section5][language-diagrams]. Ordinary `node` coordinates are absolute diagram coordinates and do not alter containment/allocation. `routes.edge` currently accepts a Relation or Trace, never a scenario exchange occurrence. Route list order/comments are retained by identity; endpoints and automatic elbows are deliberately not saved. [`Command`][commands] already has Create/EditDiagram, Create/EditNode, MoveNode, Set/RemoveEdgeRoute, SetSteps, Batch and Layout. [`Document::execute`][document] prepares a complete candidate, updates source with the identity map, and commits the accepted model/source pair together. [Server routes][server] expose conditional project transactions; adding layout must use this pathway, not a second desktop-only store.
## Alternatives and proposed choice
Criteria: satisfy manual placement/resizing/bends; preserve behavioral semantics during cosmetic edits; exact source/API/Undo/reopen parity; retain existing authored architecture/state geometry; use stable identities for repeats; keep the interaction understandable; avoid a broad rewrite before a useful end-to-end workflow exists.
| Candidate | Advantages | Material failure or cost | Decision |
| --- | --- | --- | --- |
| More camera controls, auto-layout spacing sliders, wider fixed cards | Small desktop diff; preserves current generator | Still cannot place individual objects/routes; explicit user rejection already falsifies sufficiency | Reject as the feature; optional layout assistance only |
| Desktop/session position overrides | Fast visual prototype | Loses source/REST/save parity; undo splits between model and view; stale/reused identities become ambiguous | Reject production storage; transient drag preview is its only role |
| Put all behavior in an unconstrained generic graph, with free x/y treated as semantic order | Broad shape reuse | Cosmetic drags can change execution; sequence endpoints, lifecycle, operands and nested calls require special treatment anyway | Reject semantics-by-coordinate; reuse primitives only |
| New independent BehaviorDiagram top-level aggregate | Clean domain separation and typed layouts | Duplicates view naming/identity/source ownership/artifacts/navigation/server inventory; more migration and integration than needed | Viable if Diagram becomes unmaintainable, but not smallest coherent first choice |
| Extend existing Diagram with owner-bound Process/Scenario projections and typed domain layout | Reuses stable saved-view lifecycle and source transactions; direct process nodes/routes fit existing records; scenario-specific anchors stay explicit | Requires real core/source/API work, and pure geometry extraction from desktop | **Proposed choice**, with the type partition below |
Reuse direct process `NodePlacement` and existing relation `EdgeRoute` records. Do not distort scenario arrows into fake semantic relations just to use EdgeRoute. Do not force every scenario representation into a generic rectangle with meaningless fields. Add typed scenario presentation keyed by occurrence/lifeline identity and typed qualified-process presentation keyed by full call path. These records remain inside the same Diagram, with the same history/source owner. This is a deliberate domain distinction, not separate persistence technology.
## Proposed persistence contract
This section is an implementation candidate requiring specification review, not a declaration of existing syntax. The current schema/source version is7. Reserve a new version during integration; examples below use8 provisionally. Coordinate the version with other schema owners before editing it.
1. Add `ProjectionKind::Process { process: Id }` accepting a Process or FunctionalChain owner, and `Scenario { scenario: Id }` accepting a Scenario, each in the diagram's layer. A diagram has one explicit owner. Multiple saved views of that owner are legal and independent. Owner identity and diagram identity are distinct.
2. Process direct occurrence boxes use ordinary `Diagram.nodes`: one placement per included occurrence in a view, positioned independently of its represented work/exchange. Explicit SequenceLink and ContextualLink geometry uses ordinary `Diagram.routes`. Moving any process node changes only its placement; it does not edit links, parent, steps, represented element, or allocation. Automatic rank is only a seed/explicit Arrange result.
3. A typed optional process presentation block holds `context_nodes` and `context_routes`. A contextual node key is `OccurrenceEndpoint { references: Vec<Id>, occurrence: Id }`. A contextual route key is `{ references: Vec<Id>, edge: Id }`, where the edge belongs to the resolved called process. Direct ContextualLink edges still use their own relation ID in normal routes. Each key is unique per view. Retain full IDs in the scene, including preview links; never use labels, tile indices or abbreviated paths as keys.
4. A typed optional scenario presentation block has separate records for lifeline headers (`lifeline`, `x`, `width`, `height`), message anchors (`occurrence`, desired `y`), boxes/frames (`occurrence`, desired rectangle), operand presentation extents, and message routes (`occurrence`, pinned waypoints, optional EdgeLabel). Types reject inapplicable fields. Lifeline x is presentation order: the present metamodel does not contain Sirius's explicit semantic instance-role ordering, so do not invent one. Normalized route-label fractions/offsets and finite coordinate/size limits reuse existing primitives.
5. Scenario box/frame time anchors have one canonical derivation from their rectangle (specified per kind, e.g. top event/header anchor); no competing stored `y` values for one occurrence. Birth/death ends and execution intervals remain derived semantic attachments. Header x/size is authored; creation timing determines its vertical attachment. A box attached to a lifeline may have a presentation x offset/leader while retaining the same lifeline reference. A cosmetic horizontal move must never rebind its participant.
6. Persisted process child coordinates are absolute, matching normal nodes. Moving a reused group translates its visible descendant presentation records in one batch if group movement is selected; resizing a containing frame preserves child authored coordinates, consistent with #16. Scenario frame resizing changes frame geometry and available space; it does not silently add/remove covered events, change operands or move semantic ownership.
7. Valid, feasible authored geometry is used exactly. Missing records use deterministic initial geometry. Passive rendering/navigation never creates records, marks dirty, saves, or resets authored geometry. Existing records survive collapse, temporary invisibility, filters and owner renames. Delete/reidentify/reparent/view-owner changes must explicitly clean or transform dependent references in the core transaction; stale path records cannot silently bind to a new same-named object.
8. New records count against parse/model limits; route points retain a bounded per-route limit. Resolve caller paths with existing cycle/depth defenses and a bounded visible expansion budget. An explicit partial expansion is not permission to discard invisible authored records. Large stored layouts should not be rebuilt in App.update per pointer move.
Example candidate source, following existing constructor/record conventions:
```text
arcadia 8;
// Existing semantic declarations omitted for brevity.
diagram response_view "Response workflow" {
layer Oa;
projection { Process { process @oa_response; }; };
routes [{ edge @oa_confirm_path;
waypoints [{ x 580; y 110; }, { x 580; y 360; }];
label { fraction 0.5; offset { x 0; y -16; }; }; }];
process_layout {
context_nodes [{ endpoint { references [@oa_assess_step];
occurrence @oa_assessment_action; };
position { x 95; y 185; };
size { width 210; height 85; }; }];
};
}
node confirm_view {
diagram @response_view; element @oa_confirm_step;
position { x 710; y 350; }; size { width 320; height 125; };
}
diagram conversation_view "Conversation" {
layer Oa;
projection { Scenario { scenario @oa_conversation; }; };
scenario_layout {
lifelines [{ lifeline @oa_caller; x 180; width 240; height 90; },
{ lifeline @oa_responder; x 660; width 280; height 90; }];
messages [{ occurrence @oa_call; y 210; },
{ occurrence @oa_reply; y 390; }];
message_routes [{ occurrence @oa_call;
waypoints [{ x 430; y 240; }];
label { fraction 0.55; offset { x 0; y -20; }; }; }];
};
}
```
`oa_call` and `oa_reply` intentionally have independent anchor/route records although the release fixture uses the same underlying `oa_contact` exchange for both. `oa_confirm_path` is the fixture's explicit link from `oa_merge` to `oa_confirm_step`. Exact grammar, diagnostics and canonical formatting must be specified and round-tripped before UI depends on this candidate.
API candidate: existing CreateDiagram/CreateNode/MoveNode/EditNode/SetEdgeRoute remain ordinary direct-process operations. Add typed upsert/remove operations for contextual nodes/routes and scenario lifelines/items/message routes, or one `EditBehaviorLayout { diagram, patch }` with a strictly tagged list of those operations. Prefer bounded per-record patches for scripting and safe comment retention; retain full EditDiagram replacement for existing generic clients. Do not make full-diagram replacement the only geometry API. A scenario message move changes its anchor and any explicitly previewed affected neighbor anchors in one `Batch`; an explicit reorder adds `SetSteps` to that same batch. REST uses the existing conditional transaction route and concurrency rules. Source writeback updates only the owning diagram declaration/file and matches nested comments by full typed key.
## Scenario drag policy: compare before deciding
The user requested movable arrows, not implicit behavioral mutation. In the current model, ordered occurrences and operand membership carry sequence meaning independently of their visual y. There are two materially different policies:
| Policy | Benefit | Risk | Assessment |
| --- | --- | --- | --- |
| Ordinary drag crossing another event commits `SetSteps` | Closest to Sirius event reorder; quick behavioral edits | An engineer making room for a long label can change execution; a few pixels of overshoot is consequential; source diff mixes geometry with semantics | Do not make this the default without direct user-workflow evidence |
| Ordinary drag edits presentation; explicit Reorder changes steps | Cosmetic operations preserve semantics; source diff/Undo intent is clear | Need an understandable constraint/ripple preview and an accessible reorder command | **Recommended default** |
Within the second policy, a hard tiny-gap clamp would remain frustrating and could repeat the rigid-canvas failure. Prefer a local spacing planner: drag within available space moves the chosen anchor; dragging farther proposes moving the affected following/preceding event block while retaining semantic order. Show every moved row in the preview. The user can insert/remove vertical space directly, spread lifelines freely, move labels/bends independently, and resize boxes/frames. A selected arrow itself is the handle for movement; no left-margin rectangle is required. A pointer cursor/status can say “Move message” or “Reorder message” according to the active action. Do not silently fall back from a blocked layout move to semantic reorder.
Provide named Reorder in the common context menu/Properties actions and keyboard accessibility. An optional modifier may invoke the same action after it is discoverable; the modifier is not the sole route. Reorder shows a before/after insertion marker in the actual operand and previews lifecycle/activation changes. Cross-operand movement remains a separately named semantic action until its valid rules are implemented. Complete reorder in one atomic semantic+layout transaction, not a SetSteps commit followed by a best-effort geometry save.
Two storage choices for constrained y require an early evaluator:
- Absolute desired anchors are easy to understand in text and support precise coordinates. When source editing changes steps without adjusting layout, the pure projector must resolve only actual order/containment conflicts, retain authored values and report displaced anchors; it must not allow a contradictory rendered sequence or rewrite source during render. GUI reorder should persist its previewed resolved anchors, so reopen matches exactly.
- Nonnegative gap-before records naturally survive order edits and make blank-space insertion simple. They are less direct for exact coordinates; box-height changes move downstream events by construction, and frame/nested-call constraints still need a solver. They also risk recreating an automatic-only layout if exposed as the only UI freedom.
Recommend absolute desired anchors plus a deterministic, explicitly tested local conflict resolver, subject to falsification on source reorder/nesting fixtures before commitment. A conflicting source layout is a presentation diagnostic, not grounds to reject a semantically valid model or silently mutate its order. The renderer must distinguish stored geometry from resolved geometry. No broad layout run occurs on selection, property inspection, camera changes, label edits that still fit, or switching views. If the resolver cannot meet hard semantic anchors, it produces a clear bounded conflict result; it does not claim that an unsearched resize/move is impossible.
Connection bends are presentation-only. Process edges attach to their existing source/target occurrences; route handles move/add/remove pinned points and labels use existing fraction+offset behavior. Scenario message ends remain attached to the existing sender/receiver and event anchor; interior bendpoints/label offsets do not encode send/receive order. Self-message loops must be resizable/routable while preserving their occurrence identity. Reconnection is a different visible handle/action and uses semantic validation. Derived legacy process adjacency lacks a stable relation ID: either give its presentation a typed `{source_occurrence,target_occurrence}` key with lifecycle rules, or require an explicit link before authoring its route. Never create a hidden SequenceLink as a side effect of dragging an elbow. This is a concrete remaining route-coverage decision for legacy fixtures.
## Interaction and architecture boundaries
Extract pure process/scenario geometry projection into oa-core (or an existing UI-free shared crate if the core layering demands it). Inputs are project, explicit view identity/presentation, and bounded expansion state. Outputs have stable typed representation targets, actual hit bounds, attachment anchors, routed polylines, constraints and diagnostics. Fonts/text measurements need a deterministic shared interface or conservative documented metrics; do not put Iced types into persisted data. Keep initial layout and explicit Arrange as planners separate from projection. The same candidate projector must drive drag preview, committed render, navigation bounds, export and geometry tests.
Reuse architecture route math/label projection and peer resize planning rather than copying its algorithms into both behavior renderers. The existing [`routing::route_diagram`][routing] is coupled to projected diagrams, so first reuse primitives or adapt typed scene edges; do not pretend it already accepts sequence events. Process graph topology/rank logic remains valuable for initial/selected Arrange. Scenario lifetime/call semantics remain a separate input to geometry.
Interaction state is transient: `Gesture { document, diagram, owner, revision, epoch, target, original, candidate }`. Pointer-down resolves one exact rendered target, pointer moves only update a candidate, and release revalidates the complete scope before one normal transaction. Escape, focus loss, document/view switch, modal entry, source changes and stale revisions cancel without history. Zero movement retains exact authored data. Camera changes must either transform the captured gesture consistently or cancel it; they cannot replay a saved release against a new view. Peer resize hit arbitration must order visible resize/route handles ahead of overlapping invisible port slop.
Canvas is always present and pointer-active whenever its document is editable. Remove the user-facing Canvas activation button and mode-dependent hiding of editing essentials. F6 may remain ordinary focus traversal; text inputs still own text/navigation keys, and dialogs/drafts retain their existing guards. “Always active” must not make Delete/arrow keys operate behind a focused Properties text field. Keep the stamped control/input protection already introduced in the camera prerequisite.
Use one conventional selection and Properties workflow: click a box/arrow selects it, selected objects display familiar handles, double-click/name action edits its name, context menu offers relevant semantic actions, and the common Properties panel follows selection automatically. Replace the Details shelf with this panel; avoid a second selection editor or tiny reorder controls. Tools remain available in a compact palette. At the minimum supported window, the panel must be collapsible/resizable or use a stable shared inspector region; selection must not shift the canvas coordinate origin mid-gesture. The existing300px opaque overlay is evidence of current behavior, not proof that it is an acceptable final layout. Root needs native evaluation for hit size, palette contrast, long names and keyboard flow.
Saved-view identity must propagate to `Scope`, process/scenario State identity, camera cache, recovery target and diagram-usage navigation. Current process/scenario usages identify owner-based surfaces; multiple views require the saved Diagram ID as well. Qualified occurrences retain their full paths. Navigation selects/reveals the actual saved appearance without creating a view, resetting geometry or applying drafts. Camera can remain session-local; authored expansion/collapse affecting the saved view must have an explicit persistence policy rather than being conflated with camera focus.
## Migration, source edits and lifecycle
- Old version7 source/JSON loads without manufacturing views or geometry. New optional blocks default absent. Frozen old-version readers must reject new fields/owner constructors rather than silently accept and drop them. Update schema gates, serde/parser defaults, formatter, strict reST, API schemas/OpenAPI, source limits and transition/copy/reference walkers together.
- With no saved behavior view, show the current deterministic initial presentation and allow immediate gestures. The first accepted geometry edit creates the saved view and required initial presentation in the same Undo transaction. This is an internal lifecycle, not a new Canvas-enable prompt. View creation must allocate IDs once before preview/source preparation; no render-time random IDs. Merely opening a scenario remains clean.
- Decide whether initial capture is complete or sparse before implementation. Complete capture of the currently rendered direct surface gives stronger protection against unrelated future edits moving objects; sparse overrides create smaller source but leave untouched objects dependent on changing automatic ranks. Recommend complete direct-surface capture on the first layout edit, with unseen qualified expansions initialized lazily. Preserve omitted/invisible semantic objects as omissions; do not turn opening a view into a semantic model synthesis.
- Changing semantic names preserves positions/routes and grows/clips only according to an explicit content-size policy. Show long names through wrapping, handles and Properties; automatic size growth cannot silently overwrite stored dimensions. New objects get a local collision-aware initial position and do not trigger Arrange All.
- Deleting a view removes only presentation; deleting an occurrence removes its direct/qualified layout and route keys; deleting a caller invalidates paths through it; reidentification transforms every reference while preserving geometry/comments. Changing an owner or reparenting must reject or explicitly repair incompatible presentation in the same transaction. Coordinate these dependency walkers with peer Delete ownership before touching them.
- Source reorder and semantic relation edits must preserve all nonconflicting authored geometry. Layout diagnostics/derived conflict resolution must be deterministic and available outside the GUI. Text-only users can fully author the same representation and reset individual routes/placements without opening a window.
- Saving/reopening, REST import/export, copy/transition and undo/redo must preserve distinct repeated occurrences, qualified paths, pinned route points and source comments. A route whose edge is temporarily hidden remains stored, matching existing architecture semantics.
## Milestones and acceptance that can falsify this proposal
1. **Contract/core slice first.** Choose schema ownership and event-anchor policy; implement one owner-bound process view with ordinary nodes/routes and one two-lifeline scenario view with separately keyed call/reply anchors/routes. Prove parse/format/model equality, JSON/source migration, REST conditional transaction and one-Undo source parity before expanding gestures. Independent tests must use expected coordinates/semantic invariants, not merely call the same planner twice.
2. **Shared geometry/resize integration.** Extract scene projection and connect the #16 candidate planner. Exercise eight handles, active/inactive axes, port/state counterexamples where shared code applies, collapsed reuse and nested frame bounds. Demand projected preview=commit=reopen, cancellation=no change, child authored coordinates unchanged on resize. Failed bounded search is not proof of a minimum.
3. **Direct manipulation and Properties.** On the actual minimum window and realistic large model, enter a process/scenario and immediately drag the object itself, resize from each handle, edit a bend/label, select and change a property. No activation button, Details detour, unexplained rectangle or moving viewport origin. Test text focus, Tab/F6/Escape, touchpad/mouse camera, modal entry mid-drag and dirty-source refusal/recovery.
4. **Behavior-specific depth.** Process cycles/parallel links, repeated callee appearances and expanded nested callers; scenario same-exchange call/reply, self-message, long lifeline labels, create/delete, ALT/PAR/LOOP operands, ScenarioUse and nested activation #21. Verify routing/labels and bounds after every move. Finish all visible object kinds rather than calling the simple fixture feature-complete.
5. **Preservation/regression/package.** Source comments across included files, two views per owner, hidden routes, reidentify/delete, conditional REST stale revisions, save/reopen, undo/redo, source reorder conflict diagnostics, navigation to the exact saved appearance, and long-model responsiveness. Root must run native workflow review and fresh independent critique, then integrate/publish a versioned milestone with honest remaining issues.
Concrete user-workflow checks:
- In `scenario_oa_conversation.arcadia`, widen/spread caller/responder until the full call label is readable, move call/reply to separately chosen y positions, edit only the call route, save and reopen. Underlying exchange IDs, `reply_to`, sender/receiver, steps and lifetime semantics are byte-for-byte unchanged after cosmetic operations. The two appearances retain different geometry.
- Drag the call down across the reply's initial screen row. Default movement preserves semantic order and shows any spacing/ripple adjustment. Invoke Reorder explicitly and verify a valid/invalid preview according to call/reply semantics; there is no automatic `SetSteps` hidden in ordinary drag.
- In `process_oa_response.arcadia`, put the confirmation box below/left of its previous rank column, resize it, bend its explicit incoming edge around another object and move its label. Links/steps/represented work do not change. Reopening does not return the box to a rank column.
- Place two references to the assessment procedure, expand each, position/resize one visible inner occurrence and route an inner link where present. Only that caller path changes; opening the callee definition and the other caller is unaffected. Collapse/reexpand retains it.
- Resize a fragment around existing operands, then resize a reuse card: child authored coordinates and semantic membership stay unchanged. Use a separately named semantic action to change membership. New nested activation support must use the same geometry contract rather than regenerate all rows.
- Edit names/steps in source with comments and included files; undo restores both source and geometry. A source reorder that conflicts with authored y produces a deterministic, inspectable presentation result without rejecting a valid model, silently saving, or editing semantics from pixels.
## Remaining decisions and limits
The proposed absolute-anchor conflict resolver, local ripple behavior, legacy derived-path route identity, saved expansion policy, and exact Properties layout need early independent evaluators/native evidence. They are explicit design questions, not authorization to defer basic persistence or free manipulation. Capella's behavior is a comparison, not the required product specification.
Official primary references support the distinction: [Sirius sequence user documentation](https://eclipse.dev/sirius/doc/user/sequences/Sequence%20Diagrams.html) describes movable lifelines, stored header height, manual blank-space insertion and order-preserving layout. Its [sequence specifier documentation](https://eclipse.dev/sirius/doc/specifier/sequences/Sequence%20Diagrams.html) explicitly delegates event/instance reordering to semantic tools when graphical movement changes order. [General Sirius diagram documentation](https://eclipse.dev/sirius/doc/user/diagrams/Diagrams.html) supplies ordinary shape movement/resizing, route bendpoint and label interactions. These are useful interaction precedents; they do not prove native Capella's current configuration or justify copying its menu density. [Capella's official feature overview](https://mbse-capella.org/features.html) distinguishes functional, exchange and interface scenarios; the same presentation architecture should apply across the application's supported scenario viewpoints rather than fixing only one.
[model]: ../../../crates/oa-core/src/model.rs#L1431
[topology-state]: ../../../crates/oa-desktop/src/behavior/topology.rs#L79
[graph]: ../../../crates/oa-desktop/src/behavior/topology.rs#L1000
[process-input]: ../../../crates/oa-desktop/src/behavior/topology/direct.rs#L662
[process-handle]: ../../../crates/oa-desktop/src/behavior/topology/direct.rs#L562
[context-preview]: ../../../crates/oa-desktop/src/behavior/topology/contextual.rs#L253
[scene]: ../../../crates/oa-desktop/src/behavior.rs#L1228
[scene-occurrences]: ../../../crates/oa-desktop/src/behavior.rs#L1393
[presentation]: ../../../crates/oa-desktop/src/behavior/scenario/workspace.rs#L14
[scenario-handle]: ../../../crates/oa-desktop/src/behavior.rs#L1819
[scenario-reorder]: ../../../crates/oa-desktop/src/behavior/scenario.rs#L1071
[lifecycle]: ../../../crates/oa-desktop/src/behavior/scenario_lifecycle.rs#L70
[controls]: ../../../crates/oa-desktop/src/behavior/canvas_workspace.rs#L13
[host]: ../../../crates/oa-desktop/src/behavior/canvas_workspace.rs#L214
[language-diagrams]: ../../../docs/language.rst#L1056
[commands]: ../../../crates/oa-core/src/session.rs#L11
[document]: ../../../crates/oa-desktop/src/document.rs#L315
[server]: ../../../crates/oa-server/src/routes.rs#L1017
[routing]: ../../../crates/oa-core/src/routing.rs#L429
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
# Issue 21 — independent activation rendering analysis
2026-09-12, `/root/diagram_usage_workflows`, for root synthesis and peer Codex-956atf's implementation ownership. Read current issues/comments #20 and #21, including peer claim637 and root claim641. Root subsequently yielded implementation to peer956 and assigned this independent read-only evaluation. No production writes, compiler, model experiment, or native application interaction were performed. Active inspected worktree: `C:/Users/User/Documents/Git/ARCADIA-Studio/.local/diagram-usages-ytr83r-20260912`, base7aa007b plus root's diagram-usage working changes. Source line references identify the inspected files and may shift after integration.
## User requirement and scope
[Issue21](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/21) gives the exact stored order Call1 L1→L2, Call2 L1→L2, Reply2 L2→L1, Reply1 L2→L1 and reports invisible inner call blocks. Comment622 asks to examine Capella because the user likes its treatment. The attached image at root `.local/gitea-issue21-25269f9e.png` shows two calls arriving at the left lifeline and one visible pale strip with no separate nested activation apparent. This supports the reported visual symptom but does not reveal the complete model, both correlations, build version, or screenshot provenance beyond the issue attachment.
[Issue20](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/20) requires less rigid scenario diagrams: ordinary direct controls for spacing lifelines, moving arrows, resizing elements and avoiding clipped names, comparable in ease to architecture editing. The #21 correction should not hardwire a new geometry scheme that makes that later work more difficult. This analysis does not propose taking #20 implementation scope.
## Findings: verified source facts
### 1. Overlapping activations have identical horizontal geometry and UUID-dependent paint/hit precedence
`behavior.rs:1339–1363` gathers Calls by `scene.rows.keys()` from a BTreeMap keyed by occurrence ID, then invokes `activation_sequence` for each Call. This is UUID order, not call occurrence order or outer-before-inner order.
`activation_sequence` follows the particular Call's `reply_to` correlation and correctly can produce two different vertical spans for the reported simple case. However, every `activation_segment` (`:1657–1678`) receives exactly the receiver lane x and emits the same `x−4` origin and width8. Reply caps (`:1739–1751`) likewise use fixed `x−7`,width14. There is no nesting depth, horizontal interval assignment or activation-specific anchor.
For y1<y2<y3<y4, both Call1's span [y1,y4] and Call2's span [y2,y3] occupy [x−4,x+4]. `Scene::draw` (`:2169` onward) paints filled boxes in their stored order before messages. If the outer Call sorts later, its opaque fill/stroke covers the whole inner interval. If the inner sorts later, some short cross-lines can survive, but there is still no distinct offset nested block. This is sufficient source evidence for the reported symptom; it does not depend on a guessed GPU bug.
`Scene::hit` (`:1848–1858`) searches empty-title boxes in reverse order after message/header checks. Thus the same overlap makes a click select whichever Call's bar was appended last, regardless of intended nested identity. A paint-only color tweak would leave interaction ambiguity.
### 2. Messages are attached to lane center, not to a distinct activation boundary
Occurrence geometry (`:1505–1531`) derives call/reply polyline endpoints from lane x positions. Birth/death rendering later adjusts lifecycle messages, but ordinary call/reply endpoints remain at the lane center. Offsetting activation rectangles alone would leave the arrowhead or reply origin disconnected from the corresponding block, or passing through the wrong block.
Therefore the correction needs a shared call-activation geometry association for draw, message endpoints and hit testing, retaining the original occurrence/correlation IDs. The semantics do not require a new persistent activation model record merely to render that association.
### 3. Recursive/self-call activation starts at the send row, 24 units above its receive endpoint
The self-message polyline ends at `(x, y+24)` (`:1513–1520`); its occurrence row is recorded at y. `activation_sequence` starts its receiver activation at `self.rows[call].y` (`:1710`) rather than that receive anchor. Thus a self-Call bar currently begins before its drawn receive endpoint. For ordinary horizontal calls both anchors have the same y, which hides this defect.
For self-replies, termination should follow the replying activation's send anchor; the subsequent receive anchor belongs to the resumed caller. A correction that uses the same row as both events would perpetuate the recursive case and conflict with movable arrows in #20. No native reproduction was performed here; the 24-unit mismatch is directly derivable from the code.
### 4. Existing fragment and lifetime behavior is meaningful and must be preserved
`activation_sequence` splits an inherited activation across Fragment operands, identifies a Reply by its exact correlation, stops branch-local segments at matching Reply/Delete, and leaves a visible unresolved cue for open continuations. ALT resumes when a path can remain open; PAR, OPT and LOOP have distinct continuation rules (`:1755–1787`). These are not interchangeable flattened vertical intervals.
`scenario_lifecycle/render.rs:154–174` clips activation spans to the receiver's Alive intervals in the same scope. An uncreated/dead/unresolved lifetime must not gain a visually asserted active span through the correction. Create/Delete markers paint after ordinary bars/messages, with their original occurrence identity.
Existing tests (`behavior.rs:direct_alt_execution_stops_each_operand_at_its_reply_and_marks_open_operand` and `direct_execution_span_ends_at_its_correlated_reply_and_marks_an_open_call`) check span ends, operand splits and unresolved cues for one Call. They do not test two overlapping same-receiver activations, UUID permutation, endpoint attachment or distinguishable hit regions. They therefore do not disprove the reported defect.
## Semantic boundary: what nesting must and must not imply
`docs/language.rst:678–701` requires Reply to reference a preceding Call on a guaranteed common path, reverse its actual lifelines, and avoid duplicate replies that may follow on one shared execution path. It does not impose a LIFO stack between replies to different Calls. Rendering should not silently change that contract.
The issue's y1<y2<y3<y4 correlations form strictly nested intervals, so an offset inner block is well justified. A crossing case Call1,Call2,Reply1,Reply2 must still preserve both admitted correlations. Treat it as two overlapping active intervals with separate visible tracks, not as a proof that Call2 is semantically invoked by Call1 or a reason to rewrite which Reply completes which Call. Calls from two different senders can overlap on one receiver without their senders being part of one execution stack.
Likewise, different ALT operands are exclusive paths; screen stacking does not make their Calls nested. PAR operands are not a fabricated total execution order. Track assignment should be scoped by branch-path compatibility and inherited open activations, not by raw rectangle containment across the entire flattened canvas.
## Primary comparison evidence, with limits
The official [Sirius sequence-editor specification](https://help.eclipse.org/latest/topic/org.eclipse.sirius.doc/doc/specifier/sequences/Sequence%20Diagrams.html) describes executions with start and finish events, recursive execution containment, and mappings that connect those events to graphical elements. It also separates graphical ordering from semantic ordering and requires them to remain coherent. This supports an explicit event/activation geometry mapping and nested border-node treatment rather than painting multiple indistinguishable rectangles on a lifeline. It does not independently establish how the user's installed Capella version renders this particular model.
Official [Capella features](https://mbse-capella.org/features.html) distinguishes functional, exchange and interface scenarios by their lifeline/message meanings. The same geometric nested-activation correction should therefore be assessed against supported Studio scenario viewpoints rather than assuming every Call is a software operation.
The official [Sirius historical release notes](https://help.eclipse.org/latest/topic/org.eclipse.sirius.doc/doc/Release_Notes_Previous.html) describe direct execution resizing within operands with enclosing containers growing as needed, and sequence-diagram control of geometry to preserve semantic ordering. That is relevant to #20 compatibility: editable geometry can remain constrained by event/ownership semantics. It is not evidence of current native Capella affordances. Peer owner retains the requested comparable native exploration; this report does not duplicate it.
## Independently derived acceptance expectations
Fixture identity/correlation maps should be handwritten separately from the renderer's output. Use exact Call/Reply IDs, lane IDs, scope paths and stored order. Tests must check observable visible geometry and selection, not only count BoxItems or confirm no panic.
| Case | Independent expected behavior |
| --- | --- |
| Exact user case, L1 left of L2 | With order C1,C2,R2,R1 and correlations R2→C2,R1→C1, show outer receiver activation from C1 receive to R1 send; inner activation from C2 receive to R2 send. Inner block has a visible offset boundary, and each Call/Reply endpoint attaches to its own block. A point in each exposed strip selects the corresponding Call. |
| Mirrored user case | Exchange the physical left/right lane positions while retaining the same message/correlation identities. The two spans remain visibly distinct and correctly attached. An implementation must not assume sender is left of receiver. |
| UUID permutation | Reidentify or construct IDs so C1 sorts before C2, then so C1 sorts after C2, while preserving each model's equivalent order/correlations. Geometric layout and which block appears on top must be equivalent modulo identities. Neither paint nor hit precedence may switch arbitrarily with ID order. |
| Three nested Calls to same receiver | C1,C2,C3,R3,R2,R1 produces three visible, separately selectable intervals, with each inner receive/send attachment at its own depth. Ending C3 does not end C2/C1. |
| Nonoverlapping repeat | C1,R1,C2,R2 reuses the base track when no interval overlaps. Do not accumulate horizontal indentation permanently by chronological Call count. |
| Crossing overlap | C1,C2,R1,R2 retains each explicit correlation and shows both active intervals without hiding one. Do not change semantic order or fabricate LIFO rejection. If the core rejects a particular fixture for an independent channel/viewpoint reason, repair that fixture rather than interpreting the unrelated rejection as a stack rule. |
| Opposite-direction reentrancy | C1 L1→L2, C2 L2→L1, C3 L1→L2, then R3,R2,R1. On L2, C3 overlaps C1 and needs a distinguishable nested/overlap track; C2 belongs to L1. Per-lane identity and reply association remain exact. |
| Recursive self-call | C1 L→L, C2 L→L, R2 L→L, R1 L→L. Every activation begins at its Call's actual receive endpoint (currently y+24 for the elbow), not its send row; each terminates at its correlated Reply's send endpoint. Elbows clear all live activation tracks and their arrowheads land on the correct boundaries. |
| ALT with inherited outer Call | Outer C1 precedes ALT. Operand A contains C2,R2,R1; operand B contains its own C3,R3 and leaves C1 open. Distinct inner tracks coexist with branch-local C1 segments. No C1 segment joins across operand headers; no activation depth leaks from A into B. Only B/possible continuation remains unresolved. |
| PAR and optional/repeated fragments | Test independent Calls in separate PAR operands and an inherited outer Call under OPT/LOOP. Preserve current valid/invalid correlation rules and uncertainty cues. Different screen operand rows do not manufacture nesting or serialize concurrent paths. An optional/repeated Reply cannot assert guaranteed completion. |
| Delayed creation/deletion | Create L2, then C1,C2,R2,R1,Delete L2: no activation before birth/after death; both nested intervals remain visible while alive. Separate warning-admitted unresolved-lifetime case retains neutral gaps. If Delete occurs while a Call remains open and is admitted, it clips the visible activation at death and preserves unresolved-call indication, never a false Reply cap. |
| Unreplied inner/outer | C1,C2 with missing R2 and/or R1 retains separate identifiable incomplete indications where current semantics permit. Do not use a guessed end to merge or hide the two calls. |
| Viewpoint/layer and typography | Exercise at least ordinary OA exchange scenario and SA boundary/interface Call with actual operation identity. Same geometry invariant, no alias/name correlation guessing. Repeat with long and Unicode labels, 100%,125%,pan and minimum supported window; label backgrounds, markers and selection do not erase the exposed block boundary. |
| Passive and edited layout | Query/render/select/pan/zoom preserves complete Project, accepted source envelope, source buffers and undo/redo history. In the future #20 layout representation, move lane coordinates or message geometry while retaining correlation/order; the same event-based activation association follows the chosen anchors and survives save/reopen without adding semantic edges or silently reordering steps. |
Geometric oracle for the minimal issue: let receive/send anchors be (xC1,y1),(xC2,y2),(xR2,y3),(xR1,y4) with y1<y2<y3<y4. Verify C1 spans [y1,y4], C2 spans [y2,y3], the bars are not identical in x range, both expose a drawable and selectable boundary during overlap, and R2 remains associated with C2. No required absolute pixel width/offset is imposed here; the implementation must demonstrate legibility at the actual tested scale. A screenshot alone is insufficient to prove identity selection; a hit geometry assertion alone is insufficient to establish visible contrast.
## Bounded correction candidates and tradeoffs
| Candidate | Benefits | Falsification / limitation | Assessment |
| --- | --- | --- | --- |
| Sort existing boxes and recolor selected inner bar | Smallest local edit | Same x range remains; one bar occludes another, hit ambiguity persists, recursive anchor still wrong | Insufficient. Useful only as part of a geometric correction. |
| Add derived ActivationSegment metadata, then assign deterministic receiver-local visible tracks and shared message anchors | Reuses existing correlation/branch/lifetime traversal; can separate segment derivation from display geometry and keep source untouched; supports exposed hits and endpoints | Must carry scope/path and start/end event identity, handle crossing intervals and inherited branches, and prove opposite direction/self-call; naive global y nesting would be wrong | Leading bounded correction. Preserve current scope-aware clipping and add one authoritative geometry product consumed by paint/hit/routing. |
| Replace current activation traversal with a full execution-tree/stack semantic model | May support richer execution semantics later | More than user requested; a stack can reject permitted crossing Calls; new persistent execution identities complicate textual/API parity and #20 layout | Defer unless actual requirements establish new semantic executions. Rendering nested activations does not itself authorize a metamodel change. |
| Persistent manual activation rectangles | Can be visually adjusted | Duplicates derivable lifetime/correlation data, invites stale ends after Reply edits, and shifts the original defect to users | Reject as correction; #20 can persist presentation offsets/anchors without making manual rectangles semantic authority. |
Suggested bounded implementation shape: retain existing activation_sequence's branch/correlation traversal, but emit typed records `(call, receiver, scope/path, start/end event anchors, termination state)` before reducing to rectangles. Derive track assignment from comparable active intervals, with stable stored-event order as the primary ordering. Resolve lane positions and message send/receive anchors in a layout pass, then use the same rectangles/anchors for paint, hit targets and navigation bounds. Lifeline birth/death clipping remains explicit. This is an architectural candidate, not reviewed implementation or a mandatory API.
For #20 compatibility, treat `lane_x`, event rows and actual message anchor positions as inputs to geometry rather than deriving activations from hardcoded row offsets forever. Persistent layout fields (when specified by #20) remain presentation data and must not replace `reply_to` or sequence/branch ownership. Do not compute semantic nesting from whichever y coordinates the user dragged on screen.
## Verification status and handoff
The fixed-width overlap, UUID-driven precedence, lane-center attachment and self-call 24-unit start mismatch are verified source facts. The user's image is consistent with them. No runtime reproduction, prototype, correction, automated test pass, native Capella comparison or release acceptance is claimed. Peer956 owns implementation; root should consolidate this evidence with the peer's reproduction and compare its final geometry/hit changes against the independent matrix before integration. Existing single-call/ALT/lifecycle evidence can be reused for unchanged invariants, but same-lane nesting, recursive anchors and UUID independence need new checks.