@mergesignal/shared 0.2.7 → 0.3.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 (85) hide show
  1. package/dist/actionsStepSummary.d.ts.map +1 -1
  2. package/dist/actionsStepSummary.js +2 -29
  3. package/dist/collectNarrativeWhyBullets.d.ts +12 -0
  4. package/dist/collectNarrativeWhyBullets.d.ts.map +1 -0
  5. package/dist/collectNarrativeWhyBullets.js +104 -0
  6. package/dist/deriveScanNarrative.d.ts +0 -3
  7. package/dist/deriveScanNarrative.d.ts.map +1 -1
  8. package/dist/deriveScanNarrative.js +177 -63
  9. package/dist/deriveScanNarrative.test.js +90 -6
  10. package/dist/engineWireRegression.test.d.ts +2 -0
  11. package/dist/engineWireRegression.test.d.ts.map +1 -0
  12. package/dist/engineWireRegression.test.js +57 -0
  13. package/dist/fixtures/legacyEngineRepoIntelligence.d.ts +28 -0
  14. package/dist/fixtures/legacyEngineRepoIntelligence.d.ts.map +1 -0
  15. package/dist/fixtures/legacyEngineRepoIntelligence.js +28 -0
  16. package/dist/fixtures/repoIntelligenceFixtures.d.ts +2 -2
  17. package/dist/fixtures/repoIntelligenceFixtures.d.ts.map +1 -1
  18. package/dist/fixtures/repoIntelligenceFixtures.js +59 -3
  19. package/dist/fixtures/repoIntelligenceTestHelpers.d.ts +5 -0
  20. package/dist/fixtures/repoIntelligenceTestHelpers.d.ts.map +1 -0
  21. package/dist/fixtures/repoIntelligenceTestHelpers.js +28 -0
  22. package/dist/formatInsight.d.ts +2 -2
  23. package/dist/formatInsight.d.ts.map +1 -1
  24. package/dist/formatInsight.js +2 -7
  25. package/dist/formatInsight.test.js +1 -1
  26. package/dist/index.d.ts +6 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +6 -0
  29. package/dist/narrativeParity.test.d.ts +2 -0
  30. package/dist/narrativeParity.test.d.ts.map +1 -0
  31. package/dist/narrativeParity.test.js +65 -0
  32. package/dist/narrativePresentation.d.ts +50 -0
  33. package/dist/narrativePresentation.d.ts.map +1 -0
  34. package/dist/narrativePresentation.js +180 -0
  35. package/dist/narrativePresentation.test.d.ts +2 -0
  36. package/dist/narrativePresentation.test.d.ts.map +1 -0
  37. package/dist/narrativePresentation.test.js +54 -0
  38. package/dist/normalizeGeneratedText.d.ts +8 -0
  39. package/dist/normalizeGeneratedText.d.ts.map +1 -0
  40. package/dist/normalizeGeneratedText.js +31 -0
  41. package/dist/normalizeGeneratedText.test.d.ts +2 -0
  42. package/dist/normalizeGeneratedText.test.d.ts.map +1 -0
  43. package/dist/normalizeGeneratedText.test.js +18 -0
  44. package/dist/prCheckRunPresentation.d.ts +4 -3
  45. package/dist/prCheckRunPresentation.d.ts.map +1 -1
  46. package/dist/prCheckRunPresentation.js +56 -51
  47. package/dist/prCheckRunPresentation.test.js +2 -2
  48. package/dist/presentGitHubPrComment.d.ts +9 -0
  49. package/dist/presentGitHubPrComment.d.ts.map +1 -0
  50. package/dist/presentGitHubPrComment.js +80 -0
  51. package/dist/presentScanCardSummary.d.ts.map +1 -1
  52. package/dist/presentScanCardSummary.js +69 -64
  53. package/dist/repoIntelligenceMappers.d.ts +20 -0
  54. package/dist/repoIntelligenceMappers.d.ts.map +1 -0
  55. package/dist/repoIntelligenceMappers.js +60 -0
  56. package/dist/repoIntelligenceSchema.contract.test.d.ts +2 -0
  57. package/dist/repoIntelligenceSchema.contract.test.d.ts.map +1 -0
  58. package/dist/repoIntelligenceSchema.contract.test.js +19 -0
  59. package/dist/repoIntelligenceSchema.d.ts +52 -83
  60. package/dist/repoIntelligenceSchema.d.ts.map +1 -1
  61. package/dist/repoIntelligenceSchema.js +99 -141
  62. package/dist/repoIntelligenceValidation.d.ts +18 -0
  63. package/dist/repoIntelligenceValidation.d.ts.map +1 -0
  64. package/dist/repoIntelligenceValidation.js +76 -0
  65. package/dist/repoIntelligenceValidation.persist.test.d.ts +2 -0
  66. package/dist/repoIntelligenceValidation.persist.test.d.ts.map +1 -0
  67. package/dist/repoIntelligenceValidation.persist.test.js +44 -0
  68. package/dist/riskVocabulary.js +1 -1
  69. package/dist/scanCardSummary.d.ts +9 -1
  70. package/dist/scanCardSummary.d.ts.map +1 -1
  71. package/dist/scanCardSummary.js +1 -1
  72. package/dist/scanCardSummary.test.js +12 -8
  73. package/dist/scanDetailViewModel.d.ts +9 -1
  74. package/dist/scanDetailViewModel.d.ts.map +1 -1
  75. package/dist/scanDetailViewModel.js +164 -37
  76. package/dist/scanDetailViewModel.test.js +28 -1
  77. package/dist/scanNarrativeFacts.d.ts +23 -8
  78. package/dist/scanNarrativeFacts.d.ts.map +1 -1
  79. package/dist/scanNarrativeFacts.js +7 -0
  80. package/dist/scanSurfaceCopy.d.ts +26 -26
  81. package/dist/scanSurfaceCopy.d.ts.map +1 -1
  82. package/dist/scanSurfaceCopy.js +26 -26
  83. package/dist/types.d.ts +15 -3
  84. package/dist/types.d.ts.map +1 -1
  85. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
1
  import { humanizeEngineSurfaceText, layerRiskBandLabel, sortPRInsightsForDisplay, truncateWithEllipsis, } from "./actionsStepSummary.js";
2
2
  import { mapFindingToCatalogPhrase, mapGraphInsightsToCatalogPhrases, phraseForFamily, } from "./cardObservationCatalog.js";
3
3
  import { deriveScanNarrative } from "./deriveScanNarrative.js";
4
- import { presentScanCardSummary } from "./presentScanCardSummary.js";
4
+ import { formatCardAreaLabels } from "./formatCardAreaLabels.js";
5
+ import { composeContextLineFromFacts, formatChangedPackagesShort, formatUsageSummaryLine, labelBlastRadiusLevel, labelReachabilityKind, labelRuntimeSurface, summarizeBlastRadius, } from "./narrativePresentation.js";
6
+ import { normalizeGeneratedText, normalizeGeneratedTextNullable, } from "./normalizeGeneratedText.js";
5
7
  import { deriveCardOperationalObservations } from "./deriveCardOperationalObservations.js";
6
8
  import { deriveScanDetailRecommendations, recommendationTitlesForDedupe, } from "./deriveScanDetailRecommendations.js";
7
9
  import { deriveSignalSummary, } from "./deriveRiskScoreSummary.js";
@@ -208,6 +210,72 @@ function graphInsightToPackage(item, severity, evidence) {
208
210
  evidence,
209
211
  };
210
212
  }
213
+ function usageWhereFromFacts(facts) {
214
+ const primary = facts.changedPackages.primary;
215
+ const row = facts.packageUsage.find((u) => u.packageName === primary) ??
216
+ facts.packageUsage[0];
217
+ if (!row)
218
+ return undefined;
219
+ const paths = [...row.paths, ...row.criticalPaths, ...row.files].filter(Boolean);
220
+ if (paths.length === 0 && row.areas.length > 0) {
221
+ return row.areas.slice(0, 3).join(", ");
222
+ }
223
+ if (paths.length === 0)
224
+ return undefined;
225
+ const sample = paths.slice(0, 3).join(", ");
226
+ if (paths.length > 3) {
227
+ return `${sample} (+${paths.length - 3} more)`;
228
+ }
229
+ return sample;
230
+ }
231
+ function buildAttentionAreasFromFacts(facts) {
232
+ const areas = [];
233
+ if (facts.hotspots.length > 0) {
234
+ const packages = facts.hotspots.map((h) => ({
235
+ name: h.packageName,
236
+ direct: true,
237
+ evidence: h.paths[0],
238
+ }));
239
+ areas.push({
240
+ problemLabel: "Dependency hotspots",
241
+ problemDescription: "Packages where paths converge or corpus analysis flagged critical usage.",
242
+ packages: packages.slice(0, ACT3_EVIDENCE_COLLAPSE_THRESHOLD),
243
+ overflowCount: Math.max(0, packages.length - ACT3_EVIDENCE_COLLAPSE_THRESHOLD),
244
+ });
245
+ }
246
+ const blast = facts.blastRadius;
247
+ if (blast &&
248
+ (blast.level === "wide" || (blast.changedPackageCount ?? 0) >= 8)) {
249
+ const names = facts.changedPackages.all;
250
+ if (names.length > 0) {
251
+ const packages = names
252
+ .slice(0, ACT3_EVIDENCE_COLLAPSE_THRESHOLD)
253
+ .map((name) => ({ name, direct: true }));
254
+ areas.push({
255
+ problemLabel: phraseForFamily("blast_radius"),
256
+ problemDescription: blast.factors.length > 0
257
+ ? `Wide blast radius: ${blast.factors.slice(0, 3).join(", ").replace(/_/g, " ")}`
258
+ : "Many packages changed in this upgrade.",
259
+ packages,
260
+ overflowCount: Math.max(0, names.length - ACT3_EVIDENCE_COLLAPSE_THRESHOLD),
261
+ });
262
+ }
263
+ }
264
+ return areas;
265
+ }
266
+ function mergeAttentionAreas(fromFacts, fromGraph) {
267
+ if (fromFacts.length === 0)
268
+ return fromGraph;
269
+ const factPackageNames = new Set(fromFacts.flatMap((a) => a.packages.map((p) => p.name)));
270
+ const filteredGraph = fromGraph.filter((area) => {
271
+ if (area.problemLabel !== phraseForFamily("transitive_hotspots")) {
272
+ return true;
273
+ }
274
+ const onlyDupes = area.packages.every((p) => factPackageNames.has(p.name));
275
+ return !onlyDupes;
276
+ });
277
+ return [...fromFacts, ...filteredGraph];
278
+ }
211
279
  function buildAttentionAreas(result) {
212
280
  const areas = [];
213
281
  const gi = result.graphInsights;
@@ -312,7 +380,7 @@ function buildTopology(result) {
312
380
  }))
313
381
  : [];
314
382
  return {
315
- summaryLine: `${nodes} packages · ${edges} edges · max depth ${maxDepth}`,
383
+ summaryLine: normalizeGeneratedText(`${nodes} packages | ${edges} edges | max depth ${maxDepth}`),
316
384
  deepest,
317
385
  };
318
386
  }
@@ -346,28 +414,64 @@ function deriveConfidenceCaveat(result) {
346
414
  }
347
415
  return undefined;
348
416
  }
349
- function narrativeContextFromFacts(facts) {
350
- const card = presentScanCardSummary(facts);
417
+ export function presentScanDetailNarrativeContext(facts) {
418
+ const affectedAreas = [];
419
+ for (const area of facts.affectedAreas) {
420
+ const formatted = formatCardAreaLabels([area.label], 1);
421
+ if (formatted[0])
422
+ affectedAreas.push(formatted[0]);
423
+ if (affectedAreas.length >= 4)
424
+ break;
425
+ }
426
+ const usageHighlights = [];
427
+ for (const row of facts.packageUsage.slice(0, 4)) {
428
+ const paths = [...row.paths, ...row.criticalPaths, ...row.files];
429
+ if (paths[0])
430
+ usageHighlights.push(paths[0]);
431
+ }
432
+ const blast = summarizeBlastRadius(facts, 5);
351
433
  return {
352
- mode: card.narrativeMode,
353
- codeIntelligenceAvailable: card.codeIntelligenceAvailable,
354
- changedPackagesDisplay: card.changedPackagesDisplay,
355
- runtimeSurfaceLabel: card.runtimeSurfaceLabel,
356
- reachabilityLabel: card.reachabilityLabel,
357
- blastRadiusLabel: card.blastRadiusLabel,
358
- affectedAreas: card.affectedAreas,
359
- structuralOnlyDisclaimer: card.structuralOnlyDisclaimer,
434
+ mode: facts.availability.mode,
435
+ codeIntelligenceAvailable: facts.availability.codeIntelligenceAvailable,
436
+ changedPackagesDisplay: formatChangedPackagesShort(facts, 4),
437
+ runtimeSurfaceLabel: labelRuntimeSurface(facts),
438
+ reachabilityLabel: labelReachabilityKind(facts),
439
+ blastRadiusLabel: labelBlastRadiusLevel(facts),
440
+ affectedAreas,
441
+ structuralOnlyDisclaimer: facts.availability.mode === "graph_fallback" &&
442
+ !facts.availability.tiersPresent.tier1
443
+ ? scanSurfaceCopy.narrativeCard.structuralOnlyDisclaimer
444
+ : null,
445
+ usageHighlights: usageHighlights.slice(0, 5),
446
+ frameworks: facts.frameworks.slice(0, 5),
447
+ blastRadiusFactors: blast.factors.map((f) => f.replace(/_/g, " ")),
448
+ hotspotNames: facts.hotspots.map((h) => h.packageName).slice(0, 8),
449
+ usageContextLine: normalizeGeneratedTextNullable(formatUsageSummaryLine(facts, 2)),
450
+ upgradeContextLine: normalizeGeneratedTextNullable(composeContextLineFromFacts(facts, {
451
+ includePathSample: true,
452
+ maxAreas: 4,
453
+ })),
360
454
  };
361
455
  }
362
- function guidanceToImpactItem(g, verifyLabels) {
456
+ function narrativeContextFromFacts(facts) {
457
+ return presentScanDetailNarrativeContext(facts);
458
+ }
459
+ function guidanceToImpactItem(g, verifyLabels, facts) {
363
460
  const verify = g.remediation &&
364
461
  !verifyLabels.has(g.remediation.toLowerCase().replace(/\s+/g, " ").trim())
365
462
  ? g.remediation
366
463
  : undefined;
464
+ let where = g.context?.trim() || undefined;
465
+ if (!where &&
466
+ facts &&
467
+ (facts.availability.mode === "pr_intelligence" ||
468
+ facts.availability.tiersPresent.tier1)) {
469
+ where = usageWhereFromFacts(facts);
470
+ }
367
471
  return {
368
- message: g.message,
369
- where: g.context,
370
- verify,
472
+ message: normalizeGeneratedText(g.message),
473
+ where: where ? normalizeGeneratedText(where) : undefined,
474
+ verify: verify ? normalizeGeneratedText(verify) : undefined,
371
475
  affectedFiles: g.affectedFiles,
372
476
  };
373
477
  }
@@ -377,7 +481,7 @@ function deriveOperationalImpactFromFacts(facts, result, verifyLabels) {
377
481
  (facts.availability.tiersPresent.tier1 && changedGuidance.length > 0)) {
378
482
  const items = changedGuidance
379
483
  .slice(0, 6)
380
- .map((g) => guidanceToImpactItem(g, verifyLabels));
484
+ .map((g) => guidanceToImpactItem(g, verifyLabels, facts));
381
485
  if (items.length > 0) {
382
486
  return { status: "rich", items };
383
487
  }
@@ -393,41 +497,60 @@ function deriveOperationalImpactFromFacts(facts, result, verifyLabels) {
393
497
  status: "rich",
394
498
  items: changedGuidance
395
499
  .slice(0, 6)
396
- .map((g) => guidanceToImpactItem(g, verifyLabels)),
500
+ .map((g) => guidanceToImpactItem(g, verifyLabels, facts)),
397
501
  };
398
502
  }
399
503
  return deriveOperationalImpact(result, verifyLabels);
400
504
  }
505
+ function themeCandidateFromLabel(label) {
506
+ const trimmed = label.trim();
507
+ if (!trimmed)
508
+ return null;
509
+ return sanitizeAct2Theme(trimmed) ?? trimmed.slice(0, ACT2_MAX_THEME_CHARS);
510
+ }
401
511
  function deriveBecauseThemesFromFacts(facts) {
402
512
  const themes = [];
403
513
  const seen = new Set();
404
- for (const g of facts.reviewerGuidance.slice(0, ACT2_MAX_THEMES + 2)) {
405
- const sanitized = sanitizeAct2Theme(g.message);
406
- if (!sanitized)
407
- continue;
408
- const key = sanitized.toLowerCase();
514
+ const prIntelligence = facts.availability.mode === "pr_intelligence" ||
515
+ facts.availability.tiersPresent.tier1;
516
+ const pushTheme = (raw) => {
517
+ if (!raw)
518
+ return;
519
+ const normalized = normalizeGeneratedText(raw);
520
+ const key = normalized.toLowerCase();
409
521
  if (seen.has(key))
410
- continue;
522
+ return;
411
523
  seen.add(key);
412
- themes.push(sanitized);
524
+ themes.push(normalized);
525
+ };
526
+ if (prIntelligence) {
527
+ for (const area of facts.affectedAreas) {
528
+ pushTheme(themeCandidateFromLabel(area.label));
529
+ if (themes.length >= ACT2_MAX_THEMES)
530
+ return themes;
531
+ }
532
+ for (const factor of facts.blastRadius?.factors ?? []) {
533
+ pushTheme(themeCandidateFromLabel(factor.replace(/_/g, " ")));
534
+ if (themes.length >= ACT2_MAX_THEMES)
535
+ return themes;
536
+ }
537
+ const reachLabel = labelReachabilityKind(facts);
538
+ if (reachLabel)
539
+ pushTheme(reachLabel);
540
+ }
541
+ for (const g of facts.reviewerGuidance.slice(0, ACT2_MAX_THEMES + 2)) {
542
+ pushTheme(sanitizeAct2Theme(g.message));
413
543
  if (themes.length >= ACT2_MAX_THEMES)
414
- break;
544
+ return themes;
415
545
  }
416
- if (themes.length < ACT2_MAX_THEMES) {
546
+ if (themes.length < ACT2_MAX_THEMES && !prIntelligence) {
417
547
  for (const ctx of facts.repositoryContext) {
418
- const sanitized = sanitizeAct2Theme(phraseForFamily(ctx.family));
419
- if (!sanitized)
420
- continue;
421
- const key = sanitized.toLowerCase();
422
- if (seen.has(key))
423
- continue;
424
- seen.add(key);
425
- themes.push(sanitized);
548
+ pushTheme(sanitizeAct2Theme(phraseForFamily(ctx.family)));
426
549
  if (themes.length >= ACT2_MAX_THEMES)
427
550
  break;
428
551
  }
429
552
  }
430
- return themes;
553
+ return themes.slice(0, ACT2_MAX_THEMES);
431
554
  }
432
555
  function deriveVerdictLineFromFacts(facts, result) {
433
556
  const topGuidance = facts.reviewerGuidance.find((g) => (g.scope === "changed" || g.kind === "insight") && g.message.trim());
@@ -450,7 +573,11 @@ export function presentScanDetailViewModel(facts, result, options) {
450
573
  const themes = deriveBecauseThemesFromFacts(facts);
451
574
  const confidenceCaveat = deriveConfidenceCaveat(result);
452
575
  const because = themes.length > 0 || confidenceCaveat ? { themes, confidenceCaveat } : null;
453
- const attentionAreas = buildAttentionAreas(result);
576
+ const factsAttention = facts.availability.mode === "pr_intelligence" ||
577
+ facts.availability.tiersPresent.tier1
578
+ ? buildAttentionAreasFromFacts(facts)
579
+ : [];
580
+ const attentionAreas = mergeAttentionAreas(factsAttention, buildAttentionAreas(result));
454
581
  const allFindings = annotateFindingsWithCoverage(buildFindingRows(result), recommendedActions);
455
582
  const topology = buildTopology(result);
456
583
  const hasEvidence = attentionAreas.length > 0 || allFindings.length > 0 || topology != null;
@@ -1,6 +1,8 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { primaryPrExample } from "./productMessaging.js";
3
3
  import { ACT2_MAX_THEMES, TIER1_MAX_VISIBLE_IMPACTS, deriveAct2Themes, deriveOperationalImpact, deriveFollowUpBridgeNote, deriveScanDetailViewModel, deriveVerdictLine, sanitizeAct2Theme, tier1PassesRecallTest, } from "./scanDetailViewModel.js";
4
+ import { fixtureRepoIntelligenceFastify } from "./fixtures/repoIntelligenceFixtures.js";
5
+ import { analysisPreparationWithValidRepoIntel } from "./fixtures/repoIntelligenceTestHelpers.js";
4
6
  const baseResult = {
5
7
  totalScore: 10,
6
8
  layerScores: {
@@ -58,7 +60,7 @@ describe("reach vocabulary on fixtures", () => {
58
60
  changedPackages: Array.from({ length: 14 }, (_, i) => `pkg-${i}`),
59
61
  }, { scanId: "s2", status: "done" });
60
62
  expect(vm?.verdict.scopeChip).toBe("Wide reach");
61
- expect(vm?.verdict.verdictLine).toBe("No merge blockers · wide upgrade footprint");
63
+ expect(vm?.verdict.verdictLine).toBe("No merge blockers - wide upgrade footprint");
62
64
  });
63
65
  it("needs review + limited reach — minimalResult score 42", () => {
64
66
  const vm = deriveScanDetailViewModel(minimalResult(), {
@@ -128,6 +130,31 @@ describe("deriveVerdictLine", () => {
128
130
  });
129
131
  });
130
132
  describe("Tier 1 success criterion", () => {
133
+ it("surfaces package usage paths in narrative context and evidence when corpus available", () => {
134
+ const vm = deriveScanDetailViewModel({
135
+ ...baseResult,
136
+ changedPackages: ["fastify"],
137
+ analysisPreparation: analysisPreparationWithValidRepoIntel(),
138
+ repoIntelligence: fixtureRepoIntelligenceFastify,
139
+ insights: [
140
+ {
141
+ type: "usage_risk",
142
+ priority: "high",
143
+ confidence: "confirmed",
144
+ scope: "changed",
145
+ message: "Fastify middleware ordering may shift",
146
+ context: "",
147
+ remediation: "Run auth integration tests",
148
+ },
149
+ ],
150
+ }, { scanId: "corpus", status: "done" });
151
+ expect(vm?.narrativeContext.usageHighlights.length).toBeGreaterThan(0);
152
+ expect(vm?.narrativeContext.usageContextLine).toMatch(/Used in/);
153
+ expect(vm?.narrativeContext.blastRadiusFactors.length).toBeGreaterThan(0);
154
+ const hotspotArea = vm?.evidence?.attentionAreas.find((a) => a.problemLabel.includes("hotspot"));
155
+ expect(hotspotArea?.packages[0]?.name).toBe("fastify");
156
+ expect(tier1PassesRecallTest(vm.operationalImpact)).toBe(true);
157
+ });
131
158
  it("insight-rich scan passes recall test", () => {
132
159
  const vm = deriveScanDetailViewModel({
133
160
  ...minimalResult(),
@@ -7,6 +7,14 @@ export type BlastRadiusLevel = "narrow" | "moderate" | "wide";
7
7
  export type ReviewerGuidanceKind = "insight" | "finding" | "recommendation";
8
8
  export type ReviewerGuidanceScope = "changed" | "all" | "unknown";
9
9
  export type RepositoryContextSource = "graphInsights" | "explain" | "finding";
10
+ export type NarrativePackageUsage = {
11
+ packageName: string;
12
+ paths: string[];
13
+ criticalPaths: string[];
14
+ files: string[];
15
+ areas: string[];
16
+ };
17
+ export type RepoIntelligenceParseStatus = "ok" | "invalid" | "absent" | "untrusted";
10
18
  export type ScanNarrativeFacts = {
11
19
  availability: {
12
20
  mode: NarrativeAvailabilityMode;
@@ -16,30 +24,33 @@ export type ScanNarrativeFacts = {
16
24
  tier2: boolean;
17
25
  tier3: boolean;
18
26
  };
27
+ repoIntelligenceParse: RepoIntelligenceParseStatus;
19
28
  };
20
29
  changedPackages: {
21
30
  primary: string | null;
22
31
  others: string[];
23
32
  all: string[];
24
33
  };
34
+ packageUsage: NarrativePackageUsage[];
35
+ frameworks: string[];
25
36
  runtimeSurface: {
26
37
  kind: RuntimeSurfaceKind;
27
- evidence?: {
28
- packages?: string[];
29
- paths?: string[];
38
+ evidence: {
39
+ packages: string[];
40
+ paths: string[];
30
41
  };
31
42
  } | null;
32
43
  reachability: {
33
44
  kind: ReachabilityKind;
34
- evidence?: {
35
- paths?: string[];
36
- frameworks?: string[];
45
+ evidence: {
46
+ paths: string[];
47
+ frameworks: string[];
37
48
  };
38
49
  } | null;
39
50
  blastRadius: {
40
51
  level: BlastRadiusLevel;
41
52
  changedPackageCount?: number;
42
- factors?: string[];
53
+ factors: string[];
43
54
  } | null;
44
55
  affectedAreas: Array<{
45
56
  id: string;
@@ -49,7 +60,7 @@ export type ScanNarrativeFacts = {
49
60
  packageName: string;
50
61
  source: "code" | "graph";
51
62
  depth?: number;
52
- paths?: string[];
63
+ paths: string[];
53
64
  }>;
54
65
  reviewerGuidance: Array<{
55
66
  kind: ReviewerGuidanceKind;
@@ -76,4 +87,8 @@ export type ScanNarrativeFacts = {
76
87
  riskIndex: number | null;
77
88
  };
78
89
  export declare const EMPTY_SCAN_NARRATIVE_FACTS: ScanNarrativeFacts;
90
+ /** Derivation caps — presenters apply tighter channel limits. */
91
+ export declare const NARRATIVE_FACT_MAX_PATHS = 20;
92
+ export declare const NARRATIVE_FACT_MAX_AREAS = 12;
93
+ export declare const NARRATIVE_FACT_MAX_HOTSPOTS = 15;
79
94
  //# sourceMappingURL=scanNarrativeFacts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanNarrativeFacts.d.ts","sourceRoot":"","sources":["../src/scanNarrativeFacts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanNarrativeFacts.d.ts","sourceRoot":"","sources":["../src/scanNarrativeFacts.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,11 @@ export const EMPTY_SCAN_NARRATIVE_FACTS = {
3
3
  mode: "denormalized",
4
4
  codeIntelligenceAvailable: false,
5
5
  tiersPresent: { tier1: false, tier2: false, tier3: false },
6
+ repoIntelligenceParse: "absent",
6
7
  },
7
8
  changedPackages: { primary: null, others: [], all: [] },
9
+ packageUsage: [],
10
+ frameworks: [],
8
11
  runtimeSurface: null,
9
12
  reachability: null,
10
13
  blastRadius: null,
@@ -16,3 +19,7 @@ export const EMPTY_SCAN_NARRATIVE_FACTS = {
16
19
  mergePosture: null,
17
20
  riskIndex: null,
18
21
  };
22
+ /** Derivation caps — presenters apply tighter channel limits. */
23
+ export const NARRATIVE_FACT_MAX_PATHS = 20;
24
+ export const NARRATIVE_FACT_MAX_AREAS = 12;
25
+ export const NARRATIVE_FACT_MAX_HOTSPOTS = 15;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Single source for short scan pipeline / Actions copy (not i18n keep flat and small).
2
+ * Single source for short scan pipeline / Actions copy (not i18n - keep flat and small).
3
3
  * Risk / merge posture labels stay in riskVocabulary / MERGE_POSTURE_LABEL.
4
4
  */
5
5
  export declare const scanSurfaceCopy: {
@@ -14,7 +14,7 @@ export declare const scanSurfaceCopy: {
14
14
  readonly failureTitle: "MergeSignal";
15
15
  readonly failureBody: "Analysis could not be completed. Check the workflow logs for details.";
16
16
  readonly demoSummaryTitle: "MergeSignal (demo output)";
17
- readonly demoSummaryBanner: "Sample analysis only not production MergeSignal results. Do not use for merge decisions.";
17
+ readonly demoSummaryBanner: "Sample analysis only - not production MergeSignal results. Do not use for merge decisions.";
18
18
  readonly trustedSummaryMethodologyLine: "Methodology";
19
19
  /** Dogfood workflow: secret missing on same-repo runs (annotation + logs). */
20
20
  readonly trustedWorkflowSecretMissing: "Trusted MergeSignal analysis is unavailable in this repository. Complete engine access setup, then re-run the workflow.";
@@ -35,7 +35,7 @@ export declare const scanSurfaceCopy: {
35
35
  readonly pushTrustedScanSkippedNoEngineToken: "Trusted MergeSignal analysis was skipped because no engine access token is configured for this repository.";
36
36
  /** Step summary when trusted scan cannot start (canonical repo, token missing). */
37
37
  readonly trustedWorkflowCredentialHintBody: "The engine checkout token was not available to this workflow run. Add it under this repository's Actions secrets, or grant this repository access to an organization secret. Secrets that exist only on a GitHub Environment are not available here unless this job declares that environment.";
38
- /** Trusted step summary H1 product line (before posture · risk index). */
38
+ /** Trusted step summary H1 product line (before posture | risk index). */
39
39
  readonly trustedStepSummaryTitlePrefix: "MergeSignal dependency review";
40
40
  /** GitHub Actions step summary: risk index direction (shared with web/CLI where imported). */
41
41
  readonly riskIndexDirectionShort: "0 = lowest merge risk, 100 = highest merge risk";
@@ -43,13 +43,13 @@ export declare const scanSurfaceCopy: {
43
43
  readonly mergePostureUnavailableShort: "Posture unavailable";
44
44
  readonly mergePostureUnavailableDetail: "This scan did not include a merge posture verdict; use the risk index as a coarse signal only.";
45
45
  /** `<summary>` lines for collapsible sections (keep short for GitHub UI). */
46
- readonly scoreBreakdownDetailsSummary: "Layer scores this scan";
46
+ readonly scoreBreakdownDetailsSummary: "Layer scores - this scan";
47
47
  readonly dependencyGraphDetailsSummary: "Graph context";
48
48
  readonly moreActionsDetailsSummary: "More guidance";
49
49
  readonly moreInsightsDetailsSummary: "More insights";
50
50
  /** Inside dependency graph `<details>`. */
51
- readonly supportingGraphContextNote: "Supporting context not a merge verdict by itself.";
52
- readonly layerScoreGlossary: "*Higher column scores = more risk in that dimension (0 best 100 worst).*";
51
+ readonly supportingGraphContextNote: "Supporting context - not a merge verdict by itself.";
52
+ readonly layerScoreGlossary: "*Higher column scores = more risk in that dimension (0 best ??? 100 worst).*";
53
53
  /** After layer table: scan-specific drivers from explain/contributions. */
54
54
  readonly layerDriversHeading: "Signals behind elevated scores";
55
55
  /** When surfacing recommendation rationale first (trusted default fold). */
@@ -58,7 +58,7 @@ export declare const scanSurfaceCopy: {
58
58
  /** Development profile: no recommendations or actionable insights. */
59
59
  readonly devNoImmediateActions: "No immediate actions required";
60
60
  };
61
- /** GitHub App Check Run (PR) calm, concise; not Actions step summary. */
61
+ /** GitHub App Check Run (PR) - calm, concise; not Actions step summary. */
62
62
  readonly checkRun: {
63
63
  readonly titleBase: "PR dependency change";
64
64
  readonly titleBaselineSuffix: "baseline scan only";
@@ -73,9 +73,9 @@ export declare const scanSurfaceCopy: {
73
73
  };
74
74
  readonly product: {
75
75
  /** Single line for UI/CLI/Actions parity (risk index semantics). */
76
- readonly riskIndexDirectionShort: "0 is best · 100 is worst";
76
+ readonly riskIndexDirectionShort: "0 is best | 100 is worst";
77
77
  };
78
- /** Scan detail page (`/scan/[id]`) show-don't-teach reviewer copy. */
78
+ /** Scan detail page (`/scan/[id]`) - show-don't-teach reviewer copy. */
79
79
  readonly scanDetail: {
80
80
  readonly recommendedActionsHeading: "Recommended actions";
81
81
  readonly signalSummaryHeading: "Signal summary";
@@ -88,7 +88,7 @@ export declare const scanSurfaceCopy: {
88
88
  readonly proofHeading: "Proof";
89
89
  readonly nextStepsHeading: "Recommended next steps";
90
90
  readonly topologySummary: "Dependency topology";
91
- readonly topologyCollapsedHint: "Supporting detail graph paths and depth";
91
+ readonly topologyCollapsedHint: "Supporting detail - graph paths and depth";
92
92
  readonly whereLabel: "Where";
93
93
  readonly verifyLabel: "Verify";
94
94
  readonly moreImpactsSummary: "More impacts";
@@ -101,15 +101,15 @@ export declare const scanSurfaceCopy: {
101
101
  readonly wide: "Wide reach";
102
102
  };
103
103
  readonly verdictLine: {
104
- readonly safeNoBlockersNarrow: "No merge blockers · narrow footprint";
105
- readonly safeNoBlockersModerate: "No merge blockers · moderate dependency footprint";
106
- readonly safeNoBlockersWide: "No merge blockers · wide upgrade footprint";
107
- readonly reviewBeforeMergeNarrow: "Review before merge · narrow footprint";
108
- readonly reviewBeforeMergeModerate: "Review before merge · moderate dependency footprint";
109
- readonly reviewBeforeMergeWide: "Review before merge · wide dependency footprint";
110
- readonly riskyResolveNarrow: "Resolve blockers before merge · focused footprint";
111
- readonly riskyResolveModerate: "Resolve blockers before merge · moderate dependency footprint";
112
- readonly riskyResolveWide: "Resolve blockers before merge · wide transitive tree";
104
+ readonly safeNoBlockersNarrow: "No merge blockers - narrow footprint";
105
+ readonly safeNoBlockersModerate: "No merge blockers - moderate dependency footprint";
106
+ readonly safeNoBlockersWide: "No merge blockers - wide upgrade footprint";
107
+ readonly reviewBeforeMergeNarrow: "Review before merge - narrow footprint";
108
+ readonly reviewBeforeMergeModerate: "Review before merge - moderate dependency footprint";
109
+ readonly reviewBeforeMergeWide: "Review before merge - wide dependency footprint";
110
+ readonly riskyResolveNarrow: "Resolve blockers before merge - focused footprint";
111
+ readonly riskyResolveModerate: "Resolve blockers before merge - moderate dependency footprint";
112
+ readonly riskyResolveWide: "Resolve blockers before merge - wide transitive tree";
113
113
  };
114
114
  readonly tier1Fallback: {
115
115
  /** Graph-only / lightweight PR baseline (pattern F3). */
@@ -123,9 +123,9 @@ export declare const scanSurfaceCopy: {
123
123
  };
124
124
  readonly confidenceCaveat: {
125
125
  readonly medium: "Based on partial dependency signal";
126
- readonly low: "Limited signal treat this as directional";
126
+ readonly low: "Limited signal - treat this as directional";
127
127
  };
128
- readonly codeAnalysisTimeout: "Code analysis timed out runtime impact may be incomplete";
128
+ readonly codeAnalysisTimeout: "Code analysis timed out - runtime impact may be incomplete";
129
129
  readonly scanPipelineNote: "This page updates automatically.";
130
130
  readonly recommendationDetail: {
131
131
  readonly selectPrompt: "Select a recommendation to understand it";
@@ -189,7 +189,7 @@ export declare const scanSurfaceCopy: {
189
189
  readonly why: "Dependency health is stable now but benefits from ongoing observation.";
190
190
  readonly whyNow: "Monitoring catches regressions that appear only after merge.";
191
191
  readonly expectedBenefit: "Earlier detection of dependency regressions in production.";
192
- readonly signals: readonly ["No immediate blockers monitor after merge"];
192
+ readonly signals: readonly ["No immediate blockers - monitor after merge"];
193
193
  };
194
194
  readonly mergeAfterVerification: {
195
195
  readonly why: "Wide upgrade footprints warrant a quick sanity check before merge.";
@@ -249,7 +249,7 @@ export declare const scanSurfaceCopy: {
249
249
  readonly signalSummary: {
250
250
  readonly scoreCaption: "Dependency signal score";
251
251
  readonly layersHeading: "Layer signals";
252
- readonly gaugeAriaLabel: "Dependency signal score {score} {band}";
252
+ readonly gaugeAriaLabel: "Dependency signal score {score} - {band}";
253
253
  readonly followUpImprovementIdentified: "1 follow-up improvement was identified";
254
254
  readonly followUpImprovementsIdentified: "{count} follow-up improvements were identified";
255
255
  readonly bandLabel: {
@@ -264,7 +264,7 @@ export declare const scanSurfaceCopy: {
264
264
  };
265
265
  };
266
266
  };
267
- /** PR narrative presentation channel-specific copy built from ScanNarrativeFacts. */
267
+ /** PR narrative presentation - channel-specific copy built from ScanNarrativeFacts. */
268
268
  readonly narrativeCard: {
269
269
  readonly structuralOnlyDisclaimer: "Structural dependency analysis only";
270
270
  readonly runtimeSurface: {
@@ -285,8 +285,8 @@ export declare const scanSurfaceCopy: {
285
285
  readonly moderate: "Moderate";
286
286
  readonly wide: "Wide";
287
287
  };
288
- readonly areasSeparator: " · ";
289
- readonly contextSeparator: " · ";
288
+ readonly areasSeparator: " | ";
289
+ readonly contextSeparator: " | ";
290
290
  };
291
291
  readonly cli: {
292
292
  readonly stderrAnalysisIncomplete: "Analysis could not be completed.";
@@ -1 +1 @@
1
- {"version":3,"file":"scanSurfaceCopy.d.ts","sourceRoot":"","sources":["../src/scanSurfaceCopy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;QAgBxB,8EAA8E;;QAG9E,6DAA6D;;;;QAO7D,qDAAqD;;;;;QASrD,mEAAmE;;;;QAOnE,yFAAyF;;QAGzF,mFAAmF;;QAGnF,0EAA0E;;QAE1E,8FAA8F;;QAE9F,+DAA+D;;;QAI/D,6EAA6E;;;;;QAK7E,2CAA2C;;;QAK3C,2EAA2E;;QAE3E,4EAA4E;;;QAI5E,sEAAsE;;;IAGxE,2EAA2E;;;;;;;;;;;;;;QAiBzE,oEAAoE;;;IAGtE,wEAAwE;;;;;;QAOtE,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkCzC,yDAAyD;;YAGzD,mDAAmD;;YAGnD,8BAA8B;;YAE9B,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CtD,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsI/C,uFAAuF;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BvF,sEAAsE;;;;;CAO9D,CAAC;AAEX,iEAAiE;AACjE,wBAAgB,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D"}
1
+ {"version":3,"file":"scanSurfaceCopy.d.ts","sourceRoot":"","sources":["../src/scanSurfaceCopy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;QAgBxB,8EAA8E;;QAG9E,6DAA6D;;;;QAO7D,qDAAqD;;;;;QASrD,mEAAmE;;;;QAOnE,yFAAyF;;QAGzF,mFAAmF;;QAGnF,4EAA4E;;QAE5E,8FAA8F;;QAE9F,+DAA+D;;;QAI/D,6EAA6E;;;;;QAK7E,2CAA2C;;;QAK3C,2EAA2E;;QAE3E,4EAA4E;;;QAI5E,sEAAsE;;;IAGxE,2EAA2E;;;;;;;;;;;;;;QAiBzE,oEAAoE;;;IAGtE,wEAAwE;;;;;;QAOtE,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkCzC,yDAAyD;;YAGzD,mDAAmD;;YAGnD,8BAA8B;;YAE9B,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CtD,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsI/C,uFAAuF;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BvF,sEAAsE;;;;;CAO9D,CAAC;AAEX,iEAAiE;AACjE,wBAAgB,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D"}