Files
ARCADIA-Studio/harness/release-scenarios-core.md

9.4 KiB

R4 reusable scenario and message core milestone — 2026-09-05

Status: bounded core implementation and focused verification complete. Source/API migration, graphical authoring/rendering, native workflows and independent review remain integration gates. This provides explicit modeling semantics, not message execution or simulation.

Frozen interface

  • ScenarioViewpoint: OperationalActivity, ParticipantInteraction, Functional, BoundaryInterface, MixedLegacy. SharedBody::Scenario adds viewpoint. New OA scenarios default to OperationalActivity; new SA scenarios default to Functional. The demo explicitly uses BoundaryInterface because its lifelines represent participants.
  • Work viewpoints use Activity/Function lifelines and the corresponding Interaction/FunctionalExchange. Participant viewpoints use OA Entity/Actor/Role or SA System/SystemActor lifelines; their exchanges can use participant ports or allocated work, with the existing endpoint/effective-performer agreement rules. Wrong declared viewpoint/layer or represented family rejects.
  • OccurrenceBody::Exchange adds message_kind: MessageKind, reply_to: Option<Id> and values: Vec<MessageValue>.
  • MessageKind: Asynchronous, Call, Reply, Create, Delete, Timer { expression: String }. A timer is a local lifeline event: sender required as an editable reference; receiver absent or equal to sender; no global exchange or carried values. Missing duration/deadline expression warns.
  • MessageValue { field: Id, expression: String }: contextual expression annotation bound to an actual carried DataField identity, including nested named-record fields. It is not a claim that expressions are evaluated or literal values type-checked. Duplicate/unrelated fields reject; empty expressions warn.
  • LifelineBinding { referenced: Id, local: Id } and OccurrenceBody::ScenarioUse { scenario: Option<Id>, bindings: Vec<LifelineBinding> }: same-layer, same-viewpoint reuse with explicit one-to-one lifeline correspondence. Bound lifelines represent the same semantic object, or an explicitly realized operational role. This is reuse of existing semantics, not an implicit generic-template substitution. Missing target/bindings warn; wrong context/identity, duplicates and recursive reuse reject. MixedLegacy viewpoints remain reviewable without inventing a precise historical viewpoint.

Behavioral rules

A Reply references a Call in the same scenario, reverses its sender/receiver, and follows it on a guaranteed containing branch path. A call inside one alternative or optional loop is not treated as an unconditional call after the fragment. A reply can reuse the call's exchange with reversed direction, or use a separate reverse-direction exchange. Sequential duplicate replies reject; mutually exclusive branches are not silently linearized. Only Reply has reply_to.

Create/Delete check structurally possible co-execution and order: a created receiver cannot already be used earlier on a possible path, and a deleted receiver cannot be used later. A conditional branch and a following sibling can co-execute, as can Parallel operands. Distinct Alternative operands are mutually exclusive. These checks do not solve arbitrary guards or execute traces. Call/reply/lifecycle/timer kinds belong to scenarios; ordinary process/chain exchange contributions remain Asynchronous.

Reuse and call/value references participate in the common visitor, reference closure, transition mapping and deletion. Scenario viewpoint maps OperationalActivity↔Functional and ParticipantInteraction↔BoundaryInterface. Reusing one scenario twice preserves one referenced scenario identity. Explicit loop fragments model repetition; recursion in scenario references is rejected.

Deleting a referenced scenario keeps its caller use as an incomplete draft and removes invalid lifeline bindings. Deleting a call clears reply correlation; deleting a bound lifeline prunes its binding. Deleting a carried payload/item also removes annotations for fields that cease to be carried, even if those fields survive in a shared record type. validation::carried_fields(p, relation) is the shared query for these direct/nested fields and graphical picker filtering.

Compatibility during integration

Schema version stays 2 temporarily. Missing serialized Scenario viewpoint defaults to MixedLegacy; missing message kind/reply/value fields default to Asynchronous/None/empty. These defaults preserve old model information while clearly flagging unreviewed viewpoint semantics. The language/persistence owner is responsible for explicit lossless V2 migration and the eventual release schema/version change. The default factory and old-input compatibility behavior are intentionally different.

Verification actually run

Using CARGO_TARGET_DIR=D:/CodexBuilds/Capella2-01a06e2e:

cargo check -p oa-core --all-targets --locked
cargo test -p oa-core --locked --test release_scenarios
cargo test -p oa-core --locked --test workflows --test review_regressions --test process_diagnostics --test release_capabilities --test release_topology
cargo clippy -p oa-core --all-targets --locked -- -D warnings

Observed 7 scenario tests plus 57 prior focused core tests passed, strict core Clippy passed, edited Rust sources/tests formatted. Evidence includes both transition directions; shared reuse from two callers; wrong/recursive bindings; call/reply direction, branch order and correlation; lifecycle/timer contracts; carried-field and nested-record values; every conversation element/relation UUID reidentification/deletion with exact undo; reused-scenario/lifeline deletion retaining callers; and loops distinct from recursive reuse.

The annotation cleanup test initially failed when deleting a payload disconnected a surviving nested field. The core deletion path was corrected and the full scenario suite rerun successfully. No remaining failing focused test is waived. R3 full semantic-drift reconciliation, R5 states/events and R6 data contracts remain required; native authoring and rendering of these R4 constructs is not established by core tests.

Independent review corrections — 2026-09-05

Reproduced all three findings in release-semantic-review.md by running its separately compiled reproduction package. The original implementation wrongly reused call-dominance ordering for conflict detection. It now keeps guaranteed_before for Call→Reply correlation and uses separate common-ancestor co-execution/order for conflicting replies and lifecycle operations. Optional/Alternative-branch reply followed by a second reply and conditional deletion followed by use reject. Two Parallel replies or parallel delete/use reject. Legal mutually exclusive Alternative replies and delete/use operands remain accepted.

Role endpoint compatibility now recognizes an explicitly assigned operational role. A distinct unassigned role realized by the same participant is incompatible; an assigned abstract role remains valid when concrete realizations are ambiguous. Three public helpers share these semantics between core validation, scenario-use binding checks and graphical pickers:

validation::message_endpoints(&Project, &OccurrenceBody) -> Option<(Id, Id)>
validation::lifeline_matches_endpoint(&Project, line: Id, endpoint: Id) -> Option<bool>
validation::semantic_representation_compatible(&Project, representation: Id, semantic: Id) -> Option<bool>

An unresolved reply correlation has no inferred endpoints. None compatibility means a missing reference or unresolved concrete performer, never an arbitrarily chosen realization.

Observed after fixes: 68 focused core tests passed (11 scenario plus 57 prior), strict core all-target Clippy passed. The independent reproduction now reports duplicate_reply_after_optional: 1 error (duplicate_reply), use_after_optional_delete: 1 error (lifeline_lifetime), and valid_role_lifeline: 0 errors, no diagnostics. Four new regression tests cover conditional/parallel/exclusive paths, role assignment versus realization/ambiguity, and effective forward/reverse reply endpoints. Graphical picker changes and independent re-review belong to the lead's integration gate.

Repetition follow-up

Fresh review exposed two remaining silent repeated-execution risks. Added reply_repetition warnings when a Reply has an enclosing Loop that does not also enclose its correlated Call, checking every nested scope. A Call and Reply inside the same repeating scope remain valid. Added lifeline_repetition warnings for repeated Create/Delete without an ordered complementary lifecycle message in the same operand. This preserves coherent create→use→delete per iteration while diagnosing [use, delete] on the next iteration, creation without deletion, and conditional cleanup that may be skipped. Free-text guards provide no proven iteration bound, so these are conservative warnings rather than simulated execution results or a blanket prohibition of loops.

Observed after this follow-up: 71 focused core tests passed (14 scenario plus 57 prior), strict core all-target Clippy passed. The independently compiled reproduction now emits reply_repetition for one_call_with_repeated_reply and lifeline_repetition for use_after_delete_next_loop_iteration; both models remain editable with explicit warnings. The original conditional-path errors and valid Role scenario retain their corrected results. Three regression groups cover outside/same/nested call scopes, both missing lifecycle complements, balanced per-iteration lifetime and optional cleanup. No serialized shape changed.