archsight 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -1
  3. data/README.md +7 -2
  4. data/docs/computed_annotations.md +7 -5
  5. data/docs/icons.md +3 -2
  6. data/docs/index.md.erb +5 -4
  7. data/docs/licenses.md +1 -2
  8. data/docs/modeling.md +127 -6
  9. data/docs/pages.md +72 -6
  10. data/docs/search.md +26 -2
  11. data/docs/togaf.md +4 -0
  12. data/lib/archsight/annotations/annotation.rb +5 -4
  13. data/lib/archsight/annotations/computed.rb +5 -1
  14. data/lib/archsight/annotations/relation_resolver.rb +109 -83
  15. data/lib/archsight/cli.rb +9 -2
  16. data/lib/archsight/database.rb +59 -4
  17. data/lib/archsight/diagram.rb +7 -0
  18. data/lib/archsight/documentation.rb +9 -5
  19. data/lib/archsight/editor.rb +2 -2
  20. data/lib/archsight/export/confluence/exporter.rb +11 -2
  21. data/lib/archsight/export/confluence/storage.rb +99 -8
  22. data/lib/archsight/export/confluence/tables.rb +78 -0
  23. data/lib/archsight/helpers/fenced_blocks.rb +61 -0
  24. data/lib/archsight/helpers/requirements_blocks.rb +90 -0
  25. data/lib/archsight/helpers/resource_resolver.rb +1 -1
  26. data/lib/archsight/helpers/view_blocks.rb +108 -0
  27. data/lib/archsight/helpers/wiki_links.rb +50 -5
  28. data/lib/archsight/helpers.rb +3 -0
  29. data/lib/archsight/import/handlers/go_grapher.rb +4 -1
  30. data/lib/archsight/import/handlers/go_module_parser.rb +4 -1
  31. data/lib/archsight/linter.rb +31 -3
  32. data/lib/archsight/mcp/analyze_resource_tool.rb +2 -2
  33. data/lib/archsight/mcp/base.rb +38 -0
  34. data/lib/archsight/mcp/resource_doc_tool.rb +2 -2
  35. data/lib/archsight/query/ast.rb +2 -1
  36. data/lib/archsight/query/evaluator.rb +2 -2
  37. data/lib/archsight/references.rb +129 -0
  38. data/lib/archsight/requirements.rb +70 -0
  39. data/lib/archsight/resources/analysis.rb +2 -1
  40. data/lib/archsight/resources/application_component.rb +8 -3
  41. data/lib/archsight/resources/application_interface.rb +5 -3
  42. data/lib/archsight/resources/application_service.rb +8 -7
  43. data/lib/archsight/resources/base.rb +67 -17
  44. data/lib/archsight/resources/business_actor.rb +5 -3
  45. data/lib/archsight/resources/business_control.rb +80 -0
  46. data/lib/archsight/resources/business_process.rb +3 -2
  47. data/lib/archsight/resources/business_product.rb +6 -5
  48. data/lib/archsight/resources/compliance_evidence.rb +40 -3
  49. data/lib/archsight/resources/data_object.rb +3 -2
  50. data/lib/archsight/resources/import.rb +5 -2
  51. data/lib/archsight/resources/{business_constraint.rb → motivation_constraint.rb} +4 -4
  52. data/lib/archsight/resources/motivation_goal.rb +1 -1
  53. data/lib/archsight/resources/{business_requirement.rb → motivation_requirement.rb} +19 -8
  54. data/lib/archsight/resources/motivation_stakeholder.rb +2 -2
  55. data/lib/archsight/resources/page.rb +4 -2
  56. data/lib/archsight/resources/strategy_capability.rb +2 -2
  57. data/lib/archsight/resources/technology_artifact.rb +4 -3
  58. data/lib/archsight/resources/technology_node.rb +2 -2
  59. data/lib/archsight/resources/technology_service.rb +4 -0
  60. data/lib/archsight/resources/technology_system_software.rb +4 -0
  61. data/lib/archsight/resources/view.rb +2 -1
  62. data/lib/archsight/resources.rb +34 -3
  63. data/lib/archsight/template.rb +2 -2
  64. data/lib/archsight/version.rb +1 -1
  65. data/lib/archsight/view_table.rb +102 -0
  66. data/lib/archsight/web/api/docs.rb +1 -1
  67. data/lib/archsight/web/api/json_helpers.rb +21 -15
  68. data/lib/archsight/web/api/openapi/spec.yaml +135 -2
  69. data/lib/archsight/web/api/page_helpers.rb +8 -7
  70. data/lib/archsight/web/api/requirements_helpers.rb +26 -0
  71. data/lib/archsight/web/api/routes.rb +19 -0
  72. data/lib/archsight/web/application.rb +12 -2
  73. data/lib/archsight/web/public/vue/ApiDocsPage-DZ0fa5-h.css +1 -0
  74. data/lib/archsight/web/public/vue/ApiDocsPage-DoOxKjG0.js +1 -0
  75. data/lib/archsight/web/public/vue/{DocPage-uaT8CdFm.js → DocPage-CfsC3CeQ.js} +1 -1
  76. data/lib/archsight/web/public/vue/EditorPage-CbG4mc9T.css +1 -0
  77. data/lib/archsight/web/public/vue/EditorPage-CsJA0q8n.js +35 -0
  78. data/lib/archsight/web/public/vue/ErrorPage-Ck9izEUS.css +1 -0
  79. data/lib/archsight/web/public/vue/ErrorPage-OJpJz9df.js +2 -0
  80. data/lib/archsight/web/public/vue/GraphView-BvWAbUAl.css +1 -0
  81. data/lib/archsight/web/public/vue/GraphView-CBq6oFRV.js +1 -0
  82. data/lib/archsight/web/public/vue/HomePage-BwgMLgVC.js +2 -0
  83. data/lib/archsight/web/public/vue/InstanceRouter-DQz-SsQq.js +1 -0
  84. data/lib/archsight/web/public/vue/InstanceRouter-jeavM6PW.css +1 -0
  85. data/lib/archsight/web/public/vue/KindList-4q0K9Cll.js +1 -0
  86. data/lib/archsight/web/public/vue/PageView-DzeGnvoS.js +1 -0
  87. data/lib/archsight/web/public/vue/QueryError-3EqjpbyV.css +1 -0
  88. data/lib/archsight/web/public/vue/QueryError-kg6Yf-pW.js +1 -0
  89. data/lib/archsight/web/public/vue/ResourceList-B0FLaFR3.css +1 -0
  90. data/lib/archsight/web/public/vue/ResourceList-Df_0e0qt.js +2 -0
  91. data/lib/archsight/web/public/vue/SearchResults-CKgY6_wH.js +1 -0
  92. data/lib/archsight/web/public/vue/SearchResults-CyPUZZSC.css +1 -0
  93. data/lib/archsight/web/public/vue/WikiPage-DoFJ0dbW.css +1 -0
  94. data/lib/archsight/web/public/vue/WikiPage-DrvCHwJ7.js +13 -0
  95. data/lib/archsight/web/public/vue/architecture-7GRP2DOG-BfA1TPxQ.js +1 -0
  96. data/lib/archsight/web/public/vue/cynefin-OW5HDTMX-BmgdUKVD.js +1 -0
  97. data/lib/archsight/web/public/vue/eventmodeling-NTZA5JFV-DbXDvAWF.js +1 -0
  98. data/lib/archsight/web/public/vue/gitGraph-4MIJSDKK-BkVhrKS1.js +1 -0
  99. data/lib/archsight/web/public/vue/index-D0Q5GZRs.js +3 -0
  100. data/lib/archsight/web/public/vue/index-oF-iyZvk.css +1 -0
  101. data/lib/archsight/web/public/vue/info-A6RAGUB7-BIlCVuUY.js +1 -0
  102. data/lib/archsight/web/public/vue/mermaid-BjEi5URd.js +3334 -0
  103. data/lib/archsight/web/public/vue/packet-AYTQ26CC-eoQTjY3j.js +1 -0
  104. data/lib/archsight/web/public/vue/pie-WAS4IAKB-DEOotGhh.js +1 -0
  105. data/lib/archsight/web/public/vue/radar-RG4KPBEZ-C2yucuUN.js +1 -0
  106. data/lib/archsight/web/public/vue/railroad-74A4TZTK-CzONK5VY.js +1 -0
  107. data/lib/archsight/web/public/vue/railroad-abnf-HS5TGJTU-9zRPsDsx.js +1 -0
  108. data/lib/archsight/web/public/vue/railroad-ebnf-LZEXJU2U-BJ4dkz9l.js +1 -0
  109. data/lib/archsight/web/public/vue/railroad-peg-WCYAUIDC-DFy_rqAj.js +1 -0
  110. data/lib/archsight/web/public/vue/treeView-Q6P3EWNA-2cq5CyD2.js +1 -0
  111. data/lib/archsight/web/public/vue/treemap-WGGIJYW6-DK-e9Ez4.js +1 -0
  112. data/lib/archsight/web/public/vue/{useGraphviz-C71SdG-N.js → useGraphviz-DweKV7Kg.js} +1 -1
  113. data/lib/archsight/web/public/vue/wardley-WFR3VGLG-BQwqUqfB.js +1 -0
  114. data/lib/archsight/web/public/vue.html +3 -3
  115. data/lib/archsight.rb +2 -0
  116. metadata +53 -42
  117. data/lib/archsight/web/public/vue/ApiDocsPage-C0y953v0.css +0 -1
  118. data/lib/archsight/web/public/vue/ApiDocsPage-C_4tAWis.js +0 -1
  119. data/lib/archsight/web/public/vue/EditorPage-C557BJC-.js +0 -35
  120. data/lib/archsight/web/public/vue/EditorPage-df5N-p21.css +0 -1
  121. data/lib/archsight/web/public/vue/ErrorPage-Vdebmife.js +0 -2
  122. data/lib/archsight/web/public/vue/ErrorPage-uMDnfY5_.css +0 -1
  123. data/lib/archsight/web/public/vue/GraphView-BduUql2N.js +0 -1
  124. data/lib/archsight/web/public/vue/GraphView-Cj2V2stN.css +0 -1
  125. data/lib/archsight/web/public/vue/HomePage-BHUTg8Ap.js +0 -2
  126. data/lib/archsight/web/public/vue/InstanceRouter-1lSigA58.js +0 -1
  127. data/lib/archsight/web/public/vue/InstanceRouter-Di7f3Rya.css +0 -1
  128. data/lib/archsight/web/public/vue/KindList-BDZs0j6d.js +0 -1
  129. data/lib/archsight/web/public/vue/PageView-BYzJDwof.js +0 -1
  130. data/lib/archsight/web/public/vue/ResourceList-CnbhU9wm.js +0 -1
  131. data/lib/archsight/web/public/vue/ResourceList-xyBwu7fh.css +0 -1
  132. data/lib/archsight/web/public/vue/SearchResults-CNhf6VOx.js +0 -1
  133. data/lib/archsight/web/public/vue/SearchResults-DOHzqAy3.css +0 -1
  134. data/lib/archsight/web/public/vue/WikiPage-DbmWkM7W.js +0 -13
  135. data/lib/archsight/web/public/vue/WikiPage-GV67QmNJ.css +0 -1
  136. data/lib/archsight/web/public/vue/architecture-TIHT7OUA-Bf-MWFmn.js +0 -1
  137. data/lib/archsight/web/public/vue/cynefin-VYW2F7L2-CkKt8qqs.js +0 -1
  138. data/lib/archsight/web/public/vue/eventmodeling-45OFAUF4-NwSTYPHj.js +0 -1
  139. data/lib/archsight/web/public/vue/gitGraph-TEB2WS4Q-DLRegrRG.js +0 -1
  140. data/lib/archsight/web/public/vue/index-CyVWObLU.js +0 -3
  141. data/lib/archsight/web/public/vue/index-DtKeHT3S.css +0 -1
  142. data/lib/archsight/web/public/vue/info-DKCQHKI2-EV39NzoN.js +0 -1
  143. data/lib/archsight/web/public/vue/mermaid-BMkGfnhm.js +0 -3279
  144. data/lib/archsight/web/public/vue/packet-7NZHBO7P-USljV3MZ.js +0 -1
  145. data/lib/archsight/web/public/vue/pie-RZYD4A2V-DChciBW2.js +0 -1
  146. data/lib/archsight/web/public/vue/radar-I7S5WNFK-CgGJdW1t.js +0 -1
  147. data/lib/archsight/web/public/vue/railroad-3IZDKUUU-Dy43vF5c.js +0 -1
  148. data/lib/archsight/web/public/vue/railroad-abnf-AHOZXSZD-BhsTH-sE.js +0 -1
  149. data/lib/archsight/web/public/vue/railroad-ebnf-EBAXGLYW-BBTd_u0u.js +0 -1
  150. data/lib/archsight/web/public/vue/railroad-peg-LSFZ7HO6-BiNTEzf0.js +0 -1
  151. data/lib/archsight/web/public/vue/treeView-QDETBFTQ-BfnCcf-q.js +0 -1
  152. data/lib/archsight/web/public/vue/treemap-6X3UGDF4-BsAORhvk.js +0 -1
  153. data/lib/archsight/web/public/vue/wardley-OPB4EBWU-DQvnEhRj.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47bed92ae99f141a261c0dc19a47095a566bd60b9c6a9201dbcd2f6298e1a35f
4
- data.tar.gz: 5ff9e1d7d7f02162192a95d86a3a89194b1e450006f4766191da9206f7de55bf
3
+ metadata.gz: 464d36ecbae64b55e25554f9d60d9c208fb2477ba1910f2318c415eef2cea018
4
+ data.tar.gz: e423de1798a1a0fc99f16220051139800780e6bd9f01b096bce378dda1ccb25e
5
5
  SHA512:
6
- metadata.gz: dd5b2c1db012e147af1f123c530184b1c4a6eab3b5e7e1e1dbacb658c6e70080b461975d659d68faeca43118989d52d63d134a91fee79767966f06797e352b3c
7
- data.tar.gz: f50137692088c6f3a24e799eb7433206e5124c5d83805b94e4d1ea1992537b71528f742538fe6362f4c56c547ffa88cca3d5719bfa153fb09181b893046f4de5
6
+ metadata.gz: 0eb109e3f462b8ec1a23a17ab8c95d5d8bc176a5b54d038e47fa9dcf383e2597c9cc4a540efb1bd876714b279486dfd5a74d1bf1adc8c435a64db07913128890
7
+ data.tar.gz: 7ce31438036e3addcc8bda4e3587165f13b31399bd7a416323747d1552d9ae910c3e53191f8f7689f7b01a3d84508b9a32cf6cf7486fbb9bde3c0920560283bd
data/CONTRIBUTING.md CHANGED
@@ -84,7 +84,7 @@ class Archsight::Resources::MyResource < Archsight::Resources::Base
84
84
  description: 'Custom field description',
85
85
  enum: ['value1', 'value2']
86
86
 
87
- relation :realizes, :businessRequirements, :BusinessRequirement
87
+ relation :realizes, :motivationRequirements, :MotivationRequirement
88
88
  end
89
89
  ```
90
90
 
data/README.md CHANGED
@@ -91,17 +91,22 @@ archsight web
91
91
  claude mcp add --transport sse ionos-architecture http://localhost:4567/mcp/sse
92
92
  ```
93
93
 
94
+ For a deployed server use its address, for example `claude mcp add --transport sse archsight https://archsight.example.com/mcp/sse`.
95
+ The MCP endpoint accepts any hostname, like the web UI and the API, and has no authentication of its own: if the
96
+ ingress requires a token, pass it with `--header "Authorization: Bearer <token>"`. The ingress must not buffer or
97
+ time out the long-lived SSE connection.
98
+
94
99
  **Available tools:**
95
100
 
96
101
  - `query` - Search and filter resources using the query language
97
102
  - `analyze_resource` - Get detailed resource information and impact analysis
98
103
  - `resource_doc` - Get documentation for resource kinds
99
104
 
100
- **Export to Confluence**: `archsight export --to confluence` publishes pages to the Confluence page they link to, with images, diagrams and draw.io, and refuses to overwrite edits made in Confluence unless `--force` ([Wiki pages](docs/pages.md#exporting-to-confluence)).
105
+ **Export to Confluence**: `archsight export --to confluence` publishes pages to the Confluence page they link to, with images, diagrams and draw.io, views and requirements as tables, and refuses to overwrite edits made in Confluence unless `--force` ([Wiki pages](docs/pages.md#exporting-to-confluence)).
101
106
 
102
107
  **Macros** such as `{status:yellow WIP}` and `{emoticon:2705}` work inline in pages ([Wiki pages](docs/pages.md#macros)).
103
108
 
104
- **Views and analyses** can be embedded in pages with `![[View/Name]]` / `![[Analysis/Name]]` ([Wiki pages](docs/pages.md#embedding-views-and-analyses)).
109
+ **Views and analyses** can be embedded in pages with `![[View/Name]]` / `![[Analysis/Name]]` ([Wiki pages](docs/pages.md#embedding-views-and-analyses)); a view can also be written in place with a ```` ```view ```` block ([inline views](docs/pages.md#inline-views)), and the requirements of a selection of resources shown with a ```` ```requirements ```` block ([requirements](docs/pages.md#requirements-of-a-selection-of-resources)).
105
110
 
106
111
  **Images and draw.io diagrams** are plain files in the resources directory and are embedded in markdown with relative
107
112
  paths (`![](../img/a.png)`, `![](../../fop/flow.drawio)`); only files of image, draw.io and `.asd` diagram types inside the resources
@@ -40,9 +40,13 @@ Computed annotations support all the same options as regular annotations:
40
40
  | `enum` | Array | nil | Allowed values |
41
41
  | `sidebar` | Boolean | false | Show in sidebar |
42
42
  | `type` | Class | nil | Type for value coercion (Integer, Float, String) |
43
- | `list` | Boolean | false | Whether values are lists |
43
+ | `summary` | Boolean | false | Return the value with every search hit of this kind (at most 3 per kind) |
44
44
  | `&block` | Block | required | The computation logic |
45
45
 
46
+ `summary: true` (also available on regular `annotation` definitions) marks the value as a summary attribute: the
47
+ search API returns it with every hit of the kind (`highlights`) and the result page shows it next to the name.
48
+ A kind can have at most 3 summary annotations; a fourth raises an `ArgumentError` when the kind is defined.
49
+
46
50
  ### Value Handling
47
51
 
48
52
  - **Nil values**: Not stored (annotation key won't exist)
@@ -89,8 +93,7 @@ end
89
93
  computed_annotation 'computed/languages',
90
94
  title: 'Languages',
91
95
  description: 'All programming languages used',
92
- filter: :list,
93
- list: true do
96
+ filter: :list do
94
97
  collect(outgoing_transitive(:TechnologyArtifact), 'scc/languages')
95
98
  end
96
99
  ```
@@ -299,8 +302,7 @@ class ApplicationComponent < Base
299
302
  computed_annotation 'computed/languages',
300
303
  title: 'Languages',
301
304
  description: 'All programming languages used across related artifacts',
302
- filter: :list,
303
- list: true do
305
+ filter: :list do
304
306
  collect(outgoing_transitive(:TechnologyArtifact), 'scc/languages')
305
307
  end
306
308
 
data/docs/icons.md CHANGED
@@ -11,16 +11,17 @@ Current icon assignments for each resource type:
11
11
  | ApplicationInterface | `usb` | <i class="iconoir-usb"></i> |
12
12
  | ApplicationService | `cube` | <i class="iconoir-cube"></i> |
13
13
  | BusinessActor | `community` | <i class="iconoir-community"></i> |
14
- | BusinessConstraint | `prohibition` | <i class="iconoir-prohibition"></i> |
14
+ | BusinessControl | `shield-search` | <i class="iconoir-shield-search"></i> |
15
15
  | BusinessProcess | `kanban-board` | <i class="iconoir-kanban-board"></i> |
16
16
  | BusinessProduct | `box-iso` | <i class="iconoir-box-iso"></i> |
17
- | BusinessRequirement | `task-list` | <i class="iconoir-task-list"></i> |
18
17
  | ComplianceEvidence | `shield-check` | <i class="iconoir-shield-check"></i> |
19
18
  | DataObject | `database` | <i class="iconoir-database"></i> |
20
19
  | ApplicationComponent | `component` | <i class="iconoir-component"></i> |
21
20
  | TechnologySystemSoftware | `terminal-tag` | <i class="iconoir-terminal-tag"></i> |
22
21
  | MotivationGoal | `archery` | <i class="iconoir-archery"></i> |
23
22
  | MotivationOutcome | `badge-check` | <i class="iconoir-badge-check"></i> |
23
+ | MotivationRequirement | `task-list` | <i class="iconoir-task-list"></i> |
24
+ | MotivationConstraint | `prohibition` | <i class="iconoir-prohibition"></i> |
24
25
  | MotivationStakeholder | `user-crown` | <i class="iconoir-user-crown"></i> |
25
26
  | TechnologyNode | `server-connection` | <i class="iconoir-server-connection"></i> |
26
27
  | StrategyCapability | `strategy` | <i class="iconoir-strategy"></i> |
data/docs/index.md.erb CHANGED
@@ -24,21 +24,22 @@ The following diagram shows all resource types organized by layer and their rela
24
24
 
25
25
  ### Motivation Layer
26
26
 
27
- Resources representing stakeholders, goals, and outcomes that drive architectural decisions.
27
+ Resources representing stakeholders, goals, outcomes, requirements, and constraints that drive architectural decisions.
28
28
 
29
29
  - [MotivationStakeholder](/doc/resources/motivation_stakeholder) - Roles with interests in the architecture
30
30
  - [MotivationGoal](/doc/resources/motivation_goal) - High-level statements of intent
31
31
  - [MotivationOutcome](/doc/resources/motivation_outcome) - End results or consequences
32
+ - [MotivationRequirement](/doc/resources/motivation_requirement) - Compliance, legal and functional requirements
33
+ - [MotivationConstraint](/doc/resources/motivation_constraint) - Limitations and restrictions
32
34
 
33
35
  ### Business Layer
34
36
 
35
- Resources representing business processes, actors, and products.
37
+ Resources representing business processes, actors, products, and the controls that guide processes.
36
38
 
37
39
  - [BusinessActor](/doc/resources/business_actor) - Teams and organizations
38
40
  - [BusinessProcess](/doc/resources/business_process) - Structured business workflows
39
41
  - [BusinessProduct](/doc/resources/business_product) - Products offered to customers
40
- - [BusinessRequirement](/doc/resources/business_requirement) - Business and compliance requirements
41
- - [BusinessConstraint](/doc/resources/business_constraint) - Limitations and restrictions
42
+ - [BusinessControl](/doc/resources/business_control) - Controls that guide business processes
42
43
 
43
44
  ### Strategy Layer
44
45
 
data/docs/licenses.md CHANGED
@@ -236,8 +236,7 @@ end
236
236
  # Collect all unique dependency licenses across the portfolio
237
237
  computed_annotation 'computed/license_types',
238
238
  title: 'All License Types',
239
- filter: :list,
240
- list: true do
239
+ filter: :list do
241
240
  collect(outgoing_transitive(:TechnologyArtifact), 'license/dependencies/licenses')
242
241
  end
243
242
 
data/docs/modeling.md CHANGED
@@ -52,6 +52,8 @@ Model **why** the architecture exists.
52
52
  | MotivationStakeholder | For roles that have interest in architecture outcomes (CTO, Security Team, Customers) |
53
53
  | MotivationGoal | For high-level objectives ("Achieve SOC 2 compliance", "Reduce latency") |
54
54
  | MotivationOutcome | For measurable results ("99.9% availability", "Sub-100ms response") |
55
+ | MotivationRequirement | For must-have capabilities (compliance, functional needs) |
56
+ | MotivationConstraint | For limitations (budget, regulations, technical debt) |
55
57
 
56
58
  **Example chain:** Stakeholder "Security Team" → hasConcern → Goal "Achieve Compliance" → realizes → Requirement "Encrypt data at rest"
57
59
 
@@ -64,11 +66,12 @@ Model **who** does **what** in business terms.
64
66
  | BusinessActor | For teams, departments, or organizations |
65
67
  | BusinessProcess | For workflows that produce business value |
66
68
  | BusinessProduct | For offerings to customers (cloud services, APIs) |
67
- | BusinessRequirement | For must-have capabilities (compliance, functional needs) |
68
- | BusinessConstraint | For limitations (budget, regulations, technical debt) |
69
+ | BusinessControl | For controls that guide a process (access review, change approval), with an owner and executors |
69
70
 
70
71
  **Example chain:** Actor "Platform Team" → performedBy → Process "Incident Response" → servedBy → Service "Monitoring"
71
72
 
73
+ **Controls:** Process "Incident Response" → guidedBy → Control "Escalation Review" → ownedBy / executedBy → Actor "Platform Team". How controls, requirements and evidence fit together is described under Relation Patterns below.
74
+
72
75
  ### Strategy Layer
73
76
 
74
77
  Model strategic **capabilities**.
@@ -114,7 +117,7 @@ Model **infrastructure** and **code**.
114
117
  Shows how abstract concepts become concrete:
115
118
 
116
119
  ```
117
- BusinessRequirement
120
+ MotivationRequirement
118
121
  ↓ realizes
119
122
  ApplicationService
120
123
  ↓ realizedThrough
@@ -135,17 +138,110 @@ TechnologyService
135
138
  TechnologySystemSoftware
136
139
  ```
137
140
 
141
+ ### Requirements, Controls and Evidence
142
+
143
+ A requirement is the point where the process side and the application side of compliance meet:
144
+
145
+ ```
146
+ Process side Application side
147
+
148
+ BusinessProcess ApplicationService / ApplicationComponent
149
+ ↓ guidedBy ↓ realizes / plans
150
+ BusinessControl ↓ evidencedBy
151
+ ↓ satisfies ComplianceEvidence
152
+ ↓ ↓ satisfies
153
+ └────────────→ MotivationRequirement ←────────┘
154
+ ```
155
+
156
+ | Kind | Answers | Key relations |
157
+ |------|---------|---------------|
158
+ | MotivationRequirement | What must hold? | satisfied by controls and evidence; realized or planned by applications |
159
+ | BusinessControl | What do we do about it, who does it, how often? | a process is `guidedBy` it; `ownedBy` and `executedBy` actors; `satisfies` requirements; `evidencedBy` evidence |
160
+ | ComplianceEvidence | How is it met, how can it be shown? | `satisfies` requirements; `evidencedBy` from an application, a technology element or a control |
161
+
162
+ How to model it:
163
+
164
+ - **Process side.** Model a control once, let every process it governs point to it with `guidedBy`, and link it with `satisfies` to each requirement it addresses. Give it an owner (the accountable actor) and executors (the actors carrying it out). The `control/status` and `control/frequency` filters find, for example, the controls that are only partially implemented.
165
+ - **Application side.** Whether an application implements a requirement is stated on the application (`realizes`, `plans`, `evidencedBy`), never on the control. Evidence is per resource and requirement: it says how *this* service or component meets *that* requirement.
166
+ - **Evidence of a control.** A control can be `evidencedBy` evidence too. Use it for the records the control itself produces (reviews, diagrams, change history, audit logs) and set `evidence/type` to `process`, `documentation` or `audit-log`. Evidence that an application meets a requirement is linked from the application, not from a control.
167
+ - **Reading it back.** A requirement's page lists its controls and evidence as incoming `satisfies` relations. The "Requirements" table of an application page and the `requirements` blocks list what applications implement (`realizes`, `partiallyRealizes`, `plans`); controls are not part of that table.
168
+
169
+ ```yaml
170
+ # process side
171
+ kind: BusinessProcess
172
+ metadata: { name: Process:ChangeManagement }
173
+ spec:
174
+ guidedBy:
175
+ businessControls: [Control:ChangeApproval]
176
+ ---
177
+ kind: BusinessControl
178
+ metadata: { name: Control:ChangeApproval }
179
+ spec:
180
+ ownedBy: { businessActors: [Team:Management] }
181
+ executedBy: { businessActors: [Team:Operations] }
182
+ satisfies: { motivationRequirements: [Requirement:ChangeTraceability] }
183
+ ---
184
+ # application side
185
+ kind: ApplicationService
186
+ metadata: { name: Deployment }
187
+ spec:
188
+ realizes: { motivationRequirements: [Requirement:ChangeTraceability] }
189
+ evidencedBy: { complianceEvidences: [Evidence:DeploymentAuditLog] }
190
+ ```
191
+
138
192
  ### Compliance Chain
139
193
 
140
194
  Shows how requirements are satisfied:
141
195
 
142
196
  ```
143
- BusinessRequirement
197
+ MotivationRequirement
144
198
  ↑ satisfies
145
199
  ComplianceEvidence
146
200
  ↑ evidencedBy
147
- ApplicationService
201
+ ApplicationService (or TechnologyService / TechnologySystemSoftware)
202
+ ```
203
+
204
+ Technology elements such as a Kubernetes cluster runtime can plan, realize and be evidenced
205
+ for requirements directly, so the requirement does not have to be attached to a placeholder
206
+ ApplicationService. Applications deployed on them point to the TechnologyService with `servedBy`.
207
+
208
+ ApplicationComponents can be evidenced as well (`realizes` / `plans motivationRequirements`, `evidencedBy
209
+ complianceEvidences`), so requirements can be answered per component and not only per service.
210
+
211
+ A ComplianceEvidence answers "how is the requirement met" in structured markdown fields next to
212
+ `architecture/description` (kept as a short summary): `evidence/mechanism`, `evidence/coverage`,
213
+ `evidence/operatorView` (does it hold against operators or only against other tenants),
214
+ `evidence/verification`, `evidence/gaps` and `evidence/sources`. Because they are separate annotations they can be
215
+ queried, for example `ComplianceEvidence: evidence/gaps =~ "needs review"`.
216
+
217
+ ### Derived References
218
+
219
+ Text and diagrams already say which resources they are about, so archsight turns that into relations instead of asking you
220
+ to repeat it in YAML. There are two, and they are never written in a file:
221
+
222
+ | Relation | Comes from | Where |
223
+ |----------|------------|-------|
224
+ | `mentions` | `[[Target]]`, `[[Kind/Name]]` links and `![[View/Name]]` embeds | the content of a page, the description of any resource, any markdown annotation |
225
+ | `depicts` | the `resource "..."` of the nodes of a diagram | ```` ```asd ```` blocks and `![](file.asd)` files in those texts, and the `architecture/diagram` of any resource |
226
+
148
227
  ```
228
+ Page "Architecture overview" --mentions--> ApplicationComponent "Core:Database" ([[Core:Database]])
229
+ Page "Architecture overview" --depicts---> ApplicationComponent "Web:API" (resource "Web:API" in a diagram)
230
+ ```
231
+
232
+ They are rebuilt on every load, so they cannot drift from the text. They show on both sides: a resource lists the pages
233
+ that mention and depict it under Relations ("Page / mentions"), and a page lists what it refers to. Only an exact name counts: a
234
+ page by its name or title, `Kind/Name`, or a resource name that exists once. Part of a name, a name that exists in several
235
+ kinds, and an unknown name do not make a relation (`archsight lint` reports unknown links in pages). Links in code are shown as
236
+ written and do not count, and neither does a resource referring to itself. Views and requirements blocks pick resources with a
237
+ query when they run, so they name nothing.
238
+
239
+ Derived relations are followed like written ones: queries (`ApplicationComponent: <- Page`, `Page: -> ApplicationComponent`),
240
+ transitive queries and impact analysis. A page that mentions a component therefore shows up when you ask what a change to the
241
+ component affects, which tells you which pages to update, and a resource that only a page mentions is not an orphan
242
+ (`<- none`). To leave them out of a query, exclude the verbs: `ApplicationComponent: ~{!mentions,depicts}> TechnologyArtifact`.
243
+ Computed annotations (costs, teams, repositories) follow written relations only, so a link in a text never changes a number.
244
+ They are not part of the editor's relation form, and `mentions:` or `depicts:` in a file is an unknown verb.
149
245
 
150
246
  ## Annotation Best Practices
151
247
 
@@ -190,7 +286,7 @@ relations:
190
286
  ### Compliance Mapping
191
287
 
192
288
  ```yaml
193
- kind: BusinessRequirement
289
+ kind: MotivationRequirement
194
290
  name: DataEncryption
195
291
  annotations:
196
292
  requirement/reference: c5-2020, gdpr-2018
@@ -200,3 +296,28 @@ relations:
200
296
  outcomes:
201
297
  - DataProtection
202
298
  ```
299
+
300
+ ## Renamed Kinds
301
+
302
+ Requirements and constraints are Motivation elements in ArchiMate, so their kinds are named that way:
303
+
304
+ | Old | New |
305
+ |-----|-----|
306
+ | `BusinessRequirement` | `MotivationRequirement` |
307
+ | `BusinessConstraint` | `MotivationConstraint` |
308
+ | relation key `businessRequirements` | `motivationRequirements` |
309
+ | relation key `businessConstraints` | `motivationConstraints` |
310
+
311
+ Both kinds moved from the Business to the Motivation layer. Their annotations (`requirement/*`) are unchanged.
312
+
313
+ For now the old names keep working: files with `kind: BusinessRequirement` or `businessRequirements:` keys load as they are, queries such as `BusinessRequirement: requirement/priority == "must"` and `~> BusinessRequirement` still match, and old links to `/kinds/BusinessRequirement/...` still open. Everything shown (the UI, the API, files written by the inline editor) uses the new names.
314
+
315
+ `archsight lint` lists every use of an old name as a deprecation, with the file and line, without failing. Replace them, for example with a find and replace over your resources directory (YAML files and the queries in markdown pages):
316
+
317
+ ```bash
318
+ find resources \( -name '*.yaml' -o -name '*.md' \) -exec sed -i.bak \
319
+ -e 's/BusinessRequirement/MotivationRequirement/g' -e 's/BusinessConstraint/MotivationConstraint/g' \
320
+ -e 's/businessRequirements/motivationRequirements/g' -e 's/businessConstraints/motivationConstraints/g' {} +
321
+ ```
322
+
323
+ The old names will be removed in a future release.
data/docs/pages.md CHANGED
@@ -146,6 +146,62 @@ link to the resource. Other kinds are not embeddable; an unknown name, another k
146
146
  a sentence (instead of on its own line) is shown as a marker or a link, and `archsight lint` reports embeds that do not
147
147
  resolve. Code blocks and inline code are left alone.
148
148
 
149
+ ### Inline views
150
+
151
+ A view that only this page needs does not have to be a resource of its own: a fenced ```` ```view ```` block holds the
152
+ View as it would be written in a YAML file and is shown like an embedded view:
153
+
154
+ ````markdown
155
+ ```view
156
+ apiVersion: architecture/v1alpha1
157
+ kind: View
158
+ metadata:
159
+ name: Services without backup # the title above the list, optional
160
+ annotations:
161
+ view/query: 'ApplicationService: backup/mode == "none"'
162
+ view/fields: name, @owner
163
+ view/sort: -name
164
+ view/type: list:name
165
+ ```
166
+ ````
167
+
168
+ Only `view/query` is required; `kind`, if given, must be `View` and `apiVersion` can be left out. Other annotations are
169
+ ignored, so a View's YAML can be pasted in unchanged (to turn the block into a real view later, or the other way round).
170
+ It loads and runs in the browser like any embed; the server only writes `<div class="view-embed" data-title data-query
171
+ data-fields data-sort data-type>` around the source. A block that is not a valid View (broken YAML, missing or
172
+ unparsable query, unknown `view/*` key or type) shows an error box with the source, and `archsight lint` reports it.
173
+
174
+ ### Requirements of a selection of resources
175
+
176
+ The "Requirements" table of an instance page (the requirements it `realizes`, `partiallyRealizes` or `plans`,
177
+ with status, priority and story) can be put on a page for any selection of resources with a ```` ```requirements ```` block:
178
+
179
+ ````markdown
180
+ ```requirements
181
+ title: Requirements of the backup services # optional, default "Requirements"
182
+ of: 'ApplicationService: name =~ "Backup"' # required: query selecting the resources
183
+ priority: must # optional: must, should, may (one value or a list)
184
+ status: [implemented, partial] # optional: implemented, partial, planned
185
+ ```
186
+ ````
187
+
188
+ The table has one row per requirement of all selected resources. Its status is the best one any of them gives it
189
+ (`realizes` = implemented, then `partially`, then `plans` = planned), and a "Realized by" column names the resources with their own
190
+ status (left out when only one resource is selected). Rows are sorted by priority, then name; `priority` and `status` filter the rows.
191
+ Like views, the block is only a placeholder on the server (`<div class="requirements-embed" data-title data-of data-priority
192
+ data-status>` around the source): the frontend loads the rows from `GET /api/v1/requirements?of=&priority=&status=`, so rendering a page
193
+ never runs the query. A block with a missing or unparsable `of`, an unknown key, priority or status shows an error box with the
194
+ source, and `archsight lint` reports it.
195
+
196
+ ## What a page refers to
197
+
198
+ What a page says about the architecture becomes relations without anything to write: `[[Core:Database]]` or `[[Kind/Name]]` in the
199
+ text makes the page `mention` that resource, and a resource in a diagram of the page (an ```` ```asd ```` block or an embedded
200
+ `.asd` file) makes the page `depict` it. The resource then lists the page under Relations, and the page lists the resource, so you
201
+ can see which pages talk about a component, and which pages to review when it changes (impact analysis includes them). Only exact
202
+ names count and links in code are ignored. The same applies to the description and the diagram of every other resource. See
203
+ [Derived references](modeling.md#derived-references).
204
+
149
205
  ## Macros
150
206
 
151
207
  Inline macros are written `{name:arguments}` and named like the macros of Confluence. They work inside a sentence, a
@@ -202,6 +258,8 @@ If several pages qualify, a page named `home` wins over one that is only titled
202
258
  - Tables, code blocks and other GitHub-flavoured markdown.
203
259
  - Diagrams: fenced ```` ```asd ```` blocks (see [Diagrams](/doc/diagram)) replace draw.io drawings.
204
260
  - Links: `[[Page title]]`, `[[page-name]]`, `[[Name|label]]` and `[[Kind/Name]]` link to pages and resources.
261
+ A link without a label shows the title of a page and the name of a resource (`[[ApplicationComponent/KubeVirt]]` shows "KubeVirt"); hovering it shows the
262
+ kind and the first line of the description (the status of a page). The export to Confluence writes the same texts, without the hover.
205
263
 
206
264
  ## Editing
207
265
 
@@ -224,6 +282,7 @@ or `.../display/KEY/Title`). Without `PAGE` every page that has a `confluence:`
224
282
 
225
283
  ```bash
226
284
  archsight export --to confluence -r resources # all linked pages
285
+ archsight export --to confluence -r resources --tag public # only pages tagged `public` (repeat or list: any match)
227
286
  archsight export --to confluence handbook-home --dry-run # show what would happen
228
287
  archsight export --to confluence handbook-home --force # overwrite changes made in Confluence
229
288
  ```
@@ -257,10 +316,17 @@ confluence:
257
316
  With `drawio` off nothing draw.io-specific is written, so any Confluence shows the diagrams. Rendering a `.drawio` needs the
258
317
  draw.io desktop CLI (`drawio`, or `ARCHSIGHT_DRAWIO_CLI`) on the machine that exports; the preview of an SVG needs
259
318
  `rsvg-convert` or that CLI. A diagram that cannot be rendered fails the page instead of leaving a blank diagram. Attachments an
260
- earlier export added and the page no longer uses are removed; attachments added by others are left alone. `[[links]]` to pages that have a Confluence link
261
- become links to them, other links are plain text; embedded views and analyses (`![[View/..]]`) become a note, their content
262
- is live and exists in Archsight only. A page with a broken image or a diagram that does not render is not exported and
263
- reported as failed. The Confluence title is kept.
319
+ earlier export added and the page no longer uses are removed; attachments added by others are left alone. `[[links]]` and markdown links to pages (`[text](/pages/name)`) that have a Confluence link
320
+ become links to them, other links to Archsight (pages without a Confluence link, resources, searches) are plain text. A page with a broken image, a diagram that does not render or an invalid
321
+ ```` ```view ````/```` ```requirements ```` block is not exported and reported as failed. The Confluence title is kept. The exported page uses the Confluence layout: the page properties top left, the note that the page is generated by Archsight top right, and the content below in a section of its own.
322
+
323
+ **Views and requirements** are live in Archsight, so Confluence gets a regular table with the data of the moment of the export (every
324
+ export writes the current data; a page whose tables did not change is `unchanged`): `![[View/Name]]` on a line of its own, a
325
+ ```` ```view ```` block and a ```` ```requirements ```` block each become a table with the title and item count above it, the columns of
326
+ the view (Name, Kind unless `list:name`, the `view/fields`, sorted by `view/sort`; times are the stored values, not "3 days ago") or
327
+ the requirements table (status and priority as status lozenges: implemented green, partial yellow, planned blue; `must` red,
328
+ `should` yellow, `may` grey), and names of pages that have a Confluence link as links. At most 200 rows are exported, a note says how many
329
+ were left out. A `![[View/..]]` that is not alone on its line or names no view stays a note, and so does `![[Analysis/..]]` (it runs a script).
264
330
 
265
331
  **Links in diagrams**: a node with `resource "Some Page"` links to the Confluence page of that wiki page (the page's own
266
332
  `confluence:` link) instead of its Archsight address, which means nothing in Confluence. A reference to a page without a
@@ -276,8 +342,8 @@ changed it and when, and the command exits with 1. `--force` overwrites it anywa
276
342
  were replaced. A page whose generated content is unchanged is left alone (no new version).
277
343
 
278
344
  **Locking and revisions**: unless `--no-lock`, editing is restricted to the exporting user (if the server does not allow it,
279
- the export still succeeds and says "NOT locked"). Every exported version has the message "Generated by Archsight <version> from
280
- <file>, do not edit in Confluence", and the page starts with a note that it is generated and that the source file is the place
345
+ the export still succeeds and says "NOT locked"). Every exported version has the message "Generated by Archsight `<version>` from
346
+ `<file>`, do not edit in Confluence", and the page starts with a note that it is generated and that the source file is the place
281
347
  to edit.
282
348
 
283
349
  ## Pages and AI assistants (MCP)
data/docs/search.md CHANGED
@@ -121,7 +121,7 @@ Examples:
121
121
  -> ApplicationInterface # exposes an interface
122
122
  -> "Kubernetes:RestAPI" # exposes specific interface
123
123
  <- ApplicationComponent # referenced by a component
124
- ~> BusinessRequirement # transitively reaches requirement
124
+ ~> MotivationRequirement # transitively reaches requirement
125
125
  -> none & <- none # orphan (no relations)
126
126
  TechnologyArtifact: <- none # unreferenced artifacts
127
127
 
@@ -175,6 +175,13 @@ Examples:
175
175
  # Find artifacts with NO maintainedBy relations
176
176
  TechnologyArtifact: -{maintainedBy}> none
177
177
 
178
+ # Pages that mention a component, and the components they depict
179
+ ApplicationComponent: <{mentions}- Page
180
+ Page: -{depicts}> ApplicationComponent
181
+
182
+ # Leave the derived relations (links in text, nodes of diagrams) out of a traversal
183
+ ApplicationComponent: ~{!mentions,depicts}> TechnologyArtifact
184
+
178
185
  ## Sub-Query Targets
179
186
 
180
187
  Use `$(expression)` to dynamically find relation targets based on a query:
@@ -249,7 +256,7 @@ Large Go codebases:
249
256
 
250
257
  Resources with compliance chain:
251
258
 
252
- ~> BusinessRequirement
259
+ ~> MotivationRequirement
253
260
 
254
261
  Complex query with grouping:
255
262
 
@@ -263,3 +270,20 @@ Using `in` to simplify OR conditions:
263
270
 
264
271
  # Combined with other conditions:
265
272
  activity/status == "active" & repository/artifacts in ("container", "chart")
273
+
274
+ ## Search results
275
+
276
+ The result page lists the hits with a count per kind. Click a kind to narrow the list; the query stays the same.
277
+ Every hit also shows its **summary attributes**: up to three annotations per kind (normal or computed) that
278
+ the kind definition marks with `summary: true`, for example the activity status of a repository or the priority
279
+ of a requirement. Clicking a tag value searches for that value.
280
+
281
+ The same data is available from the API: `GET /api/v1/search?q=...` returns `by_kind` (hits per kind, for all
282
+ hits of the query) and, for each hit, `highlights`:
283
+
284
+ "highlights": [
285
+ { "key": "activity/status", "title": "Activity Status", "value": "active", "format": "tag_word", "type": null }
286
+ ]
287
+
288
+ Add `kind=TechnologyArtifact` to narrow the hits to one kind (`total` and paging follow, `by_kind` still counts
289
+ all hits).
data/docs/togaf.md CHANGED
@@ -124,6 +124,10 @@ The metamodel defines architectural entities and their relationships across all
124
124
 
125
125
  - **Principle**, **Constraint**, **Requirement**, **Gap**, **Work Package**, **Location**
126
126
 
127
+ **Governance:**
128
+
129
+ - **Control**: a decision-making step with accountability and authority, applied to a process or function. ArchiMate has no element for it; Archsight models it as `BusinessControl`, which a `BusinessProcess` is `guidedBy`
130
+
127
131
  ### Critical Relationships
128
132
 
129
133
  1. **Traceability**: Drivers → Goals → Objectives → Course of Action → Business Elements → Applications → Technology
@@ -5,7 +5,7 @@ require_relative "person"
5
5
 
6
6
  # Annotation represents a single annotation definition with its schema and behavior
7
7
  class Archsight::Annotations::Annotation
8
- attr_reader :key, :description, :filter, :format, :enum, :sidebar, :type, :list, :editor
8
+ attr_reader :key, :description, :filter, :format, :enum, :sidebar, :type, :summary, :editor
9
9
 
10
10
  def initialize(key, options = {})
11
11
  @key = key
@@ -15,7 +15,7 @@ class Archsight::Annotations::Annotation
15
15
  @enum = options[:enum]
16
16
  @validator = options[:validator]
17
17
  @sidebar = options.fetch(:sidebar, true)
18
- @list = options.fetch(:list, false)
18
+ @summary = options.fetch(:summary, false)
19
19
  @editor = options.fetch(:editor, true)
20
20
  @type = options[:type]
21
21
 
@@ -51,8 +51,9 @@ class Archsight::Annotations::Annotation
51
51
  @filter == :list
52
52
  end
53
53
 
54
- def list_display?
55
- @list == true
54
+ # Summary annotations are returned with every search hit (at most MAX_SUMMARY per kind)
55
+ def summary?
56
+ @summary == true
56
57
  end
57
58
 
58
59
  def has_validation?
@@ -28,7 +28,7 @@ class Archsight::Annotations::ComputedEvaluator
28
28
  @instance = instance
29
29
  @database = database
30
30
  @manager = manager
31
- @resolver = Archsight::Annotations::ComputedRelationResolver.new(instance, database)
31
+ @resolver = Archsight::Annotations::ComputedRelationResolver.new(instance, database, manager.traversal_cache)
32
32
  end
33
33
 
34
34
  # Access a regular annotation value from the current instance
@@ -170,8 +170,12 @@ end
170
170
  # ComputedManager orchestrates the computation of all computed annotations.
171
171
  # It handles lazy evaluation, caching, and cycle detection.
172
172
  class Archsight::Annotations::ComputedManager
173
+ # Shared by all resolvers of this run, see ComputedRelationResolver::TraversalCache
174
+ attr_reader :traversal_cache
175
+
173
176
  def initialize(database)
174
177
  @database = database
178
+ @traversal_cache = Archsight::Annotations::ComputedRelationResolver::TraversalCache.new(database)
175
179
  @computed_cache = {} # { [instance_object_id, key] => value }
176
180
  @computing = Set.new # For cycle detection
177
181
  end