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

64 lines
9.4 KiB
Markdown

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