@mergesignal/shared 0.4.2 → 0.5.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 (193) hide show
  1. package/dist/actionsStepSummary.d.ts +1 -22
  2. package/dist/actionsStepSummary.d.ts.map +1 -1
  3. package/dist/actionsStepSummary.js +19 -716
  4. package/dist/actionsStepSummary.test.js +34 -329
  5. package/dist/assessmentLabels.d.ts +6 -0
  6. package/dist/assessmentLabels.d.ts.map +1 -0
  7. package/dist/assessmentLabels.js +33 -0
  8. package/dist/assessmentProjection.d.ts +12 -0
  9. package/dist/assessmentProjection.d.ts.map +1 -0
  10. package/dist/assessmentProjection.js +100 -0
  11. package/dist/assessmentSchema.d.ts +155 -0
  12. package/dist/assessmentSchema.d.ts.map +1 -0
  13. package/dist/assessmentSchema.js +110 -0
  14. package/dist/cardObservationCatalog.d.ts +2 -0
  15. package/dist/cardObservationCatalog.d.ts.map +1 -1
  16. package/dist/cardObservationCatalog.js +47 -1
  17. package/dist/engineWireRegression.test.js +24 -4
  18. package/dist/fixtures/assessmentFixtures.d.ts +13 -0
  19. package/dist/fixtures/assessmentFixtures.d.ts.map +1 -0
  20. package/dist/fixtures/assessmentFixtures.js +164 -0
  21. package/dist/formatCardExposureDisplay.d.ts +0 -4
  22. package/dist/formatCardExposureDisplay.d.ts.map +1 -1
  23. package/dist/formatCardExposureDisplay.js +0 -15
  24. package/dist/formatInsight.d.ts +3 -2
  25. package/dist/formatInsight.d.ts.map +1 -1
  26. package/dist/formatInsight.js +26 -1
  27. package/dist/index.d.ts +7 -11
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +7 -11
  30. package/dist/narrativeParity.test.js +6 -37
  31. package/dist/presentGitHubPrComment.d.ts +1 -3
  32. package/dist/presentGitHubPrComment.d.ts.map +1 -1
  33. package/dist/presentGitHubPrComment.js +0 -17
  34. package/dist/presentation/compose/narrativeChannels.d.ts +17 -0
  35. package/dist/presentation/compose/narrativeChannels.d.ts.map +1 -0
  36. package/dist/presentation/compose/narrativeChannels.js +45 -0
  37. package/dist/presentation/compose/narrativeChannels.test.d.ts +2 -0
  38. package/dist/presentation/compose/narrativeChannels.test.d.ts.map +1 -0
  39. package/dist/presentation/compose/narrativeChannels.test.js +42 -0
  40. package/dist/presentation/compose/narrativeCompose.d.ts +1 -0
  41. package/dist/presentation/compose/narrativeCompose.d.ts.map +1 -1
  42. package/dist/presentation/compose/narrativeCompose.js +5 -7
  43. package/dist/presentation/dto/assessmentPresentationFields.d.ts +13 -0
  44. package/dist/presentation/dto/assessmentPresentationFields.d.ts.map +1 -0
  45. package/dist/presentation/dto/dashboardCardPresentation.d.ts +30 -0
  46. package/dist/presentation/dto/dashboardCardPresentation.d.ts.map +1 -0
  47. package/dist/presentation/dto/dashboardCardPresentation.js +1 -0
  48. package/dist/presentation/dto/githubAndCliPresentation.d.ts +4 -3
  49. package/dist/presentation/dto/githubAndCliPresentation.d.ts.map +1 -1
  50. package/dist/presentation/dto/scanDetailsPresentation.d.ts +2 -1
  51. package/dist/presentation/dto/scanDetailsPresentation.d.ts.map +1 -1
  52. package/dist/presentation/dto/types.d.ts +0 -9
  53. package/dist/presentation/dto/types.d.ts.map +1 -1
  54. package/dist/presentation/dto/types.js +1 -22
  55. package/dist/presentation/fixtures/dashboardCardGolden.test.d.ts +2 -0
  56. package/dist/presentation/fixtures/dashboardCardGolden.test.d.ts.map +1 -0
  57. package/dist/presentation/fixtures/dashboardCardGolden.test.js +38 -0
  58. package/dist/presentation/fixtures/presentationPersonaFixtures.d.ts.map +1 -1
  59. package/dist/presentation/fixtures/presentationPersonaFixtures.js +31 -24
  60. package/dist/presentation/fixtures/scanResultFixtures.d.ts.map +1 -1
  61. package/dist/presentation/fixtures/scanResultFixtures.js +14 -3
  62. package/dist/presentation/index.d.ts +6 -6
  63. package/dist/presentation/index.d.ts.map +1 -1
  64. package/dist/presentation/index.js +2 -4
  65. package/dist/presentation/orchestration/buildScanCardPresentation.d.ts +2 -2
  66. package/dist/presentation/orchestration/buildScanCardPresentation.d.ts.map +1 -1
  67. package/dist/presentation/orchestration/buildScanCardPresentation.js +13 -9
  68. package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts +1 -1
  69. package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts.map +1 -1
  70. package/dist/presentation/orchestration/buildScanPresentationBundle.js +12 -10
  71. package/dist/presentation/orchestration/scanPresentationBundle.d.ts +8 -3
  72. package/dist/presentation/orchestration/scanPresentationBundle.d.ts.map +1 -1
  73. package/dist/presentation/presentation.test.js +16 -18
  74. package/dist/presentation/presentationPersonas.test.js +20 -19
  75. package/dist/presentation/presenters/presentCliScanSummary.d.ts.map +1 -1
  76. package/dist/presentation/presenters/presentCliScanSummary.js +4 -2
  77. package/dist/presentation/presenters/presentDashboardCard.d.ts +5 -0
  78. package/dist/presentation/presenters/presentDashboardCard.d.ts.map +1 -0
  79. package/dist/presentation/presenters/presentDashboardCard.js +119 -0
  80. package/dist/presentation/presenters/presentGitHubCheckRun.d.ts.map +1 -1
  81. package/dist/presentation/presenters/presentGitHubCheckRun.js +4 -2
  82. package/dist/presentation/presenters/presentGitHubPrComment.d.ts.map +1 -1
  83. package/dist/presentation/presenters/presentGitHubPrComment.js +15 -21
  84. package/dist/presentation/presenters/presentScanDetails.d.ts.map +1 -1
  85. package/dist/presentation/presenters/presentScanDetails.js +53 -127
  86. package/dist/presentation/profile/buildProfileFromAssessment.d.ts +5 -0
  87. package/dist/presentation/profile/buildProfileFromAssessment.d.ts.map +1 -0
  88. package/dist/presentation/profile/buildProfileFromAssessment.js +58 -0
  89. package/dist/presentation/projectAssessmentFields.d.ts +4 -0
  90. package/dist/presentation/projectAssessmentFields.d.ts.map +1 -0
  91. package/dist/presentation/projectAssessmentFields.js +13 -0
  92. package/dist/presentation/surfaceParity.test.d.ts +2 -0
  93. package/dist/presentation/surfaceParity.test.d.ts.map +1 -0
  94. package/dist/presentation/surfaceParity.test.js +74 -0
  95. package/dist/productMessaging.d.ts +4 -4
  96. package/dist/productMessaging.d.ts.map +1 -1
  97. package/dist/productMessaging.js +4 -4
  98. package/dist/productMessaging.test.js +2 -2
  99. package/dist/repoIntelligenceSchema.d.ts +2 -2
  100. package/dist/resolvePipelineStatus.d.ts +15 -0
  101. package/dist/resolvePipelineStatus.d.ts.map +1 -0
  102. package/dist/resolvePipelineStatus.js +37 -0
  103. package/dist/scanCardPresentationState.d.ts +4 -0
  104. package/dist/scanCardPresentationState.d.ts.map +1 -0
  105. package/dist/scanCardPresentationState.js +4 -0
  106. package/dist/{scanDetailViewModel.d.ts → scanDetailViewModelTypes.d.ts} +60 -32
  107. package/dist/scanDetailViewModelTypes.d.ts.map +1 -0
  108. package/dist/scanDetailViewModelTypes.js +4 -0
  109. package/dist/scanResultSchema.d.ts +75 -2
  110. package/dist/scanResultSchema.d.ts.map +1 -1
  111. package/dist/scanResultSchema.js +4 -2
  112. package/dist/scanResultSchema.test.js +16 -0
  113. package/dist/trustedScanGuards.test.js +7 -0
  114. package/dist/types.d.ts +3 -0
  115. package/dist/types.d.ts.map +1 -1
  116. package/package.json +1 -1
  117. package/dist/collectNarrativeWhyBullets.d.ts +0 -12
  118. package/dist/collectNarrativeWhyBullets.d.ts.map +0 -1
  119. package/dist/collectNarrativeWhyBullets.js +0 -104
  120. package/dist/deriveCardDisplaySummary.d.ts +0 -16
  121. package/dist/deriveCardDisplaySummary.d.ts.map +0 -1
  122. package/dist/deriveCardDisplaySummary.js +0 -56
  123. package/dist/deriveCardDisplaySummary.test.d.ts +0 -2
  124. package/dist/deriveCardDisplaySummary.test.d.ts.map +0 -1
  125. package/dist/deriveCardDisplaySummary.test.js +0 -89
  126. package/dist/deriveCardOperationalObservations.d.ts +0 -19
  127. package/dist/deriveCardOperationalObservations.d.ts.map +0 -1
  128. package/dist/deriveCardOperationalObservations.js +0 -180
  129. package/dist/deriveCardOperationalObservations.test.d.ts +0 -2
  130. package/dist/deriveCardOperationalObservations.test.d.ts.map +0 -1
  131. package/dist/deriveCardOperationalObservations.test.js +0 -268
  132. package/dist/deriveRiskScoreSummary.d.ts +0 -33
  133. package/dist/deriveRiskScoreSummary.d.ts.map +0 -1
  134. package/dist/deriveRiskScoreSummary.js +0 -90
  135. package/dist/deriveRiskScoreSummary.test.d.ts +0 -2
  136. package/dist/deriveRiskScoreSummary.test.d.ts.map +0 -1
  137. package/dist/deriveRiskScoreSummary.test.js +0 -47
  138. package/dist/deriveScanDetailRecommendations.d.ts +0 -63
  139. package/dist/deriveScanDetailRecommendations.d.ts.map +0 -1
  140. package/dist/deriveScanDetailRecommendations.js +0 -725
  141. package/dist/deriveScanDetailRecommendations.test.d.ts +0 -2
  142. package/dist/deriveScanDetailRecommendations.test.d.ts.map +0 -1
  143. package/dist/deriveScanDetailRecommendations.test.js +0 -181
  144. package/dist/deriveScanSummaryText.d.ts +0 -7
  145. package/dist/deriveScanSummaryText.d.ts.map +0 -1
  146. package/dist/deriveScanSummaryText.js +0 -24
  147. package/dist/deriveScanSummaryText.test.d.ts +0 -2
  148. package/dist/deriveScanSummaryText.test.d.ts.map +0 -1
  149. package/dist/deriveScanSummaryText.test.js +0 -77
  150. package/dist/formatCardEvidenceCounts.d.ts +0 -7
  151. package/dist/formatCardEvidenceCounts.d.ts.map +0 -1
  152. package/dist/formatCardEvidenceCounts.js +0 -19
  153. package/dist/prCheckRunPresentation.d.ts +0 -68
  154. package/dist/prCheckRunPresentation.d.ts.map +0 -1
  155. package/dist/prCheckRunPresentation.js +0 -319
  156. package/dist/prCheckRunPresentation.test.d.ts +0 -2
  157. package/dist/prCheckRunPresentation.test.d.ts.map +0 -1
  158. package/dist/prCheckRunPresentation.test.js +0 -278
  159. package/dist/presentation/dto/scanCardPresentation.d.ts +0 -27
  160. package/dist/presentation/dto/scanCardPresentation.d.ts.map +0 -1
  161. package/dist/presentation/intent/derivePresentationInterpretation.d.ts +0 -4
  162. package/dist/presentation/intent/derivePresentationInterpretation.d.ts.map +0 -1
  163. package/dist/presentation/intent/derivePresentationInterpretation.js +0 -202
  164. package/dist/presentation/intent/formatPresentationCopy.d.ts +0 -7
  165. package/dist/presentation/intent/formatPresentationCopy.d.ts.map +0 -1
  166. package/dist/presentation/intent/formatPresentationCopy.js +0 -153
  167. package/dist/presentation/intent/presentationIntent.test.d.ts +0 -2
  168. package/dist/presentation/intent/presentationIntent.test.d.ts.map +0 -1
  169. package/dist/presentation/intent/presentationIntent.test.js +0 -29
  170. package/dist/presentation/intent/verificationFocusLabels.d.ts +0 -2
  171. package/dist/presentation/intent/verificationFocusLabels.d.ts.map +0 -1
  172. package/dist/presentation/intent/verificationFocusLabels.js +0 -45
  173. package/dist/presentation/presenters/presentPipelineScanCard.d.ts +0 -3
  174. package/dist/presentation/presenters/presentPipelineScanCard.d.ts.map +0 -1
  175. package/dist/presentation/presenters/presentPipelineScanCard.js +0 -23
  176. package/dist/presentation/presenters/presentScanCard.d.ts +0 -7
  177. package/dist/presentation/presenters/presentScanCard.d.ts.map +0 -1
  178. package/dist/presentation/presenters/presentScanCard.js +0 -44
  179. package/dist/presentation/profile/derivePresentationProfile.d.ts +0 -12
  180. package/dist/presentation/profile/derivePresentationProfile.d.ts.map +0 -1
  181. package/dist/presentation/profile/derivePresentationProfile.js +0 -85
  182. package/dist/scanCardSummary.d.ts +0 -59
  183. package/dist/scanCardSummary.d.ts.map +0 -1
  184. package/dist/scanCardSummary.js +0 -146
  185. package/dist/scanCardSummary.test.d.ts +0 -2
  186. package/dist/scanCardSummary.test.d.ts.map +0 -1
  187. package/dist/scanCardSummary.test.js +0 -234
  188. package/dist/scanDetailViewModel.d.ts.map +0 -1
  189. package/dist/scanDetailViewModel.js +0 -636
  190. package/dist/scanDetailViewModel.test.d.ts +0 -2
  191. package/dist/scanDetailViewModel.test.d.ts.map +0 -1
  192. package/dist/scanDetailViewModel.test.js +0 -530
  193. /package/dist/presentation/dto/{scanCardPresentation.js → assessmentPresentationFields.js} +0 -0
@@ -1,3 +1,4 @@
1
+ import { assessmentBullmq, assessmentEslint, assessmentMixedTypescriptFastify, assessmentNextAuth, assessmentPrettier, assessmentUnknownSafe, assessmentVitest, } from "../../fixtures/assessmentFixtures.js";
1
2
  import { fixtureRepoIntelligenceFastify, fixtureRepoIntelligenceTypescript, } from "../../fixtures/repoIntelligenceFixtures.js";
2
3
  import { analysisPreparationWithValidRepoIntel } from "../../fixtures/repoIntelligenceTestHelpers.js";
3
4
  import { scanResultFastifyRuntime, scanResultLimitedContext, scanResultTypescriptPatch, } from "./scanResultFixtures.js";
@@ -128,7 +129,22 @@ const fixtureRepoIntelligenceMixedToolingRuntime = {
128
129
  blastRadius: fixtureRepoIntelligenceFastify.blastRadius,
129
130
  applicationAreas: fixtureRepoIntelligenceFastify.applicationAreas,
130
131
  };
131
- function scanBase(over = {}) {
132
+ function decisionForAssessment(assessment) {
133
+ return {
134
+ recommendation: assessment.posture,
135
+ confidence: assessment.confidence,
136
+ reasoning: assessment.posture === "safe"
137
+ ? [
138
+ "No dedicated dependency review required beyond normal engineering process.",
139
+ ]
140
+ : assessment.primaryConcern === "confirmed_runtime_usage"
141
+ ? [
142
+ "Changed package has confirmed usage on runtime application paths in this repository.",
143
+ ]
144
+ : ["Explicit human review warranted before merge."],
145
+ };
146
+ }
147
+ function scanBase(assessment, over = {}) {
132
148
  return {
133
149
  totalScore: 18,
134
150
  layerScores: {
@@ -139,59 +155,50 @@ function scanBase(over = {}) {
139
155
  },
140
156
  findings: [],
141
157
  generatedAt: "2026-01-01T00:00:00.000Z",
142
- decision: {
143
- recommendation: "safe",
144
- confidence: "high",
145
- reasoning: [],
146
- },
158
+ assessment,
159
+ decision: decisionForAssessment(assessment),
147
160
  analysisPreparation: basePrep,
148
161
  ...over,
149
162
  };
150
163
  }
151
- export const scanResultEslint = scanBase({
164
+ export const scanResultEslint = scanBase(assessmentEslint, {
152
165
  changedPackages: ["eslint"],
153
166
  repoIntelligence: fixtureRepoIntelligenceEslint,
154
167
  });
155
- export const scanResultPrettier = scanBase({
168
+ export const scanResultPrettier = scanBase(assessmentPrettier, {
156
169
  changedPackages: ["prettier"],
157
170
  repoIntelligence: fixtureRepoIntelligencePrettier,
158
171
  });
159
- export const scanResultVitest = scanBase({
172
+ export const scanResultVitest = scanBase(assessmentVitest, {
160
173
  changedPackages: ["vitest"],
161
174
  repoIntelligence: fixtureRepoIntelligenceVitest,
162
175
  });
163
- export const scanResultNextAuth = scanBase({
176
+ export const scanResultNextAuth = scanBase(assessmentNextAuth, {
164
177
  totalScore: 52,
165
178
  changedPackages: ["next-auth"],
166
179
  repoIntelligence: fixtureRepoIntelligenceNextAuth,
167
- decision: {
168
- recommendation: "needs_review",
169
- confidence: "medium",
170
- reasoning: [],
171
- },
172
180
  });
173
- export const scanResultBullmq = scanBase({
181
+ export const scanResultBullmq = scanBase(assessmentBullmq, {
174
182
  totalScore: 48,
175
183
  changedPackages: ["bullmq"],
176
184
  repoIntelligence: fixtureRepoIntelligenceBullmq,
177
185
  decision: {
178
186
  recommendation: "needs_review",
179
187
  confidence: "medium",
180
- reasoning: [],
188
+ reasoning: [
189
+ "Changed package has confirmed usage on runtime application paths in this repository.",
190
+ "Queue infrastructure",
191
+ "Verification focus required",
192
+ ],
181
193
  },
182
194
  });
183
- export const scanResultUnknownSafe = scanBase({
195
+ export const scanResultUnknownSafe = scanBase(assessmentUnknownSafe, {
184
196
  changedPackages: ["opaque-pkg"],
185
197
  repoIntelligence: fixtureRepoIntelligenceUnknown,
186
198
  });
187
- export const scanResultMixedTypescriptFastify = scanBase({
199
+ export const scanResultMixedTypescriptFastify = scanBase(assessmentMixedTypescriptFastify, {
188
200
  totalScore: 55,
189
201
  changedPackages: ["typescript", "fastify"],
190
202
  repoIntelligence: fixtureRepoIntelligenceMixedToolingRuntime,
191
- decision: {
192
- recommendation: "needs_review",
193
- confidence: "medium",
194
- reasoning: [],
195
- },
196
203
  });
197
204
  export { scanResultFastifyRuntime, scanResultLimitedContext, scanResultTypescriptPatch, };
@@ -1 +1 @@
1
- {"version":3,"file":"scanResultFixtures.d.ts","sourceRoot":"","sources":["../../../src/presentation/fixtures/scanResultFixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOjD,eAAO,MAAM,wBAAwB,EAAE,UA6BtC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,UAwBvC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,UAyBtC,CAAC"}
1
+ {"version":3,"file":"scanResultFixtures.d.ts","sourceRoot":"","sources":["../../../src/presentation/fixtures/scanResultFixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAYjD,eAAO,MAAM,wBAAwB,EAAE,UAiCtC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,UA2BvC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,UA4BtC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { assessmentFastifyRuntime, assessmentLimitedContext, assessmentTypescriptPatch, } from "../../fixtures/assessmentFixtures.js";
1
2
  import { fixtureRepoIntelligenceFastify, fixtureRepoIntelligenceTypescript, } from "../../fixtures/repoIntelligenceFixtures.js";
2
3
  import { analysisPreparationWithValidRepoIntel } from "../../fixtures/repoIntelligenceTestHelpers.js";
3
4
  export const scanResultFastifyRuntime = {
@@ -13,10 +14,14 @@ export const scanResultFastifyRuntime = {
13
14
  changedPackages: ["fastify"],
14
15
  analysisPreparation: analysisPreparationWithValidRepoIntel(),
15
16
  repoIntelligence: fixtureRepoIntelligenceFastify,
17
+ assessment: assessmentFastifyRuntime,
16
18
  decision: {
17
19
  recommendation: "needs_review",
18
20
  confidence: "medium",
19
- reasoning: [],
21
+ reasoning: [
22
+ "Changed package has confirmed usage on runtime application paths in this repository.",
23
+ "HTTP framework infrastructure",
24
+ ],
20
25
  },
21
26
  insights: [
22
27
  {
@@ -43,10 +48,13 @@ export const scanResultTypescriptPatch = {
43
48
  changedPackages: ["typescript"],
44
49
  analysisPreparation: analysisPreparationWithValidRepoIntel(),
45
50
  repoIntelligence: fixtureRepoIntelligenceTypescript,
51
+ assessment: assessmentTypescriptPatch,
46
52
  decision: {
47
53
  recommendation: "safe",
48
54
  confidence: "high",
49
- reasoning: [],
55
+ reasoning: [
56
+ "No dedicated dependency review required beyond normal engineering process.",
57
+ ],
50
58
  },
51
59
  graphInsights: {
52
60
  maxDepth: 4,
@@ -67,6 +75,7 @@ export const scanResultLimitedContext = {
67
75
  generatedAt: "2026-01-01T00:00:00.000Z",
68
76
  changedPackages: ["lodash"],
69
77
  repoIntelligence: { invalid: true },
78
+ assessment: assessmentLimitedContext,
70
79
  graphInsights: {
71
80
  maxDepth: 5,
72
81
  nodes: 200,
@@ -78,6 +87,8 @@ export const scanResultLimitedContext = {
78
87
  decision: {
79
88
  recommendation: "needs_review",
80
89
  confidence: "low",
81
- reasoning: [],
90
+ reasoning: [
91
+ "Collection evidence is partial; confidence is reduced but review posture is preserved when runtime signals exist.",
92
+ ],
82
93
  },
83
94
  };
@@ -7,14 +7,14 @@ export { buildScanDetailsPresentation } from "./orchestration/buildScanDetailsPr
7
7
  export type { BuildScanDetailsPresentationInput } from "./orchestration/buildScanDetailsPresentation.js";
8
8
  export type { PresentationProfile } from "./profile/presentationProfile.js";
9
9
  export type { PresentationIntent, PresentationInterpretation, } from "./intent/presentationIntent.js";
10
- export { derivePresentationInterpretation } from "./intent/derivePresentationInterpretation.js";
11
10
  export type { PipelineStatus, PresentationStatus, PresentationDensity, PresentationConfidence, PresentationPriority, PresentationEvidenceContext, PresentationEvidenceRow, } from "./dto/types.js";
12
- export type { ScanCardPresentation } from "./dto/scanCardPresentation.js";
11
+ export type { DashboardCardPresentation } from "./dto/dashboardCardPresentation.js";
12
+ export type { DashboardCardLayout } from "./dto/dashboardCardPresentation.js";
13
+ /** @deprecated Use DashboardCardPresentation */
14
+ export type { DashboardCardPresentation as ScanCardPresentation } from "./dto/dashboardCardPresentation.js";
13
15
  export type { ScanDetailsPresentation } from "./dto/scanDetailsPresentation.js";
14
16
  export type { GitHubCheckRunPresentation, GitHubPrCommentPresentation, CliScanPresentation, } from "./dto/githubAndCliPresentation.js";
15
- export { presentScanCard } from "./presenters/presentScanCard.js";
16
- export type { PresentScanCardContext } from "./presenters/presentScanCard.js";
17
- export { presentPipelineScanCard } from "./presenters/presentPipelineScanCard.js";
17
+ export { presentDashboardCard, presentPipelineDashboardCard, } from "./presenters/presentDashboardCard.js";
18
18
  export { presentScanDetails } from "./presenters/presentScanDetails.js";
19
19
  export type { PresentScanDetailsContext } from "./presenters/presentScanDetails.js";
20
20
  export { presentGitHubCheckRun } from "./presenters/presentGitHubCheckRun.js";
@@ -23,5 +23,5 @@ export { presentCliScanSummary } from "./presenters/presentCliScanSummary.js";
23
23
  export { renderGitHubCheckRunMarkdown } from "./render/renderGitHubCheckRunMarkdown.js";
24
24
  export { renderGitHubPrCommentMarkdown } from "./render/renderGitHubPrCommentMarkdown.js";
25
25
  export { renderCliScanSummaryText } from "./render/renderCliScanSummaryText.js";
26
- export { composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels, composeEvidenceRows, composeSupportingContext, evidenceContextFromProfile, } from "./compose/narrativeCompose.js";
26
+ export { buildNarrativeChannels, projectCompactKeyPoints, composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels, composeEvidenceRows, composeSupportingContext, evidenceContextFromProfile, } from "./compose/narrativeCompose.js";
27
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presentation/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC7F,YAAY,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AACvG,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAC;AACzF,YAAY,EAAE,8BAA8B,EAAE,MAAM,8CAA8C,CAAC;AACnG,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,YAAY,EAAE,iCAAiC,EAAE,MAAM,iDAAiD,CAAC;AAEzG,YAAY,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,YAAY,EACV,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,gCAAgC,EAAE,MAAM,8CAA8C,CAAC;AAChG,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,YAAY,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAChF,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,YAAY,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAO,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/presentation/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAC7F,YAAY,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AACvG,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAC;AACzF,YAAY,EAAE,8BAA8B,EAAE,MAAM,8CAA8C,CAAC;AACnG,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAC/F,YAAY,EAAE,iCAAiC,EAAE,MAAM,iDAAiD,CAAC;AAEzG,YAAY,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,YAAY,EACV,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AACpF,YAAY,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,gDAAgD;AAChD,YAAY,EAAE,yBAAyB,IAAI,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC5G,YAAY,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAChF,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AACxF,OAAO,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC"}
@@ -1,9 +1,7 @@
1
1
  export { buildScanPresentationBundle } from "./orchestration/buildScanPresentationBundle.js";
2
2
  export { buildScanCardPresentation } from "./orchestration/buildScanCardPresentation.js";
3
3
  export { buildScanDetailsPresentation } from "./orchestration/buildScanDetailsPresentation.js";
4
- export { derivePresentationInterpretation } from "./intent/derivePresentationInterpretation.js";
5
- export { presentScanCard } from "./presenters/presentScanCard.js";
6
- export { presentPipelineScanCard } from "./presenters/presentPipelineScanCard.js";
4
+ export { presentDashboardCard, presentPipelineDashboardCard, } from "./presenters/presentDashboardCard.js";
7
5
  export { presentScanDetails } from "./presenters/presentScanDetails.js";
8
6
  export { presentGitHubCheckRun } from "./presenters/presentGitHubCheckRun.js";
9
7
  export { presentGitHubPrComment } from "./presenters/presentGitHubPrComment.js";
@@ -11,4 +9,4 @@ export { presentCliScanSummary } from "./presenters/presentCliScanSummary.js";
11
9
  export { renderGitHubCheckRunMarkdown } from "./render/renderGitHubCheckRunMarkdown.js";
12
10
  export { renderGitHubPrCommentMarkdown } from "./render/renderGitHubPrCommentMarkdown.js";
13
11
  export { renderCliScanSummaryText } from "./render/renderCliScanSummaryText.js";
14
- export { composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels, composeEvidenceRows, composeSupportingContext, evidenceContextFromProfile, } from "./compose/narrativeCompose.js";
12
+ export { buildNarrativeChannels, projectCompactKeyPoints, composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels, composeEvidenceRows, composeSupportingContext, evidenceContextFromProfile, } from "./compose/narrativeCompose.js";
@@ -1,11 +1,11 @@
1
1
  import type { PipelineStatus } from "../dto/types.js";
2
2
  import type { ScanResult } from "../../types.js";
3
- import type { ScanCardPresentation } from "../dto/scanCardPresentation.js";
3
+ import type { DashboardCardPresentation } from "../dto/dashboardCardPresentation.js";
4
4
  export type BuildScanCardPresentationInput = {
5
5
  pipelineStatus: PipelineStatus;
6
6
  result: ScanResult | null;
7
7
  decision?: string | null;
8
8
  totalScore?: number | null;
9
9
  };
10
- export declare function buildScanCardPresentation(input: BuildScanCardPresentationInput): ScanCardPresentation;
10
+ export declare function buildScanCardPresentation(input: BuildScanCardPresentationInput): DashboardCardPresentation;
11
11
  //# sourceMappingURL=buildScanCardPresentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildScanCardPresentation.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/buildScanCardPresentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAKjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,MAAM,8BAA8B,GAAG;IAC3C,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AA2BF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,8BAA8B,GACpC,oBAAoB,CA2BtB"}
1
+ {"version":3,"file":"buildScanCardPresentation.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/buildScanCardPresentation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAUjD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAErF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AA+BF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,8BAA8B,GACpC,yBAAyB,CA2B3B"}
@@ -1,12 +1,13 @@
1
- import { mergePostureFromDecision } from "../../riskVocabulary.js";
1
+ import { assessmentLimitedContext } from "../../fixtures/assessmentFixtures.js";
2
+ import { mergePostureFromDecision, } from "../../riskVocabulary.js";
2
3
  import { buildScanPresentationBundle } from "./buildScanPresentationBundle.js";
3
- import { presentScanCard } from "../presenters/presentScanCard.js";
4
- import { presentPipelineScanCard } from "../presenters/presentPipelineScanCard.js";
4
+ import { presentDashboardCard, presentPipelineDashboardCard, } from "../presenters/presentDashboardCard.js";
5
5
  function minimalResultFromDenormalized(decision, totalScore) {
6
6
  const posture = mergePostureFromDecision(decision ?? undefined);
7
7
  if (!posture && (totalScore == null || !Number.isFinite(totalScore))) {
8
8
  return null;
9
9
  }
10
+ const resolvedPosture = posture;
10
11
  return {
11
12
  totalScore: totalScore ?? 0,
12
13
  layerScores: {
@@ -17,19 +18,22 @@ function minimalResultFromDenormalized(decision, totalScore) {
17
18
  },
18
19
  findings: [],
19
20
  generatedAt: new Date().toISOString(),
20
- decision: posture
21
- ? { recommendation: posture, confidence: "medium", reasoning: [] }
21
+ decision: resolvedPosture
22
+ ? { recommendation: resolvedPosture, confidence: "medium", reasoning: [] }
23
+ : undefined,
24
+ assessment: resolvedPosture
25
+ ? { ...assessmentLimitedContext, posture: resolvedPosture }
22
26
  : undefined,
23
27
  };
24
28
  }
25
29
  export function buildScanCardPresentation(input) {
26
30
  if (input.pipelineStatus !== "done") {
27
- return presentPipelineScanCard(input.pipelineStatus === "failed" ? "failed" : input.pipelineStatus);
31
+ return presentPipelineDashboardCard(input.pipelineStatus === "failed" ? "failed" : input.pipelineStatus);
28
32
  }
29
33
  const result = input.result ??
30
34
  minimalResultFromDenormalized(input.decision, input.totalScore);
31
35
  if (!result) {
32
- return presentPipelineScanCard("failed");
36
+ return presentPipelineDashboardCard("failed");
33
37
  }
34
38
  const bundle = buildScanPresentationBundle({
35
39
  result,
@@ -38,7 +42,7 @@ export function buildScanCardPresentation(input) {
38
42
  totalScore: input.totalScore,
39
43
  });
40
44
  if (!bundle) {
41
- return presentPipelineScanCard("failed");
45
+ return presentPipelineDashboardCard("failed");
42
46
  }
43
- return presentScanCard(bundle, { includeFindingCounts: true });
47
+ return presentDashboardCard(bundle);
44
48
  }
@@ -9,7 +9,7 @@ export type BuildScanPresentationBundleInput = {
9
9
  };
10
10
  /**
11
11
  * Mandatory orchestration entrypoint for completed-scan presentation.
12
- * Only place that calls deriveScanNarrative and derivePresentationProfile.
12
+ * Assessment is the sole authority; profile is a thin projection.
13
13
  */
14
14
  export declare function buildScanPresentationBundle(input: BuildScanPresentationBundleInput): ScanPresentationBundle | null;
15
15
  //# sourceMappingURL=buildScanPresentationBundle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildScanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/buildScanPresentationBundle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,UAAU,CAAC;IACnB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC,GACtC,sBAAsB,GAAG,IAAI,CAiB/B"}
1
+ {"version":3,"file":"buildScanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/buildScanPresentationBundle.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,UAAU,CAAC;IACnB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC,GACtC,sBAAsB,GAAG,IAAI,CAsB/B"}
@@ -1,23 +1,25 @@
1
+ import { parseAssessmentOrThrow, toPublicPresentation, } from "../../assessmentSchema.js";
1
2
  import { deriveScanNarrative } from "../../deriveScanNarrative.js";
2
- import { derivePresentationProfile } from "../profile/derivePresentationProfile.js";
3
+ import { buildProfileFromAssessment } from "../profile/buildProfileFromAssessment.js";
3
4
  /**
4
5
  * Mandatory orchestration entrypoint for completed-scan presentation.
5
- * Only place that calls deriveScanNarrative and derivePresentationProfile.
6
+ * Assessment is the sole authority; profile is a thin projection.
6
7
  */
7
8
  export function buildScanPresentationBundle(input) {
8
9
  if (input.pipelineStatus !== "done" || !input.result)
9
10
  return null;
10
- const facts = deriveScanNarrative(input.result);
11
- const profile = derivePresentationProfile(facts, {
12
- pipelineStatus: input.pipelineStatus,
13
- decision: input.decision,
14
- totalScore: input.totalScore ?? input.result.totalScore,
15
- });
16
- if (!profile)
11
+ const assessment = input.result.assessment;
12
+ if (!assessment)
17
13
  return null;
14
+ parseAssessmentOrThrow(assessment);
15
+ const presentation = toPublicPresentation(assessment.presentation);
16
+ const profile = buildProfileFromAssessment(assessment, presentation, input.result);
17
+ const facts = deriveScanNarrative(input.result);
18
18
  return {
19
- facts,
19
+ assessment,
20
+ presentation,
20
21
  profile,
22
+ facts,
21
23
  result: input.result,
22
24
  };
23
25
  }
@@ -1,15 +1,20 @@
1
+ import type { Assessment, AssessmentPresentationPublic } from "../../assessmentSchema.js";
1
2
  import type { ScanNarrativeFacts } from "../../scanNarrativeFacts.js";
2
3
  import type { ScanResult } from "../../types.js";
3
4
  import type { PresentationProfile } from "../profile/presentationProfile.js";
4
5
  export type ScanPresentationBundle = {
5
- facts: ScanNarrativeFacts;
6
+ assessment: Assessment;
7
+ presentation: AssessmentPresentationPublic;
6
8
  profile: PresentationProfile;
9
+ /**
10
+ * Evidence layout only — not an authority for posture, concern, or intensity.
11
+ * @deprecated Prefer assessment + repoIntelligence on result for new code.
12
+ */
13
+ facts: ScanNarrativeFacts;
7
14
  /**
8
15
  * Projection-only reference to the raw scan payload.
9
16
  * Presenters may read fields for formatting but must NOT re-derive interpretation.
10
17
  */
11
18
  result: ScanResult;
12
- /** Extension point for future shared derived artifacts */
13
- shared?: Record<string, unknown>;
14
19
  };
15
20
  //# sourceMappingURL=scanPresentationBundle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/scanPresentationBundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,OAAO,EAAE,mBAAmB,CAAC;IAC7B;;;OAGG;IACH,MAAM,EAAE,UAAU,CAAC;IACnB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC"}
1
+ {"version":3,"file":"scanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/scanPresentationBundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,4BAA4B,EAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,4BAA4B,CAAC;IAC3C,OAAO,EAAE,mBAAmB,CAAC;IAC7B;;;OAGG;IACH,KAAK,EAAE,kBAAkB,CAAC;IAC1B;;;OAGG;IACH,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { buildScanPresentationBundle } from "./orchestration/buildScanPresentationBundle.js";
3
- import { presentScanCard } from "./presenters/presentScanCard.js";
3
+ import { presentDashboardCard } from "./presenters/presentDashboardCard.js";
4
4
  import { presentScanDetails } from "./presenters/presentScanDetails.js";
5
5
  import { presentGitHubCheckRun } from "./presenters/presentGitHubCheckRun.js";
6
6
  import { presentGitHubPrComment } from "./presenters/presentGitHubPrComment.js";
@@ -43,32 +43,30 @@ describe("buildScanPresentationBundle", () => {
43
43
  expect(bundle.profile.degradedMessage).toBeTruthy();
44
44
  });
45
45
  });
46
- describe("presentScanCard personas", () => {
47
- it("fastify card is rich with affected areas and verification", () => {
46
+ describe("presentDashboardCard personas", () => {
47
+ it("fastify card has scope areas and verification", () => {
48
48
  const bundle = buildScanPresentationBundle({
49
49
  result: scanResultFastifyRuntime,
50
50
  pipelineStatus: "done",
51
51
  });
52
- const card = presentScanCard(bundle);
53
- expect(card.density).toBe("rich");
54
- expect(card.affectedAreas.length).toBeGreaterThan(0);
55
- expect(card.verificationActions.length).toBeGreaterThan(0);
52
+ const card = presentDashboardCard(bundle);
53
+ expect(card.layout).toBe("expanded");
54
+ expect(card.scopeAreas.length).toBeGreaterThan(0);
55
+ expect(card.verification.length).toBeGreaterThan(0);
56
56
  expect(card.headline.toLowerCase()).toContain("fastify");
57
- expect(card.supportingContext).toBeUndefined();
57
+ expect(card.verdict?.posture).toBe("needs_review");
58
58
  });
59
- it("typescript card is minimal safe without graph-first story", () => {
59
+ it("typescript card is quiet safe", () => {
60
60
  const bundle = buildScanPresentationBundle({
61
61
  result: scanResultTypescriptPatch,
62
62
  pipelineStatus: "done",
63
63
  });
64
- const card = presentScanCard(bundle);
65
- expect(card.density).toBe("minimal");
66
- expect(card.status).toBe("safe");
67
- expect(card.presentationIntent).toBe("tooling_patch");
64
+ const card = presentDashboardCard(bundle);
65
+ expect(["quiet", "standard"]).toContain(card.layout);
66
+ expect(card.verdict?.posture).toBe("safe");
68
67
  expect(card.headline).toMatch(/patch upgrade/i);
69
68
  expect(card.headline).not.toMatch(/needs review/i);
70
- expect(card.changedPackages).toContain("typescript");
71
- expect(card.verificationActions.length).toBeGreaterThan(0);
69
+ expect(card.verification.length).toBeGreaterThan(0);
72
70
  });
73
71
  });
74
72
  describe("presentation parity across surfaces", () => {
@@ -77,7 +75,7 @@ describe("presentation parity across surfaces", () => {
77
75
  result: scanResultFastifyRuntime,
78
76
  pipelineStatus: "done",
79
77
  });
80
- const card = presentScanCard(bundle);
78
+ const card = presentDashboardCard(bundle);
81
79
  const details = presentScanDetails(bundle, { scanId: SCAN_ID });
82
80
  const check = presentGitHubCheckRun(bundle, {
83
81
  scanId: SCAN_ID,
@@ -85,13 +83,13 @@ describe("presentation parity across surfaces", () => {
85
83
  });
86
84
  const comment = presentGitHubPrComment(bundle);
87
85
  const cli = presentCliScanSummary(bundle, { repoLabel: "acme/api" });
88
- for (const dto of [card, details, check, comment, cli]) {
86
+ for (const dto of [details, check, comment, cli]) {
89
87
  expect(dto.status).toBe(bundle.profile.status);
90
88
  expect(dto.density).toBe(bundle.profile.density);
91
89
  expect(dto.confidence).toBe(bundle.profile.confidence);
92
90
  expect(dto.evidenceContext?.priority).toBe(bundle.profile.priority);
93
91
  }
94
- expect(card.primaryPackage).toBe("fastify");
92
+ expect(card.verdict?.posture).toBe(bundle.profile.status);
95
93
  expect(details.narrative.primaryPackage).toBe("fastify");
96
94
  expect(check.title.toLowerCase()).toContain("fastify");
97
95
  });
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { buildScanPresentationBundle } from "./orchestration/buildScanPresentationBundle.js";
3
- import { presentScanCard } from "./presenters/presentScanCard.js";
3
+ import { presentDashboardCard } from "./presenters/presentDashboardCard.js";
4
4
  import { presentScanDetails } from "./presenters/presentScanDetails.js";
5
5
  import { presentCliScanSummary } from "./presenters/presentCliScanSummary.js";
6
6
  import { scanResultBullmq, scanResultEslint, scanResultFastifyRuntime, scanResultLimitedContext, scanResultMixedTypescriptFastify, scanResultNextAuth, scanResultPrettier, scanResultTypescriptPatch, scanResultUnknownSafe, scanResultVitest, } from "./fixtures/presentationPersonaFixtures.js";
@@ -25,9 +25,9 @@ const personas = [
25
25
  intent: "tooling_upgrade",
26
26
  status: "safe",
27
27
  density: "minimal",
28
- headlineMatch: /tooling upgrade/i,
28
+ headlineMatch: /patch upgrade/i,
29
29
  headlineMustNot: /needs review/i,
30
- verificationIncludes: ["CI", "lint"],
30
+ verificationIncludes: ["ci", "lint"],
31
31
  },
32
32
  {
33
33
  name: "prettier",
@@ -35,7 +35,7 @@ const personas = [
35
35
  intent: "tooling_upgrade",
36
36
  status: "safe",
37
37
  density: "minimal",
38
- headlineMatch: /tooling upgrade/i,
38
+ headlineMatch: /patch upgrade/i,
39
39
  headlineMustNot: /needs review/i,
40
40
  verificationIncludes: ["format"],
41
41
  },
@@ -45,9 +45,9 @@ const personas = [
45
45
  intent: "tooling_upgrade",
46
46
  status: "safe",
47
47
  density: "minimal",
48
- headlineMatch: /tooling upgrade/i,
48
+ headlineMatch: /patch upgrade|dependency upgrade/i,
49
49
  headlineMustNot: /needs review/i,
50
- verificationIncludes: ["test suite"],
50
+ verificationIncludes: ["test"],
51
51
  },
52
52
  {
53
53
  name: "fastify runtime",
@@ -65,7 +65,7 @@ const personas = [
65
65
  status: "needs_review",
66
66
  density: "rich",
67
67
  headlineMatch: /runtime upgrade affects/i,
68
- verificationIncludes: ["auth flow"],
68
+ verificationIncludes: ["auth_flow"],
69
69
  },
70
70
  {
71
71
  name: "bullmq runtime",
@@ -99,15 +99,16 @@ function cardFor(result) {
99
99
  result,
100
100
  pipelineStatus: "done",
101
101
  });
102
- return presentScanCard(bundle);
102
+ return presentDashboardCard(bundle);
103
103
  }
104
104
  describe("presentation personas", () => {
105
105
  for (const persona of personas) {
106
106
  it(`${persona.name}: intent, posture alignment, headline`, () => {
107
107
  const card = cardFor(persona.result);
108
- expect(card.presentationIntent).toBe(persona.intent);
109
- expect(card.status).toBe(persona.status);
110
- expect(card.density).toBe(persona.density);
108
+ expect(card.verdict?.posture).toBe(persona.status);
109
+ if (persona.density === "rich") {
110
+ expect(card.layout).toBe("expanded");
111
+ }
111
112
  expect(card.headline).toMatch(persona.headlineMatch);
112
113
  if (persona.headlineMustNot) {
113
114
  expect(card.headline).not.toMatch(persona.headlineMustNot);
@@ -115,28 +116,28 @@ describe("presentation personas", () => {
115
116
  if (persona.status === "safe") {
116
117
  const combined = [
117
118
  card.headline,
118
- ...card.keyPoints,
119
- ...card.verificationActions,
119
+ ...card.insights,
120
+ ...card.verification,
120
121
  ].join(" ");
121
122
  expect(combined).not.toMatch(SAFE_FORBIDDEN);
122
123
  }
123
124
  if (persona.status === "needs_review") {
124
- const combined = card.verificationActions.join(" ");
125
+ const combined = card.verification.join(" ");
125
126
  expect(combined).not.toMatch(REVIEW_FORBIDDEN);
126
127
  }
127
128
  if (persona.verificationIncludes) {
128
129
  for (const v of persona.verificationIncludes) {
129
- expect(card.verificationActions.some((a) => a.toLowerCase().includes(v.toLowerCase()))).toBe(true);
130
+ expect(card.verification.some((a) => a.toLowerCase().includes(v.toLowerCase()))).toBe(true);
130
131
  }
131
132
  }
132
133
  if (persona.verificationMustNot) {
133
- expect(card.verificationActions.join(" ")).not.toMatch(persona.verificationMustNot);
134
+ expect(card.verification.join(" ")).not.toMatch(persona.verificationMustNot);
134
135
  }
135
136
  });
136
137
  }
137
138
  it("mixed typescript+fastify: runtime intent, fastify in headline", () => {
138
139
  const card = cardFor(scanResultMixedTypescriptFastify);
139
- expect(card.presentationIntent).toBe("runtime_upgrade");
140
+ expect(card.verdict?.posture).toBe("needs_review");
140
141
  expect(card.headline.toLowerCase()).toContain("fastify");
141
142
  expect(card.headline).not.toMatch(/patch upgrade/i);
142
143
  });
@@ -145,7 +146,7 @@ describe("presentation personas", () => {
145
146
  result: scanResultFastifyRuntime,
146
147
  pipelineStatus: "done",
147
148
  });
148
- const card = presentScanCard(bundle);
149
+ const card = presentDashboardCard(bundle);
149
150
  const details = presentScanDetails(bundle, { scanId: SCAN_ID });
150
151
  const cli = presentCliScanSummary(bundle, { repoLabel: "acme/api" });
151
152
  expect(details.hero.headline).toBe(card.headline);
@@ -156,7 +157,7 @@ describe("presentation personas", () => {
156
157
  result: scanResultTypescriptPatch,
157
158
  pipelineStatus: "done",
158
159
  });
159
- const card = presentScanCard(bundle);
160
+ const card = presentDashboardCard(bundle);
160
161
  const details = presentScanDetails(bundle, { scanId: SCAN_ID });
161
162
  const cli = presentCliScanSummary(bundle, { repoLabel: "acme/api" });
162
163
  expect(details.hero.headline).toBe(card.headline);
@@ -1 +1 @@
1
- {"version":3,"file":"presentCliScanSummary.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentCliScanSummary.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEzF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,sBAAsB,EAC9B,GAAG,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,mBAAmB,CA6BrB"}
1
+ {"version":3,"file":"presentCliScanSummary.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentCliScanSummary.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,sBAAsB,EAC9B,GAAG,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,mBAAmB,CA8BrB"}
@@ -1,4 +1,5 @@
1
- import { composeHeadline, composeKeyPoints, composeSubheadline, composeSupportingContext, composeVerificationActions, evidenceContextFromProfile, } from "../compose/narrativeCompose.js";
1
+ import { buildNarrativeChannels, composeHeadline, composeSubheadline, composeSupportingContext, composeVerificationActions, evidenceContextFromProfile, projectCompactKeyPoints, } from "../compose/narrativeCompose.js";
2
+ import { projectAssessmentFields } from "../projectAssessmentFields.js";
2
3
  export function presentCliScanSummary(bundle, ctx = {}) {
3
4
  const { facts, profile, result } = bundle;
4
5
  const layers = result.layerScores;
@@ -6,6 +7,7 @@ export function presentCliScanSummary(bundle, ctx = {}) {
6
7
  ? `security=${layers.security} maintainability=${layers.maintainability} ecosystem=${layers.ecosystem} upgradeImpact=${layers.upgradeImpact}`
7
8
  : "";
8
9
  return {
10
+ ...projectAssessmentFields(bundle),
9
11
  header: {
10
12
  repoLabel: ctx.repoLabel ?? "scan",
11
13
  methodology: result.methodologyVersion ?? undefined,
@@ -17,7 +19,7 @@ export function presentCliScanSummary(bundle, ctx = {}) {
17
19
  evidenceContext: evidenceContextFromProfile(bundle),
18
20
  headline: composeHeadline(bundle),
19
21
  subheadline: composeSubheadline(bundle),
20
- keyPoints: composeKeyPoints(bundle, 6),
22
+ keyPoints: projectCompactKeyPoints(buildNarrativeChannels(bundle), 6),
21
23
  verificationActions: composeVerificationActions(bundle, 5),
22
24
  metrics: {
23
25
  riskIndex: facts.riskIndex ?? result.totalScore ?? 0,
@@ -0,0 +1,5 @@
1
+ import type { DashboardCardPresentation } from "../dto/dashboardCardPresentation.js";
2
+ import type { ScanPresentationBundle } from "../orchestration/scanPresentationBundle.js";
3
+ export declare function presentDashboardCard(bundle: ScanPresentationBundle): DashboardCardPresentation;
4
+ export declare function presentPipelineDashboardCard(pipelineStatus: "queued" | "running" | "failed"): DashboardCardPresentation;
5
+ //# sourceMappingURL=presentDashboardCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentDashboardCard.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentDashboardCard.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAoEzF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,sBAAsB,GAC7B,yBAAyB,CA8C3B;AAED,wBAAgB,4BAA4B,CAC1C,cAAc,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAC9C,yBAAyB,CAqB3B"}