9.7 KiB
Saved view duplication and dense exchange evaluation
2026-09-06. Design against current integrated source. Root subsequently authorized the bounded pure builder implementation noted below. No native operation or performance/readability pass is claimed here.
Duplicate a saved presentation
Use one existing Command::CreateDiagram(Diagram) transaction. It already accepts
embedded placements and runs ordinary global identity, alias, diagram and reference
validation (oa-core/src/session.rs). A new command variant or schema is unnecessary.
The pure builder takes an accepted Project plus source Diagram identity and returns a fresh Diagram. Copy name with a readable “copy” suffix, description, layer, projection (including the same StateMachine identity), ViewOptions and routes. Allocate a fresh diagram identity/alias and a fresh identity/alias for every NodePlacement. Preserve each placement's semantic element, position, size, collapsed flag and port anchors. Route edge identities, waypoints, label fractions and offsets remain unchanged; they reference semantic edges, not old placements. Visual parents are derived by projection, so no parent-placement remapping is needed.
Reserve newly allocated identities and aliases in local sets alongside the accepted
Project's identities. Calling fresh_alias repeatedly against an unchanged Project
does not reserve aliases generated for other new records. Do not run global
reidentify, which changes accepted semantic references. Do not clone existing
artifact links owned by the old diagram or its placements: those links make claims
about those particular artifacts; duplication of presentation does not establish
new claims. Semantic links remain available through the shared semantic elements.
Implementation now prepared in the new oa-desktop/src/view_copy.rs:
command(&Project, source: Id) -> Result<Command, String>. It clones only the
Diagram, reserves fresh identities and readable aliases locally, and returns the
existing CreateDiagram transaction. Three focused tests cover manual typed port
anchors/routes/filters/artifact ownership with exact source/Undo/Redo oracles,
repeated nested collapsed state-view duplication and global alias uniqueness, and
missing-source rejection. Formatted and handed to root for module/action wiring;
compilation and execution are pending, not claimed by this report.
Update after .local/source6-desktop-tests.log: all three pure duplication tests
and both selective property tests passed. Root wired DuplicateDiagram actions in
architecture and state context menus to their actual diagram identities. Independent
app review found that checking a missing source only after apply() could commit
an unrelated pending property edit; root added a preflight before Apply. Five new
app/view_copy_tests.rs regressions now cover actual state/architecture view routing,
one source Undo/Redo, stale request preserving a valid raw draft, invalid properties,
pending behavior and incomplete source. They await root's next test run. The same
review found no omitted invalidation among accepted Document replacements, Undo,
Redo and Save As source relocation; cache and SVG tests passed in the above log.
The new oa-core/examples/release_dense_views.rs generates canonical source/JSON
and an oracle report in a supplied directory. It has fixed identities, eleven
visibility cases, actual same-pair projection assertions, immutable placement/model
checks and source/JSON reopening assertions. Routing timing, overlapping label pairs
and identical path pairs are observations rather than a usability pass. Root owns
execution and native inspection; no generated output is claimed before that run.
Desktop seam: add an action next to the saved-view chooser and reuse App::apply
before the builder/transaction. This preserves existing rejection behavior for
source/behavior drafts and invalid property values. A pending valid property Apply
can be a preceding ordinary edit, as with existing AddDiagram; do not promise
that these two separate actions undo together. After success, select the duplicate,
clear obsolete placement/bend selections and use the existing diagram activation
path, including routing StateMachine views to Behavior. On Behavior use the actual
behavior.diagram.diagram, not a potentially stale architecture active_diagram.
No duplicate action should invent a default view when its source no longer exists.
| Acceptance case | Exact oracle |
|---|---|
| Ordinary nested allocation view | Same projected semantic nodes, nesting, ports and geometry after replacing only placement identities; original diagram unchanged. |
| StateMachine view | Same machine, regions, collapse, typed action/internal rows and transition routes; active workspace uses existing state tools. |
| Traceability view | OA and SA placements and reference choices preserved, including explicit cross-layer hides. |
| Saved filters and routes | All vs empty Only/Any preserved byte-for-byte in typed values; hidden or currently folded route retained. |
| Name/alias collision | Duplicate twice with deliberately occupied copy aliases; each new record globally unique and source parse succeeds. |
| Transaction/Undo | Exactly one additional Diagram with remapped placement identities; elements, relations, traces and ArtifactLinks equal original. One Undo removes copy; Redo restores the same new identities. |
| Source bundle/REST | Existing generic command endpoint and source serialization can express the identical CreateDiagram; save/reopen actual included bundle equals accepted Project. Do not assume the original view's source file is reused. |
| Invalid/pending drafts | Clone rejected or handled by existing explicit Apply semantics; raw source, property, behavior and workflow drafts retained. No hidden discard or partial diagram. |
| Missing source/identity collision | Builder/command returns an error and preserves model, source and undo/redo stacks. |
Dense forty-exchange fixture
Build a deterministic source-6 fixture from production records: two OA Activities
(Request service, Provide service), two Entities allocated to them, forty
Interactions Service data 01 through Service data 40 with the same ordered
activity endpoints, and four ExchangeItems (one per ten exchanges). Use fixed
UUIDs in a reserved fixture prefix and explicit aliases, with no user data.
Four Work categories contain exchanges 01–10, 11–20, 21–30 and 31–40 respectively. A fifth overlapping category contains 01, 11, 21 and 31. Three Processes explicitly list exchange occurrences for the first three groups; 31–40 are deliberately outside behavior. One FunctionalDataflow view has exactly two placed Activity nodes at (80, 160) and (760, 160), ordinary node sizes and no authored routes or label offsets. The initial representation therefore has exactly forty graphical edges between the same pair. Do not make the test pass by spreading the semantic endpoints into fake nodes or pre-authoring forty hand-tuned routes.
The fixture can additionally contain an allocation view of the same model and a duplicate of the dataflow view for the above duplication tests, without changing the forty-edge baseline. Participant means/categories should be exercised in their own view so the dense work-exchange oracle remains unambiguous.
| Settings / operation | Deterministic semantic or projection oracle |
|---|---|
| Defaults | 40 actual exchange IDs; no semantic reduction, route metadata invented or model edit. |
| First category only | Exactly 01–10; no node, port, placement, collapse or route mutation. |
| First + overlapping categories | Exactly 01–10 plus 11, 21 and 31 = 13 IDs. |
| In behavior / outside behavior | Exactly 01–30 / 31–40. |
| Second process context | Exactly 11–20. Outside behavior + second process = 0. |
| Empty category/context or Only([]) | 0 work lines; source distinguishes this from All. |
| Hide 05, then change label/category | Hide remains; first category displays 9. Clearing hide displays 10. |
| Name / Items / Names and items | Exact declared text with group payload reuse; visibility and model facts unchanged. |
| Save, restart, duplicate | Typed saved options and untouched geometry match; duplicate identities differ only for diagram/placements. |
Native evaluator (root sole operator): at a normal 1280×800 window, open the
unmodified dense view, Fit, and inspect at fit zoom and 100%. Record elapsed time
and screenshot; select named exchanges 01, 10, 20 and 40, verify Properties shows
their exact identity, then filter to the first concern and restore All. Repeat
at the supported minimum window size. Capture whether names are legible, labels
overlap nodes/each other, fit makes all labels microscopic, or coincident route
hits select only the same first edge. Current diagram::hit_edge breaks equal
distance by selected identity then UUID, so coincident routes cannot be assumed
individually discoverable. Existing automatic routing avoids previous segments and
settles labels afterward, but that is not evidence forty routes remain usable.
Pass requires no lockup, no unreadable overlap among the displayed labels at the task's working zoom, and a discoverable way to inspect any of the forty actual exchanges without manually rerouting them. Use timing as measured evidence; a new arbitrary timing cutoff must not replace observation on the two-CPU test machine. If baseline display fails, representation-only grouping/summary becomes required: one visible aggregate must explicitly state its count, expose all member identities and allow member inspection/unbundle without creating a new relation or rewriting categories. Filtering to ten exchanges alone does not prove the unfiltered dense case is solved. Agree the exact summary display contract before adding source fields.