@mergesignal/shared 0.12.0 → 0.12.2
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/dist/deriveScanNarrative.d.ts.map +1 -1
- package/dist/deriveScanNarrative.js +4 -0
- package/dist/formatInsight.d.ts +3 -3
- package/dist/formatInsight.d.ts.map +1 -1
- package/dist/formatInsight.js +0 -9
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/prRiskBand.d.ts +7 -0
- package/dist/prRiskBand.d.ts.map +1 -1
- package/dist/prRiskBand.js +12 -0
- package/dist/prRiskBand.test.js +12 -1
- package/dist/presentation/abi3Expression.test.js +46 -0
- package/dist/presentation/bundleAccessorParity.test.d.ts +9 -0
- package/dist/presentation/bundleAccessorParity.test.d.ts.map +1 -0
- package/dist/presentation/bundleAccessorParity.test.js +126 -0
- package/dist/presentation/cliParity.test.d.ts +2 -0
- package/dist/presentation/cliParity.test.d.ts.map +1 -0
- package/dist/presentation/cliParity.test.js +49 -0
- package/dist/presentation/compose/narrativeCompose.d.ts +0 -4
- package/dist/presentation/compose/narrativeCompose.d.ts.map +1 -1
- package/dist/presentation/compose/narrativeCompose.js +0 -20
- package/dist/presentation/decisionSurface.test.d.ts +2 -0
- package/dist/presentation/decisionSurface.test.d.ts.map +1 -0
- package/dist/presentation/decisionSurface.test.js +290 -0
- package/dist/presentation/dto/assessmentPresentationFields.d.ts +4 -0
- package/dist/presentation/dto/assessmentPresentationFields.d.ts.map +1 -1
- package/dist/presentation/index.d.ts +1 -1
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +1 -1
- package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts +1 -0
- package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts.map +1 -1
- package/dist/presentation/orchestration/buildScanPresentationBundle.js +4 -1
- package/dist/presentation/orchestration/scanPresentationBundle.d.ts +4 -4
- package/dist/presentation/orchestration/scanPresentationBundle.d.ts.map +1 -1
- package/dist/presentation/presenters/presentCliScanSummary.d.ts.map +1 -1
- package/dist/presentation/presenters/presentCliScanSummary.js +9 -7
- package/dist/presentation/presenters/presentGitHubCheckRun.d.ts.map +1 -1
- package/dist/presentation/presenters/presentGitHubCheckRun.js +11 -12
- package/dist/presentation/presenters/presentGitHubPrComment.d.ts.map +1 -1
- package/dist/presentation/presenters/presentGitHubPrComment.js +11 -10
- package/dist/presentation/presenters/presentScanDetails.d.ts.map +1 -1
- package/dist/presentation/presenters/presentScanDetails.js +8 -11
- package/dist/presentation/projectAssessmentFields.d.ts.map +1 -1
- package/dist/presentation/projectAssessmentFields.js +6 -0
- package/dist/presentation/surfaceParity.test.js +8 -0
- package/dist/scanResultSchema.d.ts +158 -0
- package/dist/scanResultSchema.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/scanDetailViewModelTypes.d.ts +0 -159
- package/dist/scanDetailViewModelTypes.d.ts.map +0 -1
- package/dist/scanDetailViewModelTypes.js +0 -4
- package/dist/truncateCardSummary.d.ts +0 -5
- package/dist/truncateCardSummary.d.ts.map +0 -1
- package/dist/truncateCardSummary.js +0 -23
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { extractAuthoredCommunication } from "@mergesignal/contracts";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { minimalReviewFocalPoint, reachScopeFor, verificationScopeFor, withAssessmentScope, } from "../fixtures/assessmentScopeFixtures.js";
|
|
4
|
+
import { buildScanPresentationBundle } from "./orchestration/buildScanPresentationBundle.js";
|
|
5
|
+
// ─── Vocabulary firewall ──────────────────────────────────────────────────────
|
|
6
|
+
/** Engine vocabulary that must never appear in any developer-facing authored string. */
|
|
7
|
+
const ENGINE_VOCABULARY = [
|
|
8
|
+
"constraint_satisfiability",
|
|
9
|
+
"lockfile_integrity",
|
|
10
|
+
"type_surface_compatibility",
|
|
11
|
+
"export_resolution",
|
|
12
|
+
"peer_dependency",
|
|
13
|
+
"engine_constraint",
|
|
14
|
+
"no_impact_proven",
|
|
15
|
+
"proof_pass",
|
|
16
|
+
"bounded_verify",
|
|
17
|
+
"representative_precision_only",
|
|
18
|
+
"architectural_precision_only",
|
|
19
|
+
"clearanceEnvelope",
|
|
20
|
+
"coverageClass",
|
|
21
|
+
"precisionLevel",
|
|
22
|
+
"proofArtifact",
|
|
23
|
+
"packageOutcome",
|
|
24
|
+
"qualityClass",
|
|
25
|
+
"qualityBasis",
|
|
26
|
+
"proofFingerprint",
|
|
27
|
+
"observationId",
|
|
28
|
+
"dimension_verification",
|
|
29
|
+
];
|
|
30
|
+
// ─── Fixture helpers ──────────────────────────────────────────────────────────
|
|
31
|
+
function scanResultWith(assessment) {
|
|
32
|
+
return {
|
|
33
|
+
totalScore: 70,
|
|
34
|
+
layerScores: {
|
|
35
|
+
security: 70,
|
|
36
|
+
maintainability: 70,
|
|
37
|
+
ecosystem: 70,
|
|
38
|
+
upgradeImpact: 70,
|
|
39
|
+
},
|
|
40
|
+
findings: [],
|
|
41
|
+
generatedAt: "2026-01-01T00:00:00Z",
|
|
42
|
+
changedPackages: assessment.reviewFocalPoint.anchors,
|
|
43
|
+
methodologyVersion: "mergesignal-engine/test",
|
|
44
|
+
assessment,
|
|
45
|
+
decision: {
|
|
46
|
+
recommendation: "needs_review",
|
|
47
|
+
confidence: "medium",
|
|
48
|
+
reasoning: [],
|
|
49
|
+
},
|
|
50
|
+
insights: [],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function assessmentWithTrustLine() {
|
|
54
|
+
return withAssessmentScope({
|
|
55
|
+
posture: "safe",
|
|
56
|
+
confidence: "high",
|
|
57
|
+
primaryConcern: null,
|
|
58
|
+
concerns: [],
|
|
59
|
+
factors: [],
|
|
60
|
+
changeClasses: [],
|
|
61
|
+
presentation: {
|
|
62
|
+
narrativeIntensity: "standard",
|
|
63
|
+
reachVisibility: "contextual",
|
|
64
|
+
verificationIntensity: "none",
|
|
65
|
+
insightEmissionFloor: "full",
|
|
66
|
+
reportMode: "high_signal_pr",
|
|
67
|
+
},
|
|
68
|
+
reasoning: [
|
|
69
|
+
"All peer dependency constraints verified — no runtime breakage confirmed.",
|
|
70
|
+
"Export compatibility proven unused in this repository.",
|
|
71
|
+
],
|
|
72
|
+
confidenceRationale: "Confidence is high: all assessed dimensions were verified by deterministic proof.",
|
|
73
|
+
}, {
|
|
74
|
+
reviewFocalPoint: minimalReviewFocalPoint(["express"]),
|
|
75
|
+
reachScope: reachScopeFor(["express"]),
|
|
76
|
+
verificationScope: verificationScopeFor(["express"]),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function assessmentWithElectionSummary() {
|
|
80
|
+
return withAssessmentScope({
|
|
81
|
+
posture: "needs_review",
|
|
82
|
+
confidence: "medium",
|
|
83
|
+
primaryConcern: "confirmed_runtime_usage",
|
|
84
|
+
concerns: [
|
|
85
|
+
{
|
|
86
|
+
kind: "confirmed_runtime_usage",
|
|
87
|
+
rank: 1,
|
|
88
|
+
packages: ["fastify"],
|
|
89
|
+
evidenceRefs: [],
|
|
90
|
+
context: "Runtime usage: `fastify` — used in HTTP request handling.",
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
factors: ["confirmed_runtime_usage"],
|
|
94
|
+
changeClasses: ["runtime_upgrade"],
|
|
95
|
+
presentation: {
|
|
96
|
+
narrativeIntensity: "standard",
|
|
97
|
+
reachVisibility: "contextual",
|
|
98
|
+
verificationIntensity: "required",
|
|
99
|
+
insightEmissionFloor: "full",
|
|
100
|
+
reportMode: "high_signal_pr",
|
|
101
|
+
},
|
|
102
|
+
reasoning: [
|
|
103
|
+
"fastify is used in HTTP request handling in this repository.",
|
|
104
|
+
],
|
|
105
|
+
confidenceRationale: "Confidence is medium: runtime usage was observed but proof coverage is representative.",
|
|
106
|
+
notAffectedLine: null,
|
|
107
|
+
resolutionLine: null,
|
|
108
|
+
}, {
|
|
109
|
+
reviewFocalPoint: {
|
|
110
|
+
episodeShape: "single_anchor",
|
|
111
|
+
anchors: ["fastify"],
|
|
112
|
+
electionSummary: "`fastify` was selected as the review anchor over `fastify-plugin` due to higher runtime reach.",
|
|
113
|
+
election: {
|
|
114
|
+
grounding: [
|
|
115
|
+
{
|
|
116
|
+
packageName: "fastify",
|
|
117
|
+
reason: "highest_runtime_reach",
|
|
118
|
+
decidedBy: "reach",
|
|
119
|
+
evidenceRefs: [],
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
exclusions: [
|
|
123
|
+
{
|
|
124
|
+
packageName: "fastify-plugin",
|
|
125
|
+
reason: "lower_runtime_reach",
|
|
126
|
+
lostOn: "reach",
|
|
127
|
+
evidenceRefs: [],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
reachScope: reachScopeFor(["fastify"]),
|
|
133
|
+
verificationScope: verificationScopeFor(["fastify"]),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function assessmentUncontestedElection() {
|
|
137
|
+
return withAssessmentScope({
|
|
138
|
+
posture: "needs_review",
|
|
139
|
+
confidence: "medium",
|
|
140
|
+
primaryConcern: "confirmed_runtime_usage",
|
|
141
|
+
concerns: [],
|
|
142
|
+
factors: ["confirmed_runtime_usage"],
|
|
143
|
+
changeClasses: ["runtime_upgrade"],
|
|
144
|
+
presentation: {
|
|
145
|
+
narrativeIntensity: "standard",
|
|
146
|
+
reachVisibility: "contextual",
|
|
147
|
+
verificationIntensity: "required",
|
|
148
|
+
insightEmissionFloor: "full",
|
|
149
|
+
reportMode: "high_signal_pr",
|
|
150
|
+
},
|
|
151
|
+
reasoning: ["express is used in HTTP request handling."],
|
|
152
|
+
confidenceRationale: "Confidence is high: runtime usage was directly observed.",
|
|
153
|
+
}, {
|
|
154
|
+
reviewFocalPoint: minimalReviewFocalPoint(["express"]),
|
|
155
|
+
reachScope: reachScopeFor(["express"]),
|
|
156
|
+
verificationScope: verificationScopeFor(["express"]),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function assessmentWithQ8Q9() {
|
|
160
|
+
return withAssessmentScope({
|
|
161
|
+
posture: "needs_review",
|
|
162
|
+
confidence: "medium",
|
|
163
|
+
primaryConcern: "confirmed_runtime_usage",
|
|
164
|
+
concerns: [],
|
|
165
|
+
factors: ["confirmed_runtime_usage"],
|
|
166
|
+
changeClasses: ["runtime_upgrade"],
|
|
167
|
+
outcome: "bounded_verify",
|
|
168
|
+
presentation: {
|
|
169
|
+
narrativeIntensity: "standard",
|
|
170
|
+
reachVisibility: "contextual",
|
|
171
|
+
verificationIntensity: "required",
|
|
172
|
+
insightEmissionFloor: "full",
|
|
173
|
+
reportMode: "high_signal_pr",
|
|
174
|
+
},
|
|
175
|
+
reasoning: ["Automation stopped before all dimensions were verified."],
|
|
176
|
+
confidenceRationale: "Confidence is medium: bounded verification is required.",
|
|
177
|
+
notAffectedLine: "No repository code paths are affected by export compatibility — this dimension is outside the review scope.",
|
|
178
|
+
resolutionLine: "A passing automated verification for this dimension would make this deterministic.",
|
|
179
|
+
}, {
|
|
180
|
+
reviewFocalPoint: minimalReviewFocalPoint(["express"]),
|
|
181
|
+
reachScope: reachScopeFor(["express"]),
|
|
182
|
+
verificationScope: {
|
|
183
|
+
packages: ["express"],
|
|
184
|
+
focus: [],
|
|
185
|
+
guidance: ["Verify route handler at `src/server.ts:42`."],
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// ─── V1 bundle transport ──────────────────────────────────────────────────────
|
|
190
|
+
describe("decision surface contract (V1) — bundle transport", () => {
|
|
191
|
+
it("trustLine carries confidenceRationale verbatim from assessment", () => {
|
|
192
|
+
const assessment = assessmentWithTrustLine();
|
|
193
|
+
const bundle = buildScanPresentationBundle({
|
|
194
|
+
result: scanResultWith(assessment),
|
|
195
|
+
pipelineStatus: "done",
|
|
196
|
+
});
|
|
197
|
+
expect(bundle).not.toBeNull();
|
|
198
|
+
expect(bundle.trustLine).toBe(assessment.confidenceRationale);
|
|
199
|
+
});
|
|
200
|
+
it("whyThisPackageLine carries electionSummary verbatim when present", () => {
|
|
201
|
+
const assessment = assessmentWithElectionSummary();
|
|
202
|
+
const bundle = buildScanPresentationBundle({
|
|
203
|
+
result: scanResultWith(assessment),
|
|
204
|
+
pipelineStatus: "done",
|
|
205
|
+
});
|
|
206
|
+
expect(bundle.whyThisPackageLine).toBe(assessment.reviewFocalPoint.electionSummary);
|
|
207
|
+
});
|
|
208
|
+
it("whyThisPackageLine is null when electionSummary is absent", () => {
|
|
209
|
+
const assessment = assessmentUncontestedElection();
|
|
210
|
+
const bundle = buildScanPresentationBundle({
|
|
211
|
+
result: scanResultWith(assessment),
|
|
212
|
+
pipelineStatus: "done",
|
|
213
|
+
});
|
|
214
|
+
expect(bundle.whyThisPackageLine).toBeNull();
|
|
215
|
+
});
|
|
216
|
+
it("reasoningLines and guidanceLines carry assessment arrays verbatim", () => {
|
|
217
|
+
const assessment = assessmentWithQ8Q9();
|
|
218
|
+
const bundle = buildScanPresentationBundle({
|
|
219
|
+
result: scanResultWith(assessment),
|
|
220
|
+
pipelineStatus: "done",
|
|
221
|
+
});
|
|
222
|
+
expect(bundle.reasoningLines).toEqual(assessment.reasoning);
|
|
223
|
+
expect(bundle.guidanceLines).toEqual(assessment.verificationScope.guidance ?? []);
|
|
224
|
+
});
|
|
225
|
+
it("notAffectedLine and resolutionLine survive parse and transport (Q8/Q9)", () => {
|
|
226
|
+
const assessment = assessmentWithQ8Q9();
|
|
227
|
+
const bundle = buildScanPresentationBundle({
|
|
228
|
+
result: scanResultWith(assessment),
|
|
229
|
+
pipelineStatus: "done",
|
|
230
|
+
});
|
|
231
|
+
expect(bundle.notAffectedLine).toBe(assessment.notAffectedLine);
|
|
232
|
+
expect(bundle.resolutionLine).toBe(assessment.resolutionLine);
|
|
233
|
+
});
|
|
234
|
+
it("concernContextLines carries concerns[].context verbatim", () => {
|
|
235
|
+
const assessment = assessmentWithElectionSummary();
|
|
236
|
+
const bundle = buildScanPresentationBundle({
|
|
237
|
+
result: scanResultWith(assessment),
|
|
238
|
+
pipelineStatus: "done",
|
|
239
|
+
});
|
|
240
|
+
expect(bundle.concernContextLines).toEqual([
|
|
241
|
+
"Runtime usage: `fastify` — used in HTTP request handling.",
|
|
242
|
+
]);
|
|
243
|
+
});
|
|
244
|
+
it("public bundle accessors match extractAuthoredCommunication", () => {
|
|
245
|
+
const assessment = assessmentWithQ8Q9();
|
|
246
|
+
const normalized = assessment;
|
|
247
|
+
const expected = extractAuthoredCommunication(normalized);
|
|
248
|
+
const bundle = buildScanPresentationBundle({
|
|
249
|
+
result: scanResultWith(assessment),
|
|
250
|
+
pipelineStatus: "done",
|
|
251
|
+
});
|
|
252
|
+
expect(bundle.trustLine).toBe(expected.trustLine);
|
|
253
|
+
expect(bundle.whyThisPackageLine).toBe(expected.whyThisPackageLine);
|
|
254
|
+
expect(bundle.notAffectedLine).toBe(expected.notAffectedLine);
|
|
255
|
+
expect(bundle.resolutionLine).toBe(expected.resolutionLine);
|
|
256
|
+
expect(bundle.reasoningLines).toEqual(expected.reasoningLines);
|
|
257
|
+
expect(bundle.guidanceLines).toEqual(expected.guidanceLines);
|
|
258
|
+
expect(bundle.concernContextLines).toEqual(expected.concernContextLines);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
// ─── Vocabulary firewall ──────────────────────────────────────────────────────
|
|
262
|
+
describe("decision surface contract (V1) — vocabulary firewall on accessors", () => {
|
|
263
|
+
function assertNoEngineVocabulary(strings, context) {
|
|
264
|
+
for (const token of ENGINE_VOCABULARY) {
|
|
265
|
+
for (const str of strings) {
|
|
266
|
+
if (!str)
|
|
267
|
+
continue;
|
|
268
|
+
expect(str, `${context}: must not contain engine token "${token}"`).not.toContain(token);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
it("bundle accessors carry no engine vocabulary", () => {
|
|
273
|
+
const assessment = assessmentWithQ8Q9();
|
|
274
|
+
const bundle = buildScanPresentationBundle({
|
|
275
|
+
result: scanResultWith(assessment),
|
|
276
|
+
pipelineStatus: "done",
|
|
277
|
+
});
|
|
278
|
+
assertNoEngineVocabulary([
|
|
279
|
+
bundle.trustLine,
|
|
280
|
+
bundle.whyThisPackageLine,
|
|
281
|
+
bundle.notAffectedLine,
|
|
282
|
+
bundle.resolutionLine,
|
|
283
|
+
...bundle.reasoningLines,
|
|
284
|
+
...bundle.guidanceLines,
|
|
285
|
+
...bundle.concernContextLines,
|
|
286
|
+
], "bundle accessors");
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
// V3 surface delivery (Dashboard, Scan Details) is intentionally excluded from V1 graduation.
|
|
290
|
+
// See presentDashboardCard / presentScanDetails adoption in V3 Surface Adoption roadmap.
|
|
@@ -10,5 +10,9 @@ export type AssessmentPresentationFields = {
|
|
|
10
10
|
verificationChannel: VerificationChannel;
|
|
11
11
|
reachVisibility: ReachVisibility;
|
|
12
12
|
narrativeIntensity: NarrativeIntensity;
|
|
13
|
+
/** ABI 3 expression — optional confidence explanation. */
|
|
14
|
+
confidenceRationale?: string;
|
|
15
|
+
/** ABI 3 expression — optional focal-election narrative. */
|
|
16
|
+
electionSummary?: string;
|
|
13
17
|
};
|
|
14
18
|
//# sourceMappingURL=assessmentPresentationFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assessmentPresentationFields.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/assessmentPresentationFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,uEAAuE;AACvE,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAC;IAC3C,cAAc,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"assessmentPresentationFields.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/assessmentPresentationFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,uEAAuE;AACvE,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAC;IAC3C,cAAc,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,0DAA0D;IAC1D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC"}
|
|
@@ -24,5 +24,5 @@ export { renderGitHubCheckRunMarkdown } from "./render/renderGitHubCheckRunMarkd
|
|
|
24
24
|
export { buildGitHubCheckRunOutput, resolveWebAppOrigin, type GitHubCheckRunConclusion, type GitHubCheckRunOutput, type BuildGitHubCheckRunOutputOptions, } from "./buildGitHubCheckRunOutput.js";
|
|
25
25
|
export { renderGitHubPrCommentMarkdown } from "./render/renderGitHubPrCommentMarkdown.js";
|
|
26
26
|
export { renderCliScanSummaryText } from "./render/renderCliScanSummaryText.js";
|
|
27
|
-
export { buildNarrativeChannels, projectCompactKeyPoints, composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels,
|
|
27
|
+
export { buildNarrativeChannels, projectCompactKeyPoints, composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels, composeSupportingContext, evidenceContextFromProfile, } from "./compose/narrativeCompose.js";
|
|
28
28
|
//# 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,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,EAC5B,sCAAsC,GACvC,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,EACL,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,GACtC,MAAM,gCAAgC,CAAC;AACxC,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,
|
|
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,EAC5B,sCAAsC,GACvC,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,EACL,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,gCAAgC,GACtC,MAAM,gCAAgC,CAAC;AACxC,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,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC"}
|
|
@@ -10,4 +10,4 @@ export { renderGitHubCheckRunMarkdown } from "./render/renderGitHubCheckRunMarkd
|
|
|
10
10
|
export { buildGitHubCheckRunOutput, resolveWebAppOrigin, } from "./buildGitHubCheckRunOutput.js";
|
|
11
11
|
export { renderGitHubPrCommentMarkdown } from "./render/renderGitHubPrCommentMarkdown.js";
|
|
12
12
|
export { renderCliScanSummaryText } from "./render/renderCliScanSummaryText.js";
|
|
13
|
-
export { buildNarrativeChannels, projectCompactKeyPoints, composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels,
|
|
13
|
+
export { buildNarrativeChannels, projectCompactKeyPoints, composeHeadline, composeSubheadline, composeKeyPoints, composeVerificationActions, composeAffectedAreaLabels, composeSupportingContext, evidenceContextFromProfile, } from "./compose/narrativeCompose.js";
|
|
@@ -9,6 +9,7 @@ export type BuildScanPresentationBundleInput = {
|
|
|
9
9
|
/**
|
|
10
10
|
* Mandatory orchestration entrypoint for completed-scan presentation.
|
|
11
11
|
* Assessment is the sole authority; profile is a thin projection.
|
|
12
|
+
* Consumes only the public ScanResult contract — see docs/engineering/presentation-ownership.md.
|
|
12
13
|
*/
|
|
13
14
|
export declare function buildScanPresentationBundle(input: BuildScanPresentationBundleInput): ScanPresentationBundle | null;
|
|
14
15
|
//# sourceMappingURL=buildScanPresentationBundle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildScanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/buildScanPresentationBundle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"buildScanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/buildScanPresentationBundle.ts"],"names":[],"mappings":"AAMA,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;CAC1B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,gCAAgC,GACtC,sBAAsB,GAAG,IAAI,CA8B/B"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { parseAssessmentOrThrow } from "@mergesignal/contracts";
|
|
1
|
+
import { extractAuthoredCommunication, parseAssessmentOrThrow, } from "@mergesignal/contracts";
|
|
2
2
|
import { toPublicPresentation } from "../../assessmentPresentationUtils.js";
|
|
3
3
|
import { deriveScanNarrative } from "../../deriveScanNarrative.js";
|
|
4
4
|
import { buildProfileFromAssessment } from "../profile/buildProfileFromAssessment.js";
|
|
5
5
|
/**
|
|
6
6
|
* Mandatory orchestration entrypoint for completed-scan presentation.
|
|
7
7
|
* Assessment is the sole authority; profile is a thin projection.
|
|
8
|
+
* Consumes only the public ScanResult contract — see docs/engineering/presentation-ownership.md.
|
|
8
9
|
*/
|
|
9
10
|
export function buildScanPresentationBundle(input) {
|
|
10
11
|
if (input.pipelineStatus !== "done" || !input.result)
|
|
@@ -22,11 +23,13 @@ export function buildScanPresentationBundle(input) {
|
|
|
22
23
|
const presentation = toPublicPresentation(normalized.presentation);
|
|
23
24
|
const profile = buildProfileFromAssessment(normalized, presentation, input.result);
|
|
24
25
|
const facts = deriveScanNarrative(input.result);
|
|
26
|
+
const authored = extractAuthoredCommunication(normalized);
|
|
25
27
|
return {
|
|
26
28
|
assessment: normalized,
|
|
27
29
|
presentation,
|
|
28
30
|
profile,
|
|
29
31
|
facts,
|
|
30
32
|
result: input.result,
|
|
33
|
+
...authored,
|
|
31
34
|
};
|
|
32
35
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { Assessment, AssessmentPresentationPublic } from "@mergesignal/contracts";
|
|
1
|
+
import type { Assessment, AssessmentPresentationPublic, AuthoredCommunicationAccessors } from "@mergesignal/contracts";
|
|
2
2
|
import type { ScanNarrativeFacts } from "../../scanNarrativeFacts.js";
|
|
3
3
|
import type { ScanResult } from "../../types.js";
|
|
4
4
|
import type { PresentationProfile } from "../profile/presentationProfile.js";
|
|
5
|
-
export type ScanPresentationBundle = {
|
|
5
|
+
export type ScanPresentationBundle = AuthoredCommunicationAccessors & {
|
|
6
6
|
assessment: Assessment;
|
|
7
7
|
presentation: AssessmentPresentationPublic;
|
|
8
8
|
profile: PresentationProfile;
|
|
9
9
|
/**
|
|
10
10
|
* Evidence layout only — not an authority for posture, concern, or intensity.
|
|
11
|
-
* @deprecated Prefer
|
|
11
|
+
* @deprecated Prefer bundle accessors for authored communication; V3 migration only.
|
|
12
12
|
*/
|
|
13
13
|
facts: ScanNarrativeFacts;
|
|
14
14
|
/**
|
|
15
15
|
* Projection-only reference to the raw scan payload.
|
|
16
|
-
*
|
|
16
|
+
* @deprecated V3 migration only — surfaces must use accessors for decision meaning.
|
|
17
17
|
*/
|
|
18
18
|
result: ScanResult;
|
|
19
19
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/scanPresentationBundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,4BAA4B,
|
|
1
|
+
{"version":3,"file":"scanPresentationBundle.d.ts","sourceRoot":"","sources":["../../../src/presentation/orchestration/scanPresentationBundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,4BAA4B,EAC5B,8BAA8B,EAC/B,MAAM,wBAAwB,CAAC;AAChC,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,8BAA8B,GAAG;IACpE,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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentCliScanSummary.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentCliScanSummary.ts"],"names":[],"mappings":"
|
|
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,CAmCrB"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { formatPrRiskSummary } from "../../prRiskBand.js";
|
|
2
2
|
import { resolvePrRiskLayerScores } from "../../prRiskWire.js";
|
|
3
|
-
import { buildNarrativeChannels,
|
|
3
|
+
import { buildNarrativeChannels, composeSubheadline, composeSupportingContext, evidenceContextFromProfile, projectCompactKeyPoints, } from "../compose/narrativeCompose.js";
|
|
4
4
|
import { projectAssessmentFields } from "../projectAssessmentFields.js";
|
|
5
5
|
export function presentCliScanSummary(bundle, ctx = {}) {
|
|
6
6
|
const { facts, profile, result } = bundle;
|
|
7
|
+
const channels = buildNarrativeChannels(bundle);
|
|
7
8
|
const layerScores = resolvePrRiskLayerScores(result);
|
|
8
9
|
const layerLine = layerScores
|
|
9
10
|
? `security=${layerScores.security} maintainability=${layerScores.maintainability} ecosystem=${layerScores.ecosystem} upgradeImpact=${layerScores.upgradeImpact}`
|
|
10
11
|
: "";
|
|
11
|
-
const
|
|
12
|
+
const prRisk = formatPrRiskSummary(facts);
|
|
13
|
+
const prRiskScore = prRisk?.prRiskScore ?? facts.riskIndex ?? 0;
|
|
12
14
|
return {
|
|
13
15
|
...projectAssessmentFields(bundle),
|
|
14
16
|
header: {
|
|
@@ -20,13 +22,13 @@ export function presentCliScanSummary(bundle, ctx = {}) {
|
|
|
20
22
|
density: profile.density,
|
|
21
23
|
confidence: profile.confidence,
|
|
22
24
|
evidenceContext: evidenceContextFromProfile(bundle),
|
|
23
|
-
headline:
|
|
25
|
+
headline: channels.headline,
|
|
24
26
|
subheadline: composeSubheadline(bundle),
|
|
25
|
-
keyPoints: projectCompactKeyPoints(
|
|
26
|
-
verificationActions:
|
|
27
|
+
keyPoints: projectCompactKeyPoints(channels, 6),
|
|
28
|
+
verificationActions: channels.verification.slice(0, 5),
|
|
27
29
|
metrics: {
|
|
28
30
|
prRiskScore,
|
|
29
|
-
prRiskBandLabel:
|
|
31
|
+
prRiskBandLabel: prRisk?.prRiskBandLabel ?? undefined,
|
|
30
32
|
riskIndex: prRiskScore,
|
|
31
33
|
layerLine,
|
|
32
34
|
findingCount: result.findings?.length ?? 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentGitHubCheckRun.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentGitHubCheckRun.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presentGitHubCheckRun.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentGitHubCheckRun.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAChE,0BAA0B,CAkD5B"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { buildNarrativeChannels,
|
|
1
|
+
import { formatPrRiskSummary } from "../../prRiskBand.js";
|
|
2
|
+
import { buildNarrativeChannels, composeSubheadline, evidenceContextFromProfile, projectCompactKeyPoints, } from "../compose/narrativeCompose.js";
|
|
3
3
|
import { projectAssessmentFields } from "../projectAssessmentFields.js";
|
|
4
4
|
export function presentGitHubCheckRun(bundle, ctx) {
|
|
5
|
-
const { profile } = bundle;
|
|
6
|
-
const
|
|
5
|
+
const { facts, profile } = bundle;
|
|
6
|
+
const channels = buildNarrativeChannels(bundle);
|
|
7
7
|
const assessmentFields = projectAssessmentFields(bundle);
|
|
8
|
-
const actions =
|
|
8
|
+
const actions = channels.verification.slice(0, 3);
|
|
9
9
|
const detailsUrl = `${ctx.webAppOrigin.replace(/\/$/, "")}/scan/${ctx.scanId}`;
|
|
10
10
|
const conclusion = profile.status === "safe"
|
|
11
11
|
? "success"
|
|
@@ -13,13 +13,12 @@ export function presentGitHubCheckRun(bundle, ctx) {
|
|
|
13
13
|
? "failure"
|
|
14
14
|
: "neutral";
|
|
15
15
|
const sections = [];
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
if (prRiskScore != null && prRiskBandLabelText) {
|
|
16
|
+
const prRisk = formatPrRiskSummary(facts);
|
|
17
|
+
if (prRisk) {
|
|
19
18
|
sections.push({
|
|
20
19
|
id: "why",
|
|
21
20
|
title: "PR Risk",
|
|
22
|
-
bullets: [`${prRiskScore} (${
|
|
21
|
+
bullets: [`${prRisk.prRiskScore} (${prRisk.prRiskBandLabel})`],
|
|
23
22
|
});
|
|
24
23
|
}
|
|
25
24
|
// Use assessment.reasoning directly for the Why section (ABI 3).
|
|
@@ -27,7 +26,7 @@ export function presentGitHubCheckRun(bundle, ctx) {
|
|
|
27
26
|
const reasoningLines = assessmentFields.reasoning.slice(0, 3);
|
|
28
27
|
const whyBullets = reasoningLines.length > 0
|
|
29
28
|
? reasoningLines
|
|
30
|
-
: projectCompactKeyPoints(
|
|
29
|
+
: projectCompactKeyPoints(channels, 3);
|
|
31
30
|
if (whyBullets.length > 0) {
|
|
32
31
|
sections.push({ id: "why", title: "Why", bullets: whyBullets });
|
|
33
32
|
}
|
|
@@ -41,9 +40,9 @@ export function presentGitHubCheckRun(bundle, ctx) {
|
|
|
41
40
|
density: profile.density,
|
|
42
41
|
confidence: profile.confidence,
|
|
43
42
|
evidenceContext: evidenceContextFromProfile(bundle),
|
|
44
|
-
title: headline,
|
|
43
|
+
title: channels.headline,
|
|
45
44
|
conclusion,
|
|
46
|
-
summaryLead: composeSubheadline(bundle) ?? headline,
|
|
45
|
+
summaryLead: composeSubheadline(bundle) ?? channels.headline,
|
|
47
46
|
sections,
|
|
48
47
|
detailsUrl,
|
|
49
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentGitHubPrComment.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentGitHubPrComment.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presentGitHubPrComment.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentGitHubPrComment.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACtF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,2BAA2B,CAyC7B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MERGE_POSTURE_LABEL } from "../../riskVocabulary.js";
|
|
2
|
-
import {
|
|
2
|
+
import { formatPrRiskSummary } from "../../prRiskBand.js";
|
|
3
3
|
import { buildNarrativeChannels, evidenceContextFromProfile, } from "../compose/narrativeCompose.js";
|
|
4
4
|
import { formatChangedPackagesShort } from "../../narrativePresentation.js";
|
|
5
5
|
import { projectAssessmentFields } from "../projectAssessmentFields.js";
|
|
@@ -11,22 +11,23 @@ export function presentGitHubPrComment(bundle) {
|
|
|
11
11
|
const changed = formatChangedPackagesShort(facts, 3);
|
|
12
12
|
if (changed)
|
|
13
13
|
introLines.push(`Changed: ${changed}`);
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const prRisk = formatPrRiskSummary(facts);
|
|
15
|
+
if (prRisk) {
|
|
16
|
+
introLines.push(`PR Risk: ${prRisk.prRiskScore} (${prRisk.prRiskBandLabel})`);
|
|
17
|
+
}
|
|
18
|
+
if (assessmentFields.electionSummary) {
|
|
19
|
+
introLines.push(assessmentFields.electionSummary);
|
|
18
20
|
}
|
|
19
|
-
const electionSummary = bundle.assessment.reviewFocalPoint.electionSummary;
|
|
20
|
-
if (electionSummary)
|
|
21
|
-
introLines.push(electionSummary);
|
|
22
21
|
for (const line of assessmentFields.reasoning.slice(0, 2)) {
|
|
23
22
|
introLines.push(line);
|
|
24
23
|
}
|
|
25
24
|
const verify = channels.verification[0];
|
|
26
25
|
if (verify)
|
|
27
26
|
introLines.push(`Verify: ${verify}`);
|
|
28
|
-
const guidanceBlocks = channels.verification
|
|
29
|
-
|
|
27
|
+
const guidanceBlocks = channels.verification
|
|
28
|
+
.slice(0, 3)
|
|
29
|
+
.map((action, index) => ({
|
|
30
|
+
message: assessmentFields.reasoning[index] ?? action,
|
|
30
31
|
where: changed ?? "See scan detail for affected paths.",
|
|
31
32
|
action,
|
|
32
33
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presentScanDetails.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentScanDetails.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presentScanDetails.d.ts","sourceRoot":"","sources":["../../../src/presentation/presenters/presentScanDetails.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAGzF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AA6FF,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,yBAAyB,GAC7B,uBAAuB,CA6EzB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MERGE_CONCERN_LABELS } from "../../assessmentLabels.js";
|
|
2
2
|
import { normalizedPackageUsagePaths } from "../../narrativePresentation.js";
|
|
3
|
-
import {
|
|
3
|
+
import { formatPrRiskSummary, prRiskBandToGaugeBand, } from "../../prRiskBand.js";
|
|
4
4
|
import { MERGE_POSTURE_LABEL } from "../../riskVocabulary.js";
|
|
5
5
|
import { buildNarrativeChannels, composeSubheadline, composeSupportingContext, evidenceContextFromProfile, projectCompactKeyPoints, } from "../compose/narrativeCompose.js";
|
|
6
6
|
import { normalizeGeneratedText, normalizeGeneratedTextNullable, } from "../../normalizeGeneratedText.js";
|
|
@@ -79,7 +79,7 @@ function mapEvidence(bundle) {
|
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
export function presentScanDetails(bundle, ctx) {
|
|
82
|
-
const {
|
|
82
|
+
const { facts, profile } = bundle;
|
|
83
83
|
const assessmentFields = projectAssessmentFields(bundle);
|
|
84
84
|
const channels = buildNarrativeChannels(bundle);
|
|
85
85
|
const keyPoints = projectCompactKeyPoints(channels, 6);
|
|
@@ -93,8 +93,8 @@ export function presentScanDetails(bundle, ctx) {
|
|
|
93
93
|
: undefined;
|
|
94
94
|
const postureLabel = MERGE_POSTURE_LABEL[profile.status];
|
|
95
95
|
const verdictLine = assessmentFields.reasoning[0] ??
|
|
96
|
-
(
|
|
97
|
-
? MERGE_CONCERN_LABELS[
|
|
96
|
+
(assessmentFields.primaryConcern
|
|
97
|
+
? MERGE_CONCERN_LABELS[assessmentFields.primaryConcern]
|
|
98
98
|
: postureLabel);
|
|
99
99
|
const verificationActions = channels.verification.map((title, index) => ({
|
|
100
100
|
title: normalizeGeneratedText(title),
|
|
@@ -110,10 +110,7 @@ export function presentScanDetails(bundle, ctx) {
|
|
|
110
110
|
: "low",
|
|
111
111
|
rationale: action.detail,
|
|
112
112
|
}));
|
|
113
|
-
const
|
|
114
|
-
const prRiskBandLabelText = facts.riskSignals?.band != null
|
|
115
|
-
? prRiskBandLabel(facts.riskSignals.band)
|
|
116
|
-
: scoreToBandLabel(prRiskScore);
|
|
113
|
+
const prRisk = formatPrRiskSummary(facts);
|
|
117
114
|
return {
|
|
118
115
|
...assessmentFields,
|
|
119
116
|
evidenceContext: evidenceContextFromProfile(bundle),
|
|
@@ -127,9 +124,9 @@ export function presentScanDetails(bundle, ctx) {
|
|
|
127
124
|
verdictLine: normalizeGeneratedText(verdictLine),
|
|
128
125
|
scopeChip: channels.reachLabel,
|
|
129
126
|
postureLabel,
|
|
130
|
-
prRiskScore,
|
|
131
|
-
prRiskBandLabel:
|
|
132
|
-
riskIndex: prRiskScore,
|
|
127
|
+
prRiskScore: prRisk?.prRiskScore ?? null,
|
|
128
|
+
prRiskBandLabel: prRisk?.prRiskBandLabel,
|
|
129
|
+
riskIndex: prRisk?.prRiskScore ?? null,
|
|
133
130
|
},
|
|
134
131
|
signalSummary: mapSignalSummary(bundle),
|
|
135
132
|
narrative: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectAssessmentFields.d.ts","sourceRoot":"","sources":["../../src/presentation/projectAssessmentFields.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"projectAssessmentFields.d.ts","sourceRoot":"","sources":["../../src/presentation/projectAssessmentFields.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAOxF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,sBAAsB,GAC7B,4BAA4B,CAoB9B"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { collectVerificationFocusForPresentation, projectReasoningLines, } from "../assessmentProjection.js";
|
|
2
|
+
function trimOptionalExpression(value) {
|
|
3
|
+
const trimmed = value?.trim();
|
|
4
|
+
return trimmed ? trimmed : undefined;
|
|
5
|
+
}
|
|
2
6
|
export function projectAssessmentFields(bundle) {
|
|
3
7
|
const { assessment, presentation, result } = bundle;
|
|
4
8
|
const { channel, focus } = collectVerificationFocusForPresentation(presentation, result);
|
|
@@ -11,5 +15,7 @@ export function projectAssessmentFields(bundle) {
|
|
|
11
15
|
verificationChannel: channel,
|
|
12
16
|
reachVisibility: presentation.reachVisibility,
|
|
13
17
|
narrativeIntensity: presentation.narrativeIntensity,
|
|
18
|
+
confidenceRationale: trimOptionalExpression(assessment.confidenceRationale),
|
|
19
|
+
electionSummary: trimOptionalExpression(assessment.reviewFocalPoint.electionSummary),
|
|
14
20
|
};
|
|
15
21
|
}
|