94 lines
16 KiB
Markdown
94 lines
16 KiB
Markdown
# 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.
|