Files
ARCADIA-Studio/harness/release-contextual-source-creation-plan-20260911.md
T

20 KiB
Raw Blame History

Contextual source creation — bounded implementation plan, 2026-09-11

Codex-9e8r6t /root/palette_finish. Root-assigned design only; Gitea #1 coordination read through #133, ownership recorded in #134. No production edits, Cargo, native input or new language contract. Codex-956atf retains the reference-chooser component; this plan concerns behavior draft orchestration and command planning, not that widget's search, popup, keyboard or scrolling implementation. Root must synthesize before implementation.

Concrete problem and current seams

An engineer creating behavior can name a contribution or lifeline before discovering that its semantic source is missing. The current guarded workflow requires canceling that draft to create the prerequisite elsewhere, then reconstructing the original intent.

Current path Code evidence User consequence
Scenario → Add lifeline behavior/scenario/workspace.rs:331 offers sources(p, d) through a named-source picker; scenario.rs:941 enumerates existing elements filtered by layer/viewpoint. scenario.rs:1274 requires a chosen compatible target and creates only a Lifeline pointing to it. Missing Activity/Function/participant cannot be authored from this form. A name already typed belongs to the lifeline, not automatically to a new model source.
Process/chain → Involve work behavior/topology.rs:326 enumerates existing same-layer work. :595 requires an existing target; topology/view.rs:444 renders that picker separately from the contribution name. A blank process over a model with no work has no useful work target. The test called legacy_edit_preserves_order_and_new_work_in_one_undo adds a contribution referencing an existing target; it does not establish semantic Activity/Function creation.
Scenario → Add action on a lifeline scenario.rs:941 offers existing work; action/lifeline association is additionally checked by core endpoint/performer validation (validation.rs:1290, :3045). Creating any arbitrary same-layer work is insufficient: a participant lifeline needs a compatible performer relationship, while a work lifeline already represents a particular work identity.
New State machine → owner behavior/creation.rs:619 explicitly instructs a user with no matching participant to refine search or cancel and create a participant in Architecture first. The named machine draft and first-view choice must be reconstructed after the detour. The new creation flow otherwise correctly distinguishes root-owned processes/scenarios from participant-owned machines.
Navigation while pending app.rs:1265 blocks leaving Behavior while a behavior form is pending; App::apply_behavior rejects conflicting raw source/property drafts. Sending the user to Architecture while retaining an ordinary active form is not currently supported. Relaxing the global guard would expose unrelated edits and weaken draft protection.
Existing recovery/commit Scenario and topology drafts serialize raw names, references, insertion/branch positions and browsing state. app/checkpoints.rs:173 restores behavior before selecting its pending layer/page. App::execute at app.rs:850 adopts through Document::execute and updates selection after success. These are usable boundaries for a nested draft and atomic operation. A new source must not be installed outside them merely to make a picker see it.

The installed Capella study provides one narrow positive pattern: in OAS, Activity at a point created a semantic Activity and its lifeline in place; Activities opened an existing-source transfer dialog. Saved XML proved distinct source/InstanceRole identities. Capella also added a capability involvement; Studio must not copy that implicit semantic addition. The exercised SFCD function-involvement picker still required an existing Function, so Capella is not evidence that every source detour is solved. See release-capella-creation-study-20260910.md for exact scope.

Root supplied additional native observations after this worker returned its input lease: at minimum size, successful creation opened a blank process canvas with Tools/Selection/Fit controls but no first-action prompt; the empty scenario still said to select a lifeline/occurrence and drag its handle, although none existed. This worker did not repeat that native action. topology/view.rs puts authoring tools in the Tools shelf, and scenario/workspace.rs:173 gives generic Select/reorder guidance without a zero-content branch, consistent with the reported problem.

Three materially distinct interaction options

Option Concrete interaction and commit boundary Tradeoff
A. Stage a source inside the current behavior draft — recommended Beside the compatible-source field, Create new activity/function/participant… opens a small typed subform in the same editor area. Use this new source validates/stages it and returns to the parent form. The parent's final Apply/Create commits the source and consuming behavior edit together. Preserves raw parent state, supports one Undo, and makes Cancel harmless. Requires explicit draft-only identities and a preview project so existing compatibility checks can see staged records.
B. Suspend the form and visit Architecture Preserve a return token and checkpoint, open Architecture, create the source there, then return and bind it. Reuses a richer editor, but early source creation creates a separate history entry and can leave an orphan when the parent is canceled. Rolling back automatically can remove independently edited work. Deferring every Architecture edit until the original form commits would require a much broader transaction workspace. This is a possible later advanced workflow, not the smallest coherent first slice.
C. Dedicated source-plus-usage tools Scenario New activity lifeline or process New function contribution opens one combined form and commits both identities immediately on its single Create. Existing-source tools remain separate. Very direct for an empty canvas, comparable to the observed Capella Activity tool. It multiplies tools and does not solve a source discovered missing inside an already partially completed form or a new machine's owner without separate implementations. It can later be a shortcut over A's planner, not a competing command path.

Recommend A, with the empty-canvas entry points below. It solves the existing-form problem and can support C-like first actions using the same draft and transaction. Do not add a general element catalog, replace the external chooser, auto-create a source from a failed search string, or commit a prerequisite merely when the child form is accepted.

Proposed first flow and semantic scope

  1. Keep Use existing as the current reference path. Add one adjacent, explicitly named Create new… action where a supported source kind is meaningful. It must remain available even when a search has matches: no matches is not permission to create, and duplicate display names are legal.
  2. Open a source subform replacing the parent's editable field area. Retain a compact context line such as New activity for lifeline in Assess distress · OA · Operational activities or New function for contribution before Verify pressure · SA. Show only admissible kinds, a separate Source name, and the proposed semantic parent. Keep the original lifeline/contribution name separately; do not overwrite it with the source name. Omitted original names can continue to use the source as the existing default.
  3. Use Use this new source to return to the original form with a visible New · <kind/name> selected reference. This is still a draft. Preserve original name, viewpoint, branch/slot, guards, values, query, scroll/focus and other selections. Back or first Escape from the source subform cancels only that subform, leaving the parent draft unchanged; no model/history change occurs.
  4. The final parent action commits the new source and consumer in one validated Command::Batch. Preview exactly what is created: 1 Activity + 1 Lifeline, 1 Function + 1 contribution, or 1 Actor + 1 State machine (+ first view if selected). On failure retain both forms and all raw values. After success open/select the consumer, not the prerequisite source. One model Undo restores the complete pre-operation model and accepted source bundle.

Admissible initial cases:

Consumer/reference New source and explicit semantics
OA OperationalActivity scenario lifeline New Activity at OA work root, or an explicitly selected valid Activity parent. Create a distinct Lifeline under this scenario with represented equal to the new Activity. No allocation, capability involvement or architecture placement inferred.
SA Functional scenario lifeline New Function with explicit work ownership and distinct Lifeline under this scenario. Missing performer can remain an ordinary completeness warning, matching staged authoring policy.
OA ParticipantInteraction scenario lifeline Explicit Entity/Actor/Role choice admitted by the actual viewpoint validator; source semantic ownership shown independently from the scenario. No participant subtype guessed from its name.
SA BoundaryInterface scenario lifeline Explicit System or external Actor choice where admitted. Existing System-of-Interest uniqueness must be respected; do not create a second System or silently substitute an Actor. Creating a participant does not create ports, interfaces or a boundary exchange.
OA process / SA chain Work target New Activity/Function plus an Action contribution at the preserved insertion. Reuse existing topology planning for explicit links/legacy conversion. Do not parent the work to the process, infer control flow from layout, or alter reusable definitions referenced elsewhere.
State-machine owner in New Behavior Explicit valid same-layer participant kind/name/parent; then the pending machine owns that exact source reference. Optional first view remains part of the same parent transaction. This must work before any participant exists in the layer.

Action-on-lifeline needs a deliberately restricted extension, not generic source insertion. For a participant lifeline, offer an explicitly labeled Create activity/function allocated to this participant… only when the core admits that direct allocation. The preview includes the allocation and new Action occurrence. For a lifeline already representing work, prefer Use this represented activity/function; a different newly created work cannot silently replace its represented identity. An unresolved lifeline or ambiguous role/performer requires explicit resolution while retaining the Action draft. Do not invent a participant, allocation or lifeline to make validation pass. Implement these qualified Action cases after the three basic consumer adapters above, using the same staging primitive.

New exchanges, operation/interface contracts, scenarios for reuse, machine states, nested library instantiation and arbitrary multi-level source dependencies are outside this first slice. Their source kinds have additional contracts and should not be silently exposed through a generic Create button. Existing references continue through the current/external chooser.

First action on an empty canvas

When no form is pending and the current semantic sequence genuinely has no content, show one small in-canvas prompt with Add first activity contribution (OA process), Add first function contribution (SA chain), or Add first lifeline (scenario). This opens the corresponding existing parent form at the explicit root append slot; the source field offers existing or staged new source as above. Show the scenario's chosen viewpoint in that prompt so “lifeline” has a concrete meaning. Avoid introducing a second global toolbar.

For a scenario that already has lifelines but no occurrences, the first prompt should change to an applicable Add first message/action route. It must not say “select an occurrence” when none exists. Do not infer a compatible exchange or lifecycle event from lifeline names. Keep the existing tools available for alternate starts such as a fragment or reused scenario. Hide the first-action prompt once content or a draft exists; if content is merely offscreen/filtered, offer navigation rather than claiming the model is empty. For process graphs count semantic contributions, not rendered or collapsed nodes.

This is contextual guidance, not an automatic wizard: it must not change model/history just by appearing, steal keyboard focus on passive resize, or reset the user's Tools/Selection shelf on every frame. At 1100×700 client size, the prompt and the source subform's Back/Use actions must fit while the canvas and parent context remain understandable.

Draft, atomicity and recovery contract for implementation review

Use a typed source request owned by the parent draft, containing document identity, layer, parent draft/invocation identity, exact reference field, source kind/semantic parent, and the original consumer context. For a contribution include the exact process/scenario owner, operand/branch and insertion address; for a machine retain pending machine/view IDs. Bind by ID and explicit field, never by display name, current selection, first eligible object or nearest visible lane.

Reserve the new source and any dependent allocation/consumer IDs once and serialize them with the raw source subform. Repeated preview, retry, recovery and final submission must not create fresh identities each time. Build a private preview Project from the staged prerequisite commands, run existing candidate predicates and parent planning against it, then validate the full combined batch through the existing Document/source boundary. Do not insert staged objects into the accepted catalog, source buffers or generic chooser inventory. The exact prepared batch determines the post-success selected consumer; unrelated/trailing commands must not borrow that selection result.

A source subform is the only nested editing level in this first slice. The main application continues to reject unrelated navigation/mutations while it is pending. Route its events through the existing Behavior ownership guard; do not globally waive has_pending. The separate reference-chooser component needs at most a host-owned adjacent create action/typed result adapter; do not add model mutation or source creation policy to that component.

On stale document, owner/slot, source-parent eligibility or perspective, refuse final adoption and retain both raw drafts with a precise repair action. Passive viewport events are not model edits and must not invalidate a useful draft. If a model revision changes, revalidate explicitly against it; never silently rebind to same-ID-but-changed-kind/ownership data. For a changed insertion position, require choosing the position again or an explicit append action, preserving entered text. A nested reference's active callee and caller return path must remain distinct.

Cancel source subform: no mutation, restore parent exactly. Cancel parent: discard all its staged sources and dependencies, no mutation. Switching back to an existing source must not accidentally commit the abandoned staged source; keep it as inactive raw draft for toggling/recovery or explicitly discard it, but final reachability of draft dependencies determines the batch. A name collision must never trigger “reuse existing” implicitly.

Checkpoint capture includes both raw forms, staging mode, typed target, fixed IDs and original context. Recovery first restores accepted model/source and then the entire pending behavior state; select the captured layer/consumer and focus the innermost source name when that form is open. Restore lint tasks together with focus. Do not perform automatic creation on recovery. Missing dependencies remain visible and repairable. Existing raw property/source drafts must remain retained and continue to block adoption where they conflict.

Ordinary modal priority remains above this nested draft: first Escape dismisses an active file/hosted/workflow dialog, next Escape backs out of the source subform, next cancels the parent. A focused text input's captured Escape must follow that same route. Undo of an accepted combined command restores exact accepted source/history; restart retains the saved result but does not invent persisted Undo history. Preserve existing source-save behavior for safely retained detached files after Undo, as clarified by the independent oracle in Gitea #132.

Falsifiable acceptance scenarios

  1. Blank OA activity scenario: explicit OperationalActivity viewpoint, no Activities. Add first lifeline → Create new Activity, source name Assess distress, independently typed lifeline label Assessment role. Before final Apply, accepted element/source counts are unchanged. Apply creates exactly one Activity and one Lifeline, correct separate names/ownership/represented UUID; no allocation/capability/view. One Undo restores exact original model and reachable source.
  2. New function inside an existing chain path: click an insertion between two contributions, type an occurrence name, stage a new Function, return, then Apply. Exactly the selected insertion/link repair occurs; original guards, sibling paths and referenced reusable definitions survive. Failed validation or source-write budget preserves both names and the insertion. Undo/Redo preserves UUIDs and exact source provenance.
  3. Machine before owner: in a layer with no participant, name a machine and opt into first view, stage an explicit valid owner, then return. Cancel parent creates nothing, including no view/placement. A second attempt committed successfully creates owner+machine+requested presentation in one history entry and opens the machine. Repeat in SA with an already existing System; illegal second-System creation refuses without fallback.
  4. Qualified action: on a participant lifeline, explicit create-and-allocate yields exactly new work + direct allocation + action occurrence. On a work lifeline, no different work is silently attached. Wrong layer, invalid owner, unresolved lifeline and ambiguous role cases retain drafts and produce explicit errors.
  5. Recovery and stale responses: recover while typing the child source name, with a long Unicode parent name and fixed branch slot. Exact raw text, IDs, layer and intended reference survive; no object appears merely on recovery. Late selection/Use events from a canceled or different invocation cannot mutate the new draft. Remove/change the parent or slot between preview and submit: reject and retain intent.
  6. Existing/new switch and cancellation: start from an existing reference, stage a same-named new source, cancel child; original reference and raw parent text remain exact. Stage again, then choose existing and commit; no unused source is created. Test focused first Escape and overlay-priority Escape at actual minimum size.
  7. Empty-state onboarding: create/open genuinely empty OA process, SA chain and both scenario viewpoint families at 1100×700. An engineer can start the first useful contribution/lifeline without opening a hidden shelf or leaving Behavior. Existing offscreen/filtered content does not trigger a false empty-state prompt. Showing/hiding/resizing the prompt does not mutate source/history or steal input focus.
  8. Preservation and chooser boundary: use same-named sources under different owners plus a large candidate list. Only the explicit typed source request affects the parent; existing chooser search/navigation remains unchanged. Verify full Project and accepted SourceBundle equality after Cancel/failed Apply, plus the documented exact reachable/detached file policy after Undo. Do not equate a successful model count with exact-source preservation.

Implementation should start with the staged-source primitive and the Lifeline, process Work, and machine-owner adapters, together with semantic empty-state first actions. Add qualified Action creation only when its explicit allocation/representation gates pass. This is a proposed bounded sequence, not an approved production change or a completed usability result.