@documentation-robotics/cli 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/README.md +36 -2
  2. package/dist/analysis/relationship-classifier.js +2 -9
  3. package/dist/analysis/relationship-classifier.js.map +2 -2
  4. package/dist/analyzers/call-graph-utils.js +2 -2
  5. package/dist/analyzers/call-graph-utils.js.map +2 -2
  6. package/dist/analyzers/cards/build.js +171 -0
  7. package/dist/analyzers/cards/build.js.map +7 -0
  8. package/dist/analyzers/cards/classify.js +42 -0
  9. package/dist/analyzers/cards/classify.js.map +7 -0
  10. package/dist/analyzers/cards/edge-index.js +44 -0
  11. package/dist/analyzers/cards/edge-index.js.map +7 -0
  12. package/dist/analyzers/cards/facts.js +46 -0
  13. package/dist/analyzers/cards/facts.js.map +7 -0
  14. package/dist/analyzers/cards/graph.js +42 -0
  15. package/dist/analyzers/cards/graph.js.map +7 -0
  16. package/dist/analyzers/cards/index.js +8 -0
  17. package/dist/analyzers/cards/index.js.map +7 -0
  18. package/dist/analyzers/cards/tier0.js +18 -0
  19. package/dist/analyzers/cards/tier0.js.map +7 -0
  20. package/dist/analyzers/cards/types.js +1 -0
  21. package/dist/analyzers/cards/types.js.map +7 -0
  22. package/dist/analyzers/cbm-analyzer.js +195 -171
  23. package/dist/analyzers/cbm-analyzer.js.map +2 -2
  24. package/dist/analyzers/cbm-responses.js +336 -0
  25. package/dist/analyzers/cbm-responses.js.map +7 -0
  26. package/dist/analyzers/edge-relationships.js +45 -0
  27. package/dist/analyzers/edge-relationships.js.map +7 -0
  28. package/dist/analyzers/mapping-loader.js +9 -0
  29. package/dist/analyzers/mapping-loader.js.map +2 -2
  30. package/dist/analyzers/tier0-rules.js +153 -0
  31. package/dist/analyzers/tier0-rules.js.map +7 -0
  32. package/dist/analyzers/types.js.map +1 -1
  33. package/dist/audit/relationships/ai/prompts.js +10 -10
  34. package/dist/audit/relationships/ai/prompts.js.map +2 -2
  35. package/dist/audit/relationships/analysis/layer-templates.js +52 -52
  36. package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
  37. package/dist/cli.js +12 -2
  38. package/dist/cli.js.map +2 -2
  39. package/dist/coding-agents/default-permissions.js +31 -1
  40. package/dist/coding-agents/default-permissions.js.map +2 -2
  41. package/dist/coding-agents/drbot-mcp.js +167 -0
  42. package/dist/coding-agents/drbot-mcp.js.map +7 -0
  43. package/dist/commands/add.js +3 -2
  44. package/dist/commands/add.js.map +2 -2
  45. package/dist/commands/analyzer.js +117 -14
  46. package/dist/commands/analyzer.js.map +2 -2
  47. package/dist/commands/changeset-verify.js +55 -0
  48. package/dist/commands/changeset-verify.js.map +7 -0
  49. package/dist/commands/changeset.js +43 -22
  50. package/dist/commands/changeset.js.map +2 -2
  51. package/dist/commands/delete.js +10 -4
  52. package/dist/commands/delete.js.map +2 -2
  53. package/dist/commands/farm.js +176 -60
  54. package/dist/commands/farm.js.map +2 -2
  55. package/dist/commands/mcp.js +19 -4
  56. package/dist/commands/mcp.js.map +2 -2
  57. package/dist/commands/relationship.js +207 -26
  58. package/dist/commands/relationship.js.map +2 -2
  59. package/dist/commands/update.js +42 -23
  60. package/dist/commands/update.js.map +2 -2
  61. package/dist/commands/upgrade.js +99 -11
  62. package/dist/commands/upgrade.js.map +3 -3
  63. package/dist/commands/version.js +1 -1
  64. package/dist/commands/visualize.js +4 -3
  65. package/dist/commands/visualize.js.map +2 -2
  66. package/dist/core/catalog-migration.js +33 -0
  67. package/dist/core/catalog-migration.js.map +7 -0
  68. package/dist/core/changeset-analysis.js +421 -0
  69. package/dist/core/changeset-analysis.js.map +7 -0
  70. package/dist/core/changeset-base-index.js +153 -0
  71. package/dist/core/changeset-base-index.js.map +7 -0
  72. package/dist/core/changeset-brief-delta.js +102 -0
  73. package/dist/core/changeset-brief-delta.js.map +7 -0
  74. package/dist/core/changeset-graph.js +281 -0
  75. package/dist/core/changeset-graph.js.map +7 -0
  76. package/dist/core/changeset-only-guard.js +32 -0
  77. package/dist/core/changeset-only-guard.js.map +7 -0
  78. package/dist/core/changeset-summary.js +68 -0
  79. package/dist/core/changeset-summary.js.map +7 -0
  80. package/dist/core/changeset-validator.js +66 -20
  81. package/dist/core/changeset-validator.js.map +2 -2
  82. package/dist/core/changeset-verify.js +518 -0
  83. package/dist/core/changeset-verify.js.map +7 -0
  84. package/dist/core/changeset.js +56 -9
  85. package/dist/core/changeset.js.map +2 -2
  86. package/dist/core/element-type-migration.js +145 -0
  87. package/dist/core/element-type-migration.js.map +7 -0
  88. package/dist/core/farm-manifest.js +12 -6
  89. package/dist/core/farm-manifest.js.map +2 -2
  90. package/dist/core/farm-sync-engine.js +1 -1
  91. package/dist/core/farm-sync-engine.js.map +2 -2
  92. package/dist/core/farm-sync-state.js +10 -2
  93. package/dist/core/farm-sync-state.js.map +2 -2
  94. package/dist/core/migration-registry.js +75 -46
  95. package/dist/core/migration-registry.js.map +2 -2
  96. package/dist/core/model-upgrade.js +102 -0
  97. package/dist/core/model-upgrade.js.map +7 -0
  98. package/dist/core/model.js +82 -30
  99. package/dist/core/model.js.map +2 -2
  100. package/dist/core/mutation-handler.js +71 -6
  101. package/dist/core/mutation-handler.js.map +2 -2
  102. package/dist/core/relationship-migration-table.js +6639 -0
  103. package/dist/core/relationship-migration-table.js.map +7 -0
  104. package/dist/core/relationship-migration.js +272 -0
  105. package/dist/core/relationship-migration.js.map +7 -0
  106. package/dist/core/relationship-prune.js +49 -0
  107. package/dist/core/relationship-prune.js.map +7 -0
  108. package/dist/core/relationship-staging.js +68 -0
  109. package/dist/core/relationship-staging.js.map +7 -0
  110. package/dist/core/relationships.js +26 -4
  111. package/dist/core/relationships.js.map +2 -2
  112. package/dist/core/report-data-model.js +7 -13
  113. package/dist/core/report-data-model.js.map +2 -2
  114. package/dist/core/staged-changeset-storage.js +64 -17
  115. package/dist/core/staged-changeset-storage.js.map +2 -2
  116. package/dist/core/staged-source-reference.js +28 -0
  117. package/dist/core/staged-source-reference.js.map +7 -0
  118. package/dist/core/staging-area.js +83 -18
  119. package/dist/core/staging-area.js.map +2 -2
  120. package/dist/core/virtual-projection.js +13 -5
  121. package/dist/core/virtual-projection.js.map +2 -2
  122. package/dist/export/archimate-exporter.js +1 -0
  123. package/dist/export/archimate-exporter.js.map +2 -2
  124. package/dist/generated/compiled-validators.js +2 -2
  125. package/dist/generated/compiled-validators.js.map +2 -2
  126. package/dist/generated/layer-registry.js +16 -16
  127. package/dist/generated/layer-registry.js.map +2 -2
  128. package/dist/generated/node-types.js +186 -168
  129. package/dist/generated/node-types.js.map +2 -2
  130. package/dist/generated/relationship-index.js +2236 -7790
  131. package/dist/generated/relationship-index.js.map +2 -2
  132. package/dist/integrations/claude_code/agents/dr-architect.md +16 -3
  133. package/dist/integrations/claude_code/agents/dr-extractor.md +1 -1
  134. package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
  135. package/dist/integrations/claude_code/commands/dr-map.md +13 -0
  136. package/dist/integrations/claude_code/commands/dr-plan.md +40 -0
  137. package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
  138. package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
  139. package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
  140. package/dist/integrations/claude_code/docs/MCP_SERVER.md +26 -2
  141. package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
  142. package/dist/integrations/claude_code/docs/README.md +48 -1
  143. package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
  144. package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
  145. package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
  146. package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
  147. package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
  148. package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
  149. package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
  150. package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
  151. package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
  152. package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
  153. package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
  154. package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
  155. package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +92 -15
  156. package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +119 -0
  157. package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +3 -0
  158. package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +1 -1
  159. package/dist/integrations/github_copilot/agents/dr-architect.md +1 -1
  160. package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
  161. package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
  162. package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
  163. package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
  164. package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
  165. package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
  166. package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
  167. package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
  168. package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
  169. package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
  170. package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
  171. package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
  172. package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +222 -102
  173. package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +119 -0
  174. package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
  175. package/dist/integrations/hash-utils.js.map +2 -2
  176. package/dist/mcp/api-key-manager.js +14 -1
  177. package/dist/mcp/api-key-manager.js.map +2 -2
  178. package/dist/mcp/changeset-only.js +34 -0
  179. package/dist/mcp/changeset-only.js.map +7 -0
  180. package/dist/mcp/tool-registry.js +19 -3
  181. package/dist/mcp/tool-registry.js.map +2 -2
  182. package/dist/mcp/tools/changeset-analysis-tools.js +78 -0
  183. package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
  184. package/dist/mcp/tools/changeset-editing.js +184 -0
  185. package/dist/mcp/tools/changeset-editing.js.map +7 -0
  186. package/dist/mcp/tools/changeset-lifecycle.js +83 -0
  187. package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
  188. package/dist/mcp/tools/changeset-shared.js +31 -0
  189. package/dist/mcp/tools/changeset-shared.js.map +7 -0
  190. package/dist/mcp/tools/changeset-show.js +17 -1
  191. package/dist/mcp/tools/changeset-show.js.map +2 -2
  192. package/dist/mcp/tools/changeset-verify.js +43 -0
  193. package/dist/mcp/tools/changeset-verify.js.map +7 -0
  194. package/dist/mcp/tools/index.js +19 -1
  195. package/dist/mcp/tools/index.js.map +2 -2
  196. package/dist/mcp/tools/model-add.js +6 -5
  197. package/dist/mcp/tools/model-add.js.map +2 -2
  198. package/dist/mcp/tools/model-delete.js +2 -2
  199. package/dist/mcp/tools/model-delete.js.map +2 -2
  200. package/dist/mcp/tools/model-search.js +14 -0
  201. package/dist/mcp/tools/model-search.js.map +2 -2
  202. package/dist/mcp/tools/model-show.js +29 -2
  203. package/dist/mcp/tools/model-show.js.map +2 -2
  204. package/dist/mcp/tools/model-trace.js +93 -30
  205. package/dist/mcp/tools/model-trace.js.map +2 -2
  206. package/dist/mcp/tools/model-update.js +35 -19
  207. package/dist/mcp/tools/model-update.js.map +2 -2
  208. package/dist/mcp/tools/relationship-tools.js +98 -0
  209. package/dist/mcp/tools/relationship-tools.js.map +7 -0
  210. package/dist/mcp/tools/shared.js +25 -2
  211. package/dist/mcp/tools/shared.js.map +2 -2
  212. package/dist/mcp/tools/spec-type.js +90 -0
  213. package/dist/mcp/tools/spec-type.js.map +7 -0
  214. package/dist/schemas/bundled/analyzers/cbm.json +1186 -68
  215. package/dist/schemas/bundled/analyzers/manifest.json +2 -2
  216. package/dist/schemas/bundled/api.json +1029 -1658
  217. package/dist/schemas/bundled/apm.json +499 -734
  218. package/dist/schemas/bundled/application.json +735 -371
  219. package/dist/schemas/bundled/base.json +3 -220
  220. package/dist/schemas/bundled/business.json +452 -366
  221. package/dist/schemas/bundled/data-model.json +395 -411
  222. package/dist/schemas/bundled/data-store.json +334 -558
  223. package/dist/schemas/bundled/manifest.json +18 -18
  224. package/dist/schemas/bundled/motivation.json +349 -368
  225. package/dist/schemas/bundled/navigation.json +415 -731
  226. package/dist/schemas/bundled/product.json +325 -159
  227. package/dist/schemas/bundled/security.json +864 -1232
  228. package/dist/schemas/bundled/technology.json +574 -703
  229. package/dist/schemas/bundled/testing.json +718 -1643
  230. package/dist/schemas/bundled/ux.json +739 -1352
  231. package/dist/server/schemas.js +8 -0
  232. package/dist/server/schemas.js.map +2 -2
  233. package/dist/server/server.js +218 -34
  234. package/dist/server/server.js.map +2 -2
  235. package/dist/server-entry.js +2 -1
  236. package/dist/server-entry.js.map +2 -2
  237. package/dist/telemetry/index.js +1 -1
  238. package/dist/utils/ansi-suppressor.js +6 -8
  239. package/dist/utils/ansi-suppressor.js.map +2 -2
  240. package/dist/utils/attribute-patch.js +41 -0
  241. package/dist/utils/attribute-patch.js.map +7 -0
  242. package/dist/utils/error-hints.js +29 -0
  243. package/dist/utils/error-hints.js.map +7 -0
  244. package/dist/utils/errors.js +9 -3
  245. package/dist/utils/errors.js.map +2 -2
  246. package/dist/utils/project-paths.js +26 -1
  247. package/dist/utils/project-paths.js.map +2 -2
  248. package/dist/utils/source-reference.js +14 -12
  249. package/dist/utils/source-reference.js.map +2 -2
  250. package/dist/utils/spec-version.js +2 -2
  251. package/dist/utils/spec-version.js.map +1 -1
  252. package/dist/validators/composed-reference-validator.js +5 -27
  253. package/dist/validators/composed-reference-validator.js.map +2 -2
  254. package/dist/validators/reference-validator.js +0 -7
  255. package/dist/validators/reference-validator.js.map +2 -2
  256. package/dist/validators/relationship-schema-validator.js +3 -3
  257. package/dist/validators/relationship-schema-validator.js.map +2 -2
  258. package/dist/validators/schema-validator.js +27 -9
  259. package/dist/validators/schema-validator.js.map +2 -2
  260. package/dist/validators/types.js.map +1 -1
  261. package/dist/viewer/README.md +6 -6
  262. package/dist/viewer/assets/main-CxzcuU_o.js +84 -0
  263. package/dist/viewer/assets/main-j-7ULYpm.css +1 -0
  264. package/dist/viewer/index.html +2 -2
  265. package/dist/viewer/manifest.json +10 -10
  266. package/dist/viewer/version.json +1 -1
  267. package/package.json +2 -1
  268. package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
  269. package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
@@ -58,10 +58,10 @@ This layer uses **JSON Schema Draft 7** (industry standard) with custom extensio
58
58
  | **SchemaProperty** | Individual property definition |
59
59
  | **Reference** | $ref to other schemas |
60
60
 
61
- > **Note:** Data governance (`x-data-governance`) and database mapping (`x-database`) are
62
- > cross-layer extension **attributes**, not node types. Set them directly on the schema element
63
- > they describe — on an `objectschema` for table-level mapping, or on a `schemaproperty` for
64
- > field-level governance (e.g., marking an individual `email` property as PII).
61
+ > **Note:** Data governance and database mapping are not node types or `x-...` attributes. Record
62
+ > them as relationships from the schema element they describe: `schemaproperty satisfies
63
+ security.dataclassification` for field-level governance (e.g., marking an `email` property as PII),
64
+ > and `objectschema maps-to data-store.collection` for the physical table or collection.
65
65
 
66
66
  ---
67
67
 
@@ -83,14 +83,16 @@ Use this decision tree **before assigning a type** to any code pattern.
83
83
 
84
84
  ## Common Misclassifications
85
85
 
86
- | Misclassification | Correct Classification | Why |
87
- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
88
- | Modeling `x-data-governance` or `x-database` as their own elements | Set as extension attributes on the relevant schema element (`objectschema` or `schemaproperty`) | These are cross-layer extension attributes, not spec node types |
89
- | Using `objectschema` for a reusable definition in a `definitions` block | `schemadefinition` | `definitions` entries are named, reusable definitions; `objectschema` is for structural instances |
90
- | Using `schemadefinition` for a top-level schema document | `jsonschema` | A root document with `$schema` and `$id` is `jsonschema`, not a definition |
91
- | Using `schemaproperty` for a standalone string/numeric/array type | `stringschema` / `numericschema` / `arrayschema` | Use the specific schema type when the constraint set is rich enough to stand alone; use `schemaproperty` only for inline field declarations within an `objectschema` |
92
- | Using `objectschema` for a schema that uses `allOf` to extend another | `schemacomposition` | When the primary purpose is combining or extending schemas, classify as `schemacomposition` — even if the schema also declares `properties` |
93
- | Using `schemaproperty` for a bare `$ref` with no other constraints | `reference` | A standalone `$ref` with nothing else is a `reference`; use `schemaproperty` only when the field also carries its own constraints (`title`, `description`, `readOnly`, `default`, etc.) |
86
+ | Misclassification | Correct Classification | Why |
87
+ | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
88
+ | Modeling data governance or database mapping as their own elements (or as `x-data-governance` / `x-database` attributes) | Relationships from the schema element: `satisfies security.dataclassification`, `maps-to data-store.collection` | These are cross-layer links, not data-model node types |
89
+ | Using `objectschema` for a reusable definition in a `definitions` block | `schemadefinition` | `definitions` entries are named, reusable definitions; `objectschema` is for structural instances |
90
+ | Using `schemadefinition` for a top-level schema document | `jsonschema` | A root document with `$schema` and `$id` is `jsonschema`, not a definition |
91
+ | Using `schemaproperty` for a standalone string/numeric/array type | `stringschema` / `numericschema` / `arrayschema` | Use the specific schema type when the constraint set is rich enough to stand alone; use `schemaproperty` only for inline field declarations within an `objectschema` |
92
+ | Using `objectschema` for a schema that uses `allOf` to extend another | `schemacomposition` | When the primary purpose is combining or extending schemas, classify as `schemacomposition` — even if the schema also declares `properties` |
93
+ | Using `schemaproperty` for a bare `$ref` with no other constraints | `reference` | A standalone `$ref` with nothing else is a `reference`; use `schemaproperty` only when the field also carries its own constraints (`title`, `description`, `readOnly`, `default`, etc.) |
94
+ | Filing an in-code structure that is neither persisted nor published as a schema under `objectschema` | `application.dataobject` | Entities, ORM models and types whose shape is published as a schema are object schemas; a structure that only carries data between parts of the program is an application data object, which the object schema may realize |
95
+ | A schema `serves` the code that uses it | `application.applicationfunction` (or component, event) `accesses` the schema | Schemas are passive structure: behaviour accesses data; schemas never serve, trigger or perform |
94
96
 
95
97
  ---
96
98
 
@@ -106,20 +108,101 @@ Activate when the user:
106
108
 
107
109
  ---
108
110
 
109
- ## Cross-Layer Relationships
111
+ ## Intra-Layer Relationships
112
+
113
+ A subschema written in place is part of what declares it (`composes`); a type declared elsewhere and
114
+ reached by `$ref` or by name is `references`. Subtyping is `specializes`.
115
+
116
+ | Source Type | Predicate | Target Type | Example |
117
+ | ----------------- | ----------- | ----------------- | ------------------------------------------------------------------ |
118
+ | JSONSchema | composes | ObjectSchema | "Order API Schemas" document composes its root "Order" schema |
119
+ | JSONSchema | composes | SchemaDefinition | "Order API Schemas" composes the "Address" definition it declares |
120
+ | JSONSchema | composes | SchemaComposition | "Order API Schemas" composes its root "PaymentMethod" (`oneOf`) |
121
+ | ObjectSchema | composes | SchemaProperty | "Order" composes the "status" property |
122
+ | ObjectSchema | specializes | ObjectSchema | "AdminUser" specializes "User" |
123
+ | SchemaProperty | composes | StringSchema | "email" property composes its inline `format: email` constraint |
124
+ | SchemaProperty | composes | NumericSchema | "total" property composes its inline `minimum: 0` constraint |
125
+ | SchemaProperty | composes | ArraySchema | "lineItems" property composes its inline array constraints |
126
+ | SchemaProperty | references | ObjectSchema | "shippingAddress" property references "Address" |
127
+ | SchemaProperty | references | SchemaDefinition | "currency" property references the "CurrencyCode" definition |
128
+ | ArraySchema | composes | ObjectSchema | "LineItemList" composes its inline `items` object schema |
129
+ | ArraySchema | composes | StringSchema | "TagList" composes its inline `items` string schema |
130
+ | ArraySchema | composes | Reference | "OrderList" composes its `items: $ref: #/definitions/Order` |
131
+ | ArraySchema | references | SchemaDefinition | "OrderList" references the "Order" definition its items take |
132
+ | Reference | references | SchemaDefinition | `$ref: #/definitions/Address` references the "Address" definition |
133
+ | Reference | references | ObjectSchema | `$ref` to the "Customer" object schema |
134
+ | Reference | references | JSONSchema | `$ref: common.schema.json` references that document |
135
+ | SchemaComposition | composes | ObjectSchema | "PaymentMethod" (`oneOf`) composes its inline "CardPayment" branch |
136
+ | SchemaComposition | composes | Reference | "CustomerWithAudit" (`allOf`) composes its `$ref` branch |
137
+ | SchemaComposition | references | SchemaDefinition | "CustomerWithAudit" (`allOf`) references "AuditFields" |
138
+ | SchemaDefinition | composes | SchemaDefinition | "Customer" composes "ContactInfo" declared inside it |
139
+ | SchemaDefinition | specializes | SchemaDefinition | "PremiumCustomer" specializes "Customer" |
140
+ | SchemaDefinition | references | SchemaDefinition | "Invoice" references "Customer" |
141
+
142
+ ----------------- | ----------- | ----------------- | ----------------------------------------------------------------- |
143
+ | JSONSchema | aggregates | ObjectSchema | "Order API Schemas" document aggregates "Order" |
144
+ | JSONSchema | aggregates | SchemaDefinition | "Order API Schemas" aggregates the "Address" definition |
145
+ | JSONSchema | aggregates | SchemaComposition | "Order API Schemas" aggregates "PaymentMethod" (`oneOf`) |
146
+ | ObjectSchema | aggregates | SchemaProperty | "Order" aggregates the "status" property |
147
+ | ObjectSchema | extends | ObjectSchema | "AdminUser" extends "User" |
148
+ | SchemaProperty | references | StringSchema | "email" property references "EmailString" (`format: email`) |
149
+ | SchemaProperty | references | NumericSchema | "total" property references "MoneyAmount" (`minimum: 0`) |
150
+ | SchemaProperty | references | ArraySchema | "lineItems" property references "LineItemList" |
151
+ | SchemaProperty | references | ObjectSchema | "shippingAddress" property references "Address" |
152
+ | SchemaProperty | references | SchemaDefinition | "currency" property references the "CurrencyCode" definition |
153
+ | ArraySchema | aggregates | ObjectSchema | "LineItemList" aggregates "LineItem" (its `items` schema) |
154
+ | ArraySchema | aggregates | StringSchema | "TagList" aggregates "Tag" |
155
+ | ArraySchema | aggregates | Reference | "OrderList" aggregates `$ref: #/definitions/Order` |
156
+ | Reference | references | SchemaDefinition | `$ref: #/definitions/Address` references the "Address" definition |
157
+ | SchemaComposition | composes | ObjectSchema | "PaymentMethod" (`oneOf`) composes "CardPayment" |
158
+ | SchemaComposition | composes | SchemaDefinition | "CustomerWithAudit" (`allOf`) composes "AuditFields" |
159
+ | SchemaDefinition | composes | SchemaDefinition | "Customer" composes "ContactInfo" |
160
+ | SchemaDefinition | specializes | SchemaDefinition | "PremiumCustomer" specializes "Customer" |
161
+ | SchemaDefinition | references | SchemaDefinition | "Invoice" references "Customer" |
110
162
 
111
- **Outgoing (Data Model → Other Layers):**
112
-
113
- - `x-business-object-ref` → Business Layer (what business concept does this represent?)
114
- - `x-database` → Data Store Layer (how is this stored physically?)
115
- - `x-data-governance` → Security Layer (classification, PII, retention)
116
- - `x-apm-data-quality-metrics` → APM Layer (data quality monitoring)
117
-
118
- **Incoming (Other Layers → Data Model):**
163
+ ---
119
164
 
120
- - API Layer → Data Model (request/response schemas via $ref)
121
- - UX Layer → Data Model (form validation rules)
122
- - Testing Layer → Data Model (input constraints for test partitioning)
165
+ ## Cross-Layer References
166
+
167
+ Cross-layer links are recorded as relationships (`dr relationship add`), not as `x-...` extension attributes.
168
+
169
+ ### Outgoing References (Data Model → Other Layers)
170
+
171
+ | Source Type | Predicate | Target Type | Example |
172
+ | ---------------- | ---------- | ----------------------------- | ---------------------------------------------------------------- |
173
+ | ObjectSchema | realizes | `business.businessobject` | "Order" schema realizes the "Customer Order" business object |
174
+ | SchemaDefinition | realizes | `application.dataobject` | "Customer" definition realizes the "Customer Record" data object |
175
+ | ObjectSchema | maps-to | `data-store.collection` | "User" schema maps to the `users` table |
176
+ | SchemaDefinition | maps-to | `data-store.collection` | "AuditEntry" definition maps to the `audit_log` collection |
177
+ | ObjectSchema | maps-to | `api.requestbody` | "CreateOrderRequest" maps to the `POST /orders` request body |
178
+ | ObjectSchema | maps-to | `api.response` | "Order" maps to the `GET /orders/{id}` 200 response |
179
+ | SchemaDefinition | maps-to | `api.schema` | "Address" definition maps to the OpenAPI `Address` component |
180
+ | JSONSchema | maps-to | `api.schema` | "Order API Schemas" document maps to the API's schema set |
181
+ | SchemaProperty | maps-to | `api.parameter` | "orderId" property maps to the `{orderId}` path parameter |
182
+ | SchemaProperty | references | `security.dataclassification` | "email" property references the "PII" classification |
183
+ | SchemaProperty | satisfies | `security.fieldaccesscontrol` | "ssn" property satisfies the "SSN Masking" field control |
184
+ | SchemaProperty | satisfies | `security.validationrule` | "password" property satisfies the "Password Strength" rule |
185
+ | SchemaDefinition | requires | `security.retentionpolicy` | "AuditEntry" requires the "7-Year Audit Retention" policy |
186
+ | ObjectSchema | satisfies | `motivation.requirement` | "Order" satisfies "Orders must record tax breakdown" |
187
+
188
+ ### Incoming References (Other Layers → Data Model)
189
+
190
+ | Source Type | Predicate | Target Type | Example |
191
+ | ---------------------------------- | ---------- | ---------------- | ---------------------------------------------------------------- |
192
+ | `application.applicationfunction` | accesses | ObjectSchema | "saveOrder" function accesses the "Order" entity |
193
+ | `application.applicationcomponent` | accesses | ObjectSchema | "OrderRepository" component accesses "Order" |
194
+ | `application.applicationevent` | accesses | SchemaDefinition | "OrderPlaced" event accesses its "OrderPlacedPayload" definition |
195
+ | `ux.dataconfig` | maps-to | ObjectSchema | "Order Form Data" binding maps to the "Order" schema |
196
+ | `ux.dataconfig` | maps-to | ObjectSchema | "Customer Data" maps to "Customer" |
197
+ | `ux.tablecolumn` | maps-to | SchemaProperty | "Status" column maps to the "status" property |
198
+ | `navigation.route` | references | SchemaDefinition | `/orders/:id` route references "Order" |
199
+ | `navigation.contextvariable` | maps-to | SchemaProperty | "selectedOrderId" context variable maps to "orderId" |
200
+ | `testing.targetinputfield` | references | SchemaProperty | "Quantity" input field references "quantity" |
201
+ | `testing.testcasesketch` | tests | SchemaDefinition | "Reject invalid currency" test sketch tests "CurrencyCode" |
202
+ | `apm.metricinstrument` | monitors | SchemaDefinition | "schema_validation_failures" counter monitors "Customer" |
203
+
204
+ > API operations do not point at data-model schemas; the direction is the other way — the schema
205
+ > `maps-to` the API request body, response, or parameter it shapes.
123
206
 
124
207
  ---
125
208
 
@@ -159,9 +242,6 @@ properties:
159
242
  type: string
160
243
  format: email
161
244
  description: "User email address"
162
- x-data-governance:
163
- classification: confidential
164
- pii: true
165
245
  username:
166
246
  type: string
167
247
  minLength: 3
@@ -175,10 +255,14 @@ properties:
175
255
  items:
176
256
  type: string
177
257
  description: "User role assignments"
178
- x-business-object-ref: business.actor.user
179
- x-database:
180
- table: users
181
- schema: public
258
+ ```
259
+
260
+ Link the schema to the business concept, its physical storage, and its data classification with relationships:
261
+
262
+ ```bash
263
+ dr relationship add data-model.objectschema.user business.businessobject.user --predicate realizes
264
+ dr relationship add data-model.objectschema.user data-store.collection.users --predicate maps-to
265
+ dr relationship add data-model.schemaproperty.user-email security.dataclassification.pii --predicate references
182
266
  ```
183
267
 
184
268
  ---
@@ -205,6 +289,6 @@ If any type has ZERO elements, explicitly decide: "This type doesn't apply to th
205
289
 
206
290
  - Always specify `type` on schema elements — validation fails without it
207
291
  - Break complex schemas into reusable `schemadefinition` entries and reference them via `$ref`
208
- - Mark PII and sensitive fields with `x-data-governance` on the relevant `schemaproperty` or `objectschema`
209
- - Add `x-business-object-ref` to link to the Business Layer and `x-database` to link to the Data Store Layer
292
+ - Mark PII and sensitive fields with a `satisfies` relationship from the `schemaproperty` to a `security.dataclassification`
293
+ - Link schemas to the Business Layer with `realizes business.businessobject` and to the Data Store Layer with `maps-to data-store.collection`
210
294
  - Use `format` for semantic string types (`email`, `uuid`, `date-time`, `uri`) rather than custom `pattern` where a standard format exists
@@ -137,32 +137,81 @@ Activate when the user:
137
137
 
138
138
  ---
139
139
 
140
- ## Cross-Layer Relationships
140
+ ## Intra-Layer Relationships
141
+
142
+ Containment is one level at a time (database → namespace → collection → fields, indexes, validation
143
+ rules, event handlers). Stored data is passive: collections, views, fields and databases are accessed,
144
+ referenced and mapped, and never serve or trigger. Behaviour in the store is stored logic, event
145
+ handlers and access patterns.
146
+
147
+ | Source Type | Predicate | Target Type | Example |
148
+ | --------------- | ------------ | -------------- | ---------------------------------------------------------------------- |
149
+ | Database | composes | Namespace | "orders-db" composes the `public` schema |
150
+ | Database | composes | Collection | "sessions-redis" composes the `session:*` key collection |
151
+ | Database | replicates | Database | "orders-db-primary" replicates to "orders-db-replica" |
152
+ | Database | federates | Database | "analytics-trino" federates "orders-db" |
153
+ | Namespace | composes | Collection | `public` schema composes the `orders` table |
154
+ | Namespace | composes | View | `reporting` schema composes `monthly_revenue_mv` |
155
+ | Namespace | composes | StoredLogic | `public` schema composes `calculate_discount()` |
156
+ | Collection | composes | Field | `orders` composes `orders.customer_id` |
157
+ | Collection | composes | Index | `orders` composes `idx_orders_customer_id` |
158
+ | Collection | composes | ValidationRule | `orders` composes the `chk_orders_total_positive` check constraint |
159
+ | Collection | composes | EventHandler | `orders` composes the `orders_audit_trigger` |
160
+ | Collection | references | Collection | `orders` references `customers` (foreign key) |
161
+ | Field | composes | Field | `address` sub-document composes `address.city` |
162
+ | Index | aggregates | Field | `idx_orders_customer_date` aggregates `customer_id` and `created_at` |
163
+ | AccessPattern | accesses | Collection | "list-orders-by-customer" accesses `orders` |
164
+ | AccessPattern | uses | Index | "list-orders-by-customer" uses `idx_orders_customer_date` |
165
+ | AccessPattern | references | Field | "list-orders-by-customer" references `orders.customer_id` |
166
+ | View | derives-from | Collection | `active_users_view` derives from `users` |
167
+ | View | derives-from | View | `quarterly_revenue_mv` derives from `monthly_revenue_mv` |
168
+ | StoredLogic | accesses | Collection | `get_user_stats()` accesses `orders` |
169
+ | StoredLogic | migrates | Collection | `migrate_2024_10_split_address()` migrates `customers` |
170
+ | EventHandler | references | Field | `orders_status_trigger` references `orders.status` (AFTER UPDATE OF) |
171
+ | EventHandler | triggers | StoredLogic | `orders_audit_trigger` triggers `write_audit_row()` |
172
+ | ValidationRule | references | Field | `uq_users_email` references `users.email` |
173
+ | ValidationRule | cascades-to | Collection | `fk_order_items_order` (`ON DELETE CASCADE`) cascades to `order_items` |
174
+ | RetentionPolicy | governs | Collection | "Audit Log Retention" governs `audit_log` |
175
+ | RetentionPolicy | archives-to | Collection | "Audit Log Retention" archives to `audit_log_archive` |
141
176
 
142
- Cross-layer links are created via `dr relate`, not inline YAML attributes. Key relationships from the spec:
143
-
144
- **Outgoing (Data Store → Other Layers):**
145
-
146
- | Relationship | Example |
147
- | ---------------------------------------------------- | --------------------------------------------- |
148
- | `collection.realizes.api.schema` | Users collection → API response schema |
149
- | `collection.maps-to.api.requestbody` | Orders collection → POST /orders body |
150
- | `collection.serves.api.operation` | Products collection → GET /products operation |
151
- | `collection.implements.security.secureresource` | PII collection → SecureResource policy |
152
- | `collection.satisfies.security.dataclassification` | Payments collection → PCI data class |
153
- | `field.satisfies.security.dataclassification` | email field → PII data classification |
154
- | `field.requires.security.fieldaccesscontrol` | SSN field → FieldAccessControl rule |
155
- | `field.maps-to.api.parameter` | user_id field → API path parameter |
156
- | `database.satisfies.security.securitypolicy` | DB → encryption-at-rest policy |
157
- | `database.depends-on.technology.systemsoftware` | PostgreSQL DB → pg systemsoftware |
158
- | `retentionpolicy.satisfies.security.retentionpolicy` | Retention rule → security retention policy |
159
-
160
- **Incoming (Other Layers → Data Store):**
177
+ ---
161
178
 
162
- | Relationship | Example |
163
- | ------------------------------------------------------ | -------------------------------- |
164
- | `application.applicationcomponent.serves → collection` | UserService → users collection |
165
- | `technology.systemsoftware.depends-on → database` | PostgreSQL technology → database |
179
+ ## Cross-Layer References
180
+
181
+ Cross-layer links are created with `dr relationship add`, not inline YAML attributes.
182
+
183
+ ### Outgoing References (Data Store → Other Layers)
184
+
185
+ | Source Type | Predicate | Target Type | Example |
186
+ | --------------- | ---------- | --------------------------------- | ----------------------------------------------------------------- |
187
+ | Collection | realizes | `business.businessobject` | `orders` table realizes the "Customer Order" business object |
188
+ | Collection | realizes | `security.secureresource` | `patients` collection realizes the "Patient Records" resource |
189
+ | Collection | references | `security.dataclassification` | `payments` collection references the "PCI" classification |
190
+ | Field | references | `security.dataclassification` | `users.email` references the "PII" classification |
191
+ | Field | requires | `security.fieldaccesscontrol` | `customers.ssn` requires the "SSN Masking" field control |
192
+ | Field | maps-to | `api.parameter` | `orders.id` maps to the `{orderId}` path parameter |
193
+ | Database | depends-on | `technology.systemsoftware` | "orders-db" depends on "PostgreSQL 16" |
194
+ | Database | depends-on | `technology.node` | "orders-db" depends on the "db-primary-01" node |
195
+ | Database | satisfies | `security.securitypolicy` | "orders-db" satisfies the "Encryption at Rest" policy |
196
+ | StoredLogic | realizes | `application.applicationfunction` | `calculate_discount()` realizes "Apply Promotions" |
197
+ | EventHandler | triggers | `application.applicationevent` | "orders CDC stream" triggers "Order Placed" |
198
+ | AccessPattern | serves | `application.applicationfunction` | "get-user-by-email" serves "Authenticate User" |
199
+ | View | maps-to | `api.response` | `order_summary_view` maps to the `GET /orders/summary` response |
200
+ | RetentionPolicy | satisfies | `security.retentionpolicy` | "Audit Log Retention" satisfies the "SOC2 Audit Retention" policy |
201
+
202
+ ### Incoming References (Other Layers → Data Store)
203
+
204
+ | Source Type | Predicate | Target Type | Example |
205
+ | ---------------------------------- | --------- | -------------- | ---------------------------------------------------------------- |
206
+ | `application.applicationcomponent` | accesses | Collection | "OrderRepository" accesses `orders` |
207
+ | `application.applicationfunction` | accesses | Collection | "findOrdersByCustomer" accesses `orders` |
208
+ | `application.applicationservice` | accesses | View | "Reporting Service" accesses `monthly_revenue_mv` |
209
+ | `data-model.objectschema` | maps-to | Collection | "User" schema maps to the `users` table |
210
+ | `data-model.schemadefinition` | maps-to | Collection | "AuditEntry" definition maps to `audit_log` |
211
+ | `testing.testcoveragetarget` | covers | StoredLogic | "Discount rules" coverage target covers `calculate_discount()` |
212
+ | `testing.testcasesketch` | tests | ValidationRule | "Reject negative total" sketch tests `chk_orders_total_positive` |
213
+ | `apm.metricinstrument` | monitors | Database | "db.client.connections.usage" monitors "orders-db" |
214
+ | `apm.span` | monitors | Collection | "SELECT orders" span monitors `orders` |
166
215
 
167
216
  ---
168
217
 
@@ -289,7 +338,7 @@ properties:
289
338
  - ❌ Using SQL-only concepts (Table, Column, Constraint) — use paradigm-neutral `collection`, `field`, `validationrule`
290
339
  - ❌ Skipping `AccessPattern` for NoSQL stores (DynamoDB, Cassandra) — define access patterns first
291
340
  - ❌ Nesting fields inline inside a collection element — `field` entities are always separate elements linked via `collection.composes.field`
292
- - ❌ Using invented `x-pii`, `x-json-schema`, or `x-apm-performance-metrics` attributes — these are not in the spec; use relationships (`field.satisfies.security.dataclassification`, `collection.realizes.api.schema`) instead
341
+ - ❌ Using invented `x-pii`, `x-json-schema`, or `x-apm-performance-metrics` attributes — these are not in the spec; use relationships (`field satisfies security.dataclassification`, `data-model.objectschema maps-to collection`) instead
293
342
  - ❌ Using `ttlDays` / `archiveAfterDays` in retentionpolicy — use `retentionDuration` (ISO 8601, e.g. `"P365D"`) and `action` (enum: DELETE | ARCHIVE | ...)
294
343
  - ❌ Forgetting `RetentionPolicy` for regulated data
295
344
  - ❌ Not documenting `EventHandler` for CDC or change-triggered workflows
@@ -139,20 +139,89 @@ EXPERIENCE TIER — specific to a view or experience
139
139
 
140
140
  ---
141
141
 
142
- ## Cross-Layer Relationships
142
+ ## Intra-Layer Relationships
143
+
144
+ Placement is `composes`: a view composes its sub-views, instances and action components, and an
145
+ instance composes its nested instances, slots, chart series and table columns. Instances and placed
146
+ sub-views `realizes` their library definition. Elements `applies` their layout, `binds-to` their data
147
+ config and `uses` their error config. A state composes its outgoing transitions, which `flows-to`
148
+ the next state. UX reaches other layers only through the interfaces and features a view realizes,
149
+ the operations an action triggers and the data a data config maps to.
150
+
151
+ | Source Type | Predicate | Target Type | Example |
152
+ | ------------------ | ------------ | ------------------- | ------------------------------------------------------------- |
153
+ | UXApplication | aggregates | UXSpec | "Storefront Web" aggregates the "Checkout Experience" spec |
154
+ | UXSpec | aggregates | View | "Checkout Experience" aggregates the "Cart" view |
155
+ | UXSpec | aggregates | ExperienceState | "Checkout Experience" aggregates the "Payment Pending" state |
156
+ | UXSpec | uses | UXLibrary | "Checkout Experience" uses the "Design System" library |
157
+ | UXLibrary | aggregates | LibraryComponent | "Design System" aggregates "Data Table" |
158
+ | UXLibrary | aggregates | LibrarySubView | "Design System" aggregates "Address Form Group" |
159
+ | View | composes | SubView | "Cart" view composes the "Order Summary" panel |
160
+ | View | composes | ComponentInstance | "Cart" view composes "Cart Items Table" |
161
+ | View | composes | ActionComponent | "Cart" view composes the "Checkout" button |
162
+ | View | applies | LayoutConfig | "Cart" view applies the "Two-Column Grid" layout |
163
+ | View | binds-to | DataConfig | "Cart" view binds to "Cart Data" |
164
+ | View | uses | ErrorConfig | "Cart" view uses "Cart Load Error" |
165
+ | SubView | realizes | LibrarySubView | "Shipping Address" section realizes "Address Form Group" |
166
+ | SubView | composes | ComponentInstance | "Order Summary" panel composes "Totals Card" |
167
+ | ComponentInstance | realizes | LibraryComponent | "Cart Items Table" realizes "Data Table" |
168
+ | ComponentInstance | binds-to | DataConfig | "Cart Items Table" binds to "Cart Data" |
169
+ | ComponentInstance | composes | TableColumn | "Cart Items Table" composes the "Quantity" column |
170
+ | ComponentInstance | composes | ChartSeries | "Revenue Chart" composes the "Monthly Revenue" series |
171
+ | ComponentReference | references | LibraryComponent | "Primary Button Slot" references "Button" (variant `primary`) |
172
+ | LibraryComponent | composes | LibraryComponent | "Data Table" composes "Pagination Bar" |
173
+ | LibraryComponent | specializes | LibraryComponent | "Currency Input" specializes "Text Input" |
174
+ | LibraryComponent | uses | StatePattern | "Data Table" uses the "Loading / Loaded / Error" pattern |
175
+ | ActionPattern | governs | ActionComponent | The "Submit" action pattern governs the "Checkout" button |
176
+ | ActionComponent | triggers | StateTransition | "Checkout" button triggers "Begin Payment" |
177
+ | ActionComponent | navigates-to | View | "Continue Shopping" link navigates to the "Catalog" view |
178
+ | ExperienceState | composes | StateTransition | "Cart Ready" composes "Begin Payment" |
179
+ | StateTransition | flows-to | ExperienceState | "Begin Payment" flows to "Payment Pending" |
180
+ | StateTransition | triggers | StateAction | "Begin Payment" triggers "Disable Checkout Button" |
181
+ | StateAction | realizes | StateActionTemplate | "Show Spinner" realizes the "Show Loading Indicator" template |
182
+ | StatePattern | aggregates | ExperienceState | "Loading / Loaded / Error" aggregates "Loading" |
183
+ | StateTransition | uses | TransitionTemplate | "Open Cart" uses the "Slide-In Drawer" template |
184
+ | DataConfig | uses | ErrorConfig | "Cart Data" uses the "Cart Load Error" config |
143
185
 
144
- **Outgoing (UX → Other Layers):**
145
-
146
- - `motivation.*` → Motivation Layer (UX supports goals)
147
- - `business.*` → Business Layer (UX realizes business processes)
148
- - `api.*` → API Layer (API calls from components)
149
- - `data-model.*` → Data Model Layer (schema references for data-bound components)
150
- - `navigation.*` → Navigation Layer (routing to views)
151
-
152
- **Incoming (Other Layers → UX):**
186
+ ---
153
187
 
154
- - Navigation Layer → UX (routes point to views)
155
- - Business Layer → UX (business processes trigger UX flows)
188
+ ## Cross-Layer References
189
+
190
+ ### Outgoing References (UX → Other Layers)
191
+
192
+ | Source Type | Predicate | Target Type | Example |
193
+ | ---------------- | ---------- | ---------------------------------- | --------------------------------------------------------------- |
194
+ | View | realizes | `product.feature` | "Cart" view realizes the "Shopping Cart" feature |
195
+ | View | references | `business.businessobject` | "Order Detail" view references the "Order" business object |
196
+ | View | realizes | `application.applicationinterface` | "Cart" view realizes the "Storefront Web UI" interface |
197
+ | View | satisfies | `motivation.requirement` | "Checkout" view satisfies "Guest checkout must be supported" |
198
+ | View | requires | `security.permission` | "Admin Orders" view requires the `orders:read` permission |
199
+ | View | serves | `business.businessrole` | "Admin Orders" view serves the "Fulfillment Clerk" role |
200
+ | ActionComponent | triggers | `api.operation` | "Place Order" button triggers `POST /orders` |
201
+ | ActionComponent | requires | `security.permission` | "Refund" button requires the `orders:refund` permission |
202
+ | StateAction | triggers | `api.operation` | "Load Cart" on-enter action triggers `GET /cart` |
203
+ | DataConfig | maps-to | `api.response` | "Cart Data" maps to the `GET /cart` 200 response |
204
+ | DataConfig | maps-to | `api.requestbody` | "Checkout Form Data" maps to the `POST /orders` request body |
205
+ | DataConfig | maps-to | `data-model.objectschema` | "Cart Data" maps to the "Cart" schema |
206
+ | TableColumn | maps-to | `data-model.schemaproperty` | "Quantity" column maps to the "quantity" property |
207
+ | TableColumn | references | `security.fieldaccesscontrol` | "Card Number" column references the "PAN Masking" control |
208
+ | ErrorConfig | references | `api.response` | "Payment Declined" references the `POST /payments` 402 response |
209
+ | LibraryComponent | depends-on | `technology.systemsoftware` | "Data Table" depends on "React 18" |
210
+
211
+ ### Incoming References (Other Layers → UX)
212
+
213
+ | Source Type | Predicate | Target Type | Example |
214
+ | --------------------------------- | --------- | --------------- | --------------------------------------------------------------- |
215
+ | `navigation.route` | maps-to | View | `/cart` route maps to the "Cart" view |
216
+ | `navigation.navigationtransition` | triggers | StateTransition | "Cart → Checkout" transition triggers "Begin Payment" |
217
+ | `navigation.navigationguard` | triggers | ExperienceState | "Require Login" guard triggers the "Signed Out" state |
218
+ | `testing.testcasesketch` | tests | View | "Empty cart renders placeholder" tests the "Cart" view |
219
+ | `testing.testcasesketch` | tests | ActionComponent | "Checkout disabled when cart empty" tests the "Checkout" button |
220
+ | `apm.span` | monitors | View | "page.load /cart" span monitors the "Cart" view |
221
+ | `apm.metricinstrument` | monitors | ActionComponent | "checkout_click_count" monitors the "Checkout" button |
222
+
223
+ > Routing is modelled from the Navigation Layer: a `navigation.route` `maps-to` the view it shows,
224
+ > rather than the view pointing at the route.
156
225
 
157
226
  ---
158
227
 
@@ -274,6 +343,13 @@ dr add ux dataconfig "Login Data" --attributes '{"source":"api","target":"ux.com
274
343
 
275
344
  # Add error config for failed login
276
345
  dr add ux errorconfig "Login Error" --description "Show inline error on auth failure"
346
+
347
+ # Wire the elements together
348
+ dr relationship add ux.view.login ux.componentinstance.login-form-instance --predicate composes
349
+ dr relationship add ux.componentinstance.login-form-instance ux.librarycomponent.login-form --predicate realizes
350
+ dr relationship add ux.statetransition.submit-clicked ux.experiencestate.submitting --predicate flows-to
351
+ dr relationship add ux.componentinstance.login-form-instance ux.dataconfig.login-data --predicate binds-to
352
+ dr relationship add ux.view.login ux.errorconfig.login-error --predicate uses
277
353
  ```
278
354
 
279
355
  ---
@@ -120,19 +120,75 @@ Activate when the user:
120
120
 
121
121
  ---
122
122
 
123
- ## Cross-Layer Relationships
123
+ ## Intra-Layer Relationships
124
+
125
+ A guard `evaluates` its condition, `triggers` its action on denial and `protects` what it guards. A
126
+ transition leaves its source route (`flows-to`) and `navigates-to` its destination. Context variables
127
+ are passive state that steps, guards, conditions, actions and transitions `accesses`. Navigation
128
+ never reaches the data store directly, and reaches the business through the product workflows that
129
+ flows and steps realize.
130
+
131
+ | Source Type | Predicate | Target Type | Example |
132
+ | -------------------- | ------------ | -------------------- | ------------------------------------------------------------- |
133
+ | NavigationGraph | composes | Route | "Web App Navigation" composes "User Profile Route" |
134
+ | NavigationGraph | composes | NavigationTransition | "Web App Navigation" composes "Cart To Shipping" |
135
+ | NavigationGraph | aggregates | NavigationFlow | "Web App Navigation" aggregates "Checkout Flow" |
136
+ | NavigationGraph | aggregates | NavigationGuard | "Web App Navigation" aggregates "Auth Guard" |
137
+ | NavigationGraph | aggregates | BreadcrumbConfig | "Web App Navigation" aggregates "Profile Breadcrumb" |
138
+ | Route | composes | RouteMeta | "User Profile Route" composes "Profile Route Meta" |
139
+ | Route | aggregates | Route | "Settings Route" aggregates "Settings Security Route" |
140
+ | Route | navigates-to | Route | "Legacy Account Route" navigates-to "Account Settings Route" |
141
+ | Route | flows-to | NavigationTransition | "Cart Route" flows-to "Cart To Shipping" (its source route) |
142
+ | BreadcrumbConfig | references | RouteMeta | "Profile Breadcrumb" references "Profile Route Meta" (labels) |
143
+ | BreadcrumbConfig | references | Route | "Profile Breadcrumb" references "Dashboard Route" |
144
+ | NavigationGuard | protects | Route | "Auth Guard" protects "User Profile Route" |
145
+ | NavigationGuard | evaluates | GuardCondition | "Auth Guard" evaluates "Is Authenticated" |
146
+ | NavigationGuard | triggers | GuardAction | "Auth Guard" triggers "Redirect To Login" |
147
+ | GuardCondition | accesses | ContextVariable | "Is Authenticated" accesses "Session Token" |
148
+ | GuardAction | navigates-to | Route | "Redirect To Login" navigates-to "Login Route" |
149
+ | NavigationFlow | composes | FlowStep | "Checkout Flow" composes "Cart Review Step" |
150
+ | NavigationFlow | aggregates | ContextVariable | "Checkout Flow" aggregates "Cart ID" |
151
+ | NavigationGuard | protects | NavigationFlow | "Cart Not Empty Guard" protects "Checkout Flow" |
152
+ | FlowStep | navigates-to | Route | "Cart Review Step" navigates-to "Cart Route" |
153
+ | FlowStep | accesses | ContextVariable | "Payment Step" accesses "Cart ID" |
154
+ | NavigationTransition | navigates-to | Route | "Cart To Shipping" navigates-to "Shipping Route" |
155
+ | NavigationGuard | protects | NavigationTransition | "Valid Address Guard" protects "Shipping To Payment" |
124
156
 
125
- **Outgoing (Navigation → Other Layers):**
126
-
127
- - `view-ref` → UX Layer (which view does this route show?)
128
- - `business.realizes-process` → Business Layer (what process does this flow realize?)
129
- - `security.required-roles` → Security Layer (authorization requirements)
130
- - `apm.flow-metrics` → APM Layer (navigation analytics)
131
-
132
- **Incoming (Other Layers → Navigation):**
157
+ ---
133
158
 
134
- - UX Layer → Navigation (views reference routes)
135
- - Business Layer → Navigation (processes trigger flows)
159
+ ## Cross-Layer References
160
+
161
+ ### Outgoing References (Navigation → Other Layers)
162
+
163
+ | Source Type | Predicate | Target Type | Example |
164
+ | -------------------- | ---------- | ---------------------------------- | ---------------------------------------------------------------- |
165
+ | Route | maps-to | `ux.view` | "User Profile Route" maps-to "User Profile View" |
166
+ | RouteMeta | uses | `ux.layoutconfig` | "Profile Route Meta" uses "Authenticated Shell Layout" |
167
+ | NavigationTransition | triggers | `ux.statetransition` | "Cart To Shipping" triggers "Cart Submitted Transition" |
168
+ | Route | requires | `security.permission` | "Admin Users Route" requires "users:read" |
169
+ | NavigationGuard | requires | `security.role` | "Auth Guard" requires "Authenticated User" |
170
+ | NavigationGuard | realizes | `security.securitypolicy` | "Admin Guard" realizes "Admin Access Policy" |
171
+ | ContextVariable | maps-to | `api.parameter` | "User ID" maps-to "userId path parameter" |
172
+ | Route | lazy-loads | `application.applicationcomponent` | "Reports Route" lazy-loads "Reports Module" |
173
+ | Route | uses | `application.applicationservice` | "Order Detail Route" uses "Order Service" (resolver) |
174
+ | NavigationFlow | realizes | `product.userworkflow` | "Onboarding Flow" realizes "New User Onboarding" |
175
+ | FlowStep | realizes | `product.workflowstep` | "Payment Step" realizes "Enter Payment Details" |
176
+ | Route | satisfies | `motivation.requirement` | "Order History Route" satisfies "Customers Can View Past Orders" |
177
+
178
+ ### Incoming References (Other Layers → Navigation)
179
+
180
+ | Source Type | Predicate | Target Type | Example |
181
+ | ---------------------------- | --------- | -------------------- | ------------------------------------------------------------------- |
182
+ | `api.operation` | serves | Route | "GET /users/{id}" serves "User Profile Route" (its loader calls it) |
183
+ | `api.operation` | serves | NavigationGuard | "GET /auth/session" serves "Auth Guard" |
184
+ | `apm.span` | monitors | Route | "Route Change Span" monitors "User Profile Route" |
185
+ | `apm.span` | monitors | NavigationFlow | "Checkout Journey Span" monitors "Checkout Flow" |
186
+ | `apm.metricinstrument` | monitors | Route | "route_load_time" monitors "User Profile Route" |
187
+ | `apm.metricinstrument` | monitors | NavigationTransition | "checkout_step_dropoff" monitors "Shipping To Payment" |
188
+ | `testing.testcasesketch` | tests | Route | "Deep Link To Profile" tests "User Profile Route" |
189
+ | `testing.testcasesketch` | tests | NavigationGuard | "Anonymous User Redirected" tests "Auth Guard" |
190
+ | `testing.testcasesketch` | tests | NavigationFlow | "Complete Checkout" tests "Checkout Flow" |
191
+ | `testing.testcoveragetarget` | covers | Route | "User Profile" target covers "User Profile Route" |
136
192
 
137
193
  ---
138
194
 
@@ -205,7 +261,6 @@ name: "User Profile Route"
205
261
  type: route
206
262
  properties:
207
263
  path: /profile/:userId
208
- view-ref: ux.view.user-profile
209
264
  guards:
210
265
  - navigation.navigationguard.authentication
211
266
  - navigation.navigationguard.profile-ownership
@@ -226,15 +281,15 @@ properties:
226
281
  dataMapping:
227
282
  - source: route.params.userId
228
283
  target: view.data.userId
229
- security:
230
- required-roles:
231
- - security.role.authenticated-user
232
- business:
233
- realizes-process: business.process.profile-management
234
- apm:
235
- flow-metrics:
236
- - apm.metric.profile-view-count
237
- - apm.metric.profile-load-time
284
+ ```
285
+
286
+ Record the cross-layer links as relationships, not as properties:
287
+
288
+ ```bash
289
+ dr relationship add navigation.route.user-profile ux.view.user-profile --predicate maps-to
290
+ dr relationship add navigation.navigationguard.authentication security.role.authenticated-user --predicate requires
291
+ dr relationship add api.operation.get-user navigation.route.user-profile --predicate serves
292
+ dr relationship add apm.metricinstrument.profile-load-time navigation.route.user-profile --predicate monitors
238
293
  ```
239
294
 
240
295
  ---
@@ -280,8 +335,12 @@ properties:
280
335
  - cartId
281
336
  - selectedAddress
282
337
  - paymentMethod
283
- business:
284
- realizes-process: business.process.checkout
338
+ ```
339
+
340
+ ```bash
341
+ dr relationship add navigation.navigationflow.checkout product.userworkflow.checkout --predicate realizes
342
+ dr relationship add navigation.navigationflow.checkout navigation.flowstep.cart-review --predicate composes
343
+ dr relationship add navigation.flowstep.cart-review navigation.route.cart --predicate navigates-to
285
344
  ```
286
345
 
287
346
  ---
@@ -314,5 +373,5 @@ If any type has ZERO elements, explicitly decide:
314
373
  - ❌ Not decomposing guards into conditions (`guardcondition`) and actions (`guardaction`) — model these as separate elements
315
374
  - ❌ Complex flows without explicit `flowstep` elements — each step in a flow should be a distinct `flowstep`
316
375
  - ❌ Missing `routemeta` for protected routes — auth requirements belong in `routemeta`, not embedded in route properties
317
- - ❌ Missing cross-layer links to UX views (`view-ref`) and business processes (`realizes-process`)
376
+ - ❌ Missing cross-layer links — each route should `maps-to` a `ux.view`, and flows should `realizes` a `business.businessprocess` or `product.userworkflow`
318
377
  - ❌ No error/fallback routes defined — model these as `route` with `type: redirect`