memo_rules_ontology
SysML API
Namespace hierarchy
memo → memo::rules → memo::rules::ontology
Packages
| Package |
memo_rules_ontology |
Imports
| Visibility |
Target |
| private |
ScalarValues::* |
| private |
memo_core_consistency_rules::* |
| private |
memo_core_enumerations::* |
Declarations
| Name |
SysML kind |
Description |
Specializes |
ContainmentAcyclicRule |
constraint def |
Constraint that checks containment acyclic rule. |
MemoConsistencyRule |
NestedPartConnectedRule |
constraint def |
Constraint that checks nested part connected rule. |
MemoConsistencyRule |
RuntimeTracesToModuleRule |
constraint def |
Constraint that checks runtime traces to module rule. |
MemoConsistencyRule |
PatientContactCharacterizedRule |
constraint def |
Constraint that checks patient contact characterized rule. |
MemoConsistencyRule |
SafetyCriticalFunctionVerifiedRule |
constraint def |
Constraint that checks safety critical function verified rule. |
MemoConsistencyRule |
CriticalTaskValidatedRule |
constraint def |
Constraint that checks critical task validated rule. |
MemoConsistencyRule |
UseErrorTracesToHazardRule |
constraint def |
Constraint that checks use error traces to hazard rule. |
MemoConsistencyRule |
SatisfiedBySourceKindRule |
constraint def |
These rules carry the constraints that connection def end TYPES used to carry in memo_core_relationships.… |
MemoConsistencyRule |
SatisfiedByTargetKindRule |
constraint def |
Constraint that checks satisfied by target kind rule. |
MemoConsistencyRule |
VerifiedByTargetKindRule |
constraint def |
Constraint that checks verified by target kind rule. |
MemoConsistencyRule |
AllocatedToSourceKindRule |
constraint def |
Constraint that checks allocated to source kind rule. |
MemoConsistencyRule |
AllocatedToTargetKindRule |
constraint def |
Constraint that checks allocated to target kind rule. |
MemoConsistencyRule |
ComposesParentKindRule |
constraint def |
Constraint that checks composes parent kind rule. |
MemoConsistencyRule |
ComposesChildKindRule |
constraint def |
Constraint that checks composes child kind rule. |
MemoConsistencyRule |
PrecedesEndKindRule |
constraint def |
Constraint that checks precedes end kind rule. |
MemoConsistencyRule |
PerformsPerformerKindRule |
constraint def |
Constraint that checks performs performer kind rule. |
MemoConsistencyRule |
EnablesEnablerKindRule |
constraint def |
Constraint that checks enables enabler kind rule. |
MemoConsistencyRule |
BindsToInterfaceEndKindRule |
constraint def |
Constraint that checks binds to interface end kind rule. |
MemoConsistencyRule |
CrossesTrustBoundaryEndKindRule |
constraint def |
Constraint that checks crosses trust boundary end kind rule. |
MemoConsistencyRule |
ComponentExchangeSourceEndpointKindRule |
constraint def |
CR-ONT-002's replacement. ComponentExchange's endpoints are ref features, not links, and the builder projects them as element-ID STRINGS in the attribute map (a §13.3 string pseudo-reference) — so they cannot be reached with sourcesOf/targetsOf.… |
MemoConsistencyRule |
ComponentExchangeTargetEndpointKindRule |
constraint def |
Constraint that checks component exchange target endpoint kind rule. |
MemoConsistencyRule |
ComponentFunctionAllocatedRule |
constraint def |
What makes ComponentFunction a definition of its own rather than an enum member on SystemFunction. An enum value cannot change a multiplicity, and "answerable to exactly one component" is the whole content of the concept. |
MemoConsistencyRule |
FunctionDecomposesIntoFunctionsRule |
constraint def |
Constraint that checks function decomposes into functions rule. |
MemoConsistencyRule |
ExchangeHasFlowRule |
constraint def |
Track A3. The flow is the edge; the exchange part carries the budget and assurance attributes. The two halves are bound by a SHARED NAME — the flow usage is named with its exchange — and this is what makes that binding a checked fact rather than a convention someone can quietl… |
MemoConsistencyRule |
AlternateScenarioHasBaseRule |
constraint def |
Constraint that checks alternate scenario has base rule. |
MemoConsistencyRule |
ContainmentAcyclicRule
constraint def ContainmentAcyclicRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks containment acyclic rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
NestedPartConnectedRule
constraint def NestedPartConnectedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks nested part connected rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
RuntimeTracesToModuleRule
constraint def RuntimeTracesToModuleRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks runtime traces to module rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
constraint def PatientContactCharacterizedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks patient contact characterized rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
SafetyCriticalFunctionVerifiedRule
constraint def SafetyCriticalFunctionVerifiedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks safety critical function verified rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
CriticalTaskValidatedRule
constraint def CriticalTaskValidatedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks critical task validated rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
UseErrorTracesToHazardRule
constraint def UseErrorTracesToHazardRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks use error traces to hazard rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
SatisfiedBySourceKindRule
constraint def SatisfiedBySourceKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
These rules carry the constraints that connection def end TYPES used to carry in memo_core_relationships.… |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
SatisfiedByTargetKindRule
constraint def SatisfiedByTargetKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks satisfied by target kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
VerifiedByTargetKindRule
constraint def VerifiedByTargetKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks verified by target kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
AllocatedToSourceKindRule
constraint def AllocatedToSourceKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks allocated to source kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
AllocatedToTargetKindRule
constraint def AllocatedToTargetKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks allocated to target kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
ComposesParentKindRule
constraint def ComposesParentKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks composes parent kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
ComposesChildKindRule
constraint def ComposesChildKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks composes child kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
PrecedesEndKindRule
constraint def PrecedesEndKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks precedes end kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
constraint def PerformsPerformerKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks performs performer kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
EnablesEnablerKindRule
constraint def EnablesEnablerKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks enables enabler kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
BindsToInterfaceEndKindRule
constraint def BindsToInterfaceEndKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks binds to interface end kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
CrossesTrustBoundaryEndKindRule
constraint def CrossesTrustBoundaryEndKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks crosses trust boundary end kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
ComponentExchangeSourceEndpointKindRule
constraint def ComponentExchangeSourceEndpointKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
CR-ONT-002's replacement. ComponentExchange's endpoints are ref features, not links, and the builder projects them as element-ID STRINGS in the attribute map (a §13.3 string pseudo-reference) — so they cannot be reached with sourcesOf/targetsOf.… |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
ComponentExchangeTargetEndpointKindRule
constraint def ComponentExchangeTargetEndpointKindRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks component exchange target endpoint kind rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
ComponentFunctionAllocatedRule
constraint def ComponentFunctionAllocatedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
What makes ComponentFunction a definition of its own rather than an enum member on SystemFunction. An enum value cannot change a multiplicity, and "answerable to exactly one component" is the whole content of the concept. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
FunctionDecomposesIntoFunctionsRule
constraint def FunctionDecomposesIntoFunctionsRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks function decomposes into functions rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
ExchangeHasFlowRule
constraint def ExchangeHasFlowRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Track A3. The flow is the edge; the exchange part carries the budget and assurance attributes. The two halves are bound by a SHARED NAME — the flow usage is named with its exchange — and this is what makes that binding a checked fact rather than a convention someone can quietl… |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
AlternateScenarioHasBaseRule
constraint def AlternateScenarioHasBaseRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks alternate scenario has base rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_ontology |
Source
rules/ontology/ontology_invariants.sysml
package memo_rules_ontology {
private import ScalarValues::*;
private import memo_core_consistency_rules::*;
private import memo_core_enumerations::*;
constraint def ContainmentAcyclicRule :> MemoConsistencyRule {
attribute id = "CR-ONT-001";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Containment/composition relations (Composes) must form no cycles.";
attribute predicateExpression = "acyclic(composes)";
constraint { true }
}
constraint def NestedPartConnectedRule :> MemoConsistencyRule {
attribute id = "AR-IBD-001";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "LogicalComponent";
attribute evaluator = "architecture";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A structural part nested inside another part should expose at least one modeled interface connector. Passive or intentionally isolated parts may retain this warning with an explicit modelling rationale.";
attribute predicateExpression = "hasConnectorInComposition";
constraint { true }
}
constraint def RuntimeTracesToModuleRule :> MemoConsistencyRule {
attribute id = "CR-ONT-011";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "SoftwareComponent";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Every runtime component must trace to a module-view definition (Realizes).";
attribute predicateExpression = "realizes->size() >= 1";
constraint { true }
}
constraint def PatientContactCharacterizedRule :> MemoConsistencyRule {
attribute id = "CR-ONT-032";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "PhysicalComponent";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Patient-contact components must identify contact nature and duration (ISO 10993-1).";
attribute predicateExpression = "patientContact == false or (contactNature != '' and contactDuration != '')";
constraint { true }
}
constraint def SafetyCriticalFunctionVerifiedRule :> MemoConsistencyRule {
attribute id = "CR-ONT-040";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "MemoFunction";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Safety-critical functions (criticality high or catastrophic) must trace to at least one verification case.";
attribute predicateExpression = "not(criticality == 'high' or criticality == 'catastrophic') or verifiedBy->size() >= 1";
constraint { true }
}
constraint def CriticalTaskValidatedRule :> MemoConsistencyRule {
attribute id = "CR-ONT-041";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "OperativeAction[criticality=high]";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Critical tasks (criticality high or catastrophic) must trace to usability validation (FDA HF guidance; IEC 62366-1 summative evaluation).";
attribute predicateExpression = "not(criticality == 'high' or criticality == 'catastrophic') or validates->size() >= 1";
constraint { true }
}
constraint def UseErrorTracesToHazardRule :> MemoConsistencyRule {
attribute id = "CR-ONT-042";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "UseError";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Safety-relevant use errors (severity serious or worse) must trace to a hazard.";
attribute predicateExpression = "not(severity == 'serious' or severity == 'critical' or severity == 'catastrophic') or causes->size() >= 1 or tracesRisk->size() >= 1";
constraint { true }
}
constraint def SatisfiedBySourceKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-060";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Only a requirement or a need is satisfied by something. The source end of SatisfiedBy must conform to MemoRequirementElement.";
attribute predicateExpression = "sourcesOf(satisfiedBy)->forAll(conformsTo(MemoRequirementElement))";
constraint { true }
}
constraint def SatisfiedByTargetKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-061";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A requirement is satisfied by a designed part, a behaviour, or a port. Never by another requirement or by a document.";
attribute predicateExpression = "targetsOf(satisfiedBy)->forAll(conformsTo(MemoPart) or construct == 'action' or construct == 'port')";
constraint { true }
}
constraint def VerifiedByTargetKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-062";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A verification case verifies a requirement, a risk control, an architecture element, a behaviour, or a port — something a test can be run against. Not a view, not an evidence record.";
attribute predicateExpression = "sourcesOf(verifiedBy)->forAll(conformsTo(MemoPart) or construct == 'requirement' or construct == 'action' or construct == 'port')";
constraint { true }
}
constraint def AllocatedToSourceKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-063";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Allocation runs from a function or a behaviour to where it runs. The source end of AllocatedTo is a part or an action.";
attribute predicateExpression = "sourcesOf(allocatedTo)->forAll(conformsTo(MemoPart) or construct == 'action')";
constraint { true }
}
constraint def AllocatedToTargetKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-064";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A function is allocated to a part — including a system or actor — as ARCADIA System Analysis requires.";
attribute predicateExpression = "targetsOf(allocatedTo)->forAll(conformsTo(MemoPart))";
constraint { true }
}
constraint def ComposesParentKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-065";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A whole in a decomposition is a part, a behaviour, or a state machine. A requirement does not compose anything.";
attribute predicateExpression = "sourcesOf(composes)->forAll(conformsTo(MemoPart) or construct == 'action' or construct == 'state')";
constraint { true }
}
constraint def ComposesChildKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-066";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A part in a decomposition is a part, a behaviour, a state, or a port — a component owns its ports, and a workflow owns its steps.";
attribute predicateExpression = "targetsOf(composes)->forAll(conformsTo(MemoPart) or construct == 'action' or construct == 'state' or construct == 'port')";
constraint { true }
}
constraint def PrecedesEndKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-067";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Precedence orders things that happen: parts or behaviours, at both ends.";
attribute predicateExpression = "sourcesOf(precedes)->forAll(conformsTo(MemoPart) or construct == 'action') and targetsOf(precedes)->forAll(conformsTo(MemoPart) or construct == 'action')";
constraint { true }
}
constraint def PerformsPerformerKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-068";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A performer is an operational entity, an actor, or a system action — a part or a behaviour. The end's own documentation said 'or system action' while its MemoPart type forbade one.";
attribute predicateExpression = "sourcesOf(performs)->forAll(conformsTo(MemoPart) or construct == 'action')";
constraint { true }
}
constraint def EnablesEnablerKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-069";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "An enabling system or function enables a workflow: the enabling end is a part or a behaviour.";
attribute predicateExpression = "sourcesOf(enables)->forAll(conformsTo(MemoPart) or construct == 'action')";
constraint { true }
}
constraint def BindsToInterfaceEndKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-070";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A port binds to an interface. The bound end is an interface definition, which the former InterfaceElement-typed end could not hold at all — Interface specializes MemoInterface, an interface def, not a part.";
attribute predicateExpression = "sourcesOf(bindsToInterface)->forAll(conformsTo(InterfaceElement) or construct == 'port') and targetsOf(bindsToInterface)->forAll(conformsTo(InterfaceElement) or construct == 'interface' or construct == 'port')";
constraint { true }
}
constraint def CrossesTrustBoundaryEndKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-071";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "Model";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A boundary is a boundary element or a port; what crosses it is an asset or an exchange item.";
attribute predicateExpression = "sourcesOf(crossesTrustBoundary)->forAll(conformsTo(InterfaceElement) or construct == 'port') and targetsOf(crossesTrustBoundary)->forAll(conformsTo(MemoPart) or construct == 'item')";
constraint { true }
}
constraint def ComponentExchangeSourceEndpointKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-072";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "ComponentExchange";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "An exchange starts at a component or at a boundary port. Stating it as a rule is what let the endpoint refs stop being MemoPart-typed, which is what lets PhysicalPort and SoftwarePort become port defs.";
attribute predicateExpression = "attributes.sourceEndpoint == '' or allOfKind('MemoPart')->exists(id == subject.attributes.sourceEndpoint) or allOfKind('InterfaceElement')->exists(id == subject.attributes.sourceEndpoint) or allOfKind('MemoPort')->exists(id == subject.attributes.sourceEndpoint)";
constraint { true }
}
constraint def ComponentExchangeTargetEndpointKindRule :> MemoConsistencyRule {
attribute id = "CR-ONT-073";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "ComponentExchange";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "An exchange ends at a component or at a boundary port, on the same grounds as CR-ONT-072.";
attribute predicateExpression = "attributes.targetEndpoint == '' or allOfKind('MemoPart')->exists(id == subject.attributes.targetEndpoint) or allOfKind('InterfaceElement')->exists(id == subject.attributes.targetEndpoint) or allOfKind('MemoPort')->exists(id == subject.attributes.targetEndpoint)";
constraint { true }
}
constraint def ComponentFunctionAllocatedRule :> MemoConsistencyRule {
attribute id = "CR-ONT-074";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "ComponentFunction";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A component function is the responsibility of exactly one component, and AllocatedTo is what names it. A component function allocated nowhere is a responsibility nobody has accepted; one allocated twice is a responsibility nobody owns. A system-level responsibility with no single owner is a SystemFunction, which allows that.";
attribute predicateExpression = "allocatedTo->size() == 1";
constraint { true }
}
constraint def FunctionDecomposesIntoFunctionsRule :> MemoConsistencyRule {
attribute id = "CR-ONT-075";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "MemoFunction";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "The functional chain decomposes functions into functions. A function composed of a component, or owned by one, is confusing allocation with decomposition — the component is named by AllocatedTo, never by Composes.";
attribute predicateExpression = "composes->forAll(conformsTo(MemoFunction))";
constraint { true }
}
constraint def ExchangeHasFlowRule :> MemoConsistencyRule {
attribute id = "CR-ONT-076";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "ComponentExchange";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "An exchange states that something crosses a boundary, which is an EDGE, and the edge is a native flow. The part def exists for the budget and assurance attributes a reader has to find from the edge, so the two are named alike and this rule holds them together. An exchange with no flow is a budget attached to nothing.";
attribute predicateExpression = "linksOf(flow)->exists(id == subject.id)";
constraint { true }
}
constraint def AlternateScenarioHasBaseRule :> MemoConsistencyRule {
attribute id = "CR-ONT-043";
attribute tailoring = RuleTailoringKind::invariant;
attribute appliesTo = "OperativeScenario";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Alternate, exception, and recovery scenarios must identify their base scenario or variation point — never duplicate the workflow.";
attribute predicateExpression = "not(variantKind == 'alternate' or variantKind == 'exception' or variantKind == 'recovery') or baseScenario->size() == 1 or variationPoint != ''";
constraint { true }
}
}