@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.
- package/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/__tests__/edge-path.test.d.ts +1 -0
- package/dist/__tests__/edge-path.test.js +39 -0
- package/dist/__tests__/scope.test.d.ts +1 -0
- package/dist/__tests__/scope.test.js +23 -0
- package/dist/__tests__/yaml-normalize.test.d.ts +1 -0
- package/dist/__tests__/yaml-normalize.test.js +148 -0
- package/dist/activities/__tests__/cpm.test.d.ts +1 -0
- package/dist/activities/__tests__/cpm.test.js +146 -0
- package/dist/activities/__tests__/gantt.test.d.ts +1 -0
- package/dist/activities/__tests__/gantt.test.js +224 -0
- package/dist/activities/__tests__/layout.test.d.ts +1 -0
- package/dist/activities/__tests__/layout.test.js +98 -0
- package/dist/activities/__tests__/validate.test.d.ts +1 -0
- package/dist/activities/__tests__/validate.test.js +363 -0
- package/dist/activities/cpm.d.ts +2 -0
- package/dist/activities/cpm.js +86 -0
- package/dist/activities/gantt.d.ts +6 -0
- package/dist/activities/gantt.js +250 -0
- package/dist/activities/index.d.ts +5 -0
- package/dist/activities/index.js +4 -0
- package/dist/activities/layout.d.ts +2 -0
- package/dist/activities/layout.js +103 -0
- package/dist/activities/types.d.ts +125 -0
- package/dist/activities/types.js +1 -0
- package/dist/activities/validate.d.ts +2 -0
- package/dist/activities/validate.js +326 -0
- package/dist/activity-card/__tests__/example.test.d.ts +1 -0
- package/dist/activity-card/__tests__/example.test.js +56 -0
- package/dist/activity-card/__tests__/layout.test.d.ts +1 -0
- package/dist/activity-card/__tests__/layout.test.js +57 -0
- package/dist/activity-card/__tests__/resolver.test.d.ts +1 -0
- package/dist/activity-card/__tests__/resolver.test.js +146 -0
- package/dist/activity-card/__tests__/validate.test.d.ts +1 -0
- package/dist/activity-card/__tests__/validate.test.js +116 -0
- package/dist/activity-card/index.d.ts +5 -0
- package/dist/activity-card/index.js +3 -0
- package/dist/activity-card/layout.d.ts +7 -0
- package/dist/activity-card/layout.js +167 -0
- package/dist/activity-card/resolver.d.ts +7 -0
- package/dist/activity-card/resolver.js +310 -0
- package/dist/activity-card/types.d.ts +175 -0
- package/dist/activity-card/types.js +20 -0
- package/dist/activity-card/validate.d.ts +3 -0
- package/dist/activity-card/validate.js +145 -0
- package/dist/actor/__tests__/validate.test.d.ts +1 -0
- package/dist/actor/__tests__/validate.test.js +57 -0
- package/dist/actor/index.d.ts +3 -0
- package/dist/actor/index.js +2 -0
- package/dist/actor/types.d.ts +20 -0
- package/dist/actor/types.js +4 -0
- package/dist/actor/validate.d.ts +2 -0
- package/dist/actor/validate.js +34 -0
- package/dist/applications/__tests__/validate.test.d.ts +1 -0
- package/dist/applications/__tests__/validate.test.js +223 -0
- package/dist/applications/index.d.ts +2 -0
- package/dist/applications/index.js +1 -0
- package/dist/applications/types.d.ts +39 -0
- package/dist/applications/types.js +1 -0
- package/dist/applications/validate.d.ts +3 -0
- package/dist/applications/validate.js +109 -0
- package/dist/assertion/__tests__/example.test.d.ts +1 -0
- package/dist/assertion/__tests__/example.test.js +32 -0
- package/dist/assertion/__tests__/validate.test.d.ts +1 -0
- package/dist/assertion/__tests__/validate.test.js +130 -0
- package/dist/assertion/index.d.ts +4 -0
- package/dist/assertion/index.js +2 -0
- package/dist/assertion/types.d.ts +43 -0
- package/dist/assertion/types.js +7 -0
- package/dist/assertion/validate.d.ts +9 -0
- package/dist/assertion/validate.js +137 -0
- package/dist/blocks/__tests__/layout.test.d.ts +1 -0
- package/dist/blocks/__tests__/layout.test.js +153 -0
- package/dist/blocks/__tests__/validate.test.d.ts +1 -0
- package/dist/blocks/__tests__/validate.test.js +235 -0
- package/dist/blocks/index.d.ts +4 -0
- package/dist/blocks/index.js +2 -0
- package/dist/blocks/layout.d.ts +4 -0
- package/dist/blocks/layout.js +145 -0
- package/dist/blocks/types.d.ts +56 -0
- package/dist/blocks/types.js +1 -0
- package/dist/blocks/validate.d.ts +9 -0
- package/dist/blocks/validate.js +186 -0
- package/dist/capability-map/__tests__/validate.test.d.ts +1 -0
- package/dist/capability-map/__tests__/validate.test.js +212 -0
- package/dist/capability-map/index.d.ts +2 -0
- package/dist/capability-map/index.js +1 -0
- package/dist/capability-map/types.d.ts +26 -0
- package/dist/capability-map/types.js +1 -0
- package/dist/capability-map/validate.d.ts +3 -0
- package/dist/capability-map/validate.js +103 -0
- package/dist/change/__tests__/validate.test.d.ts +1 -0
- package/dist/change/__tests__/validate.test.js +73 -0
- package/dist/change/index.d.ts +2 -0
- package/dist/change/index.js +1 -0
- package/dist/change/types.d.ts +17 -0
- package/dist/change/types.js +3 -0
- package/dist/change/validate.d.ts +2 -0
- package/dist/change/validate.js +57 -0
- package/dist/compliance/__tests__/classify.test.d.ts +1 -0
- package/dist/compliance/__tests__/classify.test.js +24 -0
- package/dist/compliance/__tests__/confidence.test.d.ts +1 -0
- package/dist/compliance/__tests__/confidence.test.js +78 -0
- package/dist/compliance/__tests__/coverage-metric.test.d.ts +1 -0
- package/dist/compliance/__tests__/coverage-metric.test.js +164 -0
- package/dist/compliance/__tests__/demo-scenario.test.d.ts +1 -0
- package/dist/compliance/__tests__/demo-scenario.test.js +226 -0
- package/dist/compliance/__tests__/example.test.d.ts +1 -0
- package/dist/compliance/__tests__/example.test.js +51 -0
- package/dist/compliance/__tests__/gap-report.test.d.ts +1 -0
- package/dist/compliance/__tests__/gap-report.test.js +113 -0
- package/dist/compliance/__tests__/html.test.d.ts +1 -0
- package/dist/compliance/__tests__/html.test.js +122 -0
- package/dist/compliance/__tests__/impact.test.d.ts +1 -0
- package/dist/compliance/__tests__/impact.test.js +410 -0
- package/dist/compliance/__tests__/markdown.test.d.ts +1 -0
- package/dist/compliance/__tests__/markdown.test.js +85 -0
- package/dist/compliance/__tests__/views.test.d.ts +1 -0
- package/dist/compliance/__tests__/views.test.js +59 -0
- package/dist/compliance/classify.d.ts +27 -0
- package/dist/compliance/classify.js +60 -0
- package/dist/compliance/confidence.d.ts +27 -0
- package/dist/compliance/confidence.js +43 -0
- package/dist/compliance/coverage-metric.d.ts +74 -0
- package/dist/compliance/coverage-metric.js +181 -0
- package/dist/compliance/gap-report.d.ts +20 -0
- package/dist/compliance/gap-report.js +64 -0
- package/dist/compliance/html.d.ts +22 -0
- package/dist/compliance/html.js +256 -0
- package/dist/compliance/impact.d.ts +251 -0
- package/dist/compliance/impact.js +464 -0
- package/dist/compliance/index.d.ts +16 -0
- package/dist/compliance/index.js +9 -0
- package/dist/compliance/markdown.d.ts +18 -0
- package/dist/compliance/markdown.js +129 -0
- package/dist/compliance/reverse-index.d.ts +8 -0
- package/dist/compliance/reverse-index.js +30 -0
- package/dist/compliance/types.d.ts +98 -0
- package/dist/compliance/types.js +5 -0
- package/dist/compliance/views.d.ts +14 -0
- package/dist/compliance/views.js +35 -0
- package/dist/compliance-matrix/__tests__/build.test.d.ts +1 -0
- package/dist/compliance-matrix/__tests__/build.test.js +183 -0
- package/dist/compliance-matrix/__tests__/example.test.d.ts +1 -0
- package/dist/compliance-matrix/__tests__/example.test.js +49 -0
- package/dist/compliance-matrix/build.d.ts +18 -0
- package/dist/compliance-matrix/build.js +0 -0
- package/dist/compliance-matrix/index.d.ts +2 -0
- package/dist/compliance-matrix/index.js +1 -0
- package/dist/compliance-matrix/types.d.ts +86 -0
- package/dist/compliance-matrix/types.js +8 -0
- package/dist/confidence/__tests__/score.test.d.ts +1 -0
- package/dist/confidence/__tests__/score.test.js +188 -0
- package/dist/confidence/index.d.ts +2 -0
- package/dist/confidence/index.js +1 -0
- package/dist/confidence/score.d.ts +62 -0
- package/dist/confidence/score.js +215 -0
- package/dist/confidence/types.d.ts +79 -0
- package/dist/confidence/types.js +6 -0
- package/dist/edge-path.d.ts +18 -0
- package/dist/edge-path.js +35 -0
- package/dist/element-envelope.d.ts +15 -0
- package/dist/element-envelope.js +55 -0
- package/dist/factor/__tests__/validate.test.d.ts +1 -0
- package/dist/factor/__tests__/validate.test.js +83 -0
- package/dist/factor/index.d.ts +3 -0
- package/dist/factor/index.js +2 -0
- package/dist/factor/types.d.ts +23 -0
- package/dist/factor/types.js +6 -0
- package/dist/factor/validate.d.ts +2 -0
- package/dist/factor/validate.js +69 -0
- package/dist/fgca/__tests__/chain-table.test.d.ts +1 -0
- package/dist/fgca/__tests__/chain-table.test.js +158 -0
- package/dist/fgca/__tests__/layout.test.d.ts +1 -0
- package/dist/fgca/__tests__/layout.test.js +140 -0
- package/dist/fgca/__tests__/parse-canonical.test.d.ts +1 -0
- package/dist/fgca/__tests__/parse-canonical.test.js +224 -0
- package/dist/fgca/__tests__/preview-layout.test.d.ts +1 -0
- package/dist/fgca/__tests__/preview-layout.test.js +106 -0
- package/dist/fgca/__tests__/validate.test.d.ts +1 -0
- package/dist/fgca/__tests__/validate.test.js +125 -0
- package/dist/fgca/chain-table.d.ts +36 -0
- package/dist/fgca/chain-table.js +177 -0
- package/dist/fgca/index.d.ts +16 -0
- package/dist/fgca/index.js +11 -0
- package/dist/fgca/layout.d.ts +27 -0
- package/dist/fgca/layout.js +156 -0
- package/dist/fgca/nodeTypes.d.ts +6 -0
- package/dist/fgca/nodeTypes.js +10 -0
- package/dist/fgca/nodes/FGCAActivityNode.d.ts +13 -0
- package/dist/fgca/nodes/FGCAActivityNode.js +35 -0
- package/dist/fgca/nodes/FGCAChangeNode.d.ts +12 -0
- package/dist/fgca/nodes/FGCAChangeNode.js +35 -0
- package/dist/fgca/nodes/FGCAFactorNode.d.ts +12 -0
- package/dist/fgca/nodes/FGCAFactorNode.js +35 -0
- package/dist/fgca/nodes/FGCAGoalNode.d.ts +14 -0
- package/dist/fgca/nodes/FGCAGoalNode.js +40 -0
- package/dist/fgca/parse-canonical.d.ts +58 -0
- package/dist/fgca/parse-canonical.js +339 -0
- package/dist/fgca/preview-layout.d.ts +87 -0
- package/dist/fgca/preview-layout.js +122 -0
- package/dist/fgca/types.d.ts +39 -0
- package/dist/fgca/types.js +7 -0
- package/dist/fgca/validate.d.ts +14 -0
- package/dist/fgca/validate.js +108 -0
- package/dist/geometry.d.ts +7 -0
- package/dist/geometry.js +2 -0
- package/dist/goals/__tests__/layout.test.d.ts +1 -0
- package/dist/goals/__tests__/layout.test.js +153 -0
- package/dist/goals/__tests__/mutations.test.d.ts +1 -0
- package/dist/goals/__tests__/mutations.test.js +95 -0
- package/dist/goals/__tests__/parse-canonical.test.d.ts +1 -0
- package/dist/goals/__tests__/parse-canonical.test.js +129 -0
- package/dist/goals/__tests__/validate.test.d.ts +1 -0
- package/dist/goals/__tests__/validate.test.js +183 -0
- package/dist/goals/index.d.ts +6 -0
- package/dist/goals/index.js +4 -0
- package/dist/goals/layout.d.ts +11 -0
- package/dist/goals/layout.js +147 -0
- package/dist/goals/mutations.d.ts +6 -0
- package/dist/goals/mutations.js +116 -0
- package/dist/goals/parse-canonical.d.ts +29 -0
- package/dist/goals/parse-canonical.js +257 -0
- package/dist/goals/types.d.ts +71 -0
- package/dist/goals/types.js +1 -0
- package/dist/goals/validate.d.ts +2 -0
- package/dist/goals/validate.js +122 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +23 -0
- package/dist/issues/__tests__/layout.test.d.ts +1 -0
- package/dist/issues/__tests__/layout.test.js +62 -0
- package/dist/issues/__tests__/validate.test.d.ts +1 -0
- package/dist/issues/__tests__/validate.test.js +82 -0
- package/dist/issues/index.d.ts +4 -0
- package/dist/issues/index.js +2 -0
- package/dist/issues/layout.d.ts +10 -0
- package/dist/issues/layout.js +82 -0
- package/dist/issues/types.d.ts +61 -0
- package/dist/issues/types.js +6 -0
- package/dist/issues/validate.d.ts +3 -0
- package/dist/issues/validate.js +143 -0
- package/dist/process-blueprint/__tests__/compliance-lane.test.d.ts +1 -0
- package/dist/process-blueprint/__tests__/compliance-lane.test.js +272 -0
- package/dist/process-blueprint/__tests__/layout.test.d.ts +1 -0
- package/dist/process-blueprint/__tests__/layout.test.js +159 -0
- package/dist/process-blueprint/__tests__/validate.test.d.ts +1 -0
- package/dist/process-blueprint/__tests__/validate.test.js +280 -0
- package/dist/process-blueprint/index.d.ts +4 -0
- package/dist/process-blueprint/index.js +2 -0
- package/dist/process-blueprint/layout.d.ts +2 -0
- package/dist/process-blueprint/layout.js +416 -0
- package/dist/process-blueprint/types.d.ts +220 -0
- package/dist/process-blueprint/types.js +1 -0
- package/dist/process-blueprint/validate.d.ts +3 -0
- package/dist/process-blueprint/validate.js +165 -0
- package/dist/process-map/__tests__/validate.test.d.ts +1 -0
- package/dist/process-map/__tests__/validate.test.js +199 -0
- package/dist/process-map/index.d.ts +2 -0
- package/dist/process-map/index.js +1 -0
- package/dist/process-map/types.d.ts +32 -0
- package/dist/process-map/types.js +1 -0
- package/dist/process-map/validate.d.ts +3 -0
- package/dist/process-map/validate.js +115 -0
- package/dist/products/__tests__/validate.test.d.ts +1 -0
- package/dist/products/__tests__/validate.test.js +210 -0
- package/dist/products/index.d.ts +2 -0
- package/dist/products/index.js +1 -0
- package/dist/products/types.d.ts +28 -0
- package/dist/products/types.js +1 -0
- package/dist/products/validate.d.ts +3 -0
- package/dist/products/validate.js +93 -0
- package/dist/repo-validate/__tests__/validate-repo.test.d.ts +1 -0
- package/dist/repo-validate/__tests__/validate-repo.test.js +132 -0
- package/dist/repo-validate/index.d.ts +2 -0
- package/dist/repo-validate/index.js +1 -0
- package/dist/repo-validate/types.d.ts +34 -0
- package/dist/repo-validate/types.js +14 -0
- package/dist/repo-validate/validate-repo.d.ts +8 -0
- package/dist/repo-validate/validate-repo.js +189 -0
- package/dist/requirement/__tests__/example.test.d.ts +1 -0
- package/dist/requirement/__tests__/example.test.js +21 -0
- package/dist/requirement/__tests__/validate.test.d.ts +1 -0
- package/dist/requirement/__tests__/validate.test.js +80 -0
- package/dist/requirement/index.d.ts +4 -0
- package/dist/requirement/index.js +2 -0
- package/dist/requirement/types.d.ts +25 -0
- package/dist/requirement/types.js +4 -0
- package/dist/requirement/validate.d.ts +7 -0
- package/dist/requirement/validate.js +81 -0
- package/dist/scenarios/__tests__/validate.test.d.ts +1 -0
- package/dist/scenarios/__tests__/validate.test.js +183 -0
- package/dist/scenarios/index.d.ts +2 -0
- package/dist/scenarios/index.js +1 -0
- package/dist/scenarios/types.d.ts +45 -0
- package/dist/scenarios/types.js +1 -0
- package/dist/scenarios/validate.d.ts +3 -0
- package/dist/scenarios/validate.js +110 -0
- package/dist/schema-version.d.ts +16 -0
- package/dist/schema-version.js +16 -0
- package/dist/scope.d.ts +23 -0
- package/dist/scope.js +38 -0
- package/dist/stakeholder/__tests__/validate.test.d.ts +1 -0
- package/dist/stakeholder/__tests__/validate.test.js +86 -0
- package/dist/stakeholder/index.d.ts +3 -0
- package/dist/stakeholder/index.js +2 -0
- package/dist/stakeholder/types.d.ts +24 -0
- package/dist/stakeholder/types.js +5 -0
- package/dist/stakeholder/validate.d.ts +2 -0
- package/dist/stakeholder/validate.js +58 -0
- package/dist/target-state/__tests__/validate.test.d.ts +1 -0
- package/dist/target-state/__tests__/validate.test.js +62 -0
- package/dist/target-state/index.d.ts +2 -0
- package/dist/target-state/index.js +1 -0
- package/dist/target-state/types.d.ts +18 -0
- package/dist/target-state/types.js +7 -0
- package/dist/target-state/validate.d.ts +2 -0
- package/dist/target-state/validate.js +61 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.js +2 -0
- package/dist/theme/themes.d.ts +16 -0
- package/dist/theme/themes.js +213 -0
- package/dist/theme/tokens.d.ts +158 -0
- package/dist/theme/tokens.js +105 -0
- package/dist/typed-id.d.ts +20 -0
- package/dist/typed-id.js +38 -0
- package/dist/validation-types.d.ts +34 -0
- package/dist/validation-types.js +1 -0
- package/dist/webview/__tests__/entry-notations.test.d.ts +1 -0
- package/dist/webview/__tests__/entry-notations.test.js +62 -0
- package/dist/webview/__tests__/entry.test.d.ts +1 -0
- package/dist/webview/__tests__/entry.test.js +56 -0
- package/dist/webview/__tests__/render-goals.test.d.ts +1 -0
- package/dist/webview/__tests__/render-goals.test.js +65 -0
- package/dist/webview/entry.d.ts +38 -0
- package/dist/webview/entry.js +182 -0
- package/dist/webview/render-activities.d.ts +24 -0
- package/dist/webview/render-activities.js +127 -0
- package/dist/webview/render-activity-card.d.ts +5 -0
- package/dist/webview/render-activity-card.js +168 -0
- package/dist/webview/render-applications.d.ts +11 -0
- package/dist/webview/render-applications.js +105 -0
- package/dist/webview/render-blocks.d.ts +5 -0
- package/dist/webview/render-blocks.js +71 -0
- package/dist/webview/render-capability-map.d.ts +7 -0
- package/dist/webview/render-capability-map.js +88 -0
- package/dist/webview/render-fgca.d.ts +8 -0
- package/dist/webview/render-fgca.js +94 -0
- package/dist/webview/render-goals.d.ts +6 -0
- package/dist/webview/render-goals.js +92 -0
- package/dist/webview/render-process-blueprint.d.ts +5 -0
- package/dist/webview/render-process-blueprint.js +135 -0
- package/dist/webview/render-process-map.d.ts +7 -0
- package/dist/webview/render-process-map.js +82 -0
- package/dist/webview/render-products.d.ts +7 -0
- package/dist/webview/render-products.js +81 -0
- package/dist/webview/render-scenarios.d.ts +7 -0
- package/dist/webview/render-scenarios.js +75 -0
- package/dist/webview/render-util.d.ts +16 -0
- package/dist/webview/render-util.js +31 -0
- package/dist/webview/transitrix-render.css +323 -0
- package/dist/webview/transitrix-render.js +6452 -0
- package/dist/webview/transitrix-render.js.map +7 -0
- package/dist/yaml-normalize.d.ts +20 -0
- package/dist/yaml-normalize.js +57 -0
- package/package.json +40 -0
- package/src/__tests__/edge-path.test.ts +46 -0
- package/src/__tests__/scope.test.ts +27 -0
- package/src/__tests__/yaml-normalize.test.ts +158 -0
- package/src/activities/__tests__/cpm.test.ts +164 -0
- package/src/activities/__tests__/gantt.test.ts +245 -0
- package/src/activities/__tests__/layout.test.ts +112 -0
- package/src/activities/__tests__/validate.test.ts +409 -0
- package/src/activities/cpm.ts +95 -0
- package/src/activities/gantt.ts +276 -0
- package/src/activities/index.ts +28 -0
- package/src/activities/layout.ts +112 -0
- package/src/activities/types.ts +148 -0
- package/src/activities/validate.ts +357 -0
- package/src/activity-card/__tests__/example.test.ts +66 -0
- package/src/activity-card/__tests__/layout.test.ts +63 -0
- package/src/activity-card/__tests__/resolver.test.ts +161 -0
- package/src/activity-card/__tests__/validate.test.ts +131 -0
- package/src/activity-card/index.ts +32 -0
- package/src/activity-card/layout.ts +194 -0
- package/src/activity-card/resolver.ts +337 -0
- package/src/activity-card/types.ts +237 -0
- package/src/activity-card/validate.ts +158 -0
- package/src/actor/__tests__/validate.test.ts +67 -0
- package/src/actor/index.ts +3 -0
- package/src/actor/types.ts +29 -0
- package/src/actor/validate.ts +38 -0
- package/src/applications/__tests__/validate.test.ts +256 -0
- package/src/applications/index.ts +11 -0
- package/src/applications/types.ts +43 -0
- package/src/applications/validate.ts +131 -0
- package/src/assertion/__tests__/example.test.ts +37 -0
- package/src/assertion/__tests__/validate.test.ts +142 -0
- package/src/assertion/index.ts +12 -0
- package/src/assertion/types.ts +58 -0
- package/src/assertion/validate.ts +145 -0
- package/src/blocks/__tests__/layout.test.ts +169 -0
- package/src/blocks/__tests__/validate.test.ts +260 -0
- package/src/blocks/index.ts +17 -0
- package/src/blocks/layout.ts +186 -0
- package/src/blocks/types.ts +62 -0
- package/src/blocks/validate.ts +206 -0
- package/src/capability-map/__tests__/validate.test.ts +238 -0
- package/src/capability-map/index.ts +8 -0
- package/src/capability-map/types.ts +29 -0
- package/src/capability-map/validate.ts +127 -0
- package/src/change/__tests__/validate.test.ts +88 -0
- package/src/change/index.ts +2 -0
- package/src/change/types.ts +23 -0
- package/src/change/validate.ts +61 -0
- package/src/compliance/__tests__/classify.test.ts +27 -0
- package/src/compliance/__tests__/confidence.test.ts +98 -0
- package/src/compliance/__tests__/coverage-metric.test.ts +188 -0
- package/src/compliance/__tests__/demo-scenario.test.ts +273 -0
- package/src/compliance/__tests__/example.test.ts +57 -0
- package/src/compliance/__tests__/gap-report.test.ts +129 -0
- package/src/compliance/__tests__/html.test.ts +142 -0
- package/src/compliance/__tests__/impact.test.ts +482 -0
- package/src/compliance/__tests__/markdown.test.ts +95 -0
- package/src/compliance/__tests__/views.test.ts +64 -0
- package/src/compliance/classify.ts +84 -0
- package/src/compliance/confidence.ts +69 -0
- package/src/compliance/coverage-metric.ts +263 -0
- package/src/compliance/gap-report.ts +94 -0
- package/src/compliance/html.ts +295 -0
- package/src/compliance/impact.ts +677 -0
- package/src/compliance/index.ts +56 -0
- package/src/compliance/markdown.ts +135 -0
- package/src/compliance/reverse-index.ts +33 -0
- package/src/compliance/types.ts +120 -0
- package/src/compliance/views.ts +46 -0
- package/src/compliance-matrix/__tests__/build.test.ts +200 -0
- package/src/compliance-matrix/__tests__/example.test.ts +57 -0
- package/src/compliance-matrix/build.ts +0 -0
- package/src/compliance-matrix/index.ts +11 -0
- package/src/compliance-matrix/types.ts +102 -0
- package/src/confidence/__tests__/score.test.ts +254 -0
- package/src/confidence/index.ts +21 -0
- package/src/confidence/score.ts +243 -0
- package/src/confidence/types.ts +96 -0
- package/src/edge-path.ts +44 -0
- package/src/element-envelope.ts +76 -0
- package/src/factor/__tests__/validate.test.ts +98 -0
- package/src/factor/index.ts +8 -0
- package/src/factor/types.ts +41 -0
- package/src/factor/validate.ts +74 -0
- package/src/fgca/__tests__/chain-table.test.ts +172 -0
- package/src/fgca/__tests__/layout.test.ts +179 -0
- package/src/fgca/__tests__/parse-canonical.test.ts +248 -0
- package/src/fgca/__tests__/preview-layout.test.ts +124 -0
- package/src/fgca/__tests__/validate.test.ts +142 -0
- package/src/fgca/chain-table.ts +225 -0
- package/src/fgca/index.ts +45 -0
- package/src/fgca/layout.ts +204 -0
- package/src/fgca/nodeTypes.ts +11 -0
- package/src/fgca/nodes/FGCAActivityNode.tsx +65 -0
- package/src/fgca/nodes/FGCAChangeNode.tsx +64 -0
- package/src/fgca/nodes/FGCAFactorNode.tsx +64 -0
- package/src/fgca/nodes/FGCAGoalNode.tsx +72 -0
- package/src/fgca/parse-canonical.ts +400 -0
- package/src/fgca/preview-layout.ts +217 -0
- package/src/fgca/types.ts +50 -0
- package/src/fgca/validate.ts +126 -0
- package/src/geometry.ts +9 -0
- package/src/goals/__tests__/layout.test.ts +175 -0
- package/src/goals/__tests__/mutations.test.ts +111 -0
- package/src/goals/__tests__/parse-canonical.test.ts +145 -0
- package/src/goals/__tests__/validate.test.ts +202 -0
- package/src/goals/index.ts +21 -0
- package/src/goals/layout.ts +172 -0
- package/src/goals/mutations.ts +123 -0
- package/src/goals/parse-canonical.ts +286 -0
- package/src/goals/types.ts +85 -0
- package/src/goals/validate.ts +136 -0
- package/src/index.ts +23 -0
- package/src/process-blueprint/__tests__/compliance-lane.test.ts +320 -0
- package/src/process-blueprint/__tests__/layout.test.ts +195 -0
- package/src/process-blueprint/__tests__/validate.test.ts +310 -0
- package/src/process-blueprint/index.ts +31 -0
- package/src/process-blueprint/layout.ts +531 -0
- package/src/process-blueprint/types.ts +242 -0
- package/src/process-blueprint/validate.ts +181 -0
- package/src/process-map/__tests__/validate.test.ts +223 -0
- package/src/process-map/index.ts +10 -0
- package/src/process-map/types.ts +36 -0
- package/src/process-map/validate.ts +135 -0
- package/src/products/__tests__/validate.test.ts +239 -0
- package/src/products/index.ts +9 -0
- package/src/products/types.ts +31 -0
- package/src/products/validate.ts +112 -0
- package/src/repo-validate/__tests__/validate-repo.test.ts +149 -0
- package/src/repo-validate/index.ts +2 -0
- package/src/repo-validate/types.ts +50 -0
- package/src/repo-validate/validate-repo.ts +196 -0
- package/src/requirement/__tests__/example.test.ts +24 -0
- package/src/requirement/__tests__/validate.test.ts +96 -0
- package/src/requirement/index.ts +4 -0
- package/src/requirement/types.ts +35 -0
- package/src/requirement/validate.ts +92 -0
- package/src/scenarios/__tests__/validate.test.ts +209 -0
- package/src/scenarios/index.ts +15 -0
- package/src/scenarios/types.ts +37 -0
- package/src/scenarios/validate.ts +122 -0
- package/src/schema-version.ts +16 -0
- package/src/scope.ts +46 -0
- package/src/stakeholder/__tests__/validate.test.ts +101 -0
- package/src/stakeholder/index.ts +3 -0
- package/src/stakeholder/types.ts +33 -0
- package/src/stakeholder/validate.ts +63 -0
- package/src/target-state/__tests__/validate.test.ts +74 -0
- package/src/target-state/index.ts +2 -0
- package/src/target-state/types.ts +28 -0
- package/src/target-state/validate.ts +67 -0
- package/src/theme/index.ts +4 -0
- package/src/theme/themes.ts +237 -0
- package/src/theme/tokens.ts +133 -0
- package/src/typed-id.ts +56 -0
- package/src/validation-types.ts +36 -0
- package/src/webview/__tests__/entry-notations.test.ts +77 -0
- package/src/webview/__tests__/entry.test.ts +64 -0
- package/src/webview/__tests__/render-goals.test.ts +72 -0
- package/src/webview/entry.ts +292 -0
- package/src/webview/render-activities.ts +156 -0
- package/src/webview/render-activity-card.ts +234 -0
- package/src/webview/render-applications.ts +123 -0
- package/src/webview/render-blocks.ts +91 -0
- package/src/webview/render-capability-map.ts +98 -0
- package/src/webview/render-fgca.ts +122 -0
- package/src/webview/render-goals.ts +110 -0
- package/src/webview/render-process-blueprint.ts +207 -0
- package/src/webview/render-process-map.ts +93 -0
- package/src/webview/render-products.ts +91 -0
- package/src/webview/render-scenarios.ts +90 -0
- package/src/webview/render-util.ts +34 -0
- package/src/webview/styles.css +323 -0
- 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;
|