deriva-cli 0.8.7__tar.gz → 0.8.8__tar.gz

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 (211) hide show
  1. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/PKG-INFO +2 -2
  2. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/manager.py +22 -6
  3. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/models.py +112 -23
  4. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/views.py +7 -7
  5. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/xml_export.py +5 -1
  6. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/data/derivation_config.json +221 -61
  7. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/data/extraction_config.json +40 -23
  8. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/data/system_settings.json +2 -2
  9. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/graph/models.py +8 -1
  10. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/manager.py +16 -2
  11. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/schemas.py +3 -3
  12. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/cli.py +1 -1
  13. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/commands/config.py +26 -0
  14. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/naming.py +1 -1
  15. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/conventions.py +3 -3
  16. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/application_component.py +0 -5
  17. deriva_cli-0.8.8/deriva/modules/derivation/application_function.py +35 -0
  18. deriva_cli-0.8.8/deriva/modules/derivation/application_grouping.py +194 -0
  19. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/application_service.py +0 -6
  20. deriva_cli-0.8.8/deriva/modules/derivation/artifact.py +36 -0
  21. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/base.py +24 -7
  22. deriva_cli-0.8.8/deriva/modules/derivation/business_role.py +36 -0
  23. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/component_services.py +86 -20
  24. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/data_object.py +0 -6
  25. deriva_cli-0.8.8/deriva/modules/derivation/derivation_rules.py +127 -0
  26. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/detail_level.py +2 -12
  27. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/device.py +0 -5
  28. deriva_cli-0.8.8/deriva/modules/derivation/documentation_actors.py +84 -0
  29. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/element_base.py +40 -2
  30. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/levels.py +61 -70
  31. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/abstraction_levels.py +117 -65
  32. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/cross_layer.py +5 -1
  33. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/joint.py +2 -0
  34. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/system_software.py +0 -5
  35. deriva_cli-0.8.8/deriva/modules/derivation/technology_function.py +35 -0
  36. deriva_cli-0.8.8/deriva/modules/derivation/technology_service.py +46 -0
  37. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/base.py +2 -2
  38. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/build_modules.py +159 -5
  39. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/data_entities.py +110 -10
  40. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/deployable_units.py +138 -11
  41. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/deployments.py +28 -2
  42. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/edges.py +91 -3
  43. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/lifecycles.py +2 -2
  44. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/config.py +29 -4
  45. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/derivation.py +216 -4
  46. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/export_levels.py +0 -2
  47. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/extraction.py +203 -27
  48. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/pyproject.toml +2 -2
  49. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/pyproject.toml.orig +2 -2
  50. deriva_cli-0.8.7/deriva/modules/derivation/technology_service.py +0 -83
  51. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/LICENSE +0 -0
  52. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/README.md +0 -0
  53. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/__init__.py +0 -0
  54. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/documentation/Diagram.html +0 -0
  55. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/documentation/View.html +0 -0
  56. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/documentation/model.html +0 -0
  57. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/examples/archimate3_Diagram.xsd +0 -0
  58. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/examples/archimate3_Model.xsd +0 -0
  59. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/examples/archimate3_View.xsd +0 -0
  60. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/schemas/archimate3_Diagram.xsd +0 -0
  61. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/schemas/archimate3_Model.xsd +0 -0
  62. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/schemas/archimate3_View.xsd +0 -0
  63. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-1.xml +0 -0
  64. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-10.xml +0 -0
  65. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-2.xml +0 -0
  66. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-3.xml +0 -0
  67. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-4.xml +0 -0
  68. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-5.xml +0 -0
  69. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-7.xml +0 -0
  70. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-8.xml +0 -0
  71. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-9.xml +0 -0
  72. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/archimate/validation.py +0 -0
  73. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/README.md +0 -0
  74. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/__init__.py +0 -0
  75. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/data/derivation_patterns.json +0 -0
  76. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/data/file_types.json +0 -0
  77. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/data/function_models/pcf-8.0-cross-industry.csv +0 -0
  78. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/db_tool.py +0 -0
  79. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/manager.py +0 -0
  80. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/scripts/7_extraction_params.sql +0 -0
  81. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/database/scripts/schema.sql +0 -0
  82. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/grafeo/__init__.py +0 -0
  83. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/grafeo/manager.py +0 -0
  84. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/graph/README.md +0 -0
  85. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/graph/__init__.py +0 -0
  86. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/graph/cache.py +0 -0
  87. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/graph/manager.py +0 -0
  88. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/graph/metamodel.py +0 -0
  89. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/README.md +0 -0
  90. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/__init__.py +0 -0
  91. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/cache.py +0 -0
  92. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/model_registry.py +0 -0
  93. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/models.py +0 -0
  94. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/rate_limiter.py +0 -0
  95. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/llm/retry.py +0 -0
  96. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/__init__.py +0 -0
  97. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/extract.py +0 -0
  98. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/language.py +0 -0
  99. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/manager.py +0 -0
  100. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/models.py +0 -0
  101. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/phrases.py +0 -0
  102. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/settings.py +0 -0
  103. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/text.py +0 -0
  104. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/nlp/translate.py +0 -0
  105. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/repository/README.md +0 -0
  106. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/repository/__init__.py +0 -0
  107. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/repository/manager.py +0 -0
  108. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/repository/models.py +0 -0
  109. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/__init__.py +0 -0
  110. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/cdk.py +0 -0
  111. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/__init__.py +0 -0
  112. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/base.py +0 -0
  113. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/bms.py +0 -0
  114. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/cobol.py +0 -0
  115. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/csharp.py +0 -0
  116. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/java.py +0 -0
  117. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/javascript.py +0 -0
  118. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/jcl.py +0 -0
  119. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/python.py +0 -0
  120. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/sql.py +0 -0
  121. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/languages/structural.py +0 -0
  122. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/manager.py +0 -0
  123. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/adapters/treesitter/models.py +0 -0
  124. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/README.md +0 -0
  125. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/__init__.py +0 -0
  126. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/commands/__init__.py +0 -0
  127. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/commands/graph.py +0 -0
  128. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/commands/repo.py +0 -0
  129. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/commands/run.py +0 -0
  130. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/cli/progress.py +0 -0
  131. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/__init__.py +0 -0
  132. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/cache_utils.py +0 -0
  133. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/chunking.py +0 -0
  134. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/document_reader.py +0 -0
  135. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/exceptions.py +0 -0
  136. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/file_utils.py +0 -0
  137. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/json_utils.py +0 -0
  138. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/llm_utils.py +0 -0
  139. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/logging.py +0 -0
  140. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/ocel.py +0 -0
  141. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/paths.py +0 -0
  142. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/schema_utils.py +0 -0
  143. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/settings.py +0 -0
  144. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/time_utils.py +0 -0
  145. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/timing.py +0 -0
  146. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/types.py +0 -0
  147. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/common/urls.py +0 -0
  148. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/__init__.py +0 -0
  149. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/__init__.py +0 -0
  150. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/consistency.py +0 -0
  151. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/cross_repo_analysis.py +0 -0
  152. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/deviation.py +0 -0
  153. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/fit_analysis.py +0 -0
  154. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/model_quality.py +0 -0
  155. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/run_consistency.py +0 -0
  156. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/semantic_matching.py +0 -0
  157. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/stability_analysis.py +0 -0
  158. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/analysis/types.py +0 -0
  159. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/__init__.py +0 -0
  160. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/application_interface.py +0 -0
  161. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/business_actor.py +0 -0
  162. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/business_event.py +0 -0
  163. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/business_function.py +0 -0
  164. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/business_object.py +0 -0
  165. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/business_process.py +0 -0
  166. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/function_model.py +0 -0
  167. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/node.py +0 -0
  168. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/prep.py +0 -0
  169. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/quality.py +0 -0
  170. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/__init__.py +0 -0
  171. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/base.py +0 -0
  172. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/duplicate_elements.py +0 -0
  173. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/duplicate_relationships.py +0 -0
  174. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/graph_relationships.py +0 -0
  175. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/joint_consistency.py +0 -0
  176. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/normalization.py +0 -0
  177. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/orphan_elements.py +0 -0
  178. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/derivation/refine/structural_consistency.py +0 -0
  179. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/__init__.py +0 -0
  180. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/business_concept.py +0 -0
  181. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/classification.py +0 -0
  182. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/concept_candidates.py +0 -0
  183. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/cooperation.py +0 -0
  184. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/coverage.py +0 -0
  185. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/data_domains.py +0 -0
  186. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/directory.py +0 -0
  187. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/directory_classification.py +0 -0
  188. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/external_dependency.py +0 -0
  189. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/file.py +0 -0
  190. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/method.py +0 -0
  191. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/repository.py +0 -0
  192. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/roles.py +0 -0
  193. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/step_tags.py +0 -0
  194. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/technologies.py +0 -0
  195. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/technology_candidates.py +0 -0
  196. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/test.py +0 -0
  197. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/modules/extraction/type_definition.py +0 -0
  198. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/__init__.py +0 -0
  199. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/about.py +0 -0
  200. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/config_models.py +0 -0
  201. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/export_bundle.py +0 -0
  202. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/llm_log.py +0 -0
  203. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/model_configs.py +0 -0
  204. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/ontology.py +0 -0
  205. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/overfit.py +0 -0
  206. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/pipeline.py +0 -0
  207. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/quality.py +0 -0
  208. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/session.py +0 -0
  209. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/storage.py +0 -0
  210. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/deriva/services/trace.py +0 -0
  211. {deriva_cli-0.8.7 → deriva_cli-0.8.8}/packages/README-deriva-cli.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deriva-cli
3
- Version: 0.8.7
3
+ Version: 0.8.8
4
4
  Summary: Deriva is a research project aimed at enabling digital architects by automating the derivation of enterprise architecture models. Deriva uses dual knowledge graphs, heuristics and LLM's.
5
5
  Keywords: archimate,enterprise-architecture,code-analysis,llm,grafeo,fastapi
6
6
  Author: S. T. Grond
@@ -35,7 +35,7 @@ Requires-Dist: tree-sitter-c-sharp>=0.23
35
35
  Requires-Dist: pypdf>=6
36
36
  Requires-Dist: python-docx>=1.2
37
37
  Requires-Dist: spacy==3.8.16
38
- Requires-Dist: ctranslate2==4.8.3
38
+ Requires-Dist: ctranslate2==4.8.4
39
39
  Requires-Dist: sentencepiece==0.2.2
40
40
  Requires-Dist: solvor>=0.6.3
41
41
  Requires-Dist: pydantic-ai-slim[openai,anthropic]>=2.57
@@ -168,9 +168,7 @@ class ArchimateManager:
168
168
 
169
169
  # Validate relationship
170
170
  if validate:
171
- is_valid, errors = self.validator.validate_relationship(relationship)
172
- if not is_valid:
173
- raise ValidationError(f"Relationship validation failed: {errors}")
171
+ self._validate_relationship(relationship)
174
172
 
175
173
  try:
176
174
  # Create Cypher query to add relationship
@@ -215,6 +213,26 @@ class ArchimateManager:
215
213
  logger.error(f"Failed to add relationship {relationship.identifier}: {e}")
216
214
  raise
217
215
 
216
+ def _validate_relationship(self, relationship: Relationship) -> None:
217
+ """Raise ValidationError for a relationship the validator or the metamodel refuses: the metamodel decides
218
+ the type pair of the stored source and target (an endpoint that is not stored fails when it is created)."""
219
+ if self.db is None:
220
+ raise RuntimeError("Not connected to grafeo. Call connect() first.")
221
+ is_valid, errors = self.validator.validate_relationship(relationship)
222
+ if is_valid:
223
+ rows = self.db.execute_read(
224
+ f"MATCH (e:`{self.namespace}`) WHERE e.identifier IN [$source, $target] "
225
+ f"RETURN e.identifier AS identifier, [lbl IN labels(e) WHERE lbl <> '{self.namespace}'][0] AS element_type",
226
+ {"source": relationship.source, "target": relationship.target},
227
+ )
228
+ types = {row["identifier"]: row["element_type"] for row in rows}
229
+ if (source := types.get(relationship.source)) and (target := types.get(relationship.target)):
230
+ allowed, reason = self.metamodel.can_relate(source, relationship.relationship_type, target)
231
+ if not allowed:
232
+ is_valid, errors = False, [reason]
233
+ if not is_valid:
234
+ raise ValidationError(f"Relationship validation failed: {errors}")
235
+
218
236
  def get_element(self, identifier: str) -> Element | None:
219
237
  """Get an element by identifier.
220
238
 
@@ -672,9 +690,7 @@ class ArchimateManager:
672
690
  documentation=old.documentation,
673
691
  properties=old.properties,
674
692
  )
675
- is_valid, errors = self.validator.validate_relationship(new)
676
- if not is_valid:
677
- raise ValidationError(f"Relationship validation failed: {errors}")
693
+ self._validate_relationship(new)
678
694
  # Attributes that steps wrote directly on the edge (such as a consolidated confidence) go along
679
695
  edge = f"(:`{self.namespace}`)-[r]->(:`{self.namespace}`)"
680
696
  rows = self.query(f"MATCH {edge} WHERE r.identifier = $identifier RETURN properties(r) AS attributes", {"identifier": identifier})
@@ -60,6 +60,12 @@ ELEMENT_TYPES: dict[str, ElementType] = {
60
60
  aspect="Behavior",
61
61
  description="An explicitly defined exposed application behavior",
62
62
  ),
63
+ "ApplicationFunction": ElementType(
64
+ name="ApplicationFunction",
65
+ layer="Application",
66
+ aspect="Behavior",
67
+ description="Automated behavior that can be performed by an application component",
68
+ ),
63
69
  "DataObject": ElementType(
64
70
  name="DataObject",
65
71
  layer="Application",
@@ -97,6 +103,18 @@ ELEMENT_TYPES: dict[str, ElementType] = {
97
103
  aspect="Structure",
98
104
  description="An organizational entity that is capable of performing behavior",
99
105
  ),
106
+ "BusinessRole": ElementType(
107
+ name="BusinessRole",
108
+ layer="Business",
109
+ aspect="Structure",
110
+ description="The responsibility for performing specific behavior, to which an actor can be assigned",
111
+ ),
112
+ "BusinessService": ElementType(
113
+ name="BusinessService",
114
+ layer="Business",
115
+ aspect="Behavior",
116
+ description="An explicitly defined behavior that a business role, business actor, or business collaboration exposes to its environment",
117
+ ),
100
118
  # Technology Layer
101
119
  "Node": ElementType(
102
120
  name="Node",
@@ -116,13 +134,19 @@ ELEMENT_TYPES: dict[str, ElementType] = {
116
134
  aspect="Structure",
117
135
  description="Software that provides or contributes to an environment for storing, executing, and using software or data",
118
136
  ),
137
+ "TechnologyFunction": ElementType(
138
+ name="TechnologyFunction",
139
+ layer="Technology",
140
+ aspect="Behavior",
141
+ description="A collection of technology behavior that can be performed by a technology internal active structure element",
142
+ ),
119
143
  "TechnologyService": ElementType(
120
144
  name="TechnologyService",
121
145
  layer="Technology",
122
146
  aspect="Behavior",
123
147
  description="An explicitly defined exposed technology behavior",
124
148
  ),
125
- # A detail-level element (the export's detail level): the deployed image or package of a component
149
+ # The deployed image, package or bundle of a component (one per component with a function; 0.8.8)
126
150
  "Artifact": ElementType(
127
151
  name="Artifact",
128
152
  layer="Technology",
@@ -141,6 +165,7 @@ STRUCTURE_ELEMENTS: set[str] = {
141
165
  "ApplicationComponent",
142
166
  "ApplicationInterface",
143
167
  "BusinessActor",
168
+ "BusinessRole",
144
169
  "Node",
145
170
  "Device",
146
171
  "SystemSoftware",
@@ -149,9 +174,12 @@ STRUCTURE_ELEMENTS: set[str] = {
149
174
  # Behavior elements (processes, services, functions)
150
175
  BEHAVIOR_ELEMENTS: set[str] = {
151
176
  "ApplicationService",
177
+ "ApplicationFunction",
152
178
  "BusinessProcess",
153
179
  "BusinessFunction",
154
180
  "BusinessEvent",
181
+ "BusinessService",
182
+ "TechnologyFunction",
155
183
  "TechnologyService",
156
184
  }
157
185
 
@@ -170,11 +198,14 @@ APPLICATION_LAYER: set[str] = {
170
198
  "ApplicationComponent",
171
199
  "ApplicationInterface",
172
200
  "ApplicationService",
201
+ "ApplicationFunction",
173
202
  "DataObject",
174
203
  }
175
204
 
176
205
  BUSINESS_LAYER: set[str] = {
177
206
  "BusinessActor",
207
+ "BusinessRole",
208
+ "BusinessService",
178
209
  "BusinessProcess",
179
210
  "BusinessFunction",
180
211
  "BusinessEvent",
@@ -185,6 +216,7 @@ TECHNOLOGY_LAYER: set[str] = {
185
216
  "Node",
186
217
  "Device",
187
218
  "SystemSoftware",
219
+ "TechnologyFunction",
188
220
  "TechnologyService",
189
221
  "Artifact",
190
222
  }
@@ -201,13 +233,39 @@ def layer_of(element_type: str) -> str:
201
233
  return "Other"
202
234
 
203
235
 
236
+ # Internal behaviour per layer: the same behaviour is often modelled as any of these (a function or a process)
237
+ INTERNAL_BEHAVIOUR: dict[str, str] = {f"{layer}{kind}": layer for layer in ("Business", "Application", "Technology") for kind in ("Process", "Function", "Interaction", "Event")}
238
+
239
+
240
+ def types_match(derived: str, reference: str) -> bool:
241
+ """Whether a derived element's type counts as a reference element's type when a model is compared with a reference:
242
+ the same type, or both internal behaviour (process, function, interaction, event) of one layer (user, 2026-10-19).
243
+ Services and structure types stay strict."""
244
+ if derived == reference:
245
+ return True
246
+ layer = INTERNAL_BEHAVIOUR.get(derived)
247
+ return layer is not None and layer == INTERNAL_BEHAVIOUR.get(reference)
248
+
249
+
250
+ def match_kind(element_type: str) -> str:
251
+ """The key an element type is matched under: internal behaviour as its layer's behaviour, else the type itself (two
252
+ types match exactly when their keys are equal, as ``types_match`` says)."""
253
+ layer = INTERNAL_BEHAVIOUR.get(element_type)
254
+ return f"{layer} behaviour" if layer else element_type
255
+
256
+
204
257
  # =============================================================================
205
258
  # ArchiMate 3.2 Relationship Table
206
259
  # =============================================================================
207
- # Source: ArchiMate 3.2 Specification, Appendix B.5 "Relationship Tables", restricted
208
- # to the 13 element types Deriva derives plus Artifact (the export's detail level). The spec publishes the tables as images;
209
- # letters were read from them and cross-checked (case-insensitively, all 169 cells)
210
- # against Archi's relationships.xml v3.2.
260
+ # Source: ArchiMate 3.2 Specification (C226), restricted to the element types Deriva derives plus Artifact. Letters:
261
+ # Archi's relationships.xml v3.2 (Influence left out), which matches the spec's Appendix B.5 tables in every cell. Tier,
262
+ # from the metamodel figures (0.8.8; B.4, p. 140: the restrictions apply to derived relationships only, not to those the
263
+ # metamodel diagrams define): uppercase where a figure draws the relationship, else lowercase. The figures: within a
264
+ # layer Fig. 52 p. 58 (business), Fig. 70 p. 73 (application), Fig. 82 p. 83 (technology), with Fig. 53 p. 59 (actor
265
+ # assigned to role), Fig. 71 p. 74 (component realizes component), Fig. 83 p. 84 (node, device, system software) and
266
+ # Fig. 97 p. 93 (artifact); across layers Fig. 104 p. 101 and Fig. 105 p. 102; the note under every layer figure for
267
+ # same-type composition, aggregation and specialization. Triggering and flow only where a figure draws both line ends
268
+ # unambiguously. Association is allowed between any two elements (uppercase everywhere).
211
269
  #
212
270
  # Uppercase letter: relationship explicit in the metamodel figures ("direct").
213
271
  # Lowercase letter: allowed only via the spec's derivation rules ("derived").
@@ -230,46 +288,70 @@ _LETTER_BY_RELATIONSHIP = {name: letter for letter, name in RELATIONSHIP_LETTERS
230
288
 
231
289
  _TABLE_COLUMNS = (
232
290
  "BusinessActor",
291
+ "BusinessRole",
233
292
  "BusinessProcess",
234
293
  "BusinessFunction",
235
294
  "BusinessEvent",
295
+ "BusinessService",
236
296
  "BusinessObject",
237
297
  "ApplicationComponent",
238
298
  "ApplicationInterface",
239
299
  "ApplicationService",
300
+ "ApplicationFunction",
240
301
  "DataObject",
241
302
  "Node",
242
303
  "Device",
243
304
  "SystemSoftware",
305
+ "TechnologyFunction",
244
306
  "TechnologyService",
245
307
  "Artifact",
246
308
  )
247
309
 
248
- # Artifact (row and column) from Archi's relationships.xml; uppercase where the spec's metamodel figures show the
249
- # relationship: Node, Device and SystemSoftware are assigned to an artifact, an artifact realizes an application
250
- # component, a data object or system software; artifacts compose, aggregate and specialize artifacts.
251
- # Row = source, columns in _TABLE_COLUMNS order = target.
252
310
  # fmt: off
253
311
  _TABLE_ROWS: dict[str, tuple[str, ...]] = {
254
- "BusinessActor": ("SCGvtfO", "IvtfO", "IvtfO", "IvtfO", "aO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
255
- "BusinessProcess": ("vtfO", "SCGvTFO", "CGvTFO", "vTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
256
- "BusinessFunction": ("vtfO", "CGvTFO", "SCGvTFO", "vTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
257
- "BusinessEvent": ("vtfO", "vTFO", "vTFO", "SCGvTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
258
- "BusinessObject": ("O", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O", "O", "O", "O", "O"),
259
- "ApplicationComponent": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGRvtfO", "CgrvtfO", "irvtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
260
- "ApplicationInterface": ("VtfO", "vtfO", "vtfO", "vtfO", "aO", "VtfO", "SCGvtfO", "IvtfO", "aO", "VtfO", "VtfO", "VtfO", "vtfO", "aO"),
261
- "ApplicationService": ("VtfO", "VtfO", "VtfO", "vtfO", "aO", "VtfO", "vtfO", "SCGvTFO", "AO", "VtfO", "VtfO", "VtfO", "vtfO", "aO"),
262
- "DataObject": ("O", "O", "O", "O", "RO", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O"),
263
- "Node": ("ivtfO", "irvtfO", "irvtfO", "irvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGivtfO", "CGirvtfO", "CGirvtfO", "irvtfO", "aIO"),
264
- "Device": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "SCGvtfO", "CGIrvtfO", "irvtfO", "aIO"),
265
- "SystemSoftware": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "vtfO", "SCGIrvtfO", "irvtfO", "aIO"),
266
- "TechnologyService": ("VtfO", "VtfO", "VtfO", "vtfO", "aO", "VtfO", "vtfO", "RvtfO", "aO", "VtfO", "VtfO", "VtfO", "SCGvTFO", "aO"),
267
- "Artifact": ("O", "rO", "rO", "rO", "rO", "RO", "rO", "rO", "RO", "O", "O", "RO", "rO", "SCGrO"),
312
+ "BusinessActor": ("SCGvtfO", "IvtfO", "IvtfO", "IvtfO", "IvtfO", "irvtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
313
+ "BusinessRole": ("vtfO", "SCGvtfO", "IvtfO", "IvtfO", "IvtfO", "irvtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
314
+ "BusinessProcess": ("vtfO", "vtfO", "SCGvTFO", "CGvTFO", "vTFO", "RvtfO", "AO", "vtfO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
315
+ "BusinessFunction": ("vtfO", "vtfO", "CGvTFO", "SCGvTFO", "vTFO", "RvtfO", "AO", "vtfO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
316
+ "BusinessEvent": ("vtfO", "vtfO", "vTFO", "vTFO", "SCGvTFO", "vtfO", "AO", "vtfO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
317
+ "BusinessService": ("VtfO", "VtfO", "VtfO", "VtfO", "vtfO", "SCGvTFO", "AO", "vtfO", "vtfO", "vtfO", "VtfO", "aO", "vtfO", "vtfO", "vtfO", "VtfO", "vtfO", "aO"),
318
+ "BusinessObject": ("O", "O", "O", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O"),
319
+ "ApplicationComponent": ("vtfO", "vtfO", "rvtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGRvtfO", "CgrvtfO", "irvtfO", "IrvtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"), # noqa: E501
320
+ "ApplicationInterface": ("VtfO", "VtfO", "vtfO", "vtfO", "vtfO", "rvtfO", "aO", "VtfO", "SCGvtfO", "IvtfO", "vtfO", "aO", "VtfO", "VtfO", "VtfO", "vtfO", "vtfO", "aO"),
321
+ "ApplicationService": ("vtfO", "vtfO", "VtfO", "VtfO", "vtfO", "RvtfO", "aO", "VtfO", "vtfO", "SCGvTFO", "VtfO", "AO", "vtfO", "vtfO", "vtfO", "VtfO", "vtfO", "aO"),
322
+ "ApplicationFunction": ("vtfO", "vtfO", "RvtfO", "RvtfO", "vtfO", "rvtfO", "aO", "vtfO", "vtfO", "RvtfO", "SCGvTFO", "AO", "vtfO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
323
+ "DataObject": ("O", "O", "O", "O", "O", "O", "RO", "O", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O", "O"),
324
+ "Node": ("ivtfO", "ivtfO", "irvtfO", "irvtfO", "irvtfO", "irvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGivtfO", "CGirvtfO", "CGirvtfO", "IrvtfO", "irvtfO", "iaO"), # noqa: E501
325
+ "Device": ("vtfO", "vtfO", "rvtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "SCGvtfO", "CGIrvtfO", "IrvtfO", "irvtfO", "IaO"), # noqa: E501
326
+ "SystemSoftware": ("vtfO", "vtfO", "rvtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "vtfO", "SCGIrvtfO", "IrvtfO", "irvtfO", "IaO"), # noqa: E501
327
+ "TechnologyFunction": ("vtfO", "vtfO", "RvtfO", "RvtfO", "vtfO", "rvtfO", "aO", "vtfO", "vtfO", "rvtfO", "RvtfO", "aO", "vtfO", "vtfO", "vtfO", "SCGvTFO", "RvtfO", "AO"),
328
+ "TechnologyService": ("vtfO", "vtfO", "VtfO", "VtfO", "vtfO", "RvtfO", "aO", "vtfO", "vtfO", "RvtfO", "VtfO", "aO", "VtfO", "VtfO", "VtfO", "VtfO", "SCGvTFO", "AO"),
329
+ "Artifact": ("O", "O", "rO", "rO", "rO", "rO", "RO", "RO", "rO", "rO", "rO", "RO", "O", "O", "RO", "rO", "rO", "SCGrO"),
268
330
  }
269
331
  # fmt: on
270
332
 
271
333
  RELATIONSHIP_TABLE: dict[tuple[str, str], str] = {(source, target): cell for source, row in _TABLE_ROWS.items() for target, cell in zip(_TABLE_COLUMNS, row, strict=True)}
272
334
 
335
+ # The valid derivation rules of ArchiMate 3.2, Appendix B.2 (spec pp. 127-131; the potential rules of B.3 are left out),
336
+ # as plain data for the derivation engine: (number, first relationship types, second types, join, derived type).
337
+ # Joins: "chain" p(a,b) q(b,c) -> r(a,c); "back" p(a,b) q(c,b) -> r(c,a). Derived type: "weakest" (by
338
+ # STRUCTURAL_STRENGTH), "first" (p's type) or "second" (q's type). The restrictions of B.4 (p. 139) hold through the
339
+ # relationship table, which is built from the figures and these rules: a derived triple the table does not allow is none.
340
+ STRUCTURAL_RELATIONSHIPS = ("Composition", "Aggregation", "Assignment", "Realization") # Section 5.1
341
+ DEPENDENCY_RELATIONSHIPS = ("Serving", "Access", "Influence", "Association") # Section 5.2
342
+ DYNAMIC_RELATIONSHIPS = ("Triggering", "Flow") # Section 5.3
343
+ STRUCTURAL_STRENGTH = ("Realization", "Assignment", "Aggregation", "Composition") # B.2.2, weakest first
344
+ VALID_DERIVATION_RULES: tuple[tuple[str, tuple[str, ...], tuple[str, ...], str, str], ...] = (
345
+ ("DR 1", ("Specialization",), ("Specialization",), "chain", "first"), # p. 127: transitivity of specialization
346
+ ("DR 2", STRUCTURAL_RELATIONSHIPS, STRUCTURAL_RELATIONSHIPS, "chain", "weakest"), # p. 128
347
+ ("DR 3", STRUCTURAL_RELATIONSHIPS, DEPENDENCY_RELATIONSHIPS, "chain", "second"), # p. 129: in line
348
+ ("DR 4", STRUCTURAL_RELATIONSHIPS, DEPENDENCY_RELATIONSHIPS, "back", "second"), # p. 129: opposing
349
+ ("DR 5", STRUCTURAL_RELATIONSHIPS, DYNAMIC_RELATIONSHIPS, "chain", "second"), # p. 130
350
+ ("DR 6", STRUCTURAL_RELATIONSHIPS, ("Flow",), "back", "second"), # p. 130
351
+ ("DR 7", ("Triggering",), STRUCTURAL_RELATIONSHIPS, "chain", "first"), # p. 130
352
+ ("DR 8", ("Triggering",), ("Triggering",), "chain", "first"), # p. 131: transitivity of triggering
353
+ )
354
+
273
355
  # Relationship types Deriva may propose. Association, Specialization and Influence
274
356
  # are valid ArchiMate but deliberately not derived.
275
357
  DERIVABLE_RELATIONSHIP_TYPES: tuple[str, ...] = (
@@ -338,11 +420,18 @@ class ArchiMateMetamodel:
338
420
  # ArchiMate 3.2: a part is composed into at most one whole, and composition hierarchies are acyclic.
339
421
  single_parent_relationship_types: frozenset[str] = frozenset({"Composition"})
340
422
  acyclic_relationship_types: frozenset[str] = frozenset({"Composition"})
423
+ # Appendix B.2: the valid derivation rules as data, and the structural strength order they use (weakest first)
424
+ derivation_rules = VALID_DERIVATION_RULES
425
+ structural_strength = STRUCTURAL_STRENGTH
341
426
 
342
427
  def __init__(self):
343
428
  self.element_types = ELEMENT_TYPES
344
429
  self.relationship_types = RELATIONSHIP_TYPES
345
430
 
431
+ def tier(self, source_element_type: str, relationship_type: str, target_element_type: str) -> str | None:
432
+ """ "direct" (a metamodel figure draws it), "derived", or None if ArchiMate 3.2 does not allow it."""
433
+ return relationship_tier(source_element_type, relationship_type, target_element_type)
434
+
346
435
  def is_valid_element_type(self, element_type: str) -> bool:
347
436
  """Check if element type is valid."""
348
437
  return element_type in self.element_types
@@ -14,7 +14,7 @@ from dataclasses import dataclass, field
14
14
  from .models import Element, Relationship, layer_of
15
15
 
16
16
  ENTERPRISE, SOLUTION, DETAIL = "enterprise", "solution", "detail"
17
- DEPLOYMENT = frozenset({"ApplicationComponent", "Node", "Device", "SystemSoftware", "TechnologyService"})
17
+ DEPLOYMENT = frozenset({"ApplicationComponent", "Node", "Device", "SystemSoftware", "TechnologyFunction", "TechnologyService", "Artifact"})
18
18
  # (view name, viewpoint, element types, level), in export order
19
19
  VIEWPOINTS: tuple[tuple[str, str, frozenset[str] | None, str], ...] = (
20
20
  ("Layered (enterprise)", "Layered", None, ENTERPRISE),
@@ -24,11 +24,11 @@ VIEWPOINTS: tuple[tuple[str, str, frozenset[str] | None, str], ...] = (
24
24
  (
25
25
  "Business (enterprise)",
26
26
  "Business Process Cooperation",
27
- frozenset({"BusinessActor", "BusinessProcess", "BusinessFunction", "BusinessEvent", "ApplicationService"}),
27
+ frozenset({"BusinessActor", "BusinessRole", "BusinessProcess", "BusinessFunction", "BusinessEvent", "ApplicationService"}),
28
28
  ENTERPRISE,
29
29
  ),
30
30
  ("Application Structure (solution)", "Application Structure", frozenset({"ApplicationComponent"}), SOLUTION),
31
- ("Application Cooperation (solution)", "Application Cooperation", frozenset({"ApplicationComponent", "ApplicationInterface"}), SOLUTION),
31
+ ("Application Cooperation (solution)", "Application Cooperation", frozenset({"ApplicationComponent", "ApplicationInterface", "ApplicationFunction"}), SOLUTION),
32
32
  ("Information Structure (solution)", "Information Structure", frozenset({"DataObject"}), SOLUTION),
33
33
  ("Implementation and Deployment (solution)", "Implementation and Deployment", DEPLOYMENT, SOLUTION),
34
34
  ("Information Structure (detail)", "Information Structure", frozenset({"DataObject"}), DETAIL),
@@ -38,12 +38,12 @@ VIEWPOINTS: tuple[tuple[str, str, frozenset[str] | None, str], ...] = (
38
38
  )
39
39
 
40
40
  # A view needs an element of its anchor types (the Business view: a business element, not application services alone)
41
- ANCHORS = {"Business (enterprise)": frozenset({"BusinessActor", "BusinessProcess", "BusinessFunction", "BusinessEvent"})}
41
+ ANCHORS = {"Business (enterprise)": frozenset({"BusinessActor", "BusinessRole", "BusinessProcess", "BusinessFunction", "BusinessEvent"})}
42
42
  BANDS = ("Business", "Application", "Technology", "Other")
43
43
  TYPE_ORDER = (
44
- "BusinessActor", "BusinessFunction", "BusinessProcess", "BusinessEvent", "BusinessObject",
45
- "ApplicationComponent", "ApplicationInterface", "ApplicationService", "DataObject",
46
- "Node", "Device", "SystemSoftware", "TechnologyService", "Artifact",
44
+ "BusinessActor", "BusinessRole", "BusinessFunction", "BusinessProcess", "BusinessEvent", "BusinessObject",
45
+ "ApplicationComponent", "ApplicationInterface", "ApplicationService", "ApplicationFunction", "DataObject",
46
+ "Node", "Device", "SystemSoftware", "TechnologyFunction", "TechnologyService", "Artifact",
47
47
  ) # fmt: skip
48
48
  COLUMNS, WIDTH, HEIGHT, GAP, BAND_GAP, MARGIN = 6, 160, 60, 20, 60, 20
49
49
 
@@ -29,7 +29,11 @@ class ArchiMateXMLExporter:
29
29
 
30
30
  NSMAP = {None: ARCHIMATE_NS, "xsi": XSI_NS, "dc": DC_NS}
31
31
 
32
- SCHEMA_LOCATION = "http://www.opengroup.org/xsd/archimate/3.0/ http://www.opengroup.org/xsd/archimate/3.1/archimate3_Model.xsd"
32
+ # As the exchange format's own examples: the diagram schema (the export carries views) and Dublin Core (the metadata)
33
+ SCHEMA_LOCATION = (
34
+ "http://www.opengroup.org/xsd/archimate/3.0/ http://www.opengroup.org/xsd/archimate/3.1/archimate3_Diagram.xsd "
35
+ "http://purl.org/dc/elements/1.1/ http://www.opengroup.org/xsd/archimate/3.1/dc.xsd"
36
+ )
33
37
 
34
38
  def __init__(self, pretty_print: bool = True, encoding: str = "UTF-8"):
35
39
  """