Files
ARCADIA-Studio/harness/release-coverage-diagnostics-design.md

12 KiB

Bounded coverage diagnostics — decision proposal, 2026-09-06

Read-only design for task 3 in the current coverage audit. No model/schema changes or implementation acceptance. Scope is OA/SA only.

Add five advisory codes to shared validation, using existing identities and references. They describe missing explicit evidence, not proof of incorrect engineering. All remain Severity::Warning: no rejection of Apply, Save, REST transactions or source compilation solely because of these checks.

The official Arcadia Q&A, “Leaf functions, parent functions?” and “Functional exchanges only on leaf functions?” recommends leaf-level behavioral definition and contextual involvement in finalized models, while recognizing intermediate decomposition work. The exact warning policy below is a Studio design choice; it does not introduce a mandatory Capella conformance test.

Code / located record and field Exact trigger and repair
non_leaf_work_exchange / Interaction or FunctionalExchange, source or target The referenced endpoint is work with a direct child of the same work kind. Emit once per affected endpoint. “Choose the leaf activity/function responsible for this exchange.” SA uses the relation's function IDs, not its input/output port IDs; repair must keep port ownership consistent.
work_without_behavior_context / leaf Activity or Function, record location (field = "") No included Action names this work and no included Interaction/FE names it as an endpoint. “Include this leaf in a process/chain or scenario through a work action or exchange occurrence.”
exchange_without_behavior_context / Interaction or FunctionalExchange, record location No included Exchange occurrence names this relation. “Use this exchange in a process/chain or scenario.” Suppress while it has a non-leaf endpoint: first repair the more specific endpoint warning.
mission_without_capability / OperationalMission or Mission, record location No valid outgoing MissionCapability to a capability in its layer. “Connect this mission to a capability that delivers it.” MissionInvolvement is participant responsibility and does not satisfy this check.
capability_without_behavior_context / Capability or SystemCapability, record location Capability has participant/work/role support but no explicit process/chain or scenario context. “Link a process/chain with Chain involvement, or set a scenario's Context to this capability.” Do not emit alongside existing unsupported_capability for the same capability.

The final code deliberately checks presence of an explicit context, not whether that context is complete. A linked empty chain/scenario has existing empty_sequence and missing-contribution diagnostics; repeating these on the capability would add noise. An isolated leaf capability with no support keeps the existing unsupported_capability warning.

Capability context means either (a) incoming valid ChainInvolvement from a Process/FunctionalChain or (b) an existing same-layer Scenario whose context is this capability. A scenario whose context is a chain already linked to the capability is naturally covered by (a). Narrowly extend the existing unsupported_capability support predicate to recognize (b), so a scenario-only capability is not wrongly called unsupported. No new capability warning is needed on a pure grouping capability with same-kind child capabilities; inspect its children. Capability include/extend/generalization, parent containment, shared performers, mission context and similarly named records do not manufacture a direct context link. The message must say “explicit context,” not “no behavior exists.”

Exact traversal and exclusions

Current seams: model.rs defines OaBody::Process, SaBody::FunctionalChain, SharedBody::Scenario { context, steps, .. }, Element::steps() and the closed OccurrenceBody variants. validation.rs already checks ownership, ordered membership, recursion and reference compatibility. The existing leaf-allocation predicate is kind().is_work() with no p.children(id) child of the same kind; reuse that definition. Build an indexed set of non-leaf work once rather than rescanning all children for every exchange.

Build global covered-work and covered-exchange identity sets in one bounded iterative walk:

  1. Seed every Process, FunctionalChain and Scenario as a root, even if no capability references it. Coverage asks whether a context exists anywhere in the same project; it does not require every context to serve a capability.
  2. Follow only identities listed in the owner's steps(), checking the occurrence's actual parent. For a Fragment follow its explicit branches whose parent is that fragment; for each Branch follow its occurrences through steps(). Do not walk arbitrary descendants: an unordered occurrence is not part of the authored behavior.
  3. For Exchange { exchange: Some(id), .. }, mark the referenced Interaction/FE and its explicit work endpoints. For Action { action: Some(id), .. }, mark that referenced Activity/Function. Parent work does not cover its children. Mark identities, not occurrence counts; repeated messages and correlated replies cannot increase or double-count coverage.
  4. Follow SequenceReference { sequence: Some(id) } only to the same process/chain kind and layer. Follow ScenarioUse { scenario: Some(id), .. } to the referenced scenario; ScenarioUse bindings preserve represented identity under current validation and do not substitute different work or exchanges. Visit each container/occurrence ID once. No recursion or per-root transitive-closure materialization. Every referenced sequence is also a root, so reuse does not change global coverage; this explicit treatment prevents later capability-scoped extensions from silently losing reused content.
  5. An explicit work Action counts even when its scenario lifeline is unfinished: the work identity is known, and the existing missing-lifeline warning explains the remaining work. An exchange occurrence likewise counts its known exchange despite missing contextual details. Controls, timer-only occurrences, bare lifelines, State observations, StateAction/Availability links and Scenario.context alone do not mark work/exchanges covered. A state observation on a work lifeline observes state; it does not assert that work contributed. Participant/boundary messages never infer coverage of allocated Interaction/FE records: allocation of a transport is not evidence that every allocated exchange occurs in that scenario.

No warnings for ports, BoundaryExchange, future CommunicationMean, data items, participants, roles, parent work coverage, diagrams or promoted/folded summary edges. Diagram visibility and layout are irrelevant. Allocation/role sharing does not propagate coverage to sibling work. Non-leaf endpoint warnings inspect authored relationships only.

Recommended malformed-candidate policy: run this new completeness pass only when the existing structural validation pass has no Errors. This avoids cascades from dangling references, wrong layers, cycles or invalid ownership; accepted projects and saveable incomplete drafts still receive all new warnings. Keep the walk visited-set guarded regardless. Existing warning-only issues (unordered_occurrence, missing endpoints, empty sequences, topology gaps) do not disable the pass. Ignore incomplete edges with no usable referenced identity.

Existing checks to retain rather than duplicate: unallocated_leaf, unsupported_capability, empty_sequence, unordered_occurrence, incomplete_step, missing_exchange, sequence_gap, isolated_contribution, unreachable_contribution, nonterminating_contribution, sequence_starts/ends, control/guard warnings and recursive-use errors. An unallocated leaf may also lack behavior context: these are distinct repairs.

User location and shared contract

Use Issue.element = Some(record_id), stable code and a real endpoint field or record-level location. Do not fabricate a coverage field absent from the source grammar. source_project::model_diagnostics already maps object/field to its owning file; source lint and REST consume shared validation. views.rs::checks already offers Open on the located identity. Endpoint warnings should open the exchange's properties; coverage warnings open the leaf/exchange or mission/capability and explain the Behavior/Actions repair. No automatic creation, allocation or reassignment is implied.

Warnings must be deterministic by ID and endpoint, share codes/location across GUI/source/JSON/REST, disappear after the stated repair and reappear on Undo. The new helper should be linear in indexed records/references aside from ordered-map lookup costs. It should not call validate() recursively or perform a full graph walk separately for every leaf/capability.

Three acceptance fixtures

  1. Valid covered SA, including reuse. One System, one Actor, allocated leaf functions F/G, typed ports and FE E from F to G. Inner chain has an Exchange occurrence E; outer chain reuses inner and has ChainInvolvement to capability C. Mission M has MissionCapability to C. Add a functional scenario with F/G lifelines and repeated E call/reply plus a second scenario reusing it through a branch with identity-preserving bindings. Expected: none of the five new warnings; reuse/repetition does not duplicate facts. Remove E occurrences from every context: F/G and E become uncovered; add an Action F alone: only F's work warning clears, E/G remain. Run an OA counterpart variant with Interaction and Process to prove symmetric layer semantics.

  2. Structurally invalid candidate. Starting from fixture 1, make a ScenarioUse cycle, then independently try an FE referencing a missing function and an occurrence listed under the wrong owner. Expected: existing exact structural errors, no new completeness cascade, candidate rejected atomically and accepted model/coverage unchanged. A visited-set traversal must terminate even when invoked directly on these malformed graphs. This fixture does not reinterpret invalid structure as permissible incompleteness.

  3. Saveable incomplete OA with exact repair targets. Parent activity P has leaves A/B; independent leaf C. Allocate A/B/C to valid performers. Interaction Eab is A→B and appears in a Process; Ep is P→C and Eca is C→A, neither used in behavior. Mission M has no MissionCapability. Capability Q has only participant involvement. Add a participant scenario with only an observation of C's performer's state and no capability Context. Expected new warnings: Ep/source non-leaf; C uncovered; Eca uncovered; M missing capability; Q missing explicit behavior context. Ep's uncovered-exchange warning is suppressed until its endpoint is repaired. A/B are covered through Eab. Add an unordered occurrence Eca: existing unordered warning appears and coverage stays missing. Put it in ordered steps: Eca and C coverage clear. Repair Ep to A→C with matching source semantics, then include it in the process; link M→Q and process→Q. All five original warnings clear; Undo restores the relevant exact warnings. Repeated/reused Eab must never hide Eca's absence. Separately link an empty chain/scenario to Q: Q's context warning clears while the existing empty-sequence warning remains.

For these fixtures compare code/record/field tuples through core validation, multi-file source lint and real REST; check Save success for fixture 3 and rejection atomicity for fixture 2. Native check Open navigation and repair/Undo at normal and minimum window sizes. These are proposed checks, not completed tests.