Files
ARCADIA-Studio/harness/scenario-layout-design.md
T

16 KiB

Persisted scenario editing: implementation direction

Status: selected storage direction after independent source comparison and critique; implementation and acceptance remain open. This note does not adopt a new model/source version or public field spelling. Shared schema, source and reference changes are coordinated in issue 7 comment 756.

The user requires ordinary direct scenario editing, including spreading lifelines, moving arrows and resizing diagram content, with graphical/text/API parity. Issue 20 is the live outcome record; PROJECT_GOAL.md retains the full application requirement. Lane and whole-message spacing are the first persisted increment, not completion of that outcome. Process topology, frame/box resizing and route editing remain required work with their own geometry contracts.

Evidence and choice

Use the existing Diagram identity namespace, adding an owner-bound Scenario projection and a typed scenario-layout payload. Preserve current architecture serialization initially. Do not convert every existing diagram to a new generic representation merely to add this capability.

An owner-keyed presentation map is smaller only if there is exactly one arrangement per semantic scenario. That product restriction is not established. Adding view IDs, aliases, naming, duplication, source declarations, deletion and history to that alternative would recreate a second Diagram subsystem. Existing Diagram IDs and the owner-bound StateMachine projection supply useful precedents, while checked Diagram commands and source transactions already exist.

This choice does not make integration automatic. Current behavior navigation, camera scopes and gesture contexts identify semantic owners. Saved views need representation identity throughout those paths. Current non-state saved-diagram dispatch can also fall through to architecture rendering. These are required parts of the first increment, not optional cleanup.

The first projection is Scenario only. Process and FunctionalChain currently use topology rendering, while the row-anchor experiment concerns Scene::sequence. An unused Process projection with a sequence payload would claim a capability it does not supply. Later process-layout persistence may extend the same Diagram namespace with its appropriate typed payload.

Reviewed source bases:

  • 208268c8: prepared navigation/rename union, not yet compiled or accepted together.
  • 4b782a71 experiment: complete-anchor bridge, with explicit frame/lifecycle/scope falsifiers. Windows compilation check passed; runtime result was pending when this note was prepared. Use its subsequent evidence record for current results.
  • aadc6396 renderer: peer typed activation/lifecycle integration. Reported 51 targeted checks do not establish full/native acceptance or this layout integration.
  • 847b1caa analysis candidate: prospective schema 8, analysis definitions and fallible remapping. Its version and persistence boundary must be reconciled, not overwritten.

Identity and logical data contract

The following names describe meaning; source/JSON spellings remain subject to the shared schema design.

Identity/value Meaning and invariant
Diagram ID One saved representation. Two diagrams of one scenario may carry different layouts. It is distinct from the scenario owner ID.
Scenario owner ID The semantic Scenario rendered by that representation; its layer must match the Diagram.
Lane identity The Scenario's Lifeline ID, not its represented performer ID. Two lifelines representing the same performer remain independently addressable.
Message appearance Its occurrence identity plus any reference-occurrence path. Never key by the represented Exchange definition. OccurrenceEndpoint is the existing path concept.
Lane x override Authored horizontal center in diagram coordinates. Absence retains automatic placement.
Whole-message send-y override Authored send endpoint height. The receive endpoint and current self-message offset remain derived for a whole-arrow move. A renderer row that denotes receive height must be converted explicitly; row storage conventions must not leak into the public meaning.

Use typed records with explicit reference-valued fields and reject duplicate addresses. Arbitrary UUID-valued JSON object keys bypass existing source alias/reference handling and are not a suitable shortcut. Direct appearances use an empty reference path. This first increment must not claim expanded-reference editing before its resolver and renderer are implemented and tested; unsupported addresses need explicit admission behavior, not accidental fallback to a definition-level placement.

Coordinate admission reuses the project's finite coordinate bounds. Negative coordinates, large gaps and the resulting viewport extents require actual projection tests; a positive-only fixture does not establish them. Stored values represent authored intent, not a copy of every generated endpoint, label, activation or box bound.

A Scenario projection accepts only its compatible typed layout. Architecture projections reject that payload. Scenario views reject incompatible architecture node/route payloads. Every projection dispatch, selector and usage query must classify the projection explicitly; state_machine().is_none() is not an architecture classifier.

Structural validity is separate from the unsettled vertical movement policy. This note does not authorize semantic chronology contradictions, automatic reparenting, unexplained clamping or a new blanket spacing rule.

Projection and editing lifecycle

  1. Opening an old Scenario retains its derived unsaved view. It creates neither a Diagram nor a history entry and does not dirty source.
  2. An explicit create/save-view action, or the first real geometry edit, may create a saved Diagram. Creation plus its initial authored override is one checked transaction. Undo restores the prior absence exactly.
  3. Resolve absent positions automatically without persisting them. Preserve sparse authored values through folding, hiding, preview and passive layout. A zero-motion drag, including signed zero, must not materialize positions or erase latent values merely because a constraint displaced their displayed geometry.
  4. Preview state lives outside the Document. Capture accepted source/document identity, an explicit derived-versus-saved representation identity, semantic owner and the current view-visit/input context when a gesture starts. A derived view has no saved Diagram ID; allocate that ID only inside an accepted creation/edit transaction. Switching between two views of the same Scenario, or leaving and returning to one without an intermediate frame, must invalidate old gesture/navigation envelopes. Cancellation and zero motion retain the derived view without creating a Diagram.
  5. Commit one validated transaction on accepted release. Escape, stale context, invalid input and no-op release preserve model, exact source bytes, revision and redo history. Reuse the Document's checked source writeback boundary; do not maintain a parallel layout history.
  6. Source export/import, JSON/REST transactions, native Save/reopen and model Undo/Redo must represent the same layout. Existing transaction no-op/ETag behavior remains applicable. Preview geometry alone is not persistence parity.

The first prototype must exercise two separately arranged diagrams of the same Scenario. This exposes representation/owner confusion early, before substantial UI work depends on it.

References, transformations and limits

Visit the Scenario owner, lifeline IDs, occurrence IDs and every reference-path component in validation, rename/reidentification, deletion and checked remapping. Integrate with the peer's fallible remapping/preflight contract instead of adding an infallible competing walker.

Duplicating a saved view creates a new Diagram identity and copies authored layout values while retaining its semantic owner, lifeline, occurrence and reference-path identities. Duplicating a representation does not reidentify or duplicate its semantic objects. A separate semantic-model copy operation may remap those references according to its explicit copy map; these operations must not share an ambiguous blanket reidentification rule.

Deleting an owner removes its saved Scenario views. Removing an appearance prunes its authored layout according to an explicit, tested rule while preserving unrelated semantic elements and other views. Retargeting a view or reparenting an appearance must reject or explicitly clear incompatible layout; it must not silently apply coordinates to another appearance. Hiding or folding is not deletion and retains authored data.

Nested source records need stable identities and reference handling so a coordinate edit does not rewrite unrelated comments or records. Enforce duplicate-address and collection bounds before unbounded work. Determine these limits through the same checked persistence boundary as other model data; do not invent a second codec admission policy.

Movement policy still to evaluate

Current ordinary scenario dragging already performs semantic reorder through a validated SetSteps command within the same parent sequence. The semantic model orders whole occurrences, not independently ordered send and receive events. Parallel and alternative operands also cannot be treated as one flattened chronology.

Compare these two user gestures before selecting the release behavior:

  • Spacing drag preserves semantic order and shows its feasible boundary; an explicit Reorder action changes steps.
  • Continuous drag adds spacing and previews a semantic reorder when crossing an event, extending the existing gesture. Release commits the layout and validated reorder atomically when applicable.

Evaluate ordinary spacing, intentional and accidental crossings, Call/Reply and Create/Delete validity, same-owner view switches, discoverability, cancellation and one-step Undo. Both candidates must preserve operand membership unless the user invokes an explicit structural move. A persistence-home choice does not settle this gesture choice.

The next bounded workflow prototype will evaluate spacing through the arrow or label, with explicitly named Reorder available at the selection. This is a candidate for runtime evaluation, not release acceptance. Spacing has a view-local purpose; reordering changes the shared Scenario and therefore affects its other representations. Inferring that shared semantic instruction merely from pointer travel is the principal reason to try separate actions first. Continuous spacing/reorder retains today's motor behavior and remains the alternative if the explicit action proves difficult to discover or use.

This deliberately changes the current body-drag behavior: both an occurrence hit and the selected handle currently capture Reorder, with a three-screen-pixel movement threshold. Retaining only the existing handle is insufficient. Its world rectangle at x6..28 becomes 1.1 screen pixels wide at 0.05 zoom and can pan offscreen while the selected message remains visible. The named action must remain reachable at the current selection and camera position.

The prototype must distinguish arrow/label, activation shoulder, lifecycle marker and reorder-handle hit roles; a shared occurrence UUID does not imply a shared drag action. It must preserve exact authored values, source, revision and redo on cancellation, stale view-visit context or return to the starting position. Geometry diagnostics are inputs to explicit preview feedback, not permission to rewrite steps, clamp stored values or manufacture missing arrows. The complete resolver's acceptance of source-admitted crossings does not itself select the gesture's crossing policy.

Acceptance needs one independent native workflow: make two close messages easier to read, then deliberately swap them without being taught the handle. Include negative/far-right selections, Fit zoom, self Call/Reply and Delete, activation-shoulder input, and two saved views of one owner. Compare complete steps, both layouts, source and one-step Undo. Failure to discover Reorder or understand a refused spacing preview requires revising the interaction before adoption. No full implementation of both candidates is required merely to compare their risks; this first experiment does not replace the broader direct-editing acceptance matrix below.

Labels are part of the spacing outcome

Both reviewed renderers shorten each complete message label to 32 graphemes independently of lane spacing. Their 225-unit backplate estimate is not a matching text clip. Existing release1 call/reply names already expose this truncation. The navigation membership helper independently assumes the same shortened label; changing paint alone would make its visibility claims wrong.

The next bounded label candidate measures the same single-line text the canvas paints, resolving one displayed text/prefix/bounds result for paint, backplate, hit testing and visible-field navigation. Wider usable space must reveal a full known label when it fits. Measurement must account for the actual canvas zoom, font, shaping and font-system revision. Layout advances are not proof of pixel-ink bounds for overhanging glyphs.

Resolve the corridor after lifecycle/activation endpoint alignment. Reversed and self messages need explicit corridor choices; a zero sender/receiver gap is not a valid self-message policy. The label helper should accept a corridor rather than hide those choices. Wrapping is a separate row-height/collision decision. Preserve the peer's backplate → activation → arrow/text paint order and precise shoulder-hit behavior.

Required evidence before adoption

Check Observable success
Legacy open / zero motion No new Diagram, coordinate entries, source changes, revision or history changes.
Two views of one Scenario Independent layouts and camera/input contexts survive switching, export, REST, reopen and Undo. Delayed input from the first cannot edit the second.
Repeated Exchange / performer Moving one appearance changes only its intended authored layout records; other appearance records and semantic identities remain intact. Dependent rendered geometry follows the separately selected movement policy.
Whole-message motion Exact send/receive geometry, marker and activation alignment, with source semantics preserved for spacing and changed only by an explicit accepted reorder transaction.
Lifetime and self-call Delete clipping and unanswered-call cues stay truthful; self-call execution begins at the actual receive endpoint, not its send row.
References / copy / deletion All qualified identities transform consistently; unrelated layouts, comments and semantics remain intact.
Label readability Full known names and distinguishing suffixes appear at sufficient width; actual font/render checks cover CJK, combining text, reversed/self calls, hits and nested bar continuity.
Projection extents Negative coordinates, wide gaps and label extents remain reachable without changing authored values to fit the viewport.
Persistence transaction One real drag yields one source/model history entry; invalid/stale/no-op paths leave source, disk and ETag unchanged as appropriate.
Real workflow A matching Windows build supports direct selection, drag, cancel, next keyboard edit, navigation, Save and reopen on small and representative large models.

The old floor and complete-plan probes are evidence about integration seams, not an adoptable free-editing architecture. In a later typed-activation union, update their bar/cue representations and compare the full activation vector; preserve nonempty/count and complete source/history assertions. Independent source review alone does not satisfy any runtime row in this table.