@memoarchitect/ontology 0.10.9 → 0.11.0

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 (35) 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 +0 -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 +20 -0
  33. package/src/rules/closure/closure_rules.sysml +36 -2
  34. package/src/rules/crosslayer/cross_layer_rules.sysml +1 -1
  35. package/src/rules/ontology/ontology_invariants.sysml +13 -2
@@ -21,7 +21,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
21
21
  // ── The spec side ───────────────────────────────────────────
22
22
  requirement reqRateEntry : Requirement {
23
23
  @MemoIdentity { :>> providedId = "UIR-REQ-001"; } attribute :>> name = "RateEntryConfirmation";
24
- attribute :>> requirementKind = RequirementKind::software;
24
+ attribute :>> requirementType = RequirementTypeKind::software;
25
25
  attribute :>> statement = "When the clinician enters a new infusion rate, the pump shall display the entered rate for explicit confirmation before applying it.";
26
26
  attribute :>> notation = RequirementNotationKind::ears;
27
27
  attribute :>> earsPattern = EarsPatternKind::eventDriven;
@@ -34,7 +34,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
34
34
 
35
35
  requirement reqRateLegibility : Requirement {
36
36
  @MemoIdentity { :>> providedId = "UIR-REQ-002"; } attribute :>> name = "RateLegibility";
37
- attribute :>> requirementKind = RequirementKind::system;
37
+ attribute :>> requirementType = RequirementTypeKind::system;
38
38
  attribute :>> statement = "The pump shall display the active infusion rate legibly at 1 m under 100–1000 lux ambient illumination.";
39
39
  attribute :>> notation = RequirementNotationKind::sophist;
40
40
  attribute :>> obligation = ObligationKind::shall;
@@ -48,7 +48,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
48
48
 
49
49
  requirement reqVolumeDisplay : Requirement {
50
50
  @MemoIdentity { :>> providedId = "UIR-REQ-003"; } attribute :>> name = "VolumeDeliveredDisplay";
51
- attribute :>> requirementKind = RequirementKind::software;
51
+ attribute :>> requirementType = RequirementTypeKind::software;
52
52
  attribute :>> statement = "The pump shall display cumulative volume delivered for the active infusion, updated at least once per second.";
53
53
  attribute :>> notation = RequirementNotationKind::ears;
54
54
  attribute :>> earsPattern = EarsPatternKind::stateDriven;
@@ -60,7 +60,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
60
60
 
61
61
  requirement reqDrugLibrarySelection : Requirement {
62
62
  @MemoIdentity { :>> providedId = "UIR-REQ-004"; } attribute :>> name = "DrugLibrarySelection";
63
- attribute :>> requirementKind = RequirementKind::software;
63
+ attribute :>> requirementType = RequirementTypeKind::software;
64
64
  attribute :>> statement = "The pump shall permit selection only from drug and concentration entries enabled for the active care area.";
65
65
  attribute :>> notation = RequirementNotationKind::ears;
66
66
  attribute :>> earsPattern = EarsPatternKind::stateDriven;
@@ -73,7 +73,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
73
73
 
74
74
  requirement reqDisplayFreshness : Requirement {
75
75
  @MemoIdentity { :>> providedId = "UIR-REQ-005"; } attribute :>> name = "InfusionStatusFreshness";
76
- attribute :>> requirementKind = RequirementKind::system;
76
+ attribute :>> requirementType = RequirementTypeKind::system;
77
77
  attribute :>> statement = "The pump shall refresh the displayed active rate and cumulative delivered volume at least once per second while an infusion is running.";
78
78
  attribute :>> notation = RequirementNotationKind::sophist;
79
79
  attribute :>> obligation = ObligationKind::shall;
@@ -87,7 +87,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
87
87
 
88
88
  requirement reqActiveRateDisplay : Requirement {
89
89
  @MemoIdentity { :>> providedId = "UIR-REQ-006"; } attribute :>> name = "ActiveInfusionRateDisplay";
90
- attribute :>> requirementKind = RequirementKind::software;
90
+ attribute :>> requirementType = RequirementTypeKind::software;
91
91
  attribute :>> statement = "While an infusion is running, the pump shall display the active infusion rate value and its mL/h unit.";
92
92
  attribute :>> notation = RequirementNotationKind::ears;
93
93
  attribute :>> earsPattern = EarsPatternKind::stateDriven;
@@ -100,7 +100,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
100
100
 
101
101
  requirement reqDrugIdentityDisplay : Requirement {
102
102
  @MemoIdentity { :>> providedId = "UIR-REQ-007"; } attribute :>> name = "ActiveDrugIdentityDisplay";
103
- attribute :>> requirementKind = RequirementKind::software;
103
+ attribute :>> requirementType = RequirementTypeKind::software;
104
104
  attribute :>> statement = "Where a drug-library entry is active, the pump shall display the selected drug name and concentration on the running-infusion screen.";
105
105
  attribute :>> notation = RequirementNotationKind::ears;
106
106
  attribute :>> earsPattern = EarsPatternKind::optionalFeature;
@@ -113,7 +113,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
113
113
 
114
114
  requirement reqTimeDisplay : Requirement {
115
115
  @MemoIdentity { :>> providedId = "UIR-REQ-008"; } attribute :>> name = "LocalTimeDisplay";
116
- attribute :>> requirementKind = RequirementKind::software;
116
+ attribute :>> requirementType = RequirementTypeKind::software;
117
117
  attribute :>> statement = "While the running-infusion screen is visible, the pump shall display synchronized local time in 24-hour HH:mm format.";
118
118
  attribute :>> notation = RequirementNotationKind::ears;
119
119
  attribute :>> earsPattern = EarsPatternKind::stateDriven;
@@ -125,7 +125,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
125
125
 
126
126
  requirement reqTimeAccuracy : Requirement {
127
127
  @MemoIdentity { :>> providedId = "UIR-REQ-009"; } attribute :>> name = "DisplayedTimeAccuracy";
128
- attribute :>> requirementKind = RequirementKind::system;
128
+ attribute :>> requirementType = RequirementTypeKind::system;
129
129
  attribute :>> statement = "The running-infusion display shall present local time within 2 seconds of the synchronized device clock and refresh the visible minute within 1 second of rollover.";
130
130
  attribute :>> notation = RequirementNotationKind::sophist;
131
131
  attribute :>> obligation = ObligationKind::shall;
@@ -139,7 +139,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
139
139
 
140
140
  requirement reqBatteryStatusDisplay : Requirement {
141
141
  @MemoIdentity { :>> providedId = "UIR-REQ-010"; } attribute :>> name = "BatteryStatusDisplay";
142
- attribute :>> requirementKind = RequirementKind::software;
142
+ attribute :>> requirementType = RequirementTypeKind::software;
143
143
  attribute :>> statement = "While the pump is operating, the pump shall display battery state of charge as a percentage and graphical icon.";
144
144
  attribute :>> notation = RequirementNotationKind::ears;
145
145
  attribute :>> earsPattern = EarsPatternKind::stateDriven;
@@ -152,7 +152,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
152
152
 
153
153
  requirement reqBatteryWarningPerformance : Requirement {
154
154
  @MemoIdentity { :>> providedId = "UIR-REQ-011"; } attribute :>> name = "LowBatteryStatusLatency";
155
- attribute :>> requirementKind = RequirementKind::system;
155
+ attribute :>> requirementType = RequirementTypeKind::system;
156
156
  attribute :>> statement = "When estimated battery operating time falls below 30 minutes, the pump shall present a visually prominent low-battery state within 1 second.";
157
157
  attribute :>> notation = RequirementNotationKind::sophist;
158
158
  attribute :>> obligation = ObligationKind::shall;
@@ -166,7 +166,7 @@ package memo_examples_ui_screen_regions_assurance_requirements {
166
166
 
167
167
  requirement reqDrugSelectionPerformance : Requirement {
168
168
  @MemoIdentity { :>> providedId = "UIR-REQ-012"; } attribute :>> name = "DrugSelectorResponseTime";
169
- attribute :>> requirementKind = RequirementKind::software;
169
+ attribute :>> requirementType = RequirementTypeKind::software;
170
170
  attribute :>> statement = "When the clinician activates the drug selector, the pump shall display the enabled drug list within 250 milliseconds.";
171
171
  attribute :>> notation = RequirementNotationKind::ears;
172
172
  attribute :>> earsPattern = EarsPatternKind::eventDriven;
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/extension-aadl'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: AADL (SAE AS5506) correspondence profile and runtime component families
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/extension-cloud'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: Networked services and managed data stores
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/extension-container'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: OCI container images and container runtimes as deployment content
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/extension-messaging'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: Publish/subscribe messaging — topics, brokers, and delivery semantics
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/extension-ros'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: ROS 2 nodes, messages, topic/service/action interfaces, QoS, and containerized deployment
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/methodology-default'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: "MEMO default medical-device methodology \u2014 selects viewpoints/views/DHF documents from @memoarchitect/ontology and adds rules, gates, patterns, profiles, and workflow."
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/methodology-gpca'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: "GPCA infusion pump methodology \u2014 subtraction-based tailoring of @memoarchitect/methodology-default for the non-networked prototype variant. Excludes cybersecurity and SOUP."
12
12
  license: MIT
13
13
  tags:
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/ontology'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: "MEMO \u2014 the single canonical medical-device ontology: core semantics, the Arcadia-inspired architecture layers (context, requirements, behavior, structure, interfaces, risk, cybersecurity,\
12
12
  \ assurance, \u2026), compliance, viewpoints, views, and invariant rules. One namespace (memo::), one src/ tree."
13
13
  license: MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoarchitect/ontology",
3
- "version": "0.10.9",
3
+ "version": "0.11.0",
4
4
  "packageManager": "pnpm@9.15.0",
5
5
  "description": "MEMO — Medical Engineering Modelling Ontology. Pure SysML v2 medical-device ontology with native constraints, portable to any conformant SysML v2 tool (SysIDE, SysON, sysand).",
6
6
  "scripts": {
@@ -7,7 +7,7 @@
7
7
  # (`type`, `extends`, `usage`, `ontologies`, `methodology`, `modules`) were
8
8
  # removed at the native semantic flip and are now rejected if present.
9
9
  name: '@memoarchitect/medical-modeling-profile'
10
- version: 0.8.24
10
+ version: 0.11.0
11
11
  description: Closure rules and viewpoints for medical device modeling
12
12
  license: MIT
13
13
  tags:
@@ -42,13 +42,12 @@ package memo_architecture_operational_scenarios {
42
42
  attribute assumptionSummary : String;
43
43
  attribute guaranteeSummary : String;
44
44
  attribute securityObjective : String;
45
- attribute abuseCaseReference : String;
45
+ ref abuseCase : OperativeScenario[0..1];
46
46
  attribute defaultCategory : ThreatCategoryKind[0..1];
47
47
  // verification scenario
48
48
  attribute verificationEnvironment : String;
49
49
  attribute stimulusSummary : String;
50
50
  // hazard-related use scenario (IEC 62366-1 3.9)
51
- attribute hazardReference : String;
52
51
  attribute selectionRationale : String;
53
52
  }
54
53
 
@@ -16,7 +16,7 @@ required_for: ["CE", "FDA_510k", "MDR"]
16
16
 
17
17
  This Hardware Requirements Specification (HRS) defines the safety, construction, and performance requirements for the **{{project.product}}** physical equipment, ensuring compliance with IEC 60601-1 (general safety) and applicable collateral standards (IEC 60601-1-2 for electromagnetic compatibility).
18
18
 
19
- Hardware requirements are identified by the model's `requirementKind` attribute. Per-topic sections — construction, electrical, EMC, mechanical — are **not** name filters: each is the set of elements claiming the clause that governs that topic, selected by traversing `ConformsTo` to that clause. A clause is named by its element id rather than by its number, because a clause number is not unique across standards: "8" is a clause of IEC 60601-1, of IEC 60601-1-2 and of IEC 62304.
19
+ Hardware requirements are identified by the model's `requirementType` attribute. Per-topic sections — construction, electrical, EMC, mechanical — are **not** name filters: each is the set of elements claiming the clause that governs that topic, selected by traversing `ConformsTo` to that clause. A clause is named by its element id rather than by its number, because a clause number is not unique across standards: "8" is a clause of IEC 60601-1, of IEC 60601-1-2 and of IEC 62304.
20
20
 
21
21
  ---
22
22
 
@@ -26,7 +26,7 @@ Summary metrics for the hardware requirements captured in the model:
26
26
 
27
27
  ```memo-query
28
28
  kind: Requirement
29
- where: requirementKind == "RequirementKind::hardware"
29
+ where: requirementType == "RequirementTypeKind::hardware"
30
30
  display: count
31
31
  label: Total hardware requirements
32
32
  ```
@@ -35,11 +35,11 @@ label: Total hardware requirements
35
35
 
36
36
  ```memo-query
37
37
  kind: Requirement
38
- where: requirementKind == "RequirementKind::hardware"
38
+ where: requirementType == "RequirementTypeKind::hardware"
39
39
  display: table
40
- columns: name, requirementKind, electricalSafetyRelevant, doc
40
+ columns: name, requirementType, electricalSafetyRelevant, doc
41
41
  sort: name
42
- empty: "No hardware requirements defined. Add Requirement elements with requirementKind = hardware."
42
+ empty: "No hardware requirements defined. Add Requirement elements with requirementType = hardware."
43
43
  ```
44
44
 
45
45
  ---
@@ -142,7 +142,7 @@ Hardware requirements traced to the elements that satisfy them:
142
142
 
143
143
  ```memo-query
144
144
  kind: Requirement
145
- where: requirementKind == "RequirementKind::hardware"
145
+ where: requirementType == "RequirementTypeKind::hardware"
146
146
  traverse: outgoing satisfiedBy
147
147
  display: table
148
148
  columns: name, kind, layer, doc
@@ -16,7 +16,7 @@ required_for: ["CE", "FDA_510k", "MDR"]
16
16
 
17
17
  This Software Requirements Specification (SRS) defines the software requirements for **{{project.product}}** in accordance with IEC 62304:2006+AMD1:2015 §5.2.
18
18
 
19
- Software, hardware and system requirements are distinguished by the model's own `requirementKind` attribute, never by which layer directory a file sits in and never by what a requirement is called. There is no "software layer": hardware and software are sibling directories inside `implementation`.
19
+ Software, hardware and system requirements are distinguished by the model's own `requirementType` attribute, never by which layer directory a file sits in and never by what a requirement is called. There is no "software layer": hardware and software are sibling directories inside `implementation`.
20
20
 
21
21
  ---
22
22
 
@@ -26,14 +26,14 @@ Summary metrics for the requirements captured in the model:
26
26
 
27
27
  ```memo-query
28
28
  kind: Requirement
29
- where: requirementKind == "RequirementKind::software"
29
+ where: requirementType == "RequirementTypeKind::software"
30
30
  display: count
31
31
  label: Total software requirements
32
32
  ```
33
33
 
34
34
  ```memo-query
35
35
  kind: Requirement
36
- where: requirementKind == "RequirementKind::system"
36
+ where: requirementType == "RequirementTypeKind::system"
37
37
  display: count
38
38
  label: System requirements
39
39
  ```
@@ -48,7 +48,7 @@ Requirements carrying a `shall` obligation — the binding ones:
48
48
  kind: Requirement
49
49
  where: obligation == "ObligationKind::shall"
50
50
  display: table
51
- columns: name, requirementKind, safetyClass, doc
51
+ columns: name, requirementType, safetyClass, doc
52
52
  sort: name
53
53
  empty: "No requirements carry a `shall` obligation. Set `obligation` on Requirement elements."
54
54
  ```
@@ -57,11 +57,11 @@ empty: "No requirements carry a `shall` obligation. Set `obligation` on Requirem
57
57
 
58
58
  ```memo-query
59
59
  kind: Requirement
60
- where: requirementKind == "RequirementKind::software"
60
+ where: requirementType == "RequirementTypeKind::software"
61
61
  display: table
62
- columns: name, requirementKind, safetyClass, doc
62
+ columns: name, requirementType, safetyClass, doc
63
63
  sort: name
64
- empty: "No software requirements defined. Add Requirement elements with requirementKind = software."
64
+ empty: "No software requirements defined. Add Requirement elements with requirementType = software."
65
65
  ```
66
66
 
67
67
  ---
@@ -97,9 +97,9 @@ System requirements allocated to software per IEC 62304 §5.2, drawn from the mo
97
97
 
98
98
  ```memo-query
99
99
  kind: Requirement
100
- where: requirementKind == "RequirementKind::system"
100
+ where: requirementType == "RequirementTypeKind::system"
101
101
  display: table
102
- columns: name, requirementKind, safetyClass, doc
102
+ columns: name, requirementType, safetyClass, doc
103
103
  sort: name
104
104
  empty: "No system requirements defined."
105
105
  ```
@@ -155,7 +155,7 @@ empty: "No SOUP identified. Add DependsOnSoup links from software items to the S
155
155
 
156
156
  ```memo-query
157
157
  kind: Requirement
158
- where: requirementKind == "RequirementKind::software"
158
+ where: requirementType == "RequirementTypeKind::software"
159
159
  traverse: outgoing verifiedBy
160
160
  display: table
161
161
  columns: name, kind, layer, doc
@@ -26,7 +26,7 @@ Summary metrics for the system requirements captured in the model:
26
26
 
27
27
  ```memo-query
28
28
  kind: Requirement
29
- where: requirementKind == "RequirementKind::system"
29
+ where: requirementType == "RequirementTypeKind::system"
30
30
  display: count
31
31
  label: Total system requirements
32
32
  ```
@@ -41,7 +41,7 @@ Binding system requirements — those carrying a `shall` obligation:
41
41
  kind: Requirement
42
42
  where: obligation == "ObligationKind::shall"
43
43
  display: table
44
- columns: name, requirementKind, doc
44
+ columns: name, requirementType, doc
45
45
  sort: name
46
46
  empty: "No requirements carry a `shall` obligation. Set `obligation` on Requirement elements."
47
47
  ```
@@ -50,11 +50,11 @@ empty: "No requirements carry a `shall` obligation. Set `obligation` on Requirem
50
50
 
51
51
  ```memo-query
52
52
  kind: Requirement
53
- where: requirementKind == "RequirementKind::system"
53
+ where: requirementType == "RequirementTypeKind::system"
54
54
  display: table
55
- columns: name, requirementKind, safetyClass, doc
55
+ columns: name, requirementType, safetyClass, doc
56
56
  sort: name
57
- empty: "No system requirements defined. Add Requirement elements with requirementKind = system."
57
+ empty: "No system requirements defined. Add Requirement elements with requirementType = system."
58
58
  ```
59
59
 
60
60
  ---
@@ -67,7 +67,7 @@ How system requirements are allocated down to hardware and software.
67
67
 
68
68
  ```memo-query
69
69
  kind: Requirement
70
- where: requirementKind == "RequirementKind::system"
70
+ where: requirementType == "RequirementTypeKind::system"
71
71
  traverse: outgoing satisfiedBy
72
72
  display: table
73
73
  columns: name, kind, layer, doc
@@ -53,7 +53,6 @@ package memo_assurance_cybersecurity {
53
53
  attribute safetyImpact : String;
54
54
  attribute privacyImpact : String;
55
55
  attribute operationalImpact : String;
56
- attribute linkedSafetyHazardId : String;
57
56
  }
58
57
 
59
58
  part def CyberRisk specializes Risk {
@@ -15,7 +15,6 @@ package memo_assurance_human_factors {
15
15
 
16
16
  part def UseError specializes MemoPart {
17
17
  attribute errorCategory : UseErrorCategoryKind;
18
- attribute taskReference : String;
19
18
  attribute severity : SeverityKind;
20
19
  attribute rootCauseType : String;
21
20
  }
@@ -7,25 +7,32 @@ package memo_assurance_requirements {
7
7
  private import memo_assurance_requirements_needs::*;
8
8
  part def RiskDriver specializes RequirementDriver { attribute driverKind : String; }
9
9
 
10
- // The kind of requirement. Was a subclass branch (SystemRequirement /
11
- // SoftwareRequirement / HardwareRequirement) plus a parallel design-control
12
- // specification hierarchy (DesignControlSpecification / System- / Software- /
13
- // HardwareSpecification); now one attribute. The role-specific attributes
14
- // below are all optional so a requirement carries only the ones its kind
15
- // needs. IEC 62304 / design-control classification is preserved as the
16
- // enum value, not lost.
17
- enum def RequirementKind {
10
+ // What a requirement is about: the system, the software, the hardware, or
11
+ // the instructions for use. One axis, and the members are its values.
12
+ //
13
+ // It carried a second axis until now. `systemSpecification`,
14
+ // `softwareSpecification`, `hardwareSpecification` and `designControl` are
15
+ // the design-control ROLE — input versus output, 21 CFR 820.30(c)/(d) and
16
+ // ISO 13485 §7.3.3/§7.3.4 — multiplied into the subject. A requirement then
17
+ // could not say "software" without also committing to a role, the grid was
18
+ // incomplete by construction (there is no `ifuSpecification`, and there
19
+ // would have to be one for every future pairing), and nothing ever used the
20
+ // four: 250 requirements across the examples say system, software or
21
+ // hardware. A role, if a project needs one, is its own attribute.
22
+ //
23
+ // The instructions for use are neither hardware nor software: the device
24
+ // satisfies such a requirement with words rather than with a part or a
25
+ // module, and it is verified by reviewing the IFU rather than by testing a
26
+ // build (EU MDR Annex I §23.4, ISO 20417, IEC 62366-1 §7.2).
27
+ enum def RequirementTypeKind {
18
28
  enum system;
19
29
  enum software;
20
30
  enum hardware;
21
- enum systemSpecification;
22
- enum softwareSpecification;
23
- enum hardwareSpecification;
24
- enum designControl;
31
+ enum ifu;
25
32
  }
26
33
 
27
34
  requirement def Requirement specializes MemoRequirement {
28
- attribute requirementKind : RequirementKind;
35
+ attribute requirementType : RequirementTypeKind;
29
36
  attribute :>> statement : String;
30
37
  attribute sourceKind : RequirementSourceKind;
31
38
  attribute concernKind : ConcernKind;
@@ -53,9 +60,6 @@ package memo_assurance_requirements {
53
60
  // design-control specification (ISO 13485 design output)
54
61
  attribute specificationDomain : String;
55
62
  attribute sourceFolder : String;
56
- attribute linkedUserNeeds : String;
57
- attribute linkedRisks : String;
58
- attribute linkedTests : String;
59
63
  }
60
64
  // Named constant defined by a source requirements document (e.g. CriSys
61
65
  // GPCA App. A.4) and referenced from requirement statements.
@@ -6,8 +6,15 @@
6
6
  package memo_assurance_requirements_needs {
7
7
  private import ScalarValues::*;
8
8
 
9
+ private import Metaobjects::SemanticMetadata;
10
+
9
11
  private import memo_core_common::*;
10
12
  private import memo_core_enumerations::*;
13
+ private import memo_core_relationships::*;
14
+ // A need is held by someone and arises in a context, and both are modelled
15
+ // elements. Assurance may depend on architecture; the reverse may not.
16
+ private import memo_architecture_operational_context_actors::*;
17
+ private import memo_architecture_operational_context_use_context::*;
11
18
 
12
19
  // The kind of need. Was a subclass branch (StakeholderNeed / UserNeed /
13
20
  // ClinicalUserNeed / PatientUserNeed / BusinessNeed / ServiceNeed /
@@ -29,15 +36,36 @@ package memo_assurance_requirements_needs {
29
36
 
30
37
  requirement def Need specializes MemoNeed {
31
38
  attribute needKind : NeedKind;
32
- // user need (IEC 62366-1)
33
- attribute userPopulationReference : String;
39
+ // A user need (IEC 62366-1) says WHOSE need it is with HeldBy, and the
40
+ // user's characteristics live on the User: `userPopulation`,
41
+ // `impairmentConsiderations`, `intendedTraining`, `intendedQualification`.
42
+ // A `userPopulationReference` string stood here and held prose — "ward
43
+ // nurses, including those wearing corrective lenses" — which is two
44
+ // typed attributes of a user profile written as one sentence nothing
45
+ // could read, on the wrong element.
34
46
  // regulatory need
35
47
  attribute jurisdiction : String;
36
48
  attribute regulationReference : String;
37
- // operational need
38
- attribute operationalContextReference : String;
49
+ // The context an operational need arises in. Typed, because UseContext
50
+ // carries the care setting, environment and jurisdiction that an
51
+ // `operationalContextReference` string could only describe.
52
+ ref useContext : UseContext[0..1];
39
53
  // design-control need (ISO 13485 design input)
40
54
  attribute sourceFolder : String;
41
- attribute linkedDesignControls : String;
55
+ }
56
+
57
+ // Whose need this is. The holder is a modelled participant — a User, with
58
+ // the profile IEC 62366-1 asks for, or another operational participant —
59
+ // so "which users does this need serve" is a question the model answers
60
+ // rather than a sentence a reader interprets.
61
+ connection def HeldBy :> MemoRelationship {
62
+ end need : MemoNeed :>> source;
63
+ end holder : OperationalParticipant :>> target;
64
+ }
65
+ abstract connection heldByLinks : HeldBy[*];
66
+ metadata def <heldBy> HeldByMetadata :> SemanticMetadata {
67
+ :> annotatedElement : SysML::ConnectionDefinition;
68
+ :> annotatedElement : SysML::ConnectionUsage;
69
+ :>> baseType = heldByLinks meta SysML::Usage;
42
70
  }
43
71
  }
@@ -6,6 +6,9 @@ package memo_assurance_safety_risk {
6
6
  private import memo_core_common::*;
7
7
  private import memo_core_enumerations::*;
8
8
  private import memo_assurance_requirements::*;
9
+ // For HazardRelatedScenario below. Assurance may depend on architecture;
10
+ // the reverse is what the string on the scenario was avoiding.
11
+ private import memo_architecture_operational_scenarios::*;
9
12
 
10
13
  // ISO 14971 / IEC 62366-1 risk-analysis input. A model element so hazards,
11
14
  // scenarios, requirements, and DHF records can trace to the foreseeable
@@ -135,6 +138,23 @@ package memo_assurance_safety_risk {
135
138
  :> annotatedElement : SysML::ConnectionUsage;
136
139
  :>> baseType = tracesRiskLinks meta SysML::Usage;
137
140
  }
141
+ // IEC 62366-1 3.9's hazard-related use scenario: the scenario a hazard can
142
+ // arise in. It is declared HERE rather than as a `hazardReference` string
143
+ // on the scenario, which is what stood in for it: a string names nothing a
144
+ // consumer can follow, and the layering is why it was written that way —
145
+ // assurance may depend on architecture, and the scenario package cannot
146
+ // see `Hazard`. On this side both ends are visible and the dependency runs
147
+ // the direction it already runs.
148
+ connection def HazardRelatedScenario :> MemoRelationship {
149
+ end hazard : RiskItem :>> source;
150
+ end scenario : OperativeScenario :>> target;
151
+ }
152
+ abstract connection hazardRelatedScenarioLinks : HazardRelatedScenario[*];
153
+ metadata def <hazardRelatedScenario> HazardRelatedScenarioMetadata :> SemanticMetadata {
154
+ :> annotatedElement : SysML::ConnectionDefinition;
155
+ :> annotatedElement : SysML::ConnectionUsage;
156
+ :>> baseType = hazardRelatedScenarioLinks meta SysML::Usage;
157
+ }
138
158
  connection def AssessedAgainst :> MemoRelationship {
139
159
  end risk : Risk :>> source;
140
160
  end riskMatrix : RiskMatrix :>> target;
@@ -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";