Migrate schema 2 ports through frozen readers and expose schema 3 source API
Rust checks / check (ubuntu-latest) (push) Canceled after 0s
Rust checks / check (windows-latest) (push) Canceled after 0s
Rust checks / check (ubuntu-latest) (push) Canceled after 0s
Rust checks / check (windows-latest) (push) Canceled after 0s
This commit is contained in:
+121
-32
@@ -1,7 +1,7 @@
|
||||
Arcadia Studio OA / SA Language and Editing Contract
|
||||
====================================================
|
||||
|
||||
:Version: 2
|
||||
:Version: 3
|
||||
:Status: Normative current implementation contract; first-release integration
|
||||
:Core implementation: ``crates/oa-core``
|
||||
:Text suffix: ``.arcadia``
|
||||
@@ -11,17 +11,15 @@ Arcadia Studio OA / SA Language and Editing Contract
|
||||
|
||||
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 version 1. MUST, MUST NOT,
|
||||
validation, persistence, and explicit migration from versions 1 and 2. MUST, MUST NOT,
|
||||
and MAY indicate requirements, prohibitions, and permitted choices.
|
||||
|
||||
The first-release capability/mission, contextual process/chain, typed scenario
|
||||
and state/event additions
|
||||
are temporarily integrated under schema 2. This does not declare the first
|
||||
release complete or waive its remaining scenario, state, data, transition and
|
||||
usability requirements. A distinct release schema and explicit V2 migration
|
||||
will be specified after those interfaces are frozen. This document describes
|
||||
the current implemented records, rather than inventing compatibility rules for
|
||||
that future schema.
|
||||
Schema 3 introduces typed function and component ports, required functional
|
||||
exchange endpoints, independently oriented boundary exchanges, and explicit
|
||||
PortAllocation relations. First-release scenario/state additions remain in
|
||||
scope; this schema change does not declare native acceptance or the wider
|
||||
release complete. The preserved schema-2 reader validates the original
|
||||
contract before migration.
|
||||
|
||||
OA describes stakeholders, operational work and needs. SA describes the
|
||||
selected system boundary, external actors, functions, services and expected
|
||||
@@ -42,7 +40,7 @@ Actual verification evidence is separate from this contract.
|
||||
2. One authoritative model
|
||||
--------------------------
|
||||
|
||||
A Project stores ``schema_version`` (2), ``id``, ``alias``, ``name``,
|
||||
A Project stores ``schema_version`` (3), ``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.
|
||||
@@ -108,8 +106,8 @@ lists all additional fields. ``ref`` means ``@alias``; ``ref?`` also accepts
|
||||
- ``items``: exchange-item refs
|
||||
- ``[]``
|
||||
* - ``oa_port``, ``sa_port``
|
||||
- ``direction``: In, Out, InOut; ``interface``: ref?
|
||||
- InOut; none
|
||||
- ``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 for omitted schema-2 source; none; ``""``; ``""``; ``[]``
|
||||
@@ -205,7 +203,7 @@ 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. Ports belong to
|
||||
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
|
||||
@@ -235,10 +233,13 @@ references. Their kind is the declaration keyword:
|
||||
- ``items`` refs / []
|
||||
* - ``functional_exchange``
|
||||
- SA function → SA function
|
||||
- ``source_port``, ``target_port`` / none; ``items`` / []
|
||||
- Required ``source_port``, ``target_port`` refs; ``items`` / []
|
||||
* - ``boundary_exchange``
|
||||
- Participant-owned output-compatible port → input-compatible port
|
||||
- ``items`` refs / []
|
||||
- Different participant owners; typed component ports have matching kinds
|
||||
- ``oriented`` bool / true; ``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
|
||||
@@ -297,12 +298,75 @@ 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.
|
||||
|
||||
Functional ports, when selected, belong to the corresponding endpoint function
|
||||
and have compatible direction. Boundary ports belong to participants and have
|
||||
compatible direction. An interface groups ExchangeItems; an exchange using
|
||||
that port interface must carry items supported by it. Studio's OA boundary
|
||||
exchange is a simplified representation of operational communication; it is
|
||||
not a claim of complete Capella CommunicationMean equivalence.
|
||||
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. Item compatibility is identity equality; future specialization is
|
||||
not inferred from names. 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 source-3 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 3;
|
||||
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" { items [@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
|
||||
@@ -814,16 +878,16 @@ 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 V1 migration
|
||||
-------------------------------
|
||||
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
|
||||
canonical V2 text; other suffixes use V2 JSON. Both forms preserve the same
|
||||
canonical V3 text (``arcadia 3``); other suffixes use V3 JSON. Both forms preserve the same
|
||||
complete model. JSON rejects unknown fields throughout typed payloads,
|
||||
duplicate maps, unsupported versions, and structural errors.
|
||||
|
||||
During first-release schema-2 integration, old Scenario bodies without a
|
||||
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
|
||||
@@ -836,8 +900,33 @@ 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. A future schema-3 adapter remains a separate required
|
||||
migration and is not implied by this temporary compatibility behavior.
|
||||
the added defaults through the explicit schema-3 migration.
|
||||
|
||||
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 3. 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 V3 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 this same V2-to-3 stage.
|
||||
|
||||
Save validates a snapshot, writes a sibling temporary file, flushes it, and
|
||||
atomically replaces the destination. Failed serialization or validation must
|
||||
@@ -856,7 +945,7 @@ 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 V2 result, including repeated occurrences.
|
||||
input therefore yields the same V3 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
|
||||
@@ -864,7 +953,7 @@ 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
|
||||
V2 projects. Future versions remain errors until a separate migration exists.
|
||||
V3 projects. Future versions remain errors until a separate migration exists.
|
||||
|
||||
10. Complete authoring example
|
||||
------------------------------
|
||||
@@ -874,7 +963,7 @@ the assigned UUIDs explicitly.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
arcadia 2;
|
||||
arcadia 3;
|
||||
project harbor "Harbor assistance" {
|
||||
oa_entity control "Harbor control" {}
|
||||
oa_activity assess "Assess assistance" {}
|
||||
|
||||
Reference in New Issue
Block a user