memo_rules_closure
SysML API
Namespace hierarchy
memo → memo::rules → memo::rules::closure
Packages
| Package |
memo_rules_closure |
Imports
| Visibility |
Target |
| private |
ScalarValues::* |
| private |
memo_core_consistency_rules::* |
| private |
memo_core_enumerations::* |
| private |
memo_core_common::* |
| private |
memo_core_common::MemoIdentity |
| private |
memo_artifacts_standards_traceability::EnforcesClause |
| private |
memo_artifacts_standards_fda_cybersecurity_2023::* |
| private |
memo_artifacts_standards_iec_62304::* |
| private |
memo_artifacts_standards_iec_62366_1::* |
| private |
memo_artifacts_standards_iso_13485::* |
| private |
memo_artifacts_standards_iso_14971::* |
Declarations
| Name |
SysML kind |
Description |
Specializes |
HazardMitigationRule |
constraint def |
Constraint that checks hazard mitigation rule. |
MemoConsistencyRule |
HazardSeverityRule |
constraint def |
Constraint that checks hazard severity rule. |
MemoConsistencyRule |
RiskControlVerificationRule |
constraint def |
Constraint that checks risk control verification rule. |
MemoConsistencyRule |
InitialRiskMatrixRule |
constraint def |
Constraint that checks initial risk matrix rule. |
MemoConsistencyRule |
SysReqTraceRule |
constraint def |
Constraint that checks sys req trace rule. |
MemoConsistencyRule |
SwReqTraceRule |
constraint def |
Constraint that checks sw req trace rule. |
MemoConsistencyRule |
SwComponentSafetyClassRule |
constraint def |
Constraint that checks sw component safety class rule. |
MemoConsistencyRule |
SwComponentReqRule |
constraint def |
Constraint that checks sw component req rule. |
MemoConsistencyRule |
LogicalFunctionAllocationRule |
constraint def |
Constraint that checks logical function allocation rule. |
MemoConsistencyRule |
FunctionInChainRule |
constraint def |
A function that no edge reaches is not in the chain. This was a TypeScript rule (BV-002) applying to every action usage in the model, which reported a scenario and a flow step as defects for not being wired like a function.… |
MemoConsistencyRule |
UserNeedIdentifiesUserRule |
constraint def |
A user need names the user whose need it is. IEC 62366-1's user profile is typed on the User element — population, impairments, training, qualification — so the need points at that element rather than restating any of it in prose, which is what userPopulationReference was do… |
MemoConsistencyRule |
VerificationCaseMethodRule |
constraint def |
Constraint that checks verification case method rule. |
MemoConsistencyRule |
VerificationCaseTargetRule |
constraint def |
Constraint that checks verification case target rule. |
MemoConsistencyRule |
EvidenceProductionRule |
constraint def |
Constraint that checks evidence production rule. |
MemoConsistencyRule |
ThreatMitigationRule |
constraint def |
Constraint that checks threat mitigation rule. |
MemoConsistencyRule |
AssetThreatLinkRule |
constraint def |
Constraint that checks asset threat link rule. |
MemoConsistencyRule |
LogicalInterfaceDirectionRule |
constraint def |
Constraint that checks logical interface direction rule. |
MemoConsistencyRule |
SafetyClassCVerificationRule |
constraint def |
Constraint that checks safety class cverification rule. |
MemoConsistencyRule |
UiElementDesignRecordRule |
constraint def |
The load-bearing traceability rule. A UI element that is not chrome must reach a design record — a requirement it satisfies, or an action it triggers. Chrome must be DECLARED decoration; an element left unclassified fails rather than passing as scenery. |
MemoConsistencyRule |
ControlInvokesFunctionRule |
constraint def |
Interactive UI is where use error happens (IEC 62366-1), so a control that reaches no system function is either dead UI or unmodelled UI. The interactive-form restriction lives in the predicate because it spans several enum values. |
MemoConsistencyRule |
BoundsDetectionConfirmedRule |
constraint def |
Automatic boundary detection proposes; a reviewer disposes. An unconfirmed machine guess must never reach a design review looking like an engineering decision. |
MemoConsistencyRule |
ScreenCaptureProvenanceRule |
constraint def |
A screenshot with no build behind it is undated design intent, not evidence of what the device does. |
MemoConsistencyRule |
HazardHasSituationRule |
constraint def |
Written from the classification in plans/memo-rules-domain-trace-and-editor.md (Step 5): each checks a property the model carries, and each traces to the clause it enforces. |
MemoConsistencyRule |
SituationLeadsToHarmRule |
constraint def |
Constraint that checks situation leads to harm rule. |
MemoConsistencyRule |
RiskEstimateRule |
constraint def |
Constraint that checks risk estimate rule. |
MemoConsistencyRule |
RiskAcceptabilityRule |
constraint def |
Constraint that checks risk acceptability rule. |
MemoConsistencyRule |
ResidualRiskAcceptabilityRule |
constraint def |
Constraint that checks residual risk acceptability rule. |
MemoConsistencyRule |
ResidualRiskEvaluatedRule |
constraint def |
Constraint that checks residual risk evaluated rule. |
MemoConsistencyRule |
MisuseReachesSituationRule |
constraint def |
ISO 14971 clauses 5.2, 5.3 and 7.4 on the links the model already has: a misuse is not an item of the risk chain, so it reaches the chain by causes (the risk can start at any element: an operational flow, an FMEA row, a use error, a misuse); a safety-related characteristic r… |
MemoConsistencyRule |
CharacteristicReachesHazardRule |
constraint def |
Constraint that checks characteristic reaches hazard rule. |
MemoConsistencyRule |
BenefitRiskWeighedRule |
constraint def |
Constraint that checks benefit risk weighed rule. |
MemoConsistencyRule |
SoupAnomaliesRule |
constraint def |
Constraint that checks soup anomalies rule. |
MemoConsistencyRule |
SoupIdentifiedRule |
constraint def |
Constraint that checks soup identified rule. |
MemoConsistencyRule |
SoupRequirementRule |
constraint def |
Constraint that checks soup requirement rule. |
MemoConsistencyRule |
UnitDecompositionRule |
constraint def |
Constraint that checks unit decomposition rule. |
MemoConsistencyRule |
ChangeImpactRule |
constraint def |
Constraint that checks change impact rule. |
MemoConsistencyRule |
ChangeApprovalRule |
constraint def |
Constraint that checks change approval rule. |
MemoConsistencyRule |
ChangeTraceRule |
constraint def |
Constraint that checks change trace rule. |
MemoConsistencyRule |
HazardMitigationRule
constraint def HazardMitigationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks hazard mitigation rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
HazardSeverityRule
constraint def HazardSeverityRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks hazard severity rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
RiskControlVerificationRule
constraint def RiskControlVerificationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks risk control verification rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
InitialRiskMatrixRule
constraint def InitialRiskMatrixRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks initial risk matrix rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SysReqTraceRule
constraint def SysReqTraceRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks sys req trace rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SwReqTraceRule
constraint def SwReqTraceRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks sw req trace rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SwComponentSafetyClassRule
constraint def SwComponentSafetyClassRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks sw component safety class rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SwComponentReqRule
constraint def SwComponentReqRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks sw component req rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
LogicalFunctionAllocationRule
constraint def LogicalFunctionAllocationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks logical function allocation rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
FunctionInChainRule
constraint def FunctionInChainRule :> MemoConsistencyRule
| Property |
Value |
| Description |
A function that no edge reaches is not in the chain. This was a TypeScript rule (BV-002) applying to every action usage in the model, which reported a scenario and a flow step as defects for not being wired like a function.… |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
UserNeedIdentifiesUserRule
constraint def UserNeedIdentifiesUserRule :> MemoConsistencyRule
| Property |
Value |
| Description |
A user need names the user whose need it is. IEC 62366-1's user profile is typed on the User element — population, impairments, training, qualification — so the need points at that element rather than restating any of it in prose, which is what userPopulationReference was do… |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
VerificationCaseMethodRule
constraint def VerificationCaseMethodRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks verification case method rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
VerificationCaseTargetRule
constraint def VerificationCaseTargetRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks verification case target rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
EvidenceProductionRule
constraint def EvidenceProductionRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks evidence production rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ThreatMitigationRule
constraint def ThreatMitigationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks threat mitigation rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
AssetThreatLinkRule
constraint def AssetThreatLinkRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks asset threat link rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
LogicalInterfaceDirectionRule
constraint def LogicalInterfaceDirectionRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks logical interface direction rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SafetyClassCVerificationRule
constraint def SafetyClassCVerificationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks safety class cverification rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
UiElementDesignRecordRule
constraint def UiElementDesignRecordRule :> MemoConsistencyRule
| Property |
Value |
| Description |
The load-bearing traceability rule. A UI element that is not chrome must reach a design record — a requirement it satisfies, or an action it triggers. Chrome must be DECLARED decoration; an element left unclassified fails rather than passing as scenery. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ControlInvokesFunctionRule
constraint def ControlInvokesFunctionRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Interactive UI is where use error happens (IEC 62366-1), so a control that reaches no system function is either dead UI or unmodelled UI. The interactive-form restriction lives in the predicate because it spans several enum values. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
BoundsDetectionConfirmedRule
constraint def BoundsDetectionConfirmedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Automatic boundary detection proposes; a reviewer disposes. An unconfirmed machine guess must never reach a design review looking like an engineering decision. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ScreenCaptureProvenanceRule
constraint def ScreenCaptureProvenanceRule :> MemoConsistencyRule
| Property |
Value |
| Description |
A screenshot with no build behind it is undated design intent, not evidence of what the device does. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
HazardHasSituationRule
constraint def HazardHasSituationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Written from the classification in plans/memo-rules-domain-trace-and-editor.md (Step 5): each checks a property the model carries, and each traces to the clause it enforces. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SituationLeadsToHarmRule
constraint def SituationLeadsToHarmRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks situation leads to harm rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
RiskEstimateRule
constraint def RiskEstimateRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks risk estimate rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
RiskAcceptabilityRule
constraint def RiskAcceptabilityRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks risk acceptability rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ResidualRiskAcceptabilityRule
constraint def ResidualRiskAcceptabilityRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks residual risk acceptability rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ResidualRiskEvaluatedRule
constraint def ResidualRiskEvaluatedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks residual risk evaluated rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
MisuseReachesSituationRule
constraint def MisuseReachesSituationRule :> MemoConsistencyRule
| Property |
Value |
| Description |
ISO 14971 clauses 5.2, 5.3 and 7.4 on the links the model already has: a misuse is not an item of the risk chain, so it reaches the chain by causes (the risk can start at any element: an operational flow, an FMEA row, a use error, a misuse); a safety-related characteristic r… |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
CharacteristicReachesHazardRule
constraint def CharacteristicReachesHazardRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks characteristic reaches hazard rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
BenefitRiskWeighedRule
constraint def BenefitRiskWeighedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks benefit risk weighed rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SoupAnomaliesRule
constraint def SoupAnomaliesRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks soup anomalies rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SoupIdentifiedRule
constraint def SoupIdentifiedRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks soup identified rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
SoupRequirementRule
constraint def SoupRequirementRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks soup requirement rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
UnitDecompositionRule
constraint def UnitDecompositionRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks unit decomposition rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ChangeImpactRule
constraint def ChangeImpactRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks change impact rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ChangeApprovalRule
constraint def ChangeApprovalRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks change approval rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
ChangeTraceRule
constraint def ChangeTraceRule :> MemoConsistencyRule
| Property |
Value |
| Description |
Constraint that checks change trace rule. |
| Kind |
constraint def |
| Abstract |
No |
| Specializes |
MemoConsistencyRule |
| Owning package |
memo_rules_closure |
Source
rules/closure/closure_rules.sysml
package memo_rules_closure {
private import ScalarValues::*;
private import memo_core_consistency_rules::*;
private import memo_core_enumerations::*;
private import memo_core_common::*;
private import memo_core_common::MemoIdentity;
private import memo_artifacts_standards_traceability::EnforcesClause;
private import memo_artifacts_standards_fda_cybersecurity_2023::*;
private import memo_artifacts_standards_iec_62304::*;
private import memo_artifacts_standards_iec_62366_1::*;
private import memo_artifacts_standards_iso_13485::*;
private import memo_artifacts_standards_iso_14971::*;
constraint def HazardMitigationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-001"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Hazard";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "ISO 14971 requires each identified hazard to have risk control measures.";
attribute predicateExpression = "mitigates->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from HazardMitigationRule to iso14971::iso14971Clause7::iso14971Clause7_1;
constraint def HazardSeverityRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-002"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Hazard";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Hazard severity is required for risk estimation per ISO 14971.";
attribute predicateExpression = "attributes.severity != ''";
constraint { true }
}
#EnforcesClause dependency from HazardSeverityRule to iso14971::iso14971Clause5::iso14971Clause5_5;
constraint def RiskControlVerificationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-003"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "RiskControlMeasure";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Risk controls shall be verified per ISO 14971 clause 7.2.";
attribute predicateExpression = "verifiedBy->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from RiskControlVerificationRule to iso14971::iso14971Clause7::iso14971Clause7_2;
constraint def InitialRiskMatrixRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-004"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Risk";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Pre-mitigation risk must be assessed against a risk acceptability matrix.";
attribute predicateExpression = "assessedAgainst->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from InitialRiskMatrixRule to iso14971::iso14971Clause6;
constraint def SysReqTraceRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-010"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Requirement[requirementType=system]";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Requirements shall be traceable to stakeholder needs per ISO 13485.";
attribute predicateExpression = "derivesFrom->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from SysReqTraceRule to iso13485::iso13485Clause7::iso13485Clause7_3::iso13485Clause7_3_3;
constraint def SwReqTraceRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-011"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Requirement[requirementType=software]";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Software requirements derive from system requirements per IEC 62304.";
attribute predicateExpression = "derivesFrom->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from SwReqTraceRule to iec62304::iec62304Clause5::iec62304Clause5_2::iec62304Clause5_2_1;
constraint def SwComponentSafetyClassRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-020"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SoftwareModule";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "IEC 62304 requires safety classification for all software items.";
attribute predicateExpression = "attributes.safetyClass != ''";
constraint { true }
}
#EnforcesClause dependency from SwComponentSafetyClassRule to iec62304::iec62304Clause4::iec62304Clause4_3;
constraint def SwComponentReqRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-021"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "SoftwareModule";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Software items shall be linked to their requirements per IEC 62304.";
attribute predicateExpression = "satisfiedBy->size() >= 1";
constraint { true }
}
constraint def LogicalFunctionAllocationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-022"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "SystemFunction";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Functions should be allocated to implementation elements. A function definition is a type and is not allocated; its usages are.";
attribute predicateExpression = "isDefinition == 'true' or allocatedTo->size() >= 1";
constraint { true }
}
constraint def FunctionInChainRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-023"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "MemoFunction";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A function participates in the functional chain through a flow or a succession, through the functions it decomposes into, or by being performed — by a functional chain, or by the action that triggers it. One that participates in none of them is unreachable behaviour: nothing triggers it and nothing consumes what it produces.";
attribute predicateExpression = "isDefinition == 'true' or flow->size() >= 1 or succession->size() >= 1 or downstream(composes)->size() >= 1 or upstream(performs)->size() >= 1";
constraint { true }
}
constraint def UserNeedIdentifiesUserRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-024"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Need";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A user need is a need someone has. Which users a device serves, and what they can be assumed to see, know and do, is the input a usability engineering file is built from (IEC 62366-1 5.1); a need that names no user leaves that input to prose.";
attribute predicateExpression = "not(needKind == 'user' or needKind == 'clinicalUser' or needKind == 'patientUser') or heldBy->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from UserNeedIdentifiesUserRule to iec62366_1::iec62366_1Clause5::iec62366_1Clause5_1;
constraint def VerificationCaseMethodRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-030"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "VerificationCase";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Verification method (test, analysis, inspection, demonstration) required per IEC 62304.";
attribute predicateExpression = "attributes.methodKind != ''";
constraint { true }
}
constraint def VerificationCaseTargetRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-031"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "VerificationCase";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Verification cases must be linked to verifiable items.";
attribute predicateExpression = "verifiedBy->size() >= 1";
constraint { true }
}
constraint def EvidenceProductionRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-032"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "VerificationCase";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Verification results should be documented as evidence records.";
attribute predicateExpression = "producesEvidence->size() >= 1";
constraint { true }
}
constraint def ThreatMitigationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-040"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Threat";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "FDA cybersecurity guidance requires threat mitigation.";
attribute predicateExpression = "derivesCyberRequirement->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from ThreatMitigationRule to fdaCybersecurity2023::fdaCyberSection5::fdaCyberSection5A;
constraint def AssetThreatLinkRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-041"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "CybersecurityAsset";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Assets should have threat analysis per FDA cybersecurity guidance.";
attribute predicateExpression = "threatenedBy->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from AssetThreatLinkRule to fdaCybersecurity2023::fdaCyberSection5::fdaCyberSection5A;
constraint def LogicalInterfaceDirectionRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-050"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "Interface";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Interface direction required for integration analysis.";
attribute predicateExpression = "attributes.direction != ''";
constraint { true }
}
constraint def SafetyClassCVerificationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-101"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SoftwareModule";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "IEC 62304 requires rigorous verification for Class C software.";
attribute predicateExpression = "not(attributes.safetyClass == 'C') or verifiedBy->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from SafetyClassCVerificationRule to iec62304::iec62304Clause5::iec62304Clause5_5::iec62304Clause5_5_4, iec62304::iec62304Clause5::iec62304Clause5_5::iec62304Clause5_5_5;
constraint def UiElementDesignRecordRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-110"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "UIElement";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "Every functional UI element must have a design record — a requirement it satisfies or an action it triggers. Elements with formKind `decoration` are chrome and are exempt.";
attribute predicateExpression = "attributes.formKind == 'decoration' or satisfiedBy->size() >= 1 or elementTriggersAction->size() >= 1";
constraint { true }
}
constraint def ControlInvokesFunctionRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-111"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "UIElement";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "An interactive UI element (button, selector, slider, field) should trigger a UIAction that invokes a system function; otherwise the control's purpose is not in the model. Physical controls are OperatorInterfaceElement and are covered separately.";
attribute predicateExpression = "not(formKind == 'button' or formKind == 'selector' or formKind == 'slider' or formKind == 'field') or elementTriggersAction->size() >= 1";
constraint { true }
}
constraint def BoundsDetectionConfirmedRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-112"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "UIElement";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Automatically detected bounds are a proposal until a reviewer confirms them; released UI documentation should contain no unconfirmed automatic bounds.";
attribute predicateExpression = "not(attributes.detectionMethod == 'automatic') or attributes.confirmedBy != ''";
constraint { true }
}
constraint def ScreenCaptureProvenanceRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-113"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::modelling;
attribute obligation = RuleObligationKind::recommended;
attribute appliesTo = "ScreenCapture";
attribute severity = RuleSeverityKind::error;
attribute rationaleText = "A screen capture used as design or usability evidence must identify the build it was taken from and hash the image bytes, or it cannot be relied on in the DHF.";
attribute predicateExpression = "attributes.capturedBuild != '' and attributes.imageHash != ''";
constraint { true }
}
constraint def HazardHasSituationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-005"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Hazard";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A hazard is analysed through the hazardous situations it can lead to: a hazard that reaches no hazardous situation has not been analysed far enough to estimate a risk.";
attribute predicateExpression = "downstream(tracesRisk)->exists(conformsTo(HazardousSituation))";
constraint { true }
}
#EnforcesClause dependency from HazardHasSituationRule to iso14971::iso14971Clause5::iso14971Clause5_4;
constraint def SituationLeadsToHarmRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-006"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "HazardousSituation";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A hazardous situation is described by the harm it can cause; one that reaches no harm leaves the severity of the risk unestimated.";
attribute predicateExpression = "downstream(tracesRisk)->exists(conformsTo(Harm))";
constraint { true }
}
#EnforcesClause dependency from SituationLeadsToHarmRule to iso14971::iso14971Clause5::iso14971Clause5_4;
constraint def RiskEstimateRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-007"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Risk";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A risk is estimated from the probability of occurrence and the severity of the harm; a risk missing either has no estimate.";
attribute predicateExpression = "attributes.probabilityEstimate != '' and attributes.severityEstimate != ''";
constraint { true }
}
#EnforcesClause dependency from RiskEstimateRule to iso14971::iso14971Clause5::iso14971Clause5_5;
constraint def RiskAcceptabilityRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-008"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "Risk";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Each estimated risk is evaluated against the acceptability criteria, so a risk states whether it is acceptable.";
attribute predicateExpression = "attributes.acceptability != ''";
constraint { true }
}
#EnforcesClause dependency from RiskAcceptabilityRule to iso14971::iso14971Clause6;
constraint def ResidualRiskAcceptabilityRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-009"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ResidualRisk";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "After risk control the residual risk is evaluated: it follows a control and states whether it is acceptable.";
attribute predicateExpression = "reducedBy->size() >= 1 and attributes.acceptability != ''";
constraint { true }
}
#EnforcesClause dependency from ResidualRiskAcceptabilityRule to iso14971::iso14971Clause7::iso14971Clause7_3;
constraint def ResidualRiskEvaluatedRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-014"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ResidualRisk";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "The overall residual risk is evaluated from the individual residual risks, so each residual risk is an input to that evaluation.";
attribute predicateExpression = "evaluatedIn->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from ResidualRiskEvaluatedRule to iso14971::iso14971Clause8;
constraint def MisuseReachesSituationRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-027"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ReasonablyForeseeableMisuse";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Reasonably foreseeable misuse is an input to the risk analysis: a misuse that leads to no hazardous situation has not been analysed, and one that is not recorded as leading anywhere cannot be shown to have been considered.";
attribute predicateExpression = "downstream(causes)->exists(conformsTo(HazardousSituation) or downstream(tracesRisk)->exists(conformsTo(HazardousSituation)))";
constraint { true }
}
#EnforcesClause dependency from MisuseReachesSituationRule to iso14971::iso14971Clause5::iso14971Clause5_2;
constraint def CharacteristicReachesHazardRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-028"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SafetyRelatedCharacteristic";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A characteristic that could affect safety is identified so that the hazards it bears on are analysed: one linked to no hazard has been identified and then left unused.";
attribute predicateExpression = "downstream(impactsSafety)->exists(conformsTo(RiskItem))";
constraint { true }
}
#EnforcesClause dependency from CharacteristicReachesHazardRule to iso14971::iso14971Clause5::iso14971Clause5_3;
constraint def BenefitRiskWeighedRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-029"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ResidualRisk";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "Where a residual risk calls for a benefit-risk analysis, the benefit it is weighed against is stated.";
attribute predicateExpression = "attributes.benefitRiskRequired != 'true' or upstream(weighedAgainst)->exists(conformsTo(Benefit))";
constraint { true }
}
#EnforcesClause dependency from BenefitRiskWeighedRule to iso14971::iso14971Clause7::iso14971Clause7_4;
constraint def SoupAnomaliesRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-015"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SOUPSoftwareModule";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "The published anomaly list of a SOUP item is evaluated for anomalies that could lead to a hazardous situation, and the result is recorded on the item.";
attribute predicateExpression = "attributes.knownAnomalies != ''";
constraint { true }
}
#EnforcesClause dependency from SoupAnomaliesRule to iec62304::iec62304Clause7::iec62304Clause7_1::iec62304Clause7_1_3;
constraint def SoupIdentifiedRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-016"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SOUPSoftwareModule";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A SOUP item is identified under configuration management by its title, manufacturer and version, so a SOUP item states a vendor and a version.";
attribute predicateExpression = "attributes.version != '' and attributes.supplier != ''";
constraint { true }
}
#EnforcesClause dependency from SoupIdentifiedRule to iec62304::iec62304Clause8::iec62304Clause8_1::iec62304Clause8_1_2;
constraint def SoupRequirementRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-017"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SOUPSoftwareModule";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "The functional and performance a software item needs from a SOUP item are stated as requirements, so a SOUP item is the subject of at least one requirement.";
attribute predicateExpression = "satisfiedBy->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from SoupRequirementRule to iec62304::iec62304Clause5::iec62304Clause5_3::iec62304Clause5_3_3;
constraint def UnitDecompositionRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-018"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "SoftwareModule";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A software item of safety class B or C is subdivided into software units, so such an item contains at least one module of kind unit.";
attribute predicateExpression = "not(attributes.moduleKind == 'item' and (attributes.safetyClass == 'B' or attributes.safetyClass == 'C')) or downstream(composes)->exists(attributes.moduleKind == 'unit')";
constraint { true }
}
#EnforcesClause dependency from UnitDecompositionRule to iec62304::iec62304Clause5::iec62304Clause5_4::iec62304Clause5_4_1;
constraint def ChangeImpactRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-019"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ChangeRequest";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A change request is analysed for its effect on the organisation, the released software and the systems that interface with it, and the analysis is recorded on the request.";
attribute predicateExpression = "attributes.impactAssessment != ''";
constraint { true }
}
#EnforcesClause dependency from ChangeImpactRule to iec62304::iec62304Clause6::iec62304Clause6_2::iec62304Clause6_2_3;
constraint def ChangeApprovalRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-025"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ChangeRequest";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A change request records whether it was approved before the change is made.";
attribute predicateExpression = "attributes.approvalStatus != ''";
constraint { true }
}
#EnforcesClause dependency from ChangeApprovalRule to iec62304::iec62304Clause6::iec62304Clause6_2::iec62304Clause6_2_4, iec62304::iec62304Clause8::iec62304Clause8_2::iec62304Clause8_2_1;
constraint def ChangeTraceRule :> MemoConsistencyRule {
@MemoIdentity { :>> providedId = "CR-MED-026"; }
attribute tailoring = RuleTailoringKind::assurance;
attribute domain = RuleDomainKind::medicalDevice;
attribute obligation = RuleObligationKind::required;
attribute appliesTo = "ChangeRequest";
attribute severity = RuleSeverityKind::warning;
attribute rationaleText = "A change request is traceable to the items it changes, so it has a changes relation to at least one element.";
attribute predicateExpression = "changes->size() >= 1";
constraint { true }
}
#EnforcesClause dependency from ChangeTraceRule to iec62304::iec62304Clause8::iec62304Clause8_2::iec62304Clause8_2_4;
}