Preserve loaded draft bytes and model history, reject stale workspace and input events, and keep captured Escape under modal priority. Verified 181 focused Windows tests and strict desktop Clippy on exact inputs4; earlier full737 scope and component/native preparation evidence are archived separately. Native navigation acceptance remains pending.
2286 lines
129 KiB
ReStructuredText
2286 lines
129 KiB
ReStructuredText
Arcadia Studio OA / SA Language and Editing Contract
|
||
====================================================
|
||
|
||
:Version: 7 (integration in progress)
|
||
:Status: Source-7 contract under integration; native and API acceptance pending
|
||
:Core implementation: ``crates/oa-core``
|
||
:Text suffix: ``.arcadia``
|
||
|
||
1. Scope and conformance
|
||
------------------------
|
||
|
||
This specification defines the shared Operational Analysis (OA) and System
|
||
Analysis (SA) model, its textual language, graphical editing obligations,
|
||
validation, persistence, and explicit migration from versions 1, 2, 3, 4, 5 and 6. MUST, MUST NOT,
|
||
and MAY indicate requirements, prohibitions, and permitted choices.
|
||
|
||
Schema 7 adds caller-qualified process/chain links and explicit interface-operation
|
||
selection on boundary scenario invocations. Schema 6 added OA communication means,
|
||
exchange categories and saved view options. Integration and acceptance are tracked
|
||
separately; this version label does not claim completed graphical/API parity.
|
||
Schema 5 added closed typed semantic review facts to trace baselines, including
|
||
historical references that may no longer exist in the live model. It retains
|
||
schema 4 bounded reusable data types, typed defaults, exchange mechanisms,
|
||
qualified values, specialization, interface allocations and associations, and
|
||
schema 3 typed ports and state views. Explicit older readers preserve meanings
|
||
and identities without inventing previously reviewed semantic values.
|
||
This contract does not by itself establish native acceptance or release completion.
|
||
|
||
OA describes stakeholders, operational work and needs. SA describes the
|
||
selected system boundary, external actors, functions, services and expected
|
||
behavior. SA permits at most one System of Interest; its absence is an
|
||
incomplete-model warning when other SA elements exist. The SA System MUST NOT
|
||
contain internal components. Functional decomposition is independent of that
|
||
structural boundary. Logical Architecture, Physical Architecture, deployment,
|
||
Capella file interchange, and executable behavioral simulation are outside
|
||
this specification. This independent language does not claim complete Arcadia,
|
||
Eclipse Capella, or SysML conformance.
|
||
|
||
An implementation conforms only when each supported field and relationship is
|
||
reachable in both graphical and textual editing, preserves identity through
|
||
save/open and undo, and uses the same structural validation. Merely displaying
|
||
a name or storing an opaque payload does not establish graphical support.
|
||
Actual verification evidence is separate from this contract.
|
||
|
||
2. One authoritative model
|
||
--------------------------
|
||
|
||
A Project stores ``schema_version`` (7), ``id``, ``alias``, ``name``,
|
||
``description``, and maps named ``elements``, ``relations``, ``diagrams``,
|
||
``artifact_links``, and ``traces``. Each map is keyed by the UUID contained in
|
||
its record. Duplicate map keys and mismatching keys/identities are errors.
|
||
|
||
All objects share one UUID and alias namespace: Project, Element, Relation,
|
||
Diagram, NodePlacement, ArtifactLink, and Trace. UUIDs are durable identity;
|
||
aliases are durable, editable source labels. Display-name changes MUST NOT
|
||
regenerate existing aliases. Different objects MAY have the same display name.
|
||
|
||
Every Element has ``id``, ``alias``, ``name``, ``description``, ``parent``
|
||
(optional element reference), and a typed ``body``. Its kind and OA/SA layer
|
||
are derived from its body. A Relation has ``id``, ``alias``, ``name``,
|
||
``description``, and a typed body; it has no independently editable kind tag
|
||
that can disagree with its payload.
|
||
|
||
Diagram placement does not determine semantic ownership. NodePlacement
|
||
records belong to diagrams and reference semantic elements. Multiple diagrams
|
||
can show the same element with independent placement and collapse state.
|
||
Within one diagram, each element appears at most once.
|
||
|
||
All stored strings MUST contain only XML 1.0 characters: U+0009, U+000A,
|
||
U+000D, U+0020–U+D7FF, U+E000–U+FFFD, or U+10000–U+10FFFF. Strings are not
|
||
trimmed or Unicode-normalized. Escaping a forbidden character does not permit
|
||
it. Coordinates and sizes are finite IEEE-754 binary32 values with absolute
|
||
value at most 1000000. Width and height MUST be positive. Signed zero and
|
||
subnormal coordinates are retained.
|
||
|
||
3. Element declarations and typed fields
|
||
----------------------------------------
|
||
|
||
Each element declaration starts with its layer and kind, for example
|
||
``oa_activity`` or ``sa_function``. Every element body accepts
|
||
``description`` (default ``""``) and ``parent`` (default ``none`` for a
|
||
document-level declaration, or its lexical element owner when nested; section
|
||
6.2). The table
|
||
lists all additional fields. ``ref`` means ``@alias``; ``ref?`` also accepts
|
||
``none``. Lists preserve order. Unknown or duplicate fields are errors.
|
||
|
||
.. list-table:: Element body field catalog
|
||
:header-rows: 1
|
||
:widths: 27 43 30
|
||
|
||
* - Declarations
|
||
- Additional fields
|
||
- Defaults
|
||
* - ``oa_entity``, ``oa_actor``, ``oa_role``, ``oa_activity``, ``oa_capability``, ``oa_mission``
|
||
- None
|
||
- Empty body
|
||
* - ``sa_system``, ``sa_actor``, ``sa_function``, ``sa_capability``, ``sa_mission``
|
||
- None
|
||
- Empty body
|
||
* - ``oa_process``, ``sa_functional_chain``
|
||
- ``steps``: occurrence refs
|
||
- ``[]``
|
||
* - ``oa_exchange_item``, ``sa_exchange_item``
|
||
- ``kind``: Information, Material, Energy; ``mechanism``: ExchangeMechanism; ``supertype``: item ref?
|
||
- Information; Unspecified; none
|
||
* - ``oa_exchange_category``, ``sa_exchange_category``
|
||
- ``family``: Work or Participant; ``exchanges``: same-layer exchange refs
|
||
- Work; ``[]``; root-level only
|
||
* - ``oa_data_type``, ``sa_data_type``
|
||
- ``definition``: DataTypeDefinition; ``default``: DataValue?; ``unit``: string
|
||
- String with minimum_length 0 / maximum_length none; none; ``""``
|
||
* - ``oa_data_field``, ``sa_data_field``
|
||
- ``type_ref``; ``minimum``: u32; ``maximum``: optional u32; ``unit``: string; ``direction``: ParameterDirection; ``storage``: FieldStorage; ``default``: DataValue list?
|
||
- String; 1; 1; ``""``; Unspecified; Value; none
|
||
* - ``oa_interface``, ``sa_interface``
|
||
- ``supertype``: interface ref?
|
||
- none; membership is an identified interface_item_allocation relation
|
||
* - ``oa_port``, ``sa_port``
|
||
- ``contract``: required PortContract; ``legacy``: optional LegacyPortContract
|
||
- No implicit contract; ``legacy`` defaults none. OA admits Legacy only.
|
||
* - ``oa_scenario``, ``sa_scenario``
|
||
- ``viewpoint``: ScenarioViewpoint; ``context``: ref?; ``precondition``, ``postcondition``: strings; ``steps``: occurrence refs
|
||
- MixedLegacy when viewpoint is omitted, including newly authored source 7 (see section 4.3); none; ``""``; ``""``; ``[]``
|
||
* - ``oa_lifeline``, ``sa_lifeline``
|
||
- ``represented``: participant, work, or role ref?
|
||
- none
|
||
* - ``oa_occurrence``, ``sa_occurrence``
|
||
- ``body``: occurrence constructor; ``precondition``, ``postcondition``: strings
|
||
- Exchange with none references, Asynchronous message kind and no values; two empty strings
|
||
* - ``oa_state_machine``, ``sa_state_machine``, ``oa_region``, ``sa_region``
|
||
- None
|
||
- Empty body
|
||
* - ``oa_state``, ``sa_state``, ``oa_mode``, ``sa_mode``, ``oa_initial``, ``sa_initial``, ``oa_final``, ``sa_final``
|
||
- ``kind``: StateKind; ``entry``, ``exit``, ``do_activity``: strings
|
||
- Kind selected by declaration; three empty strings
|
||
* - ``oa_choice``, ``oa_junction``, ``oa_fork``, ``oa_join``, ``oa_shallow_history``, ``oa_deep_history``, ``oa_entry_point``, ``oa_exit_point``, ``oa_terminate`` and corresponding ``sa_`` declarations
|
||
- Same State body; StateKind is Choice, Junction, Fork, Join, ShallowHistory, DeepHistory, EntryPoint, ExitPoint or Terminate
|
||
- Kind selected by declaration; three empty strings
|
||
* - ``oa_event``, ``sa_event``
|
||
- ``body``: Signal, Time or Change constructor
|
||
- Signal with ``items []``
|
||
* - ``oa_constraint``, ``sa_constraint``
|
||
- ``expression``: string; ``constrained``: semantic record refs
|
||
- ``""``; ``[]``
|
||
|
||
The explicit state ``kind`` field MUST agree with its declaration keyword.
|
||
``u32`` is an integer from 0 through 4294967295. A DataField's maximum MUST
|
||
be at least its minimum; ``none`` means unbounded. Primitive TypeRefs are
|
||
Boolean, Integer, Real, and String. A named TypeRef uses a DataType reference.
|
||
An Enumeration contains unique string literals. For example:
|
||
|
||
.. code-block:: text
|
||
|
||
definition { Enumeration { literals ["Clear", "Fog"]; }; };
|
||
type_ref { Named @weather_classification; };
|
||
|
||
These are typed constructors with named fields, not embedded JSON documents.
|
||
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: ``?`` denotes a
|
||
value that can be ``none``; 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.
|
||
|
||
The following table records the source-7 OccurrenceBody contracts. Optional
|
||
references may be omitted and then mean ``none``. Exchange also admits omitted
|
||
``message_kind`` and ``values``, meaning Asynchronous and ``[]`` 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.
|
||
|
||
Canonical formatting writes the hydrated occurrence references and default
|
||
``message_kind``, ``reply_to`` and ``values`` explicitly. An absent
|
||
``operation`` 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.
|
||
|
||
.. list-table:: Occurrence body constructors
|
||
:header-rows: 1
|
||
:widths: 18 36 46
|
||
|
||
* - Constructor
|
||
- Required fields
|
||
- Fields that may be omitted, with their resulting values
|
||
* - Exchange
|
||
- None
|
||
- ``exchange``: exchange relation ref?, ``sender``, ``receiver``: lifeline refs?, ``reply_to``: occurrence ref?, ``operation``: OperationUse? → ``none``; ``message_kind``: MessageKind → Asynchronous; ``values``: MessageValue records → ``[]``
|
||
* - Action
|
||
- None
|
||
- ``action``: activity/function ref?, ``lifeline``: ref? → ``none``
|
||
* - Control
|
||
- ``kind``: Choice, Merge, Fork, Join, Loop
|
||
- None
|
||
* - SequenceReference
|
||
- None
|
||
- ``sequence``: process/functional-chain ref? → ``none``
|
||
* - ScenarioUse
|
||
- ``bindings``: LifelineBinding records
|
||
- ``scenario``: scenario ref? → ``none``
|
||
* - State
|
||
- None
|
||
- ``state``: state/mode ref?, ``lifeline``: ref? → ``none``
|
||
* - Fragment
|
||
- ``operator``: Alternative, Parallel, Loop, Optional; ``branches``: branch occurrence refs
|
||
- None
|
||
* - Branch
|
||
- ``guard``: string; ``occurrences``: occurrence refs
|
||
- None
|
||
|
||
For example, ``body { Action { action @assess; lifeline @operator_line; }; };``
|
||
selects an Action occurrence. Processes and functional chains contain Exchange,
|
||
Action, Control and SequenceReference occurrences. Process/chain Actions are
|
||
contextual work contributions and MUST have ``lifeline none``. A Control or
|
||
SequenceReference MUST belong directly to a Process or FunctionalChain, not a
|
||
Scenario. Scenarios contain Exchange, Action, State, Fragment, Branch and ScenarioUse
|
||
occurrences according to their enclosing ownership rules. Each
|
||
listed occurrence belongs to its enclosing sequence or branch through
|
||
``parent``. A Branch belongs to a Fragment; the Fragment's ``branches`` list
|
||
references the branches it owns.
|
||
|
||
An exchange and an occurrence of that exchange have different identities.
|
||
Repeating an exchange requires distinct occurrence records. Repeating one
|
||
occurrence identity within an ordered list is invalid. Conditions, guards,
|
||
entry/exit/do text, and constraint expressions are descriptive strings; this
|
||
version does not parse or execute them as a programming language.
|
||
|
||
4. Containment, allocation, and relationships
|
||
---------------------------------------------
|
||
|
||
Containment MUST be acyclic and stay within one layer. Entities may contain
|
||
entities, actors, and roles. Actors are not structural containers. Activities
|
||
contain activities; functions contain functions. Capability grouping uses
|
||
same-layer capability parents; it does not mean inheritance or inclusion.
|
||
Operational and system missions are root semantic records; they do not own
|
||
capabilities by containment. MissionCapability expresses that association.
|
||
DataFields belong to ExchangeItems or Record DataTypes. Preserved generic ports belong to
|
||
participants or work. Lifelines belong to scenarios. State-machine ownership
|
||
uses participant → machine → region → state/mode; a state or mode can contain
|
||
a nested region. All other state vertices belong to Regions as well. Events
|
||
are root semantic records and do not acquire a machine owner when referenced.
|
||
|
||
DataFields, ports, lifelines, occurrences, Regions and all state vertices
|
||
require an owner. An unowned StateMachine can be saved as incomplete
|
||
work and produces a warning. The System cannot own internal components.
|
||
The present Studio profile does not decompose SA Actors.
|
||
|
||
All relations have a header identity, alias, display name, optional
|
||
``description`` (default ``""``), and required ``source`` and ``target``
|
||
endpoints. Ordinary endpoints are semantic references; ContextualLink endpoints
|
||
are qualified OccurrenceEndpoint records resolved from its required ``owner``.
|
||
Their kind is the declaration keyword:
|
||
|
||
.. list-table:: Relation catalog
|
||
:header-rows: 1
|
||
:widths: 24 49 27
|
||
|
||
* - Declaration
|
||
- Endpoint meaning
|
||
- Additional fields / defaults
|
||
* - ``allocation``
|
||
- Same-layer participant → leaf activity/function
|
||
- None
|
||
* - ``interface_item_allocation``
|
||
- Same-layer Interface → ExchangeItem
|
||
- ``order`` u32 / 0; ``transmission`` TransmissionProtocol / Unspecified; ``acquisition`` AcquisitionProtocol / Unspecified
|
||
* - ``data_association``
|
||
- Same-layer Record DataType → Record DataType
|
||
- ``source_role``, ``target_role`` / ""; ``source_minimum``, ``target_minimum`` / 0; ``source_maximum``, ``target_maximum`` / none; ``source_navigable``, ``target_navigable`` / false
|
||
* - ``interaction``
|
||
- OA activity → OA activity
|
||
- ``items`` refs / []
|
||
* - ``functional_exchange``
|
||
- SA function → SA function
|
||
- Required ``source_port``, ``target_port`` refs; ``items`` / []
|
||
* - ``boundary_exchange``
|
||
- Different participant owners; typed component ports have matching kinds
|
||
- ``oriented`` bool / true; ``items`` refs / []
|
||
* - ``communication_mean``
|
||
- Different OA Entity/Actor elements; no operational ports or role inference
|
||
- ``oriented`` bool / false; ``items`` refs / []
|
||
* - ``port_allocation``
|
||
- SA Component port → SA FunctionInput/FunctionOutput port
|
||
- Requires the function's actual work Allocation to that component
|
||
* - ``capability_involvement``
|
||
- Participant, activity/function, or OA role → capability
|
||
- None
|
||
* - ``chain_involvement``
|
||
- Process/functional chain → capability
|
||
- None
|
||
* - ``role_realization``
|
||
- OA entity/actor → OA role
|
||
- None
|
||
* - ``role_assignment``
|
||
- OA role → leaf OA activity
|
||
- None
|
||
* - ``mission_capability``
|
||
- OA mission → OA capability, or SA mission → SA capability
|
||
- None
|
||
* - ``mission_involvement``
|
||
- OA entity/actor → OA mission, or SA System/Actor → SA mission
|
||
- None
|
||
* - ``capability_include``
|
||
- Including capability → included capability in one layer
|
||
- None
|
||
* - ``capability_extend``
|
||
- Extending capability → extended capability in one layer
|
||
- ``condition`` string / ""
|
||
* - ``capability_generalization``
|
||
- Specific capability → general capability in one layer
|
||
- None
|
||
* - ``sequence_link``
|
||
- Preceding contribution → following contribution in one process/chain
|
||
- ``guard`` string / ""
|
||
* - ``contextual_link``
|
||
- Qualified occurrence endpoints resolved from an explicit owner Process/FunctionalChain; section 4.2.1
|
||
- Required ``owner``, ``source`` and ``target`` OccurrenceEndpoint records, and typed ``purpose``: Precedence, Exchange or CommonWork
|
||
* - ``state_transition``
|
||
- State vertices in one machine, subject to section 4.4
|
||
- ``trigger``, ``guard``, ``effect`` strings / ""; ``transition_kind`` External; ``triggers``, ``effects`` reference lists / []
|
||
* - ``availability``
|
||
- Work, participant, capability, or process/chain → state/mode
|
||
- None
|
||
* - ``exchange_allocation``
|
||
- CommunicationMean → OA Interaction, or BoundaryExchange → same-layer Interaction/FunctionalExchange
|
||
- None
|
||
* - ``interface_provision``, ``interface_requirement``
|
||
- Participant/port → provided/required interface
|
||
- None
|
||
* - ``state_action``
|
||
- State/mode → activity/function
|
||
- ``phase``: Entry, Do, Exit / Do
|
||
|
||
Relation endpoints and carried ExchangeItems stay in the same layer. Parallel
|
||
exchanges with distinct identities are permitted. Self-relations are invalid
|
||
except for a state transition that returns to its source state or an explicit
|
||
DataAssociation between two ends of the same Record type.
|
||
|
||
Source-6 communication and exchange categories
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
An OA ``communication_mean`` joins two distinct Entity/Actor records directly.
|
||
Its stable source/target tuple does not create operational ports. An unoriented
|
||
means permits either direction; an oriented ordinary use follows source to target.
|
||
The empty carried-item set is explicit, not a wildcard. Every item carried by an
|
||
allocated Interaction must specialize or equal a declared means item, using the
|
||
same inheritance rule as existing exchange allocations.
|
||
|
||
``exchange_allocation`` remains a separately identified relation. A means may
|
||
allocate several Interactions and an Interaction may have several explicit means.
|
||
Allocation compares actual activity-to-participant Allocations, without inferring
|
||
responsibility from roles or nesting. Every known performer must fit one complete
|
||
permitted endpoint pair. A known contradiction is an error; a missing actual
|
||
performer is an incomplete-model warning. Reorienting or reconnecting a means
|
||
validates all dependent allocations and scenario uses in one candidate.
|
||
|
||
ParticipantInteraction and compatible MixedLegacy scenarios may reference means.
|
||
For bidirectional use, explicit sender and receiver lifelines determine one
|
||
compatible ordered endpoint pair. Missing or ambiguous bindings do not guess a
|
||
direction. A Reply reusing its Call's means reverses the resolved actual Call,
|
||
including a reverse Call on an unoriented means. The existing operation-response
|
||
exception permits the correlated Reply on an oriented means; this implies no
|
||
physical transport property. OA process contributions continue to use Interaction.
|
||
|
||
Mapped unoriented SA BoundaryExchange messages use the same explicit lifeline
|
||
resolution. Ordinary messages also respect component-port direction; legacy
|
||
port boundaries retain their stored direction. A correlated same-channel Reply
|
||
still reverses the actual Call, including across directional Flow ports.
|
||
|
||
CommunicationMean and SA BoundaryExchange support Exchange traces. OA-to-SA
|
||
transition requires a separate component-port choice for each end of each means:
|
||
reuse an existing compatible port, or create a port with explicitly chosen
|
||
Standard/Flow kind and orientation. Participant correspondence never substitutes
|
||
a port UUID for its participant UUID. Interfaces and PortAllocations are not
|
||
invented; unresolved technical allocations must be reviewed or omitted from the
|
||
selection and authored explicitly. Reverse transition projects SA port owners to
|
||
reviewed OA participant counterparts, without copying typed SA ports into OA.
|
||
Source/Target review retains the exact participant/port identities in history.
|
||
Taking an OA endpoint requires the scoped technical port decision, while Keep
|
||
and a valid Candidate retain explicit technical choices.
|
||
|
||
``oa_exchange_category`` and ``sa_exchange_category`` are root-level named
|
||
semantic elements with ``family`` Work (default) or Participant, and ``exchanges``
|
||
references (default []). Work categories contain Interaction/FunctionalExchange;
|
||
Participant categories contain CommunicationMean/BoundaryExchange. Members must
|
||
be distinct and in the category's layer; categories never own or merge exchanges.
|
||
Category transition requires mapped counterpart members. ``Category.Family`` and
|
||
``Member { collection CategoryExchanges; ... }`` are closed typed semantic facts.
|
||
Deleting an exchange removes its category membership; deleting a category does
|
||
not remove its exchanges. Reidentification preserves all live references and
|
||
typed historical reference provenance.
|
||
|
||
Each Diagram has optional ``view_options`` (all selections unrestricted, no hidden
|
||
edges, Name labels by default). Its closed fields are ``hidden_edges``,
|
||
``relation_kinds``, ``work_categories``, ``participant_categories``, ``coverage``,
|
||
``work_contexts`` and ``exchange_labels``. Relation kinds use All or Only with
|
||
Relation(kind)/Trace entries; Only([]) draws no lines, including traces. Category
|
||
selectors use All or Any(category IDs); Any([]) draws none of that exchange family.
|
||
Selected categories are unioned within each family; independent restrictions
|
||
intersect. Coverage is All/InBehavior/OutsideBehavior; work contexts are All or
|
||
Any(explicit process, chain or scenario IDs). Contexts follow ordered owned
|
||
contributions and explicit reuse, sharing the advisory diagnostic evidence walk.
|
||
Labels are Name, Items or NameAndItems. These settings alter presentation only;
|
||
automatic port positions use unfiltered eligible lines. Hidden routes and semantic
|
||
identities remain saved. Removing a referenced selection preserves explicit empty
|
||
filters rather than widening them to All.
|
||
|
||
Traceability views retain their established two-layer projection: default options
|
||
preserve eligible OA and SA lines. Their hidden-edge, category and context
|
||
references may therefore select either layer. All ordinary projections require
|
||
these references in the declared diagram layer. A filter never hides the other
|
||
layer merely because the Traceability diagram has an OA or SA layer label.
|
||
|
||
Versions 1–5 reject the new relation, category constructor, diagram field (even
|
||
an explicitly supplied default), and category historical facts. Reading version 5
|
||
preserves existing records, legacy OA boundaries and reviewed facts, with an
|
||
explicit upgrade report to the current version 7. Source upgrading changes the version token
|
||
without rewriting unrelated authored trivia. No old boundary is automatically
|
||
converted into communication means. Source-6 graphical/API/native acceptance is
|
||
still tracked separately from this integration contract.
|
||
|
||
Direct Allocation has at most one performer per leaf. Role sharing is a
|
||
different relationship: several OA participants can realize a Role. A direct
|
||
allocation inconsistent with its role's realized performers produces an
|
||
advisory warning; it does not prevent saving the model. Shared roles do not
|
||
imply a unique performer.
|
||
Allocation of a non-leaf work element is invalid. A computed graphical summary
|
||
of its allocated leaves MUST NOT create an extra semantic allocation.
|
||
|
||
Typed function ports belong directly to SA Functions. ``FunctionOutput``
|
||
declares ``outgoing_items``; ``FunctionInput`` declares ``incoming_items``.
|
||
The lists contain distinct same-layer ExchangeItem references. A functional
|
||
exchange MUST reference output/input ports owned by its respective functions,
|
||
and each carried item MUST fit both declarations. Empty declarations accept
|
||
no items. A carried item satisfies an identical declaration or a declaration
|
||
of one of its explicit base items. A base item does not satisfy a more
|
||
specialized declaration; names imply no compatibility. Port declarations
|
||
remain independent of incident exchanges after creation.
|
||
|
||
A ``Component`` contract belongs to an SA System or SystemActor and stores
|
||
``kind`` (Standard or Flow) and ``orientation`` (Unset, In, Out, InOut).
|
||
Standard requires Unset. Flow Unset is an incomplete draft, not InOut. Typed
|
||
component connections require matching kinds: Standard/Flow mismatch is an
|
||
error. Standard connections normally use ``oriented false``; directional Flow
|
||
connections use true. Boundary orientation is separate from endpoint kind and
|
||
orientation. Oriented Flow endpoints permit Out at source and In at target;
|
||
unoriented Flow endpoints must permit at least one communication direction.
|
||
|
||
Provided/required interfaces are separate identified relations. A Standard
|
||
partner satisfies a requirement by providing the identical interface; stored
|
||
source/target order does not infer service roles. Component carried items must
|
||
fit the declared interface-item union when explicit declarations exist. An
|
||
explicitly empty interface is not a wildcard. Missing declarations and
|
||
unsatisfied required interfaces produce located completeness warnings.
|
||
|
||
``PortAllocation`` relates a Component port to a typed function port only when
|
||
that function has an actual Allocation to the component owner. Standard may
|
||
allocate either function direction; Flow directions must agree. A typed
|
||
ExchangeAllocation requires both corresponding PortAllocations and compatible
|
||
carried items. Unoriented boundary exchanges allow reversed correspondence.
|
||
Visual allocation nesting is never evidence of a stored allocation relation.
|
||
|
||
``Legacy`` requires ``legacy { direction ...; interface ...; }``. It preserves
|
||
generic direction/interface data and emits a located compatibility warning.
|
||
It is an explicit compatibility constructor in JSON/source; ordinary creation
|
||
pickers do not offer it. Resolution to a typed SA contract retains this record
|
||
without treating it as another active constraint. OA generic ports remain
|
||
Legacy; OA Interactions stay activity-to-activity without function ports.
|
||
Deleting a referenced legacy interface clears that optional live reference.
|
||
|
||
A current-source functional exchange MUST specify both port aliases; the parser does
|
||
not create endpoints. Graphical/command FE creation plans ports atomically,
|
||
using unique compatible typed-port reuse or deterministic new endpoints.
|
||
Port deletion cascades to incident FEs; FE deletion retains independent ports.
|
||
|
||
For example::
|
||
|
||
arcadia 7;
|
||
project ports_example "Typed function contract" {
|
||
sa_function send "Send" {}
|
||
sa_function receive "Receive" {}
|
||
sa_exchange_item payload "Payload" {}
|
||
sa_interface old_service "Preserved service" {}
|
||
interface_item_allocation service_payload "Service payload" { source @old_service; target @payload; }
|
||
sa_port output "Output" {
|
||
parent @send;
|
||
contract { FunctionOutput { outgoing_items [@payload]; }; };
|
||
}
|
||
sa_port input "Input" {
|
||
parent @receive;
|
||
contract { FunctionInput { incoming_items [@payload]; }; };
|
||
}
|
||
functional_exchange message "Message" {
|
||
source @send; target @receive;
|
||
source_port @output; target_port @input; items [@payload];
|
||
}
|
||
sa_port preserved "Unresolved original" {
|
||
parent @send; contract Legacy;
|
||
legacy { direction InOut; interface @old_service; };
|
||
}
|
||
}
|
||
|
||
An exclusive region has at most one initial state. Missing initial state is
|
||
a completeness warning. Initial states have no incoming transitions and at
|
||
most one outgoing transition; their outgoing transition has no trigger/guard.
|
||
Final states have no outgoing transitions. Mixing State and Mode entries is
|
||
permitted by this Studio profile. StateAction links provide typed work
|
||
references alongside the descriptive entry/exit/do strings.
|
||
|
||
4.1. Capabilities and missions
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Include means the including capability requires the included capability's
|
||
behavior. Extend means the source capability adds conditional behavior to the
|
||
target; its ``condition`` records when that behavior applies. Generalization
|
||
means a specific source capability specializes a general target capability.
|
||
Each relationship stays within OA capabilities or within SA capabilities.
|
||
Include and Generalization graphs MUST each be acyclic, including transitive
|
||
cycles. Extend does not introduce an additional cycle restriction; the ordinary
|
||
no-self rule still applies. An empty Extend condition is an engineering warning
|
||
so an incomplete capability map can be authored and saved.
|
||
|
||
MissionCapability and MissionInvolvement express need and stakeholder/system
|
||
participation. They MUST NOT create a capability parent, a performer allocation,
|
||
or a cross-layer realization. These relationships remain distinct when the
|
||
same objects appear in a diagram or share names.
|
||
|
||
4.2. Contextual process and chain topology
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
A Process or FunctionalChain owns contribution occurrences with stable
|
||
identities. ``steps`` is their persistent membership and presentation order;
|
||
an identity MUST occur at most once in that list. A work contribution points to
|
||
an existing same-layer Activity or Function. Reusing the same work or exchange
|
||
requires separate occurrence identities and MUST NOT duplicate the referenced
|
||
engineering element. A SequenceReference points to another same-layer Process
|
||
or FunctionalChain of the owner's kind. Its target may be ``none`` while the
|
||
draft is incomplete. Direct and transitive recursive sequence reuse are errors.
|
||
|
||
SequenceLinks connect distinct occurrences directly owned by the same process
|
||
or chain. Their source is the predecessor and target is the successor. A link
|
||
from work to an exchange requires that work to be the referenced exchange's
|
||
source; an exchange-to-work link requires the target work to be its endpoint.
|
||
Two adjacent exchange contributions require the first exchange's target to
|
||
match the second exchange's source. A mismatch is a structural error. Other
|
||
links express contextual precedence without manufacturing a global exchange.
|
||
|
||
When links or work/control/reuse contributions exist, topology is explicit.
|
||
Reordering ``steps`` MUST NOT add, remove or reorder SequenceLinks. The editor
|
||
MUST retain the difference between alternative Choice/Merge and parallel
|
||
Fork/Join contributions. Choice/Fork expect one incoming and at least two
|
||
outgoing links; Merge/Join expect at least two incoming and one outgoing link.
|
||
Loop expects at least one incoming and two outgoing links for repetition and
|
||
exit. These cardinalities are completeness warnings, not barriers to building
|
||
an incomplete flow. Choice and Loop outgoing paths with empty guards warn;
|
||
an explicit ``else`` guard is permitted. Guards remain descriptive strings.
|
||
|
||
Validation warns about missing/ambiguous entry and exit, isolated or unreachable
|
||
contributions, contributions with no reachable exit, and splits/merges that
|
||
lack explicit controls. Topology cycles are permitted for loops; the recursive
|
||
SequenceReference prohibition is a different rule. A legacy exchange-only
|
||
sequence without explicit links retains its ordered linear meaning and
|
||
adjacent-exchange gap diagnostics. Implementations MUST NOT silently invent
|
||
topology links when loading or reordering such a sequence.
|
||
|
||
4.2.1. Links into reusable sequences
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
``ContextualLink`` owns an explicit ``owner`` Process or FunctionalChain and two
|
||
``OccurrenceEndpoint`` records. Each endpoint contains an ordered ``references``
|
||
list of SequenceReference occurrence identities and an ``occurrence`` leaf
|
||
identity. Start at the link owner; each path member MUST be a contribution of the
|
||
current sequence and reference a valid same-layer sequence of the owner's kind.
|
||
Descend into that referenced definition before resolving the next path member or
|
||
leaf. The final leaf MUST be a contribution of the resulting sequence. A path
|
||
contains reference occurrences, never work elements or sequence-definition IDs.
|
||
An empty path denotes a direct contribution of the owner. Missing targets,
|
||
wrong owners, wrong kinds/layers and recursive reuse are errors.
|
||
|
||
Repeated references remain distinct. Given P with A→B→C and two references R1(P)
|
||
and R2(P), a link from direct X to ``[R1], B`` affects only the R1 contribution
|
||
of B. It MUST NOT target R2.B, alter P's definition, delay R1.A by replacing the
|
||
endpoint with the whole R1 reference, or duplicate A/B/C. Two endpoints with the
|
||
same leaf identity but distinct paths are distinct caller contributions.
|
||
|
||
The closed ``purpose`` has exactly three alternatives:
|
||
|
||
* ``Precedence { guard }`` describes predecessor/successor order; guard is prose.
|
||
When both paths are empty, use the existing SequenceLink. All-direct
|
||
ContextualLink Precedence MUST be rejected, preserving one canonical encoding.
|
||
* ``Exchange { exchange }`` identifies the same-layer work exchange connecting
|
||
the addressed work contributions; both endpoint works MUST match its actual
|
||
source and target. It records assembly incidence, not an implicit extra
|
||
precedence edge.
|
||
* ``CommonWork { work }`` requires both addressed contributions to reference that
|
||
same-layer Activity or Function. It states shared work identity, without
|
||
fusing executions, deleting contributions or asserting precedence.
|
||
|
||
For example, within a complete source-7 project with the referenced declarations::
|
||
|
||
contextual_link after_check "Continue this assessment" {
|
||
owner @alarm_process;
|
||
source { references []; occurrence @external_check; };
|
||
target { references [@first_assessment]; occurrence @assessment_b; };
|
||
purpose { Precedence { guard "check accepted"; }; };
|
||
}
|
||
|
||
The owner controls persistence/module placement and graphical editing context,
|
||
including when neither leaf belongs directly to it. Generic leaf source/target
|
||
accessors MUST NOT be used to infer ownership. Rename and reidentification visit
|
||
every typed owner/path/leaf/purpose reference. Normal deletion of any such live
|
||
dependency removes the entire dependent link in the same transaction; it MUST
|
||
NOT shorten a path, substitute another reference instance or change purpose.
|
||
Retargeting a reference that invalidates a surviving link MUST refuse unless an
|
||
explicit repair batch makes the whole candidate valid. Undo restores complete
|
||
identities, links and authored source.
|
||
|
||
Admission permits at most 64reference occurrences per endpoint and counts all
|
||
authored reference-list entries against the caller's ordered-reference budget:
|
||
50,000 for the REST service and 500,000 for the desktop source workspace. Core
|
||
callers select their ParseLimits policy explicitly. Duplicate work definitions
|
||
do not erase this accounting. Cache capacity,
|
||
cache warmth, expansion order and diagram folding MUST NOT change admission.
|
||
Cache eviction is permitted; rejecting a valid address because a cache is full
|
||
is not.
|
||
|
||
Contextual diagnostics use separate precedence, exchange/common-work incidence
|
||
and caller coverage projections. Expand callee topology separately for each
|
||
reference path. Synthetic entry/exit connectivity is identifiable and MUST NOT
|
||
count as authored degree or satisfy authored guards. Missing or empty definitions
|
||
and expansion beyond 50,000 nodes/100,000 edges MUST report incomplete analysis;
|
||
they MUST NOT produce a guessed bypass or a complete-looking reachability result.
|
||
For X→R1.B plus P's A→B, an advisory may report two incoming authored links at
|
||
R1.B. It MUST NOT invalidate the model, require an invented Join, change the
|
||
standalone P or R2 diagnostics, or claim executable synchronization semantics.
|
||
Existing direct-only diagnostics remain unchanged.
|
||
|
||
4.3. Typed scenarios and reusable behavior
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ScenarioViewpoint is one of OperationalActivity (OA activity lifelines),
|
||
ParticipantInteraction (OA entity/actor/role lifelines), Functional (SA function
|
||
lifelines), BoundaryInterface (SA System/Actor lifelines), or MixedLegacy.
|
||
The first two are OA viewpoints; the next two are SA viewpoints. Lifeline
|
||
references MUST agree with that perspective. OperationalActivity messages use
|
||
Interactions; Functional messages use FunctionalExchanges. Participant views
|
||
may use their layer's work exchanges through effective performer allocation,
|
||
or participant boundary exchanges through the relevant ports. Corresponding
|
||
lifelines and endpoints MUST agree; a viewpoint is not a label that suppresses
|
||
reference checks.
|
||
|
||
Omitted schema-2 viewpoints hydrate as MixedLegacy in both source and JSON.
|
||
This preserves pre-extension mixed work/participant scenes without discarding
|
||
their lifelines or silently assigning a stricter meaning. MixedLegacy emits a
|
||
review warning. Source parsing also uses MixedLegacy when ``viewpoint`` is
|
||
omitted from a newly authored source-7 scenario; it does not infer a strict
|
||
viewpoint from the layer or lifelines. Write the intended viewpoint explicitly
|
||
when starting a scenario. For example, this new OA source project starts an
|
||
activity-based scenario whose lifelines and occurrences can be added later::
|
||
|
||
arcadia 7;
|
||
project response "Distress response" {
|
||
oa_scenario assessment "Assess the distress report" {
|
||
viewpoint OperationalActivity;
|
||
}
|
||
}
|
||
|
||
An empty scenario can produce completeness warnings while remaining editable.
|
||
The desktop's Behavior **New** flow asks authors to choose one of the layer's
|
||
two strict viewpoints explicitly. Authors can also select a strict viewpoint
|
||
after reviewing a legacy scene; canonical source then records that choice.
|
||
|
||
MessageKind is Asynchronous, Call, Reply, Create, Delete, or
|
||
``{ Timer { expression "after 5 s"; }; }``. A process/chain exchange
|
||
contribution MUST remain Asynchronous with no reply correlation. Call/reply,
|
||
creation/deletion and timer semantics belong to scenarios. Reply's ``reply_to``
|
||
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
|
||
warning; non-Reply messages MUST NOT have ``reply_to``.
|
||
|
||
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
|
||
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.
|
||
|
||
Each MessageValue is ``{ path [@parameter]; field @data_field; expression "value expression"; }``.
|
||
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
|
||
references, excluding the terminal field; direct parameters use ``[]``. Every
|
||
hop MUST follow Value storage through a named Record's effective fields. Reference
|
||
storage stops traversal. Operation Call accepts In/InOut and Reply accepts
|
||
Out/InOut/Return, interpreted from the provider's perspective. Nested field paths
|
||
inherit their direct parameter's direction. Unspecified direction warns.
|
||
At most one annotation for a pair is allowed. Omitted path defaults to ``[]``;
|
||
an ambiguous preserved legacy nested annotation warns ``message_value_ambiguous_path``
|
||
until an explicit path is selected. New graphical choices always identify a path.
|
||
Values never overwrite types or items. Expression text is descriptive, preserved
|
||
exactly and not evaluated; an empty expression warns.
|
||
|
||
4.3.1. Explicit interface-operation invocations
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
The optional Exchange occurrence field ``operation`` distinguishes ordinary
|
||
messages from explicit operation intent. Omitted or ``none`` retains ordinary
|
||
channel semantics and is omitted in canonical output. A present closed record
|
||
with absent/``none`` ``allocation`` means an explicitly unresolved operation.
|
||
A present ``allocation @service_operation`` selects that exact
|
||
InterfaceItemAllocation relation, not its item UUID, a name, a port or whichever
|
||
allocation happens to carry the same parameters. Thus parameterless Reset and
|
||
ReadStatus operations on one channel remain distinct maintained identities.
|
||
|
||
Operation intent is permitted only on SA BoundaryInterface scenario Call or
|
||
Asynchronous occurrences. A selected allocation MUST expose an Information
|
||
Operation item through the actual concrete Standard component ports used by the
|
||
invocation: receiver Provides, sender Requires a compatible interface exposing
|
||
that same allocation, using the normal interface inheritance rules. Containment
|
||
does not inherit participant interface roles onto a port. A separately allocated
|
||
same item is not the selected allocation. The actual channel traversal determines
|
||
direction, including an unoriented channel used in reverse. Call requires
|
||
Synchronous transmission; Asynchronous requires Asynchronous transmission;
|
||
Unspecified is incomplete and warns. A selected allocation without these proofs
|
||
is an error. Explicit unresolved intent remains editable with a located warning.
|
||
|
||
Reply MUST store no operation selection. It derives allocation, provider and
|
||
signature from its exact correlated Call, while independently satisfying the
|
||
existing reply order, reverse-participant and channel checks. It may reuse the
|
||
Call channel in reverse or use a separate explicit return channel. The separate
|
||
channel MUST carry the selected item or an admitted subtype and satisfy its own
|
||
actual endpoint contract, including for a parameterless/void return. The Reply
|
||
receiver need not provide the operation; the provider was established by the
|
||
Call. No operation or correlation may be guessed from similar names or fields.
|
||
|
||
Selected Call/Asynchronous values use only that operation's In/InOut signature;
|
||
Reply values use Out/InOut/Return. All ordinary nested-path and multiplicity rules
|
||
still apply. Unresolved operation intent preserves still-live expressions and
|
||
performs independent live-reference/path checks with an incomplete-signature
|
||
warning. It MUST NOT fall back to the union of items carried by the channel.
|
||
Selecting a new allocation validates all retained values and refuses incompatible
|
||
values without silently pruning them or creating defaults.
|
||
|
||
Deletion cleanup clears a deleted selected allocation to explicit unresolved
|
||
intent and preserves still-live values; it does not erase the Call or Reply.
|
||
The whole candidate MUST still satisfy independent channel contracts. Deleting
|
||
the sole allocation can therefore refuse while a boundary still carries its
|
||
now-unadmitted item. An explicit repair batch must address every affected channel,
|
||
including a separate Reply channel. If a surviving allocation admits the item,
|
||
deletion can succeed, but it MUST NOT select that surviving allocation as the
|
||
operation. Item/field deletion uses the normal proven-reference cleanup rules.
|
||
|
||
SA→OA transition of operation intent requires one explicit
|
||
``OperationOmission { source, rationale }`` per selected invocation. Rationale
|
||
MUST be nonempty. Missing, irrelevant, duplicate or wrong-direction decisions
|
||
are errors. Reply derives its Call's abstraction without a second operation
|
||
choice. The source model retains its operation; other facts and values are mapped
|
||
explicitly and the complete target is validated. The transition MUST NOT invent
|
||
OA technical ports, operation identities or functional refinement to avoid this
|
||
decision.
|
||
|
||
4.3.2. Scenario reuse
|
||
^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
ScenarioUse references an existing same-layer scenario and maps its lifelines
|
||
with ``bindings [ { referenced @callee_line; local @caller_line; } ];``.
|
||
Each binding is one-to-one and references a direct lifeline of the appropriate
|
||
scenario. Bound lifelines represent the same semantic object, or an explicitly
|
||
realized operational role. Strict viewpoints MUST agree; MixedLegacy retains
|
||
the compatibility case until reviewed. Missing bindings produce warnings.
|
||
Direct/transitive recursive scenario use is invalid; repetition uses a Loop
|
||
fragment instead. ScenarioUse owns neither its referenced scenario nor its
|
||
lifelines; deleting a use does not delete the reusable definition.
|
||
|
||
4.4. State vertices, events and transition contracts
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
StateKind comprises State, Mode, Initial, Final, Choice, Junction, Fork, Join,
|
||
ShallowHistory, DeepHistory, EntryPoint, ExitPoint and Terminate. Every vertex
|
||
belongs to a Region. Only State and Mode are stable states: only these may own
|
||
nested Regions, typed StateAction links, availability and scenario state
|
||
observations. Multiple sibling Regions describe orthogonal configurations.
|
||
EntryPoint and ExitPoint retain Region ownership; their boundary is that
|
||
Region's owning State/Mode or StateMachine. Their graphical symbols belong on
|
||
that boundary. This is Studio's explicit containment encoding.
|
||
|
||
Events are ordinary same-layer semantic elements, independent of diagram
|
||
placements. EventBody has exactly these constructors:
|
||
|
||
.. list-table:: Event definitions
|
||
:header-rows: 1
|
||
|
||
* - Constructor
|
||
- Fields and meaning
|
||
* - Signal
|
||
- ``items`` is a unique list of same-layer ExchangeItem references; empty is valid
|
||
* - Time
|
||
- ``kind`` is After or At; ``expression`` is descriptive time text
|
||
* - Change
|
||
- ``expression`` describes the Boolean condition becoming true
|
||
|
||
After measures relative time from activation of a transition's source state;
|
||
At describes an absolute instant. Empty Time/Change expressions are located
|
||
completeness warnings. The application does not execute expressions, fire
|
||
timers or transport signals. For example::
|
||
|
||
sa_event timeout "Recovery timeout" {
|
||
body { Time { kind After; expression "30 s"; }; };
|
||
}
|
||
sa_event recovered "Pressure recovered" {
|
||
body { Change { expression "pressure > 4 && status == \"Ready\""; }; };
|
||
}
|
||
|
||
StateTransition's ``triggers`` references Events or layer-appropriate work
|
||
(OA Activity / SA Function). Referenced work need not have the machine owner's
|
||
performer: external work can cause the observed transition. Multiple triggers
|
||
are alternatives. ``effects`` references work describing effects, without
|
||
executing it. Duplicate, missing, wrong-layer or wrong-kind references are
|
||
errors. The existing ``trigger``, ``guard`` and ``effect`` strings remain
|
||
authored prose; they MUST NOT be renamed, parsed as UUIDs or inferred by name.
|
||
|
||
With typed triggers, ``trigger`` adds descriptive information. With no typed
|
||
triggers and nonblank trigger prose, the transition has an unresolved
|
||
descriptive trigger and emits a warning. Both empty denotes completion from
|
||
a stable state or transient routing from a pseudostate. Deleting the final
|
||
typed trigger when prose is empty MUST leave an explicit descriptive reminder;
|
||
it MUST NOT silently create a completion transition. Guards/effect prose remain
|
||
unchanged. Signal payload references and typed effect references are pruned
|
||
when their targets are removed.
|
||
|
||
TransitionKind is External, Local or Internal. External leaves/re-enters the
|
||
affected configuration; a stable self-transition includes exit and entry
|
||
behavior. Internal requires the same stable source and target, preserves nested
|
||
configuration, and does not imply entry/exit. Local requires a composite stable
|
||
source and proper descendant target, preserving the source activation; an
|
||
EntryPoint also routes locally into its boundary. Local self/outside targets
|
||
are invalid. Other pseudostates route externally. Endpoints MUST share a layer
|
||
and StateMachine; crossing nested Regions within that machine is not generally
|
||
forbidden. A pseudostate self-transition is invalid.
|
||
|
||
A simple state's completion means entry/do behavior is complete. A composite
|
||
completes when its active Regions complete. Final completes its containing
|
||
Region; Terminate ends the containing machine's activation. These are modeling
|
||
meanings, not evidence of a running state-machine engine.
|
||
|
||
Missing connections/guards and unfinished initial/history paths produce
|
||
warnings, so an engineer can insert vertices before wiring them. Contradictory
|
||
upper cardinalities, forbidden directions/kinds and invalid references reject.
|
||
|
||
.. list-table:: Vertex connection constraints
|
||
:header-rows: 1
|
||
|
||
* - Vertex
|
||
- Structural restrictions
|
||
- Incomplete-model warnings
|
||
* - Initial
|
||
- At most one per Region; no incoming; at most one outgoing; no outgoing trigger or guard
|
||
- Missing initial/default entry or outgoing
|
||
* - Final / Terminate
|
||
- No outgoing or nested Region
|
||
- No incoming
|
||
* - Choice
|
||
- At most one incoming; outgoing transient alternatives
|
||
- Missing incoming, fewer than two outgoing, missing guard or else
|
||
* - Junction
|
||
- Transient routing, no implicit concurrency
|
||
- Missing side or ambiguous unguarded alternatives
|
||
* - Fork
|
||
- At most one incoming; outgoing stable targets in distinct orthogonal Regions
|
||
- Missing incoming or fewer than two outgoing
|
||
* - Join
|
||
- At most one outgoing; incoming stable sources in distinct orthogonal Regions
|
||
- Fewer than two incoming or missing outgoing
|
||
* - ShallowHistory
|
||
- At most one per Region; at most one fallback to a direct stable child of that Region; no fallback trigger/guard
|
||
- Missing fallback/default entry
|
||
* - DeepHistory
|
||
- At most one per Region; at most one fallback to a stable descendant of that Region; no fallback trigger/guard
|
||
- Missing fallback/default entry
|
||
* - EntryPoint
|
||
- Incoming from outside boundary, outgoing Local into it; at most one outgoing per destination Region
|
||
- Missing outgoing or incomplete affected-Region entry
|
||
* - ExitPoint
|
||
- Incoming from inside boundary; at most one outgoing External to outside
|
||
- Missing input/output; top-level exit is an exit endpoint, not implicit termination
|
||
|
||
Fork outputs and Join inputs MUST NOT carry guards or typed/descriptive
|
||
triggers. Their distinct orthogonal Regions are the first Regions beneath the
|
||
nearest common composite or machine, not merely each endpoint's immediate
|
||
parent. Choice/Junction routing expresses conditional alternatives. Retained
|
||
pseudostate entry/exit/do prose produces a warning and remains editable; it
|
||
does not become a typed state behavior. StateAction remains the maintained
|
||
reference for entry/do/exit work on stable states.
|
||
|
||
Other pseudostate outgoing segments MUST NOT introduce event/work triggers
|
||
or trigger prose. A Choice has at most one literal ``else`` guard; the tool
|
||
does not prove arbitrary guard expressions disjoint or exhaustive. Choice
|
||
expresses a dynamic decision after incoming effects; Junction expresses a
|
||
compound path selected by guards before traversing it. ShallowHistory remembers
|
||
the immediate state and uses default entry for deeper configuration;
|
||
DeepHistory remembers nested configuration. Fallback applies when no resumable
|
||
history exists. History is per Region, including top-level Regions in this
|
||
Studio profile; no running history state is persisted or synthesized.
|
||
|
||
4.5. Data contracts, specialization and interface allocation
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
ExchangeItem ``kind`` describes nature: Information, Material or Energy.
|
||
``mechanism`` is Unspecified, Flow, Event, Operation or SharedData. Unknown
|
||
mechanisms remain explicit Unspecified drafts with a warning. Material/Energy
|
||
with Event/Operation/SharedData warns for engineering review; it is not silently
|
||
reclassified. Empty Event notifications and void Operations are valid. An empty
|
||
carried/allocated Flow, SharedData or Unspecified item warns.
|
||
|
||
An Operation's directly owned DataFields are parameters. ``direction`` is
|
||
Unspecified, In, Out, InOut or Return, from the provider's perspective. At most
|
||
one effective parameter is Return. Unspecified parameters warn; non-operation
|
||
fields MUST use Unspecified. Nested record fields inherit direction from their
|
||
direct parameter when used in message paths, rather than storing context on a
|
||
shared type. ``storage`` is Value or Reference. Reference requires a named Record,
|
||
has no explicit default, and does not convey ownership or deletion of the type.
|
||
|
||
DataTypeDefinition has exactly the following constructors:
|
||
|
||
.. list-table:: Reusable definitions
|
||
:header-rows: 1
|
||
|
||
* - Constructor
|
||
- Required fields
|
||
* - Boolean
|
||
- None
|
||
* - Integer
|
||
- ``minimum``, ``maximum``: optional signed 64-bit integers
|
||
* - Real
|
||
- ``minimum``, ``maximum``: optional finite IEEE-754 binary64 values
|
||
* - String
|
||
- ``minimum_length``: u32; ``maximum_length``: optional u32
|
||
* - Enumeration
|
||
- ``literals``: unique nonempty, case-sensitive strings
|
||
* - Record
|
||
- ``supertype``: same-layer Record ref?
|
||
|
||
Bounds are inclusive and ordered; an absent bound means unbounded within the
|
||
represented numeric domain. Integer comparisons MUST NOT convert to binary64.
|
||
NaN, infinities, overflow and reversed bounds reject. String length counts Unicode
|
||
scalar values, not UTF-8 bytes or grapheme clusters. Enum defaults match exact
|
||
literals. Empty enum definitions remain incomplete drafts with a warning.
|
||
|
||
DataValue is a tagged scalar: ``{ Boolean true; }``, ``{ Integer 42; }``,
|
||
``{ Real 1.5; }``, ``{ String "value"; }`` or ``{ Enumeration "Ready"; }``.
|
||
There is no implicit numeric or string coercion. A type default is one compatible
|
||
scalar within its bounds. Record type defaults and record/object instance literals
|
||
are unsupported. A field default is absent (``none``) or a list of compatible
|
||
scalars with length inside its multiplicity. ``[]`` explicitly supplies an empty
|
||
collection and requires minimum 0, including Value Record fields; a nonempty
|
||
Record literal rejects. Reference fields MUST use ``none``. A one-valued scalar
|
||
field uses a one-value list. A named type default supplies an individual element's
|
||
default, not a collection or an implicit instance of a mandatory field.
|
||
|
||
Numeric types may carry unit text. Empty field units inherit the named type unit;
|
||
an explicit different unit warns when that type has a unit. Units on nonnumeric
|
||
fields/types warn and remain preserved. Unit strings never convert values or
|
||
establish dimensional compatibility. Expressions are not executed.
|
||
|
||
Record, ExchangeItem and Interface each permit one same-family, same-layer
|
||
supertype. Specialization is acyclic and separate from containment. Effective
|
||
fields are base fields followed by local fields, preserving original field UUIDs
|
||
and owners. Local names MUST NOT shadow inherited names. Item specialization
|
||
preserves base nature and any specified mechanism; an Unspecified base mechanism
|
||
may be refined. Deleting a derived record never deletes its base. Mandatory
|
||
Value-field cycles warn ``record_no_finite_value``; optional or Reference cycles
|
||
are valid without that warning. Traversal is cycle guarded and bounded; a payload
|
||
path budget failure is an explicit diagnostic, not silent truncation.
|
||
|
||
InterfaceItemAllocation is an ordinary identified relation from Interface to
|
||
ExchangeItem. It stores ``order`` and independent transmission/acquisition
|
||
protocols. Transmission is Unspecified, Synchronous, Asynchronous, Unicast,
|
||
Multicast or Broadcast; acquisition is Unspecified, Read or Accept. No protocol
|
||
combination is inferred from mechanism. Effective allocations are base-first,
|
||
then local ordered by (order, alias, UUID). A local item already allocated locally
|
||
or inherited is an error. Removing an allocation keeps its item and other
|
||
allocations; if live boundary compatibility would break, the transaction MUST
|
||
repair the affected contract explicitly or reject atomically. Artifacts can
|
||
reference the allocation identity independently of the global item.
|
||
|
||
An exchange carrying a specialized item satisfies a declaration of its base,
|
||
never the reverse. Standard provided/required compatibility uses explicit
|
||
interface ancestry. Identity/ancestry, not matching names, defines conformance.
|
||
The current typed function/component port contracts remain unchanged.
|
||
|
||
DataAssociation connects Record types without adding fields or transitively
|
||
carrying payload. Each named end has role, multiplicity and navigability. Source
|
||
multiplicity counts source instances per target instance and vice versa; it is
|
||
not a count of model elements. An end's navigable flag permits navigation toward
|
||
that end. Self-associations are valid; if both ends are navigable they require
|
||
distinct nonempty roles. Empty roles and duplicate role contracts warn, whereas
|
||
invalid ranges reject. Composition/shared aggregation, multiple inheritance,
|
||
redefinition, instance literals and arbitrary-precision decimal arithmetic are
|
||
outside this bounded contract.
|
||
|
||
This complete data contract example is also exercised through the REST API:
|
||
|
||
.. code-block:: text
|
||
|
||
arcadia 7;
|
||
project engineering_data "Engineering data" {
|
||
sa_data_type voltage "Voltage" {
|
||
definition { Real { minimum 0.0; maximum 48.0; }; };
|
||
default { Real 24.0; }; unit "V";
|
||
}
|
||
sa_data_type coordinate "Coordinate" {
|
||
definition { Record { supertype none; }; };
|
||
sa_data_field latitude "Latitude" { type_ref Real; }
|
||
}
|
||
sa_data_type located "Located asset" {
|
||
definition { Record { supertype @coordinate; }; };
|
||
sa_data_field supply "Supply" { type_ref { Named @voltage; }; }
|
||
}
|
||
sa_exchange_item navigate "Navigate" {
|
||
mechanism Operation;
|
||
sa_data_field origin "Origin" { type_ref { Named @coordinate; }; direction In; }
|
||
sa_data_field destination "Destination" { type_ref { Named @coordinate; }; direction In; }
|
||
sa_data_field accepted "Accepted" { type_ref Boolean; direction Return; }
|
||
}
|
||
sa_interface navigation "Navigation" {}
|
||
sa_interface monitoring "Monitoring" {}
|
||
interface_item_allocation nav_operation "Navigation operation" {
|
||
source @navigation; target @navigate; transmission Synchronous; acquisition Accept;
|
||
}
|
||
interface_item_allocation monitor_operation "Monitoring operation" {
|
||
source @monitoring; target @navigate; transmission Asynchronous; acquisition Read;
|
||
}
|
||
data_association location_link "Location relationship" {
|
||
source @coordinate; target @located;
|
||
source_role "location"; target_role "assets";
|
||
source_maximum 1;
|
||
}
|
||
}
|
||
|
||
5. Diagrams, artifacts, and cross-layer traceability
|
||
----------------------------------------------------
|
||
|
||
``diagram`` has name, identity, alias, description, ``layer`` (Oa by default),
|
||
``projection`` (Overview by default), and ``routes`` (empty list by default).
|
||
The string projections are Overview, Decomposition, Allocation,
|
||
FunctionalDataflow, Capabilities, and Traceability. StateMachine is a payload
|
||
constructor with one required ``machine`` reference. Traceability diagrams
|
||
can show both layers; other diagrams show their chosen layer.
|
||
|
||
Allocation is an architecture view: it shows participants and work, nests
|
||
allocated work under its performer, and displays interactions, functional
|
||
exchanges and boundary exchanges. FunctionalDataflow shows the work hierarchy
|
||
and its exchanges. Capabilities shows participants, roles, missions and
|
||
capabilities with their involvement, exploitation, include, extend and
|
||
generalization links. Decomposition and Overview retain general containment;
|
||
Overview also exposes all relationships. These string projections hide
|
||
inapplicable placements without deleting them or changing semantic records.
|
||
|
||
A StateMachine projection MUST reference an existing StateMachine in the
|
||
diagram's layer. Its placements MUST refer to that machine, its Regions, or
|
||
its state vertices, including nested Regions and vertices. Events, other
|
||
machines and their members, and unrelated semantic elements are not valid
|
||
placements in this view. Empty and partial state views are valid; neither
|
||
creating nor reading a view synthesizes semantic elements or placements.
|
||
Changing an existing diagram to StateMachine, or changing its machine, MUST
|
||
remove or relocate incompatible placements in the same transaction. Context
|
||
errors use ``state_diagram_context``; incompatible placements use
|
||
``state_diagram_member``. Neither case silently hides invalid members.
|
||
|
||
This complete source example places one state from an existing machine:
|
||
|
||
.. code-block:: text
|
||
|
||
arcadia 7;
|
||
project operating "Operating modes" {
|
||
oa_entity crew "Crew" {}
|
||
oa_state_machine modes "Modes" { parent @crew; }
|
||
oa_region main "Main region" { parent @modes; }
|
||
oa_state ready "Ready" { parent @main; }
|
||
diagram mode_view "Operating modes" {
|
||
layer Oa;
|
||
projection { StateMachine { machine @modes; }; };
|
||
}
|
||
node ready_view { diagram @mode_view; element @ready; }
|
||
}
|
||
|
||
The JSON projection is
|
||
``{"StateMachine":{"machine":"11111111-1111-4111-8111-111111111111"}}``,
|
||
where the UUID is the referenced machine's identity. A bare ``"StateMachine"``,
|
||
a missing or null ``machine``, an invalid UUID, or additional payload fields
|
||
is malformed. Existing projections retain their string representation, for
|
||
example ``"Overview"`` in JSON and ``projection Overview;`` in source.
|
||
|
||
Ports are boundary anchors of visible owners, with their existing
|
||
semantic identity. An explicitly placed port is not rendered as a separate
|
||
large node. Functional exchanges use their declared source/target ports;
|
||
boundary exchanges attach to their participant ports even if those ports have
|
||
no separate placement. Collapsing an owner hides its interior; projected links
|
||
may terminate at a visible ancestor without creating a new port or exchange.
|
||
|
||
``node`` has an alias and identity but no display-name string. Required fields
|
||
are ``diagram`` and ``element`` references. Optional fields are ``position``
|
||
(record with x/y, default 0/0), ``size`` (width/height, default 224/94), and
|
||
``collapsed`` (false), and ``port_anchors`` (empty list). Node identity is
|
||
independent of its semantic element.
|
||
Coordinates are absolute diagram coordinates. Placement does not alter parent,
|
||
allocation, or realization. Hiding an element from a diagram must remain
|
||
distinguishable from deleting it from the model.
|
||
Changing a node's diagram preserves the placement identity, alias, coordinates,
|
||
size, collapse state, manual port anchors, and attached artifacts. The destination
|
||
must accept the element's layer, satisfy StateMachine membership when applicable,
|
||
and must not already contain another placement of that element.
|
||
|
||
Each ``port_anchors`` entry is a PortAnchor record with required ``port``
|
||
reference, ``side`` (Left, Right, Top, or Bottom), and ``offset`` (finite
|
||
binary32 from 0 through 1). It has no separate identity or alias. The port MUST
|
||
be an existing Port directly owned by the placement's ``element``. A port MAY
|
||
have one manual anchor per placement; different diagrams MAY position it
|
||
independently. List order is preserved but has no positional meaning.
|
||
|
||
``offset`` measures a fraction of the complete projected owner edge, from top
|
||
on Left/Right or from left on Top/Bottom. Zero and one denote its corners.
|
||
The side is presentation data and MUST NOT change the port's contract,
|
||
orientation, ownership, allocations, or connected exchanges. Absent anchors use
|
||
automatic positioning. Empty lists are omitted in canonical JSON/source;
|
||
earlier schema-3 input without this field hydrates as ``[]``.
|
||
|
||
.. code-block:: text
|
||
|
||
node actor_view {
|
||
diagram @architecture; element @vessel;
|
||
port_anchors [{ port @communication; side Top; offset 0.25; }];
|
||
}
|
||
|
||
``SetPortAnchor { diagram, node, anchor }`` upserts by port identity and retains
|
||
unrelated entries. ``RemovePortAnchor { diagram, node, port }`` restores
|
||
automatic positioning; it is a no-op only for an existing direct child port
|
||
of that placement. Unknown fields, duplicate port references, non-port or
|
||
foreign-owner references, and invalid offsets are structural errors. Each
|
||
anchor counts as one record against ``ParseLimits.max_records``.
|
||
|
||
These commands use the same atomic history, conditional REST transactions, and
|
||
source writeback as other presentation edits. Source references resolve across
|
||
files, and anchor comments follow port identity. Reidentifying a port updates
|
||
anchor references; deleting it removes its anchors. Reparenting MUST repair
|
||
old-owner anchors in the same transaction, for example by removing them before
|
||
the Reparent command. Moving, resizing, arranging, or folding an owner retains
|
||
its authored sides and fractions. Frozen schema-1/schema-2 readers do not accept
|
||
``port_anchors``; their explicit migration supplies an empty list.
|
||
|
||
Each ``routes`` entry is an EdgeRoute record with a required ``edge`` reference
|
||
to an existing Relation or Trace, ``waypoints`` (default ``[]``), and ``label``
|
||
(default ``none``). Route records have no separate UUID or alias. An edge occurs
|
||
at most once in a diagram's route list; different diagrams MAY store independent
|
||
routes for the same edge. List order and explicit empty entries are retained by
|
||
source and JSON round trips, although list order has no routing meaning. Edges
|
||
need not currently be visible in their diagram.
|
||
|
||
.. code-block:: text
|
||
|
||
routes [
|
||
{ edge @report_exchange;
|
||
waypoints [{ x 420; y 260; }, { x 690; y 260; }];
|
||
label { fraction 0.55; offset { x 0; y -16; }; };
|
||
}
|
||
];
|
||
|
||
Waypoints are pinned absolute diagram positions in source-to-target traversal
|
||
order; at most 128 are allowed per edge. Computed endpoints and automatic elbows
|
||
MUST NOT be persisted as authored waypoints. A label record requires both
|
||
``fraction`` (finite binary32 from 0 through 1, measured along the computed
|
||
polyline's arc length) and ``offset`` (a relative x/y diagram displacement).
|
||
All position/displacement components obey the coordinate bounds in section 2.
|
||
An absent label uses automatic placement. Unknown fields, missing required
|
||
nested fields, duplicate route edges, non-edge references and invalid numbers
|
||
are structural errors. A pinned point that obstructs routing remains stored;
|
||
geometric routing difficulty is reported separately from structural validity.
|
||
Each EdgeRoute counts as one record against ``ParseLimits.max_records``; pinned
|
||
points are bounded by the per-route limit and aggregate input byte limits.
|
||
|
||
``SetEdgeRoute { diagram, route }`` upserts an entry by edge identity, retaining
|
||
the order and contents of unrelated entries. ``RemoveEdgeRoute { diagram, edge }``
|
||
removes it; removing an absent entry is a no-op for an existing diagram and edge.
|
||
The latter is the Reset routing operation. Either command participates in the
|
||
same atomic transactions, validation and undo as other model edits. Deleting a
|
||
relation or trace removes its routes in every diagram; reidentifying it updates
|
||
route references without changing geometry. Folding, hiding, changing projection
|
||
or relocating placements MUST NOT erase routing metadata. Group movement
|
||
translates pins when both actual endpoint owners move by the same delta; label
|
||
offsets remain relative. Raw ``EditNode`` and source position edits are exact
|
||
record edits and do not implicitly translate pins.
|
||
|
||
This is an additive schema-3 field. Earlier schema-3 JSON/source that omits
|
||
``routes`` loads as an empty list. Frozen schema-1 and schema-2 readers do not
|
||
accept this new field; migration creates empty route lists. Source projects keep
|
||
routes in their owning diagram declaration/file, resolve ``edge @alias`` across
|
||
files, and retain route-entry comments by referenced edge identity when entries
|
||
are reordered. The existing REST transaction endpoint accepts the same externally
|
||
tagged command records with UUID references and conditional ETags; no separate
|
||
routing endpoint or UI-only routing model exists.
|
||
|
||
``artifact`` has name, identity, alias, description, required ``owner`` ref,
|
||
``relation`` (References, Satisfies, Verifies, Implements, DerivedFrom;
|
||
default References), ``uri`` (default empty), ``revision`` (optional string),
|
||
and ``fragment`` (optional string). The two optional strings default to none.
|
||
URI must be nonempty, have no whitespace/backslash/control characters, and
|
||
use valid percent escapes. The owner is another existing model object.
|
||
Validation MUST NOT fetch the URI. Revision and fragment are retained verbatim.
|
||
|
||
``trace`` has name, identity, alias, description, required ``oa`` and ``sa``
|
||
endpoint references, ``kind`` (default Refinement), and ``baseline`` (default
|
||
none). Endpoints are canonical: SA realizes OA, regardless of which side
|
||
initiated creation. Trace does not change endpoint identity or containment.
|
||
Multiple distinct counterparts are permitted; duplicate endpoint/kind triples
|
||
are invalid.
|
||
|
||
.. list-table:: Trace kinds
|
||
:header-rows: 1
|
||
:widths: 23 77
|
||
|
||
* - Kind
|
||
- OA → SA endpoint types
|
||
* - Refinement
|
||
- Activity → Function
|
||
* - Participant
|
||
- Entity/Actor → System/Actor
|
||
* - Capability
|
||
- Operational Capability → System Capability
|
||
* - Mission
|
||
- Operational Mission → System Mission
|
||
* - Exchange
|
||
- Interaction → FunctionalExchange, or CommunicationMean → BoundaryExchange
|
||
* - Sequence
|
||
- Process → FunctionalChain, or paired occurrence contributions directly owned by Process / FunctionalChain
|
||
* - Item
|
||
- Same shared kind: ExchangeItem, DataType, DataField, Interface, or Port
|
||
* - Scenario
|
||
- Same shared kind: Scenario, Lifeline, or Occurrence
|
||
* - State
|
||
- Same shared kind: StateMachine, Region, any StateKind vertex, or Event
|
||
* - Manual
|
||
- Engineer-defined relationship between OA/SA elements or relations
|
||
|
||
A nonempty baseline retains the required prose records ``oa { name "...";
|
||
description "..."; }; sa { name "..."; description "..."; };`` and optionally
|
||
``semantic`` (default none), defined below. The original prose records and typed
|
||
semantic facts are distinct review histories. Importing an older prose baseline
|
||
MUST NOT fabricate semantic acknowledgements. Neither history is a full model
|
||
snapshot, structural synchronization, or a lossless inverse transition.
|
||
Explicit counterpart creation, linking, comparison, and reviewed property
|
||
update may start in either layer. Ordinary edits MUST NOT automatically
|
||
overwrite the counterpart. Deletion MUST NOT silently cascade across layers.
|
||
|
||
Operational Capability normally creates a System Capability. Operational Mission
|
||
and System Mission are default counterparts in both directions and use Mission
|
||
traces. An explicit Operational Capability ↔ System Mission mapping remains
|
||
supported with a Manual trace; a uniquely linked such counterpart is reused
|
||
instead of silently creating a different mapping. Required/subtree process and
|
||
chain transitions include their contextual links, owned contributions and
|
||
referenced dependencies. New process/chain contribution mappings use Sequence
|
||
traces; older Scenario-kind occurrence mappings remain accepted. The current
|
||
prose baseline alone does not reconcile later topology changes.
|
||
|
||
In the prose-only workflow, name and description are compared independently
|
||
against each endpoint's last-reviewed baseline. An unchanged source MUST NOT overwrite an accepted
|
||
different target value. A source-only change proposes an update; different
|
||
changes on both sides require an explicit decision to take the source, keep
|
||
the target, or enter a merged value. An explicit decision records both current
|
||
values as reviewed, even when they differ. A target-only edit is preserved
|
||
without advancing that field's baseline, so it remains eligible to propagate
|
||
in the reverse direction. Equal current values can be recorded as converged.
|
||
|
||
5.1. Typed semantic review facts
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
``baseline.semantic`` is either none or ``{ facets [facet, ...]; }``.
|
||
Each facet is a closed, self-tagged typed record, not a free-form path/value
|
||
entry. List position does not identify a facet. A scalar fact is exactly
|
||
``{ Family { Leaf { oa observation; sa observation; }; }; }``. Each observation
|
||
is either ``NotApplicable`` or ``{ Value value; }``, with the value type fixed
|
||
by Family/Leaf. Both sides are always canonical OA/SA, even during reverse review.
|
||
|
||
``{ Value none; }`` means an applicable optional field was absent;
|
||
``NotApplicable`` means the field's branch or record was not applicable.
|
||
An absent facet means Unreviewed. These meanings MUST NOT be conflated. Each
|
||
side is compared with its own last-reviewed value; deliberately unequal values
|
||
can be reviewed and unchanged. Reviewing one minimum does not acknowledge a
|
||
maximum, unit, default, header or referenced type definition.
|
||
|
||
Historical facts are independently acknowledged observations. They need not
|
||
compose one coherent former model: two bounds can have different review times.
|
||
They MAY outlive the endpoint's former record family, constructor and referenced
|
||
objects. Historical admission checks their closed payload types, finite values,
|
||
text, keys and uniqueness; it MUST NOT require a currently existing referenced
|
||
object or current family applicability. In contrast, a new graphical or planned
|
||
resolution MUST address the appropriate current record family and have at least
|
||
one currently applicable side. Both-side NotApplicable facts are invalid persisted
|
||
acknowledgements. A grouped constructor decision retires such obsolete branch facts.
|
||
|
||
The following table is the exhaustive scalar catalog. ``T?`` denotes an optional
|
||
T, ``T[]`` a list, and ``Id`` a historical UUID. Existing enum and typed payload
|
||
definitions in sections 3–4 apply. Every listed leaf wraps ``{ oa ...; sa ...; }``.
|
||
|
||
.. list-table:: Closed scalar semantic facets
|
||
:header-rows: 1
|
||
:widths: 15 85
|
||
|
||
* - Family
|
||
- Leaves and observation value types
|
||
* - Header
|
||
- Name, Description: string; Parent: Id?
|
||
* - ExchangeItem
|
||
- Nature: ExchangeItemKind; Mechanism: ExchangeMechanism; Supertype: Id?
|
||
* - Interface
|
||
- Supertype: Id?
|
||
* - Data
|
||
- Constructor: DataConstructor; IntegerMinimum, IntegerMaximum: i64?; RealMinimum, RealMaximum: finite f64?; StringMinimumLength: u32; StringMaximumLength: u32?; RecordSupertype: Id?; Default: DataValue?; Unit: string
|
||
* - Field
|
||
- Type: TypeRef; Minimum: u32; Maximum: u32?; Unit: string; Direction: ParameterDirection; Storage: FieldStorage; Default: DataValue[]?
|
||
* - Port
|
||
- Constructor: PortConstructor; ComponentKind: ComponentPortKind; Orientation: ComponentPortOrientation; LegacyDirection: PortDirection; LegacyInterface: Id?
|
||
* - Scenario
|
||
- Viewpoint: ScenarioViewpoint; Context: Id?; Precondition, Postcondition: string
|
||
* - Lifeline
|
||
- Represented: Id?
|
||
* - Occurrence
|
||
- Constructor: OccurrenceConstructor; Precondition, Postcondition: string; Exchange, Sender, Receiver: Id?; MessageKind: MessageConstructor; TimerExpression: string; ReplyTo, Action, ActionLifeline: Id?; ControlKind: ControlKind; Sequence, Scenario, State, StateLifeline: Id?; FragmentOperator: FragmentOperator; BranchGuard: string
|
||
* - Event
|
||
- Constructor: EventConstructor; TimeKind: TimeEventKind; TimeExpression, ChangeExpression: string
|
||
* - State
|
||
- Kind: StateKind; Entry, Exit, DoActivity: string
|
||
* - Constraint
|
||
- Expression: string
|
||
* - Relation
|
||
- Source, Target: Id; AllocationOrder: u32; Transmission: TransmissionProtocol; Acquisition: AcquisitionProtocol; SourceRole, TargetRole: string; SourceMinimum, TargetMinimum: u32; SourceMaximum, TargetMaximum: u32?; SourceNavigable, TargetNavigable: bool; SourcePort, TargetPort: Id; Oriented: bool; ExtendCondition, SequenceGuard: string; TransitionKind: TransitionKind; Trigger, Guard, Effect: string; StateActionPhase: StateActionKind
|
||
|
||
5.2. Members, rows, order, and attached records
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
The remaining facet forms are closed records. ``keys`` means ``{ oa key-or-none;
|
||
sa key-or-none; }``; at least one key MUST be present. ``review`` means the same
|
||
required OA/SA observation pair used above.
|
||
|
||
.. list-table:: Closed keyed and ordered semantic facets
|
||
:header-rows: 1
|
||
:widths: 17 45 38
|
||
|
||
* - Outer tag
|
||
- Required fields
|
||
- Key / reviewed value type
|
||
* - Member
|
||
- collection; keys; review
|
||
- Id / bool
|
||
* - Order
|
||
- collection; review
|
||
- No keys / Id[]
|
||
* - Literal
|
||
- keys; review
|
||
- Exact case-sensitive string / bool
|
||
* - Annotation
|
||
- keys; review
|
||
- ``{ path Id[]; field Id; }`` / MessageValue?
|
||
* - Binding
|
||
- keys; review
|
||
- Referenced lifeline Id / LifelineBinding?
|
||
* - Child
|
||
- keys; review
|
||
- Direct child Id / bool
|
||
* - Incident
|
||
- keys; end; review
|
||
- Relation Id, end Source or Target / bool
|
||
* - Artifact
|
||
- keys; review
|
||
- Artifact Id / nested artifact facet below
|
||
|
||
Member.collection is exactly Steps, FragmentBranches, FunctionInputItems,
|
||
FunctionOutputItems, SignalItems, ExchangeItems, TransitionTriggers,
|
||
TransitionEffects or Constrained. Order.collection is exactly Steps or
|
||
FragmentBranches. Order is independent of membership and MUST contain each
|
||
surviving member exactly once when applied. Membership Keep does not refresh
|
||
order history. An automatic insertion requires a unique unchanged mapped anchor;
|
||
ambiguous insertion or conflicting inferred orders requires an explicit final
|
||
target order. Independent removals can filter the order to surviving members.
|
||
|
||
Annotation identity is the complete ``(path, field)`` pair. Its MessageValue
|
||
payload contains ``path``, ``field`` and ``expression``; the payload key MUST
|
||
match its side's selector key. Binding payloads contain ``referenced`` and
|
||
``local``; ``referenced`` MUST match that side's key. Each row is one atomic
|
||
fact. Changing its key is an explicit old-row removal/new-row addition, not an
|
||
expression-only edit. Defaults containing repeated DataValues are atomic optional
|
||
vectors because those values have no stable member identity.
|
||
|
||
Artifact.review is ``{ Leaf { oa observation; sa observation; }; }`` where Leaf
|
||
is Presence: bool; Name, Description or Uri: string; Owner: Id;
|
||
Relation: ArtifactRelation; Revision or Fragment: string?. Metadata decisions
|
||
are authorized on the artifact's attachment in the initial project. An explicit
|
||
Owner candidate may move a target-only link and record its resulting Owner and
|
||
other selected metadata. Presence remains relative to the trace owner. Subsequent
|
||
metadata decisions require its new owner trace; historical facts remain attached
|
||
to the trace that recorded them. No review fetches artifact content.
|
||
|
||
Duplicate scalar selectors and keyed selectors that occupy the same OA slot or
|
||
the same SA slot are invalid, even when the other side's key differs. Historical
|
||
order vectors MUST NOT repeat an Id. Review history has a limit of 16384 facets,
|
||
128 Ids in an annotation path, 1000000 bytes per string, and 1000000 traversal
|
||
steps per baseline. Exceeding these implementation work limits produces a
|
||
diagnostic; truncation MUST NOT be accepted as a complete review.
|
||
|
||
5.3. Constructor groups and decisions
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Persisted constructors are discriminator words only:
|
||
|
||
* DataConstructor: Boolean, Integer, Real, String, Enumeration, Record.
|
||
* PortConstructor: FunctionInput, FunctionOutput, Component, Legacy.
|
||
* OccurrenceConstructor: Exchange, Action, Control, SequenceReference,
|
||
ScenarioUse, State, Fragment, Branch.
|
||
* EventConstructor: Signal, Time, Change.
|
||
* MessageConstructor: Asynchronous, Call, Reply, Create, Delete, Timer.
|
||
|
||
When a discriminator has no prior fact after explicit resets, both current sides
|
||
are applicable and equal, and the proposed target discriminator is unchanged,
|
||
KeepTarget, TakeSource or Candidate acknowledges only that discriminator.
|
||
It MUST NOT copy a constructor payload, acknowledge unselected descendants or
|
||
retire branch history. Descendant facets may be independently selected in the
|
||
same review; their decisions retain their own scopes and final-value audits.
|
||
Candidate records still MUST NOT change an unselected facet. Missing applicability
|
||
on either side does not qualify as an equal discriminator acknowledgement.
|
||
|
||
A grouped constructor resolution uses a transient typed target record, then
|
||
records the discriminator and each acknowledged descendant as separate facts.
|
||
It MUST NOT persist a second whole constructor payload overlapping those leaves.
|
||
Data includes its branch fields, literals and coupled default, but excludes Unit.
|
||
Port includes its contract, Legacy fields and item members. Event includes its
|
||
branch fields and Signal items. Occurrence includes its variant payload, members,
|
||
order, annotations and bindings, but excludes outer Precondition/Postcondition.
|
||
MessageKind includes its discriminator and dependent TimerExpression. State.Kind
|
||
is its own structural facet even though it changes the element's derived kind.
|
||
Other dependent changes caused by preparation remain explicit impacts.
|
||
|
||
A grouped constructor Keep requires an actual discriminator proposal or a
|
||
discriminator change since its prior review. Repeating Keep on an already reviewed
|
||
unequal pair MUST NOT acknowledge unrelated bound/default drift. A real target switch may
|
||
reconsider a previously kept difference. When the target already has the proposed
|
||
constructor, reconciliation MUST preserve target-only members rather than replace
|
||
its whole list. Removed branch facts participate in agreement as NotApplicable;
|
||
facts with neither side remaining applicable are retired.
|
||
|
||
Semantic review supports these explicit decisions in either direction:
|
||
|
||
* KeepTarget records the current source and retained target values for only the
|
||
selected facet, or the explicitly displayed constructor group.
|
||
* TakeSource maps the selected source value through the frozen correspondence and
|
||
applies only that facet's delta. Unrelated target edits and target-only collection
|
||
members, rows, children and artifacts remain intact. Removing membership unlinks
|
||
the target member; it does not authorize deleting the target semantic object.
|
||
* Candidate supplies final existing typed Element, Relation or Artifact records.
|
||
Only selected facets may differ from the result. Identity, alias and layer are
|
||
protected. New artifact creation requires a complete candidate and review of
|
||
every introduced metadata facet; removal also reviews the metadata retirement.
|
||
|
||
Headers have explicit semantic Name/Description facets; the original prose-only
|
||
workflow remains supported with its own baseline. Ordinary source editing can
|
||
explicitly edit a valid baseline; neither baseline format attests that a human
|
||
performed a particular review workflow.
|
||
Decision requests, final candidates and prepared impacts are transient editor/API
|
||
data. Source persists the resulting ordinary model and typed baseline facts;
|
||
it does not persist KeepTarget/TakeSource/Candidate as extra facet fields.
|
||
|
||
5.4. Correspondence, agreement, and atomic preparation
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Correspondence is an explicit canonical OA-to-SA Id map, including historical
|
||
deleted IDs. Names and aliases MUST NOT guess correspondence. Reverse application
|
||
uses its inverse and rejects ambiguity. Multiple trace kinds for one endpoint
|
||
pair require an explicit trace selection. Changing a keyed pairing requires an
|
||
explicit reset naming the prior selector; old pairs are never silently replaced.
|
||
If a previously paired member or branch disappears on one side, retain its pair
|
||
with the absent/NotApplicable observation, suppressing a redundant one-sided
|
||
projection. A newly appearing pair still requires reset of old one-sided history.
|
||
|
||
All selected source proposals use one immutable initial project. Resets precede
|
||
catalog and constructor-scope derivation. Many sources may affect one target only
|
||
when their desired values agree on every actual canonical target slot, including
|
||
removals and members introduced by another proposal. Child membership and the
|
||
actual child's Parent share one slot; incidents share the relation's Source or
|
||
Target endpoint; artifact Presence and Owner share the actual artifact owner slot.
|
||
Conflicting desired values MUST reject independently of request order.
|
||
|
||
Materialize the agreed writes once, then audit each desired selected value.
|
||
Prepare one ordinary complete Command batch and compare its actual project with
|
||
the explicitly reviewed candidate. Additional cleanup, such as inherited message
|
||
annotation pruning, is reported as exact object ``before``/``after`` typed records
|
||
(or absence for creation/deletion). Every induced impact requires explicit review;
|
||
an accepted impact still MUST NOT contradict a selected Keep/Take. Repeat the
|
||
selected-value audit after preparation. Baseline updates belong to the same atomic
|
||
transaction and source-preserving writeback as model edits.
|
||
|
||
A plan's base fingerprint detects a stale model; its prepared fingerprint checks
|
||
candidate consistency. The plan is client-supplied data, not an authenticated
|
||
receipt or proof of its original decisions. Applying it validates the complete
|
||
ordinary candidate and preserves generated identities; it does not re-run its
|
||
request to generate new identities. Hosted clients additionally use the revision
|
||
preconditions defined in ``api.rst``. Invalid/stale plans or failed source writeback
|
||
leave the accepted model, source, baseline, revision and history unchanged.
|
||
|
||
Own drift and linked impacts are separate, with incomplete review explicitly
|
||
visible. Absent facts MUST NOT produce a falsely complete Unchanged rollup.
|
||
Shared data/interface/event definitions are reviewed on their own traces; their
|
||
bounded derived impact walk follows reusable definitions and interface allocations,
|
||
not arbitrary architectural neighborhoods, and does not copy them into every
|
||
referrer's baseline. Its limits are 4096 objects per side and 32768 edges; exhaustion
|
||
is a diagnostic. Successful review remains one undoable transaction. Replanning
|
||
unchanged, already acknowledged leaf facts is a no-op only while their requests
|
||
remain applicable. A completed constructor switch or first acknowledgement of an
|
||
equal discriminator MUST be removed from subsequent requests; repeating it when
|
||
no switch remains is rejected. After an artifact moves to another owner,
|
||
metadata review through the old owner's trace is no longer
|
||
applicable and is rejected. An old plan becomes stale after an actual committed
|
||
change.
|
||
|
||
5.5. Source examples and historical token rules
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
This valid source records deliberately different constructor/unit observations.
|
||
Its historical integer minimum is absent; the Real side has no integer branch::
|
||
|
||
arcadia 7;
|
||
project reviewed_dimensions "Reviewed dimensions" {
|
||
oa_data_type oa_dimension "Operational distance" {
|
||
definition { Integer { minimum 0; maximum 10; }; };
|
||
unit "m";
|
||
}
|
||
sa_data_type sa_dimension "System distance" {
|
||
definition { Real { minimum 0; maximum 20; }; };
|
||
unit "ft";
|
||
}
|
||
trace dimension_review "Dimension review" {
|
||
oa @oa_dimension;
|
||
sa @sa_dimension;
|
||
kind Item;
|
||
baseline {
|
||
oa { name "Approved OA name"; description ""; };
|
||
sa { name "Approved SA name"; description ""; };
|
||
semantic { facets [
|
||
{ Data { Constructor { oa { Value Integer; }; sa { Value Real; }; }; }; },
|
||
{ Data { IntegerMinimum { oa { Value none; }; sa NotApplicable; }; }; },
|
||
{ Data { Unit { oa { Value "m"; }; sa { Value "ft"; }; }; }; }
|
||
]; };
|
||
};
|
||
}
|
||
}
|
||
|
||
Historical Id slots require ``uuid "..."`` even if the object still exists.
|
||
Only typed reference slots inside ``baseline.semantic`` accept that atom.
|
||
For example, the following is a valid historical facet value, including a deleted
|
||
named type; ``none`` and bare enum Boolean retain their different typed meanings::
|
||
|
||
{ Field { Type {
|
||
oa { Value { Named uuid "40000000-0000-4000-8000-000000000090"; }; };
|
||
sa { Value Boolean; };
|
||
}; }; }
|
||
|
||
A qualified annotation uses the same historical UUID atoms in its key and payload.
|
||
This complete facet records one old row and an applicable absent target row::
|
||
|
||
{ Annotation {
|
||
keys {
|
||
oa {
|
||
path [uuid "40000000-0000-4000-8000-000000000091"];
|
||
field uuid "40000000-0000-4000-8000-000000000092";
|
||
};
|
||
sa none;
|
||
};
|
||
review {
|
||
oa { Value {
|
||
path [uuid "40000000-0000-4000-8000-000000000091"];
|
||
field uuid "40000000-0000-4000-8000-000000000092";
|
||
expression "latitude + 1";
|
||
}; };
|
||
sa { Value none; };
|
||
};
|
||
}; }
|
||
|
||
Historical enums require bare words. Ordinary strings, including UUID-looking
|
||
units, literal keys and expressions, require quoted strings and remain text
|
||
during identity remapping. ``@alias`` is invalid anywhere inside a semantic
|
||
baseline. Live parents, trace endpoints and all other live references still
|
||
require ``@alias`` and MUST NOT accept the historical UUID atom.
|
||
|
||
The following substitutions in these examples are invalid:
|
||
|
||
* ``oa "NotApplicable";`` or ``oa { Value "Integer"; };`` in the Constructor
|
||
review: enum observations require bare words of the correct typed enum.
|
||
* ``Named "40000000-0000-4000-8000-000000000090";`` or ``Named @oa_dimension;``:
|
||
a historical Id requires the explicit UUID atom.
|
||
* ``Unit { oa { Value uuid "40000000-0000-4000-8000-000000000090"; }; ... }``:
|
||
a text field cannot hold a reference atom.
|
||
* Repeating the Unit facet, adding an unknown leaf, or supplying a numeric bound
|
||
as a quoted string: closed typed admission rejects the whole candidate.
|
||
* Changing only the annotation payload's field UUID suffix from 092 to 093,
|
||
leaving the key at 092: the row's key and payload disagree.
|
||
* Changing the document header to ``arcadia 4;`` while retaining ``semantic``:
|
||
the frozen earlier schema does not admit a future baseline shape.
|
||
|
||
6. Text grammar and resolution
|
||
------------------------------
|
||
|
||
The input is UTF-8 without a byte-order mark. LF, CR, space, and tab separate
|
||
tokens. ``//`` starts a comment through the next LF or end of input. Quoted
|
||
strings use JSON string escaping, including ``\n``, ``\r``, ``\t``, ``\\``,
|
||
and Unicode escapes. Literal unescaped newlines inside strings are invalid.
|
||
Numbers use JSON decimal/exponent syntax; NaN, infinity, hexadecimal numbers,
|
||
leading plus signs, and leading zeroes are invalid.
|
||
|
||
A small model may begin with engineering declarations alone. This complete
|
||
source describes two participants, their work, responsibility and an exchange::
|
||
|
||
arcadia 7;
|
||
project distress "Distress response" {
|
||
oa_actor vessel "Vessel in distress" {}
|
||
oa_entity rescue "Rescue coordination" {}
|
||
oa_activity report "Report distress" {}
|
||
oa_activity assess "Assess incident" {}
|
||
allocation vessel_reports "Crew reports" { source @vessel; target @report; }
|
||
allocation rescue_assesses "Team assesses" { source @rescue; target @assess; }
|
||
interaction distress_report "Distress report" { source @report; target @assess; }
|
||
}
|
||
|
||
No diagram, placement, empty description or explicit root parent is required.
|
||
The accepted source adds identities; keep those clauses during later edits.
|
||
Changing ``"Assess incident"`` changes the display name while ``@assess`` still
|
||
resolves to the same activity. Behavior-coverage warnings permit this intermediate
|
||
model to be saved. Allocation remains explicit and distinct from decomposition.
|
||
|
||
Aliases match ``[A-Za-z_][A-Za-z0-9_]*``. The following aliases are reserved:
|
||
arcadia, project, id, oa, sa, element, relation, diagram, node, artifact,
|
||
trace, body, alias, name, description, parent, from, to, entity, actor,
|
||
activity, capability, process, allocation, interaction, contribution,
|
||
realization, position, steps, true, false, null. Other field/constructor
|
||
spellings can be used in alias positions because references begin with ``@``.
|
||
|
||
The grammar below uses ``*`` for repetition and ``?`` for optional syntax.
|
||
``element-kind`` and ``relation-kind`` are exactly the corresponding declaration
|
||
keywords listed above. Typed field
|
||
sets and enum constructors are closed by sections 3–5.
|
||
|
||
.. code-block:: text
|
||
|
||
document = "arcadia" "7" ";" project
|
||
project = "project" alias string identity? "{" project-entry* "}"
|
||
project-entry = "description" string ";" | declaration
|
||
declaration = element
|
||
| (relation-kind | "diagram" | "artifact" | "trace")
|
||
alias string identity? fields
|
||
| "node" alias identity? fields
|
||
element = element-kind alias string identity? element-body
|
||
element-body = "{" (field-name value ";" | element)* "}"
|
||
identity = "id" uuid-string
|
||
fields = "{" (field-name value ";")* "}"
|
||
value = string | number | "true" | "false" | "none"
|
||
| enum-word | "@" alias | historical-id | list | fields
|
||
historical-id = "uuid" uuid-string
|
||
list = "[" (value ("," value)*)? "]"
|
||
|
||
The project description defaults to empty and may appear once. There is no
|
||
semicolon after a declaration or project closing brace. Every field inside a
|
||
record ends with a semicolon, including fields whose values are nested records.
|
||
Trailing list commas are invalid. Fields may appear in any order.
|
||
|
||
UUID strings use 8-4-4-4-12 hexadecimal spelling, with uppercase or lowercase
|
||
hexadecimal accepted. Canonical output uses lowercase. Omitting an identity
|
||
creates a fresh UUID for that parse. After Apply, accepted source includes the
|
||
generated identity. Authors must keep identity clauses to preserve existing
|
||
objects across subsequent edits.
|
||
|
||
All declaration aliases are collected before references resolve, so forward
|
||
references are legal, including references to nodes and diagrams. Unknown
|
||
``@alias`` values are errors at their reference occurrence. Quoted UUIDs and
|
||
bare words cannot substitute for reference-valued fields. Alias resolution
|
||
produces UUID references; the alias itself remains stored on its declaration.
|
||
Changing an alias in source requires updating its uses. Display names never
|
||
resolve references.
|
||
|
||
``historical-id`` is context-restricted to the typed semantic baseline reference
|
||
slots in section 5.5; it is not an alternative spelling of a live reference.
|
||
|
||
Unknown fields, duplicate fields, incompatible constructor payloads, unsupported
|
||
enum spellings, duplicate aliases/identities, and structural validation errors
|
||
reject the entire candidate. No declaration silently replaces another.
|
||
Ordinary string fields require quoted strings and cannot contain an unquoted
|
||
``@alias`` reference. Enum fields require unquoted named values or their typed
|
||
constructor records. Typed values MUST NOT nest more than 64 levels; malformed
|
||
deeply nested drafts produce a diagnostic instead of exhausting the parser stack.
|
||
|
||
6.1. Modular source projects
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
The pure ``source_project`` core API compiles a virtual source bundle, containing
|
||
``entry`` and a ``files`` map from logical paths to UTF-8 strings. Its entry is a
|
||
root-level ``.arcadia`` file with the source7 project header above. A project entry
|
||
MAY also be ``include string ";"``. An included fragment consists only of ordinary
|
||
declarations and include statements; it MUST NOT contain another version header,
|
||
project wrapper, or project description. Includes MUST occur at document level,
|
||
never inside an element body or typed field value. For example::
|
||
|
||
arcadia 7;
|
||
project rescue "Rescue" id "00000000-0000-4000-8000-000000000001" {
|
||
description "Operational model";
|
||
include "oa/participants.arcadia";
|
||
include "oa/activities/activity_respond.arcadia";
|
||
include "views/diagram_operational.arcadia";
|
||
}
|
||
|
||
An include path is relative to its containing file. ``.`` and ``..`` segments
|
||
normalize within the virtual project root; escaping that root is an error. Bundle
|
||
keys MUST already be normalized, use forward slashes and the lowercase
|
||
``.arcadia`` suffix, and contain no empty path segments. Absolute, drive, UNC,
|
||
URL, backslash, control-character and non-portable Windows device paths are
|
||
rejected. Paths ending a segment in dot or space are rejected. Keys that collide
|
||
after Unicode lowercasing are rejected. References use the exact normalized
|
||
spelling; filesystems do not participate in resolution.
|
||
|
||
Every reachable file is compiled once, including through repeated or diamond
|
||
includes. Include cycles are errors with their chain and including location.
|
||
Missing files, duplicate JSON file keys and supplied unreachable files are
|
||
errors. The compiler MUST NOT read local files, network resources, environment
|
||
variables or the process working directory. The native loader is responsible
|
||
for translating a directory into this explicit bundle and enforcing physical
|
||
path ownership; the pure compiler grants no filesystem access.
|
||
|
||
``inspect_includes(path, source, is_entry, limits)`` supports native discovery
|
||
before all included documents are available. It uses the same strict entry or
|
||
fragment syntax parser, applies document byte/record and local include-edge
|
||
budgets, and returns normalized targets with exact directive spans. Comments and
|
||
strings that mention include syntax are not directives. A syntax failure anywhere
|
||
in the document returns located errors and no partial include list; it does not
|
||
scan arbitrary token strings after failure. Global references and engineering
|
||
validation are deferred to bundle compilation. A native loader MUST retain the
|
||
unparsed draft on failure and enforce aggregate bytes/files/depth/edges while
|
||
loading; this inspection call does not own or inspect a directory.
|
||
|
||
All files share the existing global alias/UUID namespace. Files add no semantic
|
||
namespace, implicit parent, allocation or port contract. Forward references work
|
||
across files. Duplicate aliases and identities report the offending declaration
|
||
and the previous declaration location, including collisions with the project.
|
||
Moving a declaration between files MUST preserve the resulting model and UUIDs.
|
||
|
||
``ProjectLimits`` adds file, include-depth and include-edge budgets to the existing
|
||
``language::ParseLimits``. Model bytes, graph objects, records and ordered
|
||
references are counted across the complete bundle, never reset per file. The
|
||
default candidate policy is 256 files, depth 32 (entry depth zero), 1,024 include
|
||
edges and 64 MiB combined UTF-8 source. Other model counts remain caller policy.
|
||
Repeated include edges count toward the edge budget; file contents count once.
|
||
The compiler admits input and stabilized output against the same limits.
|
||
|
||
``compile_bundle`` returns either located errors and no candidate, or a
|
||
``CompiledSourceProject`` with the validated ``DecodeResult``, stabilized bundle,
|
||
derived ``SourceIndex`` and located engineering warnings. It inserts explicit
|
||
UUID clauses into headers that omitted them without otherwise reformatting the
|
||
input. The returned source index and diagnostics address the returned stabilized
|
||
bytes. Clients MUST retain that bundle after successful Apply; recompiling the
|
||
original buffers with missing identities would generate fresh identities.
|
||
|
||
Bundle diagnostics wrap the existing Diagnostic with a logical path and optional
|
||
related locations. Declaration spans, own-field value spans, lexical owners,
|
||
declaration bodies, project header/body/description spans and resolved includes are available in
|
||
the source index. Columns remain one-based Unicode scalars within the real file;
|
||
spans never refer to concatenated or synthetic source.
|
||
|
||
Single-string parse/lint APIs remain filesystem-free and reject include
|
||
statements with an explicit source-bundle requirement. V1/V2 single-file imports
|
||
continue through explicit migration. Modular projects accept source3 through
|
||
source7. Older bundles are upgraded as one project, preserving file paths, includes, nested
|
||
ownership and comments through targeted token edits. Generated allocation
|
||
declarations stay in their interface's existing file. Individual include fragments
|
||
are not independently migrated. Missing UUIDs stabilize before migration so new
|
||
allocation identities are deterministic on subsequent compilation.
|
||
An authored source4 bundle upgrades through the strict prose-only baseline
|
||
adapter; after any missing UUID stabilization, the version token alone changes
|
||
to 7. Existing prose, comments, includes and nested ownership remain intact.
|
||
Source5 semantic facet comments follow their closed selector identity through
|
||
row reordering and reidentification; UUID-looking text does not act as an Id.
|
||
|
||
6.2. Nested element ownership
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
An element body MAY contain element declarations interleaved with its ordinary
|
||
fields. Its immediate enclosing element is its lexical owner. For example::
|
||
|
||
sa_actor harbor "Harbor operator" {
|
||
sa_port radio "Radio" {
|
||
contract { Component { kind Standard; orientation Unset; }; };
|
||
}
|
||
}
|
||
|
||
Nesting expresses semantic ``Element.parent`` only. It does not allocate a
|
||
function to an actor or System, deploy equipment, or add or reorder occurrence
|
||
references in an owner's explicit ``steps`` list. Those relationships retain
|
||
their explicit records and fields. The
|
||
same parent-kind, layer and acyclicity constraints apply as for flat source.
|
||
Only element declarations can nest: relations, diagrams, placements, artifacts,
|
||
traces and include directives remain at document level. A typed record value
|
||
contains fields, never element declarations.
|
||
|
||
If a nested declaration omits ``parent``, it inherits its lexical owner's UUID.
|
||
An explicit ``parent`` MUST reference that owner; another reference or ``none``
|
||
is an error located at the parent value. At document level, omitted ``parent``
|
||
means ``none`` and explicit parent references retain their existing meaning.
|
||
Nesting creates no alias namespace. Aliases and UUIDs remain globally unique,
|
||
and references can target nested declarations before or after their definition
|
||
or from another included file. Identity stabilization inserts missing UUIDs in
|
||
nested headers just as it does in document-level headers.
|
||
|
||
Source positions distinguish each declaration's own fields from its descendants'
|
||
fields. A declaration's body span encloses its lexical children as well as its
|
||
own fields. An inherited parent has no synthetic source token or field span.
|
||
Located diagnostics and editor navigation MUST address real source bytes.
|
||
|
||
7. Canonical output and source tooling
|
||
--------------------------------------
|
||
|
||
For every structurally valid Project P, parsing its canonical output MUST
|
||
reproduce P, and canonicalizing that result MUST be idempotent:
|
||
|
||
.. code-block:: text
|
||
|
||
parse(format(P)) == P
|
||
format(parse(format(P))) == format(P)
|
||
|
||
Equality includes all persistent fields, stored aliases, body variants,
|
||
references, placements, artifacts, trace baselines, and ordered occurrences.
|
||
Map order is irrelevant. The writer preserves signed coordinate zero and
|
||
emits decimals that recover the original binary32 value.
|
||
|
||
Canonical output uses LF, four-space indentation, explicit identities,
|
||
defaults, and JSON-escaped strings. Elements are emitted in UUID order, then
|
||
relations; diagrams and their nodes follow, then artifacts, then traces.
|
||
Fields use deterministic name order. Output ends with LF. Alias values come
|
||
from the model, never from regenerating display names.
|
||
|
||
Comments and input whitespace are lexical trivia to the canonical writer.
|
||
Canonical export does not preserve them. The source-project editor and compiler
|
||
preserve authored comments and whitespace on Apply while inserting missing
|
||
identities. Explicit canonical export remains a separate operation. Project
|
||
update/export distinctions are described below.
|
||
Camera position, selection, source cursor, and undo history are not stored
|
||
model fields. Layout, collapse state, and manual port anchors inside
|
||
NodePlacement are model data.
|
||
|
||
The pure ``format_bundle`` exporter uses the same typed declaration writer as
|
||
``format``. It creates a small entry file, layer/category modules, separate
|
||
activity/function roots and behavior contexts, and separate diagrams with their
|
||
placements. Ports follow their owner; relations follow their source/context.
|
||
Module names derive from persistent aliases, not display names or UUID chunks.
|
||
Declarations are ordered by semantic ancestry and alias, with owners before
|
||
descendants. Case-colliding generated file names receive deterministic numeric
|
||
suffixes. When more than 240 distinct modules would be produced, aggregate
|
||
folders consolidate into category modules to avoid thousands of tiny files.
|
||
For every valid P, ``compile_bundle(format_bundle(P)).decoded.project == P``
|
||
when the caller supplies sufficient admission budgets.
|
||
|
||
``update_bundle(compiled, P, limits)`` is a core source update facility. It
|
||
checks that the compiled document/index/model snapshot still agrees, preserves
|
||
untouched document bytes, and recompiles the result before returning it. Flat
|
||
declarations retain their document-level position and file when reparented.
|
||
Nested declarations move into their new semantic owner's body, across files if
|
||
necessary; becoming a root moves them to document level. New children prefer
|
||
their owner's body. New roots use canonical module rules and add an explicit
|
||
entry include.
|
||
Removed declarations do not delete source files. Alias changes also update
|
||
declarations containing references to that alias. Invalid or stale updates
|
||
return errors without mutating the input workspace.
|
||
|
||
A moved declaration carries its contiguous leading comment block and comments
|
||
following its closing brace on the same line. A blank line separates a comment
|
||
block from the following declaration; such gap comments stay in the enclosing
|
||
scope. Comments trailing a preceding field likewise stay with that field.
|
||
Deletion retains annotations in the nearest surviving original scope and
|
||
separates them from adjacent declarations with blank lines. Surviving descendants
|
||
move with an enclosing declaration unless their own semantic parent changes;
|
||
independent parent and child moves are resolved together. Leading whitespace
|
||
adjusts to the destination scope; other token spelling remains authored.
|
||
|
||
Updates MUST NOT canonicalize surviving declarations in full. Header, field and
|
||
nested value positions are derived from the existing syntax parser. Unchanged
|
||
fields retain their exact bytes, including field order, omitted defaults, number
|
||
and string spelling, comments, indentation and line endings. Changed literals and
|
||
references replace only the required tokens; a reference with comments between
|
||
``@`` and its alias retains those comments. A previously omitted default is
|
||
inserted only if its semantic value changes. New fields use the existing record's
|
||
indentation and line-ending style without reformatting its other fields.
|
||
|
||
A constructor tag change retains shared nested fields in place. Removed fields,
|
||
constructors and declarations remove syntax tokens, retaining their comments
|
||
and whitespace as annotations in the enclosing record or file. A complete value
|
||
shape replacement likewise retains the old value's comments beside the new value.
|
||
The updater does not invent an engineering interpretation for orphaned comments.
|
||
|
||
List entries use stable referenced UUIDs, message-value ``field`` references or
|
||
lifeline-binding ``referenced`` identities when these keys are unique. Literal
|
||
entries use their literal value. Retained entries carry their authored value
|
||
text and inter-separator comments when reordered. Trivia after a preceding comma
|
||
belongs to the following entry; trivia before the next comma belongs to the
|
||
preceding entry. Separators are reconstructed before trailing line comments so
|
||
that the result remains valid syntax. Unkeyed or duplicate-key lists use source
|
||
positions. Removed-entry comments remain as annotations in the list; newly added
|
||
entries receive formatted syntax. These rules preserve comments without silently
|
||
attaching new semantic identity to an ambiguous list entry.
|
||
|
||
Retained declaration UUIDs remain unchanged unless explicitly edited. Source
|
||
ownership remains unchanged except for the nested relocation rules above.
|
||
Records match by UUID, not display name or alias. The model-only ``update_bundle`` treats an
|
||
explicit UUID replacement as removal and creation. The desktop instead uses
|
||
``update_bundle_with_identity_map`` with the surviving-record provenance from
|
||
``prepare_command``: explicit identity edits and sequential identity swaps MUST
|
||
preserve each original declaration's owning file and attached source trivia,
|
||
unless the same edit changes its nested semantic parent and requires relocation.
|
||
New records have no original identity mapping. The mapping MUST be injective,
|
||
refer to existing records and preserve record classes. The
|
||
result is recompiled, reindexed and checked for equality with the requested
|
||
model before return. Equal model values do not imply a no-op if command
|
||
provenance removes or replaces a declaration; the resulting model and source
|
||
bundle together determine whether the accepted state changed.
|
||
Source changes needed for undo are workspace history data;
|
||
callers should retain complete compiled workspace snapshots rather than infer
|
||
past omission/layout choices from a model-only undo.
|
||
|
||
Canonical modular export is a distinct, explicit operation and does not promise
|
||
original comment/layout preservation. The native editor integrates per-file
|
||
drafts and source-project saves as specified below. The pure compiler performs
|
||
no filesystem access. REST ``source-project`` endpoints exchange the accepted
|
||
bundle with all its files. One revision and ETag protect the model and source
|
||
together, including source-only comment edits; stored envelopes contain both.
|
||
Canonical ``source`` endpoints remain explicit model interchange. The precise
|
||
transport, admission and persistence contract is in ``api.rst``.
|
||
|
||
``parse`` returns a complete structurally validated candidate or error
|
||
diagnostics and no model. Engineering warnings alone MUST NOT reject a valid
|
||
candidate. Parsing may stop at the first syntax/conversion error. Diagnostics
|
||
contain severity (Error or Warning), a code identifying the diagnostic category,
|
||
optional object UUID and field path, a message, one-based line and Unicode-scalar
|
||
column, and a half-open UTF-8 byte Span. Tabs count as one scalar; LF advances
|
||
the line. Structural errors and engineering warnings point to a relevant
|
||
declaration or field when available. Clients MUST use severity/code rather than
|
||
parse the human message; diagnostic wording is not a stable machine API.
|
||
|
||
.. rubric:: Explicit behavior coverage diagnostics
|
||
|
||
The following shared engineering checks are advisory ``Warning`` diagnostics.
|
||
They MUST NOT reject graphical Apply, source compilation, Save, or an API
|
||
transaction solely because the model is incomplete. They run only after the
|
||
structural pass reports no ``Error``, avoiding cascades from invalid ownership,
|
||
references, layers, or recursion. Their policy concerns explicit evidence in
|
||
the authored model, not proof that no engineering behavior exists.
|
||
|
||
* ``non_leaf_work_exchange`` locates each ``source`` or ``target`` of an
|
||
Interaction or FunctionalExchange that has direct same-kind child work.
|
||
Repair the exchange to name its responsible leaf Activity/Function, keeping
|
||
SA function-port ownership consistent.
|
||
* ``work_without_behavior_context`` locates a leaf Activity/Function lacking
|
||
an included Action or an included Interaction/FunctionalExchange occurrence
|
||
that explicitly names it as an endpoint.
|
||
* ``exchange_without_behavior_context`` locates an Interaction or
|
||
FunctionalExchange lacking an included Exchange occurrence. It is suppressed
|
||
while a more specific non-leaf endpoint warning applies to that exchange.
|
||
* ``mission_without_capability`` locates an OperationalMission/Mission lacking
|
||
a valid same-layer outgoing MissionCapability. Participant responsibility
|
||
through MissionInvolvement does not satisfy this check.
|
||
* ``capability_without_behavior_context`` locates a supported leaf
|
||
Capability/SystemCapability lacking either an incoming ChainInvolvement or
|
||
a same-layer Scenario explicitly naming it as ``context``. It MUST NOT
|
||
duplicate ``unsupported_capability`` on the same record.
|
||
|
||
Record-level checks have no invented field path. Coverage traverses all Process,
|
||
FunctionalChain and Scenario roots, following only their explicitly listed,
|
||
correctly owned occurrences and Fragment branches. Reusable sequence/scenario
|
||
contents are traversed with identity-based cycle guards. Known work/exchange
|
||
references count despite unfinished lifelines; unordered occurrences do not.
|
||
Repeated exchanges and correlated replies contribute the same identity once.
|
||
Parent work does not cover its children. Bare lifelines, state observations,
|
||
StateAction/Availability links, timer-only occurrences, and participant/boundary
|
||
messages do not imply work/exchange coverage. Allocation does not imply that
|
||
every exchange carried by a boundary message occurs. Diagram layout is irrelevant.
|
||
|
||
As an explicit Studio completeness policy, same-kind capability grouping parents
|
||
are excluded from both capability support warnings; their leaf capabilities are
|
||
checked independently. A valid direct Scenario context also satisfies existing
|
||
``unsupported_capability`` support. An empty linked process/chain or scenario
|
||
satisfies explicit context presence while retaining its own ``empty_sequence``
|
||
warning. Include/extend/generalization, parent containment, and shared performers
|
||
MUST NOT manufacture a context. These advisory checks follow the distinction
|
||
between dataflow and its usage contexts described in the official
|
||
`Arcadia Questions and Answers <https://mbse-capella.org/arcadia-qna.html>`_;
|
||
they are not a declaration of full Capella conformance.
|
||
|
||
``parse_limited`` and ``decode_limited`` accept caller admission budgets for
|
||
input bytes, graph objects, total persistent records and ordered step references.
|
||
Counts MUST be checked before expensive structural validation; migration budgets
|
||
include generated records before migration. Exceeding a budget does not mutate
|
||
the model. Admission limits are host capacity policy, not hidden restrictions
|
||
on otherwise valid language semantics; ordinary ``parse`` has no such model
|
||
size policy. The REST service's fixed policy is specified in ``api.rst``.
|
||
|
||
``tokenize`` is tolerant: it covers every input byte with nonoverlapping
|
||
TokenSpans, including incomplete strings and invalid characters. Token classes
|
||
are Keyword, Identifier, String, Number, Comment, Punctuation, Whitespace,
|
||
and Error. ``@`` is punctuation followed by the referenced alias token.
|
||
``lint`` returns syntax, structural and engineering warning diagnostics for the
|
||
current draft without adopting a model. A valid unallocated SA function, for
|
||
example, can report missing System and allocation warnings before Apply.
|
||
``analyze``
|
||
combines tokens, diagnostics, and declaration spans with alias, optional
|
||
explicit UUID, and declaration kind. A malformed later declaration does not
|
||
erase earlier declaration spans. None of these APIs mutates a session.
|
||
|
||
8. Graphical parity and transactional editing
|
||
---------------------------------------------
|
||
|
||
The graphical editor MUST expose all persistent properties through typed
|
||
controls, including optional references, lists, variant constructors, aliases,
|
||
IDs, nested parent changes, diagram placements, artifact metadata, and trace
|
||
baselines. Inspector controls may provide operations unavailable as a canvas
|
||
gesture. Exact strings, including tabs and line breaks in names, must remain
|
||
editable through an appropriate escaped-string input when ordinary widgets
|
||
cannot represent them.
|
||
|
||
A move into a functional parent, an allocation onto a performer, and a diagram
|
||
placement move are different transactions. The UI MUST identify which operation
|
||
will occur. Reparenting work must not silently change its performer. A computed
|
||
parent summary must remain distinguishable from direct allocation. A collapse
|
||
operation hides presentation detail without deleting the children.
|
||
|
||
Applying a reachable source bundle is one model transaction. Graphical edits
|
||
update its owning declarations through the source-preserving updater. Both
|
||
paths validate their candidate and model/source equality before
|
||
adoption; failure preserves the committed model, save baseline, and history.
|
||
Incomplete but structurally safe references and coverage gaps produce warnings
|
||
that allow continued authoring and saving.
|
||
|
||
Source and property drafts contribute to unsaved-work state. Invalid drafts
|
||
MUST NOT be replaced by generated text or lost on ordinary navigation. Undoing
|
||
source-buffer edits and undoing committed model changes are distinct operations.
|
||
Successful source Apply creates one model-history entry. Undo/redo restores
|
||
the full stored model and exact accepted source bundle, including aliases,
|
||
trace links, occurrence identity, comments and file ownership. Each open file
|
||
retains its own unapplied draft across file navigation. Located lint diagnostics
|
||
refer to the raw draft bytes rather than an identity-stabilized intermediate.
|
||
Property editing MUST NOT silently discard a pending source draft.
|
||
|
||
In Textual model, place the caret on a declaration alias or an ``@reference``
|
||
and choose **Definition** (``F12``) or **References** (``Shift+F12``).
|
||
**Back** (``Alt+Left``) returns to the previous source location in this
|
||
workspace. These shortcuts act while the source editor has focus; the Text
|
||
toolbar also exposes the actions. If the previous draft changed, Back restores
|
||
its current cursor rather than reusing an obsolete selection.
|
||
|
||
Symbol navigation reads bounded snapshots of the currently loaded source
|
||
drafts. It does not apply drafts or load missing included files. The results
|
||
identify partial scope, draft evidence, detached or unverified files, alias
|
||
ambiguity and authored-ID collisions. Draft, detached and ambiguous definition
|
||
candidates require an explicit row choice. References are lexical uses of an
|
||
alias, not a list of resolved typed relationships; comments and strings are
|
||
excluded. Declaration and use counts include any rows omitted by the result
|
||
limits. If sources change, stale rows cannot navigate: run the query again.
|
||
Navigation MUST preserve the accepted model and every source draft, and select
|
||
locations in the original UTF-8 bytes. Displayed locations use one-based lines
|
||
and UTF-8 byte columns.
|
||
|
||
Changing a graphical UUID must atomically update map keys and every reference.
|
||
Alias changes preserve UUID identity. Deletion must account for owned elements,
|
||
incident relationships, ordered occurrences, and diagram placements without
|
||
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.
|
||
|
||
9. Persistence and explicit migration
|
||
-------------------------------------
|
||
|
||
Loading detects JSON from its first non-whitespace ``{``; other input is parsed
|
||
as Arcadia source regardless of filename. Saving an ``.arcadia`` suffix uses
|
||
the accepted V7 source bundle (``arcadia 7``); other suffixes use V7 JSON. Both forms preserve the same
|
||
complete model. JSON rejects unknown fields throughout typed payloads,
|
||
duplicate maps, unsupported versions, and structural errors.
|
||
|
||
The explicit schema-4 reader retains the exact old Project/Trace/TraceBaseline
|
||
envelope with closed fields. It reuses unchanged typed elements, relations,
|
||
diagrams and artifacts. Version4 prose baselines migrate with semantic none;
|
||
their names/descriptions remain exact even when live endpoint values differ.
|
||
The adapter MUST NOT infer semantic review from live values, and version3/4
|
||
inputs MUST reject semantic baseline fields. The migration report retains the
|
||
original from_schema and current to_schema 7. Reopening a current7 save produces
|
||
no migration report. The real V4 reviewed-prose fixtures remain compatibility input.
|
||
|
||
The schema-3 reader freezes the changed data payloads and old constructor catalog;
|
||
schema-4 fields/constructors MUST NOT be silently accepted as schema 3. Existing
|
||
typed PortContract records remain unchanged. Information/Material/Energy retain
|
||
their nature with Unspecified mechanism; old Event becomes Information with Event
|
||
mechanism. Old bounds/defaults/supertypes are absent, String length is 0..unbounded,
|
||
and fields retain type/multiplicity/unit with Unspecified direction, Value storage
|
||
and no explicit default. No physical mechanism or direction is guessed.
|
||
|
||
Each old Interface.items entry generates one InterfaceItemAllocation with its
|
||
original zero-based order and Unspecified protocols. UUID v5 uses the project UUID
|
||
namespace and name ``v2-interface-item:<interface-uuid>:<item-uuid>`` consistently
|
||
for schema-2 and schema-3 inputs. Aliases are deterministic and collision-free;
|
||
collision with any existing identity is an error rather than an overwrite. Existing
|
||
interface/item identities remain intact. Old nested message values acquire a path
|
||
only when exactly one valid path exists. Ambiguous paths, including recursive
|
||
reuse, retain the old annotation with a located warning rather than guessing.
|
||
|
||
Migration reports additionally contain ``semantic_defaults`` (object, field,
|
||
description), ``generated_interface_allocations`` (id, source, target, alias,
|
||
order) and ``unresolved_message_values`` (occurrence, field, reason). These new
|
||
report arrays default empty when reading older responses. Version 1 normalizes
|
||
through V2, then the typed-port V3 adapter, shared V4 data upgrade and V5 review
|
||
adapter. Original V2 and real V3 fixtures remain unchanged compatibility inputs. Current exports
|
||
always use version 7; reading/migrating alone never saves or changes revisions.
|
||
|
||
Versions 1–6 MUST reject ContextualLink, operation fields (including explicit
|
||
null/default values) and their new typed semantic facets. Current semantic review
|
||
adds Occurrence.Operation and Relation.ContextOwner/ContextSource/ContextTarget/
|
||
ContextPurpose. Historical endpoints and operation selections remain typed
|
||
historical UUIDs, never live graph references or inferred current facts.
|
||
Version 5/6 migration preserves old Call/Reply/values, direct SequenceLinks,
|
||
traces, and version-appropriate view selectors without guessing operation intent
|
||
or contextual links. An authored source upgrade changes only the version token
|
||
until an actual model edit requires further writeback.
|
||
|
||
Desktop recovery MUST verify old 5/6 checkpoint fingerprints with the exact
|
||
historical serializer and closed old-version admission before accepting the
|
||
migrated model. It retains invalid raw buffers and authored review decisions;
|
||
transient impact approvals are reset and plans are recomputed against the
|
||
accepted base. A saved unchecked executable plan/command MUST NOT be restored.
|
||
|
||
Native source Save All checks the original contents of observed dependencies
|
||
before staging writes. Existing target files are replaced individually and the
|
||
entry is installed last. A transaction journal records originals and intended
|
||
writes; explicit recovery restores originals only when current bytes match a
|
||
known transaction state. Unrelated external contents MUST NOT be overwritten
|
||
by recovery. Missing entry files and lint updates MUST NOT hide a detected
|
||
pending-recovery action. This is not cross-process compare-and-swap or atomic
|
||
multi-file visibility. Save failures retain the accepted model and drafts.
|
||
Detached dirty buffers MUST be reattached or reverted before source saving;
|
||
JSON export does not replace the source project's saved baseline or location.
|
||
|
||
The frozen schema-2 reader retains staged compatibility defaults. Old Scenario bodies without a
|
||
``viewpoint`` retain MixedLegacy, and old Exchange occurrence bodies without
|
||
``message_kind``, ``reply_to`` or ``values`` retain Asynchronous, none and [].
|
||
Old StateTransition bodies without ``transition_kind``, ``triggers`` or
|
||
``effects`` retain External, [] and []; existing ``trigger``, ``guard`` and
|
||
``effect`` strings are preserved exactly. Source declaration defaults and JSON
|
||
compatibility defaults MUST agree; no event or work reference is inferred from
|
||
legacy prose.
|
||
This compatibility applies equally to source and JSON. It adds explicit
|
||
defaults without changing any prior identity, name, reference, order, geometry,
|
||
artifact or trace field. The original V2 golden source/JSON in
|
||
``crates/oa-core/tests/fixtures`` MUST NOT be regenerated from the newer demo;
|
||
they verify that every old persistent field survives. Canonical output writes
|
||
the added defaults through explicit migration to the current schema 7.
|
||
|
||
The V2 adapter preserves every original identity, alias, prose, parent,
|
||
placement, trace and artifact. Generic ports become Legacy with their original
|
||
direction/interface record. Existing FE endpoint IDs remain unchanged. For
|
||
only a missing endpoint it creates an item-bearing FunctionOutput/Input owned
|
||
by the already specified function, using UUID v5 in the project namespace
|
||
with ``v2-fe-port:<fe-id>:source`` or ``v2-fe-port:<fe-id>:target``. Every
|
||
identity category is checked for collision; collisions are located errors,
|
||
never overwrites. New aliases follow the deterministic collision-free alias
|
||
convention. Every old boundary exchange receives ``oriented true``; no
|
||
PortAllocation is inferred.
|
||
|
||
``decode_with_report``, ``load_with_report`` and their limited/source variants
|
||
return the model plus a migration report containing original unresolved port
|
||
IDs, required resolutions, generated endpoint IDs/aliases/owners, and boundary
|
||
orientation defaults. REST import, replacement, candidate validation and
|
||
project snapshots surface the same report. Opening an old server envelope
|
||
preserves its resource ID/revision and bytes; the next explicit edit writes
|
||
schema 7. Model/source exports contain only the canonical model. Migration
|
||
reports are transient response metadata, not persisted model facts.
|
||
|
||
Admission checks account for generated objects and their references before
|
||
construction. Both the old V2 contract and the resulting current graph are
|
||
validated. Migration itself does not save or increase a stored revision.
|
||
Canonical second saves are stable. V1 normalization produces the frozen V2
|
||
model and then uses the same explicit adapters to reach schema 7.
|
||
|
||
Save validates a snapshot, writes a sibling temporary file, flushes it, and
|
||
atomically replaces the destination. Failed serialization or validation must
|
||
not truncate a previous file. External concurrent-writer conflict resolution
|
||
and crash recovery are outside this storage contract.
|
||
|
||
Version 1 text and JSON are accepted through an explicit adapter. Migration
|
||
preserves project, element, and relation UUIDs; names and descriptions; relation
|
||
endpoints; all coordinates; and exact process exchange order and repetition.
|
||
Allocation and Interaction remain their corresponding V2 relations.
|
||
Contribution becomes CapabilityInvolvement; the old Process-to-Capability
|
||
Realization becomes ChainInvolvement, retaining its ID and name.
|
||
|
||
Legacy positions become nodes in one OA Overview diagram. Each old process
|
||
step becomes a distinct occurrence element owned by its process. Generated
|
||
diagram, node, and occurrence identities use UUID v5 with the old Project ID
|
||
as namespace and deterministic role/index names. If such an identity collides,
|
||
a deterministic suffix is tried. Reimporting the same fully identified V1
|
||
input therefore yields the same V5 result, including repeated occurrences.
|
||
No System or SA content is invented during an OA-only migration.
|
||
|
||
V1 source aliases are retained when valid in V2. JSON imports generate the old
|
||
canonical aliases deterministically. Any alias newly reserved in V2 is changed
|
||
by a deterministic suffix; aliases were not persistent V1 semantic data.
|
||
A project alias and aliases for new records are generated without colliding
|
||
with retained aliases. The existing bundled V1 text and JSON migrate to equal
|
||
V5 projects. Future versions remain errors until a separate migration exists.
|
||
|
||
10. Complete authoring example
|
||
------------------------------
|
||
|
||
This document intentionally omits IDs for new authoring. Apply and Save write
|
||
the assigned UUIDs explicitly.
|
||
|
||
.. code-block:: text
|
||
|
||
arcadia 7;
|
||
project harbor "Harbor assistance" {
|
||
oa_entity control "Harbor control" {}
|
||
oa_activity assess "Assess assistance" {}
|
||
allocation performs "Performs" {
|
||
source @control;
|
||
target @assess;
|
||
}
|
||
sa_system service "Harbor assistance system" {}
|
||
sa_function evaluate "Evaluate assistance request" {}
|
||
allocation system_performs "Performs" {
|
||
source @service;
|
||
target @evaluate;
|
||
}
|
||
trace assessment_trace "Operational realization" {
|
||
oa @assess;
|
||
sa @evaluate;
|
||
kind Refinement;
|
||
}
|
||
diagram operational_view "Operational allocation" {
|
||
layer Oa;
|
||
projection Allocation;
|
||
}
|
||
node assessment_card {
|
||
diagram @operational_view;
|
||
element @assess;
|
||
position { x 360; y 70; };
|
||
}
|
||
}
|
||
|
||
11. Verification and primary references
|
||
---------------------------------------
|
||
|
||
``cargo test -p oa-core --test language --locked`` verifies typed round-trips,
|
||
stable aliases, strict syntax/reference failures, Unicode source spans,
|
||
deterministic V1 migration, occurrence identity, coordinate bits, persistence,
|
||
and model-history integration. Core validation and session tests cover domain
|
||
mutation rules; native UI and API verification are separate evidence.
|
||
|
||
``cargo test -p oa-core --test r3_semantic --test r3_source --test r3_migration --locked``
|
||
checks the closed facet catalog, partial decisions, constructor scopes, canonical
|
||
agreement, target-only preservation, historic references, exact prepared impacts,
|
||
source/JSON parity, comment ownership and explicit original1–4 migration. The
|
||
source suite includes actual included-file save/reopen and prepared review
|
||
writeback. These checks establish core/source behavior; they do not establish
|
||
graphical or hosted API acceptance by themselves.
|
||
|
||
The research record in ``docs/research-v2-semantics.md`` distinguishes method
|
||
requirements from Studio design choices and links to original UI evidence.
|
||
The following sources inform this language without extending its scope:
|
||
|
||
* `Arcadia Q&A <https://mbse-capella.org/arcadia-qna.html>`_
|
||
* `Arcadia language reference <https://mbse-capella.org/resources/arcadia-reference/Arcadia%20Language%20-%20MetaModel.pdf>`_
|
||
* `Capella allocation guide <https://github.com/eclipse-capella/capella/blob/master/doc/plugins/org.polarsys.capella.ui.doc/html/05.%20Diagram%20Management/Allocating%20Functions%20on%20Components.mediawiki>`_
|
||
* `Capella iterative transitions <https://github.com/eclipse-capella/capella/blob/master/doc/plugins/org.polarsys.capella.transitions.doc/html/11.%20Iterative%20Transitions/11.1.%20Concepts.mediawiki>`_
|
||
* `W3C XML 1.0 characters <https://www.w3.org/TR/xml/#charsets>`_
|