@memoarchitect/ontology 0.10.9 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/examples/gpca-pump/memo.identity.yaml +12 -6
  3. package/examples/gpca-pump/model/catalog/gpca_context.sysml +7 -4
  4. package/examples/gpca-pump/model/catalog/gpca_requirements.sysml +100 -100
  5. package/examples/nested-architecture-dsm/memo.identity.yaml +181 -0
  6. package/examples/nested-architecture-dsm/model/catalog/architecture/operational/context.sysml +34 -0
  7. package/examples/nested-architecture-dsm/model/catalog/assurance/requirements/needs.sysml +5 -2
  8. package/examples/nested-architecture-dsm/model/catalog/assurance/requirements/requirements.sysml +7 -7
  9. package/examples/nested-architecture-dsm/model/catalog/project.sysml +1 -0
  10. package/examples/surgical-closure-workflow/model/catalog/surgical_closure_workflow.sysml +3 -0
  11. package/examples/sysml-diagram-samples/model/catalog/viewpoints/unassigned/views/requirements_view.sysml +3 -3
  12. package/examples/ui-screen-regions/memo.identity.yaml +205 -0
  13. package/examples/ui-screen-regions/model/catalog/assurance/requirements/requirements.sysml +12 -12
  14. package/extensions/aadl/memo.package.yaml +1 -1
  15. package/extensions/cloud/memo.package.yaml +1 -1
  16. package/extensions/container/memo.package.yaml +1 -1
  17. package/extensions/messaging/memo.package.yaml +1 -1
  18. package/extensions/ros/memo.package.yaml +1 -1
  19. package/methodologies/default/memo.package.yaml +1 -1
  20. package/methodologies/gpca/memo.package.yaml +1 -1
  21. package/ontology/memo.package.yaml +1 -1
  22. package/package.json +1 -1
  23. package/profile/memo.package.yaml +1 -1
  24. package/src/architecture/operational/scenarios/memo_scenarios.sysml +1 -2
  25. package/src/artifacts/templates/dhf/iec-60601/hrs.md +6 -6
  26. package/src/artifacts/templates/dhf/iec-62304/srs.md +10 -10
  27. package/src/artifacts/templates/dhf/system/syrs.md +6 -6
  28. package/src/assurance/cybersecurity/memo_cybersecurity.sysml +5 -1
  29. package/src/assurance/human_factors/memo_human_factors.sysml +0 -1
  30. package/src/assurance/requirements/memo_requirements.sysml +20 -16
  31. package/src/assurance/requirements/needs/memo_needs.sysml +33 -5
  32. package/src/assurance/safety_risk/memo_risk.sysml +39 -16
  33. package/src/assurance/verification_validation/memo_assurance.sysml +18 -0
  34. package/src/rules/closure/closure_rules.sysml +36 -2
  35. package/src/rules/crosslayer/cross_layer_rules.sysml +1 -1
  36. package/src/rules/ontology/ontology_invariants.sysml +13 -2
@@ -56,7 +56,7 @@ package memo_rules_closure {
56
56
  constraint def SysReqTraceRule :> MemoConsistencyRule {
57
57
  @MemoIdentity { :>> providedId = "CR-MED-010"; }
58
58
  attribute tailoring = RuleTailoringKind::assurance;
59
- attribute appliesTo = "Requirement[requirementKind=system]";
59
+ attribute appliesTo = "Requirement[requirementType=system]";
60
60
  attribute severity = RuleSeverityKind::error;
61
61
  attribute rationaleText = "Requirements shall be traceable to stakeholder needs per ISO 13485.";
62
62
  attribute predicateExpression = "derivesFrom->size() >= 1";
@@ -66,7 +66,7 @@ package memo_rules_closure {
66
66
  constraint def SwReqTraceRule :> MemoConsistencyRule {
67
67
  @MemoIdentity { :>> providedId = "CR-MED-011"; }
68
68
  attribute tailoring = RuleTailoringKind::assurance;
69
- attribute appliesTo = "Requirement[requirementKind=software]";
69
+ attribute appliesTo = "Requirement[requirementType=software]";
70
70
  attribute severity = RuleSeverityKind::error;
71
71
  attribute rationaleText = "Software requirements derive from system requirements per IEC 62304.";
72
72
  attribute predicateExpression = "derivesFrom->size() >= 1";
@@ -111,6 +111,40 @@ package memo_rules_closure {
111
111
  constraint { true }
112
112
  }
113
113
 
114
+ // A function that no edge reaches is not in the chain. This was a
115
+ // TypeScript rule (BV-002) applying to every action usage in the model,
116
+ // which reported a scenario and a flow step as defects for not being
117
+ // wired like a function. It is declared here instead: scoped by the
118
+ // ontology to the family it is about, tailorable by a methodology, and
119
+ // readable next to the rule that requires the allocation.
120
+ constraint def FunctionInChainRule :> MemoConsistencyRule {
121
+ @MemoIdentity { :>> providedId = "CR-MED-023"; }
122
+ attribute tailoring = RuleTailoringKind::assurance;
123
+ attribute appliesTo = "MemoFunction";
124
+ attribute severity = RuleSeverityKind::warning;
125
+ attribute rationaleText = "A function participates in the functional chain through a flow or a succession, or through the functions it decomposes into. One that participates in none of them is unreachable behaviour: nothing triggers it and nothing consumes what it produces.";
126
+ // `downstream` and not a bare `composes`: the relation navigates both
127
+ // ways, so a bare name would exempt every child on the strength of
128
+ // having a parent. A decomposed function participates through its
129
+ // parts; a leaf has to be reached by an edge of its own.
130
+ attribute predicateExpression = "flow->size() >= 1 or succession->size() >= 1 or downstream(composes)->size() >= 1";
131
+ constraint { true }
132
+ }
133
+
134
+ // A user need names the user whose need it is. IEC 62366-1's user profile
135
+ // is typed on the User element — population, impairments, training,
136
+ // qualification — so the need points at that element rather than restating
137
+ // any of it in prose, which is what `userPopulationReference` was doing.
138
+ constraint def UserNeedIdentifiesUserRule :> MemoConsistencyRule {
139
+ @MemoIdentity { :>> providedId = "CR-MED-024"; }
140
+ attribute tailoring = RuleTailoringKind::assurance;
141
+ attribute appliesTo = "Need";
142
+ attribute severity = RuleSeverityKind::warning;
143
+ 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.";
144
+ attribute predicateExpression = "not(needKind == 'user' or needKind == 'clinicalUser' or needKind == 'patientUser') or heldBy->size() >= 1";
145
+ constraint { true }
146
+ }
147
+
114
148
  // ─── Verification Layer Rules ────────────────────────────────────────
115
149
 
116
150
  constraint def VerificationCaseMethodRule :> MemoConsistencyRule {
@@ -21,7 +21,7 @@ package memo_rules_crosslayer {
21
21
  constraint def ReqToArchTraceRule :> MemoConsistencyRule {
22
22
  @MemoIdentity { :>> providedId = "XL-002"; }
23
23
  attribute tailoring = RuleTailoringKind::assurance;
24
- attribute appliesTo = "Requirement[requirementKind=system]";
24
+ attribute appliesTo = "Requirement[requirementType=system]";
25
25
  attribute severity = RuleSeverityKind::warning;
26
26
  attribute rationaleText = "Requirements-to-architecture traceability per IEC 62304.";
27
27
  attribute predicateExpression = "satisfiedBy->size() >= 1";
@@ -349,13 +349,24 @@ package memo_rules_ontology {
349
349
  constraint { true }
350
350
  }
351
351
 
352
+ // The predicate here named three features that do not exist — `variantKind`,
353
+ // `baseScenario`, `variationPoint` — so it could never fail, and a rule that
354
+ // cannot fail is coverage on paper only. `baseScenario` is the one the
355
+ // scenario def deliberately refused: "a nominal/alternate pair are scenarios
356
+ // of the same workflow, distinguished by scenarioKind — no baseScenario
357
+ // back-ref". The base of an alternate IS the nominal scenario of its
358
+ // workflow, so the rule asks the containment that already expresses it.
352
359
  constraint def AlternateScenarioHasBaseRule :> MemoConsistencyRule {
353
360
  @MemoIdentity { :>> providedId = "CR-ONT-043"; }
354
361
  attribute tailoring = RuleTailoringKind::invariant;
355
362
  attribute appliesTo = "OperativeScenario";
356
363
  attribute severity = RuleSeverityKind::error;
357
- attribute rationaleText = "Alternate, exception, and recovery scenarios must identify their base scenario or variation point — never duplicate the workflow.";
358
- attribute predicateExpression = "not(variantKind == 'alternate' or variantKind == 'exception' or variantKind == 'recovery') or baseScenario->size() == 1 or variationPoint != ''";
364
+ attribute rationaleText = "An alternate scenario is a variation of a nominal path, so it belongs to a workflow that has one. An alternate with no nominal sibling is either a workflow with no happy path or a scenario filed under the wrong parent.";
365
+ // A nominal scenario usually says nothing: `nominal` is the default on
366
+ // the definition, and a default is not written onto every usage. So the
367
+ // sibling test is "not alternate", and `conformsTo` keeps it from being
368
+ // satisfied by an ordinary step of the same workflow.
369
+ attribute predicateExpression = "not(scenarioKind == 'alternate') or composes.composes->exists(conformsTo(OperativeScenario) and scenarioKind != 'alternate')";
359
370
  constraint { true }
360
371
  }
361
372