@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,256 @@
1
+ // HTML renderers for the compliance views (vkgeorgia/strategy#84 Phase 5,
2
+ // PDF follow-on). Pure string builders — fed to WeasyPrint by the
3
+ // `transitrix export-compliance --format pdf` path in src/export-compliance.ts.
4
+ //
5
+ // Each entry point returns a complete, self-contained HTML document (no
6
+ // external assets) so WeasyPrint reads the whole brief on stdin. CSS is
7
+ // inlined; the page rules target A4 portrait with branded header and footer.
8
+ // Status colours mirror the Studio preview palette (see compliance-render.ts)
9
+ // so the export and the in-editor view stay visually consistent.
10
+ import { buildComplianceMatrix } from '../compliance-matrix/index.js';
11
+ import { buildComplianceIndex } from './reverse-index.js';
12
+ import { buildLawTree, buildProductView } from './views.js';
13
+ import { buildGapReport } from './gap-report.js';
14
+ const STATUS_LABELS = {
15
+ compliant: 'Compliant',
16
+ partial: 'Partial',
17
+ non_compliant: 'Non-compliant',
18
+ under_review: 'Under review',
19
+ n_a: 'N/A',
20
+ };
21
+ function escHtml(s) {
22
+ return s
23
+ .replace(/&/g, '&')
24
+ .replace(/</g, '&lt;')
25
+ .replace(/>/g, '&gt;')
26
+ .replace(/"/g, '&quot;');
27
+ }
28
+ function badge(status) {
29
+ return `<span class="cmp-badge cmp-${status}">${escHtml(STATUS_LABELS[status])}</span>`;
30
+ }
31
+ // A4 portrait with 18mm margins — matches the WeasyPrint one-pager template
32
+ // the site uses. Brand colour `#004d67` mirrors `--ts-brand-primary` from
33
+ // extension/src/compliance-render.ts so the PDF and the Studio preview agree.
34
+ const CSS = `
35
+ @page {
36
+ size: A4 portrait;
37
+ margin: 18mm 16mm 22mm;
38
+ @bottom-left { content: "Transitrix — compliance report"; font: 9pt "Helvetica", "Arial", sans-serif; color: #475569; }
39
+ @bottom-right { content: "Page " counter(page) " / " counter(pages); font: 9pt "Helvetica", "Arial", sans-serif; color: #475569; }
40
+ }
41
+ html, body { margin: 0; padding: 0; }
42
+ body { font-family: "Helvetica", "Arial", sans-serif; font-size: 10pt; color: #0f172a; line-height: 1.4; }
43
+ .cmp-header { border-bottom: 2px solid #004d67; padding-bottom: 6pt; margin-bottom: 14pt; }
44
+ .cmp-header .cmp-eyebrow { font-size: 8.5pt; letter-spacing: 0.08em; text-transform: uppercase; color: #004d67; font-weight: 700; }
45
+ .cmp-header h1 { font-size: 17pt; margin: 2pt 0 4pt; color: #0f172a; }
46
+ .cmp-header .cmp-stamp { font-size: 9pt; color: #475569; }
47
+ h2 { font-size: 12pt; margin: 16pt 0 6pt; color: #0f172a; page-break-after: avoid; }
48
+ h2 .cmp-count { color: #64748b; font-weight: 400; font-size: 10pt; }
49
+ p.cmp-empty { color: #64748b; font-style: italic; }
50
+ table { border-collapse: collapse; width: 100%; font-size: 9.5pt; margin-bottom: 10pt; }
51
+ th, td { border: 0.5pt solid #cbd5e1; padding: 4pt 6pt; text-align: left; vertical-align: top; }
52
+ th { background: #f1f5f9; font-weight: 700; color: #0f172a; }
53
+ table.cmp-matrix th:first-child, table.cmp-matrix td:first-child { background: #f8fafc; font-weight: 600; }
54
+ code, .cmp-id { font-family: "Menlo", "Consolas", monospace; font-size: 9pt; color: #475569; }
55
+ .cmp-badge { display: inline-block; padding: 1pt 6pt; border-radius: 8pt; font-size: 8.5pt; font-weight: 700; }
56
+ .cmp-compliant { background: #d1fae5; color: #065f46; }
57
+ .cmp-partial { background: #fef9c3; color: #854d0e; }
58
+ .cmp-non_compliant { background: #fee2e2; color: #991b1b; }
59
+ .cmp-under_review { background: #e0f2fe; color: #0c4a6e; }
60
+ .cmp-n_a { background: #f1f5f9; color: #64748b; }
61
+ .cmp-cell-gap { color: #94a3b8; text-align: center; }
62
+ .cmp-req { border: 0.5pt solid #cbd5e1; border-radius: 3pt; margin-bottom: 8pt; page-break-inside: avoid; }
63
+ .cmp-req-head { background: #f1f5f9; padding: 5pt 8pt; }
64
+ .cmp-req-head .cmp-req-name { font-weight: 700; color: #0f172a; }
65
+ .cmp-req-head .cmp-req-id { margin-left: 6pt; color: #475569; font-size: 9pt; font-family: "Menlo", "Consolas", monospace; }
66
+ .cmp-sev { font-size: 8pt; text-transform: uppercase; letter-spacing: 0.06em; margin-left: 8pt; }
67
+ .cmp-sev-high { color: #b91c1c; }
68
+ .cmp-sev-medium { color: #b45309; }
69
+ .cmp-sev-low { color: #2563eb; }
70
+ .cmp-assertions { list-style: none; margin: 0; padding: 0; }
71
+ .cmp-assertions li { padding: 4pt 8pt 4pt 16pt; border-top: 0.5pt solid #e2e8f0; }
72
+ .cmp-assertions li .cmp-meta { color: #475569; font-size: 8.5pt; margin-left: 6pt; }
73
+ .cmp-section { margin-bottom: 12pt; }
74
+ .cmp-rows { list-style: none; margin: 0; padding: 0; }
75
+ .cmp-rows li { padding: 3pt 0 3pt 14pt; border-bottom: 0.5pt solid #e2e8f0; text-indent: -10pt; }
76
+ .cmp-rows li::before { content: "☐"; color: #94a3b8; margin-right: 6pt; }
77
+ .cmp-ok { color: #065f46; font-weight: 600; }
78
+ .cmp-summary { font-size: 9pt; color: #475569; }
79
+ `;
80
+ function htmlDoc(title, today, body) {
81
+ const stamp = today ? `Generated ${escHtml(today)}` : '';
82
+ return [
83
+ '<!doctype html>',
84
+ '<html lang="en">',
85
+ '<head>',
86
+ '<meta charset="utf-8"/>',
87
+ `<title>${escHtml(title)}</title>`,
88
+ `<style>${CSS}</style>`,
89
+ '</head>',
90
+ '<body>',
91
+ '<header class="cmp-header">',
92
+ '<div class="cmp-eyebrow">Transitrix · Compliance</div>',
93
+ `<h1>${escHtml(title)}</h1>`,
94
+ stamp ? `<div class="cmp-stamp">${stamp}</div>` : '',
95
+ '</header>',
96
+ body,
97
+ '</body>',
98
+ '</html>',
99
+ '',
100
+ ].join('\n');
101
+ }
102
+ /** Renders the requested compliance view from a scanned canon to a complete HTML document. */
103
+ export function renderComplianceHtml(canon, scope, options = {}) {
104
+ switch (scope.mode) {
105
+ case 'matrix': {
106
+ const m = buildComplianceMatrix({ products: canon.products, requirements: canon.requirements, assertions: canon.assertions });
107
+ const title = options.title ?? 'Compliance Matrix';
108
+ const summary = `<p class="cmp-summary">${m.summary.products} products × ${m.summary.requirements} requirements · ${m.summary.gaps} gaps · ${m.summary.assertions} assertions</p>`;
109
+ if (m.products.length === 0 || m.requirements.length === 0) {
110
+ return htmlDoc(title, options.today, `${summary}<p class="cmp-empty">No products or requirements found in the scanned canon.</p>`);
111
+ }
112
+ const head = `<tr><th>Product \\ Requirement</th>${m.requirements.map(r => `<th>${escHtml(r.name)}</th>`).join('')}</tr>`;
113
+ const rows = m.products.map((p, ri) => {
114
+ const cells = m.requirements.map((_r, ci) => {
115
+ const c = m.cells[ri][ci];
116
+ return c.status ? `<td>${badge(c.status)}</td>` : '<td class="cmp-cell-gap">—</td>';
117
+ }).join('');
118
+ const name = escHtml(p.name) + (p.unresolved ? ' <span class="cmp-sev cmp-sev-high">unresolved</span>' : '');
119
+ return `<tr><td>${name}</td>${cells}</tr>`;
120
+ }).join('');
121
+ return htmlDoc(title, options.today, `${summary}<table class="cmp-matrix"><thead>${head}</thead><tbody>${rows}</tbody></table>`);
122
+ }
123
+ case 'law': {
124
+ const index = buildComplianceIndex({ requirements: canon.requirements, assertions: canon.assertions });
125
+ const tree = buildLawTree(scope.id, index);
126
+ const law = canon.codex.find(c => c.id === scope.id);
127
+ const title = options.title ?? `Compliance — ${law ? law.name : scope.id}`;
128
+ const summary = `<p class="cmp-summary"><code>${escHtml(scope.id)}</code> · ${tree.requirements.length} requirement(s)</p>`;
129
+ if (tree.requirements.length === 0) {
130
+ return htmlDoc(title, options.today, `${summary}<p class="cmp-empty">No requirements derive from <code>${escHtml(scope.id)}</code>.</p>`);
131
+ }
132
+ const blocks = tree.requirements.map(node => {
133
+ const sev = node.requirement.severity ? ` <span class="cmp-sev cmp-sev-${escHtml(node.requirement.severity)}">${escHtml(node.requirement.severity)}</span>` : '';
134
+ const head = `<div class="cmp-req-head"><span class="cmp-req-name">${escHtml(node.requirement.name)}</span><span class="cmp-req-id">${escHtml(node.requirement.id)}</span>${sev}</div>`;
135
+ if (node.assertions.length === 0) {
136
+ return `<section class="cmp-req">${head}<ul class="cmp-assertions"><li><em>No assertion — compliance gap.</em></li></ul></section>`;
137
+ }
138
+ const items = node.assertions.map(a => {
139
+ const metaParts = [];
140
+ if (a.assessed_at)
141
+ metaParts.push(`assessed ${escHtml(a.assessed_at)}`);
142
+ if (a.next_review_at)
143
+ metaParts.push(`review by ${escHtml(a.next_review_at)}`);
144
+ const meta = metaParts.length > 0 ? `<span class="cmp-meta">${metaParts.join(' · ')}</span>` : '';
145
+ return `<li>${badge(a.status)} <code>${escHtml(a.id)}</code> <span class="cmp-meta">subject <code>${escHtml(a.subject)}</code></span> ${meta}</li>`;
146
+ }).join('');
147
+ return `<section class="cmp-req">${head}<ul class="cmp-assertions">${items}</ul></section>`;
148
+ }).join('');
149
+ return htmlDoc(title, options.today, `${summary}${blocks}`);
150
+ }
151
+ case 'product': {
152
+ const index = buildComplianceIndex({ requirements: canon.requirements, assertions: canon.assertions });
153
+ const view = buildProductView(scope.id, index);
154
+ const product = canon.products.find(p => p.id === scope.id);
155
+ const title = options.title ?? `Compliance — ${product ? product.name : scope.id}`;
156
+ const summary = `<p class="cmp-summary"><code>${escHtml(scope.id)}</code> · ${view.requirements.length} requirement(s) asserted</p>`;
157
+ if (view.requirements.length === 0) {
158
+ return htmlDoc(title, options.today, `${summary}<p class="cmp-empty">No assertion names this product as its subject.</p>`);
159
+ }
160
+ const rows = view.requirements.map(({ requirement, assertion }) => (`<tr>` +
161
+ `<td>${escHtml(requirement.name)} <code>${escHtml(requirement.id)}</code></td>` +
162
+ `<td>${badge(assertion.status)}</td>` +
163
+ `<td><code>${escHtml(assertion.id)}</code></td>` +
164
+ `<td>${assertion.next_review_at ? escHtml(assertion.next_review_at) : '—'}</td>` +
165
+ `</tr>`)).join('');
166
+ const head = '<tr><th>Requirement</th><th>Status</th><th>Assertion</th><th>Next review</th></tr>';
167
+ return htmlDoc(title, options.today, `${summary}<table><thead>${head}</thead><tbody>${rows}</tbody></table>`);
168
+ }
169
+ case 'gap': {
170
+ const index = buildComplianceIndex({ requirements: canon.requirements, assertions: canon.assertions });
171
+ const report = buildGapReport(index, { today: options.today });
172
+ const title = options.title ?? 'Compliance Gap Dashboard';
173
+ const total = report.requirementsWithoutAssertions.length + report.assertionsWithoutEvidence.length + report.staleAssertions.length;
174
+ const summary = `<p class="cmp-summary">${total} gap(s)</p>`;
175
+ const section = (heading, count, items) => {
176
+ const body = items.length === 0
177
+ ? '<p class="cmp-ok">✓ none</p>'
178
+ : `<ul class="cmp-rows">${items.join('')}</ul>`;
179
+ return `<section class="cmp-section"><h2>${escHtml(heading)} <span class="cmp-count">(${count})</span></h2>${body}</section>`;
180
+ };
181
+ const reqs = report.requirementsWithoutAssertions.map(r => (`<li><code>${escHtml(r.id)}</code> ${escHtml(r.name)}${r.severity ? ` <span class="cmp-meta">severity ${escHtml(r.severity)}</span>` : ''}${r.deadline ? ` <span class="cmp-meta">deadline ${escHtml(r.deadline)}</span>` : ''}</li>`));
182
+ const noEvidence = report.assertionsWithoutEvidence.map(a => (`<li><code>${escHtml(a.id)}</code> <span class="cmp-meta">about <code>${escHtml(a.about)}</code>, subject <code>${escHtml(a.subject)}</code>, status ${escHtml(a.status)}</span></li>`));
183
+ const stale = report.staleAssertions.map(a => (`<li><code>${escHtml(a.id)}</code> <span class="cmp-meta">review due ${a.next_review_at ? escHtml(a.next_review_at) : '—'}, subject <code>${escHtml(a.subject)}</code></span></li>`));
184
+ const pastDl = report.pastDeadlineRequirements.map(r => (`<li><code>${escHtml(r.id)}</code> ${escHtml(r.name)} <span class="cmp-meta">deadline ${r.deadline ? escHtml(r.deadline) : '—'}${r.severity ? `, severity ${escHtml(r.severity)}` : ''}</span></li>`));
185
+ const total4 = report.requirementsWithoutAssertions.length + report.assertionsWithoutEvidence.length + report.staleAssertions.length + report.pastDeadlineRequirements.length;
186
+ const body = [
187
+ `<p class="cmp-summary">${total4} gap(s) across 4 checks</p>`,
188
+ section('Requirements without assertions', report.requirementsWithoutAssertions.length, reqs),
189
+ section('Assertions without evidence — ASSERT-007', report.assertionsWithoutEvidence.length, noEvidence),
190
+ section('Stale assertions — ASSERT-008', report.staleAssertions.length, stale),
191
+ section('Past-deadline requirements (CV-5)', report.pastDeadlineRequirements.length, pastDl),
192
+ ].join('');
193
+ return htmlDoc(title, options.today, body);
194
+ }
195
+ }
196
+ }
197
+ /**
198
+ * Renders an `ImpactMatrix` (from `buildImpactMatrix`) as a self-contained
199
+ * A4 HTML document suitable for WeasyPrint PDF output.
200
+ *
201
+ * Used by `cervin export-compliance --report <id> --format pdf`.
202
+ */
203
+ export function renderImpactMatrixHtml(matrix, options = {}) {
204
+ const STATUS_GLYPH = {
205
+ compliant: 'OK', partial: 'PARTIAL', non_compliant: 'FAIL',
206
+ under_review: 'REVIEW', n_a: 'N/A',
207
+ };
208
+ const statusClass = (s) => s ?? 'gap';
209
+ const colHeaders = matrix.columns.map(c => `<th>${escHtml(c.label)}</th>`).join('');
210
+ const head = `<tr><th>Obligation</th>${colHeaders}</tr>`;
211
+ const rows = matrix.rows.map((req, ri) => {
212
+ const rowLabel = `${escHtml(req.id)}${req.name && req.name !== req.id ? ` — ${escHtml(req.name)}` : ''}`;
213
+ const cells = matrix.cells[ri].map(cell => {
214
+ if (cell.kind === 'gap')
215
+ return `<td class="cmp-gap">${escHtml(matrix.emptyLabels.no_obligation_label)}</td>`;
216
+ if (cell.kind === 'n_a_only')
217
+ return `<td class="cmp-na">${escHtml(matrix.emptyLabels.no_obligation_applies_label)}</td>`;
218
+ const glyph = STATUS_GLYPH[cell.status ?? ''] ?? String(cell.status);
219
+ return `<td class="cmp-${statusClass(cell.status)}">${escHtml(glyph)}</td>`;
220
+ }).join('');
221
+ const dlInfo = req.deadline ? ` <span class="cmp-dl">⚑ ${escHtml(req.deadline)}</span>` : '';
222
+ return `<tr><td class="cmp-row-label">${rowLabel}${dlInfo}</td>${cells}</tr>`;
223
+ }).join('');
224
+ const snapshotLine = matrix.snapshotAt ? `<span>Snapshot: ${escHtml(matrix.snapshotAt)}</span>` : '';
225
+ const desc = matrix.description ? `<p>${escHtml(matrix.description)}</p>` : '';
226
+ const extraCss = `
227
+ table { border-collapse: collapse; width: 100%; font-size: 9pt; }
228
+ th, td { border: 1px solid #cbd5e1; padding: 3pt 5pt; text-align: center; vertical-align: middle; }
229
+ td.cmp-row-label { text-align: left; font-size: 8.5pt; max-width: 180pt; white-space: normal; }
230
+ .cmp-compliant { background: #d1fae5; color: #065f46; font-weight: 700; }
231
+ .cmp-partial { background: #fef9c3; color: #854d0e; font-weight: 700; }
232
+ .cmp-non_compliant { background: #fee2e2; color: #991b1b; font-weight: 700; }
233
+ .cmp-under_review { background: #e0f2fe; color: #0c4a6e; }
234
+ .cmp-gap { background: #f8fafc; color: #94a3b8; font-size: 8pt; }
235
+ .cmp-na { background: #f1f5f9; color: #94a3b8; font-size: 8pt; }
236
+ .cmp-dl { color: #b45309; font-size: 8pt; }`;
237
+ return `<!DOCTYPE html>
238
+ <html lang="en">
239
+ <head>
240
+ <meta charset="UTF-8">
241
+ <style>
242
+ ${CSS}
243
+ ${extraCss}
244
+ </style>
245
+ </head>
246
+ <body>
247
+ <div class="cmp-header">
248
+ <div class="cmp-eyebrow">Compliance Impact Matrix</div>
249
+ <h1>${escHtml(matrix.viewName)}</h1>
250
+ <div class="cmp-stamp">View: <code>${escHtml(matrix.viewId)}</code> ${snapshotLine}${options.today ? ` · Generated: ${escHtml(options.today)}` : ''}</div>
251
+ </div>
252
+ ${desc}
253
+ <table><thead>${head}</thead><tbody>${rows}</tbody></table>
254
+ </body>
255
+ </html>`;
256
+ }
@@ -0,0 +1,251 @@
1
+ import type { AssertionStatus } from '../assertion/types.js';
2
+ import type { ComplianceCanon } from './classify.js';
3
+ import type { IndexAssertion, IndexRequirement, ObjectDetailInput, DeadlineStatus } from './types.js';
4
+ /** Filter selecting REQUIREMENTs by codex source (jurisdiction / regime keys
5
+ * are accepted for forward compatibility but not yet honoured — the canon
6
+ * projection does not carry those fields). */
7
+ export interface ImpactObligationFilter {
8
+ derived_from_codex?: string[];
9
+ }
10
+ export interface ImpactSubjects {
11
+ products?: string[];
12
+ processes?: string[];
13
+ }
14
+ export interface ImpactStatusDisplay {
15
+ show?: AssertionStatus[];
16
+ }
17
+ export interface ImpactEmptyCellLabels {
18
+ /** Label used when no admitted ASSERTION binds the cell (modelling gap). */
19
+ no_obligation_label?: string;
20
+ /** Label used when an admitted ASSERTION exists with status `n_a`
21
+ * (modelled fact: the obligation does not apply). */
22
+ no_obligation_applies_label?: string;
23
+ }
24
+ /**
25
+ * A matrix column descriptor.
26
+ *
27
+ * At the coarsest grain (`grouping.columns: 'product'`) a column maps to a
28
+ * single subject: `{ subjectId, label: subjectId }`.
29
+ *
30
+ * At `grouping.columns: 'product-stage'` a column represents one (product,
31
+ * stage) pair: `{ subjectId: productId, stageId, label: productId + ':' + stageId }`.
32
+ * A cell is populated when an ASSERTION has `subject === subjectId` and
33
+ * `stageId ∈ assertion.realised_via` (or `realised_via` is absent, meaning
34
+ * the assertion covers the entire subject — it then contributes to every
35
+ * stage column for that subject).
36
+ */
37
+ export interface ImpactColumn {
38
+ /** Subject (product / process / capability) the column belongs to. */
39
+ subjectId: string;
40
+ /** Stage ID — present only when grouping.columns is not 'product'. */
41
+ stageId?: string;
42
+ /** Human-readable column header. */
43
+ label: string;
44
+ }
45
+ /**
46
+ * Grouping options for matrix columns.
47
+ *
48
+ * `columns` controls the column grain:
49
+ * - `'product'` (default) — one column per subject.
50
+ * - `'product-stage'` — one column per (subject, stage) pair derived
51
+ * from `objectDetails` passed to `buildImpactMatrix`.
52
+ */
53
+ export interface ImpactGrouping {
54
+ columns: 'object' | 'object-details';
55
+ }
56
+ /**
57
+ * Named, versioned view-config — the report *definition*.
58
+ *
59
+ * A saved view config is the source of truth for a deterministic report run:
60
+ * given the same config + canon, `buildImpactMatrix` always produces the
61
+ * same matrix. Configs are stored in YAML files (top-level `view:` key) and
62
+ * referenced by `id`.
63
+ *
64
+ * `snapshot_at` (ISO 8601 date) records when the report was last generated.
65
+ * CV-3 blueprint-lane rendering uses it to mark obligations that appeared in
66
+ * the canon *after* the snapshot as "new" (dashed-border cell decoration).
67
+ */
68
+ export interface ImpactViewConfig {
69
+ id: string;
70
+ name: string;
71
+ description?: string;
72
+ /**
73
+ * ISO 8601 date of the last report snapshot (YYYY-MM-DD).
74
+ * Populated automatically by the CLI on each run and stored back to the
75
+ * view-config file, giving CV-3 its "new since last run" signal.
76
+ */
77
+ snapshot_at?: string;
78
+ subjects: ImpactSubjects;
79
+ obligations: {
80
+ include?: string[];
81
+ filter?: ImpactObligationFilter;
82
+ };
83
+ status_display?: ImpactStatusDisplay;
84
+ empty_cells?: ImpactEmptyCellLabels;
85
+ order_rows_by?: 'id' | 'name';
86
+ /**
87
+ * Column grouping options. Omit (or set `columns: 'product'`) for the
88
+ * default single-column-per-subject behaviour. Set `columns: 'product-stage'`
89
+ * and pass `objectDetails` into `buildImpactMatrix` to expand each subject
90
+ * into per-stage sub-columns.
91
+ */
92
+ grouping?: ImpactGrouping;
93
+ }
94
+ /**
95
+ * Explicit defaults for every optional field in ImpactViewConfig.
96
+ *
97
+ * When a view config omits a field, COMPLIANCE_IMPACT_DEFAULTS defines the
98
+ * assumed behaviour. The CLI prints these so re-runs without a full config
99
+ * are auditable ("what I assumed").
100
+ */
101
+ export declare const COMPLIANCE_IMPACT_DEFAULTS: {
102
+ /** Accept all four active statuses + n_a in cell aggregation. */
103
+ readonly status_display: {
104
+ readonly show: AssertionStatus[];
105
+ };
106
+ /** Order rows by canonical REQUIREMENT ID (lexicographic). */
107
+ readonly order_rows_by: "id";
108
+ /** §5.3 empty-cell labels. */
109
+ readonly empty_cells: {
110
+ readonly no_obligation_label: "No mapped obligation (current model)";
111
+ readonly no_obligation_applies_label: "No obligation applies";
112
+ };
113
+ /** Obligation scope: all known REQUIREMENTs in the canon (no filter). */
114
+ readonly obligations: {
115
+ readonly include: string[] | undefined;
116
+ readonly filter: undefined;
117
+ };
118
+ /** Subjects: empty — must be supplied explicitly in the view config. */
119
+ readonly subjects: {
120
+ readonly products: string[];
121
+ readonly processes: string[];
122
+ };
123
+ /** Column grain: one column per business object (no stage decomposition). */
124
+ readonly grouping: {
125
+ readonly columns: "object";
126
+ };
127
+ };
128
+ export type ParseImpactViewConfigResult = {
129
+ ok: true;
130
+ config: ImpactViewConfig;
131
+ } | {
132
+ ok: false;
133
+ errors: string[];
134
+ };
135
+ /**
136
+ * Validate and normalise a raw (YAML-parsed) value into an ImpactViewConfig.
137
+ *
138
+ * Accepts both the bare config object and the view-config file shape
139
+ * (`{ view: { id, name, … } }`) — the top-level `view:` wrapper is unwrapped
140
+ * automatically.
141
+ *
142
+ * Every optional field is filled from COMPLIANCE_IMPACT_DEFAULTS, so callers
143
+ * can rely on the returned config being complete without any `??` chains.
144
+ *
145
+ * Returns `{ ok: false, errors }` on schema violations rather than throwing,
146
+ * so the CLI can surface a clean error message without a stack trace.
147
+ */
148
+ export declare function parseImpactViewConfig(raw: unknown): ParseImpactViewConfigResult;
149
+ /** A single cell of the rendered matrix. */
150
+ export interface ImpactCell {
151
+ /** Resolved status when an ASSERTION binds the cell, else null. */
152
+ status: AssertionStatus | null;
153
+ /** Empty-cell condition per §5.3 — one of:
154
+ * - `bound` : at least one admitted ASSERTION binds the cell; `status` is set.
155
+ * - `n_a_only`: every binding ASSERTION has status `n_a` (modelled fact).
156
+ * - `gap` : no admitted ASSERTION binds the cell (modelling gap). */
157
+ kind: 'bound' | 'n_a_only' | 'gap';
158
+ /** The assertions that contributed to this cell, id-sorted. */
159
+ assertions: IndexAssertion[];
160
+ /**
161
+ * CV-3 blueprint-lane decorations.
162
+ *
163
+ * `isNew` — the row's REQUIREMENT was admitted after the report
164
+ * `snapshot_at` date (dashed-border decoration).
165
+ * `isUrgent` — the cell is a gap AND the requirement has a deadline
166
+ * whose temporal status is `past_due` or `in_force`.
167
+ * `deadlineStatus` — temporal distance to the deadline (or `'none'`).
168
+ */
169
+ decoration: {
170
+ isNew: boolean;
171
+ isUrgent: boolean;
172
+ deadlineStatus: DeadlineStatus;
173
+ };
174
+ }
175
+ export interface ImpactMatrix {
176
+ viewId: string;
177
+ viewName: string;
178
+ description?: string;
179
+ /**
180
+ * ISO 8601 date of the last report snapshot, copied from the view config.
181
+ * CV-3 blueprint-lane rendering uses this to flag obligations that appeared
182
+ * after the snapshot as "new" (dashed-border cell decoration).
183
+ */
184
+ snapshotAt?: string;
185
+ /** Row dimension — REQUIREMENT projections, in the configured order. */
186
+ rows: IndexRequirement[];
187
+ /**
188
+ * Column dimension.
189
+ *
190
+ * At `grouping.columns: 'product'` (default) each entry has only `subjectId`
191
+ * and `label`. At `'product-stage'` entries additionally carry `stageId`.
192
+ */
193
+ columns: ImpactColumn[];
194
+ /** Cells, indexed as `cell[rowIdx][colIdx]`. */
195
+ cells: ImpactCell[][];
196
+ /** Canonical empty-cell labels actually used (after defaults applied). */
197
+ emptyLabels: Required<ImpactEmptyCellLabels>;
198
+ /**
199
+ * CV-3 derived obligations lane.
200
+ *
201
+ * For each column, the set of codex source IDs (`REQUIREMENT.derived_from`)
202
+ * that appear in at least one non-gap cell in that column. Renderers use
203
+ * this to display a "laws lane" header above or below the matrix columns.
204
+ * Empty array when no requirement in the column has a `derived_from`.
205
+ */
206
+ obligationsLane: string[][];
207
+ }
208
+ /**
209
+ * Classify a REQUIREMENT deadline relative to a reference date.
210
+ *
211
+ * @param deadline ISO 8601 date string (YYYY-MM-DD), or undefined.
212
+ * @param today Reference date string (YYYY-MM-DD); defaults to today.
213
+ */
214
+ export declare function computeDeadlineStatus(deadline: string | undefined, today?: string): DeadlineStatus;
215
+ /**
216
+ * Build the matrix per §5.2.
217
+ *
218
+ * At the default `grouping.columns: 'product'` grain, one column per subject.
219
+ * At `grouping.columns: 'product-stage'`, pass `objectDetails` to expand each
220
+ * subject into per-stage sub-columns (typically extracted from a
221
+ * process-blueprint document via `extractObjectDetails`). Subjects with no
222
+ * stage mapping fall back to a single product-grain column automatically.
223
+ *
224
+ * Subjects are taken from `config.subjects.products` and
225
+ * `config.subjects.processes` (in that order). Subjects with no binding
226
+ * obligation still appear as columns so the gap is visible.
227
+ */
228
+ export declare function buildImpactMatrix(canon: ComplianceCanon, config: ImpactViewConfig, objectDetails?: ObjectDetailInput[]): ImpactMatrix;
229
+ /**
230
+ * Extract `ObjectDetailInput` from a raw (YAML-parsed) process-blueprint document.
231
+ *
232
+ * Accepts both the bare document object and the wrapped form
233
+ * (`{ process_blueprint: { id, stages: […] } }`).
234
+ * Returns `null` when the document is not a recognisable process-blueprint or
235
+ * has no `id` / `stages` array so callers can skip unrecognised files safely.
236
+ *
237
+ * Pass the returned value into `buildImpactMatrix` as part of the
238
+ * `objectDetails` array when `grouping.columns: 'product-stage'` is configured.
239
+ */
240
+ export declare function extractObjectDetails(doc: unknown): ObjectDetailInput | null;
241
+ /**
242
+ * Render the matrix as a GitHub-flavoured markdown table.
243
+ *
244
+ * Cell display:
245
+ * - `bound` → the §5.2 deterministic status label.
246
+ * - `n_a_only` → the "No obligation applies" label (or `view.empty_cells`
247
+ * override).
248
+ * - `gap` → the "No mapped obligation (current model)" label (or
249
+ * override).
250
+ */
251
+ export declare function renderImpactMarkdown(matrix: ImpactMatrix): string;