Render explicit scenario lifetimes and preserve marker selection

This commit is contained in:
2026-09-11 05:25:04 -07:00
parent b853a1eca3
commit 52f6e176cd
15 changed files with 2231 additions and 97 deletions
+87 -21
View File
@@ -752,7 +752,7 @@ lists all additional fields. <span class="docutils literal">ref</span> means <sp
</tr>
<tr><td><p><span class="docutils literal">oa_scenario</span>, <span class="docutils literal">sa_scenario</span></p></td>
<td><p><span class="docutils literal">viewpoint</span>: ScenarioViewpoint; <span class="docutils literal">context</span>: ref?; <span class="docutils literal">precondition</span>, <span class="docutils literal">postcondition</span>: strings; <span class="docutils literal">steps</span>: occurrence refs</p></td>
<td><p>MixedLegacy for omitted schema-2 source; none; <span class="docutils literal">&quot;&quot;</span>; <span class="docutils literal">&quot;&quot;</span>; <span class="docutils literal">[]</span></p></td>
<td><p>MixedLegacy when viewpoint is omitted, including newly authored source 7 (see section 4.3); none; <span class="docutils literal">&quot;&quot;</span>; <span class="docutils literal">&quot;&quot;</span>; <span class="docutils literal">[]</span></p></td>
</tr>
<tr><td><p><span class="docutils literal">oa_lifeline</span>, <span class="docutils literal">sa_lifeline</span></p></td>
<td><p><span class="docutils literal">represented</span>: participant, work, or role ref?</p></td>
@@ -792,49 +792,71 @@ An Enumeration contains unique string literals. For example:</p>
<pre class="code text literal-block"><code>definition { Enumeration { literals [&quot;Clear&quot;, &quot;Fog&quot;]; }; };
type_ref { Named &#64;weather_classification; };</code></pre>
<p>These are typed constructors with named fields, not embedded JSON documents.
Constructor field names and enum spellings are case-sensitive. When replacing
a constructor, all of its fields MUST be supplied; the containing declaration
defaults do not silently fill a different constructor's missing fields.
During schema-2 compatibility, the new Exchange fields <span class="docutils literal">message_kind</span>,
<span class="docutils literal">reply_to</span> and <span class="docutils literal">values</span> are exceptions: omitted values hydrate as
Asynchronous, none and [] respectively. Canonical output writes them explicitly.
This preserves older schema-2 source/JSON without inventing call correlation or
value annotations. It is not a rule for an unspecified future schema.</p>
Constructor field names and enum spellings are case-sensitive. A selected
constructor uses its own field contract; it does not inherit the payload of a
different constructor from the declaration default. Required fields MUST be
supplied. Nullability and omission are separate properties: <span class="docutils literal">?</span> denotes a
value that can be <span class="docutils literal">none</span>; a constructor's omission contract determines whether
the field may be absent. There is no general all-constructor-fields-required
rule. Other typed constructors use their contracts in the corresponding
sections; the occurrence rules below do not establish defaults for them.</p>
<p>The following table records the source-7 OccurrenceBody contracts. Optional
references may be omitted and then mean <span class="docutils literal">none</span>. Exchange also admits omitted
<span class="docutils literal">message_kind</span> and <span class="docutils literal">values</span>, meaning Asynchronous and <span class="docutils literal">[]</span> respectively.
These omissions are accepted in newly authored source 7, not only in schema-2
compatibility input. Earlier schema admission of constructors and fields is
still governed by its version rules.</p>
<p>Canonical formatting writes the hydrated occurrence references and default
<span class="docutils literal">message_kind</span>, <span class="docutils literal">reply_to</span> and <span class="docutils literal">values</span> explicitly. An absent
<span class="docutils literal">operation</span> remains omitted in canonical output. Lossless no-op updates and
unrelated name edits retain authored omissions; canonical formatting is a
different operation. An admitted incomplete occurrence can still produce model
checks requesting its missing work, exchange, lifeline or referenced scenario.</p>
<table>
<caption>Occurrence body constructors</caption>
<colgroup>
<col style="width: 22.0%" />
<col style="width: 78.0%" />
<col style="width: 18.0%" />
<col style="width: 36.0%" />
<col style="width: 46.0%" />
</colgroup>
<thead>
<tr><th class="head"><p>Constructor</p></th>
<th class="head"><p>Required fields</p></th>
<th class="head"><p>Fields that may be omitted, with their resulting values</p></th>
</tr>
</thead>
<tbody>
<tr><td><p>Exchange</p></td>
<td><p><span class="docutils literal">exchange</span>: exchange relation ref?; <span class="docutils literal">sender</span>, <span class="docutils literal">receiver</span>: lifeline refs?; <span class="docutils literal">message_kind</span>: MessageKind; <span class="docutils literal">reply_to</span>: occurrence ref?; <span class="docutils literal">values</span>: MessageValue records</p></td>
<td><p>None</p></td>
<td><p><span class="docutils literal">exchange</span>: exchange relation ref?, <span class="docutils literal">sender</span>, <span class="docutils literal">receiver</span>: lifeline refs?, <span class="docutils literal">reply_to</span>: occurrence ref?, <span class="docutils literal">operation</span>: OperationUse? → <span class="docutils literal">none</span>; <span class="docutils literal">message_kind</span>: MessageKind → Asynchronous; <span class="docutils literal">values</span>: MessageValue records → <span class="docutils literal">[]</span></p></td>
</tr>
<tr><td><p>Action</p></td>
<td><p><span class="docutils literal">action</span>: activity/function ref?; <span class="docutils literal">lifeline</span>: ref?</p></td>
<td><p>None</p></td>
<td><p><span class="docutils literal">action</span>: activity/function ref?, <span class="docutils literal">lifeline</span>: ref? → <span class="docutils literal">none</span></p></td>
</tr>
<tr><td><p>Control</p></td>
<td><p><span class="docutils literal">kind</span>: Choice, Merge, Fork, Join, Loop</p></td>
<td><p>None</p></td>
</tr>
<tr><td><p>SequenceReference</p></td>
<td><p><span class="docutils literal">sequence</span>: process/functional-chain ref?</p></td>
<td><p>None</p></td>
<td><p><span class="docutils literal">sequence</span>: process/functional-chain ref? → <span class="docutils literal">none</span></p></td>
</tr>
<tr><td><p>ScenarioUse</p></td>
<td><p><span class="docutils literal">scenario</span>: scenario ref?; <span class="docutils literal">bindings</span>: LifelineBinding records</p></td>
<td><p><span class="docutils literal">bindings</span>: LifelineBinding records</p></td>
<td><p><span class="docutils literal">scenario</span>: scenario ref? → <span class="docutils literal">none</span></p></td>
</tr>
<tr><td><p>State</p></td>
<td><p><span class="docutils literal">state</span>: state/mode ref?; <span class="docutils literal">lifeline</span>: ref?</p></td>
<td><p>None</p></td>
<td><p><span class="docutils literal">state</span>: state/mode ref?, <span class="docutils literal">lifeline</span>: ref? → <span class="docutils literal">none</span></p></td>
</tr>
<tr><td><p>Fragment</p></td>
<td><p><span class="docutils literal">operator</span>: Alternative, Parallel, Loop, Optional; <span class="docutils literal">branches</span>: branch occurrence refs</p></td>
<td><p>None</p></td>
</tr>
<tr><td><p>Branch</p></td>
<td><p><span class="docutils literal">guard</span>: string; <span class="docutils literal">occurrences</span>: occurrence refs</p></td>
<td><p>None</p></td>
</tr>
</tbody>
</table>
@@ -1297,16 +1319,25 @@ references a Call occurrence in the same scenario. The call MUST precede the
reply on a guaranteed common sequence/enclosing branch path. Reply lifelines
reverse the call's sender/receiver; it may reuse the call's exchange in reverse
or use an explicit reverse-direction exchange. A second reply to the same call
on that guaranteed path is an error. Missing reply correlation is a draft
that can follow another reply on a shared execution path, including conditional
or parallel operands, is an error. Missing reply correlation is a draft
warning; non-Reply messages MUST NOT have <span class="docutils literal">reply_to</span>.</p>
<p>Create identifies the receiver lifeline's creation. An earlier guaranteed use
of that lifeline is an error. Delete identifies its destruction; a later
guaranteed use is an error. Ordering checks respect branch ownership; they MUST
NOT flatten alternative branches into a false unconditional order. A Timer is
<p>Create identifies the receiver lifeline's creation. Another use that can precede
its creation on a shared execution path is an error. Delete identifies its
destruction; another use that can follow it on a shared execution path is an
error. These checks include conditional and parallel operands but exclude
mutually exclusive alternatives. Ordering checks respect branch ownership; they
MUST NOT flatten alternative branches into a false unconditional order. A Timer is
local to its sender lifeline, has no global exchange or values, and has either
no receiver or the same receiver as sender. Its nonempty expression describes
the delay/deadline; an empty expression warns. Conditions and expressions are
stored engineering annotations, not an executable simulation language.</p>
<p>These ordering checks compare distinct stored occurrences along structural
paths; they do not simulate repeated loop iterations. Repetition risks use
<span class="docutils literal">reply_repetition</span> and <span class="docutils literal">lifeline_repetition</span> warnings separately. For example,
a loop containing one Reply to an outer Call can warn about repetition without
containing two distinct replies; a same-operand Create/use/Delete lifetime can
repeat without its previous iteration being treated as an earlier stored use.</p>
<p>Each MessageValue is <span class="docutils literal">{ path [&#64;parameter]; field &#64;data_field; expression &quot;value expression&quot;; }</span>.
Its identity is the pair (path, field), so two uses of one Record can have
different values for the same terminal field. Path contains enclosing DataField
@@ -2618,6 +2649,41 @@ leaving dangling references. Deleting a sequence does not delete the semantic
exchanges it references. Cross-layer counterparts are not owned descendants.
Text edits describe a complete candidate and must remove or repair dependencies
explicitly before Apply succeeds.</p>
<section id="scenario-lifetime-presentation">
<h3>8.1. Scenario lifetime presentation</h3>
<p>Scenario lifetime geometry is derived from the stored occurrences and their
sequence/operand ownership. It adds no model records, source annotations or
history entries. A lifeline's identity header and neutral editing guide remain
available before creation, after deletion and when its represented element is
unfinished. The guide MUST be visually distinguishable from a live interval;
it is an editing axis, not a statement that the participant exists.</p>
<p>A directly ordered Create starts the receiver's live interval at its occurrence;
Delete ends that receiver's interval at its occurrence. Create uses a named birth
marker and Delete an X, each selectable through the original occurrence identity.
The message's receiving endpoint MUST align with its marker, including self
messages. A pre-existing lifeline without a creation has a live interval from
below its header; without deletion it extends to the visible scenario bottom,
including in an empty scenario. A missing lifecycle receiver MUST NOT be inferred from
the exchange. An explicit local receiver remains meaningful when its exchange
reference is unfinished.</p>
<p>Operands MUST be projected independently from their enclosing entry context.
A lifetime change in an alternative, optional, loop or parallel operand MUST
NOT imply the same change in its displayed sibling or a definite lifetime
after the fragment. When local structure does not establish one lifetime across
the represented paths, the continuation is visually unresolved. A subsequent
explicit Create or Delete in the enclosing sequence can establish a definite interval.
Neither guard text, screen order nor a guessed loop count proves execution.
ScenarioUse remains opaque: opening its definition may show its lifecycle,
but a callee's geometry MUST NOT create or destroy a caller lifeline.</p>
<p>Call activation is distinct from lifetime. A branch-local Delete clips that
branch's visible activation at the death marker without inventing a Reply,
removing an unresolved-call warning or terminating sibling paths.
Solid activation bars are restricted to definite live intervals; an unresolved
continuation retains its uncertainty/call diagnostic rather than depicting
definite survival after a possible deletion. Selection,
insertion slots, source edits and Undo/Redo retain the same semantic identities
and validation boundary regardless of the rendered intervals.</p>
</section>
</section>
<section id="persistence-and-explicit-migration">
<h2>9. Persistence and explicit migration</h2>