@transitrix/diagrams 1.0.0 → 1.1.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 (315) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +47 -47
  3. package/dist/__tests__/edge-path.test.js +8 -0
  4. package/dist/activities/cpm.js +11 -2
  5. package/dist/activities/gantt.js +6 -3
  6. package/dist/activities/types.d.ts +1 -0
  7. package/dist/activities/validate.js +3 -3
  8. package/dist/activity-card/__tests__/example.test.js +20 -1
  9. package/dist/activity-card/__tests__/layout.test.js +102 -11
  10. package/dist/activity-card/__tests__/resolver.test.js +161 -7
  11. package/dist/activity-card/index.d.ts +1 -1
  12. package/dist/activity-card/layout.d.ts +1 -1
  13. package/dist/activity-card/layout.js +220 -103
  14. package/dist/activity-card/resolver.js +115 -28
  15. package/dist/activity-card/types.d.ts +150 -27
  16. package/dist/activity-card/validate.js +3 -0
  17. package/dist/actor/__tests__/validate.test.js +63 -31
  18. package/dist/actor/index.d.ts +1 -1
  19. package/dist/actor/index.js +1 -1
  20. package/dist/actor/types.d.ts +7 -3
  21. package/dist/actor/types.js +17 -3
  22. package/dist/actor/validate.js +55 -26
  23. package/dist/assertion/types.d.ts +3 -1
  24. package/dist/assertion/types.js +1 -1
  25. package/dist/change/__tests__/validate.test.js +40 -34
  26. package/dist/change/index.d.ts +1 -0
  27. package/dist/change/types.d.ts +1 -1
  28. package/dist/change/types.js +2 -2
  29. package/dist/change/validate.d.ts +6 -1
  30. package/dist/change/validate.js +68 -41
  31. package/dist/compliance/__tests__/classify.test.js +34 -0
  32. package/dist/compliance/__tests__/coverage-metric.test.js +146 -46
  33. package/dist/compliance/__tests__/html.test.js +2 -2
  34. package/dist/compliance/__tests__/impact.test.js +509 -6
  35. package/dist/compliance/classify.d.ts +6 -0
  36. package/dist/compliance/classify.js +9 -1
  37. package/dist/compliance/coverage-metric.d.ts +31 -11
  38. package/dist/compliance/coverage-metric.js +149 -39
  39. package/dist/compliance/html.js +78 -81
  40. package/dist/compliance/impact.d.ts +100 -16
  41. package/dist/compliance/impact.js +272 -28
  42. package/dist/compliance/index.d.ts +2 -2
  43. package/dist/compliance/index.js +1 -1
  44. package/dist/compliance/markdown.js +1 -0
  45. package/dist/compliance/types.d.ts +25 -6
  46. package/dist/edge-path.d.ts +8 -4
  47. package/dist/edge-path.js +11 -6
  48. package/dist/factor/__tests__/validate.test.js +75 -46
  49. package/dist/factor/index.d.ts +3 -2
  50. package/dist/factor/index.js +1 -1
  51. package/dist/factor/types.d.ts +5 -8
  52. package/dist/factor/types.js +10 -5
  53. package/dist/factor/validate.d.ts +6 -1
  54. package/dist/factor/validate.js +68 -50
  55. package/dist/fgca/__tests__/chain-table.test.js +2 -2
  56. package/dist/fgca/__tests__/layout.test.js +11 -11
  57. package/dist/fgca/__tests__/preview-layout.test.js +7 -7
  58. package/dist/fgca/__tests__/resolver.test.js +185 -0
  59. package/dist/fgca/chain-table.d.ts +1 -1
  60. package/dist/fgca/chain-table.js +4 -4
  61. package/dist/fgca/index.d.ts +4 -2
  62. package/dist/fgca/index.js +2 -1
  63. package/dist/fgca/layout.d.ts +2 -2
  64. package/dist/fgca/layout.js +9 -9
  65. package/dist/fgca/nodeTypes.d.ts +1 -1
  66. package/dist/fgca/nodeTypes.js +2 -2
  67. package/dist/fgca/nodes/FGCAFactorNode.d.ts +3 -3
  68. package/dist/fgca/nodes/FGCAFactorNode.js +5 -5
  69. package/dist/fgca/parse-canonical.js +15 -10
  70. package/dist/fgca/preview-layout.d.ts +1 -1
  71. package/dist/fgca/preview-layout.js +4 -4
  72. package/dist/fgca/resolver.d.ts +49 -0
  73. package/dist/fgca/resolver.js +126 -0
  74. package/dist/fgca/types.d.ts +11 -11
  75. package/dist/fgca/types.js +2 -2
  76. package/dist/fgca/validate.d.ts +2 -2
  77. package/dist/fgca/validate.js +17 -14
  78. package/dist/goals/index.d.ts +1 -1
  79. package/dist/index.d.ts +5 -0
  80. package/dist/index.js +5 -0
  81. package/dist/process-blueprint/__tests__/layout.test.js +37 -0
  82. package/dist/process-blueprint/index.d.ts +1 -1
  83. package/dist/process-blueprint/layout.js +66 -35
  84. package/dist/process-blueprint/types.d.ts +36 -1
  85. package/dist/scenarios/index.d.ts +1 -1
  86. package/dist/scenarios/types.d.ts +4 -4
  87. package/dist/stakeholder/__tests__/validate.test.js +49 -47
  88. package/dist/stakeholder/index.d.ts +1 -0
  89. package/dist/stakeholder/types.d.ts +3 -4
  90. package/dist/stakeholder/types.js +2 -3
  91. package/dist/stakeholder/validate.d.ts +6 -1
  92. package/dist/stakeholder/validate.js +71 -50
  93. package/dist/target-state/__tests__/validate.test.js +43 -27
  94. package/dist/target-state/index.d.ts +2 -0
  95. package/dist/target-state/index.js +1 -0
  96. package/dist/target-state/types.d.ts +6 -1
  97. package/dist/target-state/types.js +8 -7
  98. package/dist/target-state/validate.d.ts +6 -1
  99. package/dist/target-state/validate.js +69 -45
  100. package/dist/theme/themes.js +71 -69
  101. package/dist/theme/tokens.d.ts +7 -1
  102. package/dist/theme/tokens.js +3 -1
  103. package/dist/webview/__tests__/entry-notations.test.js +2 -0
  104. package/dist/webview/__tests__/entry.test.js +11 -11
  105. package/dist/webview/__tests__/render-process.test.js +463 -0
  106. package/dist/webview/__tests__/render-util.test.d.ts +1 -0
  107. package/dist/webview/__tests__/render-util.test.js +54 -0
  108. package/dist/webview/entry.d.ts +1 -1
  109. package/dist/webview/entry.js +9 -5
  110. package/dist/webview/render-activities.d.ts +24 -2
  111. package/dist/webview/render-activities.js +92 -57
  112. package/dist/webview/render-activity-card.d.ts +11 -1
  113. package/dist/webview/render-activity-card.js +115 -79
  114. package/dist/webview/render-blocks.d.ts +24 -1
  115. package/dist/webview/render-blocks.js +58 -24
  116. package/dist/webview/render-fgca.d.ts +31 -0
  117. package/dist/webview/render-fgca.js +30 -19
  118. package/dist/webview/render-goals.d.ts +27 -1
  119. package/dist/webview/render-goals.js +42 -32
  120. package/dist/webview/render-process-blueprint.d.ts +11 -1
  121. package/dist/webview/render-process-blueprint.js +118 -53
  122. package/dist/webview/render-process.d.ts +95 -0
  123. package/dist/webview/render-process.js +392 -0
  124. package/dist/webview/render-scenarios.js +2 -2
  125. package/dist/webview/render-util.d.ts +19 -6
  126. package/dist/webview/render-util.js +23 -15
  127. package/package.json +54 -40
  128. package/src/__tests__/edge-path.test.ts +58 -46
  129. package/src/__tests__/scope.test.ts +27 -27
  130. package/src/__tests__/yaml-normalize.test.ts +158 -158
  131. package/src/activities/__tests__/cpm.test.ts +164 -164
  132. package/src/activities/__tests__/gantt.test.ts +245 -245
  133. package/src/activities/__tests__/layout.test.ts +112 -112
  134. package/src/activities/__tests__/validate.test.ts +409 -409
  135. package/src/activities/cpm.ts +107 -95
  136. package/src/activities/gantt.ts +277 -276
  137. package/src/activities/index.ts +28 -28
  138. package/src/activities/layout.ts +112 -112
  139. package/src/activities/types.ts +149 -148
  140. package/src/activities/validate.ts +357 -357
  141. package/src/activity-card/__tests__/example.test.ts +85 -66
  142. package/src/activity-card/__tests__/layout.test.ts +169 -63
  143. package/src/activity-card/__tests__/resolver.test.ts +330 -161
  144. package/src/activity-card/__tests__/validate.test.ts +131 -131
  145. package/src/activity-card/index.ts +38 -32
  146. package/src/activity-card/layout.ts +324 -194
  147. package/src/activity-card/resolver.ts +422 -337
  148. package/src/activity-card/types.ts +376 -237
  149. package/src/activity-card/validate.ts +162 -158
  150. package/src/actor/__tests__/validate.test.ts +70 -31
  151. package/src/actor/index.ts +1 -1
  152. package/src/actor/types.ts +21 -7
  153. package/src/actor/validate.ts +59 -27
  154. package/src/applications/__tests__/validate.test.ts +256 -256
  155. package/src/applications/index.ts +11 -11
  156. package/src/applications/types.ts +43 -43
  157. package/src/applications/validate.ts +131 -131
  158. package/src/assertion/__tests__/example.test.ts +37 -37
  159. package/src/assertion/__tests__/validate.test.ts +142 -142
  160. package/src/assertion/index.ts +12 -12
  161. package/src/assertion/types.ts +60 -58
  162. package/src/assertion/validate.ts +145 -145
  163. package/src/blocks/__tests__/layout.test.ts +169 -169
  164. package/src/blocks/__tests__/validate.test.ts +260 -260
  165. package/src/blocks/index.ts +17 -17
  166. package/src/blocks/layout.ts +186 -186
  167. package/src/blocks/types.ts +62 -62
  168. package/src/blocks/validate.ts +206 -206
  169. package/src/capability-map/__tests__/validate.test.ts +238 -238
  170. package/src/capability-map/index.ts +8 -8
  171. package/src/capability-map/types.ts +29 -29
  172. package/src/capability-map/validate.ts +127 -127
  173. package/src/change/__tests__/validate.test.ts +43 -34
  174. package/src/change/index.ts +1 -0
  175. package/src/change/types.ts +5 -3
  176. package/src/change/validate.ts +75 -43
  177. package/src/compliance/__tests__/classify.test.ts +64 -27
  178. package/src/compliance/__tests__/confidence.test.ts +98 -98
  179. package/src/compliance/__tests__/coverage-metric.test.ts +300 -188
  180. package/src/compliance/__tests__/demo-scenario.test.ts +273 -273
  181. package/src/compliance/__tests__/example.test.ts +57 -57
  182. package/src/compliance/__tests__/gap-report.test.ts +128 -128
  183. package/src/compliance/__tests__/html.test.ts +141 -141
  184. package/src/compliance/__tests__/impact.test.ts +1059 -481
  185. package/src/compliance/__tests__/markdown.test.ts +94 -94
  186. package/src/compliance/__tests__/views.test.ts +64 -64
  187. package/src/compliance/classify.ts +100 -84
  188. package/src/compliance/confidence.ts +69 -69
  189. package/src/compliance/coverage-metric.ts +404 -263
  190. package/src/compliance/gap-report.ts +94 -94
  191. package/src/compliance/html.ts +291 -295
  192. package/src/compliance/impact.ts +979 -677
  193. package/src/compliance/index.ts +57 -56
  194. package/src/compliance/markdown.ts +136 -135
  195. package/src/compliance/reverse-index.ts +33 -33
  196. package/src/compliance/types.ts +136 -120
  197. package/src/compliance/views.ts +46 -46
  198. package/src/compliance-matrix/__tests__/build.test.ts +200 -200
  199. package/src/compliance-matrix/__tests__/example.test.ts +57 -57
  200. package/src/compliance-matrix/index.ts +11 -11
  201. package/src/compliance-matrix/types.ts +102 -102
  202. package/src/edge-path.ts +50 -44
  203. package/src/factor/__tests__/validate.test.ts +81 -46
  204. package/src/factor/index.ts +3 -7
  205. package/src/factor/types.ts +15 -19
  206. package/src/factor/validate.ts +77 -51
  207. package/src/fgca/__tests__/chain-table.test.ts +172 -172
  208. package/src/fgca/__tests__/layout.test.ts +179 -179
  209. package/src/fgca/__tests__/parse-canonical.test.ts +248 -248
  210. package/src/fgca/__tests__/preview-layout.test.ts +124 -124
  211. package/src/fgca/__tests__/resolver.test.ts +209 -0
  212. package/src/fgca/__tests__/validate.test.ts +142 -142
  213. package/src/fgca/chain-table.ts +225 -225
  214. package/src/fgca/index.ts +47 -45
  215. package/src/fgca/layout.ts +204 -204
  216. package/src/fgca/nodeTypes.ts +11 -11
  217. package/src/fgca/nodes/FGCAActivityNode.tsx +65 -65
  218. package/src/fgca/nodes/FGCAChangeNode.tsx +64 -64
  219. package/src/fgca/nodes/FGCAFactorNode.tsx +64 -64
  220. package/src/fgca/nodes/FGCAGoalNode.tsx +72 -72
  221. package/src/fgca/parse-canonical.ts +405 -400
  222. package/src/fgca/preview-layout.ts +217 -217
  223. package/src/fgca/resolver.ts +159 -0
  224. package/src/fgca/types.ts +50 -50
  225. package/src/fgca/validate.ts +129 -126
  226. package/src/geometry.ts +9 -9
  227. package/src/goals/__tests__/layout.test.ts +175 -175
  228. package/src/goals/__tests__/mutations.test.ts +111 -111
  229. package/src/goals/__tests__/parse-canonical.test.ts +145 -145
  230. package/src/goals/__tests__/validate.test.ts +202 -202
  231. package/src/goals/index.ts +20 -21
  232. package/src/goals/layout.ts +172 -172
  233. package/src/goals/mutations.ts +123 -123
  234. package/src/goals/parse-canonical.ts +286 -286
  235. package/src/goals/types.ts +85 -85
  236. package/src/goals/validate.ts +136 -136
  237. package/src/index.ts +28 -23
  238. package/src/process-blueprint/__tests__/compliance-lane.test.ts +320 -320
  239. package/src/process-blueprint/__tests__/layout.test.ts +240 -195
  240. package/src/process-blueprint/__tests__/validate.test.ts +310 -310
  241. package/src/process-blueprint/index.ts +32 -31
  242. package/src/process-blueprint/layout.ts +564 -531
  243. package/src/process-blueprint/types.ts +278 -242
  244. package/src/process-blueprint/validate.ts +181 -181
  245. package/src/process-map/__tests__/validate.test.ts +223 -223
  246. package/src/process-map/index.ts +10 -10
  247. package/src/process-map/types.ts +36 -36
  248. package/src/process-map/validate.ts +135 -135
  249. package/src/products/__tests__/validate.test.ts +239 -239
  250. package/src/products/index.ts +9 -9
  251. package/src/products/types.ts +31 -31
  252. package/src/products/validate.ts +112 -112
  253. package/src/repo-validate/__tests__/validate-repo.test.ts +149 -149
  254. package/src/repo-validate/index.ts +2 -2
  255. package/src/repo-validate/types.ts +50 -50
  256. package/src/repo-validate/validate-repo.ts +196 -196
  257. package/src/requirement/__tests__/example.test.ts +24 -24
  258. package/src/requirement/__tests__/validate.test.ts +96 -96
  259. package/src/requirement/index.ts +4 -4
  260. package/src/requirement/types.ts +35 -35
  261. package/src/requirement/validate.ts +92 -92
  262. package/src/scenarios/__tests__/validate.test.ts +209 -209
  263. package/src/scenarios/index.ts +15 -15
  264. package/src/scenarios/types.ts +37 -37
  265. package/src/scenarios/validate.ts +122 -122
  266. package/src/schema-version.ts +16 -16
  267. package/src/scope.ts +46 -46
  268. package/src/stakeholder/__tests__/validate.test.ts +51 -47
  269. package/src/stakeholder/index.ts +1 -0
  270. package/src/stakeholder/types.ts +7 -7
  271. package/src/stakeholder/validate.ts +79 -52
  272. package/src/target-state/__tests__/validate.test.ts +48 -27
  273. package/src/target-state/index.ts +2 -0
  274. package/src/target-state/types.ts +11 -7
  275. package/src/target-state/validate.ts +76 -46
  276. package/src/theme/index.ts +4 -4
  277. package/src/theme/themes.ts +239 -237
  278. package/src/theme/tokens.ts +135 -133
  279. package/src/typed-id.ts +56 -56
  280. package/src/validation-types.ts +36 -36
  281. package/src/webview/__tests__/entry-notations.test.ts +79 -77
  282. package/src/webview/__tests__/entry.test.ts +64 -64
  283. package/src/webview/__tests__/render-goals.test.ts +72 -72
  284. package/src/webview/__tests__/render-process.test.ts +538 -0
  285. package/src/webview/__tests__/render-util.test.ts +66 -0
  286. package/src/webview/entry.ts +298 -292
  287. package/src/webview/render-activities.ts +111 -69
  288. package/src/webview/render-activity-card.ts +275 -234
  289. package/src/webview/render-blocks.ts +78 -28
  290. package/src/webview/render-fgca.ts +53 -28
  291. package/src/webview/render-goals.ts +133 -110
  292. package/src/webview/render-process-blueprint.ts +281 -207
  293. package/src/webview/render-process.ts +507 -0
  294. package/src/webview/render-scenarios.ts +3 -3
  295. package/src/webview/render-util.ts +27 -14
  296. package/src/webview/styles.css +322 -323
  297. package/src/yaml-normalize.ts +56 -56
  298. package/dist/element-envelope.d.ts +0 -15
  299. package/dist/element-envelope.js +0 -55
  300. package/dist/issues/__tests__/layout.test.js +0 -62
  301. package/dist/issues/__tests__/validate.test.js +0 -82
  302. package/dist/issues/index.d.ts +0 -4
  303. package/dist/issues/index.js +0 -2
  304. package/dist/issues/layout.d.ts +0 -10
  305. package/dist/issues/layout.js +0 -82
  306. package/dist/issues/types.d.ts +0 -61
  307. package/dist/issues/types.js +0 -6
  308. package/dist/issues/validate.d.ts +0 -3
  309. package/dist/issues/validate.js +0 -143
  310. package/dist/webview/transitrix-render.css +0 -323
  311. package/dist/webview/transitrix-render.js +0 -6452
  312. package/dist/webview/transitrix-render.js.map +0 -7
  313. package/src/element-envelope.ts +0 -76
  314. /package/dist/{issues/__tests__/layout.test.d.ts → fgca/__tests__/resolver.test.d.ts} +0 -0
  315. /package/dist/{issues/__tests__/validate.test.d.ts → webview/__tests__/render-process.test.d.ts} +0 -0
@@ -1,237 +1,376 @@
1
- // Activity Card notation — single-project narrative view.
2
- //
3
- // Spec: transitrix/methodology `notations/views/18-activity-card.md` (v0.1).
4
- // Epic vkgeorgia/strategy#97, Studio track #134.
5
- //
6
- // The Activity Card is the first MULTI-DOCUMENT Studio notation. The card
7
- // YAML itself holds only `id`, `project` (an Activity ID), `description`,
8
- // and `milestones[]`. Everything painted on the card — the project name,
9
- // dates, motivation chain (Factors → Goals → Changes), and child activities
10
- // — is pulled BY REFERENCE at view time from the canonical ELEMENT and
11
- // RELATION store (`canon/elements/**`, `canon/relations/**`), never from
12
- // other view documents. This honours the view-purity invariant: a view is a
13
- // projection over elements + relations (methodology ELEMENT_PRIMITIVES.md §1).
14
- // See `resolver.ts`.
15
- //
16
- // This file declares two model layers:
17
- // 1. the RAW card document (what the YAML parses into), and
18
- // 2. the ASSEMBLED card view-model (what the resolver produces and the
19
- // layout consumes).
20
-
21
- import type {
22
- ValidationError as SharedValidationError,
23
- ValidationWarning as SharedValidationWarning,
24
- ValidationResult as SharedValidationResult,
25
- } from '../validation-types.js';
26
-
27
- // Keep PREFIXED aliases consistent with the other notation modules so
28
- // external consumers can name the activity-card result types directly.
29
- export type ActivityCardValidationError = SharedValidationError;
30
- export type ActivityCardValidationWarning = SharedValidationWarning;
31
- export type ActivityCardValidationResult = SharedValidationResult;
32
-
33
- // ── Raw card document (the `*.activity-card.transitrix.yaml` shape) ──────────
34
-
35
- export interface RawMilestone {
36
- id: string;
37
- name: string;
38
- /** Quoted ISO 8601 date (YYYY-MM-DD) when the milestone is reached. */
39
- date: string;
40
- description?: string;
41
- /** CHANGE-… IDs; each must be a subset of the project Activity's delivers_changes. */
42
- delivers_changes?: string[];
43
- }
44
-
45
- export interface ActivityCardBlock {
46
- id: string;
47
- /** Canonical ID of the referenced project Activity (ACTIVITY-…). */
48
- project: string;
49
- description?: string;
50
- milestones?: RawMilestone[];
51
- }
52
-
53
- export interface ActivityCardDoc {
54
- notation: string;
55
- spec_version?: string;
56
- activity_card: ActivityCardBlock;
57
- }
58
-
59
- // ── Canon sources consumed by the resolver ──────────────────────────────────
60
- //
61
- // View-purity invariant (methodology ELEMENT_PRIMITIVES.md §1): a view is a
62
- // projection over the canonical ELEMENTS + RELATIONS, never over other view
63
- // documents. The Activity Card therefore resolves its project, child
64
- // activities, and motivation chain from the canon element store
65
- // (`canon/elements/**` — one ACTIVITY / FACTOR / GOAL / CHANGE element per
66
- // file, each a `notation: <type>` document carrying its own `id`) and the
67
- // relation store (`canon/relations/**` — `notation: relation` files), NOT from
68
- // sibling `*.activities.*` / `*.fgca.*` view documents.
69
- //
70
- // The resolver is filesystem-free: the extension reads + parses the element and
71
- // relation files and hands the parsed objects in. We model them as `unknown[]`
72
- // at the boundary and narrow defensively inside the resolver, so a malformed
73
- // element / relation degrades to a resolution error rather than a crash.
74
-
75
- export interface ActivityCardSources {
76
- /** Parsed canon element documents — one element per file (`notation: activity|factor|goal|change|…`). */
77
- elements: unknown[];
78
- /** Parsed canon relation documents (`notation: relation`). */
79
- relations: unknown[];
80
- }
81
-
82
- // ── Assembled card view-model (resolver output → layout input) ───────────────
83
-
84
- export interface ResolvedProject {
85
- id: string;
86
- name: string;
87
- /** Full description from the Activity (the card's own `description` is separate). */
88
- description?: string;
89
- /** Lifecycle: decision-to-initiate date (CONTRACT.md §7). */
90
- valid_from?: string;
91
- /** Lifecycle: when the project ceased effect, or undefined if active. */
92
- valid_to?: string;
93
- /** Planned work range. */
94
- start_date?: string;
95
- end_date?: string;
96
- }
97
-
98
- export interface ResolvedMilestone {
99
- id: string;
100
- name: string;
101
- date: string;
102
- description?: string;
103
- /** CHANGE-… IDs this milestone delivers (subset of the project's). */
104
- deliversChanges: string[];
105
- }
106
-
107
- export interface ResolvedFactor {
108
- id: string;
109
- name: string;
110
- }
111
-
112
- export interface ResolvedGoal {
113
- id: string;
114
- name: string;
115
- /** FACTOR-… IDs that motivate this goal (canonical `goal.factors`). */
116
- factorIds: string[];
117
- }
118
-
119
- export interface ResolvedChange {
120
- id: string;
121
- name: string;
122
- /** GOAL-… IDs this change advances (canonical `change.goals`). */
123
- goalIds: string[];
124
- }
125
-
126
- /** Motivation chain: Factors → Goals → Changes, scoped to the project. */
127
- export interface ResolvedMotivation {
128
- factors: ResolvedFactor[];
129
- goals: ResolvedGoal[];
130
- changes: ResolvedChange[];
131
- }
132
-
133
- export interface ResolvedChildActivity {
134
- id: string;
135
- name: string;
136
- activity_type?: string;
137
- start_date?: string;
138
- end_date?: string;
139
- owner?: string;
140
- }
141
-
142
- export interface ResolvedActivityCard {
143
- cardId: string;
144
- /** The card's own executive-summary description (distinct from the project's). */
145
- cardDescription?: string;
146
- project: ResolvedProject;
147
- /** Sorted ascending by `date`. */
148
- milestones: ResolvedMilestone[];
149
- motivation: ResolvedMotivation;
150
- /** Activities whose `parent` = the project Activity id. */
151
- childActivities: ResolvedChildActivity[];
152
- }
153
-
154
- // ── Layout geometry (pure; the preview turns this into SVG) ───────────────────
155
-
156
- import type { LayoutBounds } from '../geometry.js';
157
- export type { LayoutBounds };
158
-
159
- /** A boxed value-pair shown in the dates band. */
160
- export interface DateField {
161
- label: string;
162
- value: string;
163
- x: number;
164
- y: number;
165
- width: number;
166
- height: number;
167
- }
168
-
169
- /** One milestone marker on the timeline. */
170
- export interface MilestoneMarker {
171
- id: string;
172
- name: string;
173
- date: string;
174
- /** ArchiMate class label appended by the renderer (§5.1). */
175
- archimateClass: string;
176
- x: number;
177
- y: number;
178
- width: number;
179
- height: number;
180
- }
181
-
182
- /** One node in a motivation-chain column. */
183
- export interface ChainNode {
184
- id: string;
185
- name: string;
186
- x: number;
187
- y: number;
188
- width: number;
189
- height: number;
190
- }
191
-
192
- /** An edge between two chain nodes (factor→goal or goal→change). */
193
- export interface ChainEdge {
194
- sourceId: string;
195
- targetId: string;
196
- }
197
-
198
- export interface ChildActivityRow {
199
- id: string;
200
- name: string;
201
- /** ArchiMate class label appended by the renderer (§5.1). */
202
- archimateClass: string;
203
- meta: string;
204
- x: number;
205
- y: number;
206
- width: number;
207
- height: number;
208
- }
209
-
210
- export interface SectionHeader {
211
- label: string;
212
- x: number;
213
- y: number;
214
- width: number;
215
- height: number;
216
- }
217
-
218
- export interface ActivityCardLayoutOptions {
219
- /** Outer card width (px). */
220
- cardWidth?: number;
221
- /** Horizontal gap (px) between the three motivation-chain columns. */
222
- columnGap?: number;
223
- /** Vertical gap (px) between stacked rows within a section. */
224
- rowGap?: number;
225
- }
226
-
227
- export interface ActivityCardLayout {
228
- bounds: LayoutBounds;
229
- title: { name: string; x: number; y: number };
230
- dateFields: DateField[];
231
- sectionHeaders: SectionHeader[];
232
- milestones: MilestoneMarker[];
233
- /** Three columns of the motivation chain, in F→G→C order. */
234
- chainColumns: { factors: ChainNode[]; goals: ChainNode[]; changes: ChainNode[] };
235
- chainEdges: ChainEdge[];
236
- childActivities: ChildActivityRow[];
237
- }
1
+ // Activity Card notation — single-project narrative view.
2
+ //
3
+ // Spec: transitrix/methodology `notations/views/18-activity-card.md` (v0.1).
4
+ // Epic vkgeorgia/strategy#97, Studio track #134.
5
+ //
6
+ // The Activity Card is the first MULTI-DOCUMENT Studio notation. The card
7
+ // YAML itself holds only `id`, `project` (an Activity ID), `description`,
8
+ // and `milestones[]`. Everything painted on the card — the project name,
9
+ // dates, motivation chain (Factors → Goals → Changes), and child activities
10
+ // — is pulled BY REFERENCE at view time from the canonical ELEMENT and
11
+ // RELATION store (`canon/elements/**`, `canon/relations/**`), never from
12
+ // other view documents. This honours the view-purity invariant: a view is a
13
+ // projection over elements + relations (methodology ELEMENT_PRIMITIVES.md §1).
14
+ // See `resolver.ts`.
15
+ //
16
+ // This file declares two model layers:
17
+ // 1. the RAW card document (what the YAML parses into), and
18
+ // 2. the ASSEMBLED card view-model (what the resolver produces and the
19
+ // layout consumes).
20
+
21
+ import type {
22
+ ValidationError as SharedValidationError,
23
+ ValidationWarning as SharedValidationWarning,
24
+ ValidationResult as SharedValidationResult,
25
+ } from '../validation-types.js';
26
+
27
+ // Keep PREFIXED aliases consistent with the other notation modules so
28
+ // external consumers can name the activity-card result types directly.
29
+ export type ActivityCardValidationError = SharedValidationError;
30
+ export type ActivityCardValidationWarning = SharedValidationWarning;
31
+ export type ActivityCardValidationResult = SharedValidationResult;
32
+
33
+ // ── Raw card document (the `*.activity-card.transitrix.yaml` shape) ──────────
34
+
35
+ export interface RawMilestone {
36
+ id: string;
37
+ name: string;
38
+ /** Quoted ISO 8601 date (YYYY-MM-DD) when the milestone is reached. */
39
+ date: string;
40
+ description?: string;
41
+ /** CHANGE-… IDs; each must be a subset of the project Activity's delivers_changes. */
42
+ delivers_changes?: string[];
43
+ }
44
+
45
+ export interface ActivityCardBlock {
46
+ id: string;
47
+ /** Canonical ID of the referenced project Activity (ACTIVITY-…). */
48
+ project: string;
49
+ description?: string;
50
+ milestones?: RawMilestone[];
51
+ /**
52
+ * Supplementary notes shown in the card footer. Free text; stored in the
53
+ * view file (not in canon elements) as report-level context.
54
+ */
55
+ notes?: string;
56
+ }
57
+
58
+ export interface ActivityCardDoc {
59
+ notation: string;
60
+ spec_version?: string;
61
+ activity_card: ActivityCardBlock;
62
+ }
63
+
64
+ // ── Canon sources consumed by the resolver ──────────────────────────────────
65
+ //
66
+ // View-purity invariant (methodology ELEMENT_PRIMITIVES.md §1): a view is a
67
+ // projection over the canonical ELEMENTS + RELATIONS, never over other view
68
+ // documents. The Activity Card therefore resolves its project, child
69
+ // activities, and motivation chain from the canon element store
70
+ // (`canon/elements/**` — one ACTIVITY / FACTOR / GOAL / CHANGE element per
71
+ // file, each a `notation: <type>` document carrying its own `id`) and the
72
+ // relation store (`canon/relations/**` — `notation: relation` files), NOT from
73
+ // sibling `*.activities.*` / `*.fgca.*` view documents.
74
+ //
75
+ // The resolver is filesystem-free: the extension reads + parses the element and
76
+ // relation files and hands the parsed objects in. We model them as `unknown[]`
77
+ // at the boundary and narrow defensively inside the resolver, so a malformed
78
+ // element / relation degrades to a resolution error rather than a crash.
79
+
80
+ export interface ActivityCardSources {
81
+ /** Parsed canon element documents — one element per file (`notation: activity|factor|goal|change|…`). */
82
+ elements: unknown[];
83
+ /** Parsed canon relation documents (`notation: relation`). */
84
+ relations: unknown[];
85
+ }
86
+
87
+ // ── Assembled card view-model (resolver output → layout input) ───────────────
88
+
89
+ export interface ResolvedProject {
90
+ id: string;
91
+ name: string;
92
+ /** Full description from the Activity (the card's own `description` is separate). */
93
+ description?: string;
94
+ /** Lifecycle: decision-to-initiate date (CONTRACT.md §7). */
95
+ valid_from?: string;
96
+ /** Lifecycle: when the project ceased effect, or undefined if active. */
97
+ valid_to?: string;
98
+ /** Planned work range. */
99
+ start_date?: string;
100
+ end_date?: string;
101
+ /**
102
+ * Activity scale: programme | project | workstream | task (or any custom
103
+ * value). Shown in the card header so the reader knows what level this card
104
+ * represents. Optional — card shows "—" when absent.
105
+ */
106
+ activity_type?: string;
107
+ /**
108
+ * Current execution state: planned | in_progress | on_track | at_risk |
109
+ * blocked | completed | cancelled. Optional — card shows "—" when absent.
110
+ */
111
+ status?: string;
112
+ }
113
+
114
+ export interface ResolvedMilestone {
115
+ id: string;
116
+ name: string;
117
+ date: string;
118
+ description?: string;
119
+ /** CHANGE-… IDs this milestone delivers (subset of the project's). */
120
+ deliversChanges: string[];
121
+ }
122
+
123
+ export interface ResolvedDriver {
124
+ id: string;
125
+ name: string;
126
+ }
127
+
128
+ /** @deprecated Use {@link ResolvedDriver}. */
129
+ export type ResolvedFactor = ResolvedDriver;
130
+
131
+ /**
132
+ * A dated finding about the current state of a Driver, answering the
133
+ * question "what specific problem are we solving?" (pain point).
134
+ * Resolved from ASSESSMENT elements whose `assesses` field points to a
135
+ * Driver that is in scope for this activity's motivation chain.
136
+ */
137
+ export interface ResolvedAssessment {
138
+ id: string;
139
+ name: string;
140
+ /** ID of the Driver this assessment observes. */
141
+ driverId: string;
142
+ description?: string;
143
+ /** ISO 8601 date when the finding was observed. */
144
+ observed_at?: string;
145
+ }
146
+
147
+ export interface ResolvedGoal {
148
+ id: string;
149
+ name: string;
150
+ /** DRIVER-… IDs that motivate this goal (canonical `goal.factors` YAML field). */
151
+ driverIds: string[];
152
+ }
153
+
154
+ export interface ResolvedChange {
155
+ id: string;
156
+ name: string;
157
+ /** GOAL-… IDs this change advances (canonical `change.goals`). */
158
+ goalIds: string[];
159
+ }
160
+
161
+ /** Motivation chain: Drivers → Goals → Changes, scoped to the project. */
162
+ export interface ResolvedMotivation {
163
+ drivers: ResolvedDriver[];
164
+ goals: ResolvedGoal[];
165
+ changes: ResolvedChange[];
166
+ }
167
+
168
+ export interface ResolvedChildActivity {
169
+ id: string;
170
+ name: string;
171
+ activity_type?: string;
172
+ start_date?: string;
173
+ end_date?: string;
174
+ owner?: string;
175
+ }
176
+
177
+ /** A STAKEHOLDER element linked to the project (via `activity_stakeholder`). */
178
+ export interface ResolvedStakeholder {
179
+ id: string;
180
+ name: string;
181
+ /** internal | external (STAKEHOLDER `type`). */
182
+ type?: string;
183
+ interest?: string;
184
+ influence?: string;
185
+ /**
186
+ * Project role from the `activity_stakeholder` relation:
187
+ * initiator | owner | sponsor | project_manager.
188
+ * Optional — card shows the name without a role badge when absent.
189
+ */
190
+ role?: string;
191
+ }
192
+
193
+ export interface ResolvedActivityCard {
194
+ cardId: string;
195
+ /** The card's own executive-summary description (distinct from the project's). */
196
+ cardDescription?: string;
197
+ project: ResolvedProject;
198
+ /** Sorted ascending by `date`. */
199
+ milestones: ResolvedMilestone[];
200
+ motivation: ResolvedMotivation;
201
+ /**
202
+ * Assessments (pain points) for the in-scope Drivers, sorted by
203
+ * `observed_at` ascending. Empty when no Assessment elements are found —
204
+ * the gap is intentionally visible on the card.
205
+ */
206
+ assessments: ResolvedAssessment[];
207
+ /** Activities whose `parent` = the project Activity id. */
208
+ childActivities: ResolvedChildActivity[];
209
+ /**
210
+ * Names of the GOALs the project DIRECTLY serves (the `activity_goal`
211
+ * targets, not the wider motivation chain) — painted as the "Project goal"
212
+ * text field. Empty when the project serves no goal.
213
+ */
214
+ goalNames?: string[];
215
+ /**
216
+ * Stakeholders linked to the project via active `activity_stakeholder`
217
+ * relations. Empty when none are linked (the card still shows the field
218
+ * with a "—" placeholder).
219
+ */
220
+ stakeholders?: ResolvedStakeholder[];
221
+ /**
222
+ * Supplementary notes for the card footer (from `activity_card.notes` in
223
+ * the view YAML). Not a canonical element field.
224
+ */
225
+ notes?: string;
226
+ }
227
+
228
+ // ── Layout geometry (pure; the preview turns this into SVG) ───────────────────
229
+
230
+ import type { LayoutBounds } from '../geometry.js';
231
+ export type { LayoutBounds };
232
+
233
+ /** A boxed value-pair shown in the dates band. */
234
+ export interface DateField {
235
+ label: string;
236
+ value: string;
237
+ x: number;
238
+ y: number;
239
+ width: number;
240
+ height: number;
241
+ }
242
+
243
+ /** A small badge shown in the header (activity type or status). */
244
+ export interface Badge {
245
+ label: string;
246
+ x: number;
247
+ y: number;
248
+ width: number;
249
+ height: number;
250
+ }
251
+
252
+ /** One stakeholder role slot in the header roles row. Always rendered; `name` is "—" when unfilled. */
253
+ export interface StakeholderRoleSlot {
254
+ /** Display label: "Initiator", "Owner", "Sponsor", "PM". */
255
+ role: string;
256
+ /** Stakeholder name or "—". */
257
+ name: string;
258
+ x: number;
259
+ y: number;
260
+ width: number;
261
+ height: number;
262
+ }
263
+
264
+ /** One node in a chain section (driver / assessment / goal / change). */
265
+ export interface ChainNode {
266
+ id: string;
267
+ name: string;
268
+ /** Supplementary text shown below the name (e.g. observed_at date for assessments). */
269
+ meta?: string;
270
+ x: number;
271
+ y: number;
272
+ width: number;
273
+ height: number;
274
+ }
275
+
276
+ /** An edge between two chain nodes (for SVG connectors). */
277
+ export interface ChainEdge {
278
+ sourceId: string;
279
+ targetId: string;
280
+ }
281
+
282
+ /**
283
+ * One vertical section of the body chain: Drivers | Assessments | Goals | Changes.
284
+ * When `isEmpty` is true the section has no nodes and renders a gap indicator
285
+ * so the author sees the missing data.
286
+ */
287
+ export interface ChainSectionLayout {
288
+ type: 'drivers' | 'assessments' | 'goals' | 'changes';
289
+ /** Section header label. */
290
+ label: string;
291
+ /** Short question answered by this section, shown in grey after the label. */
292
+ subtitle: string;
293
+ nodes: ChainNode[];
294
+ isEmpty: boolean;
295
+ x: number;
296
+ y: number;
297
+ width: number;
298
+ height: number;
299
+ }
300
+
301
+ /** One milestone marker. */
302
+ export interface MilestoneMarker {
303
+ id: string;
304
+ name: string;
305
+ date: string;
306
+ /** ArchiMate class label appended by the renderer (§5.1). */
307
+ archimateClass: string;
308
+ x: number;
309
+ y: number;
310
+ width: number;
311
+ height: number;
312
+ }
313
+
314
+ /**
315
+ * A labeled, full-width text row with wrapped value lines.
316
+ * Used for the Description (body) and Notes (footer).
317
+ */
318
+ export interface InfoRow {
319
+ label: string;
320
+ valueLines: string[];
321
+ x: number;
322
+ y: number;
323
+ width: number;
324
+ height: number;
325
+ }
326
+
327
+ export interface ChildActivityRow {
328
+ id: string;
329
+ name: string;
330
+ /** ArchiMate class label appended by the renderer (§5.1). */
331
+ archimateClass: string;
332
+ meta: string;
333
+ x: number;
334
+ y: number;
335
+ width: number;
336
+ height: number;
337
+ }
338
+
339
+ export interface ActivityCardLayoutOptions {
340
+ /** Outer card width (px). */
341
+ cardWidth?: number;
342
+ /** Vertical gap (px) between stacked rows within a section. */
343
+ rowGap?: number;
344
+ }
345
+
346
+ export interface ActivityCardLayout {
347
+ bounds: LayoutBounds;
348
+
349
+ // ── Header ────────────────────────────────────────────────────────────────
350
+ /** Project name, positioned in the title row. */
351
+ titleRow: { name: string; x: number; y: number };
352
+ /** Activity-type badge (programme / project / workstream / task). Absent when field is unset. */
353
+ activityTypeBadge?: Badge;
354
+ /** Status badge (planned / in_progress / on_track / …). Absent when field is unset. */
355
+ statusBadge?: Badge;
356
+ /** Three date cells: Initiation, Planned start, Planned end. */
357
+ dateFields: DateField[];
358
+ /** Four role slots always rendered: Initiator, Owner, Sponsor, PM. Name is "—" when unfilled. */
359
+ stakeholderRoleSlots: StakeholderRoleSlot[];
360
+
361
+ // ── Body ──────────────────────────────────────────────────────────────────
362
+ /** Executive-summary description row. Absent when `cardDescription` is empty. */
363
+ descriptionRow?: InfoRow;
364
+ /** Vertical chain: Drivers → Assessments → Goals → Changes. */
365
+ chainSections: ChainSectionLayout[];
366
+ /** Node-level edges within the chain (driver→assessment, driver→goal, goal→change). */
367
+ chainEdges: ChainEdge[];
368
+ /** Milestone markers below the chain, wrapped left→right by date. */
369
+ milestones: MilestoneMarker[];
370
+ /** Child activities below milestones. */
371
+ childActivities: ChildActivityRow[];
372
+
373
+ // ── Footer ────────────────────────────────────────────────────────────────
374
+ /** Notes row from `activity_card.notes`. Absent when empty. */
375
+ footerRow?: InfoRow;
376
+ }