@mergesignal/shared 0.4.3 → 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.
- package/dist/actionsStepSummary.d.ts +1 -22
- package/dist/actionsStepSummary.d.ts.map +1 -1
- package/dist/actionsStepSummary.js +19 -716
- package/dist/actionsStepSummary.test.js +34 -329
- package/dist/assessmentLabels.d.ts +6 -0
- package/dist/assessmentLabels.d.ts.map +1 -0
- package/dist/assessmentLabels.js +33 -0
- package/dist/assessmentProjection.d.ts +12 -0
- package/dist/assessmentProjection.d.ts.map +1 -0
- package/dist/assessmentProjection.js +100 -0
- package/dist/assessmentSchema.d.ts +155 -0
- package/dist/assessmentSchema.d.ts.map +1 -0
- package/dist/assessmentSchema.js +110 -0
- package/dist/cardObservationCatalog.d.ts +2 -0
- package/dist/cardObservationCatalog.d.ts.map +1 -1
- package/dist/cardObservationCatalog.js +47 -1
- package/dist/engineWireRegression.test.js +22 -2
- package/dist/fixtures/assessmentFixtures.d.ts +13 -0
- package/dist/fixtures/assessmentFixtures.d.ts.map +1 -0
- package/dist/fixtures/assessmentFixtures.js +164 -0
- package/dist/formatCardExposureDisplay.d.ts +0 -4
- package/dist/formatCardExposureDisplay.d.ts.map +1 -1
- package/dist/formatCardExposureDisplay.js +0 -15
- package/dist/formatInsight.d.ts +3 -2
- package/dist/formatInsight.d.ts.map +1 -1
- package/dist/formatInsight.js +26 -1
- package/dist/index.d.ts +7 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -11
- package/dist/narrativeParity.test.js +4 -34
- package/dist/presentGitHubPrComment.d.ts +1 -3
- package/dist/presentGitHubPrComment.d.ts.map +1 -1
- package/dist/presentGitHubPrComment.js +0 -17
- package/dist/presentation/compose/narrativeChannels.d.ts.map +1 -1
- package/dist/presentation/compose/narrativeChannels.js +13 -43
- package/dist/presentation/compose/narrativeCompose.d.ts.map +1 -1
- package/dist/presentation/compose/narrativeCompose.js +2 -5
- package/dist/presentation/dto/assessmentPresentationFields.d.ts +13 -0
- package/dist/presentation/dto/assessmentPresentationFields.d.ts.map +1 -0
- package/dist/presentation/dto/assessmentPresentationFields.js +1 -0
- package/dist/presentation/dto/dashboardCardPresentation.d.ts +2 -1
- package/dist/presentation/dto/dashboardCardPresentation.d.ts.map +1 -1
- package/dist/presentation/dto/githubAndCliPresentation.d.ts +4 -3
- package/dist/presentation/dto/githubAndCliPresentation.d.ts.map +1 -1
- package/dist/presentation/dto/scanDetailsPresentation.d.ts +2 -1
- package/dist/presentation/dto/scanDetailsPresentation.d.ts.map +1 -1
- package/dist/presentation/fixtures/dashboardCardGolden.test.js +21 -14
- package/dist/presentation/fixtures/presentationPersonaFixtures.d.ts.map +1 -1
- package/dist/presentation/fixtures/presentationPersonaFixtures.js +31 -24
- package/dist/presentation/fixtures/scanResultFixtures.d.ts.map +1 -1
- package/dist/presentation/fixtures/scanResultFixtures.js +14 -3
- package/dist/presentation/index.d.ts +0 -1
- package/dist/presentation/index.d.ts.map +1 -1
- package/dist/presentation/index.js +0 -1
- package/dist/presentation/orchestration/buildScanCardPresentation.d.ts.map +1 -1
- package/dist/presentation/orchestration/buildScanCardPresentation.js +8 -3
- package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts +1 -1
- package/dist/presentation/orchestration/buildScanPresentationBundle.d.ts.map +1 -1
- package/dist/presentation/orchestration/buildScanPresentationBundle.js +12 -10
- package/dist/presentation/orchestration/scanPresentationBundle.d.ts +8 -3
- package/dist/presentation/orchestration/scanPresentationBundle.d.ts.map +1 -1
- package/dist/presentation/presentationPersonas.test.js +6 -6
- package/dist/presentation/presenters/presentCliScanSummary.d.ts.map +1 -1
- package/dist/presentation/presenters/presentCliScanSummary.js +2 -0
- package/dist/presentation/presenters/presentDashboardCard.d.ts.map +1 -1
- package/dist/presentation/presenters/presentDashboardCard.js +2 -0
- package/dist/presentation/presenters/presentGitHubCheckRun.d.ts.map +1 -1
- package/dist/presentation/presenters/presentGitHubCheckRun.js +2 -0
- package/dist/presentation/presenters/presentGitHubPrComment.d.ts.map +1 -1
- package/dist/presentation/presenters/presentGitHubPrComment.js +15 -21
- package/dist/presentation/presenters/presentScanDetails.d.ts.map +1 -1
- package/dist/presentation/presenters/presentScanDetails.js +52 -129
- package/dist/presentation/profile/buildProfileFromAssessment.d.ts +5 -0
- package/dist/presentation/profile/buildProfileFromAssessment.d.ts.map +1 -0
- package/dist/presentation/profile/buildProfileFromAssessment.js +58 -0
- package/dist/presentation/projectAssessmentFields.d.ts +4 -0
- package/dist/presentation/projectAssessmentFields.d.ts.map +1 -0
- package/dist/presentation/projectAssessmentFields.js +13 -0
- package/dist/presentation/surfaceParity.test.d.ts +2 -0
- package/dist/presentation/surfaceParity.test.d.ts.map +1 -0
- package/dist/presentation/surfaceParity.test.js +74 -0
- package/dist/productMessaging.d.ts +4 -4
- package/dist/productMessaging.d.ts.map +1 -1
- package/dist/productMessaging.js +4 -4
- package/dist/productMessaging.test.js +2 -2
- package/dist/repoIntelligenceSchema.d.ts +2 -2
- package/dist/resolvePipelineStatus.d.ts +15 -0
- package/dist/resolvePipelineStatus.d.ts.map +1 -0
- package/dist/resolvePipelineStatus.js +37 -0
- package/dist/scanCardPresentationState.d.ts +4 -0
- package/dist/scanCardPresentationState.d.ts.map +1 -0
- package/dist/scanCardPresentationState.js +4 -0
- package/dist/{scanDetailViewModel.d.ts → scanDetailViewModelTypes.d.ts} +60 -32
- package/dist/scanDetailViewModelTypes.d.ts.map +1 -0
- package/dist/scanDetailViewModelTypes.js +4 -0
- package/dist/scanResultSchema.d.ts +75 -2
- package/dist/scanResultSchema.d.ts.map +1 -1
- package/dist/scanResultSchema.js +4 -2
- package/dist/scanResultSchema.test.js +16 -0
- package/dist/trustedScanGuards.test.js +7 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/collectNarrativeWhyBullets.d.ts +0 -12
- package/dist/collectNarrativeWhyBullets.d.ts.map +0 -1
- package/dist/collectNarrativeWhyBullets.js +0 -104
- package/dist/deriveCardDisplaySummary.d.ts +0 -16
- package/dist/deriveCardDisplaySummary.d.ts.map +0 -1
- package/dist/deriveCardDisplaySummary.js +0 -56
- package/dist/deriveCardDisplaySummary.test.d.ts +0 -2
- package/dist/deriveCardDisplaySummary.test.d.ts.map +0 -1
- package/dist/deriveCardDisplaySummary.test.js +0 -89
- package/dist/deriveCardOperationalObservations.d.ts +0 -19
- package/dist/deriveCardOperationalObservations.d.ts.map +0 -1
- package/dist/deriveCardOperationalObservations.js +0 -180
- package/dist/deriveCardOperationalObservations.test.d.ts +0 -2
- package/dist/deriveCardOperationalObservations.test.d.ts.map +0 -1
- package/dist/deriveCardOperationalObservations.test.js +0 -268
- package/dist/deriveRiskScoreSummary.d.ts +0 -33
- package/dist/deriveRiskScoreSummary.d.ts.map +0 -1
- package/dist/deriveRiskScoreSummary.js +0 -90
- package/dist/deriveRiskScoreSummary.test.d.ts +0 -2
- package/dist/deriveRiskScoreSummary.test.d.ts.map +0 -1
- package/dist/deriveRiskScoreSummary.test.js +0 -47
- package/dist/deriveScanDetailRecommendations.d.ts +0 -63
- package/dist/deriveScanDetailRecommendations.d.ts.map +0 -1
- package/dist/deriveScanDetailRecommendations.js +0 -725
- package/dist/deriveScanDetailRecommendations.test.d.ts +0 -2
- package/dist/deriveScanDetailRecommendations.test.d.ts.map +0 -1
- package/dist/deriveScanDetailRecommendations.test.js +0 -181
- package/dist/deriveScanSummaryText.d.ts +0 -7
- package/dist/deriveScanSummaryText.d.ts.map +0 -1
- package/dist/deriveScanSummaryText.js +0 -24
- package/dist/deriveScanSummaryText.test.d.ts +0 -2
- package/dist/deriveScanSummaryText.test.d.ts.map +0 -1
- package/dist/deriveScanSummaryText.test.js +0 -77
- package/dist/formatCardEvidenceCounts.d.ts +0 -7
- package/dist/formatCardEvidenceCounts.d.ts.map +0 -1
- package/dist/formatCardEvidenceCounts.js +0 -19
- package/dist/prCheckRunPresentation.d.ts +0 -68
- package/dist/prCheckRunPresentation.d.ts.map +0 -1
- package/dist/prCheckRunPresentation.js +0 -319
- package/dist/prCheckRunPresentation.test.d.ts +0 -2
- package/dist/prCheckRunPresentation.test.d.ts.map +0 -1
- package/dist/prCheckRunPresentation.test.js +0 -278
- package/dist/presentation/intent/derivePresentationInterpretation.d.ts +0 -4
- package/dist/presentation/intent/derivePresentationInterpretation.d.ts.map +0 -1
- package/dist/presentation/intent/derivePresentationInterpretation.js +0 -202
- package/dist/presentation/intent/formatPresentationCopy.d.ts +0 -8
- package/dist/presentation/intent/formatPresentationCopy.d.ts.map +0 -1
- package/dist/presentation/intent/formatPresentationCopy.js +0 -140
- package/dist/presentation/intent/presentationIntent.test.d.ts +0 -2
- package/dist/presentation/intent/presentationIntent.test.d.ts.map +0 -1
- package/dist/presentation/intent/presentationIntent.test.js +0 -29
- package/dist/presentation/intent/verificationFocusLabels.d.ts +0 -2
- package/dist/presentation/intent/verificationFocusLabels.d.ts.map +0 -1
- package/dist/presentation/intent/verificationFocusLabels.js +0 -45
- package/dist/presentation/profile/derivePresentationProfile.d.ts +0 -12
- package/dist/presentation/profile/derivePresentationProfile.d.ts.map +0 -1
- package/dist/presentation/profile/derivePresentationProfile.js +0 -85
- package/dist/scanCardSummary.d.ts +0 -58
- package/dist/scanCardSummary.d.ts.map +0 -1
- package/dist/scanCardSummary.js +0 -146
- package/dist/scanCardSummary.test.d.ts +0 -2
- package/dist/scanCardSummary.test.d.ts.map +0 -1
- package/dist/scanCardSummary.test.js +0 -234
- package/dist/scanDetailViewModel.d.ts.map +0 -1
- package/dist/scanDetailViewModel.js +0 -636
- package/dist/scanDetailViewModel.test.d.ts +0 -2
- package/dist/scanDetailViewModel.test.d.ts.map +0 -1
- package/dist/scanDetailViewModel.test.js +0 -530
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { narrativeIntensityToDensity } from "../../assessmentSchema.js";
|
|
2
|
+
import { safeParseRepoIntelligence } from "../../repoIntelligenceSchema.js";
|
|
3
|
+
import { scanSurfaceCopy } from "../../scanSurfaceCopy.js";
|
|
4
|
+
import { collectVerificationFocus } from "../../assessmentProjection.js";
|
|
5
|
+
function buildInterpretation(assessment, presentation, result) {
|
|
6
|
+
const verificationLabels = collectVerificationFocus(result);
|
|
7
|
+
const anchorPackage = result.changedPackages?.[0] ?? null;
|
|
8
|
+
const suppressRuntimeNarrative = presentation.reachVisibility === "hidden";
|
|
9
|
+
let intent = "unknown_upgrade";
|
|
10
|
+
if (assessment.primaryConcern === "insufficient_evidence") {
|
|
11
|
+
intent = "limited_context";
|
|
12
|
+
}
|
|
13
|
+
else if (assessment.changeClasses.includes("tooling_maintenance")) {
|
|
14
|
+
intent = "tooling_patch";
|
|
15
|
+
}
|
|
16
|
+
else if (assessment.primaryConcern === "confirmed_runtime_usage") {
|
|
17
|
+
if (assessment.factors.includes("queue_infrastructure")) {
|
|
18
|
+
intent = "queue_runtime_upgrade";
|
|
19
|
+
}
|
|
20
|
+
else if (assessment.factors.includes("auth_infrastructure")) {
|
|
21
|
+
intent = "auth_runtime_upgrade";
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
intent = "runtime_upgrade";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
intent,
|
|
29
|
+
anchorPackage,
|
|
30
|
+
suppressRuntimeNarrative,
|
|
31
|
+
allowRuntimeNarrative: !suppressRuntimeNarrative,
|
|
32
|
+
showLimitedEvidence: assessment.confidence === "low",
|
|
33
|
+
expectedImpactKey: null,
|
|
34
|
+
verificationLabels,
|
|
35
|
+
runtimeSurfaceLabel: null,
|
|
36
|
+
runtimePackages: [],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function buildProfileFromAssessment(assessment, presentation, result) {
|
|
40
|
+
const riParse = safeParseRepoIntelligence(result.repoIntelligence);
|
|
41
|
+
const priority = riParse.ok && (result.changedPackages?.length ?? 0) > 0
|
|
42
|
+
? "pr_intelligence"
|
|
43
|
+
: "limited";
|
|
44
|
+
const degradedMessage = assessment.primaryConcern === "insufficient_evidence" ||
|
|
45
|
+
assessment.confidence === "low"
|
|
46
|
+
? scanSurfaceCopy.presentation.limitedContextMessage
|
|
47
|
+
: priority === "limited"
|
|
48
|
+
? scanSurfaceCopy.presentation.limitedContextMessage
|
|
49
|
+
: undefined;
|
|
50
|
+
return {
|
|
51
|
+
status: assessment.posture,
|
|
52
|
+
density: narrativeIntensityToDensity(presentation.narrativeIntensity),
|
|
53
|
+
confidence: assessment.confidence,
|
|
54
|
+
priority,
|
|
55
|
+
degradedMessage,
|
|
56
|
+
interpretation: buildInterpretation(assessment, presentation, result),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AssessmentPresentationFields } from "./dto/assessmentPresentationFields.js";
|
|
2
|
+
import type { ScanPresentationBundle } from "./orchestration/scanPresentationBundle.js";
|
|
3
|
+
export declare function projectAssessmentFields(bundle: ScanPresentationBundle): AssessmentPresentationFields;
|
|
4
|
+
//# sourceMappingURL=projectAssessmentFields.d.ts.map
|
|
@@ -0,0 +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;AAExF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,sBAAsB,GAC7B,4BAA4B,CAW9B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { collectVerificationFocus, projectReasoningLines, } from "../assessmentProjection.js";
|
|
2
|
+
export function projectAssessmentFields(bundle) {
|
|
3
|
+
const { assessment, presentation, result } = bundle;
|
|
4
|
+
return {
|
|
5
|
+
posture: assessment.posture,
|
|
6
|
+
primaryConcern: assessment.primaryConcern,
|
|
7
|
+
factors: [...assessment.factors],
|
|
8
|
+
reasoning: projectReasoningLines(result),
|
|
9
|
+
verificationFocus: collectVerificationFocus(result),
|
|
10
|
+
reachVisibility: presentation.reachVisibility,
|
|
11
|
+
narrativeIntensity: presentation.narrativeIntensity,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surfaceParity.test.d.ts","sourceRoot":"","sources":["../../src/presentation/surfaceParity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { buildScanPresentationBundle } from "./orchestration/buildScanPresentationBundle.js";
|
|
3
|
+
import { presentDashboardCard } from "./presenters/presentDashboardCard.js";
|
|
4
|
+
import { presentScanDetails } from "./presenters/presentScanDetails.js";
|
|
5
|
+
import { presentGitHubCheckRun } from "./presenters/presentGitHubCheckRun.js";
|
|
6
|
+
import { presentGitHubPrComment } from "./presenters/presentGitHubPrComment.js";
|
|
7
|
+
import { renderGitHubCheckRunMarkdown } from "./render/renderGitHubCheckRunMarkdown.js";
|
|
8
|
+
import { renderGitHubPrCommentMarkdown } from "./render/renderGitHubPrCommentMarkdown.js";
|
|
9
|
+
import { scanResultBullmq, scanResultEslint, scanResultFastifyRuntime, scanResultMixedTypescriptFastify, scanResultPrettier, scanResultTypescriptPatch, scanResultVitest, } from "./fixtures/presentationPersonaFixtures.js";
|
|
10
|
+
import { projectAssessmentFields } from "./projectAssessmentFields.js";
|
|
11
|
+
const SCAN_ID = "22222222-2222-4222-8222-222222222222";
|
|
12
|
+
const ORIGIN = "https://app.example.com";
|
|
13
|
+
const validationPersonas = [
|
|
14
|
+
{ name: "PR #26 mixed", result: scanResultMixedTypescriptFastify },
|
|
15
|
+
{ name: "PR #27 fastify", result: scanResultFastifyRuntime },
|
|
16
|
+
{ name: "PR #28 typescript", result: scanResultTypescriptPatch },
|
|
17
|
+
{ name: "PR #29 prettier", result: scanResultPrettier },
|
|
18
|
+
{ name: "PR #30 bullmq", result: scanResultBullmq },
|
|
19
|
+
{ name: "eslint", result: scanResultEslint },
|
|
20
|
+
{ name: "vitest", result: scanResultVitest },
|
|
21
|
+
];
|
|
22
|
+
function surfacesFor(result) {
|
|
23
|
+
const bundle = buildScanPresentationBundle({
|
|
24
|
+
result,
|
|
25
|
+
pipelineStatus: "done",
|
|
26
|
+
});
|
|
27
|
+
const fields = projectAssessmentFields(bundle);
|
|
28
|
+
const card = presentDashboardCard(bundle);
|
|
29
|
+
const details = presentScanDetails(bundle, { scanId: SCAN_ID });
|
|
30
|
+
const check = presentGitHubCheckRun(bundle, {
|
|
31
|
+
scanId: SCAN_ID,
|
|
32
|
+
webAppOrigin: ORIGIN,
|
|
33
|
+
});
|
|
34
|
+
const comment = presentGitHubPrComment(bundle);
|
|
35
|
+
const checkMd = renderGitHubCheckRunMarkdown(check);
|
|
36
|
+
const commentMd = renderGitHubPrCommentMarkdown(comment);
|
|
37
|
+
return { bundle, fields, card, details, check, comment, checkMd, commentMd };
|
|
38
|
+
}
|
|
39
|
+
describe("surfaceParity guardrail", () => {
|
|
40
|
+
for (const persona of validationPersonas) {
|
|
41
|
+
it(`${persona.name}: posture and assessment fields match across surfaces`, () => {
|
|
42
|
+
const s = surfacesFor(persona.result);
|
|
43
|
+
expect(s.card.posture).toBe(s.fields.posture);
|
|
44
|
+
expect(s.details.posture).toBe(s.fields.posture);
|
|
45
|
+
expect(s.check.posture).toBe(s.fields.posture);
|
|
46
|
+
expect(s.comment.posture).toBe(s.fields.posture);
|
|
47
|
+
expect(s.card.verdict?.posture).toBe(s.fields.posture);
|
|
48
|
+
expect(s.card.primaryConcern).toBe(s.fields.primaryConcern);
|
|
49
|
+
expect(s.details.primaryConcern).toBe(s.fields.primaryConcern);
|
|
50
|
+
expect(s.check.primaryConcern).toBe(s.fields.primaryConcern);
|
|
51
|
+
expect(s.comment.primaryConcern).toBe(s.fields.primaryConcern);
|
|
52
|
+
expect(s.card.narrativeIntensity).toBe(s.fields.narrativeIntensity);
|
|
53
|
+
expect(s.details.narrativeIntensity).toBe(s.fields.narrativeIntensity);
|
|
54
|
+
expect(s.check.narrativeIntensity).toBe(s.fields.narrativeIntensity);
|
|
55
|
+
expect(s.comment.narrativeIntensity).toBe(s.fields.narrativeIntensity);
|
|
56
|
+
expect(s.card.reachVisibility).toBe(s.fields.reachVisibility);
|
|
57
|
+
expect(s.details.reachVisibility).toBe(s.fields.reachVisibility);
|
|
58
|
+
expect(s.check.reachVisibility).toBe(s.fields.reachVisibility);
|
|
59
|
+
expect(s.comment.reachVisibility).toBe(s.fields.reachVisibility);
|
|
60
|
+
expect(s.card.reasoning).toEqual(s.fields.reasoning);
|
|
61
|
+
expect(s.details.reasoning).toEqual(s.fields.reasoning);
|
|
62
|
+
expect(s.check.reasoning).toEqual(s.fields.reasoning);
|
|
63
|
+
expect(s.comment.reasoning).toEqual(s.fields.reasoning);
|
|
64
|
+
expect(s.card.verificationFocus).toEqual(s.fields.verificationFocus);
|
|
65
|
+
expect(s.details.verificationFocus).toEqual(s.fields.verificationFocus);
|
|
66
|
+
expect(s.check.verificationFocus).toEqual(s.fields.verificationFocus);
|
|
67
|
+
expect(s.comment.verificationFocus).toEqual(s.fields.verificationFocus);
|
|
68
|
+
});
|
|
69
|
+
it(`${persona.name}: headline matches across card and details`, () => {
|
|
70
|
+
const s = surfacesFor(persona.result);
|
|
71
|
+
expect(s.details.hero.headline).toBe(s.card.headline);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Canonical marketing / category copy. Operational scan strings stay in scanSurfaceCopy.
|
|
3
3
|
*/
|
|
4
4
|
export declare const productMessaging: {
|
|
5
|
-
readonly formalDefinition: "MergeSignal analyzes dependency upgrades,
|
|
5
|
+
readonly formalDefinition: "MergeSignal analyzes dependency upgrades in context, inspects relevant code paths, and provides focused reviewer guidance before merge - without requiring a full repository scan.";
|
|
6
6
|
readonly hero: {
|
|
7
7
|
readonly kicker: "Merge-decision intelligence for dependency upgrades";
|
|
8
8
|
readonly h1: "See what a dependency upgrade can break.";
|
|
@@ -68,10 +68,10 @@ export declare const productMessaging: {
|
|
|
68
68
|
readonly dashboardPrCard: {
|
|
69
69
|
readonly intro: "The repository dashboard is a runtime-aware review surface for open upgrade pull requests: triage by merge recommendation, then read operational context on each card.";
|
|
70
70
|
readonly posture: `Posture indicates the merge recommendation (${string}, ${string}, ${string}).`;
|
|
71
|
-
readonly exposure: "
|
|
72
|
-
readonly exposureCategoriesLead: "
|
|
71
|
+
readonly exposure: "Reach indicates how prominently affected application paths are surfaced for this upgrade.";
|
|
72
|
+
readonly exposureCategoriesLead: "Risk index bands (supporting context) read as one of:";
|
|
73
73
|
readonly exposureCategories: readonly string[];
|
|
74
|
-
readonly cardBody: "Below the verdict, scanned cards lead with the changed package,
|
|
74
|
+
readonly cardBody: "Below the verdict, scanned cards lead with the changed package, affected areas, verification checks, and blast radius when code intelligence is available - focused on this PR, not the whole repository.";
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
77
|
/** Illustrative scan-card example for homepage proof band and getting-started. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"productMessaging.d.ts","sourceRoot":"","sources":["../src/productMessaging.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmF3B,6FAA6F;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"productMessaging.d.ts","sourceRoot":"","sources":["../src/productMessaging.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAmF3B,6FAA6F;;;;;;;;;CAarF,CAAC;AAEX,kFAAkF;AAClF,eAAO,MAAM,gBAAgB;;;;CAOnB,CAAC;AAEX,iEAAiE;AACjE,wBAAgB,wBAAwB,IAAI,MAAM,EAAE,CAOnD"}
|
package/dist/productMessaging.js
CHANGED
|
@@ -4,7 +4,7 @@ import { MERGE_POSTURE_LABEL } from "./riskVocabulary.js";
|
|
|
4
4
|
* Canonical marketing / category copy. Operational scan strings stay in scanSurfaceCopy.
|
|
5
5
|
*/
|
|
6
6
|
export const productMessaging = {
|
|
7
|
-
formalDefinition: "MergeSignal analyzes dependency upgrades,
|
|
7
|
+
formalDefinition: "MergeSignal analyzes dependency upgrades in context, inspects relevant code paths, and provides focused reviewer guidance before merge - without requiring a full repository scan.",
|
|
8
8
|
hero: {
|
|
9
9
|
kicker: "Merge-decision intelligence for dependency upgrades",
|
|
10
10
|
h1: "See what a dependency upgrade can break.",
|
|
@@ -83,10 +83,10 @@ export const productMessaging = {
|
|
|
83
83
|
dashboardPrCard: {
|
|
84
84
|
intro: "The repository dashboard is a runtime-aware review surface for open upgrade pull requests: triage by merge recommendation, then read operational context on each card.",
|
|
85
85
|
posture: `Posture indicates the merge recommendation (${MERGE_POSTURE_LABEL.safe}, ${MERGE_POSTURE_LABEL.needs_review}, ${MERGE_POSTURE_LABEL.risky}).`,
|
|
86
|
-
exposure: "
|
|
87
|
-
exposureCategoriesLead: "
|
|
86
|
+
exposure: "Reach indicates how prominently affected application paths are surfaced for this upgrade.",
|
|
87
|
+
exposureCategoriesLead: "Risk index bands (supporting context) read as one of:",
|
|
88
88
|
exposureCategories: CARD_EXPOSURE_CATEGORY_LABELS,
|
|
89
|
-
cardBody: "Below the verdict, scanned cards lead with the changed package,
|
|
89
|
+
cardBody: "Below the verdict, scanned cards lead with the changed package, affected areas, verification checks, and blast radius when code intelligence is available - focused on this PR, not the whole repository.",
|
|
90
90
|
},
|
|
91
91
|
};
|
|
92
92
|
/** Illustrative scan-card example for homepage proof band and getting-started. */
|
|
@@ -71,8 +71,8 @@ describe("productMessaging", () => {
|
|
|
71
71
|
d.cardBody,
|
|
72
72
|
].join(" ");
|
|
73
73
|
expect(text).toContain("merge recommendation");
|
|
74
|
-
expect(text).toContain("
|
|
75
|
-
expect(text).not.toMatch(/
|
|
74
|
+
expect(text).toContain("affected application paths");
|
|
75
|
+
expect(text).not.toMatch(/total score|0-100|formula|weight/i);
|
|
76
76
|
expect(d.exposureCategories).toHaveLength(5);
|
|
77
77
|
expect(d.exposureCategories).toContain("Elevated exposure");
|
|
78
78
|
});
|
|
@@ -35,13 +35,13 @@ export declare const repoIntelligenceWireSchema: z.ZodObject<{
|
|
|
35
35
|
}, z.core.$strip>;
|
|
36
36
|
areas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
37
37
|
dependencyClass: z.ZodOptional<z.ZodEnum<{
|
|
38
|
+
format: "format";
|
|
38
39
|
unknown: "unknown";
|
|
39
40
|
runtime: "runtime";
|
|
40
41
|
build: "build";
|
|
41
42
|
test: "test";
|
|
42
43
|
tooling: "tooling";
|
|
43
44
|
lint: "lint";
|
|
44
|
-
format: "format";
|
|
45
45
|
ci: "ci";
|
|
46
46
|
}>>;
|
|
47
47
|
packageRole: z.ZodOptional<z.ZodEnum<{
|
|
@@ -64,9 +64,9 @@ export declare const repoIntelligenceWireSchema: z.ZodObject<{
|
|
|
64
64
|
development: "development";
|
|
65
65
|
}>>;
|
|
66
66
|
runtimeImpact: z.ZodOptional<z.ZodEnum<{
|
|
67
|
+
none: "none";
|
|
67
68
|
unknown: "unknown";
|
|
68
69
|
confirmed: "confirmed";
|
|
69
|
-
none: "none";
|
|
70
70
|
possible: "possible";
|
|
71
71
|
}>>;
|
|
72
72
|
expectedImpact: z.ZodOptional<z.ZodEnum<{
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type ScanPipelineStatus = "queued" | "running" | "done" | "failed";
|
|
2
|
+
export type PipelineCompletionEvidence = {
|
|
3
|
+
scannedAt?: string | null;
|
|
4
|
+
decision?: string | null;
|
|
5
|
+
totalScore?: number | null;
|
|
6
|
+
hasResult?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/** Scan completion signals — decision/totalScore/result are only set after analysis. */
|
|
9
|
+
export declare function hasScanCompletionEvidence(evidence: PipelineCompletionEvidence): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve wire status using completion evidence (decision, totalScore, result).
|
|
12
|
+
* Handles races where denormalized columns are written before status flips to done.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolvePipelineStatus(status: string | undefined, evidence: PipelineCompletionEvidence): ScanPipelineStatus;
|
|
15
|
+
//# sourceMappingURL=resolvePipelineStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvePipelineStatus.d.ts","sourceRoot":"","sources":["../src/resolvePipelineStatus.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1E,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAsBF,wFAAwF;AACxF,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,0BAA0B,GACnC,OAAO,CAQT;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,0BAA0B,GACnC,kBAAkB,CAKpB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
function normalizePipelineStatus(status) {
|
|
2
|
+
const st = String(status ?? "")
|
|
3
|
+
.trim()
|
|
4
|
+
.toLowerCase();
|
|
5
|
+
if (st === "queued" || st === "running" || st === "done" || st === "failed") {
|
|
6
|
+
return st;
|
|
7
|
+
}
|
|
8
|
+
return "failed";
|
|
9
|
+
}
|
|
10
|
+
function isMergePostureDecision(decision) {
|
|
11
|
+
return (decision === "safe" || decision === "needs_review" || decision === "risky");
|
|
12
|
+
}
|
|
13
|
+
/** Scan completion signals — decision/totalScore/result are only set after analysis. */
|
|
14
|
+
export function hasScanCompletionEvidence(evidence) {
|
|
15
|
+
if (isMergePostureDecision(evidence.decision))
|
|
16
|
+
return true;
|
|
17
|
+
if (evidence.hasResult === true)
|
|
18
|
+
return true;
|
|
19
|
+
if (evidence.totalScore != null && Number.isFinite(evidence.totalScore)) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (evidence.scannedAt?.trim())
|
|
23
|
+
return true;
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve wire status using completion evidence (decision, totalScore, result).
|
|
28
|
+
* Handles races where denormalized columns are written before status flips to done.
|
|
29
|
+
*/
|
|
30
|
+
export function resolvePipelineStatus(status, evidence) {
|
|
31
|
+
const normalized = normalizePipelineStatus(status);
|
|
32
|
+
if (normalized === "done" || normalized === "failed")
|
|
33
|
+
return normalized;
|
|
34
|
+
if (hasScanCompletionEvidence(evidence))
|
|
35
|
+
return "done";
|
|
36
|
+
return normalized;
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Dashboard PR card lifecycle — distinct from pipeline status. */
|
|
2
|
+
export type ScanCardPresentationState = "not_scanned" | "scanning" | "analysis_failed" | "ready" | "stale";
|
|
3
|
+
export declare function staleScanSubline(): string;
|
|
4
|
+
//# sourceMappingURL=scanCardPresentationState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanCardPresentationState.d.ts","sourceRoot":"","sources":["../src/scanCardPresentationState.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,MAAM,yBAAyB,GACjC,aAAa,GACb,UAAU,GACV,iBAAiB,GACjB,OAAO,GACP,OAAO,CAAC;AAIZ,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -1,13 +1,63 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export declare const ACT2_MAX_THEMES = 4;
|
|
7
|
-
export declare const ACT2_MAX_THEME_CHARS = 80;
|
|
8
|
-
export declare const VERDICT_LINE_MAX_CHARS = 120;
|
|
1
|
+
import type { ObservationSignalFamily } from "./cardObservationCatalog.js";
|
|
2
|
+
import type { NarrativeAvailabilityMode } from "./scanNarrativeFacts.js";
|
|
3
|
+
import type { MergePosture } from "./riskVocabulary.js";
|
|
4
|
+
import type { FindingSeverity, ScoreLayer } from "./types.js";
|
|
5
|
+
/** Max operational-impact rows before collapse on scan detail. */
|
|
9
6
|
export declare const TIER1_MAX_VISIBLE_IMPACTS = 3;
|
|
7
|
+
/** Findings list collapse threshold on scan detail evidence panel. */
|
|
10
8
|
export declare const ACT3_EVIDENCE_COLLAPSE_THRESHOLD = 10;
|
|
9
|
+
export type ScanDetailOverallRiskBand = "low" | "moderate" | "high";
|
|
10
|
+
export type ScanDetailLayerConcernLevel = "low" | "medium" | "high";
|
|
11
|
+
export type ScanDetailSignalLayer = {
|
|
12
|
+
layer: ScoreLayer;
|
|
13
|
+
label: string;
|
|
14
|
+
score: number;
|
|
15
|
+
concernLevel: ScanDetailLayerConcernLevel;
|
|
16
|
+
concernLabel: string;
|
|
17
|
+
};
|
|
18
|
+
export type RiskScoreGaugeModel = {
|
|
19
|
+
fillPercent: number;
|
|
20
|
+
band: ScanDetailOverallRiskBand;
|
|
21
|
+
ariaLabel: string;
|
|
22
|
+
};
|
|
23
|
+
export type ScanDetailSignalSummary = {
|
|
24
|
+
score: number;
|
|
25
|
+
overallBand: ScanDetailOverallRiskBand;
|
|
26
|
+
overallLabel: string;
|
|
27
|
+
gauge: RiskScoreGaugeModel;
|
|
28
|
+
layers: ScanDetailSignalLayer[];
|
|
29
|
+
};
|
|
30
|
+
export type RecommendationPriority = "high" | "medium" | "low";
|
|
31
|
+
export type GuidanceSource = "insight" | "recommendation" | "verification";
|
|
32
|
+
export type ScanDetailRecommendationDetail = {
|
|
33
|
+
why: string;
|
|
34
|
+
whyNow: string;
|
|
35
|
+
signals: string[];
|
|
36
|
+
affectedPackages?: {
|
|
37
|
+
names: string[];
|
|
38
|
+
overflowCount: number;
|
|
39
|
+
};
|
|
40
|
+
expectedBenefit: string;
|
|
41
|
+
};
|
|
42
|
+
export type ScanDetailRecommendation = {
|
|
43
|
+
id: string;
|
|
44
|
+
rank: number;
|
|
45
|
+
title: string;
|
|
46
|
+
priority: RecommendationPriority;
|
|
47
|
+
source: GuidanceSource;
|
|
48
|
+
signalFamily?: ObservationSignalFamily | null;
|
|
49
|
+
detail: ScanDetailRecommendationDetail;
|
|
50
|
+
proofRefs?: {
|
|
51
|
+
findingIds?: string[];
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export type ScanDetailRecommendationCenter = {
|
|
55
|
+
heading: string;
|
|
56
|
+
defaultSelectedId: string;
|
|
57
|
+
items: ScanDetailRecommendation[];
|
|
58
|
+
posture: MergePosture | null;
|
|
59
|
+
scanContext?: string;
|
|
60
|
+
};
|
|
11
61
|
export type ScanDetailOperationalImpactItem = {
|
|
12
62
|
message: string;
|
|
13
63
|
where?: string;
|
|
@@ -59,7 +109,7 @@ export type ScanDetailTopology = {
|
|
|
59
109
|
}>;
|
|
60
110
|
};
|
|
61
111
|
export type ScanDetailNarrativeContext = {
|
|
62
|
-
mode:
|
|
112
|
+
mode: NarrativeAvailabilityMode;
|
|
63
113
|
codeIntelligenceAvailable: boolean;
|
|
64
114
|
changedPackagesDisplay: string | null;
|
|
65
115
|
runtimeSurfaceLabel: string | null;
|
|
@@ -106,26 +156,4 @@ export type ScanDetailViewModel = {
|
|
|
106
156
|
codeIntelligenceAvailable?: boolean;
|
|
107
157
|
};
|
|
108
158
|
};
|
|
109
|
-
|
|
110
|
-
scanId: string;
|
|
111
|
-
status: "queued" | "running" | "done" | "failed";
|
|
112
|
-
methodologyVersion?: string | null;
|
|
113
|
-
prNumber?: number | null;
|
|
114
|
-
repoContext?: ScanDetailViewModel["repoContext"];
|
|
115
|
-
};
|
|
116
|
-
/** Bridge copy from Signal summary to Recommended actions. */
|
|
117
|
-
export declare function deriveFollowUpBridgeNote(actionCount: number): string | null;
|
|
118
|
-
/** Act 2 theme sanitizer — strips package/CVE/version content. */
|
|
119
|
-
export declare function sanitizeAct2Theme(raw: string): string | null;
|
|
120
|
-
/** Verdict line from posture + reach band (scanSurfaceCopy.scanDetail.verdictLine). */
|
|
121
|
-
export declare function deriveVerdictLine(posture: MergePosture | null, totalScore: number | null | undefined): string;
|
|
122
|
-
export declare function deriveAct2Themes(result: ScanResult): string[];
|
|
123
|
-
export declare function deriveOperationalImpact(result: ScanResult, verifyLabels?: Set<string>): ScanDetailOperationalImpact;
|
|
124
|
-
export declare function presentScanDetailNarrativeContext(facts: ScanNarrativeFacts): ScanDetailNarrativeContext;
|
|
125
|
-
export declare function deriveVerdictLineFromFacts(facts: ScanNarrativeFacts, result: ScanResult): string;
|
|
126
|
-
/** Scan detail presentation from shared narrative facts. */
|
|
127
|
-
export declare function presentScanDetailViewModel(facts: ScanNarrativeFacts, result: ScanResult, options: DeriveScanDetailOptions): ScanDetailViewModel;
|
|
128
|
-
export declare function deriveScanDetailViewModel(result: ScanResult | null | undefined, options: DeriveScanDetailOptions): ScanDetailViewModel | null;
|
|
129
|
-
/** Tier 1 recall test helper — true when message describes application-level impact. */
|
|
130
|
-
export declare function tier1PassesRecallTest(operationalImpact: ScanDetailOperationalImpact): boolean;
|
|
131
|
-
//# sourceMappingURL=scanDetailViewModel.d.ts.map
|
|
159
|
+
//# sourceMappingURL=scanDetailViewModelTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanDetailViewModelTypes.d.ts","sourceRoot":"","sources":["../src/scanDetailViewModelTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { EngineEmittedScanResult, ScanResult } from "./types.js";
|
|
3
3
|
/** Bump when persisted `result` JSON validation rules change materially (relaxed / legacy-tolerant). */
|
|
4
|
-
export declare const SCAN_RESULT_ABI: "
|
|
4
|
+
export declare const SCAN_RESULT_ABI: "2";
|
|
5
5
|
/** Bump when strict fresh-engine-output validation rules change materially. */
|
|
6
|
-
export declare const ENGINE_OUTPUT_SCAN_ABI: "
|
|
6
|
+
export declare const ENGINE_OUTPUT_SCAN_ABI: "3";
|
|
7
7
|
/**
|
|
8
8
|
* Minimum structural invariants for **persisted** `scans.result` JSON and legacy reads.
|
|
9
9
|
* `methodologyVersion` stays optional so historical rows without it remain valid.
|
|
@@ -88,6 +88,79 @@ export declare const engineOutputScanResultSchema: z.ZodObject<{
|
|
|
88
88
|
codeAnalysisMetrics: z.ZodOptional<z.ZodUnknown>;
|
|
89
89
|
methodologyVersion: z.ZodString;
|
|
90
90
|
generatedAt: z.ZodString;
|
|
91
|
+
assessment: z.ZodObject<{
|
|
92
|
+
posture: z.ZodEnum<{
|
|
93
|
+
safe: "safe";
|
|
94
|
+
needs_review: "needs_review";
|
|
95
|
+
risky: "risky";
|
|
96
|
+
}>;
|
|
97
|
+
confidence: z.ZodEnum<{
|
|
98
|
+
low: "low";
|
|
99
|
+
medium: "medium";
|
|
100
|
+
high: "high";
|
|
101
|
+
}>;
|
|
102
|
+
primaryConcern: z.ZodNullable<z.ZodEnum<{
|
|
103
|
+
confirmed_runtime_usage: "confirmed_runtime_usage";
|
|
104
|
+
security_finding: "security_finding";
|
|
105
|
+
breaking_or_major: "breaking_or_major";
|
|
106
|
+
behavioral_change: "behavioral_change";
|
|
107
|
+
ecosystem_risk: "ecosystem_risk";
|
|
108
|
+
insufficient_evidence: "insufficient_evidence";
|
|
109
|
+
graph_baseline_only: "graph_baseline_only";
|
|
110
|
+
}>>;
|
|
111
|
+
concerns: z.ZodArray<z.ZodObject<{
|
|
112
|
+
kind: z.ZodEnum<{
|
|
113
|
+
confirmed_runtime_usage: "confirmed_runtime_usage";
|
|
114
|
+
security_finding: "security_finding";
|
|
115
|
+
breaking_or_major: "breaking_or_major";
|
|
116
|
+
behavioral_change: "behavioral_change";
|
|
117
|
+
ecosystem_risk: "ecosystem_risk";
|
|
118
|
+
insufficient_evidence: "insufficient_evidence";
|
|
119
|
+
graph_baseline_only: "graph_baseline_only";
|
|
120
|
+
}>;
|
|
121
|
+
rank: z.ZodNumber;
|
|
122
|
+
packages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
123
|
+
evidenceRefs: z.ZodArray<z.ZodString>;
|
|
124
|
+
}, z.core.$strip>>;
|
|
125
|
+
factors: z.ZodArray<z.ZodString>;
|
|
126
|
+
changeClasses: z.ZodArray<z.ZodEnum<{
|
|
127
|
+
tooling_maintenance: "tooling_maintenance";
|
|
128
|
+
test_infra: "test_infra";
|
|
129
|
+
runtime_patch: "runtime_patch";
|
|
130
|
+
runtime_upgrade: "runtime_upgrade";
|
|
131
|
+
security_advisory: "security_advisory";
|
|
132
|
+
breaking_change: "breaking_change";
|
|
133
|
+
ecosystem_unknown: "ecosystem_unknown";
|
|
134
|
+
bulk_mixed: "bulk_mixed";
|
|
135
|
+
removal: "removal";
|
|
136
|
+
}>>;
|
|
137
|
+
presentation: z.ZodObject<{
|
|
138
|
+
narrativeIntensity: z.ZodEnum<{
|
|
139
|
+
minimal: "minimal";
|
|
140
|
+
standard: "standard";
|
|
141
|
+
elevated: "elevated";
|
|
142
|
+
}>;
|
|
143
|
+
reachVisibility: z.ZodEnum<{
|
|
144
|
+
hidden: "hidden";
|
|
145
|
+
contextual: "contextual";
|
|
146
|
+
prominent: "prominent";
|
|
147
|
+
}>;
|
|
148
|
+
verificationIntensity: z.ZodEnum<{
|
|
149
|
+
none: "none";
|
|
150
|
+
advisory: "advisory";
|
|
151
|
+
required: "required";
|
|
152
|
+
}>;
|
|
153
|
+
insightEmissionFloor: z.ZodEnum<{
|
|
154
|
+
none: "none";
|
|
155
|
+
explain_only: "explain_only";
|
|
156
|
+
full: "full";
|
|
157
|
+
}>;
|
|
158
|
+
reportMode: z.ZodEnum<{
|
|
159
|
+
lightweight_pr_graph_baseline: "lightweight_pr_graph_baseline";
|
|
160
|
+
high_signal_pr: "high_signal_pr";
|
|
161
|
+
}>;
|
|
162
|
+
}, z.core.$strip>;
|
|
163
|
+
}, z.core.$strip>;
|
|
91
164
|
}, z.core.$loose>;
|
|
92
165
|
export type EngineOutputScanResultParseFailure = {
|
|
93
166
|
ok: false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanResultSchema.d.ts","sourceRoot":"","sources":["../src/scanResultSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"scanResultSchema.d.ts","sourceRoot":"","sources":["../src/scanResultSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtE,wGAAwG;AACxG,eAAO,MAAM,eAAe,EAAG,GAAY,CAAC;AAE5C,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,EAAG,GAAY,CAAC;AASnD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4Bb,CAAC;AAUjB;;;GAGG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIvC,CAAC;AAEH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,uBAAuB,CAAC;CACjC,CAAC;AAEF,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,OAAO,GACZ,kCAAkC,GAAG,kCAAkC,CAazE;AAED,uFAAuF;AACvF,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,OAAO,GACZ,uBAAuB,CAMzB;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,GACZ,sBAAsB,GAAG,sBAAsB,CAajD;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAMhE"}
|
package/dist/scanResultSchema.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { assessmentSchema } from "./assessmentSchema.js";
|
|
2
3
|
/** Bump when persisted `result` JSON validation rules change materially (relaxed / legacy-tolerant). */
|
|
3
|
-
export const SCAN_RESULT_ABI = "
|
|
4
|
+
export const SCAN_RESULT_ABI = "2";
|
|
4
5
|
/** Bump when strict fresh-engine-output validation rules change materially. */
|
|
5
|
-
export const ENGINE_OUTPUT_SCAN_ABI = "
|
|
6
|
+
export const ENGINE_OUTPUT_SCAN_ABI = "3";
|
|
6
7
|
const layerScoresSchema = z.object({
|
|
7
8
|
security: z.number(),
|
|
8
9
|
maintainability: z.number(),
|
|
@@ -57,6 +58,7 @@ const engineOutputGeneratedAtSchema = z
|
|
|
57
58
|
export const engineOutputScanResultSchema = scanResultSchema.extend({
|
|
58
59
|
methodologyVersion: z.string().trim().min(1),
|
|
59
60
|
generatedAt: engineOutputGeneratedAtSchema,
|
|
61
|
+
assessment: assessmentSchema,
|
|
60
62
|
});
|
|
61
63
|
export function safeParseEngineOutputScanResult(data) {
|
|
62
64
|
const parsed = engineOutputScanResultSchema.safeParse(data);
|
|
@@ -77,10 +77,26 @@ describe("scanResultSchema", () => {
|
|
|
77
77
|
expect(parsed.findings).toEqual([]);
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
|
+
const minimalAssessment = {
|
|
81
|
+
posture: "safe",
|
|
82
|
+
confidence: "high",
|
|
83
|
+
primaryConcern: null,
|
|
84
|
+
concerns: [],
|
|
85
|
+
factors: ["tooling_maintenance"],
|
|
86
|
+
changeClasses: ["tooling_maintenance"],
|
|
87
|
+
presentation: {
|
|
88
|
+
narrativeIntensity: "minimal",
|
|
89
|
+
reachVisibility: "hidden",
|
|
90
|
+
verificationIntensity: "advisory",
|
|
91
|
+
insightEmissionFloor: "none",
|
|
92
|
+
reportMode: "high_signal_pr",
|
|
93
|
+
},
|
|
94
|
+
};
|
|
80
95
|
describe("engineOutputScanResultSchema (strict, fresh engine only)", () => {
|
|
81
96
|
const withMethodology = {
|
|
82
97
|
...minimalValid,
|
|
83
98
|
methodologyVersion: "engine-test-fixture/v1",
|
|
99
|
+
assessment: minimalAssessment,
|
|
84
100
|
};
|
|
85
101
|
it("rejects payload that relaxed parser accepts when methodology is missing", () => {
|
|
86
102
|
const r = safeParseEngineOutputScanResult(minimalValid);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { assertTrustedActionsSummaryAllowed, assertTrustedScanResult, auditTrustedActionsOutput, isStubMethodologyVersion, trustedActionsSummaryDenylistPhrases, validateTrustedEngineScanResult, } from "./trustedScanGuards.js";
|
|
3
|
+
import { assessmentStub } from "./fixtures/assessmentFixtures.js";
|
|
3
4
|
import { scanSurfaceCopy } from "./scanSurfaceCopy.js";
|
|
4
5
|
const baseResult = {
|
|
5
6
|
totalScore: 10,
|
|
@@ -13,6 +14,12 @@ const baseResult = {
|
|
|
13
14
|
recommendations: [],
|
|
14
15
|
generatedAt: "2026-01-01T00:00:00.000Z",
|
|
15
16
|
methodologyVersion: "engine-stub/v2",
|
|
17
|
+
assessment: assessmentStub,
|
|
18
|
+
decision: {
|
|
19
|
+
recommendation: "needs_review",
|
|
20
|
+
confidence: "low",
|
|
21
|
+
reasoning: ["Stub engine cannot perform real analysis"],
|
|
22
|
+
},
|
|
16
23
|
};
|
|
17
24
|
describe("trustedScanGuards", () => {
|
|
18
25
|
it("detects stub methodology", () => {
|