diff --git a/docs/language.html b/docs/language.html index ab46b44c..474902be 100644 --- a/docs/language.html +++ b/docs/language.html @@ -623,7 +623,7 @@ a { text-decoration: none; }

Arcadia Studio OA / SA Language and Editing Contract

Version:
-
4
+
5
Status:
Normative current implementation contract; first-release integration
Core implementation:
@@ -637,12 +637,14 @@ a { text-decoration: none; }

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 and 3. MUST, MUST NOT, +validation, persistence, and explicit migration from versions 1, 2, 3 and 4. MUST, MUST NOT, and MAY indicate requirements, prohibitions, and permitted choices.

-

Schema 4 adds bounded reusable data types, typed scalar defaults, exchange -mechanisms, qualified message values, specialization, identified interface -allocations and reference associations. It retains schema 3 typed ports and -state views. Explicit older readers preserve existing meanings and identities. +

Schema 5 adds 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 @@ -661,7 +663,7 @@ Actual verification evidence is separate from this contract.

2. One authoritative model

-

A Project stores schema_version (4), id, alias, name, +

A Project stores schema_version (5), 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.

@@ -1015,12 +1017,12 @@ 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 +

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 4;
+
arcadia 5;
 project ports_example "Typed function contract" {
     sa_function send "Send" {}
     sa_function receive "Receive" {}
@@ -1042,7 +1044,8 @@ project ports_example "Typed function contract" {
     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. @@ -1394,7 +1397,7 @@ 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:

-
arcadia 4;
+
arcadia 5;
 project engineering_data "Engineering data" {
     sa_data_type voltage "Voltage" {
         definition { Real { minimum 0.0; maximum 48.0; }; };
@@ -1457,7 +1460,7 @@ 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:

-
arcadia 4;
+
arcadia 5;
 project operating "Operating modes" {
     oa_entity crew "Crew" {}
     oa_state_machine modes "Modes" { parent @crew; }
@@ -1624,9 +1627,11 @@ are invalid.

-

A nonempty baseline is { oa { name "..."; description "..."; }; sa { name "..."; description "..."; }; }. It records last-reviewed names -and descriptions, not a full structural snapshot. Implementations MUST NOT -present it as structural synchronization or a lossless inverse transition. +

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.

@@ -1638,15 +1643,345 @@ 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 -name/description baseline does not reconcile later topology changes.

-

Name and description are compared independently against each endpoint's -last-reviewed baseline. An unchanged source MUST NOT overwrite an accepted +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 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 ...; }.

+ + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Closed scalar semantic facets

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.

+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Closed keyed and ordered semantic facets

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.

  • +
+

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 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 +already acknowledged unchanged values is a no-op; 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 5;
+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

@@ -1666,7 +2001,7 @@ spellings can be used in alias positions because references begin with 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.

-
document    = "arcadia" "4" ";" project
+
document    = "arcadia" "5" ";" project
 project     = "project" alias string identity? "{" project-entry* "}"
 project-entry = "description" string ";" | declaration
 declaration = element
@@ -1678,7 +2013,8 @@ element-body = "{" (field-name value ";" | element)* "}
 identity    = "id" uuid-string
 fields      = "{" (field-name value ";")* "}"
 value       = string | number | "true" | "false" | "none"
-            | enum-word | "@" alias | list | fields
+            | 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 @@ -1696,6 +2032,8 @@ 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. @@ -1707,12 +2045,12 @@ 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 source4 project header above. A project entry +root-level .arcadia file with the source5 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 4;
+
arcadia 5;
 project rescue "Rescue" id "00000000-0000-4000-8000-000000000001" {
     description "Operational model";
     include "oa/participants.arcadia";
@@ -1770,12 +2108,17 @@ 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 and source4; -source3 is upgraded as one project, preserving file paths, includes, nested +continue through explicit migration. Modular projects accept source3, source4 and +source5. Source3 is 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.

+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 5. 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

@@ -1979,9 +2322,17 @@ 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 V4 source bundle (arcadia 4); other suffixes use V4 JSON. Both forms preserve the same +the accepted V5 source bundle (arcadia 5); other suffixes use V5 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 5. Reopening a current5 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 @@ -2001,9 +2352,9 @@ reuse, retain the old annotation with a located warning rather than guessing.

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 and this shared V4 data upgrade. Original -V2 and real V3 fixtures remain unchanged compatibility inputs. Current exports -always use version 4; reading/migrating alone never saves or changes revisions.

+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 5; reading/migrating alone never saves or changes revisions.

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 @@ -2027,7 +2378,7 @@ 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 the explicit schema-3 and schema-4 migrations.

+the added defaults through the explicit schema-3, schema-4 and schema-5 migrations.

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 @@ -2044,13 +2395,13 @@ 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 4. Model/source exports contain only the canonical model. Migration +schema 5. 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 V4 graph are +construction. Both the old V2 contract and the resulting V5 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 these same V2-to-3-to-4 stages.

+model and then uses these same V2-to-3-to-4-to-5 stages.

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 @@ -2066,20 +2417,20 @@ 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 V4 result, including repeated occurrences. +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 -V4 projects. Future versions remain errors until a separate migration exists.

+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.

-
arcadia 4;
+
arcadia 5;
 project harbor "Harbor assistance" {
     oa_entity control "Harbor control" {}
     oa_activity assess "Assess assistance" {}
@@ -2116,6 +2467,13 @@ 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:

diff --git a/docs/language.rst b/docs/language.rst index 65ee36c1..ed5dbca1 100644 --- a/docs/language.rst +++ b/docs/language.rst @@ -1,7 +1,7 @@ Arcadia Studio OA / SA Language and Editing Contract ==================================================== -:Version: 4 +:Version: 5 :Status: Normative current implementation contract; first-release integration :Core implementation: ``crates/oa-core`` :Text suffix: ``.arcadia`` @@ -11,13 +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 versions 1, 2 and 3. MUST, MUST NOT, +validation, persistence, and explicit migration from versions 1, 2, 3 and 4. MUST, MUST NOT, and MAY indicate requirements, prohibitions, and permitted choices. -Schema 4 adds bounded reusable data types, typed scalar defaults, exchange -mechanisms, qualified message values, specialization, identified interface -allocations and reference associations. It retains schema 3 typed ports and -state views. Explicit older readers preserve existing meanings and identities. +Schema 5 adds 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 @@ -39,7 +41,7 @@ Actual verification evidence is separate from this contract. 2. One authoritative model -------------------------- -A Project stores ``schema_version`` (4), ``id``, ``alias``, ``name``, +A Project stores ``schema_version`` (5), ``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. @@ -347,14 +349,14 @@ 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 +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 4; + arcadia 5; project ports_example "Typed function contract" { sa_function send "Send" {} sa_function receive "Receive" {} @@ -377,6 +379,7 @@ For example:: 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 @@ -736,7 +739,7 @@ This complete data contract example is also exercised through the REST API: .. code-block:: text - arcadia 4; + arcadia 5; project engineering_data "Engineering data" { sa_data_type voltage "Voltage" { definition { Real { minimum 0.0; maximum 48.0; }; }; @@ -805,7 +808,7 @@ This complete source example places one state from an existing machine: .. code-block:: text - arcadia 4; + arcadia 5; project operating "Operating modes" { oa_entity crew "Crew" {} oa_state_machine modes "Modes" { parent @crew; } @@ -975,10 +978,12 @@ are invalid. * - Manual - Engineer-defined relationship between OA/SA elements or relations -A nonempty baseline is ``{ oa { name "..."; description "..."; }; -sa { name "..."; description "..."; }; }``. It records last-reviewed names -and descriptions, not a full structural snapshot. Implementations MUST NOT -present it as structural synchronization or a lossless inverse transition. +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. @@ -991,10 +996,10 @@ 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 -name/description baseline does not reconcile later topology changes. +prose baseline alone does not reconcile later topology changes. -Name and description are compared independently against each endpoint's -last-reviewed baseline. An unchanged source MUST NOT overwrite an accepted +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 @@ -1002,6 +1007,325 @@ 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 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. + +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 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 +already acknowledged unchanged values is a no-op; 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 5; + 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 ------------------------------ @@ -1026,7 +1350,7 @@ sets and enum constructors are closed by sections 3–5. .. code-block:: text - document = "arcadia" "4" ";" project + document = "arcadia" "5" ";" project project = "project" alias string identity? "{" project-entry* "}" project-entry = "description" string ";" | declaration declaration = element @@ -1038,7 +1362,8 @@ sets and enum constructors are closed by sections 3–5. identity = "id" uuid-string fields = "{" (field-name value ";")* "}" value = string | number | "true" | "false" | "none" - | enum-word | "@" alias | list | fields + | 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 @@ -1060,6 +1385,9 @@ 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. @@ -1073,13 +1401,13 @@ deeply nested drafts produce a diagnostic instead of exhausting the parser stack 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 source4 project header above. A project entry +root-level ``.arcadia`` file with the source5 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 4; + arcadia 5; project rescue "Rescue" id "00000000-0000-4000-8000-000000000001" { description "Operational model"; include "oa/participants.arcadia"; @@ -1145,12 +1473,17 @@ 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 and source4; -source3 is upgraded as one project, preserving file paths, includes, nested +continue through explicit migration. Modular projects accept source3, source4 and +source5. Source3 is 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 5. 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1382,10 +1715,19 @@ explicitly before Apply succeeds. 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 V4 source bundle (``arcadia 4``); other suffixes use V4 JSON. Both forms preserve the same +the accepted V5 source bundle (``arcadia 5``); other suffixes use V5 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 5. Reopening a current5 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 @@ -1407,9 +1749,9 @@ 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 and this shared V4 data upgrade. Original -V2 and real V3 fixtures remain unchanged compatibility inputs. Current exports -always use version 4; reading/migrating alone never saves or changes revisions. +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 5; reading/migrating alone never saves or changes revisions. Native source Save All checks the original contents of observed dependencies before staging writes. Existing target files are replaced individually and the @@ -1435,7 +1777,7 @@ 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 the explicit schema-3 and schema-4 migrations. +the added defaults through the explicit schema-3, schema-4 and schema-5 migrations. The V2 adapter preserves every original identity, alias, prose, parent, placement, trace and artifact. Generic ports become Legacy with their original @@ -1454,14 +1796,14 @@ 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 4. Model/source exports contain only the canonical model. Migration +schema 5. 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 V4 graph are +construction. Both the old V2 contract and the resulting V5 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 these same V2-to-3-to-4 stages. +model and then uses these same V2-to-3-to-4-to-5 stages. Save validates a snapshot, writes a sibling temporary file, flushes it, and atomically replaces the destination. Failed serialization or validation must @@ -1480,7 +1822,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 V4 result, including repeated occurrences. +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 @@ -1488,7 +1830,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 -V4 projects. Future versions remain errors until a separate migration exists. +V5 projects. Future versions remain errors until a separate migration exists. 10. Complete authoring example ------------------------------ @@ -1498,7 +1840,7 @@ the assigned UUIDs explicitly. .. code-block:: text - arcadia 4; + arcadia 5; project harbor "Harbor assistance" { oa_entity control "Harbor control" {} oa_activity assess "Assess assistance" {} @@ -1537,6 +1879,14 @@ 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: