etcion 0.2.0__py3-none-any.whl

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 (40) hide show
  1. etcion/__init__.py +350 -0
  2. etcion/comparison.py +152 -0
  3. etcion/conformance.py +136 -0
  4. etcion/derivation/__init__.py +19 -0
  5. etcion/derivation/engine.py +115 -0
  6. etcion/enums.py +117 -0
  7. etcion/exceptions.py +27 -0
  8. etcion/impact.py +590 -0
  9. etcion/metamodel/__init__.py +23 -0
  10. etcion/metamodel/application.py +162 -0
  11. etcion/metamodel/business.py +216 -0
  12. etcion/metamodel/concepts.py +129 -0
  13. etcion/metamodel/elements.py +112 -0
  14. etcion/metamodel/implementation_migration.py +99 -0
  15. etcion/metamodel/mixins.py +31 -0
  16. etcion/metamodel/model.py +374 -0
  17. etcion/metamodel/motivation.py +131 -0
  18. etcion/metamodel/notation.py +36 -0
  19. etcion/metamodel/physical.py +73 -0
  20. etcion/metamodel/profiles.py +68 -0
  21. etcion/metamodel/relationships.py +266 -0
  22. etcion/metamodel/strategy.py +72 -0
  23. etcion/metamodel/technology.py +210 -0
  24. etcion/metamodel/viewpoint_catalogue.py +1133 -0
  25. etcion/metamodel/viewpoints.py +83 -0
  26. etcion/patterns.py +1043 -0
  27. etcion/py.typed +0 -0
  28. etcion/serialization/__init__.py +1 -0
  29. etcion/serialization/json.py +92 -0
  30. etcion/serialization/registry.py +292 -0
  31. etcion/serialization/schema/archimate3_Diagram.xsd +554 -0
  32. etcion/serialization/schema/archimate3_Model.xsd +1340 -0
  33. etcion/serialization/schema/archimate3_View.xsd +321 -0
  34. etcion/serialization/xml.py +249 -0
  35. etcion/validation/__init__.py +20 -0
  36. etcion/validation/permissions.py +477 -0
  37. etcion/validation/rules.py +41 -0
  38. etcion-0.2.0.dist-info/METADATA +251 -0
  39. etcion-0.2.0.dist-info/RECORD +40 -0
  40. etcion-0.2.0.dist-info/WHEEL +4 -0
etcion/__init__.py ADDED
@@ -0,0 +1,350 @@
1
+ """etcion -- Python implementation of the ArchiMate 3.2 metamodel."""
2
+
3
+ from importlib.metadata import PackageNotFoundError
4
+ from importlib.metadata import version as _meta_version
5
+
6
+ try:
7
+ __version__: str = _meta_version("etcion")
8
+ except PackageNotFoundError: # pragma: no cover
9
+ __version__ = "0.0.0.dev0"
10
+
11
+ # Phase 4: Model comparison and diff utilities (EPIC-024, FEAT-24.1)
12
+ from etcion.comparison import ConceptChange, FieldChange, ModelDiff, diff_models
13
+ from etcion.conformance import CONFORMANCE, ConformanceProfile
14
+ from etcion.derivation.engine import DerivationEngine
15
+ from etcion.enums import (
16
+ AccessMode,
17
+ Aspect,
18
+ AssociationDirection,
19
+ ContentCategory,
20
+ InfluenceSign,
21
+ JunctionType,
22
+ Layer,
23
+ PurposeCategory,
24
+ RelationshipCategory,
25
+ )
26
+ from etcion.exceptions import (
27
+ ConformanceError,
28
+ DerivationError,
29
+ PyArchiError,
30
+ ValidationError,
31
+ )
32
+
33
+ # Phase 5: Impact analysis engine (ADR-043, Issue #9)
34
+ from etcion.impact import ImpactedConcept, ImpactResult, analyze_impact, chain_impacts
35
+
36
+ # Phase 2: Application layer (EPIC-008)
37
+ from etcion.metamodel.application import (
38
+ ApplicationCollaboration,
39
+ ApplicationComponent,
40
+ ApplicationEvent,
41
+ ApplicationFunction,
42
+ ApplicationInteraction,
43
+ ApplicationInterface,
44
+ ApplicationInternalActiveStructureElement,
45
+ ApplicationInternalBehaviorElement,
46
+ ApplicationProcess,
47
+ ApplicationService,
48
+ DataObject,
49
+ )
50
+
51
+ # Phase 2: Business layer (EPIC-007)
52
+ from etcion.metamodel.business import (
53
+ BusinessActor,
54
+ BusinessCollaboration,
55
+ BusinessEvent,
56
+ BusinessFunction,
57
+ BusinessInteraction,
58
+ BusinessInterface,
59
+ BusinessInternalActiveStructureElement,
60
+ BusinessInternalBehaviorElement,
61
+ BusinessObject,
62
+ BusinessPassiveStructureElement,
63
+ BusinessProcess,
64
+ BusinessRole,
65
+ BusinessService,
66
+ Contract,
67
+ Product,
68
+ Representation,
69
+ )
70
+ from etcion.metamodel.concepts import (
71
+ Concept,
72
+ Element,
73
+ Relationship,
74
+ RelationshipConnector,
75
+ )
76
+ from etcion.metamodel.elements import (
77
+ ActiveStructureElement,
78
+ BehaviorElement,
79
+ CompositeElement,
80
+ Event,
81
+ ExternalActiveStructureElement,
82
+ ExternalBehaviorElement,
83
+ Function,
84
+ Grouping,
85
+ Interaction,
86
+ InternalActiveStructureElement,
87
+ InternalBehaviorElement,
88
+ Location,
89
+ MotivationElement,
90
+ PassiveStructureElement,
91
+ Process,
92
+ StructureElement,
93
+ )
94
+
95
+ # Phase 2: Implementation & Migration layer (EPIC-012)
96
+ from etcion.metamodel.implementation_migration import (
97
+ Deliverable,
98
+ Gap,
99
+ ImplementationEvent,
100
+ Plateau,
101
+ WorkPackage,
102
+ )
103
+ from etcion.metamodel.model import Model
104
+
105
+ # Phase 2: Motivation layer (EPIC-011)
106
+ from etcion.metamodel.motivation import (
107
+ Assessment,
108
+ Constraint,
109
+ Driver,
110
+ Goal,
111
+ Meaning,
112
+ Outcome,
113
+ Principle,
114
+ Requirement,
115
+ Stakeholder,
116
+ Value,
117
+ )
118
+ from etcion.metamodel.notation import NotationMetadata
119
+
120
+ # Phase 2: Physical layer (EPIC-010)
121
+ from etcion.metamodel.physical import (
122
+ DistributionNetwork,
123
+ Equipment,
124
+ Facility,
125
+ Material,
126
+ PhysicalActiveStructureElement,
127
+ PhysicalPassiveStructureElement,
128
+ )
129
+
130
+ # Phase 3: Language customization (EPIC-018)
131
+ from etcion.metamodel.profiles import Profile
132
+ from etcion.metamodel.relationships import (
133
+ Access,
134
+ Aggregation,
135
+ Assignment,
136
+ Association,
137
+ Composition,
138
+ DependencyRelationship,
139
+ DynamicRelationship,
140
+ Flow,
141
+ Influence,
142
+ Junction,
143
+ OtherRelationship,
144
+ Realization,
145
+ Serving,
146
+ Specialization,
147
+ StructuralRelationship,
148
+ Triggering,
149
+ )
150
+
151
+ # Phase 2: Strategy layer (EPIC-006)
152
+ from etcion.metamodel.strategy import (
153
+ Capability,
154
+ CourseOfAction,
155
+ Resource,
156
+ StrategyBehaviorElement,
157
+ StrategyStructureElement,
158
+ ValueStream,
159
+ )
160
+
161
+ # Phase 2: Technology layer (EPIC-009)
162
+ from etcion.metamodel.technology import (
163
+ Artifact,
164
+ CommunicationNetwork,
165
+ Device,
166
+ Node,
167
+ Path,
168
+ SystemSoftware,
169
+ TechnologyCollaboration,
170
+ TechnologyEvent,
171
+ TechnologyFunction,
172
+ TechnologyInteraction,
173
+ TechnologyInterface,
174
+ TechnologyInternalActiveStructureElement,
175
+ TechnologyInternalBehaviorElement,
176
+ TechnologyProcess,
177
+ TechnologyService,
178
+ )
179
+
180
+ # Phase 4: Predefined Viewpoint Catalogue (EPIC-022, FEAT-22.1)
181
+ from etcion.metamodel.viewpoint_catalogue import VIEWPOINT_CATALOGUE, ViewpointCatalogue
182
+
183
+ # Phase 3: Viewpoints (EPIC-017)
184
+ from etcion.metamodel.viewpoints import Concern, View, Viewpoint
185
+ from etcion.validation.permissions import is_permitted, warm_cache
186
+ from etcion.validation.rules import ValidationRule
187
+
188
+ SPEC_VERSION: str = "3.2"
189
+ """The ArchiMate specification version implemented by this library."""
190
+
191
+ __all__: list[str] = [
192
+ "__version__",
193
+ "SPEC_VERSION",
194
+ # exceptions (FEAT-00.2)
195
+ "PyArchiError",
196
+ "ValidationError",
197
+ "DerivationError",
198
+ "ConformanceError",
199
+ # conformance (FEAT-01.1)
200
+ "ConformanceProfile",
201
+ "CONFORMANCE",
202
+ # root type hierarchy (EPIC-002)
203
+ "Concept",
204
+ "Element",
205
+ "Relationship",
206
+ "RelationshipConnector",
207
+ "Model",
208
+ # language structure (EPIC-003)
209
+ "Aspect",
210
+ "Layer",
211
+ "NotationMetadata",
212
+ # EPIC-004: Generic Metamodel -- Abstract Element Hierarchy
213
+ "ActiveStructureElement",
214
+ "BehaviorElement",
215
+ "CompositeElement",
216
+ "Event",
217
+ "ExternalActiveStructureElement",
218
+ "ExternalBehaviorElement",
219
+ "Function",
220
+ "Grouping",
221
+ "InternalActiveStructureElement",
222
+ "InternalBehaviorElement",
223
+ "Interaction",
224
+ "Location",
225
+ "MotivationElement",
226
+ "PassiveStructureElement",
227
+ "Process",
228
+ "StructureElement",
229
+ # EPIC-005: Relationships and Relationship Connectors
230
+ "RelationshipCategory",
231
+ "AccessMode",
232
+ "AssociationDirection",
233
+ "InfluenceSign",
234
+ "JunctionType",
235
+ "StructuralRelationship",
236
+ "DependencyRelationship",
237
+ "DynamicRelationship",
238
+ "OtherRelationship",
239
+ "Composition",
240
+ "Aggregation",
241
+ "Assignment",
242
+ "Realization",
243
+ "Serving",
244
+ "Access",
245
+ "Influence",
246
+ "Association",
247
+ "Triggering",
248
+ "Flow",
249
+ "Specialization",
250
+ "Junction",
251
+ "DerivationEngine",
252
+ "is_permitted",
253
+ "warm_cache",
254
+ "ValidationRule",
255
+ # Strategy layer (EPIC-006)
256
+ "StrategyStructureElement",
257
+ "StrategyBehaviorElement",
258
+ "Resource",
259
+ "Capability",
260
+ "ValueStream",
261
+ "CourseOfAction",
262
+ # Business layer (EPIC-007)
263
+ "BusinessInternalActiveStructureElement",
264
+ "BusinessInternalBehaviorElement",
265
+ "BusinessPassiveStructureElement",
266
+ "BusinessActor",
267
+ "BusinessRole",
268
+ "BusinessCollaboration",
269
+ "BusinessInterface",
270
+ "BusinessProcess",
271
+ "BusinessFunction",
272
+ "BusinessInteraction",
273
+ "BusinessEvent",
274
+ "BusinessService",
275
+ "BusinessObject",
276
+ "Contract",
277
+ "Representation",
278
+ "Product",
279
+ # Application layer (EPIC-008)
280
+ "ApplicationInternalActiveStructureElement",
281
+ "ApplicationInternalBehaviorElement",
282
+ "ApplicationComponent",
283
+ "ApplicationCollaboration",
284
+ "ApplicationInterface",
285
+ "ApplicationFunction",
286
+ "ApplicationInteraction",
287
+ "ApplicationProcess",
288
+ "ApplicationEvent",
289
+ "ApplicationService",
290
+ "DataObject",
291
+ # Technology layer (EPIC-009)
292
+ "TechnologyInternalActiveStructureElement",
293
+ "TechnologyInternalBehaviorElement",
294
+ "Node",
295
+ "Device",
296
+ "SystemSoftware",
297
+ "TechnologyCollaboration",
298
+ "TechnologyInterface",
299
+ "Path",
300
+ "CommunicationNetwork",
301
+ "TechnologyFunction",
302
+ "TechnologyProcess",
303
+ "TechnologyInteraction",
304
+ "TechnologyEvent",
305
+ "TechnologyService",
306
+ "Artifact",
307
+ # Physical layer (EPIC-010)
308
+ "PhysicalActiveStructureElement",
309
+ "PhysicalPassiveStructureElement",
310
+ "Equipment",
311
+ "Facility",
312
+ "DistributionNetwork",
313
+ "Material",
314
+ # Motivation layer (EPIC-011)
315
+ "Stakeholder",
316
+ "Driver",
317
+ "Assessment",
318
+ "Goal",
319
+ "Outcome",
320
+ "Principle",
321
+ "Requirement",
322
+ "Constraint",
323
+ "Meaning",
324
+ "Value",
325
+ # Implementation & Migration layer (EPIC-012)
326
+ "WorkPackage",
327
+ "Deliverable",
328
+ "ImplementationEvent",
329
+ "Plateau",
330
+ "Gap",
331
+ # Viewpoints & Language Customization (Phase 3)
332
+ "Viewpoint",
333
+ "View",
334
+ "Concern",
335
+ "Profile",
336
+ "PurposeCategory",
337
+ "ContentCategory",
338
+ # Predefined Viewpoint Catalogue (EPIC-022, FEAT-22.1)
339
+ "ViewpointCatalogue",
340
+ "VIEWPOINT_CATALOGUE",
341
+ # Model comparison and diff utilities (EPIC-024, FEAT-24.1)
342
+ "FieldChange",
343
+ "ConceptChange",
344
+ "ModelDiff",
345
+ "diff_models",
346
+ # Impact analysis engine (ADR-043, Issue #9)
347
+ "ImpactedConcept",
348
+ "ImpactResult",
349
+ "analyze_impact",
350
+ ]
etcion/comparison.py ADDED
@@ -0,0 +1,152 @@
1
+ """Model comparison and diff utilities (EPIC-024, FEAT-24.1 / FEAT-24.2)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any, Literal
7
+
8
+ from etcion.metamodel.concepts import Concept, Relationship
9
+ from etcion.metamodel.model import Model
10
+
11
+ __all__: list[str] = [
12
+ "FieldChange",
13
+ "ConceptChange",
14
+ "ModelDiff",
15
+ "diff_models",
16
+ ]
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class FieldChange:
21
+ """A single field-level change between two concept snapshots."""
22
+
23
+ field: str
24
+ old: Any
25
+ new: Any
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class ConceptChange:
30
+ """A concept present in both models whose fields differ."""
31
+
32
+ concept_id: str
33
+ concept_type: str
34
+ changes: dict[str, FieldChange]
35
+
36
+
37
+ @dataclass(frozen=True)
38
+ class ModelDiff:
39
+ """Immutable result of comparing two models."""
40
+
41
+ added: tuple[Concept, ...]
42
+ removed: tuple[Concept, ...]
43
+ modified: tuple[ConceptChange, ...]
44
+
45
+ def to_dict(self) -> dict[str, Any]:
46
+ """Return a JSON-serializable dict representation."""
47
+
48
+ def _concept_entry(c: Concept) -> dict[str, Any]:
49
+ return {
50
+ "id": c.id,
51
+ "type": type(c).__name__,
52
+ "name": getattr(c, "name", None),
53
+ }
54
+
55
+ def _change_entry(cc: ConceptChange) -> dict[str, Any]:
56
+ return {
57
+ "concept_id": cc.concept_id,
58
+ "concept_type": cc.concept_type,
59
+ "changes": {k: {"old": fc.old, "new": fc.new} for k, fc in cc.changes.items()},
60
+ }
61
+
62
+ return {
63
+ "added": [_concept_entry(c) for c in self.added],
64
+ "removed": [_concept_entry(c) for c in self.removed],
65
+ "modified": [_change_entry(cc) for cc in self.modified],
66
+ }
67
+
68
+ def summary(self) -> str:
69
+ """Return a human-readable one-line summary."""
70
+ return (
71
+ f"ModelDiff: {len(self.added)} added, "
72
+ f"{len(self.removed)} removed, "
73
+ f"{len(self.modified)} modified"
74
+ )
75
+
76
+ def __str__(self) -> str:
77
+ return self.summary()
78
+
79
+ def __bool__(self) -> bool:
80
+ return bool(self.added or self.removed or self.modified)
81
+
82
+
83
+ def _build_key(concept: Concept, match_by: Literal["id", "type_name"]) -> str | tuple[str, str]:
84
+ """Return the lookup key for a concept."""
85
+ if match_by == "id":
86
+ return concept.id
87
+ # match_by == "type_name"
88
+ name = getattr(concept, "name", "") or ""
89
+ return (type(concept).__name__, name)
90
+
91
+
92
+ def _normalize_dump(concept: Concept) -> dict[str, Any]:
93
+ """Return a model_dump() dict with id removed and source/target normalized."""
94
+ d = concept.model_dump()
95
+ d.pop("id", None)
96
+ if isinstance(concept, Relationship):
97
+ d["source"] = concept.source.id
98
+ d["target"] = concept.target.id
99
+ return d
100
+
101
+
102
+ def _diff_fields(dump_a: dict[str, Any], dump_b: dict[str, Any]) -> dict[str, FieldChange]:
103
+ """Compare two normalized dumps, returning changed fields."""
104
+ changes: dict[str, FieldChange] = {}
105
+ all_keys = dump_a.keys() | dump_b.keys()
106
+ for key in all_keys:
107
+ old = dump_a.get(key)
108
+ new = dump_b.get(key)
109
+ if old != new:
110
+ changes[key] = FieldChange(field=key, old=old, new=new)
111
+ return changes
112
+
113
+
114
+ def diff_models(
115
+ model_a: Model,
116
+ model_b: Model,
117
+ *,
118
+ match_by: Literal["id", "type_name"] = "id",
119
+ ) -> ModelDiff:
120
+ """Compare two models and return a structured diff.
121
+
122
+ :param model_a: Baseline ("before") model.
123
+ :param model_b: Revised ("after") model.
124
+ :param match_by: ``"id"`` matches concepts by id; ``"type_name"`` matches
125
+ by ``(type_name, name)`` tuple.
126
+ :returns: A frozen :class:`ModelDiff`.
127
+ """
128
+ lookup_a = {_build_key(c, match_by): c for c in model_a.concepts}
129
+ lookup_b = {_build_key(c, match_by): c for c in model_b.concepts}
130
+
131
+ keys_a = set(lookup_a)
132
+ keys_b = set(lookup_b)
133
+
134
+ added = tuple(lookup_b[k] for k in keys_b - keys_a)
135
+ removed = tuple(lookup_a[k] for k in keys_a - keys_b)
136
+
137
+ modified: list[ConceptChange] = []
138
+ for key in keys_a & keys_b:
139
+ ca, cb = lookup_a[key], lookup_b[key]
140
+ dump_a = _normalize_dump(ca)
141
+ dump_b = _normalize_dump(cb)
142
+ changes = _diff_fields(dump_a, dump_b)
143
+ if changes:
144
+ modified.append(
145
+ ConceptChange(
146
+ concept_id=ca.id,
147
+ concept_type=type(ca).__name__,
148
+ changes=changes,
149
+ )
150
+ )
151
+
152
+ return ModelDiff(added=added, removed=removed, modified=tuple(modified))
etcion/conformance.py ADDED
@@ -0,0 +1,136 @@
1
+ """Conformance profile for the etcion ArchiMate 3.2 implementation.
2
+
3
+ This module declares which features of the ArchiMate 3.2 specification the
4
+ library commits to implementing. The :class:`ConformanceProfile` dataclass
5
+ carries boolean flags grouped by the specification's three compliance levels:
6
+
7
+ * **shall** -- mandatory features for a conformant implementation.
8
+ * **should** -- recommended features the library plans to support.
9
+ * **may** -- optional features explicitly out of scope.
10
+
11
+ The module-level :data:`CONFORMANCE` singleton is the canonical instance.
12
+ It is re-exported from ``etcion.__init__`` so consumers can inspect the
13
+ library's conformance declaration via ``etcion.CONFORMANCE``.
14
+
15
+ .. note::
16
+ This module does **not** import ``SPEC_VERSION`` from ``etcion.__init__``
17
+ to avoid a circular import. The ``spec_version`` field uses the literal
18
+ ``"3.2"`` as its default. The conformance test suite asserts that this
19
+ value equals ``etcion.SPEC_VERSION``.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ from dataclasses import dataclass
25
+
26
+ __all__: list[str] = [
27
+ "ConformanceProfile",
28
+ "CONFORMANCE",
29
+ ]
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class ConformanceProfile:
34
+ """Machine-readable declaration of ArchiMate 3.2 conformance scope.
35
+
36
+ Every field defaults to the library's declared intent. ``shall``-level
37
+ and ``should``-level fields default to ``True`` (the library commits to
38
+ implementing them). The sole ``may``-level field defaults to ``False``
39
+ (explicitly out of scope).
40
+
41
+ The dataclass is frozen to prevent accidental mutation of the library's
42
+ conformance contract.
43
+ """
44
+
45
+ # --- spec version ---
46
+
47
+ # The ArchiMate specification version this profile targets.
48
+ spec_version: str = "3.2"
49
+
50
+ # --- shall-level (mandatory for conformance) ---
51
+
52
+ # Full classification framework: layers (7) and aspects (5).
53
+ # Reference: ArchiMate 3.2 Specification, Sections 3.4--3.5.
54
+ language_structure: bool = True
55
+
56
+ # Abstract element hierarchy: Concept, Element, Relationship,
57
+ # RelationshipConnector ABCs.
58
+ # Reference: ArchiMate 3.2 Specification, Section 3.1.
59
+ generic_metamodel: bool = True
60
+
61
+ # Strategy layer element types: Resource, Capability, ValueStream,
62
+ # CourseOfAction.
63
+ # Reference: ArchiMate 3.2 Specification, Chapter 7.
64
+ strategy_elements: bool = True
65
+
66
+ # Motivation layer element types: Stakeholder, Driver, Assessment, Goal,
67
+ # Outcome, Principle, Requirement, Constraint, Meaning, Value.
68
+ # Reference: ArchiMate 3.2 Specification, Chapter 6.
69
+ motivation_elements: bool = True
70
+
71
+ # Business layer element types: BusinessActor, BusinessRole,
72
+ # BusinessCollaboration, BusinessInterface, BusinessProcess,
73
+ # BusinessFunction, BusinessInteraction, BusinessEvent,
74
+ # BusinessService, BusinessObject, Contract, Representation, Product.
75
+ # Reference: ArchiMate 3.2 Specification, Chapter 8.
76
+ business_elements: bool = True
77
+
78
+ # Application layer element types: ApplicationComponent,
79
+ # ApplicationCollaboration, ApplicationInterface, ApplicationFunction,
80
+ # ApplicationInteraction, ApplicationProcess, ApplicationEvent,
81
+ # ApplicationService, DataObject.
82
+ # Reference: ArchiMate 3.2 Specification, Chapter 9.
83
+ application_elements: bool = True
84
+
85
+ # Technology layer element types: Node, Device, SystemSoftware,
86
+ # TechnologyCollaboration, TechnologyInterface, Path,
87
+ # CommunicationNetwork, TechnologyFunction, TechnologyProcess,
88
+ # TechnologyInteraction, TechnologyEvent, TechnologyService, Artifact.
89
+ # Reference: ArchiMate 3.2 Specification, Chapter 10.
90
+ technology_elements: bool = True
91
+
92
+ # Physical layer element types: Equipment, Facility,
93
+ # DistributionNetwork, Material.
94
+ # Reference: ArchiMate 3.2 Specification, Chapter 11.
95
+ physical_elements: bool = True
96
+
97
+ # Implementation & Migration layer element types: WorkPackage,
98
+ # Deliverable, ImplementationEvent, Plateau, Gap.
99
+ # Reference: ArchiMate 3.2 Specification, Chapter 13.
100
+ implementation_migration_elements: bool = True
101
+
102
+ # Support for relationships that cross layer boundaries, including all
103
+ # 11 concrete relationship types and the Junction connector.
104
+ # Reference: ArchiMate 3.2 Specification, Chapter 5.
105
+ cross_layer_relationships: bool = True
106
+
107
+ # Full Appendix B relationship permission matrix encoding and the
108
+ # ``is_permitted`` lookup function.
109
+ # Reference: ArchiMate 3.2 Specification, Appendix B.
110
+ relationship_permission_table: bool = True
111
+
112
+ # Notation metadata: corner shapes, default layer colors, and badge
113
+ # letters for each concrete element type.
114
+ # Reference: ArchiMate 3.2 Specification, Appendix A.
115
+ iconography_metadata: bool = True
116
+
117
+ # --- should-level (recommended, not mandatory) ---
118
+
119
+ # Defining and applying viewpoints to filter model views.
120
+ # Reference: ArchiMate 3.2 Specification, Chapter 14.
121
+ viewpoint_mechanism: bool = True
122
+
123
+ # Profile and extension mechanisms for customizing the language.
124
+ # Reference: ArchiMate 3.2 Specification, Chapter 15.
125
+ language_customization: bool = True
126
+
127
+ # --- may-level (optional, out of scope) ---
128
+
129
+ # Appendix C example viewpoints (Basic, Organization, etc.).
130
+ # This feature does not affect conformance checks.
131
+ # Reference: ArchiMate 3.2 Specification, Appendix C.
132
+ example_viewpoints: bool = False
133
+
134
+
135
+ CONFORMANCE: ConformanceProfile = ConformanceProfile()
136
+ """The canonical conformance profile singleton for the etcion library."""
@@ -0,0 +1,19 @@
1
+ """etcion.derivation -- Relationship derivation engine.
2
+
3
+ This sub-package implements the ArchiMate 3.2 relationship derivation rules,
4
+ computing implied (derived) relationships from chains of direct relationships
5
+ in a model.
6
+
7
+ Modules
8
+ -------
9
+ engine
10
+ DerivationEngine class implementing the derive() method and chain
11
+ traversal logic. (TODO: EPIC-005, FEAT-05.10)
12
+
13
+ Import policy
14
+ -------------
15
+ This package MAY import from etcion.metamodel, etcion.enums, and
16
+ etcion.validation. It is the top of the internal dependency graph.
17
+ """
18
+
19
+ # No public symbols yet -- DerivationEngine is added in EPIC-005.