@transitrix/diagrams 1.0.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 (541) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/dist/__tests__/edge-path.test.d.ts +1 -0
  4. package/dist/__tests__/edge-path.test.js +39 -0
  5. package/dist/__tests__/scope.test.d.ts +1 -0
  6. package/dist/__tests__/scope.test.js +23 -0
  7. package/dist/__tests__/yaml-normalize.test.d.ts +1 -0
  8. package/dist/__tests__/yaml-normalize.test.js +148 -0
  9. package/dist/activities/__tests__/cpm.test.d.ts +1 -0
  10. package/dist/activities/__tests__/cpm.test.js +146 -0
  11. package/dist/activities/__tests__/gantt.test.d.ts +1 -0
  12. package/dist/activities/__tests__/gantt.test.js +224 -0
  13. package/dist/activities/__tests__/layout.test.d.ts +1 -0
  14. package/dist/activities/__tests__/layout.test.js +98 -0
  15. package/dist/activities/__tests__/validate.test.d.ts +1 -0
  16. package/dist/activities/__tests__/validate.test.js +363 -0
  17. package/dist/activities/cpm.d.ts +2 -0
  18. package/dist/activities/cpm.js +86 -0
  19. package/dist/activities/gantt.d.ts +6 -0
  20. package/dist/activities/gantt.js +250 -0
  21. package/dist/activities/index.d.ts +5 -0
  22. package/dist/activities/index.js +4 -0
  23. package/dist/activities/layout.d.ts +2 -0
  24. package/dist/activities/layout.js +103 -0
  25. package/dist/activities/types.d.ts +125 -0
  26. package/dist/activities/types.js +1 -0
  27. package/dist/activities/validate.d.ts +2 -0
  28. package/dist/activities/validate.js +326 -0
  29. package/dist/activity-card/__tests__/example.test.d.ts +1 -0
  30. package/dist/activity-card/__tests__/example.test.js +56 -0
  31. package/dist/activity-card/__tests__/layout.test.d.ts +1 -0
  32. package/dist/activity-card/__tests__/layout.test.js +57 -0
  33. package/dist/activity-card/__tests__/resolver.test.d.ts +1 -0
  34. package/dist/activity-card/__tests__/resolver.test.js +146 -0
  35. package/dist/activity-card/__tests__/validate.test.d.ts +1 -0
  36. package/dist/activity-card/__tests__/validate.test.js +116 -0
  37. package/dist/activity-card/index.d.ts +5 -0
  38. package/dist/activity-card/index.js +3 -0
  39. package/dist/activity-card/layout.d.ts +7 -0
  40. package/dist/activity-card/layout.js +167 -0
  41. package/dist/activity-card/resolver.d.ts +7 -0
  42. package/dist/activity-card/resolver.js +310 -0
  43. package/dist/activity-card/types.d.ts +175 -0
  44. package/dist/activity-card/types.js +20 -0
  45. package/dist/activity-card/validate.d.ts +3 -0
  46. package/dist/activity-card/validate.js +145 -0
  47. package/dist/actor/__tests__/validate.test.d.ts +1 -0
  48. package/dist/actor/__tests__/validate.test.js +57 -0
  49. package/dist/actor/index.d.ts +3 -0
  50. package/dist/actor/index.js +2 -0
  51. package/dist/actor/types.d.ts +20 -0
  52. package/dist/actor/types.js +4 -0
  53. package/dist/actor/validate.d.ts +2 -0
  54. package/dist/actor/validate.js +34 -0
  55. package/dist/applications/__tests__/validate.test.d.ts +1 -0
  56. package/dist/applications/__tests__/validate.test.js +223 -0
  57. package/dist/applications/index.d.ts +2 -0
  58. package/dist/applications/index.js +1 -0
  59. package/dist/applications/types.d.ts +39 -0
  60. package/dist/applications/types.js +1 -0
  61. package/dist/applications/validate.d.ts +3 -0
  62. package/dist/applications/validate.js +109 -0
  63. package/dist/assertion/__tests__/example.test.d.ts +1 -0
  64. package/dist/assertion/__tests__/example.test.js +32 -0
  65. package/dist/assertion/__tests__/validate.test.d.ts +1 -0
  66. package/dist/assertion/__tests__/validate.test.js +130 -0
  67. package/dist/assertion/index.d.ts +4 -0
  68. package/dist/assertion/index.js +2 -0
  69. package/dist/assertion/types.d.ts +43 -0
  70. package/dist/assertion/types.js +7 -0
  71. package/dist/assertion/validate.d.ts +9 -0
  72. package/dist/assertion/validate.js +137 -0
  73. package/dist/blocks/__tests__/layout.test.d.ts +1 -0
  74. package/dist/blocks/__tests__/layout.test.js +153 -0
  75. package/dist/blocks/__tests__/validate.test.d.ts +1 -0
  76. package/dist/blocks/__tests__/validate.test.js +235 -0
  77. package/dist/blocks/index.d.ts +4 -0
  78. package/dist/blocks/index.js +2 -0
  79. package/dist/blocks/layout.d.ts +4 -0
  80. package/dist/blocks/layout.js +145 -0
  81. package/dist/blocks/types.d.ts +56 -0
  82. package/dist/blocks/types.js +1 -0
  83. package/dist/blocks/validate.d.ts +9 -0
  84. package/dist/blocks/validate.js +186 -0
  85. package/dist/capability-map/__tests__/validate.test.d.ts +1 -0
  86. package/dist/capability-map/__tests__/validate.test.js +212 -0
  87. package/dist/capability-map/index.d.ts +2 -0
  88. package/dist/capability-map/index.js +1 -0
  89. package/dist/capability-map/types.d.ts +26 -0
  90. package/dist/capability-map/types.js +1 -0
  91. package/dist/capability-map/validate.d.ts +3 -0
  92. package/dist/capability-map/validate.js +103 -0
  93. package/dist/change/__tests__/validate.test.d.ts +1 -0
  94. package/dist/change/__tests__/validate.test.js +73 -0
  95. package/dist/change/index.d.ts +2 -0
  96. package/dist/change/index.js +1 -0
  97. package/dist/change/types.d.ts +17 -0
  98. package/dist/change/types.js +3 -0
  99. package/dist/change/validate.d.ts +2 -0
  100. package/dist/change/validate.js +57 -0
  101. package/dist/compliance/__tests__/classify.test.d.ts +1 -0
  102. package/dist/compliance/__tests__/classify.test.js +24 -0
  103. package/dist/compliance/__tests__/confidence.test.d.ts +1 -0
  104. package/dist/compliance/__tests__/confidence.test.js +78 -0
  105. package/dist/compliance/__tests__/coverage-metric.test.d.ts +1 -0
  106. package/dist/compliance/__tests__/coverage-metric.test.js +164 -0
  107. package/dist/compliance/__tests__/demo-scenario.test.d.ts +1 -0
  108. package/dist/compliance/__tests__/demo-scenario.test.js +226 -0
  109. package/dist/compliance/__tests__/example.test.d.ts +1 -0
  110. package/dist/compliance/__tests__/example.test.js +51 -0
  111. package/dist/compliance/__tests__/gap-report.test.d.ts +1 -0
  112. package/dist/compliance/__tests__/gap-report.test.js +113 -0
  113. package/dist/compliance/__tests__/html.test.d.ts +1 -0
  114. package/dist/compliance/__tests__/html.test.js +122 -0
  115. package/dist/compliance/__tests__/impact.test.d.ts +1 -0
  116. package/dist/compliance/__tests__/impact.test.js +410 -0
  117. package/dist/compliance/__tests__/markdown.test.d.ts +1 -0
  118. package/dist/compliance/__tests__/markdown.test.js +85 -0
  119. package/dist/compliance/__tests__/views.test.d.ts +1 -0
  120. package/dist/compliance/__tests__/views.test.js +59 -0
  121. package/dist/compliance/classify.d.ts +27 -0
  122. package/dist/compliance/classify.js +60 -0
  123. package/dist/compliance/confidence.d.ts +27 -0
  124. package/dist/compliance/confidence.js +43 -0
  125. package/dist/compliance/coverage-metric.d.ts +74 -0
  126. package/dist/compliance/coverage-metric.js +181 -0
  127. package/dist/compliance/gap-report.d.ts +20 -0
  128. package/dist/compliance/gap-report.js +64 -0
  129. package/dist/compliance/html.d.ts +22 -0
  130. package/dist/compliance/html.js +256 -0
  131. package/dist/compliance/impact.d.ts +251 -0
  132. package/dist/compliance/impact.js +464 -0
  133. package/dist/compliance/index.d.ts +16 -0
  134. package/dist/compliance/index.js +9 -0
  135. package/dist/compliance/markdown.d.ts +18 -0
  136. package/dist/compliance/markdown.js +129 -0
  137. package/dist/compliance/reverse-index.d.ts +8 -0
  138. package/dist/compliance/reverse-index.js +30 -0
  139. package/dist/compliance/types.d.ts +98 -0
  140. package/dist/compliance/types.js +5 -0
  141. package/dist/compliance/views.d.ts +14 -0
  142. package/dist/compliance/views.js +35 -0
  143. package/dist/compliance-matrix/__tests__/build.test.d.ts +1 -0
  144. package/dist/compliance-matrix/__tests__/build.test.js +183 -0
  145. package/dist/compliance-matrix/__tests__/example.test.d.ts +1 -0
  146. package/dist/compliance-matrix/__tests__/example.test.js +49 -0
  147. package/dist/compliance-matrix/build.d.ts +18 -0
  148. package/dist/compliance-matrix/build.js +0 -0
  149. package/dist/compliance-matrix/index.d.ts +2 -0
  150. package/dist/compliance-matrix/index.js +1 -0
  151. package/dist/compliance-matrix/types.d.ts +86 -0
  152. package/dist/compliance-matrix/types.js +8 -0
  153. package/dist/confidence/__tests__/score.test.d.ts +1 -0
  154. package/dist/confidence/__tests__/score.test.js +188 -0
  155. package/dist/confidence/index.d.ts +2 -0
  156. package/dist/confidence/index.js +1 -0
  157. package/dist/confidence/score.d.ts +62 -0
  158. package/dist/confidence/score.js +215 -0
  159. package/dist/confidence/types.d.ts +79 -0
  160. package/dist/confidence/types.js +6 -0
  161. package/dist/edge-path.d.ts +18 -0
  162. package/dist/edge-path.js +35 -0
  163. package/dist/element-envelope.d.ts +15 -0
  164. package/dist/element-envelope.js +55 -0
  165. package/dist/factor/__tests__/validate.test.d.ts +1 -0
  166. package/dist/factor/__tests__/validate.test.js +83 -0
  167. package/dist/factor/index.d.ts +3 -0
  168. package/dist/factor/index.js +2 -0
  169. package/dist/factor/types.d.ts +23 -0
  170. package/dist/factor/types.js +6 -0
  171. package/dist/factor/validate.d.ts +2 -0
  172. package/dist/factor/validate.js +69 -0
  173. package/dist/fgca/__tests__/chain-table.test.d.ts +1 -0
  174. package/dist/fgca/__tests__/chain-table.test.js +158 -0
  175. package/dist/fgca/__tests__/layout.test.d.ts +1 -0
  176. package/dist/fgca/__tests__/layout.test.js +140 -0
  177. package/dist/fgca/__tests__/parse-canonical.test.d.ts +1 -0
  178. package/dist/fgca/__tests__/parse-canonical.test.js +224 -0
  179. package/dist/fgca/__tests__/preview-layout.test.d.ts +1 -0
  180. package/dist/fgca/__tests__/preview-layout.test.js +106 -0
  181. package/dist/fgca/__tests__/validate.test.d.ts +1 -0
  182. package/dist/fgca/__tests__/validate.test.js +125 -0
  183. package/dist/fgca/chain-table.d.ts +36 -0
  184. package/dist/fgca/chain-table.js +177 -0
  185. package/dist/fgca/index.d.ts +16 -0
  186. package/dist/fgca/index.js +11 -0
  187. package/dist/fgca/layout.d.ts +27 -0
  188. package/dist/fgca/layout.js +156 -0
  189. package/dist/fgca/nodeTypes.d.ts +6 -0
  190. package/dist/fgca/nodeTypes.js +10 -0
  191. package/dist/fgca/nodes/FGCAActivityNode.d.ts +13 -0
  192. package/dist/fgca/nodes/FGCAActivityNode.js +35 -0
  193. package/dist/fgca/nodes/FGCAChangeNode.d.ts +12 -0
  194. package/dist/fgca/nodes/FGCAChangeNode.js +35 -0
  195. package/dist/fgca/nodes/FGCAFactorNode.d.ts +12 -0
  196. package/dist/fgca/nodes/FGCAFactorNode.js +35 -0
  197. package/dist/fgca/nodes/FGCAGoalNode.d.ts +14 -0
  198. package/dist/fgca/nodes/FGCAGoalNode.js +40 -0
  199. package/dist/fgca/parse-canonical.d.ts +58 -0
  200. package/dist/fgca/parse-canonical.js +339 -0
  201. package/dist/fgca/preview-layout.d.ts +87 -0
  202. package/dist/fgca/preview-layout.js +122 -0
  203. package/dist/fgca/types.d.ts +39 -0
  204. package/dist/fgca/types.js +7 -0
  205. package/dist/fgca/validate.d.ts +14 -0
  206. package/dist/fgca/validate.js +108 -0
  207. package/dist/geometry.d.ts +7 -0
  208. package/dist/geometry.js +2 -0
  209. package/dist/goals/__tests__/layout.test.d.ts +1 -0
  210. package/dist/goals/__tests__/layout.test.js +153 -0
  211. package/dist/goals/__tests__/mutations.test.d.ts +1 -0
  212. package/dist/goals/__tests__/mutations.test.js +95 -0
  213. package/dist/goals/__tests__/parse-canonical.test.d.ts +1 -0
  214. package/dist/goals/__tests__/parse-canonical.test.js +129 -0
  215. package/dist/goals/__tests__/validate.test.d.ts +1 -0
  216. package/dist/goals/__tests__/validate.test.js +183 -0
  217. package/dist/goals/index.d.ts +6 -0
  218. package/dist/goals/index.js +4 -0
  219. package/dist/goals/layout.d.ts +11 -0
  220. package/dist/goals/layout.js +147 -0
  221. package/dist/goals/mutations.d.ts +6 -0
  222. package/dist/goals/mutations.js +116 -0
  223. package/dist/goals/parse-canonical.d.ts +29 -0
  224. package/dist/goals/parse-canonical.js +257 -0
  225. package/dist/goals/types.d.ts +71 -0
  226. package/dist/goals/types.js +1 -0
  227. package/dist/goals/validate.d.ts +2 -0
  228. package/dist/goals/validate.js +122 -0
  229. package/dist/index.d.ts +23 -0
  230. package/dist/index.js +23 -0
  231. package/dist/issues/__tests__/layout.test.d.ts +1 -0
  232. package/dist/issues/__tests__/layout.test.js +62 -0
  233. package/dist/issues/__tests__/validate.test.d.ts +1 -0
  234. package/dist/issues/__tests__/validate.test.js +82 -0
  235. package/dist/issues/index.d.ts +4 -0
  236. package/dist/issues/index.js +2 -0
  237. package/dist/issues/layout.d.ts +10 -0
  238. package/dist/issues/layout.js +82 -0
  239. package/dist/issues/types.d.ts +61 -0
  240. package/dist/issues/types.js +6 -0
  241. package/dist/issues/validate.d.ts +3 -0
  242. package/dist/issues/validate.js +143 -0
  243. package/dist/process-blueprint/__tests__/compliance-lane.test.d.ts +1 -0
  244. package/dist/process-blueprint/__tests__/compliance-lane.test.js +272 -0
  245. package/dist/process-blueprint/__tests__/layout.test.d.ts +1 -0
  246. package/dist/process-blueprint/__tests__/layout.test.js +159 -0
  247. package/dist/process-blueprint/__tests__/validate.test.d.ts +1 -0
  248. package/dist/process-blueprint/__tests__/validate.test.js +280 -0
  249. package/dist/process-blueprint/index.d.ts +4 -0
  250. package/dist/process-blueprint/index.js +2 -0
  251. package/dist/process-blueprint/layout.d.ts +2 -0
  252. package/dist/process-blueprint/layout.js +416 -0
  253. package/dist/process-blueprint/types.d.ts +220 -0
  254. package/dist/process-blueprint/types.js +1 -0
  255. package/dist/process-blueprint/validate.d.ts +3 -0
  256. package/dist/process-blueprint/validate.js +165 -0
  257. package/dist/process-map/__tests__/validate.test.d.ts +1 -0
  258. package/dist/process-map/__tests__/validate.test.js +199 -0
  259. package/dist/process-map/index.d.ts +2 -0
  260. package/dist/process-map/index.js +1 -0
  261. package/dist/process-map/types.d.ts +32 -0
  262. package/dist/process-map/types.js +1 -0
  263. package/dist/process-map/validate.d.ts +3 -0
  264. package/dist/process-map/validate.js +115 -0
  265. package/dist/products/__tests__/validate.test.d.ts +1 -0
  266. package/dist/products/__tests__/validate.test.js +210 -0
  267. package/dist/products/index.d.ts +2 -0
  268. package/dist/products/index.js +1 -0
  269. package/dist/products/types.d.ts +28 -0
  270. package/dist/products/types.js +1 -0
  271. package/dist/products/validate.d.ts +3 -0
  272. package/dist/products/validate.js +93 -0
  273. package/dist/repo-validate/__tests__/validate-repo.test.d.ts +1 -0
  274. package/dist/repo-validate/__tests__/validate-repo.test.js +132 -0
  275. package/dist/repo-validate/index.d.ts +2 -0
  276. package/dist/repo-validate/index.js +1 -0
  277. package/dist/repo-validate/types.d.ts +34 -0
  278. package/dist/repo-validate/types.js +14 -0
  279. package/dist/repo-validate/validate-repo.d.ts +8 -0
  280. package/dist/repo-validate/validate-repo.js +189 -0
  281. package/dist/requirement/__tests__/example.test.d.ts +1 -0
  282. package/dist/requirement/__tests__/example.test.js +21 -0
  283. package/dist/requirement/__tests__/validate.test.d.ts +1 -0
  284. package/dist/requirement/__tests__/validate.test.js +80 -0
  285. package/dist/requirement/index.d.ts +4 -0
  286. package/dist/requirement/index.js +2 -0
  287. package/dist/requirement/types.d.ts +25 -0
  288. package/dist/requirement/types.js +4 -0
  289. package/dist/requirement/validate.d.ts +7 -0
  290. package/dist/requirement/validate.js +81 -0
  291. package/dist/scenarios/__tests__/validate.test.d.ts +1 -0
  292. package/dist/scenarios/__tests__/validate.test.js +183 -0
  293. package/dist/scenarios/index.d.ts +2 -0
  294. package/dist/scenarios/index.js +1 -0
  295. package/dist/scenarios/types.d.ts +45 -0
  296. package/dist/scenarios/types.js +1 -0
  297. package/dist/scenarios/validate.d.ts +3 -0
  298. package/dist/scenarios/validate.js +110 -0
  299. package/dist/schema-version.d.ts +16 -0
  300. package/dist/schema-version.js +16 -0
  301. package/dist/scope.d.ts +23 -0
  302. package/dist/scope.js +38 -0
  303. package/dist/stakeholder/__tests__/validate.test.d.ts +1 -0
  304. package/dist/stakeholder/__tests__/validate.test.js +86 -0
  305. package/dist/stakeholder/index.d.ts +3 -0
  306. package/dist/stakeholder/index.js +2 -0
  307. package/dist/stakeholder/types.d.ts +24 -0
  308. package/dist/stakeholder/types.js +5 -0
  309. package/dist/stakeholder/validate.d.ts +2 -0
  310. package/dist/stakeholder/validate.js +58 -0
  311. package/dist/target-state/__tests__/validate.test.d.ts +1 -0
  312. package/dist/target-state/__tests__/validate.test.js +62 -0
  313. package/dist/target-state/index.d.ts +2 -0
  314. package/dist/target-state/index.js +1 -0
  315. package/dist/target-state/types.d.ts +18 -0
  316. package/dist/target-state/types.js +7 -0
  317. package/dist/target-state/validate.d.ts +2 -0
  318. package/dist/target-state/validate.js +61 -0
  319. package/dist/theme/index.d.ts +4 -0
  320. package/dist/theme/index.js +2 -0
  321. package/dist/theme/themes.d.ts +16 -0
  322. package/dist/theme/themes.js +213 -0
  323. package/dist/theme/tokens.d.ts +158 -0
  324. package/dist/theme/tokens.js +105 -0
  325. package/dist/typed-id.d.ts +20 -0
  326. package/dist/typed-id.js +38 -0
  327. package/dist/validation-types.d.ts +34 -0
  328. package/dist/validation-types.js +1 -0
  329. package/dist/webview/__tests__/entry-notations.test.d.ts +1 -0
  330. package/dist/webview/__tests__/entry-notations.test.js +62 -0
  331. package/dist/webview/__tests__/entry.test.d.ts +1 -0
  332. package/dist/webview/__tests__/entry.test.js +56 -0
  333. package/dist/webview/__tests__/render-goals.test.d.ts +1 -0
  334. package/dist/webview/__tests__/render-goals.test.js +65 -0
  335. package/dist/webview/entry.d.ts +38 -0
  336. package/dist/webview/entry.js +182 -0
  337. package/dist/webview/render-activities.d.ts +24 -0
  338. package/dist/webview/render-activities.js +127 -0
  339. package/dist/webview/render-activity-card.d.ts +5 -0
  340. package/dist/webview/render-activity-card.js +168 -0
  341. package/dist/webview/render-applications.d.ts +11 -0
  342. package/dist/webview/render-applications.js +105 -0
  343. package/dist/webview/render-blocks.d.ts +5 -0
  344. package/dist/webview/render-blocks.js +71 -0
  345. package/dist/webview/render-capability-map.d.ts +7 -0
  346. package/dist/webview/render-capability-map.js +88 -0
  347. package/dist/webview/render-fgca.d.ts +8 -0
  348. package/dist/webview/render-fgca.js +94 -0
  349. package/dist/webview/render-goals.d.ts +6 -0
  350. package/dist/webview/render-goals.js +92 -0
  351. package/dist/webview/render-process-blueprint.d.ts +5 -0
  352. package/dist/webview/render-process-blueprint.js +135 -0
  353. package/dist/webview/render-process-map.d.ts +7 -0
  354. package/dist/webview/render-process-map.js +82 -0
  355. package/dist/webview/render-products.d.ts +7 -0
  356. package/dist/webview/render-products.js +81 -0
  357. package/dist/webview/render-scenarios.d.ts +7 -0
  358. package/dist/webview/render-scenarios.js +75 -0
  359. package/dist/webview/render-util.d.ts +16 -0
  360. package/dist/webview/render-util.js +31 -0
  361. package/dist/webview/transitrix-render.css +323 -0
  362. package/dist/webview/transitrix-render.js +6452 -0
  363. package/dist/webview/transitrix-render.js.map +7 -0
  364. package/dist/yaml-normalize.d.ts +20 -0
  365. package/dist/yaml-normalize.js +57 -0
  366. package/package.json +40 -0
  367. package/src/__tests__/edge-path.test.ts +46 -0
  368. package/src/__tests__/scope.test.ts +27 -0
  369. package/src/__tests__/yaml-normalize.test.ts +158 -0
  370. package/src/activities/__tests__/cpm.test.ts +164 -0
  371. package/src/activities/__tests__/gantt.test.ts +245 -0
  372. package/src/activities/__tests__/layout.test.ts +112 -0
  373. package/src/activities/__tests__/validate.test.ts +409 -0
  374. package/src/activities/cpm.ts +95 -0
  375. package/src/activities/gantt.ts +276 -0
  376. package/src/activities/index.ts +28 -0
  377. package/src/activities/layout.ts +112 -0
  378. package/src/activities/types.ts +148 -0
  379. package/src/activities/validate.ts +357 -0
  380. package/src/activity-card/__tests__/example.test.ts +66 -0
  381. package/src/activity-card/__tests__/layout.test.ts +63 -0
  382. package/src/activity-card/__tests__/resolver.test.ts +161 -0
  383. package/src/activity-card/__tests__/validate.test.ts +131 -0
  384. package/src/activity-card/index.ts +32 -0
  385. package/src/activity-card/layout.ts +194 -0
  386. package/src/activity-card/resolver.ts +337 -0
  387. package/src/activity-card/types.ts +237 -0
  388. package/src/activity-card/validate.ts +158 -0
  389. package/src/actor/__tests__/validate.test.ts +67 -0
  390. package/src/actor/index.ts +3 -0
  391. package/src/actor/types.ts +29 -0
  392. package/src/actor/validate.ts +38 -0
  393. package/src/applications/__tests__/validate.test.ts +256 -0
  394. package/src/applications/index.ts +11 -0
  395. package/src/applications/types.ts +43 -0
  396. package/src/applications/validate.ts +131 -0
  397. package/src/assertion/__tests__/example.test.ts +37 -0
  398. package/src/assertion/__tests__/validate.test.ts +142 -0
  399. package/src/assertion/index.ts +12 -0
  400. package/src/assertion/types.ts +58 -0
  401. package/src/assertion/validate.ts +145 -0
  402. package/src/blocks/__tests__/layout.test.ts +169 -0
  403. package/src/blocks/__tests__/validate.test.ts +260 -0
  404. package/src/blocks/index.ts +17 -0
  405. package/src/blocks/layout.ts +186 -0
  406. package/src/blocks/types.ts +62 -0
  407. package/src/blocks/validate.ts +206 -0
  408. package/src/capability-map/__tests__/validate.test.ts +238 -0
  409. package/src/capability-map/index.ts +8 -0
  410. package/src/capability-map/types.ts +29 -0
  411. package/src/capability-map/validate.ts +127 -0
  412. package/src/change/__tests__/validate.test.ts +88 -0
  413. package/src/change/index.ts +2 -0
  414. package/src/change/types.ts +23 -0
  415. package/src/change/validate.ts +61 -0
  416. package/src/compliance/__tests__/classify.test.ts +27 -0
  417. package/src/compliance/__tests__/confidence.test.ts +98 -0
  418. package/src/compliance/__tests__/coverage-metric.test.ts +188 -0
  419. package/src/compliance/__tests__/demo-scenario.test.ts +273 -0
  420. package/src/compliance/__tests__/example.test.ts +57 -0
  421. package/src/compliance/__tests__/gap-report.test.ts +129 -0
  422. package/src/compliance/__tests__/html.test.ts +142 -0
  423. package/src/compliance/__tests__/impact.test.ts +482 -0
  424. package/src/compliance/__tests__/markdown.test.ts +95 -0
  425. package/src/compliance/__tests__/views.test.ts +64 -0
  426. package/src/compliance/classify.ts +84 -0
  427. package/src/compliance/confidence.ts +69 -0
  428. package/src/compliance/coverage-metric.ts +263 -0
  429. package/src/compliance/gap-report.ts +94 -0
  430. package/src/compliance/html.ts +295 -0
  431. package/src/compliance/impact.ts +677 -0
  432. package/src/compliance/index.ts +56 -0
  433. package/src/compliance/markdown.ts +135 -0
  434. package/src/compliance/reverse-index.ts +33 -0
  435. package/src/compliance/types.ts +120 -0
  436. package/src/compliance/views.ts +46 -0
  437. package/src/compliance-matrix/__tests__/build.test.ts +200 -0
  438. package/src/compliance-matrix/__tests__/example.test.ts +57 -0
  439. package/src/compliance-matrix/build.ts +0 -0
  440. package/src/compliance-matrix/index.ts +11 -0
  441. package/src/compliance-matrix/types.ts +102 -0
  442. package/src/confidence/__tests__/score.test.ts +254 -0
  443. package/src/confidence/index.ts +21 -0
  444. package/src/confidence/score.ts +243 -0
  445. package/src/confidence/types.ts +96 -0
  446. package/src/edge-path.ts +44 -0
  447. package/src/element-envelope.ts +76 -0
  448. package/src/factor/__tests__/validate.test.ts +98 -0
  449. package/src/factor/index.ts +8 -0
  450. package/src/factor/types.ts +41 -0
  451. package/src/factor/validate.ts +74 -0
  452. package/src/fgca/__tests__/chain-table.test.ts +172 -0
  453. package/src/fgca/__tests__/layout.test.ts +179 -0
  454. package/src/fgca/__tests__/parse-canonical.test.ts +248 -0
  455. package/src/fgca/__tests__/preview-layout.test.ts +124 -0
  456. package/src/fgca/__tests__/validate.test.ts +142 -0
  457. package/src/fgca/chain-table.ts +225 -0
  458. package/src/fgca/index.ts +45 -0
  459. package/src/fgca/layout.ts +204 -0
  460. package/src/fgca/nodeTypes.ts +11 -0
  461. package/src/fgca/nodes/FGCAActivityNode.tsx +65 -0
  462. package/src/fgca/nodes/FGCAChangeNode.tsx +64 -0
  463. package/src/fgca/nodes/FGCAFactorNode.tsx +64 -0
  464. package/src/fgca/nodes/FGCAGoalNode.tsx +72 -0
  465. package/src/fgca/parse-canonical.ts +400 -0
  466. package/src/fgca/preview-layout.ts +217 -0
  467. package/src/fgca/types.ts +50 -0
  468. package/src/fgca/validate.ts +126 -0
  469. package/src/geometry.ts +9 -0
  470. package/src/goals/__tests__/layout.test.ts +175 -0
  471. package/src/goals/__tests__/mutations.test.ts +111 -0
  472. package/src/goals/__tests__/parse-canonical.test.ts +145 -0
  473. package/src/goals/__tests__/validate.test.ts +202 -0
  474. package/src/goals/index.ts +21 -0
  475. package/src/goals/layout.ts +172 -0
  476. package/src/goals/mutations.ts +123 -0
  477. package/src/goals/parse-canonical.ts +286 -0
  478. package/src/goals/types.ts +85 -0
  479. package/src/goals/validate.ts +136 -0
  480. package/src/index.ts +23 -0
  481. package/src/process-blueprint/__tests__/compliance-lane.test.ts +320 -0
  482. package/src/process-blueprint/__tests__/layout.test.ts +195 -0
  483. package/src/process-blueprint/__tests__/validate.test.ts +310 -0
  484. package/src/process-blueprint/index.ts +31 -0
  485. package/src/process-blueprint/layout.ts +531 -0
  486. package/src/process-blueprint/types.ts +242 -0
  487. package/src/process-blueprint/validate.ts +181 -0
  488. package/src/process-map/__tests__/validate.test.ts +223 -0
  489. package/src/process-map/index.ts +10 -0
  490. package/src/process-map/types.ts +36 -0
  491. package/src/process-map/validate.ts +135 -0
  492. package/src/products/__tests__/validate.test.ts +239 -0
  493. package/src/products/index.ts +9 -0
  494. package/src/products/types.ts +31 -0
  495. package/src/products/validate.ts +112 -0
  496. package/src/repo-validate/__tests__/validate-repo.test.ts +149 -0
  497. package/src/repo-validate/index.ts +2 -0
  498. package/src/repo-validate/types.ts +50 -0
  499. package/src/repo-validate/validate-repo.ts +196 -0
  500. package/src/requirement/__tests__/example.test.ts +24 -0
  501. package/src/requirement/__tests__/validate.test.ts +96 -0
  502. package/src/requirement/index.ts +4 -0
  503. package/src/requirement/types.ts +35 -0
  504. package/src/requirement/validate.ts +92 -0
  505. package/src/scenarios/__tests__/validate.test.ts +209 -0
  506. package/src/scenarios/index.ts +15 -0
  507. package/src/scenarios/types.ts +37 -0
  508. package/src/scenarios/validate.ts +122 -0
  509. package/src/schema-version.ts +16 -0
  510. package/src/scope.ts +46 -0
  511. package/src/stakeholder/__tests__/validate.test.ts +101 -0
  512. package/src/stakeholder/index.ts +3 -0
  513. package/src/stakeholder/types.ts +33 -0
  514. package/src/stakeholder/validate.ts +63 -0
  515. package/src/target-state/__tests__/validate.test.ts +74 -0
  516. package/src/target-state/index.ts +2 -0
  517. package/src/target-state/types.ts +28 -0
  518. package/src/target-state/validate.ts +67 -0
  519. package/src/theme/index.ts +4 -0
  520. package/src/theme/themes.ts +237 -0
  521. package/src/theme/tokens.ts +133 -0
  522. package/src/typed-id.ts +56 -0
  523. package/src/validation-types.ts +36 -0
  524. package/src/webview/__tests__/entry-notations.test.ts +77 -0
  525. package/src/webview/__tests__/entry.test.ts +64 -0
  526. package/src/webview/__tests__/render-goals.test.ts +72 -0
  527. package/src/webview/entry.ts +292 -0
  528. package/src/webview/render-activities.ts +156 -0
  529. package/src/webview/render-activity-card.ts +234 -0
  530. package/src/webview/render-applications.ts +123 -0
  531. package/src/webview/render-blocks.ts +91 -0
  532. package/src/webview/render-capability-map.ts +98 -0
  533. package/src/webview/render-fgca.ts +122 -0
  534. package/src/webview/render-goals.ts +110 -0
  535. package/src/webview/render-process-blueprint.ts +207 -0
  536. package/src/webview/render-process-map.ts +93 -0
  537. package/src/webview/render-products.ts +91 -0
  538. package/src/webview/render-scenarios.ts +90 -0
  539. package/src/webview/render-util.ts +34 -0
  540. package/src/webview/styles.css +323 -0
  541. package/src/yaml-normalize.ts +56 -0
@@ -0,0 +1,464 @@
1
+ // Compliance-impact matrix derivation + markdown renderer
2
+ // (vkgeorgia/strategy#166 — interim renderer; CV-1 view-config wiring
3
+ // per strategy#84 decomposition refresh).
4
+ //
5
+ // Implements the render contract from
6
+ // methodology/notations/views/21-compliance-impact.md §5 at the coarsest grain
7
+ // (`product` columns × `obligation` rows). Stage / task grouping is planned
8
+ // for CV-3a and intentionally out of scope here.
9
+ import { buildComplianceIndex } from './reverse-index.js';
10
+ // ── Pinned defaults ─────────────────────────────────────────────────────────
11
+ /**
12
+ * Explicit defaults for every optional field in ImpactViewConfig.
13
+ *
14
+ * When a view config omits a field, COMPLIANCE_IMPACT_DEFAULTS defines the
15
+ * assumed behaviour. The CLI prints these so re-runs without a full config
16
+ * are auditable ("what I assumed").
17
+ */
18
+ export const COMPLIANCE_IMPACT_DEFAULTS = {
19
+ /** Accept all four active statuses + n_a in cell aggregation. */
20
+ status_display: {
21
+ show: ['compliant', 'partial', 'non_compliant', 'under_review', 'n_a'],
22
+ },
23
+ /** Order rows by canonical REQUIREMENT ID (lexicographic). */
24
+ order_rows_by: 'id',
25
+ /** §5.3 empty-cell labels. */
26
+ empty_cells: {
27
+ no_obligation_label: 'No mapped obligation (current model)',
28
+ no_obligation_applies_label: 'No obligation applies',
29
+ },
30
+ /** Obligation scope: all known REQUIREMENTs in the canon (no filter). */
31
+ obligations: { include: undefined, filter: undefined },
32
+ /** Subjects: empty — must be supplied explicitly in the view config. */
33
+ subjects: { products: [], processes: [] },
34
+ /** Column grain: one column per business object (no stage decomposition). */
35
+ grouping: { columns: 'object' },
36
+ };
37
+ /**
38
+ * Validate and normalise a raw (YAML-parsed) value into an ImpactViewConfig.
39
+ *
40
+ * Accepts both the bare config object and the view-config file shape
41
+ * (`{ view: { id, name, … } }`) — the top-level `view:` wrapper is unwrapped
42
+ * automatically.
43
+ *
44
+ * Every optional field is filled from COMPLIANCE_IMPACT_DEFAULTS, so callers
45
+ * can rely on the returned config being complete without any `??` chains.
46
+ *
47
+ * Returns `{ ok: false, errors }` on schema violations rather than throwing,
48
+ * so the CLI can surface a clean error message without a stack trace.
49
+ */
50
+ export function parseImpactViewConfig(raw) {
51
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
52
+ return { ok: false, errors: ['view config: expected an object at the document root'] };
53
+ }
54
+ const top = raw;
55
+ // Unwrap optional `view:` wrapper (view-config YAML files use this key).
56
+ const v = 'view' in top && top.view && typeof top.view === 'object' && !Array.isArray(top.view)
57
+ ? top.view
58
+ : top;
59
+ const errors = [];
60
+ if (!v.id || typeof v.id !== 'string')
61
+ errors.push('view.id: required string');
62
+ if (!v.name || typeof v.name !== 'string')
63
+ errors.push('view.name: required string');
64
+ if (v.subjects !== undefined && (typeof v.subjects !== 'object' || Array.isArray(v.subjects))) {
65
+ errors.push('view.subjects: expected an object');
66
+ }
67
+ if (errors.length)
68
+ return { ok: false, errors };
69
+ const subjects = v.subjects && typeof v.subjects === 'object' && !Array.isArray(v.subjects)
70
+ ? v.subjects
71
+ : {};
72
+ const obligations = v.obligations && typeof v.obligations === 'object' && !Array.isArray(v.obligations)
73
+ ? v.obligations
74
+ : {};
75
+ const obFilter = obligations.filter && typeof obligations.filter === 'object' && !Array.isArray(obligations.filter)
76
+ ? obligations.filter
77
+ : null;
78
+ const statusDisplay = v.status_display && typeof v.status_display === 'object' && !Array.isArray(v.status_display)
79
+ ? v.status_display
80
+ : {};
81
+ const emptyCells = v.empty_cells && typeof v.empty_cells === 'object' && !Array.isArray(v.empty_cells)
82
+ ? v.empty_cells
83
+ : {};
84
+ const config = {
85
+ id: v.id,
86
+ name: v.name,
87
+ description: typeof v.description === 'string' ? v.description : undefined,
88
+ snapshot_at: typeof v.snapshot_at === 'string' ? v.snapshot_at : undefined,
89
+ subjects: {
90
+ products: Array.isArray(subjects.products)
91
+ ? subjects.products.filter((x) => typeof x === 'string')
92
+ : [...COMPLIANCE_IMPACT_DEFAULTS.subjects.products],
93
+ processes: Array.isArray(subjects.processes)
94
+ ? subjects.processes.filter((x) => typeof x === 'string')
95
+ : [...COMPLIANCE_IMPACT_DEFAULTS.subjects.processes],
96
+ },
97
+ obligations: {
98
+ include: Array.isArray(obligations.include)
99
+ ? obligations.include.filter((x) => typeof x === 'string')
100
+ : undefined,
101
+ filter: obFilter
102
+ ? {
103
+ derived_from_codex: Array.isArray(obFilter.derived_from_codex)
104
+ ? obFilter.derived_from_codex.filter((x) => typeof x === 'string')
105
+ : undefined,
106
+ }
107
+ : undefined,
108
+ },
109
+ status_display: {
110
+ show: Array.isArray(statusDisplay.show)
111
+ ? statusDisplay.show.filter((x) => typeof x === 'string')
112
+ : [...COMPLIANCE_IMPACT_DEFAULTS.status_display.show],
113
+ },
114
+ empty_cells: {
115
+ no_obligation_label: typeof emptyCells.no_obligation_label === 'string'
116
+ ? emptyCells.no_obligation_label
117
+ : COMPLIANCE_IMPACT_DEFAULTS.empty_cells.no_obligation_label,
118
+ no_obligation_applies_label: typeof emptyCells.no_obligation_applies_label === 'string'
119
+ ? emptyCells.no_obligation_applies_label
120
+ : COMPLIANCE_IMPACT_DEFAULTS.empty_cells.no_obligation_applies_label,
121
+ },
122
+ order_rows_by: v.order_rows_by === 'name' ? 'name' : COMPLIANCE_IMPACT_DEFAULTS.order_rows_by,
123
+ };
124
+ return { ok: true, config };
125
+ }
126
+ const DEFAULT_NO_OBLIGATION_LABEL = 'No mapped obligation (current model)';
127
+ const DEFAULT_NO_OBLIGATION_APPLIES_LABEL = 'No obligation applies';
128
+ // ── Deadline temporal status (CV-3) ─────────────────────────────────────────
129
+ /** Number of days within which a deadline is considered "in force" (imminent). */
130
+ const IN_FORCE_HORIZON_DAYS = 30;
131
+ /**
132
+ * Classify a REQUIREMENT deadline relative to a reference date.
133
+ *
134
+ * @param deadline ISO 8601 date string (YYYY-MM-DD), or undefined.
135
+ * @param today Reference date string (YYYY-MM-DD); defaults to today.
136
+ */
137
+ export function computeDeadlineStatus(deadline, today = new Date().toISOString().slice(0, 10)) {
138
+ if (!deadline)
139
+ return 'none';
140
+ if (deadline < today)
141
+ return 'past_due';
142
+ const daysAway = Math.round((new Date(deadline).getTime() - new Date(today).getTime()) / (1000 * 60 * 60 * 24));
143
+ return daysAway <= IN_FORCE_HORIZON_DAYS ? 'in_force' : 'upcoming';
144
+ }
145
+ function byId(a, b) {
146
+ return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
147
+ }
148
+ function resolveObligations(config, index, allRequirements) {
149
+ // `include` wins over `filter` per §4 (and COMPIMP-007).
150
+ if (config.obligations.include?.length) {
151
+ const out = [];
152
+ for (const id of config.obligations.include) {
153
+ const r = index.requirementById.get(id);
154
+ if (r)
155
+ out.push(r);
156
+ }
157
+ return out;
158
+ }
159
+ const codices = config.obligations.filter?.derived_from_codex ?? [];
160
+ if (codices.length === 0)
161
+ return [...allRequirements].sort(byId);
162
+ const seen = new Set();
163
+ const out = [];
164
+ for (const codex of codices) {
165
+ for (const r of index.requirementsByLaw.get(codex) ?? []) {
166
+ if (!seen.has(r.id)) {
167
+ seen.add(r.id);
168
+ out.push(r);
169
+ }
170
+ }
171
+ }
172
+ return out;
173
+ }
174
+ function orderRows(rows, key) {
175
+ const sorted = [...rows];
176
+ if (key === 'name') {
177
+ sorted.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
178
+ }
179
+ else {
180
+ sorted.sort(byId);
181
+ }
182
+ return sorted;
183
+ }
184
+ /** Aggregate multiple matching assertions into one cell value, per §5.2 step 4.
185
+ * Assumes at least one assertion matches an allowed status; caller filters. */
186
+ function aggregateStatus(assertions) {
187
+ let sawPartial = false;
188
+ let sawUnderReview = false;
189
+ let sawCompliant = false;
190
+ for (const a of assertions) {
191
+ if (a.status === 'non_compliant')
192
+ return 'non_compliant';
193
+ if (a.status === 'partial')
194
+ sawPartial = true;
195
+ else if (a.status === 'under_review')
196
+ sawUnderReview = true;
197
+ else if (a.status === 'compliant')
198
+ sawCompliant = true;
199
+ }
200
+ if (sawPartial)
201
+ return 'partial';
202
+ if (sawUnderReview)
203
+ return 'under_review';
204
+ if (sawCompliant)
205
+ return 'compliant';
206
+ return 'n_a';
207
+ }
208
+ // ── Column builder helpers (CV-3a) ──────────────────────────────────────────
209
+ function buildProductColumns(config) {
210
+ const subjects = [...(config.subjects.products ?? []), ...(config.subjects.processes ?? [])];
211
+ return subjects.map(id => ({ subjectId: id, label: id }));
212
+ }
213
+ function buildObjectDetailColumns(config, objectDetails) {
214
+ const detailMap = new Map(objectDetails.map(d => [d.objectId, d.details]));
215
+ const subjects = [...(config.subjects.products ?? []), ...(config.subjects.processes ?? [])];
216
+ const cols = [];
217
+ for (const subjectId of subjects) {
218
+ const details = detailMap.get(subjectId);
219
+ if (!details || details.length === 0) {
220
+ cols.push({ subjectId, label: subjectId });
221
+ }
222
+ else {
223
+ for (const detail of details) {
224
+ cols.push({ subjectId, stageId: detail.id, label: `${subjectId}:${detail.id}` });
225
+ }
226
+ }
227
+ }
228
+ return cols;
229
+ }
230
+ /**
231
+ * Returns true when assertion `a` contributes to column `col`.
232
+ *
233
+ * At `'product'` grain: `a.subject` must match `col.subjectId`.
234
+ * At `'product-stage'` grain: `a.subject` must match AND either
235
+ * `a.realised_via` is absent (claim covers the whole subject, so every stage
236
+ * inherits it) OR `col.stageId` ∈ `a.realised_via`.
237
+ */
238
+ function assertionMatchesColumn(a, col) {
239
+ if (a.subject !== col.subjectId)
240
+ return false;
241
+ if (!col.stageId)
242
+ return true;
243
+ if (!a.realised_via || a.realised_via.length === 0)
244
+ return true;
245
+ return a.realised_via.includes(col.stageId);
246
+ }
247
+ /**
248
+ * Build the matrix per §5.2.
249
+ *
250
+ * At the default `grouping.columns: 'product'` grain, one column per subject.
251
+ * At `grouping.columns: 'product-stage'`, pass `objectDetails` to expand each
252
+ * subject into per-stage sub-columns (typically extracted from a
253
+ * process-blueprint document via `extractObjectDetails`). Subjects with no
254
+ * stage mapping fall back to a single product-grain column automatically.
255
+ *
256
+ * Subjects are taken from `config.subjects.products` and
257
+ * `config.subjects.processes` (in that order). Subjects with no binding
258
+ * obligation still appear as columns so the gap is visible.
259
+ */
260
+ export function buildImpactMatrix(canon, config, objectDetails) {
261
+ const index = buildComplianceIndex({
262
+ requirements: canon.requirements,
263
+ assertions: canon.assertions,
264
+ });
265
+ const obligations = orderRows(resolveObligations(config, index, canon.requirements), config.order_rows_by);
266
+ const useStageGrain = config.grouping?.columns === 'object-details' && objectDetails && objectDetails.length > 0;
267
+ const columns = useStageGrain
268
+ ? buildObjectDetailColumns(config, objectDetails)
269
+ : buildProductColumns(config);
270
+ const allowedStatuses = new Set(config.status_display?.show ?? ['compliant', 'partial', 'non_compliant', 'under_review', 'n_a']);
271
+ const rowIndex = new Set(obligations.map(r => r.id));
272
+ const cells = obligations.map(() => columns.map(() => emptyCell()));
273
+ for (let c = 0; c < columns.length; c++) {
274
+ const col = columns[c];
275
+ const subjectAssertions = index.assertionsBySubject.get(col.subjectId) ?? [];
276
+ for (const a of subjectAssertions) {
277
+ if (!rowIndex.has(a.about))
278
+ continue;
279
+ if (!allowedStatuses.has(a.status))
280
+ continue;
281
+ if (!assertionMatchesColumn(a, col))
282
+ continue;
283
+ const rowIdx = obligations.findIndex(r => r.id === a.about);
284
+ if (rowIdx < 0)
285
+ continue;
286
+ cells[rowIdx][c].assertions.push(a);
287
+ }
288
+ }
289
+ // Resolve each cell to a status / kind.
290
+ for (let r = 0; r < cells.length; r++) {
291
+ for (let c = 0; c < cells[r].length; c++) {
292
+ const cell = cells[r][c];
293
+ cell.assertions.sort(byId);
294
+ if (cell.assertions.length === 0) {
295
+ cell.kind = 'gap';
296
+ cell.status = null;
297
+ continue;
298
+ }
299
+ if (cell.assertions.every(a => a.status === 'n_a')) {
300
+ cell.kind = 'n_a_only';
301
+ cell.status = 'n_a';
302
+ continue;
303
+ }
304
+ cell.kind = 'bound';
305
+ cell.status = aggregateStatus(cell.assertions);
306
+ }
307
+ }
308
+ // ── CV-3 decorations ────────────────────────────────────────────────────
309
+ const today = new Date().toISOString().slice(0, 10);
310
+ for (let r = 0; r < cells.length; r++) {
311
+ const req = obligations[r];
312
+ const deadlineStatus = computeDeadlineStatus(req.deadline, today);
313
+ // "new" = requirement admitted after the snapshot date.
314
+ const isNew = !!config.snapshot_at &&
315
+ !!req.admitted_at &&
316
+ req.admitted_at > config.snapshot_at;
317
+ for (let c = 0; c < cells[r].length; c++) {
318
+ const cell = cells[r][c];
319
+ const isUrgent = cell.kind === 'gap' &&
320
+ (deadlineStatus === 'past_due' || deadlineStatus === 'in_force');
321
+ cell.decoration = { isNew, isUrgent, deadlineStatus };
322
+ }
323
+ }
324
+ // ── CV-3 derived obligations lane ───────────────────────────────────────
325
+ // For each column: collect codex source IDs from non-gap rows.
326
+ const obligationsLane = columns.map((_, c) => {
327
+ const codexIds = new Set();
328
+ for (let r = 0; r < cells.length; r++) {
329
+ if (cells[r][c].kind !== 'gap') {
330
+ for (const src of obligations[r].derived_from ?? []) {
331
+ codexIds.add(src);
332
+ }
333
+ }
334
+ }
335
+ return [...codexIds].sort();
336
+ });
337
+ return {
338
+ viewId: config.id,
339
+ viewName: config.name,
340
+ description: config.description,
341
+ snapshotAt: config.snapshot_at,
342
+ rows: obligations,
343
+ columns,
344
+ cells,
345
+ emptyLabels: {
346
+ no_obligation_label: config.empty_cells?.no_obligation_label ?? DEFAULT_NO_OBLIGATION_LABEL,
347
+ no_obligation_applies_label: config.empty_cells?.no_obligation_applies_label ?? DEFAULT_NO_OBLIGATION_APPLIES_LABEL,
348
+ },
349
+ obligationsLane,
350
+ };
351
+ }
352
+ function emptyCell() {
353
+ return {
354
+ status: null,
355
+ kind: 'gap',
356
+ assertions: [],
357
+ decoration: { isNew: false, isUrgent: false, deadlineStatus: 'none' },
358
+ };
359
+ }
360
+ // ── Process-blueprint stage extractor (CV-3a) ───────────────────────────────
361
+ /**
362
+ * Extract `ObjectDetailInput` from a raw (YAML-parsed) process-blueprint document.
363
+ *
364
+ * Accepts both the bare document object and the wrapped form
365
+ * (`{ process_blueprint: { id, stages: […] } }`).
366
+ * Returns `null` when the document is not a recognisable process-blueprint or
367
+ * has no `id` / `stages` array so callers can skip unrecognised files safely.
368
+ *
369
+ * Pass the returned value into `buildImpactMatrix` as part of the
370
+ * `objectDetails` array when `grouping.columns: 'product-stage'` is configured.
371
+ */
372
+ export function extractObjectDetails(doc) {
373
+ if (!doc || typeof doc !== 'object' || Array.isArray(doc))
374
+ return null;
375
+ const top = doc;
376
+ const bp = top.notation === 'process_blueprint'
377
+ ? top
378
+ : top.process_blueprint && typeof top.process_blueprint === 'object' && !Array.isArray(top.process_blueprint)
379
+ ? top.process_blueprint
380
+ : null;
381
+ if (!bp)
382
+ return null;
383
+ const id = typeof bp.id === 'string' ? bp.id : null;
384
+ if (!id)
385
+ return null;
386
+ if (!Array.isArray(bp.stages))
387
+ return null;
388
+ const details = [];
389
+ for (const s of bp.stages) {
390
+ if (!s || typeof s !== 'object' || Array.isArray(s))
391
+ continue;
392
+ const sid = typeof s.id === 'string' ? s.id : null;
393
+ if (!sid)
394
+ continue;
395
+ details.push({ id: sid, name: typeof s.name === 'string' ? s.name : sid });
396
+ }
397
+ return { objectId: id, details };
398
+ }
399
+ // ── Markdown rendering ──────────────────────────────────────────────────────
400
+ const STATUS_GLYPH = {
401
+ compliant: 'OK',
402
+ partial: 'PARTIAL',
403
+ non_compliant: 'FAIL',
404
+ under_review: 'REVIEW',
405
+ n_a: 'N/A',
406
+ };
407
+ function escMd(s) {
408
+ return s.replace(/\|/g, '\\|');
409
+ }
410
+ /**
411
+ * Render the matrix as a GitHub-flavoured markdown table.
412
+ *
413
+ * Cell display:
414
+ * - `bound` → the §5.2 deterministic status label.
415
+ * - `n_a_only` → the "No obligation applies" label (or `view.empty_cells`
416
+ * override).
417
+ * - `gap` → the "No mapped obligation (current model)" label (or
418
+ * override).
419
+ */
420
+ export function renderImpactMarkdown(matrix) {
421
+ const lines = [];
422
+ lines.push(`# ${matrix.viewName}`);
423
+ lines.push('');
424
+ lines.push(`View ID: \`${matrix.viewId}\``);
425
+ if (matrix.snapshotAt)
426
+ lines.push(`Report snapshot: ${matrix.snapshotAt}`);
427
+ if (matrix.description) {
428
+ lines.push('');
429
+ lines.push(matrix.description);
430
+ }
431
+ lines.push('');
432
+ if (matrix.rows.length === 0) {
433
+ lines.push('_No obligations in scope — the configured filter / include selected zero REQUIREMENTs._');
434
+ return lines.join('\n') + '\n';
435
+ }
436
+ if (matrix.columns.length === 0) {
437
+ lines.push('_No subjects in scope — `view.subjects` is empty._');
438
+ return lines.join('\n') + '\n';
439
+ }
440
+ const header = ['Obligation', ...matrix.columns.map(col => escMd(col.label))];
441
+ lines.push('| ' + header.join(' | ') + ' |');
442
+ lines.push('|' + header.map(() => '---').join('|') + '|');
443
+ for (let r = 0; r < matrix.rows.length; r++) {
444
+ const row = matrix.rows[r];
445
+ const rowLabel = `${row.id}${row.name && row.name !== row.id ? ` — ${row.name}` : ''}`;
446
+ const cells = matrix.cells[r].map(cell => renderCell(cell, matrix.emptyLabels));
447
+ lines.push('| ' + [escMd(rowLabel), ...cells].join(' | ') + ' |');
448
+ }
449
+ // Legend — the §5.3 distinction must be visible in the rendered output.
450
+ lines.push('');
451
+ lines.push('## Legend');
452
+ lines.push('');
453
+ lines.push('- **OK / PARTIAL / FAIL / REVIEW / N/A** — aggregated `ASSERTION.status` per §5.2.');
454
+ lines.push(`- **${escMd(matrix.emptyLabels.no_obligation_label)}** — modelling gap; no admitted ASSERTION binds this (obligation, subject) pair.`);
455
+ lines.push(`- **${escMd(matrix.emptyLabels.no_obligation_applies_label)}** — modelled fact; an admitted ASSERTION with status \`n_a\` excludes this pair.`);
456
+ return lines.join('\n') + '\n';
457
+ }
458
+ function renderCell(cell, labels) {
459
+ if (cell.kind === 'gap')
460
+ return escMd(labels.no_obligation_label);
461
+ if (cell.kind === 'n_a_only')
462
+ return escMd(labels.no_obligation_applies_label);
463
+ return STATUS_GLYPH[cell.status];
464
+ }
@@ -0,0 +1,16 @@
1
+ export { buildComplianceIndex } from './reverse-index.js';
2
+ export { buildLawTree, buildProductView } from './views.js';
3
+ export { buildGapReport } from './gap-report.js';
4
+ export type { GapReport, GapReportOptions } from './gap-report.js';
5
+ export { emptyCanon, ingestComplianceDoc } from './classify.js';
6
+ export type { ComplianceCanon, ComplianceProduct, ComplianceCodexDoc } from './classify.js';
7
+ export { renderComplianceMarkdown } from './markdown.js';
8
+ export type { ReportScope, MarkdownOptions } from './markdown.js';
9
+ export { renderComplianceHtml, renderImpactMatrixHtml } from './html.js';
10
+ export type { HtmlOptions, ImpactMatrixHtmlOptions } from './html.js';
11
+ export { buildImpactMatrix, renderImpactMarkdown, parseImpactViewConfig, COMPLIANCE_IMPACT_DEFAULTS, extractObjectDetails, computeDeadlineStatus } from './impact.js';
12
+ export type { ImpactCell, ImpactColumn, ImpactEmptyCellLabels, ImpactGrouping, ImpactMatrix, ImpactObligationFilter, ImpactStatusDisplay, ImpactSubjects, ImpactViewConfig, ParseImpactViewConfigResult, } from './impact.js';
13
+ export { assertionToScoringElement, complianceConfidenceHeader, requirementToScoringElement, scoreComplianceView, } from './confidence.js';
14
+ export { parseCoverageMetricConfig, buildCoverageMatrix, } from './coverage-metric.js';
15
+ export type { CoverageMetricConfig, CoverageMetricScope, CoverageMetricSubjects, CoverageMetricThresholds, CoverageMatrix, CoverageRow, ParseCoverageMetricResult, RagStatus, } from './coverage-metric.js';
16
+ export type { ComplianceIndex, ComplianceIndexInput, DeadlineStatus, IndexRequirement, IndexAssertion, LawTree, LawTreeRequirement, ProductView, ProductRequirementStatus, ObjectDetailDef, ObjectDetailInput, } from './types.js';
@@ -0,0 +1,9 @@
1
+ export { buildComplianceIndex } from './reverse-index.js';
2
+ export { buildLawTree, buildProductView } from './views.js';
3
+ export { buildGapReport } from './gap-report.js';
4
+ export { emptyCanon, ingestComplianceDoc } from './classify.js';
5
+ export { renderComplianceMarkdown } from './markdown.js';
6
+ export { renderComplianceHtml, renderImpactMatrixHtml } from './html.js';
7
+ export { buildImpactMatrix, renderImpactMarkdown, parseImpactViewConfig, COMPLIANCE_IMPACT_DEFAULTS, extractObjectDetails, computeDeadlineStatus } from './impact.js';
8
+ export { assertionToScoringElement, complianceConfidenceHeader, requirementToScoringElement, scoreComplianceView, } from './confidence.js';
9
+ export { parseCoverageMetricConfig, buildCoverageMatrix, } from './coverage-metric.js';
@@ -0,0 +1,18 @@
1
+ import type { ComplianceCanon } from './classify.js';
2
+ export type ReportScope = {
3
+ mode: 'matrix';
4
+ } | {
5
+ mode: 'law';
6
+ id: string;
7
+ } | {
8
+ mode: 'product';
9
+ id: string;
10
+ } | {
11
+ mode: 'gap';
12
+ };
13
+ export interface MarkdownOptions {
14
+ /** Today as ISO YYYY-MM-DD — enables the gap dashboard's stale-assertion list. */
15
+ today?: string;
16
+ }
17
+ /** Renders the requested compliance view from a scanned canon to Markdown. */
18
+ export declare function renderComplianceMarkdown(canon: ComplianceCanon, scope: ReportScope, options?: MarkdownOptions): string;
@@ -0,0 +1,129 @@
1
+ // Markdown renderers for the compliance views (vkgeorgia/strategy#84 Phase 5).
2
+ // Pure string builders consumed by the `transitrix export-compliance` CLI.
3
+ // PDF rendering lives in `html.ts` (HTML doc fed to WeasyPrint by the CLI).
4
+ import { buildComplianceMatrix } from '../compliance-matrix/index.js';
5
+ import { buildComplianceIndex } from './reverse-index.js';
6
+ import { buildLawTree, buildProductView } from './views.js';
7
+ import { buildGapReport } from './gap-report.js';
8
+ const STATUS_LABELS = {
9
+ compliant: 'Compliant',
10
+ partial: 'Partial',
11
+ non_compliant: 'Non-compliant',
12
+ under_review: 'Under review',
13
+ n_a: 'N/A',
14
+ };
15
+ /** Escapes a value for a Markdown table cell (pipes + newlines). */
16
+ function cell(s) {
17
+ return s.replace(/\|/g, '\\|').replace(/\r?\n/g, ' ');
18
+ }
19
+ /** Renders the requested compliance view from a scanned canon to Markdown. */
20
+ export function renderComplianceMarkdown(canon, scope, options = {}) {
21
+ switch (scope.mode) {
22
+ case 'matrix': return matrixMarkdown(canon);
23
+ case 'law': return lawMarkdown(canon, scope.id);
24
+ case 'product': return productMarkdown(canon, scope.id);
25
+ case 'gap': return gapMarkdown(canon, options.today);
26
+ }
27
+ }
28
+ function matrixMarkdown(canon) {
29
+ const m = buildComplianceMatrix({ products: canon.products, requirements: canon.requirements, assertions: canon.assertions });
30
+ const out = ['# Compliance Matrix', ''];
31
+ out.push(`_${m.summary.products} products × ${m.summary.requirements} requirements · ${m.summary.gaps} gaps · ${m.summary.assertions} assertions_`, '');
32
+ if (m.products.length === 0 || m.requirements.length === 0) {
33
+ out.push('_No products or requirements found in the scanned canon._', '');
34
+ return out.join('\n');
35
+ }
36
+ out.push(`| Product \\ Requirement | ${m.requirements.map(r => cell(r.name)).join(' | ')} |`);
37
+ out.push(`|---|${m.requirements.map(() => '---').join('|')}|`);
38
+ m.products.forEach((p, ri) => {
39
+ const cells = m.requirements.map((_r, ci) => {
40
+ const c = m.cells[ri][ci];
41
+ return c.status ? STATUS_LABELS[c.status] : '—';
42
+ });
43
+ const name = cell(p.name) + (p.unresolved ? ' ⚠' : '');
44
+ out.push(`| ${name} | ${cells.join(' | ')} |`);
45
+ });
46
+ out.push('');
47
+ return out.join('\n');
48
+ }
49
+ function lawMarkdown(canon, lawId) {
50
+ const index = buildComplianceIndex({ requirements: canon.requirements, assertions: canon.assertions });
51
+ const tree = buildLawTree(lawId, index);
52
+ const law = canon.codex.find(c => c.id === lawId);
53
+ const out = [`# Compliance — ${law ? law.name : lawId}`, ''];
54
+ out.push(`\`${lawId}\` · ${tree.requirements.length} requirement(s)`, '');
55
+ if (tree.requirements.length === 0) {
56
+ out.push(`_No requirements derive from \`${lawId}\`._`, '');
57
+ return out.join('\n');
58
+ }
59
+ for (const node of tree.requirements) {
60
+ const sev = node.requirement.severity ? ` — severity: ${node.requirement.severity}` : '';
61
+ out.push(`## ${node.requirement.name} (\`${node.requirement.id}\`)${sev}`, '');
62
+ if (node.assertions.length === 0) {
63
+ out.push('_No assertion — compliance gap._', '');
64
+ continue;
65
+ }
66
+ for (const a of node.assertions) {
67
+ const meta = [a.assessed_at ? `assessed ${a.assessed_at}` : null, a.next_review_at ? `review by ${a.next_review_at}` : null].filter(Boolean).join(', ');
68
+ out.push(`- **${STATUS_LABELS[a.status]}** — \`${a.id}\` (subject \`${a.subject}\`${meta ? `; ${meta}` : ''})`);
69
+ }
70
+ out.push('');
71
+ }
72
+ return out.join('\n');
73
+ }
74
+ function productMarkdown(canon, productId) {
75
+ const index = buildComplianceIndex({ requirements: canon.requirements, assertions: canon.assertions });
76
+ const view = buildProductView(productId, index);
77
+ const product = canon.products.find(p => p.id === productId);
78
+ const out = [`# Compliance — ${product ? product.name : productId}`, ''];
79
+ out.push(`\`${productId}\` · ${view.requirements.length} requirement(s) asserted`, '');
80
+ if (view.requirements.length === 0) {
81
+ out.push('_No assertion names this product as its subject._', '');
82
+ return out.join('\n');
83
+ }
84
+ out.push('| Requirement | Status | Assertion | Next review |', '|---|---|---|---|');
85
+ for (const { requirement, assertion } of view.requirements) {
86
+ out.push(`| ${cell(requirement.name)} (\`${requirement.id}\`) | ${STATUS_LABELS[assertion.status]} | \`${assertion.id}\` | ${assertion.next_review_at ?? '—'} |`);
87
+ }
88
+ out.push('');
89
+ return out.join('\n');
90
+ }
91
+ function gapMarkdown(canon, today) {
92
+ const index = buildComplianceIndex({ requirements: canon.requirements, assertions: canon.assertions });
93
+ const report = buildGapReport(index, { today });
94
+ const total = report.requirementsWithoutAssertions.length + report.assertionsWithoutEvidence.length + report.staleAssertions.length + report.pastDeadlineRequirements.length;
95
+ const out = ['# Compliance Gap Dashboard', '', `_${total} gap(s) across 4 checks_`, ''];
96
+ out.push(`## Requirements without assertions (${report.requirementsWithoutAssertions.length})`, '');
97
+ if (report.requirementsWithoutAssertions.length === 0)
98
+ out.push('_✓ none_', '');
99
+ else {
100
+ for (const r of report.requirementsWithoutAssertions)
101
+ out.push(`- [ ] \`${r.id}\` ${r.name}${r.severity ? ` — severity: ${r.severity}` : ''}${r.deadline ? ` — deadline: ${r.deadline}` : ''}`);
102
+ out.push('');
103
+ }
104
+ out.push(`## Assertions without evidence — ASSERT-007 (${report.assertionsWithoutEvidence.length})`, '');
105
+ if (report.assertionsWithoutEvidence.length === 0)
106
+ out.push('_✓ none_', '');
107
+ else {
108
+ for (const a of report.assertionsWithoutEvidence)
109
+ out.push(`- [ ] \`${a.id}\` — about \`${a.about}\`, subject \`${a.subject}\`, status ${a.status}`);
110
+ out.push('');
111
+ }
112
+ out.push(`## Stale assertions — ASSERT-008 (${report.staleAssertions.length})`, '');
113
+ if (report.staleAssertions.length === 0)
114
+ out.push('_✓ none_', '');
115
+ else {
116
+ for (const a of report.staleAssertions)
117
+ out.push(`- [ ] \`${a.id}\` — review due ${a.next_review_at ?? '—'}, subject \`${a.subject}\``);
118
+ out.push('');
119
+ }
120
+ out.push(`## Past-deadline requirements — CV-5 (${report.pastDeadlineRequirements.length})`, '');
121
+ if (report.pastDeadlineRequirements.length === 0)
122
+ out.push('_✓ none_', '');
123
+ else {
124
+ for (const r of report.pastDeadlineRequirements)
125
+ out.push(`- [ ] \`${r.id}\` ${r.name} — deadline: ${r.deadline ?? '—'}${r.severity ? `, severity: ${r.severity}` : ''}`);
126
+ out.push('');
127
+ }
128
+ return out.join('\n');
129
+ }
@@ -0,0 +1,8 @@
1
+ import type { ComplianceIndex, ComplianceIndexInput } from './types.js';
2
+ /**
3
+ * Builds the reverse indexes used by every compliance view. Pure; the input
4
+ * arrays are read, not mutated. Requirements with no `derived_from` simply do
5
+ * not appear under any law; assertions are indexed by both their requirement
6
+ * (`about`) and their subject.
7
+ */
8
+ export declare function buildComplianceIndex(input: ComplianceIndexInput): ComplianceIndex;