@anarchitects/governance-core 0.0.1 → 0.0.3

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 (39) hide show
  1. package/README.md +84 -54
  2. package/dist/core/adapter.d.ts +5 -2
  3. package/dist/core/adapter.d.ts.map +1 -1
  4. package/dist/core/ai-analysis.d.ts +74 -0
  5. package/dist/core/ai-analysis.d.ts.map +1 -0
  6. package/dist/core/ai-context.d.ts +125 -0
  7. package/dist/core/ai-context.d.ts.map +1 -0
  8. package/dist/core/ai-payload.d.ts +64 -0
  9. package/dist/core/ai-payload.d.ts.map +1 -0
  10. package/dist/core/ai.d.ts +1 -1
  11. package/dist/core/assessment-artifacts.d.ts +37 -0
  12. package/dist/core/assessment-artifacts.d.ts.map +1 -0
  13. package/dist/core/assessment.d.ts +2 -2
  14. package/dist/core/built-in-rule-pack.d.ts +1 -1
  15. package/dist/core/built-in-rules.d.ts +5 -2
  16. package/dist/core/built-in-rules.d.ts.map +1 -1
  17. package/dist/core/delivery-impact.d.ts +47 -0
  18. package/dist/core/delivery-impact.d.ts.map +1 -0
  19. package/dist/core/drift.d.ts +1 -1
  20. package/dist/core/exception-runtime.d.ts +46 -0
  21. package/dist/core/exception-runtime.d.ts.map +1 -0
  22. package/dist/core/exceptions.d.ts +1 -1
  23. package/dist/core/health.d.ts +11 -0
  24. package/dist/core/health.d.ts.map +1 -0
  25. package/dist/core/index.d.ts +9 -0
  26. package/dist/core/index.d.ts.map +1 -1
  27. package/dist/core/metrics.d.ts +9 -0
  28. package/dist/core/metrics.d.ts.map +1 -0
  29. package/dist/core/models.d.ts +1 -1
  30. package/dist/core/rule-engine.d.ts +1 -1
  31. package/dist/core/rules.d.ts +4 -4
  32. package/dist/core/signal-builders.d.ts +42 -0
  33. package/dist/core/signal-builders.d.ts.map +1 -0
  34. package/dist/core/snapshots.d.ts +1 -1
  35. package/dist/extensions/capabilities.d.ts +1 -1
  36. package/dist/extensions/contracts.d.ts +3 -3
  37. package/dist/extensions/runtime.d.ts +4 -4
  38. package/dist/index.js +3349 -1112
  39. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,111 +1,1394 @@
1
- function mn(e, n = { projectOverrides: {} }) {
2
- const t = ae(e), o = se(e);
1
+ import { createHash as St } from "node:crypto";
2
+ function X(e, t = { projectOverrides: {} }) {
3
+ const n = Pt(e), o = jt(e);
3
4
  return {
4
5
  id: e.workspaceId ?? e.workspace?.id ?? "workspace",
5
6
  name: e.workspaceName ?? e.workspace?.name ?? "workspace",
6
7
  root: e.workspaceRoot ?? e.workspace?.root ?? "",
7
- projects: t.map((r) => {
8
- const i = ce(r), a = r.tags ?? [], c = r.metadata ?? {}, s = n.projectOverrides[i] ?? {}, l = s.domain ?? r.domain ?? R(a, "domain") ?? R(a, "scope"), u = s.layer ?? r.layer ?? R(a, "layer"), y = de(c);
8
+ projects: n.map((r) => {
9
+ const i = bt(r), s = r.tags ?? [], a = r.metadata ?? {}, d = t.projectOverrides[i] ?? {}, c = d.domain ?? r.domain ?? oe(s, "domain") ?? oe(s, "scope"), l = d.layer ?? r.layer ?? oe(s, "layer"), u = Dt(a);
9
10
  return {
10
11
  id: r.id,
11
12
  name: i,
12
13
  root: r.root ?? "",
13
- type: le(r.type),
14
- tags: a,
15
- domain: l,
16
- layer: u,
17
- ownership: pe(
18
- y,
19
- s.ownershipTeam,
14
+ type: Ct(r.type),
15
+ tags: s,
16
+ domain: c,
17
+ layer: l,
18
+ ownership: kt(
19
+ u,
20
+ d.ownershipTeam,
20
21
  r.ownership
21
22
  ),
22
23
  metadata: {
23
- ...c,
24
- ...s.documentation !== void 0 ? { documentation: s.documentation } : {}
24
+ ...a,
25
+ ...d.documentation !== void 0 ? { documentation: d.documentation } : {}
25
26
  }
26
27
  };
27
28
  }),
28
29
  dependencies: o.map((r) => ({
29
30
  source: r.sourceProjectId,
30
31
  target: r.targetProjectId,
31
- type: ue(r.type),
32
+ type: xt(r.type),
32
33
  sourceFile: r.sourceFile
33
34
  }))
34
35
  };
35
36
  }
36
- function ae(e) {
37
- return e.projects ? e.projects : e.workspace ? e.workspace.projects.map((n) => ({
38
- id: n.id,
39
- name: n.name,
40
- root: n.root,
41
- type: n.type,
42
- domain: n.domain,
43
- layer: n.layer,
44
- tags: n.tags,
45
- ownership: n.ownership,
46
- metadata: n.metadata
37
+ const Xo = X, Zo = X, Qo = X;
38
+ function Pt(e) {
39
+ return e.projects ? e.projects : e.workspace ? e.workspace.projects.map((t) => ({
40
+ id: t.id,
41
+ name: t.name,
42
+ root: t.root,
43
+ type: t.type,
44
+ domain: t.domain,
45
+ layer: t.layer,
46
+ tags: t.tags,
47
+ ownership: t.ownership,
48
+ metadata: t.metadata
47
49
  })) : [];
48
50
  }
49
- function se(e) {
50
- return e.dependencies ? e.dependencies : e.workspace ? e.workspace.dependencies.map((n) => ({
51
- sourceProjectId: n.source,
52
- targetProjectId: n.target,
53
- type: n.type,
54
- sourceFile: n.sourceFile
51
+ function jt(e) {
52
+ return e.dependencies ? e.dependencies : e.workspace ? e.workspace.dependencies.map((t) => ({
53
+ sourceProjectId: t.source,
54
+ targetProjectId: t.target,
55
+ type: t.type,
56
+ sourceFile: t.sourceFile
55
57
  })) : [];
56
58
  }
57
- function ce(e) {
58
- return e.name ?? e.id;
59
+ function bt(e) {
60
+ return e.name ?? e.id;
61
+ }
62
+ function oe(e, t) {
63
+ return e.find((o) => o.startsWith(`${t}:`))?.split(":").slice(1).join(":");
64
+ }
65
+ function Ct(e) {
66
+ return e === "application" || e === "app" ? "application" : e === "library" || e === "lib" ? "library" : e === "tool" ? "tool" : "unknown";
67
+ }
68
+ function xt(e) {
69
+ return e === "static" || e === "dynamic" || e === "implicit" ? e : "unknown";
70
+ }
71
+ function Dt(e) {
72
+ const t = e.ownership;
73
+ if (typeof t == "string" && t)
74
+ return t;
75
+ if (t && typeof t == "object") {
76
+ const n = t.team;
77
+ if (typeof n == "string" && n)
78
+ return n;
79
+ }
80
+ }
81
+ function kt(e, t, n) {
82
+ const o = n?.contacts ?? [], r = t ?? e ?? n?.team;
83
+ return r && o.length ? {
84
+ team: r,
85
+ contacts: o,
86
+ source: "merged"
87
+ } : r ? {
88
+ team: r,
89
+ contacts: [],
90
+ source: $t(n?.source)
91
+ } : o.length ? {
92
+ contacts: o,
93
+ source: "codeowners"
94
+ } : {
95
+ source: "none"
96
+ };
97
+ }
98
+ function $t(e) {
99
+ return e === "merged" || e === "project-metadata" ? e : e === "codeowners" ? "codeowners" : "project-metadata";
100
+ }
101
+ function er(e) {
102
+ return {
103
+ kind: "root-cause",
104
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
105
+ profile: e.profile,
106
+ inputs: {
107
+ snapshot: e.snapshot,
108
+ dependencies: e.dependencies,
109
+ topViolations: e.topViolations,
110
+ metadata: e.metadata
111
+ }
112
+ };
113
+ }
114
+ function tr(e) {
115
+ return {
116
+ kind: "pr-impact",
117
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
118
+ profile: e.profile,
119
+ inputs: {
120
+ affectedProjects: e.affectedProjects,
121
+ dependencies: e.dependencies,
122
+ metadata: e.metadata
123
+ }
124
+ };
125
+ }
126
+ function nr(e) {
127
+ return {
128
+ kind: "scorecard",
129
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
130
+ profile: e.profile,
131
+ inputs: {
132
+ snapshot: e.snapshot,
133
+ comparison: e.comparison,
134
+ metadata: e.metadata
135
+ }
136
+ };
137
+ }
138
+ function or(e) {
139
+ return {
140
+ kind: "onboarding",
141
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
142
+ profile: e.profile,
143
+ inputs: {
144
+ dependencies: e.dependencies,
145
+ topViolations: e.topViolations,
146
+ metadata: e.metadata
147
+ }
148
+ };
149
+ }
150
+ function rr(e) {
151
+ return {
152
+ kind: "cognitive-load",
153
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
154
+ profile: e.profile,
155
+ inputs: {
156
+ affectedProjects: e.affectedProjects,
157
+ dependencies: e.dependencies,
158
+ metadata: e.metadata
159
+ }
160
+ };
161
+ }
162
+ function ir(e) {
163
+ return {
164
+ kind: "recommendations",
165
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
166
+ profile: e.profile,
167
+ inputs: {
168
+ dependencies: e.dependencies,
169
+ topViolations: e.topViolations,
170
+ comparison: e.comparison,
171
+ metadata: e.metadata
172
+ }
173
+ };
174
+ }
175
+ function sr(e) {
176
+ return {
177
+ kind: "smell-clusters",
178
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
179
+ profile: e.profile,
180
+ inputs: {
181
+ dependencies: e.dependencies,
182
+ topViolations: e.topViolations,
183
+ comparison: e.comparison,
184
+ metadata: e.metadata
185
+ }
186
+ };
187
+ }
188
+ function ar(e) {
189
+ return {
190
+ kind: "refactoring-suggestions",
191
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
192
+ profile: e.profile,
193
+ inputs: {
194
+ dependencies: e.dependencies,
195
+ topViolations: e.topViolations,
196
+ comparison: e.comparison,
197
+ metadata: e.metadata
198
+ }
199
+ };
200
+ }
201
+ function cr(e) {
202
+ return {
203
+ kind: "management-insights",
204
+ generatedAt: e.generatedAt ?? e.deliveryImpact.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
205
+ profile: e.profile ?? e.deliveryImpact.profile,
206
+ inputs: {
207
+ metadata: {
208
+ deliveryImpact: e.deliveryImpact,
209
+ assessmentSummary: e.assessment ? {
210
+ health: e.assessment.health,
211
+ violationCount: e.assessment.violations.length,
212
+ topIssues: e.assessment.topIssues.slice(0, 5)
213
+ } : void 0,
214
+ comparisonSummary: e.comparison ? {
215
+ healthDelta: e.comparison.healthDelta,
216
+ deliveryImpactIndexDeltas: e.comparison.deliveryImpactIndexDeltas
217
+ } : void 0,
218
+ ...e.metadata ?? {}
219
+ }
220
+ }
221
+ };
222
+ }
223
+ function Mt(e, t = 10) {
224
+ const n = {
225
+ error: 3,
226
+ warning: 2,
227
+ info: 1
228
+ };
229
+ return [...e].sort((o, r) => {
230
+ const i = (n[r.severity ?? "info"] ?? 0) - (n[o.severity ?? "info"] ?? 0);
231
+ return i !== 0 ? i : we(o).localeCompare(we(r));
232
+ }).slice(0, Math.max(0, t));
233
+ }
234
+ function dr(e) {
235
+ const t = e.inputs.topViolations ?? [], n = ve(t, (s) => s.source), o = ve(t, (s) => s.type), r = Object.entries(n).sort((s, a) => a[1] - s[1] || s[0].localeCompare(a[0])).slice(0, 3), i = r.map(([s, a], d) => ({
236
+ id: `hotspot-${d + 1}`,
237
+ title: `Hotspot: ${s}`,
238
+ detail: `${s} appears in ${a} of ${t.length} prioritized violations.`,
239
+ signals: ["top-violations", "frequency"],
240
+ confidence: t.length > 0 ? a / t.length : 0
241
+ }));
242
+ return i.length === 0 && i.push({
243
+ id: "no-prioritized-violations",
244
+ title: "No prioritized violations",
245
+ detail: "No prioritized violations were available for root-cause interpretation in the selected snapshot.",
246
+ signals: ["top-violations"],
247
+ confidence: 1
248
+ }), {
249
+ kind: "root-cause",
250
+ summary: t.length === 0 ? "No prioritized governance violations found for root-cause analysis." : `Analyzed ${t.length} prioritized violations across ${r.length} hotspot projects.`,
251
+ findings: i,
252
+ recommendations: Et(o),
253
+ metadata: {
254
+ violationTypes: o,
255
+ analyzedViolationCount: t.length
256
+ }
257
+ };
258
+ }
259
+ function lr(e) {
260
+ const t = e.inputs.metadata ?? {}, n = B(t, "changedFilesCount"), o = e.inputs.affectedProjects?.length ?? B(t, "affectedProjectsCount"), r = B(
261
+ t,
262
+ "affectedDomainCount"
263
+ ), i = B(
264
+ t,
265
+ "crossDomainDependencyEdges"
266
+ ), s = [
267
+ n * 5,
268
+ o * 15,
269
+ r * 20,
270
+ i * 10
271
+ ].reduce((c, l) => c + l, 0), a = Math.max(0, Math.min(100, s)), d = a >= 70 ? "high" : a >= 40 ? "medium" : "low";
272
+ return {
273
+ kind: "pr-impact",
274
+ summary: `PR impact is ${d} risk at ${a}/100 across ${o} affected project(s).`,
275
+ findings: [
276
+ {
277
+ id: "affected-projects",
278
+ title: "Affected project spread",
279
+ detail: `${o} project(s), ${r} domain(s), and ${i} cross-domain dependency edge(s) are implicated.`,
280
+ signals: ["affected-projects", "cross-domain-impact"],
281
+ confidence: 1
282
+ }
283
+ ],
284
+ recommendations: Ne(d),
285
+ metadata: {
286
+ changedFilesCount: n,
287
+ affectedProjectsCount: o,
288
+ affectedDomainCount: r,
289
+ crossDomainDependencyEdges: i,
290
+ risk: a
291
+ }
292
+ };
293
+ }
294
+ function ur(e) {
295
+ const t = e.inputs.snapshot, n = e.inputs.comparison, o = t?.health?.score ?? 0;
296
+ return {
297
+ kind: "scorecard",
298
+ summary: n?.healthDelta ? `Current health is ${o}/100 with a ${n.healthDelta.scoreDelta} point delta from the baseline.` : `Current health is ${o}/100.`,
299
+ findings: [
300
+ {
301
+ id: "workspace-health",
302
+ title: "Workspace health score",
303
+ detail: t?.health ? `${t.health.score}/100 (${t.health.status}, grade ${t.health.grade}).` : "No health score was available in the snapshot.",
304
+ signals: ["workspace-health"],
305
+ confidence: 1
306
+ }
307
+ ],
308
+ recommendations: n?.healthDelta && n.healthDelta.scoreDelta < 0 ? [
309
+ {
310
+ id: "recover-health-score",
311
+ title: "Recover degraded health score",
312
+ priority: "high",
313
+ reason: "The current snapshot is worse than the baseline and should be investigated before the next release."
314
+ }
315
+ ] : [],
316
+ metadata: {
317
+ scoreDelta: n?.healthDelta?.scoreDelta
318
+ }
319
+ };
320
+ }
321
+ function pr(e) {
322
+ const t = e.inputs.dependencies?.length ?? 0, n = e.inputs.topViolations?.length ?? 0;
323
+ return {
324
+ kind: "onboarding",
325
+ summary: t === 0 ? "No dependency graph details were available for onboarding analysis." : `Prepared onboarding analysis from ${t} dependency edge(s) and ${n} prioritized violation(s).`,
326
+ findings: [
327
+ {
328
+ id: "dependency-surface",
329
+ title: "Dependency surface",
330
+ detail: `${t} dependency edge(s) were included for the onboarding brief.`,
331
+ signals: ["dependency-surface"],
332
+ confidence: 1
333
+ }
334
+ ],
335
+ recommendations: n > 0 ? [
336
+ {
337
+ id: "review-prioritized-hotspots",
338
+ title: "Review prioritized hotspots first",
339
+ priority: "medium",
340
+ reason: "New contributors should start with the highest-severity governance hotspots to understand architectural risk quickly."
341
+ }
342
+ ] : [],
343
+ metadata: {
344
+ dependencyCount: t,
345
+ topViolationCount: n
346
+ }
347
+ };
348
+ }
349
+ function mr(e) {
350
+ const t = Ie(e.inputs.metadata), n = Ie(t?.deliveryImpact);
351
+ if (!n || n.indices.length === 0)
352
+ return {
353
+ kind: "management-insights",
354
+ summary: "No delivery-impact indices were available for management-insights AI handoff.",
355
+ findings: [
356
+ {
357
+ id: "no-delivery-impact-indices",
358
+ title: "No delivery-impact indices",
359
+ detail: "The payload did not include Cost of Change, Time-to-Market Risk, or other delivery-impact indices to interpret.",
360
+ signals: ["delivery-impact"],
361
+ confidence: 1
362
+ }
363
+ ],
364
+ recommendations: [],
365
+ metadata: {
366
+ indexCount: 0
367
+ }
368
+ };
369
+ const o = [...n.indices].sort(
370
+ (i, s) => s.score - i.score || i.id.localeCompare(s.id)
371
+ )[0], r = n.drivers[0];
372
+ return {
373
+ kind: "management-insights",
374
+ summary: `Prepared AI handoff input for ${n.indices.length} delivery-impact indices. Highest current pressure: ${o.name} (${o.risk}, score ${o.score}).`,
375
+ findings: [
376
+ {
377
+ id: `index-${o.id}`,
378
+ title: `${o.name} is the highest current delivery pressure`,
379
+ detail: `${o.name} is ${o.score}/100 with ${o.risk} risk.`,
380
+ signals: o.drivers.map((i) => i.id),
381
+ confidence: 1
382
+ },
383
+ ...r ? [
384
+ {
385
+ id: `driver-${r.id}`,
386
+ title: `Primary investment driver: ${r.label}`,
387
+ detail: r.explanation ?? `${r.label} is the strongest current delivery-impact driver.`,
388
+ signals: [r.id],
389
+ confidence: r.score ? r.score / 100 : 0.6
390
+ }
391
+ ] : []
392
+ ],
393
+ recommendations: [
394
+ {
395
+ id: "trace-delivery-pressure",
396
+ title: "Trace delivery pressure to concrete architecture work",
397
+ priority: o.risk === "high" ? "high" : "medium",
398
+ reason: "Management-facing delivery-impact signals are strongest when they stay tied to the concrete governance evidence already present in the payload."
399
+ }
400
+ ],
401
+ metadata: {
402
+ indexCount: n.indices.length,
403
+ driverCount: n.drivers.length
404
+ }
405
+ };
406
+ }
407
+ function fr(e) {
408
+ return pe(
409
+ e,
410
+ "recommendations",
411
+ "Architecture recommendations",
412
+ "Generate architecture work items from the strongest governance hotspots."
413
+ );
414
+ }
415
+ function gr(e) {
416
+ const t = e.inputs.affectedProjects ?? [], n = e.inputs.dependencies ?? [], o = Math.max(
417
+ 0,
418
+ Math.min(100, t.length * 15 + n.length * 2)
419
+ ), r = o >= 70 ? "high" : o >= 40 ? "medium" : "low";
420
+ return {
421
+ kind: "cognitive-load",
422
+ summary: `Estimated cognitive load is ${r} risk at ${o}/100.`,
423
+ findings: [
424
+ {
425
+ id: "cognitive-load-surface",
426
+ title: "Cognitive load surface",
427
+ detail: `${t.length} affected project(s) and ${n.length} dependency edge(s) contribute to the current change context.`,
428
+ signals: ["affected-projects", "dependency-count"],
429
+ confidence: 0.8
430
+ }
431
+ ],
432
+ recommendations: Ne(r),
433
+ metadata: {
434
+ score: o,
435
+ affectedProjectsCount: t.length,
436
+ dependencyCount: n.length
437
+ }
438
+ };
439
+ }
440
+ function yr(e) {
441
+ return pe(
442
+ e,
443
+ "smell-clusters",
444
+ "Smell clusters",
445
+ "Group recurring hotspots before choosing remediation sequencing."
446
+ );
447
+ }
448
+ function hr(e) {
449
+ return pe(
450
+ e,
451
+ "refactoring-suggestions",
452
+ "Refactoring suggestions",
453
+ "Start with the most repeated hotspot patterns before broad cleanup."
454
+ );
455
+ }
456
+ function pe(e, t, n, o) {
457
+ const r = e.inputs.topViolations ?? [], i = Mt(r, 5);
458
+ return {
459
+ kind: t,
460
+ summary: i.length === 0 ? `No prioritized violations were available for ${n.toLowerCase()}.` : `Prepared ${n.toLowerCase()} from ${i.length} prioritized violation(s).`,
461
+ findings: i.map((s, a) => ({
462
+ id: `violation-${a + 1}`,
463
+ title: s.ruleId ?? s.type,
464
+ detail: s.message ?? `${s.type} at ${s.source}.`,
465
+ signals: [s.type, s.ruleId ?? "violation"],
466
+ confidence: 1
467
+ })),
468
+ recommendations: i.length > 0 ? [
469
+ {
470
+ id: `${t}-focus`,
471
+ title: n,
472
+ priority: "medium",
473
+ reason: o
474
+ }
475
+ ] : []
476
+ };
477
+ }
478
+ function Et(e) {
479
+ return Object.entries(e).sort((t, n) => n[1] - t[1] || t[0].localeCompare(n[0])).slice(0, 3).map(([t]) => ({
480
+ id: `address-${t}`,
481
+ title: `Address ${t}`,
482
+ priority: "medium",
483
+ reason: `${t} is recurring in the prioritized violation set.`
484
+ }));
485
+ }
486
+ function Ne(e) {
487
+ return e === "low" ? [] : [
488
+ {
489
+ id: "reduce-change-risk",
490
+ title: "Reduce change risk",
491
+ priority: e === "high" ? "high" : "medium",
492
+ reason: "The current change surface spans enough projects and coupling to justify targeted architectural risk reduction before further expansion."
493
+ }
494
+ ];
495
+ }
496
+ function ve(e, t) {
497
+ return e.reduce((n, o) => {
498
+ const r = t(o);
499
+ return n[r] = (n[r] ?? 0) + 1, n;
500
+ }, {});
501
+ }
502
+ function B(e, t) {
503
+ const n = e[t];
504
+ return typeof n == "number" && Number.isFinite(n) ? n : 0;
505
+ }
506
+ function we(e) {
507
+ return [
508
+ e.ruleId ?? "",
509
+ e.type,
510
+ e.source,
511
+ e.target ?? "",
512
+ e.message ?? ""
513
+ ].join("|");
514
+ }
515
+ function Ie(e) {
516
+ return typeof e == "object" && e !== null && !Array.isArray(e) ? e : void 0;
517
+ }
518
+ const Rt = [
519
+ "graph",
520
+ "conformance",
521
+ "policy"
522
+ ], Ot = ["info", "warning", "error"], Vt = [
523
+ "structural-dependency",
524
+ "cross-domain-dependency",
525
+ "missing-domain-context",
526
+ "circular-dependency",
527
+ "conformance-violation",
528
+ "domain-boundary-violation",
529
+ "layer-boundary-violation",
530
+ "ownership-gap"
531
+ ], At = [
532
+ "architecture",
533
+ "boundaries",
534
+ "ownership",
535
+ "documentation"
536
+ ];
537
+ function vr(e, t) {
538
+ return {
539
+ baseline: e,
540
+ current: t,
541
+ metricDeltas: Se(e.metrics, t.metrics),
542
+ scoreDeltas: Se(e.scores, t.scores),
543
+ newViolations: t.violations.filter(
544
+ (n) => !xe(e.violations, n)
545
+ ),
546
+ resolvedViolations: e.violations.filter(
547
+ (n) => !xe(t.violations, n)
548
+ ),
549
+ healthDelta: zt(e, t),
550
+ signalDeltas: Tt(e, t),
551
+ metricFamilyDeltas: Lt(e, t),
552
+ topIssueDeltas: Bt(e, t),
553
+ deliveryImpactIndexDeltas: Gt(e, t)
554
+ };
555
+ }
556
+ function wr(e, t = 0.02) {
557
+ const n = [], o = e.scoreDeltas.find(
558
+ (r) => r.id === "workspaceHealth"
559
+ );
560
+ o && n.push(
561
+ re(
562
+ "workspaceHealth",
563
+ "workspace-health",
564
+ "Workspace Health",
565
+ o,
566
+ t,
567
+ e.healthDelta ? {
568
+ baselineStatus: e.healthDelta.baselineStatus,
569
+ currentStatus: e.healthDelta.currentStatus,
570
+ baselineGrade: e.healthDelta.baselineGrade,
571
+ currentGrade: e.healthDelta.currentGrade
572
+ } : void 0
573
+ )
574
+ );
575
+ for (const r of e.scoreDeltas)
576
+ r.id !== "workspaceHealth" && n.push(
577
+ re(
578
+ r.id,
579
+ "metric-score",
580
+ Ut(r.id),
581
+ r,
582
+ t
583
+ )
584
+ );
585
+ for (const r of e.metricFamilyDeltas ?? [])
586
+ n.push(
587
+ re(
588
+ `metric-family:${r.family}`,
589
+ "metric-family",
590
+ `Metric Family: ${Kt(r.family)}`,
591
+ r,
592
+ t
593
+ )
594
+ );
595
+ for (const r of e.signalDeltas?.bySource ?? [])
596
+ n.push(
597
+ G(
598
+ `signal-source:${r.source}`,
599
+ "signal-source",
600
+ `Signal Source: ${r.source}`,
601
+ r
602
+ )
603
+ );
604
+ for (const r of e.signalDeltas?.byType ?? [])
605
+ n.push(
606
+ G(
607
+ `signal-type:${r.type}`,
608
+ "signal-type",
609
+ `Signal Type: ${Yt(r.type)}`,
610
+ r
611
+ )
612
+ );
613
+ for (const r of e.signalDeltas?.bySeverity ?? [])
614
+ n.push(
615
+ G(
616
+ `signal-severity:${r.severity}`,
617
+ "signal-severity",
618
+ `Signal Severity: ${r.severity}`,
619
+ r
620
+ )
621
+ );
622
+ for (const r of e.topIssueDeltas ?? [])
623
+ n.push(
624
+ G(
625
+ _t(r),
626
+ "top-issue",
627
+ `Top Issue: ${r.message}`,
628
+ {
629
+ baseline: r.baselineCount,
630
+ current: r.currentCount,
631
+ delta: r.delta
632
+ },
633
+ {
634
+ type: r.type,
635
+ source: r.source,
636
+ severity: r.severity,
637
+ ruleId: r.ruleId,
638
+ projects: r.projects
639
+ }
640
+ )
641
+ );
642
+ return n.push({
643
+ id: "violation-footprint",
644
+ kind: "violation-footprint",
645
+ label: "Violation Footprint",
646
+ status: qe(
647
+ e.newViolations.length - e.resolvedViolations.length
648
+ ),
649
+ magnitude: Math.abs(
650
+ e.newViolations.length - e.resolvedViolations.length
651
+ ),
652
+ baseline: e.baseline.violations.length,
653
+ current: e.current.violations.length,
654
+ delta: I(
655
+ e.current.violations.length - e.baseline.violations.length
656
+ ),
657
+ details: {
658
+ newViolations: e.newViolations.length,
659
+ resolvedViolations: e.resolvedViolations.length
660
+ }
661
+ }), n.sort(Wt);
662
+ }
663
+ function Ft(e) {
664
+ const t = e.filter((r) => r.status === "worsening").sort(Ce), n = e.filter((r) => r.status === "improving").sort(Ce), o = e.filter(
665
+ (r) => r.status === "stable"
666
+ ).length;
667
+ return {
668
+ overallTrend: t.length > n.length ? "worsening" : n.length > t.length ? "improving" : "stable",
669
+ worseningCount: t.length,
670
+ improvingCount: n.length,
671
+ stableCount: o,
672
+ topWorsening: t.slice(0, 5),
673
+ topImproving: n.slice(0, 5)
674
+ };
675
+ }
676
+ function Se(e, t) {
677
+ return [.../* @__PURE__ */ new Set([...Object.keys(e), ...Object.keys(t)])].sort((o, r) => o.localeCompare(r)).map((o) => {
678
+ const r = e[o] ?? 0, i = t[o] ?? 0;
679
+ return {
680
+ id: o,
681
+ baseline: r,
682
+ current: i,
683
+ delta: I(i - r)
684
+ };
685
+ });
686
+ }
687
+ function zt(e, t) {
688
+ if (!(!e.health || !t.health))
689
+ return {
690
+ baselineScore: e.health.score,
691
+ currentScore: t.health.score,
692
+ scoreDelta: I(t.health.score - e.health.score),
693
+ baselineStatus: e.health.status,
694
+ currentStatus: t.health.status,
695
+ baselineGrade: e.health.grade,
696
+ currentGrade: t.health.grade
697
+ };
698
+ }
699
+ function Tt(e, t) {
700
+ if (!(!e.signalBreakdown || !t.signalBreakdown))
701
+ return {
702
+ bySource: Rt.map(
703
+ (n) => Nt(
704
+ n,
705
+ Pe(e, n),
706
+ Pe(t, n)
707
+ )
708
+ ),
709
+ byType: Vt.flatMap((n) => {
710
+ const o = je(e, n), r = je(t, n);
711
+ return o === 0 && r === 0 ? [] : [
712
+ {
713
+ type: n,
714
+ baseline: o,
715
+ current: r,
716
+ delta: I(r - o)
717
+ }
718
+ ];
719
+ }),
720
+ bySeverity: Ot.map(
721
+ (n) => qt(
722
+ n,
723
+ be(e, n),
724
+ be(t, n)
725
+ )
726
+ )
727
+ };
728
+ }
729
+ function Lt(e, t) {
730
+ if (!e.metricBreakdown || !t.metricBreakdown)
731
+ return;
732
+ const n = new Map(
733
+ e.metricBreakdown.families.map((r) => [
734
+ r.family,
735
+ r.score
736
+ ])
737
+ ), o = new Map(
738
+ t.metricBreakdown.families.map((r) => [
739
+ r.family,
740
+ r.score
741
+ ])
742
+ );
743
+ return At.flatMap((r) => {
744
+ const i = n.get(r), s = o.get(r);
745
+ return i === void 0 || s === void 0 ? [] : [
746
+ {
747
+ family: r,
748
+ baseline: i,
749
+ current: s,
750
+ delta: I(s - i)
751
+ }
752
+ ];
753
+ });
754
+ }
755
+ function Bt(e, t) {
756
+ if (!e.topIssues || !t.topIssues)
757
+ return;
758
+ const n = new Map(
759
+ e.topIssues.map((i) => [de(i), i])
760
+ ), o = new Map(
761
+ t.topIssues.map((i) => [de(i), i])
762
+ );
763
+ return [.../* @__PURE__ */ new Set([...n.keys(), ...o.keys()])].sort((i, s) => i.localeCompare(s)).map((i) => {
764
+ const s = n.get(i), a = o.get(i), d = a ?? s;
765
+ if (!d)
766
+ throw new Error(`Unable to resolve top issue delta for key "${i}".`);
767
+ const c = [
768
+ .../* @__PURE__ */ new Set([...s?.projects ?? [], ...a?.projects ?? []])
769
+ ].sort((l, u) => l.localeCompare(u));
770
+ return {
771
+ type: d.type,
772
+ source: d.source,
773
+ severity: d.severity,
774
+ ruleId: d.ruleId,
775
+ message: d.message,
776
+ baselineCount: s?.count ?? 0,
777
+ currentCount: a?.count ?? 0,
778
+ delta: I((a?.count ?? 0) - (s?.count ?? 0)),
779
+ projects: c
780
+ };
781
+ });
782
+ }
783
+ function Gt(e, t) {
784
+ const n = new Map(
785
+ (e.deliveryImpact?.indices ?? []).map((i) => [i.id, i])
786
+ ), o = new Map(
787
+ (t.deliveryImpact?.indices ?? []).map((i) => [i.id, i])
788
+ ), r = [...n.keys()].filter((i) => o.has(i)).sort((i, s) => i.localeCompare(s));
789
+ if (r.length !== 0)
790
+ return r.map((i) => {
791
+ const s = n.get(i), a = o.get(i);
792
+ return {
793
+ id: i,
794
+ baselineScore: s.score,
795
+ currentScore: a.score,
796
+ scoreDelta: I(a.score - s.score),
797
+ baselineRisk: s.risk,
798
+ currentRisk: a.risk
799
+ };
800
+ });
801
+ }
802
+ function re(e, t, n, o, r, i) {
803
+ return {
804
+ id: e,
805
+ kind: t,
806
+ label: n,
807
+ status: Ht(o.delta, r),
808
+ magnitude: Math.abs(o.delta),
809
+ baseline: o.baseline,
810
+ current: o.current,
811
+ delta: o.delta,
812
+ details: i
813
+ };
814
+ }
815
+ function G(e, t, n, o, r) {
816
+ return {
817
+ id: e,
818
+ kind: t,
819
+ label: n,
820
+ status: qe(o.delta),
821
+ magnitude: Math.abs(o.delta),
822
+ baseline: o.baseline,
823
+ current: o.current,
824
+ delta: o.delta,
825
+ details: r
826
+ };
827
+ }
828
+ function Nt(e, t, n) {
829
+ return {
830
+ source: e,
831
+ baseline: t,
832
+ current: n,
833
+ delta: I(n - t)
834
+ };
835
+ }
836
+ function qt(e, t, n) {
837
+ return {
838
+ severity: e,
839
+ baseline: t,
840
+ current: n,
841
+ delta: I(n - t)
842
+ };
843
+ }
844
+ function Pe(e, t) {
845
+ return e.signalBreakdown?.bySource.find((n) => n.source === t)?.count ?? 0;
846
+ }
847
+ function je(e, t) {
848
+ return e.signalBreakdown?.byType.find((n) => n.type === t)?.count ?? 0;
849
+ }
850
+ function be(e, t) {
851
+ return e.signalBreakdown?.bySeverity.find(
852
+ (n) => n.severity === t
853
+ )?.count ?? 0;
854
+ }
855
+ function de(e) {
856
+ return [
857
+ e.type,
858
+ e.source,
859
+ e.severity,
860
+ e.ruleId ?? "",
861
+ e.message
862
+ ].join("|");
863
+ }
864
+ function _t(e) {
865
+ return `top-issue:${de(e)}`;
866
+ }
867
+ function Wt(e, t) {
868
+ return e.id.localeCompare(t.id);
869
+ }
870
+ function Ce(e, t) {
871
+ return t.magnitude - e.magnitude || e.id.localeCompare(t.id);
872
+ }
873
+ function Ht(e, t) {
874
+ return Math.abs(e) < t ? "stable" : e > 0 ? "improving" : "worsening";
875
+ }
876
+ function qe(e) {
877
+ return e === 0 ? "stable" : e < 0 ? "improving" : "worsening";
878
+ }
879
+ function Ut(e) {
880
+ return e.split("-").map((t) => t[0]?.toUpperCase() + t.slice(1)).join(" ");
881
+ }
882
+ function Kt(e) {
883
+ return e[0].toUpperCase() + e.slice(1);
884
+ }
885
+ function Yt(e) {
886
+ return e.split("-").map((t) => t[0]?.toUpperCase() + t.slice(1)).join(" ");
887
+ }
888
+ function I(e) {
889
+ return Math.round(e * 1e3) / 1e3;
890
+ }
891
+ function xe(e, t) {
892
+ return e.some(
893
+ (n) => n.type === t.type && n.source === t.source && n.target === t.target
894
+ );
895
+ }
896
+ function _e(e, t, n) {
897
+ return {
898
+ totalCount: e,
899
+ selectedCount: t,
900
+ limit: n,
901
+ truncated: t < e
902
+ };
903
+ }
904
+ function h(e, t, n) {
905
+ const o = We(t, e.length), r = [...e].sort(n), i = r.slice(0, o);
906
+ return {
907
+ items: i,
908
+ truncation: _e(
909
+ r.length,
910
+ i.length,
911
+ o
912
+ )
913
+ };
914
+ }
915
+ function Jt(e, t, n) {
916
+ const o = new Set(t), r = e.filter(
917
+ (i) => o.has(i.source) || o.has(i.target)
918
+ );
919
+ return h(
920
+ r,
921
+ n,
922
+ Xt
923
+ );
924
+ }
925
+ function _(e, t) {
926
+ return De(t.severity) - De(e.severity) || (e.source ?? "").localeCompare(t.source ?? "") || (e.type ?? "").localeCompare(t.type ?? "") || (e.target ?? "").localeCompare(t.target ?? "");
927
+ }
928
+ function Ir(e) {
929
+ me(e.request, "root-cause");
930
+ const t = e.dependencies ?? e.request.inputs.dependencies ?? [], n = e.topViolations ?? e.request.inputs.topViolations ?? [], o = e.projectScope ? new Set(e.projectScope) : Qt(n), r = Jt(
931
+ t,
932
+ o,
933
+ e.dependencyLimit
934
+ ), i = e.request.inputs.snapshot?.violations.length ?? n.length, s = We(
935
+ e.topViolationsLimit,
936
+ n.length
937
+ ), a = {
938
+ projectScopeCount: o.size,
939
+ dependencies: r.truncation,
940
+ violations: _e(
941
+ i,
942
+ n.length,
943
+ s
944
+ )
945
+ };
946
+ return {
947
+ request: {
948
+ ...e.request,
949
+ inputs: {
950
+ ...e.request.inputs,
951
+ topViolations: n,
952
+ dependencies: r.items,
953
+ metadata: He(
954
+ e.request.inputs.metadata,
955
+ a
956
+ )
957
+ }
958
+ },
959
+ payloadScope: a
960
+ };
961
+ }
962
+ function Sr(e) {
963
+ me(e.request, "drift");
964
+ const t = e.comparison ?? e.request.inputs.comparison, n = e.signals ?? [], o = e.summary, r = h(
965
+ n,
966
+ e.signalLimit,
967
+ Zt
968
+ ), i = h(
969
+ t?.metricDeltas ?? [],
970
+ e.deltaLimit,
971
+ W
972
+ ), s = h(
973
+ t?.scoreDeltas ?? [],
974
+ e.deltaLimit,
975
+ W
976
+ ), a = h(
977
+ t?.newViolations ?? [],
978
+ e.violationLimit,
979
+ _
980
+ ), d = h(
981
+ t?.resolvedViolations ?? [],
982
+ e.violationLimit,
983
+ _
984
+ ), c = {
985
+ signals: r.truncation,
986
+ metricDeltas: i.truncation,
987
+ scoreDeltas: s.truncation,
988
+ newViolations: a.truncation,
989
+ resolvedViolations: d.truncation
990
+ };
991
+ return {
992
+ request: {
993
+ ...e.request,
994
+ inputs: {
995
+ ...e.request.inputs,
996
+ comparison: t ? {
997
+ ...t,
998
+ baseline: H(t.baseline),
999
+ current: H(t.current),
1000
+ metricDeltas: i.items,
1001
+ scoreDeltas: s.items,
1002
+ newViolations: a.items,
1003
+ resolvedViolations: d.items
1004
+ } : void 0,
1005
+ metadata: {
1006
+ ...e.request.inputs.metadata ?? {},
1007
+ signals: r.items,
1008
+ ...o ? { driftSummary: o } : {},
1009
+ payloadScope: Ke(
1010
+ Ue(e.request.inputs.metadata),
1011
+ c
1012
+ )
1013
+ }
1014
+ }
1015
+ },
1016
+ payloadScope: c
1017
+ };
1018
+ }
1019
+ function Pr(e) {
1020
+ me(e.request, "scorecard");
1021
+ const t = e.snapshot ?? e.request.inputs.snapshot, n = e.comparison ?? e.request.inputs.comparison, o = h(
1022
+ t?.violations ?? [],
1023
+ e.violationLimit,
1024
+ _
1025
+ ), r = h(
1026
+ n?.metricDeltas ?? [],
1027
+ e.deltaLimit,
1028
+ W
1029
+ ), i = h(
1030
+ n?.scoreDeltas ?? [],
1031
+ e.deltaLimit,
1032
+ W
1033
+ ), s = {
1034
+ snapshotViolations: o.truncation,
1035
+ metricDeltas: r.truncation,
1036
+ scoreDeltas: i.truncation
1037
+ };
1038
+ return {
1039
+ request: {
1040
+ ...e.request,
1041
+ inputs: {
1042
+ ...e.request.inputs,
1043
+ snapshot: t ? {
1044
+ ...t,
1045
+ violations: o.items
1046
+ } : void 0,
1047
+ comparison: n ? {
1048
+ ...n,
1049
+ baseline: {
1050
+ ...H(n.baseline),
1051
+ violations: []
1052
+ },
1053
+ current: {
1054
+ ...H(n.current),
1055
+ violations: []
1056
+ },
1057
+ metricDeltas: r.items,
1058
+ scoreDeltas: i.items,
1059
+ newViolations: [],
1060
+ resolvedViolations: []
1061
+ } : void 0,
1062
+ metadata: He(
1063
+ e.request.inputs.metadata,
1064
+ s
1065
+ )
1066
+ }
1067
+ },
1068
+ payloadScope: s
1069
+ };
1070
+ }
1071
+ function Xt(e, t) {
1072
+ return e.source.localeCompare(t.source) || e.target.localeCompare(t.target) || e.type.localeCompare(t.type) || (e.sourceFile ?? "").localeCompare(t.sourceFile ?? "");
1073
+ }
1074
+ function Zt(e, t) {
1075
+ return t.magnitude - e.magnitude || e.id.localeCompare(t.id);
1076
+ }
1077
+ function W(e, t) {
1078
+ return Math.abs(t.delta) - Math.abs(e.delta) || e.id.localeCompare(t.id);
1079
+ }
1080
+ function De(e) {
1081
+ return e === "error" ? 3 : e === "warning" ? 2 : e === "info" ? 1 : 0;
1082
+ }
1083
+ function Qt(e) {
1084
+ const t = /* @__PURE__ */ new Set();
1085
+ for (const n of e)
1086
+ t.add(n.source), n.target && t.add(n.target);
1087
+ return t;
1088
+ }
1089
+ function me(e, t) {
1090
+ if (e.kind !== t)
1091
+ throw new Error(
1092
+ `Expected an AI analysis request of kind "${t}", received "${e.kind}".`
1093
+ );
1094
+ }
1095
+ function We(e, t) {
1096
+ return typeof e != "number" || Number.isNaN(e) ? t : Math.max(0, Math.trunc(e));
1097
+ }
1098
+ function H(e) {
1099
+ return {
1100
+ timestamp: e.timestamp,
1101
+ repo: e.repo,
1102
+ branch: e.branch,
1103
+ commitSha: e.commitSha,
1104
+ pluginVersion: e.pluginVersion,
1105
+ metricSchemaVersion: e.metricSchemaVersion,
1106
+ metrics: {},
1107
+ scores: {},
1108
+ violations: []
1109
+ };
1110
+ }
1111
+ function He(e, t) {
1112
+ return {
1113
+ ...e,
1114
+ payloadScope: Ke(Ue(e), t)
1115
+ };
1116
+ }
1117
+ function Ue(e) {
1118
+ const t = e?.payloadScope;
1119
+ if (!(typeof t != "object" || t === null || Array.isArray(t)))
1120
+ return t;
1121
+ }
1122
+ function Ke(e, t) {
1123
+ return {
1124
+ ...e ?? {},
1125
+ ...t
1126
+ };
1127
+ }
1128
+ function en(e, t, n) {
1129
+ const o = t.map((r) => ({
1130
+ id: `drift-${r.id}`,
1131
+ title: r.label,
1132
+ detail: `Status is ${r.status} with delta ${rn(
1133
+ r.delta
1134
+ )} and magnitude ${r.magnitude.toFixed(3)}.`,
1135
+ signals: ["drift-analysis", "snapshot-comparison"],
1136
+ confidence: 1
1137
+ }));
1138
+ return {
1139
+ kind: "drift",
1140
+ summary: `Deterministic drift interpretation indicates a ${n.overallTrend} trend (${n.worseningCount} worsening, ${n.improvingCount} improving, ${n.stableCount} stable).`,
1141
+ findings: o,
1142
+ recommendations: [
1143
+ {
1144
+ id: "drift-review-regressing-signals",
1145
+ title: "Review Regressing Signals First",
1146
+ priority: n.worseningCount > 0 ? "high" : "low",
1147
+ reason: n.worseningCount > 0 ? `There are ${n.worseningCount} worsening drift signals. Prioritize investigation of those signals before broader refactoring.` : "No worsening drift signals were detected in this comparison window."
1148
+ },
1149
+ {
1150
+ id: "drift-validate-trend-window",
1151
+ title: "Validate Trend Window Confidence",
1152
+ priority: "medium",
1153
+ reason: on(e) ? "Fewer than four snapshots were available. Treat conclusions as provisional and continue collecting trend data." : "Trend window is sufficient for directional interpretation. Continue monitoring for persistence across future snapshots."
1154
+ }
1155
+ ],
1156
+ metadata: {
1157
+ trend: n.overallTrend,
1158
+ worseningCount: n.worseningCount,
1159
+ improvingCount: n.improvingCount,
1160
+ stableCount: n.stableCount,
1161
+ signalCount: t.length,
1162
+ topWorsening: n.topWorsening,
1163
+ topImproving: n.topImproving,
1164
+ ...e.inputs.metadata
1165
+ }
1166
+ };
1167
+ }
1168
+ const jr = en;
1169
+ function br(e) {
1170
+ const t = Ye(
1171
+ e.affectedProjects,
1172
+ e.projects
1173
+ ), n = e.dependencies.filter(
1174
+ (r) => t.projectNames.has(r.source) || t.projectNames.has(r.target)
1175
+ ), o = fe(
1176
+ t.projects.map((r) => r.domain).filter((r) => !!r)
1177
+ );
1178
+ return {
1179
+ changedFilesCount: e.changedFilesCount ?? e.changedFiles?.length ?? 0,
1180
+ affectedProjects: [...t.projectNames].sort(
1181
+ (r, i) => r.localeCompare(i)
1182
+ ),
1183
+ affectedProjectsCount: t.projectNames.size,
1184
+ affectedDomains: o,
1185
+ affectedDomainCount: o.length,
1186
+ scopedDependencyCount: n.length,
1187
+ crossDomainDependencyEdges: Je(
1188
+ n,
1189
+ t.projectsByName
1190
+ )
1191
+ };
59
1192
  }
60
- function R(e, n) {
61
- return e.find((o) => o.startsWith(`${n}:`))?.split(":").slice(1).join(":");
1193
+ function Cr(e) {
1194
+ const t = Ye(
1195
+ e.selectedProjects,
1196
+ e.projects
1197
+ ), n = e.dependencies.filter(
1198
+ (c) => t.projectNames.has(c.source) || t.projectNames.has(c.target)
1199
+ ), o = /* @__PURE__ */ new Map();
1200
+ for (const c of n)
1201
+ t.projectNames.has(c.source) && o.set(
1202
+ c.source,
1203
+ (o.get(c.source) ?? 0) + 1
1204
+ );
1205
+ const r = [...o.values()], i = r.length > 0 ? Number(
1206
+ (r.reduce((c, l) => c + l, 0) / r.length).toFixed(2)
1207
+ ) : 0, s = r.length > 0 ? Math.max(...r) : 0, a = fe(
1208
+ t.projects.map((c) => c.domain).filter((c) => !!c)
1209
+ ), d = [...o.entries()].sort(
1210
+ (c, l) => l[1] - c[1] || c[0].localeCompare(l[0])
1211
+ ).slice(0, Math.max(1, e.topProjectsLimit ?? 10)).map(([c, l]) => ({ project: c, fanout: l }));
1212
+ return {
1213
+ scope: e.scope ?? "workspace",
1214
+ ...e.project ? { project: e.project } : {},
1215
+ ...e.domain ? { domain: e.domain } : {},
1216
+ selectedProjects: [...t.projectNames].sort(
1217
+ (c, l) => c.localeCompare(l)
1218
+ ),
1219
+ selectedProjectsCount: t.projectNames.size,
1220
+ affectedDomains: a,
1221
+ affectedDomainCount: a.length,
1222
+ scopedDependencyCount: n.length,
1223
+ crossDomainDependencyEdges: Je(
1224
+ n,
1225
+ t.projectsByName
1226
+ ),
1227
+ averageFanout: i,
1228
+ maxFanout: s,
1229
+ topFanoutProjects: d
1230
+ };
62
1231
  }
63
- function le(e) {
64
- return e === "application" || e === "app" ? "application" : e === "library" || e === "lib" ? "library" : e === "tool" ? "tool" : "unknown";
1232
+ function xr(e) {
1233
+ return e.filter((t) => t.status === "worsening").length;
65
1234
  }
66
- function ue(e) {
67
- return e === "static" || e === "dynamic" || e === "implicit" ? e : "unknown";
1235
+ function Dr(e) {
1236
+ const t = e.summary ?? Ft([...e.signals]), n = e.snapshotCount ?? 0;
1237
+ return {
1238
+ overallTrend: t.overallTrend,
1239
+ worseningSignalCount: t.worseningCount,
1240
+ improvingSignalCount: t.improvingCount,
1241
+ stableSignalCount: t.stableCount,
1242
+ signalCount: e.signals.length,
1243
+ snapshotCount: n,
1244
+ trendWindowInsufficient: n > 0 && n < 4
1245
+ };
68
1246
  }
69
- function de(e) {
70
- const n = e.ownership;
71
- if (typeof n == "string" && n)
72
- return n;
73
- if (n && typeof n == "object") {
74
- const t = n.team;
75
- if (typeof t == "string" && t)
76
- return t;
1247
+ function tn(e) {
1248
+ const t = Math.max(1, e.minimumOccurrences ?? 2), n = /* @__PURE__ */ new Map();
1249
+ for (const o of e.recentSnapshots) {
1250
+ const r = new Set(
1251
+ o.violations.map(
1252
+ (i) => nn(i)
1253
+ )
1254
+ );
1255
+ for (const i of r)
1256
+ n.set(i, (n.get(i) ?? 0) + 1);
77
1257
  }
1258
+ return [...n.entries()].filter(([, o]) => o >= t).map(([o, r]) => {
1259
+ const [i, s] = o.split("|");
1260
+ return {
1261
+ type: i ?? "unknown",
1262
+ source: s ?? "unknown",
1263
+ count: r
1264
+ };
1265
+ }).sort(
1266
+ (o, r) => r.count - o.count || o.type.localeCompare(r.type) || o.source.localeCompare(r.source)
1267
+ );
78
1268
  }
79
- function pe(e, n, t) {
80
- const o = t?.contacts ?? [], r = n ?? e ?? t?.team;
81
- return r && o.length ? {
82
- team: r,
83
- contacts: o,
84
- source: "merged"
85
- } : r ? {
86
- team: r,
87
- contacts: [],
88
- source: fe(t?.source)
89
- } : o.length ? {
90
- contacts: o,
91
- source: "codeowners"
92
- } : {
93
- source: "none"
1269
+ function kr(e) {
1270
+ const t = h(
1271
+ e.violations,
1272
+ e.analyzedViolationsLimit ?? 10,
1273
+ _
1274
+ ).items, n = /* @__PURE__ */ new Map();
1275
+ for (const l of t)
1276
+ n.set(
1277
+ l.source,
1278
+ (n.get(l.source) ?? 0) + 1
1279
+ );
1280
+ const o = /* @__PURE__ */ new Map();
1281
+ for (const l of e.dependencies)
1282
+ o.set(
1283
+ l.source,
1284
+ (o.get(l.source) ?? 0) + 1
1285
+ );
1286
+ const r = Math.max(1, e.topProjectsLimit ?? 5), i = [...n.entries()].sort(
1287
+ (l, u) => u[1] - l[1] || l[0].localeCompare(u[0])
1288
+ ).slice(0, r).map(([l, u]) => ({ project: l, count: u })), s = [...o.entries()].sort(
1289
+ (l, u) => u[1] - l[1] || l[0].localeCompare(u[0])
1290
+ ).slice(0, r).map(([l, u]) => ({ project: l, count: u })), a = new Map(
1291
+ e.projects.map((l) => [l.name, l])
1292
+ ), d = fe(
1293
+ i.map((l) => a.get(l.project)?.domain).filter((l) => !!l)
1294
+ ), c = e.recentSnapshots ?? [];
1295
+ return {
1296
+ analyzedViolations: t.length,
1297
+ totalViolations: e.violations.length,
1298
+ hotspotProjects: i,
1299
+ highFanoutProjects: s,
1300
+ hotspotDomains: d,
1301
+ persistentSmellSignals: tn({
1302
+ recentSnapshots: c,
1303
+ minimumOccurrences: e.minimumPersistentOccurrences
1304
+ }),
1305
+ snapshotCount: c.length,
1306
+ sampledSnapshotCount: c.length
94
1307
  };
95
1308
  }
1309
+ function $r(e) {
1310
+ const t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
1311
+ for (const a of e.projects)
1312
+ a.domain && t.set(
1313
+ a.domain,
1314
+ (t.get(a.domain) ?? 0) + 1
1315
+ ), a.layer && n.set(a.layer, (n.get(a.layer) ?? 0) + 1);
1316
+ for (const a of e.dependencies)
1317
+ o.set(
1318
+ a.source,
1319
+ (o.get(a.source) ?? 0) + 1
1320
+ );
1321
+ const r = Math.max(1, e.topProjectsLimit ?? 5), i = e.projects.filter(
1322
+ (a) => !!a.ownership?.team
1323
+ ).length, s = e.topViolations?.length ?? 0;
1324
+ return {
1325
+ projectCount: e.projects.length,
1326
+ dependencyCount: e.dependencies.length,
1327
+ ownershipCoverage: e.projects.length > 0 ? Number((i / e.projects.length).toFixed(3)) : 0,
1328
+ domainSummary: [...t.entries()].sort(
1329
+ (a, d) => d[1] - a[1] || a[0].localeCompare(d[0])
1330
+ ).map(([a, d]) => ({ domain: a, count: d })),
1331
+ layerSummary: [...n.entries()].sort(
1332
+ (a, d) => d[1] - a[1] || a[0].localeCompare(d[0])
1333
+ ).map(([a, d]) => ({ layer: a, count: d })),
1334
+ topFanoutProjects: [...o.entries()].sort(
1335
+ (a, d) => d[1] - a[1] || a[0].localeCompare(d[0])
1336
+ ).slice(0, r).map(([a, d]) => ({ project: a, count: d })),
1337
+ analyzedViolations: s,
1338
+ totalViolations: e.totalViolationsCount ?? s
1339
+ };
1340
+ }
1341
+ function Ye(e, t) {
1342
+ const n = /* @__PURE__ */ new Set(), o = [], r = /* @__PURE__ */ new Map();
1343
+ if (e.length > 0 && typeof e[0] == "object" && e[0] !== null)
1344
+ for (const i of e)
1345
+ n.add(i.name), o.push(i), r.set(i.name, i);
1346
+ else {
1347
+ const i = new Map(
1348
+ (t ?? []).map((s) => [s.name, s])
1349
+ );
1350
+ for (const s of e) {
1351
+ n.add(s);
1352
+ const a = i.get(s);
1353
+ a && (o.push(a), r.set(a.name, a));
1354
+ }
1355
+ }
1356
+ return {
1357
+ projectNames: n,
1358
+ projects: o.sort(
1359
+ (i, s) => i.name.localeCompare(s.name)
1360
+ ),
1361
+ projectsByName: r
1362
+ };
1363
+ }
1364
+ function Je(e, t) {
1365
+ return e.filter((n) => {
1366
+ const o = t.get(n.source)?.domain, r = t.get(n.target)?.domain;
1367
+ return !!(o && r && o !== r);
1368
+ }).length;
1369
+ }
1370
+ function nn(e) {
1371
+ return `${e.type}|${e.source}`;
1372
+ }
96
1373
  function fe(e) {
97
- return e === "merged" || e === "project-metadata" ? e : e === "codeowners" ? "codeowners" : "project-metadata";
1374
+ return [...new Set(e)].sort((t, n) => t.localeCompare(n));
1375
+ }
1376
+ function on(e) {
1377
+ return e.inputs.metadata?.trendWindowInsufficient === !0;
1378
+ }
1379
+ function rn(e) {
1380
+ return `${e > 0 ? "+" : ""}${e.toFixed(3)}`;
98
1381
  }
99
- const M = [
1382
+ const ie = [
100
1383
  "graph",
101
1384
  "conformance",
102
1385
  "policy",
103
1386
  "extension"
104
- ], me = [
1387
+ ], sn = [
105
1388
  "info",
106
1389
  "warning",
107
1390
  "error"
108
- ], ye = [
1391
+ ], an = [
109
1392
  "structural-dependency",
110
1393
  "cross-domain-dependency",
111
1394
  "missing-domain-context",
@@ -114,17 +1397,17 @@ const M = [
114
1397
  "domain-boundary-violation",
115
1398
  "layer-boundary-violation",
116
1399
  "ownership-gap"
117
- ], ge = [
1400
+ ], cn = [
118
1401
  "architecture",
119
1402
  "boundaries",
120
1403
  "ownership",
121
1404
  "documentation"
122
- ], A = {
1405
+ ], ke = {
123
1406
  graph: 0,
124
1407
  conformance: 1,
125
1408
  policy: 2,
126
1409
  extension: 3
127
- }, b = {
1410
+ }, N = {
128
1411
  "structural-dependency": 0,
129
1412
  "cross-domain-dependency": 1,
130
1413
  "missing-domain-context": 2,
@@ -133,19 +1416,19 @@ const M = [
133
1416
  "domain-boundary-violation": 5,
134
1417
  "layer-boundary-violation": 6,
135
1418
  "ownership-gap": 7
136
- }, q = {
1419
+ }, $e = {
137
1420
  error: 0,
138
1421
  warning: 1,
139
1422
  info: 2
140
1423
  };
141
- function yn(e) {
142
- const n = he(
1424
+ function dn(e) {
1425
+ const t = ln(
143
1426
  e.violations,
144
1427
  e.reportType
145
- ), t = we(
1428
+ ), n = pn(
146
1429
  e.signals,
147
1430
  e.reportType
148
- ), o = ve(
1431
+ ), o = un(
149
1432
  e.measurements,
150
1433
  e.reportType
151
1434
  );
@@ -154,210 +1437,860 @@ function yn(e) {
154
1437
  profile: e.profile,
155
1438
  warnings: [...e.warnings ?? []],
156
1439
  exceptions: e.exceptions,
157
- violations: n,
1440
+ violations: t,
158
1441
  measurements: o,
159
- signalBreakdown: Ie(t),
160
- metricBreakdown: Pe(o),
161
- topIssues: Se(t),
1442
+ signalBreakdown: mn(n),
1443
+ metricBreakdown: fn(o),
1444
+ topIssues: Xe(n),
162
1445
  health: e.health,
163
1446
  recommendations: [...e.recommendations ?? []]
164
1447
  };
165
1448
  }
166
- function he(e, n) {
167
- return n === "boundaries" ? e.filter((t) => t.category === "boundary") : n === "ownership" ? e.filter((t) => t.category === "ownership") : n === "architecture" ? e.filter((t) => t.category !== "ownership") : e;
1449
+ function ln(e, t) {
1450
+ return t === "boundaries" ? e.filter((n) => n.category === "boundary") : t === "ownership" ? e.filter((n) => n.category === "ownership") : t === "architecture" ? e.filter((n) => n.category !== "ownership") : e;
1451
+ }
1452
+ function un(e, t) {
1453
+ return t === "boundaries" ? e.filter(
1454
+ (n) => n.family === "boundaries"
1455
+ ) : t === "ownership" ? e.filter(
1456
+ (n) => n.family === "ownership"
1457
+ ) : t === "architecture" ? e.filter(
1458
+ (n) => n.family !== "ownership" && n.family !== "documentation"
1459
+ ) : e;
1460
+ }
1461
+ function pn(e, t) {
1462
+ return t === "boundaries" ? e.filter((n) => n.category === "boundary") : t === "ownership" ? e.filter((n) => n.category === "ownership") : t === "architecture" ? e.filter((n) => n.category !== "ownership") : e;
1463
+ }
1464
+ function mn(e) {
1465
+ const t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
1466
+ for (const r of e)
1467
+ t.set(r.source, (t.get(r.source) ?? 0) + 1), n.set(r.type, (n.get(r.type) ?? 0) + 1), o.set(
1468
+ r.severity,
1469
+ (o.get(r.severity) ?? 0) + 1
1470
+ );
1471
+ return {
1472
+ total: e.length,
1473
+ bySource: [
1474
+ ...ie.map((r) => ({
1475
+ source: r,
1476
+ count: t.get(r) ?? 0
1477
+ })),
1478
+ ...le(
1479
+ [...t.keys()],
1480
+ ie
1481
+ ).filter((r) => !ie.includes(r)).map((r) => ({
1482
+ source: r,
1483
+ count: t.get(r) ?? 0
1484
+ }))
1485
+ ],
1486
+ byType: le(
1487
+ [...n.keys()],
1488
+ an
1489
+ ).flatMap((r) => {
1490
+ const i = n.get(r) ?? 0;
1491
+ return i > 0 ? [{ type: r, count: i }] : [];
1492
+ }),
1493
+ bySeverity: sn.map((r) => ({
1494
+ severity: r,
1495
+ count: o.get(r) ?? 0
1496
+ }))
1497
+ };
1498
+ }
1499
+ function fn(e) {
1500
+ const t = /* @__PURE__ */ new Map();
1501
+ for (const o of e) {
1502
+ const r = t.get(o.family) ?? [];
1503
+ r.push(o), t.set(o.family, r);
1504
+ }
1505
+ return {
1506
+ families: le(
1507
+ [...t.keys()],
1508
+ cn
1509
+ ).flatMap((o) => {
1510
+ const r = (t.get(o) ?? []).slice().sort((s, a) => s.id.localeCompare(a.id)).map((s) => ({
1511
+ id: s.id,
1512
+ name: s.name,
1513
+ score: s.score
1514
+ }));
1515
+ if (r.length === 0)
1516
+ return [];
1517
+ const i = r.reduce(
1518
+ (s, a) => s + a.score,
1519
+ 0
1520
+ ) / r.length;
1521
+ return [
1522
+ {
1523
+ family: o,
1524
+ score: Math.round(i),
1525
+ measurements: r
1526
+ }
1527
+ ];
1528
+ })
1529
+ };
1530
+ }
1531
+ function Xe(e) {
1532
+ const t = /* @__PURE__ */ new Map();
1533
+ for (const n of e) {
1534
+ const o = gn(n), r = t.get(o);
1535
+ if (r) {
1536
+ r.issue.count += 1, r.issue.projects = yn(r.issue.projects, n), r.issue.ruleId || (r.issue.ruleId = Me(n)), r.issue.sourcePluginId || (r.issue.sourcePluginId = n.sourcePluginId);
1537
+ continue;
1538
+ }
1539
+ t.set(o, {
1540
+ issue: {
1541
+ type: n.type,
1542
+ source: n.source,
1543
+ severity: n.severity,
1544
+ count: 1,
1545
+ projects: Ze(n),
1546
+ ruleId: Me(n),
1547
+ message: n.message,
1548
+ sourcePluginId: n.sourcePluginId
1549
+ }
1550
+ });
1551
+ }
1552
+ return [...t.values()].map((n) => n.issue).sort(hn);
1553
+ }
1554
+ function gn(e) {
1555
+ return [
1556
+ e.type,
1557
+ e.source,
1558
+ e.severity,
1559
+ e.sourceProjectId ?? "",
1560
+ e.targetProjectId ?? "",
1561
+ e.relatedProjectIds.join(",")
1562
+ ].join("|");
1563
+ }
1564
+ function Ze(e) {
1565
+ return [
1566
+ ...new Set(
1567
+ [
1568
+ e.sourceProjectId,
1569
+ e.targetProjectId,
1570
+ ...e.relatedProjectIds
1571
+ ].filter((t) => !!t)
1572
+ )
1573
+ ].sort((t, n) => t.localeCompare(n));
1574
+ }
1575
+ function yn(e, t) {
1576
+ return [
1577
+ .../* @__PURE__ */ new Set([...e, ...Ze(t)])
1578
+ ].sort((n, o) => n.localeCompare(o));
1579
+ }
1580
+ function Me(e) {
1581
+ const t = e.metadata?.ruleId;
1582
+ return typeof t == "string" && t.length > 0 ? t : void 0;
1583
+ }
1584
+ function hn(e, t) {
1585
+ const n = $e[e.severity] - $e[t.severity];
1586
+ if (n !== 0)
1587
+ return n;
1588
+ const o = t.count - e.count;
1589
+ if (o !== 0)
1590
+ return o;
1591
+ const r = N[e.type], i = N[t.type], s = r - i;
1592
+ if (r !== void 0 && i !== void 0 && s !== 0)
1593
+ return s;
1594
+ if (!(e.type in N) || !(t.type in N)) {
1595
+ const c = e.type.localeCompare(t.type);
1596
+ if (c !== 0)
1597
+ return c;
1598
+ }
1599
+ const a = ke[e.source] - ke[t.source];
1600
+ if (a !== 0)
1601
+ return a;
1602
+ const d = e.projects.join(",").localeCompare(t.projects.join(","));
1603
+ return d !== 0 ? d : e.message.localeCompare(t.message);
1604
+ }
1605
+ function le(e, t) {
1606
+ const n = new Set(e), o = t.filter((i) => n.has(i)), r = e.filter((i) => !t.includes(i)).sort((i, s) => i.localeCompare(s));
1607
+ return [...o, ...r];
1608
+ }
1609
+ function Mr(e) {
1610
+ const t = M(e.id, "Exception id"), n = In(e.source), o = M(e.reason, "Exception reason"), r = M(e.owner, "Exception owner"), i = wn(e.review), s = tt(e.scope);
1611
+ if (s.source !== n)
1612
+ throw new Error(
1613
+ `Exception "${t}" has source "${n}" but scope source "${s.source}".`
1614
+ );
1615
+ return {
1616
+ id: t,
1617
+ source: n,
1618
+ scope: s,
1619
+ reason: o,
1620
+ owner: r,
1621
+ review: i
1622
+ };
1623
+ }
1624
+ function Qe(e) {
1625
+ const t = tt(e);
1626
+ return et(t) ? [
1627
+ t.source,
1628
+ t.ruleId,
1629
+ t.projectId,
1630
+ t.targetProjectId ?? ""
1631
+ ].join("|") : [
1632
+ t.source,
1633
+ t.ruleId ?? "",
1634
+ t.category ?? "",
1635
+ t.projectId ?? "",
1636
+ (t.relatedProjectIds ?? []).join(",")
1637
+ ].join("|");
1638
+ }
1639
+ function et(e) {
1640
+ return e.source === "policy";
1641
+ }
1642
+ function vn(e) {
1643
+ return e.source === "conformance";
1644
+ }
1645
+ function wn(e) {
1646
+ const t = v(e.createdAt), n = v(e.reviewBy), o = v(e.expiresAt);
1647
+ if (!n && !o)
1648
+ throw new Error(
1649
+ "Governance exception review must define reviewBy or expiresAt."
1650
+ );
1651
+ return {
1652
+ ...t ? { createdAt: t } : {},
1653
+ ...n ? { reviewBy: n } : {},
1654
+ ...o ? { expiresAt: o } : {}
1655
+ };
1656
+ }
1657
+ function tt(e) {
1658
+ if (e.source === "policy")
1659
+ return {
1660
+ source: "policy",
1661
+ ruleId: M(e.ruleId, "Policy exception ruleId"),
1662
+ projectId: M(
1663
+ e.projectId,
1664
+ "Policy exception projectId"
1665
+ ),
1666
+ ...v(e.targetProjectId) ? { targetProjectId: v(e.targetProjectId) } : {}
1667
+ };
1668
+ const t = v(e.ruleId), n = Pn(e.category), o = v(e.projectId), r = Sn(e.relatedProjectIds);
1669
+ if (!t && !n && !o && r.length === 0)
1670
+ throw new Error(
1671
+ "Conformance exception scope must define ruleId, category, projectId, or relatedProjectIds."
1672
+ );
1673
+ return {
1674
+ source: "conformance",
1675
+ ...t ? { ruleId: t } : {},
1676
+ ...n ? { category: n } : {},
1677
+ ...o ? { projectId: o } : {},
1678
+ ...r.length > 0 ? { relatedProjectIds: r } : {}
1679
+ };
1680
+ }
1681
+ function In(e) {
1682
+ if (e === "policy" || e === "conformance")
1683
+ return e;
1684
+ throw new Error(`Unsupported governance exception source "${e}".`);
1685
+ }
1686
+ function M(e, t) {
1687
+ const n = v(e);
1688
+ if (!n)
1689
+ throw new Error(`${t} is required.`);
1690
+ return n;
1691
+ }
1692
+ function v(e) {
1693
+ if (typeof e != "string")
1694
+ return;
1695
+ const t = e.trim();
1696
+ return t.length > 0 ? t : void 0;
1697
+ }
1698
+ function Sn(e) {
1699
+ return Array.isArray(e) ? [
1700
+ ...new Set(
1701
+ e.map(v).filter((t) => !!t)
1702
+ )
1703
+ ].sort((t, n) => t.localeCompare(n)) : [];
1704
+ }
1705
+ function Pn(e) {
1706
+ return v(e);
1707
+ }
1708
+ const Ee = {
1709
+ policy: 0,
1710
+ conformance: 1
1711
+ }, Re = {
1712
+ error: 0,
1713
+ warning: 1,
1714
+ info: 2
1715
+ };
1716
+ function jn(e, t) {
1717
+ const n = t.getTime(), o = Ae(e.review.expiresAt);
1718
+ if (o !== void 0 && o < n)
1719
+ return {
1720
+ exception: e,
1721
+ status: "expired"
1722
+ };
1723
+ const r = Ae(e.review.reviewBy);
1724
+ return r !== void 0 && r < n ? {
1725
+ exception: e,
1726
+ status: "stale"
1727
+ } : {
1728
+ exception: e,
1729
+ status: "active"
1730
+ };
1731
+ }
1732
+ function nt(e) {
1733
+ const t = e.exceptions.map(
1734
+ (c) => jn(c, e.asOf)
1735
+ ), n = Object.fromEntries(
1736
+ t.map((c) => [c.exception.id, c.status])
1737
+ ), o = t.filter((c) => c.status === "active").map((c) => c.exception), r = t.filter(
1738
+ (c) => c.status !== "active"
1739
+ ), i = e.policyViolations.map(
1740
+ (c) => Cn(c, o)
1741
+ ), s = e.conformanceFindings.map(
1742
+ (c) => xn(c, o)
1743
+ ), a = e.policyViolations.map(
1744
+ (c) => Dn(c, r)
1745
+ ).filter(R), d = e.conformanceFindings.map(
1746
+ (c) => kn(c, r)
1747
+ ).filter(R);
1748
+ return {
1749
+ declaredExceptions: [...e.exceptions],
1750
+ exceptionStatuses: n,
1751
+ policyViolations: i,
1752
+ conformanceFindings: s,
1753
+ activePolicyViolations: i.filter((c) => c.outcome === "active").map((c) => c.finding),
1754
+ suppressedPolicyViolations: i.filter(Fe),
1755
+ reactivatedPolicyViolations: a,
1756
+ activeConformanceFindings: s.filter((c) => c.outcome === "active").map((c) => c.finding),
1757
+ suppressedConformanceFindings: s.filter(Fe),
1758
+ reactivatedConformanceFindings: d
1759
+ };
1760
+ }
1761
+ function ot(e) {
1762
+ const t = On(e), n = Object.values(
1763
+ e.exceptionStatuses
1764
+ ).filter((c) => c === "active").length, o = Object.values(
1765
+ e.exceptionStatuses
1766
+ ).filter((c) => c === "stale").length, r = Object.values(
1767
+ e.exceptionStatuses
1768
+ ).filter((c) => c === "expired").length, i = [
1769
+ ...e.suppressedPolicyViolations.map(
1770
+ (c) => Vn(c)
1771
+ ),
1772
+ ...e.suppressedConformanceFindings.map(
1773
+ (c) => An(c)
1774
+ )
1775
+ ].sort(Ve), s = [
1776
+ ...e.reactivatedPolicyViolations.map(
1777
+ (c) => Fn(c)
1778
+ ),
1779
+ ...e.reactivatedConformanceFindings.map(
1780
+ (c) => zn(c)
1781
+ )
1782
+ ].sort(Ve), a = [], d = [];
1783
+ for (const c of [...e.declaredExceptions].sort(
1784
+ (l, u) => l.id.localeCompare(u.id)
1785
+ )) {
1786
+ const l = t.get(c.id) ?? 0, u = {
1787
+ id: c.id,
1788
+ source: c.source,
1789
+ status: e.exceptionStatuses[c.id],
1790
+ reason: c.reason,
1791
+ owner: c.owner,
1792
+ review: { ...c.review },
1793
+ matchCount: l
1794
+ };
1795
+ l > 0 ? a.push(u) : d.push(u);
1796
+ }
1797
+ return {
1798
+ summary: {
1799
+ declaredCount: e.declaredExceptions.length,
1800
+ matchedCount: a.length,
1801
+ suppressedPolicyViolationCount: e.suppressedPolicyViolations.length,
1802
+ suppressedConformanceFindingCount: e.suppressedConformanceFindings.length,
1803
+ unusedExceptionCount: d.length,
1804
+ activeExceptionCount: n,
1805
+ staleExceptionCount: o,
1806
+ expiredExceptionCount: r,
1807
+ reactivatedPolicyViolationCount: e.reactivatedPolicyViolations.length,
1808
+ reactivatedConformanceFindingCount: e.reactivatedConformanceFindings.length
1809
+ },
1810
+ used: a,
1811
+ unused: d,
1812
+ suppressedFindings: i,
1813
+ reactivatedFindings: s
1814
+ };
1815
+ }
1816
+ function bn() {
1817
+ return ot(
1818
+ nt({
1819
+ exceptions: [],
1820
+ policyViolations: [],
1821
+ conformanceFindings: [],
1822
+ asOf: /* @__PURE__ */ new Date(0)
1823
+ })
1824
+ );
1825
+ }
1826
+ function Cn(e, t) {
1827
+ const n = Z(
1828
+ t.filter((o) => o.source === "policy").flatMap((o) => {
1829
+ const r = rt(o.scope, e);
1830
+ return r ? [{ ...r, exceptionId: o.id }] : [];
1831
+ })
1832
+ );
1833
+ return n ? {
1834
+ finding: e,
1835
+ outcome: "suppressed",
1836
+ matchedExceptionId: n.exceptionId,
1837
+ matchedExceptionStatus: "active"
1838
+ } : {
1839
+ finding: e,
1840
+ outcome: "active"
1841
+ };
1842
+ }
1843
+ function xn(e, t) {
1844
+ const n = Z(
1845
+ t.filter((o) => o.source === "conformance").flatMap((o) => {
1846
+ const r = it(o.scope, e);
1847
+ return r ? [{ ...r, exceptionId: o.id }] : [];
1848
+ })
1849
+ );
1850
+ return n ? {
1851
+ finding: e,
1852
+ outcome: "suppressed",
1853
+ matchedExceptionId: n.exceptionId,
1854
+ matchedExceptionStatus: "active"
1855
+ } : {
1856
+ finding: e,
1857
+ outcome: "active"
1858
+ };
1859
+ }
1860
+ function Dn(e, t) {
1861
+ const n = Z(
1862
+ t.filter((o) => o.exception.source === "policy").flatMap((o) => {
1863
+ const r = rt(o.exception.scope, e);
1864
+ return r ? [
1865
+ {
1866
+ ...r,
1867
+ exceptionId: o.exception.id,
1868
+ status: o.status
1869
+ }
1870
+ ] : [];
1871
+ })
1872
+ );
1873
+ if (!(!n || n.status === "active"))
1874
+ return {
1875
+ finding: e,
1876
+ outcome: "active",
1877
+ matchedExceptionId: n.exceptionId,
1878
+ matchedExceptionStatus: n.status
1879
+ };
1880
+ }
1881
+ function kn(e, t) {
1882
+ const n = Z(
1883
+ t.filter((o) => o.exception.source === "conformance").flatMap((o) => {
1884
+ const r = it(o.exception.scope, e);
1885
+ return r ? [
1886
+ {
1887
+ ...r,
1888
+ exceptionId: o.exception.id,
1889
+ status: o.status
1890
+ }
1891
+ ] : [];
1892
+ })
1893
+ );
1894
+ if (!(!n || n.status === "active"))
1895
+ return {
1896
+ finding: e,
1897
+ outcome: "active",
1898
+ matchedExceptionId: n.exceptionId,
1899
+ matchedExceptionStatus: n.status
1900
+ };
1901
+ }
1902
+ function rt(e, t) {
1903
+ if (!et(e))
1904
+ return null;
1905
+ const n = g(
1906
+ t.details?.targetProject ?? t.details?.target
1907
+ );
1908
+ return e.ruleId !== t.ruleId || e.projectId !== g(t.project) || e.targetProjectId && e.targetProjectId !== n ? null : {
1909
+ scopeKey: Qe(e),
1910
+ specificity: Mn(e)
1911
+ };
1912
+ }
1913
+ function it(e, t) {
1914
+ return !vn(e) || e.ruleId && e.ruleId !== t.ruleId || e.category && e.category !== t.category || e.projectId && e.projectId !== t.projectId || e.relatedProjectIds && !Rn(
1915
+ e.relatedProjectIds,
1916
+ t.relatedProjectIds
1917
+ ) ? null : {
1918
+ scopeKey: Qe(e),
1919
+ specificity: En(e)
1920
+ };
168
1921
  }
169
- function ve(e, n) {
170
- return n === "boundaries" ? e.filter(
171
- (t) => t.family === "boundaries"
172
- ) : n === "ownership" ? e.filter(
173
- (t) => t.family === "ownership"
174
- ) : n === "architecture" ? e.filter(
175
- (t) => t.family !== "ownership" && t.family !== "documentation"
176
- ) : e;
1922
+ function Z(e) {
1923
+ return e.length === 0 ? null : [...e].sort($n)[0] ?? null;
177
1924
  }
178
- function we(e, n) {
179
- return n === "boundaries" ? e.filter((t) => t.category === "boundary") : n === "ownership" ? e.filter((t) => t.category === "ownership") : n === "architecture" ? e.filter((t) => t.category !== "ownership") : e;
1925
+ function $n(e, t) {
1926
+ if (e.specificity !== t.specificity)
1927
+ return t.specificity - e.specificity;
1928
+ const n = e.scopeKey.localeCompare(t.scopeKey);
1929
+ return n !== 0 ? n : e.exceptionId.localeCompare(t.exceptionId);
180
1930
  }
181
- function Ie(e) {
182
- const n = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
183
- for (const r of e)
184
- n.set(r.source, (n.get(r.source) ?? 0) + 1), t.set(r.type, (t.get(r.type) ?? 0) + 1), o.set(
185
- r.severity,
186
- (o.get(r.severity) ?? 0) + 1
1931
+ function Mn(e) {
1932
+ return e.targetProjectId ? 2 : 1;
1933
+ }
1934
+ function En(e) {
1935
+ return [
1936
+ e.ruleId,
1937
+ e.category,
1938
+ e.projectId,
1939
+ e.relatedProjectIds?.length ? "relatedProjectIds" : void 0
1940
+ ].filter(Boolean).length;
1941
+ }
1942
+ function Rn(e, t) {
1943
+ const n = Oe(e), o = Oe(t);
1944
+ return n.length !== o.length ? !1 : n.every(
1945
+ (r, i) => r === o[i]
1946
+ );
1947
+ }
1948
+ function Oe(e) {
1949
+ return [...new Set(e.map(g).filter(R))].sort(
1950
+ (t, n) => t.localeCompare(n)
1951
+ );
1952
+ }
1953
+ function On(e) {
1954
+ const t = /* @__PURE__ */ new Map();
1955
+ for (const n of [
1956
+ ...e.suppressedPolicyViolations,
1957
+ ...e.suppressedConformanceFindings,
1958
+ ...e.reactivatedPolicyViolations.filter(
1959
+ (o) => typeof o.matchedExceptionId == "string"
1960
+ ),
1961
+ ...e.reactivatedConformanceFindings.filter(
1962
+ (o) => typeof o.matchedExceptionId == "string"
1963
+ )
1964
+ ])
1965
+ n.matchedExceptionId && t.set(
1966
+ n.matchedExceptionId,
1967
+ (t.get(n.matchedExceptionId) ?? 0) + 1
187
1968
  );
1969
+ return t;
1970
+ }
1971
+ function Vn(e) {
1972
+ const t = g(
1973
+ e.finding.details?.targetProject ?? e.finding.details?.target
1974
+ ), n = g(e.finding.project);
188
1975
  return {
189
- total: e.length,
190
- bySource: [
191
- ...M.map((r) => ({
192
- source: r,
193
- count: n.get(r) ?? 0
194
- })),
195
- ...B(
196
- [...n.keys()],
197
- M
198
- ).filter((r) => !M.includes(r)).map((r) => ({
199
- source: r,
200
- count: n.get(r) ?? 0
201
- }))
202
- ],
203
- byType: B(
204
- [...t.keys()],
205
- ye
206
- ).flatMap((r) => {
207
- const i = t.get(r) ?? 0;
208
- return i > 0 ? [{ type: r, count: i }] : [];
209
- }),
210
- bySeverity: me.map((r) => ({
211
- severity: r,
212
- count: o.get(r) ?? 0
213
- }))
1976
+ kind: "policy-violation",
1977
+ exceptionId: e.matchedExceptionId,
1978
+ source: "policy",
1979
+ ruleId: e.finding.ruleId,
1980
+ category: e.finding.category,
1981
+ severity: e.finding.severity,
1982
+ status: "active",
1983
+ ...n ? { projectId: n } : {},
1984
+ ...t ? { targetProjectId: t } : {},
1985
+ relatedProjectIds: [n, t].filter(R),
1986
+ message: e.finding.message,
1987
+ ...e.finding.sourcePluginId ? { sourcePluginId: e.finding.sourcePluginId } : {}
214
1988
  };
215
1989
  }
216
- function Pe(e) {
217
- const n = /* @__PURE__ */ new Map();
218
- for (const o of e) {
219
- const r = n.get(o.family) ?? [];
220
- r.push(o), n.set(o.family, r);
221
- }
1990
+ function An(e) {
222
1991
  return {
223
- families: B(
224
- [...n.keys()],
225
- ge
226
- ).flatMap((o) => {
227
- const r = (n.get(o) ?? []).slice().sort((a, c) => a.id.localeCompare(c.id)).map((a) => ({
228
- id: a.id,
229
- name: a.name,
230
- score: a.score
231
- }));
232
- if (r.length === 0)
233
- return [];
234
- const i = r.reduce(
235
- (a, c) => a + c.score,
236
- 0
237
- ) / r.length;
238
- return [
239
- {
240
- family: o,
241
- score: Math.round(i),
242
- measurements: r
243
- }
244
- ];
245
- })
1992
+ kind: "conformance-finding",
1993
+ exceptionId: e.matchedExceptionId,
1994
+ source: "conformance",
1995
+ ...e.finding.ruleId ? { ruleId: e.finding.ruleId } : {},
1996
+ category: e.finding.category,
1997
+ severity: e.finding.severity,
1998
+ status: "active",
1999
+ ...e.finding.projectId ? { projectId: e.finding.projectId } : {},
2000
+ relatedProjectIds: [...e.finding.relatedProjectIds].sort(
2001
+ (t, n) => t.localeCompare(n)
2002
+ ),
2003
+ message: e.finding.message,
2004
+ ...g(e.finding.metadata?.sourcePluginId) ? {
2005
+ sourcePluginId: g(e.finding.metadata?.sourcePluginId)
2006
+ } : {}
246
2007
  };
247
2008
  }
248
- function Se(e) {
249
- const n = /* @__PURE__ */ new Map();
250
- for (const t of e) {
251
- const o = be(t), r = n.get(o);
252
- if (r) {
253
- r.issue.count += 1, r.issue.projects = De(r.issue.projects, t), r.issue.ruleId || (r.issue.ruleId = V(t)), r.issue.sourcePluginId || (r.issue.sourcePluginId = t.sourcePluginId);
254
- continue;
255
- }
256
- n.set(o, {
257
- issue: {
258
- type: t.type,
259
- source: t.source,
260
- severity: t.severity,
261
- count: 1,
262
- projects: J(t),
263
- ruleId: V(t),
264
- message: t.message,
265
- sourcePluginId: t.sourcePluginId
266
- }
267
- });
268
- }
269
- return [...n.values()].map((t) => t.issue).sort(je);
2009
+ function Fn(e) {
2010
+ const t = g(
2011
+ e.finding.details?.targetProject ?? e.finding.details?.target
2012
+ ), n = g(e.finding.project);
2013
+ return {
2014
+ kind: "policy-violation",
2015
+ exceptionId: e.matchedExceptionId ?? "unknown-exception",
2016
+ source: "policy",
2017
+ status: e.matchedExceptionStatus ?? "stale",
2018
+ ruleId: e.finding.ruleId,
2019
+ category: e.finding.category,
2020
+ severity: e.finding.severity,
2021
+ ...n ? { projectId: n } : {},
2022
+ ...t ? { targetProjectId: t } : {},
2023
+ relatedProjectIds: [n, t].filter(R),
2024
+ message: e.finding.message,
2025
+ ...e.finding.sourcePluginId ? { sourcePluginId: e.finding.sourcePluginId } : {}
2026
+ };
270
2027
  }
271
- function be(e) {
272
- return [
273
- e.type,
274
- e.source,
275
- e.severity,
276
- e.sourceProjectId ?? "",
2028
+ function zn(e) {
2029
+ return {
2030
+ kind: "conformance-finding",
2031
+ exceptionId: e.matchedExceptionId ?? "unknown-exception",
2032
+ source: "conformance",
2033
+ status: e.matchedExceptionStatus ?? "stale",
2034
+ ...e.finding.ruleId ? { ruleId: e.finding.ruleId } : {},
2035
+ category: e.finding.category,
2036
+ severity: e.finding.severity,
2037
+ ...e.finding.projectId ? { projectId: e.finding.projectId } : {},
2038
+ relatedProjectIds: [...e.finding.relatedProjectIds].sort(
2039
+ (t, n) => t.localeCompare(n)
2040
+ ),
2041
+ message: e.finding.message,
2042
+ ...g(e.finding.metadata?.sourcePluginId) ? {
2043
+ sourcePluginId: g(e.finding.metadata?.sourcePluginId)
2044
+ } : {}
2045
+ };
2046
+ }
2047
+ function Ve(e, t) {
2048
+ const n = Ee[e.source] - Ee[t.source];
2049
+ if (n !== 0)
2050
+ return n;
2051
+ const o = Re[e.severity] - Re[t.severity];
2052
+ if (o !== 0)
2053
+ return o;
2054
+ const r = (e.ruleId ?? "").localeCompare(t.ruleId ?? "");
2055
+ if (r !== 0)
2056
+ return r;
2057
+ const i = [
2058
+ e.projectId ?? "",
277
2059
  e.targetProjectId ?? "",
278
2060
  e.relatedProjectIds.join(",")
279
- ].join("|");
2061
+ ].join("|").localeCompare(
2062
+ [
2063
+ t.projectId ?? "",
2064
+ t.targetProjectId ?? "",
2065
+ t.relatedProjectIds.join(",")
2066
+ ].join("|")
2067
+ );
2068
+ return i !== 0 ? i : e.message.localeCompare(t.message);
280
2069
  }
281
- function J(e) {
282
- return [
283
- ...new Set(
284
- [
285
- e.sourceProjectId,
286
- e.targetProjectId,
287
- ...e.relatedProjectIds
288
- ].filter((n) => !!n)
289
- )
290
- ].sort((n, t) => n.localeCompare(t));
2070
+ function Ae(e) {
2071
+ if (!e)
2072
+ return;
2073
+ const t = e.includes("T") ? e : `${e}T00:00:00.000Z`, n = Date.parse(t);
2074
+ if (!Number.isFinite(n))
2075
+ throw new Error(`Invalid governance exception lifecycle date "${e}".`);
2076
+ return n;
291
2077
  }
292
- function De(e, n) {
293
- return [
294
- .../* @__PURE__ */ new Set([...e, ...J(n)])
295
- ].sort((t, o) => t.localeCompare(o));
2078
+ function g(e) {
2079
+ if (typeof e != "string")
2080
+ return;
2081
+ const t = e.trim();
2082
+ return t.length > 0 ? t : void 0;
296
2083
  }
297
- function V(e) {
298
- const n = e.metadata?.ruleId;
299
- return typeof n == "string" && n.length > 0 ? n : void 0;
2084
+ function R(e) {
2085
+ return e !== void 0;
300
2086
  }
301
- function je(e, n) {
302
- const t = q[e.severity] - q[n.severity];
303
- if (t !== 0)
304
- return t;
305
- const o = n.count - e.count;
306
- if (o !== 0)
307
- return o;
308
- const r = b[e.type], i = b[n.type], a = r - i;
309
- if (r !== void 0 && i !== void 0 && a !== 0)
310
- return a;
311
- if (!(e.type in b) || !(n.type in b)) {
312
- const l = e.type.localeCompare(n.type);
313
- if (l !== 0)
314
- return l;
2087
+ function Fe(e) {
2088
+ return e.outcome === "suppressed" && typeof e.matchedExceptionId == "string";
2089
+ }
2090
+ class Er {
2091
+ capabilitiesById = /* @__PURE__ */ new Map();
2092
+ capabilities;
2093
+ constructor(t) {
2094
+ const n = t.map(
2095
+ (o) => Object.freeze({ ...o })
2096
+ );
2097
+ for (const o of n) {
2098
+ if (this.capabilitiesById.has(o.id))
2099
+ throw new Error(
2100
+ `Duplicate governance capability id "${o.id}" is not allowed.`
2101
+ );
2102
+ this.capabilitiesById.set(o.id, o);
2103
+ }
2104
+ this.capabilities = Object.freeze([...n]);
315
2105
  }
316
- const c = A[e.source] - A[n.source];
317
- if (c !== 0)
318
- return c;
319
- const s = e.projects.join(",").localeCompare(n.projects.join(","));
320
- return s !== 0 ? s : e.message.localeCompare(n.message);
321
- }
322
- function B(e, n) {
323
- const t = new Set(e), o = n.filter((i) => t.has(i)), r = e.filter((i) => !n.includes(i)).sort((i, a) => i.localeCompare(a));
324
- return [...o, ...r];
2106
+ has(t) {
2107
+ return this.capabilitiesById.has(t);
2108
+ }
2109
+ get(t) {
2110
+ return this.capabilitiesById.get(t);
2111
+ }
2112
+ list() {
2113
+ return [...this.capabilities];
2114
+ }
2115
+ }
2116
+ class se extends Error {
2117
+ diagnostics;
2118
+ constructor(t, n) {
2119
+ super(t), this.name = "GovernanceExtensionRegistrationError", this.diagnostics = n;
2120
+ }
2121
+ }
2122
+ class Tn {
2123
+ context;
2124
+ registry = {
2125
+ metricProviders: [],
2126
+ signalProviders: [],
2127
+ rulePacks: [],
2128
+ enrichers: []
2129
+ };
2130
+ pluginId;
2131
+ constructor(t, n) {
2132
+ this.context = Object.freeze({
2133
+ ...t,
2134
+ options: Object.freeze({ ...t.options })
2135
+ }), this.pluginId = n;
2136
+ }
2137
+ registerMetricProvider(t) {
2138
+ this.registry.metricProviders.push({
2139
+ pluginId: this.pluginId,
2140
+ contribution: t
2141
+ });
2142
+ }
2143
+ registerSignalProvider(t) {
2144
+ this.registry.signalProviders.push({
2145
+ pluginId: this.pluginId,
2146
+ contribution: t
2147
+ });
2148
+ }
2149
+ registerRulePack(t) {
2150
+ this.registry.rulePacks.push({
2151
+ pluginId: this.pluginId,
2152
+ contribution: t
2153
+ });
2154
+ }
2155
+ registerEnricher(t) {
2156
+ this.registry.enrichers.push({
2157
+ pluginId: this.pluginId,
2158
+ contribution: t
2159
+ });
2160
+ }
2161
+ toRegistry() {
2162
+ return {
2163
+ metricProviders: [...this.registry.metricProviders],
2164
+ signalProviders: [...this.registry.signalProviders],
2165
+ rulePacks: [...this.registry.rulePacks],
2166
+ enrichers: [...this.registry.enrichers]
2167
+ };
2168
+ }
2169
+ }
2170
+ async function Rr(e, t) {
2171
+ return (await Ln(
2172
+ e,
2173
+ t
2174
+ )).registry;
325
2175
  }
326
- function S(e, n) {
2176
+ async function Ln(e, t, n = {}) {
2177
+ const o = {
2178
+ metricProviders: [],
2179
+ signalProviders: [],
2180
+ rulePacks: [],
2181
+ enrichers: []
2182
+ }, r = [...n.diagnostics ?? []], i = /* @__PURE__ */ new Map();
2183
+ for (const s of t) {
2184
+ try {
2185
+ Wn(s);
2186
+ } catch (d) {
2187
+ throw r.push({
2188
+ code: "governance.extension.invalid_definition",
2189
+ severity: "error",
2190
+ message: ae(d),
2191
+ packageName: s.sourceSpecifier,
2192
+ moduleSpecifier: s.moduleSpecifier,
2193
+ legacy: s.legacy
2194
+ }), new se(
2195
+ ae(d),
2196
+ r
2197
+ );
2198
+ }
2199
+ const a = i.get(s.definition.id);
2200
+ if (a) {
2201
+ const d = `Duplicate governance extension id "${s.definition.id}" was found in "${a}" and "${s.moduleSpecifier}".`;
2202
+ throw r.push({
2203
+ code: "governance.extension.duplicate_id",
2204
+ severity: "error",
2205
+ message: d,
2206
+ packageName: s.sourceSpecifier,
2207
+ moduleSpecifier: s.moduleSpecifier,
2208
+ extensionId: s.definition.id,
2209
+ legacy: s.legacy
2210
+ }), new se(d, r);
2211
+ }
2212
+ i.set(s.definition.id, s.moduleSpecifier);
2213
+ try {
2214
+ const d = new Tn(
2215
+ e,
2216
+ s.definition.id
2217
+ );
2218
+ await s.definition.register(d), _n(o, d.toRegistry());
2219
+ } catch (d) {
2220
+ const c = `Governance extension "${s.definition.id}" from "${s.moduleSpecifier}" failed during registration: ${ae(d)}`;
2221
+ throw r.push({
2222
+ code: "governance.extension.registration_failed",
2223
+ severity: "error",
2224
+ message: c,
2225
+ packageName: s.sourceSpecifier,
2226
+ moduleSpecifier: s.moduleSpecifier,
2227
+ extensionId: s.definition.id,
2228
+ legacy: s.legacy
2229
+ }), new se(c, r);
2230
+ }
2231
+ }
327
2232
  return {
328
- useCase: e,
329
- request: n.request,
330
- analysis: n.analysis,
331
- ...n.payloadScope ? { payloadScope: n.payloadScope } : {},
332
- ...n.metadata ? { metadata: n.metadata } : {}
2233
+ registry: o,
2234
+ diagnostics: r
333
2235
  };
334
2236
  }
335
- function gn(e) {
336
- return S("root-cause", e);
2237
+ async function Bn(e, t) {
2238
+ let n = t.workspace;
2239
+ for (const o of e.enrichers)
2240
+ n = await o.contribution.enrichWorkspace({
2241
+ ...t,
2242
+ workspace: n
2243
+ });
2244
+ return n;
2245
+ }
2246
+ async function Gn(e, t) {
2247
+ return (await Promise.all(
2248
+ e.rulePacks.map(async (o) => (await o.contribution.evaluate(t)).map((i) => ({
2249
+ ...i,
2250
+ sourcePluginId: i.sourcePluginId ?? o.pluginId
2251
+ })))
2252
+ )).flat();
337
2253
  }
338
- function hn(e) {
339
- return S("pr-impact", e);
2254
+ async function Nn(e, t) {
2255
+ return (await Promise.all(
2256
+ e.signalProviders.map(async (o) => (await o.contribution.provideSignals(t)).map((i) => ({
2257
+ ...i,
2258
+ source: "extension",
2259
+ sourcePluginId: i.sourcePluginId ?? o.pluginId
2260
+ })))
2261
+ )).flat();
340
2262
  }
341
- function vn(e) {
342
- return S("drift", e);
2263
+ async function qn(e, t) {
2264
+ return (await Promise.all(
2265
+ e.metricProviders.map(async (o) => (await o.contribution.provideMetrics(t)).map((i) => ({
2266
+ ...i,
2267
+ sourcePluginId: i.sourcePluginId ?? o.pluginId
2268
+ })))
2269
+ )).flat();
343
2270
  }
344
- function wn(e) {
345
- return S("scorecard", e);
2271
+ function _n(e, t) {
2272
+ e.metricProviders.push(...t.metricProviders), e.signalProviders.push(...t.signalProviders), e.rulePacks.push(...t.rulePacks), e.enrichers.push(...t.enrichers);
346
2273
  }
347
- function In(e) {
348
- return S("management-insights", e);
2274
+ function Wn(e) {
2275
+ if (typeof e.definition.id != "string" || e.definition.id.trim().length === 0)
2276
+ throw new Error(
2277
+ `Governance extension module "${e.moduleSpecifier}" must declare a non-empty "id".`
2278
+ );
2279
+ }
2280
+ function ae(e) {
2281
+ return e instanceof Error ? e.message : String(e);
349
2282
  }
350
- const Pn = {
2283
+ const q = {
351
2284
  goodMinScore: 85,
352
2285
  warningMinScore: 70
353
2286
  };
354
- function z(e) {
2287
+ function ge(e) {
355
2288
  return Object.fromEntries(
356
- e.map((n, t) => [n, e.slice(t)])
2289
+ e.map((t, n) => [t, e.slice(n)])
357
2290
  );
358
2291
  }
359
- function m(e, n = {}) {
360
- const t = e.allowedLayerDependencies ?? z(e.layers), o = {
2292
+ function j(e, t = {}) {
2293
+ const n = e.allowedLayerDependencies ?? ge(e.layers), o = {
361
2294
  "domain-boundary": {
362
2295
  enabled: !0,
363
2296
  severity: "error",
@@ -369,7 +2302,7 @@ function m(e, n = {}) {
369
2302
  enabled: !0,
370
2303
  severity: "warning",
371
2304
  options: {
372
- allowedDependencies: t,
2305
+ allowedDependencies: n,
373
2306
  layers: [...e.layers],
374
2307
  usesExplicitDependencies: e.allowedLayerDependencies !== void 0
375
2308
  }
@@ -383,279 +2316,516 @@ function m(e, n = {}) {
383
2316
  }
384
2317
  }
385
2318
  }, r = Object.fromEntries(
386
- Object.entries(e.rules ?? {}).map(([i, a]) => [
2319
+ Object.entries(e.rules ?? {}).map(([i, s]) => [
387
2320
  i,
388
2321
  {
389
2322
  ...o[i] ?? {},
390
- ...a,
391
- ...a.options !== void 0 ? { options: a.options } : o[i]?.options !== void 0 ? { options: o[i]?.options } : {}
2323
+ ...s,
2324
+ ...s.options !== void 0 ? { options: s.options } : o[i]?.options !== void 0 ? { options: o[i]?.options } : {}
392
2325
  }
393
2326
  ])
394
2327
  );
395
2328
  return {
396
- name: e.name,
397
- description: e.description,
398
- rules: {
399
- ...o,
400
- ...r
401
- },
402
- scoring: {
403
- statusThresholds: e.health.statusThresholds,
404
- metricWeights: e.metrics
405
- },
406
- exceptions: n.exceptions ?? [],
407
- projectOverrides: n.projectOverrides ?? {},
408
- compatibility: {
409
- boundaryPolicySource: e.boundaryPolicySource
410
- }
2329
+ name: e.name,
2330
+ description: e.description,
2331
+ rules: {
2332
+ ...o,
2333
+ ...r
2334
+ },
2335
+ scoring: {
2336
+ statusThresholds: e.health.statusThresholds,
2337
+ metricWeights: e.metrics
2338
+ },
2339
+ exceptions: t.exceptions ?? [],
2340
+ projectOverrides: t.projectOverrides ?? {},
2341
+ compatibility: {
2342
+ boundaryPolicySource: e.boundaryPolicySource
2343
+ }
2344
+ };
2345
+ }
2346
+ function st(e, t = {}, n = q, o = {}) {
2347
+ const r = Math.round(Hn(e, t)), i = Yn(n), s = Jn(e), a = Xn(e), d = Zn(
2348
+ o.topIssues ?? []
2349
+ ), c = Qn(
2350
+ o.topIssues ?? [],
2351
+ o.projectHotspotLimit ?? 5
2352
+ ), l = Kn(r, i);
2353
+ return {
2354
+ score: r,
2355
+ status: l,
2356
+ grade: Un(r),
2357
+ hotspots: s.map((u) => u.name),
2358
+ metricHotspots: s,
2359
+ projectHotspots: c,
2360
+ explainability: {
2361
+ summary: no(
2362
+ r,
2363
+ l,
2364
+ a,
2365
+ d
2366
+ ),
2367
+ statusReason: to(r, l, i),
2368
+ weakestMetrics: a,
2369
+ dominantIssues: d
2370
+ }
2371
+ };
2372
+ }
2373
+ const Or = st;
2374
+ function at(e, t) {
2375
+ const n = [];
2376
+ return e.some((o) => o.ruleId === "domain-boundary") && n.push({
2377
+ id: "reduce-cross-domain-dependencies",
2378
+ title: "Reduce cross-domain dependencies",
2379
+ priority: "high",
2380
+ reason: "Domain boundary violations indicate tight coupling across business domains."
2381
+ }), e.some((o) => o.ruleId === "ownership-presence") && n.push({
2382
+ id: "improve-ownership-coverage",
2383
+ title: "Improve ownership coverage",
2384
+ priority: "medium",
2385
+ reason: "Unowned projects slow down incident response and architectural decision making."
2386
+ }), (t.find(
2387
+ (o) => o.id === "dependency-complexity"
2388
+ )?.score ?? 100) < 60 && n.push({
2389
+ id: "reduce-dependency-complexity",
2390
+ title: "Reduce dependency complexity",
2391
+ priority: "medium",
2392
+ reason: "High dependency complexity increases blast radius and maintenance cost."
2393
+ }), n;
2394
+ }
2395
+ const Vr = at;
2396
+ function Hn(e, t) {
2397
+ if (e.length === 0)
2398
+ return 0;
2399
+ let n = 0, o = 0;
2400
+ for (const r of e) {
2401
+ const i = t[r.id] ?? 1, s = i > 0 ? i : 0;
2402
+ n += r.score * s, o += s;
2403
+ }
2404
+ return o === 0 ? e.reduce((r, i) => r + i.score, 0) / e.length : n / o;
2405
+ }
2406
+ function Un(e) {
2407
+ return e >= 90 ? "A" : e >= 80 ? "B" : e >= 70 ? "C" : e >= 60 ? "D" : "F";
2408
+ }
2409
+ function Kn(e, t) {
2410
+ return e >= t.goodMinScore ? "good" : e >= t.warningMinScore ? "warning" : "critical";
2411
+ }
2412
+ function Yn(e) {
2413
+ const t = typeof e.goodMinScore == "number" && Number.isFinite(e.goodMinScore) ? e.goodMinScore : q.goodMinScore, n = typeof e.warningMinScore == "number" && Number.isFinite(e.warningMinScore) ? e.warningMinScore : q.warningMinScore;
2414
+ return t <= n ? q : {
2415
+ goodMinScore: t,
2416
+ warningMinScore: n
2417
+ };
2418
+ }
2419
+ function Jn(e) {
2420
+ return [...e].filter((t) => t.score < 60).sort((t, n) => t.score - n.score || t.id.localeCompare(n.id)).map((t) => ({
2421
+ id: t.id,
2422
+ name: t.name,
2423
+ score: t.score
2424
+ }));
2425
+ }
2426
+ function Xn(e) {
2427
+ return [...e].sort((t, n) => t.score - n.score || t.id.localeCompare(n.id)).slice(0, 3).map((t) => ({
2428
+ id: t.id,
2429
+ name: t.name,
2430
+ score: t.score
2431
+ }));
2432
+ }
2433
+ function Zn(e) {
2434
+ return e.slice(0, 3);
2435
+ }
2436
+ function Qn(e, t) {
2437
+ const n = /* @__PURE__ */ new Map();
2438
+ for (const o of e)
2439
+ if (eo(o))
2440
+ for (const r of o.projects) {
2441
+ const i = n.get(r) ?? {
2442
+ count: 0,
2443
+ typeCounts: /* @__PURE__ */ new Map()
2444
+ };
2445
+ i.count += o.count, i.typeCounts.set(
2446
+ o.type,
2447
+ (i.typeCounts.get(o.type) ?? 0) + o.count
2448
+ ), n.set(r, i);
2449
+ }
2450
+ return [...n.entries()].sort((o, r) => r[1].count - o[1].count || o[0].localeCompare(r[0])).slice(0, Math.max(1, t)).map(([o, r]) => ({
2451
+ project: o,
2452
+ count: r.count,
2453
+ dominantIssueTypes: [...r.typeCounts.entries()].sort((i, s) => s[1] - i[1] || i[0].localeCompare(s[0])).slice(0, 3).map(([i]) => i)
2454
+ }));
2455
+ }
2456
+ function eo(e) {
2457
+ return e.type !== "structural-dependency";
2458
+ }
2459
+ function to(e, t, n) {
2460
+ return t === "good" ? `Score ${e} is at or above the good threshold (${n.goodMinScore}).` : t === "warning" ? `Score ${e} is below the good threshold (${n.goodMinScore}) but at or above the warning threshold (${n.warningMinScore}).` : `Score ${e} is below the warning threshold (${n.warningMinScore}).`;
2461
+ }
2462
+ function no(e, t, n, o) {
2463
+ const r = n.length > 0 ? `Weakest metrics are ${n.map((s) => s.name).join(", ")}.` : "No weak metrics were detected.", i = o.length > 0 ? `Dominant issue types are ${o.map((s) => s.type).join(", ")}.` : "No dominant issue types were detected.";
2464
+ return `${oo(t)} health at ${e}. ${r} ${i}`;
2465
+ }
2466
+ function oo(e) {
2467
+ return e.length > 0 ? `${e[0].toUpperCase()}${e.slice(1)}` : e;
2468
+ }
2469
+ function ct(e) {
2470
+ const { workspace: t, signals: n } = e, o = t.dependencies.length, r = t.projects.length || 1, i = ro(n), s = io(
2471
+ i,
2472
+ (m) => m.type === "structural-dependency"
2473
+ ), a = s > 0 ? s : o, d = ce(
2474
+ i,
2475
+ so
2476
+ ), c = ce(
2477
+ i,
2478
+ (m) => m.type === "layer-boundary-violation"
2479
+ ), l = ce(
2480
+ i,
2481
+ (m) => m.type === "domain-boundary-violation"
2482
+ ), u = t.projects.filter(
2483
+ (m) => !!m.ownership?.team || (m.ownership?.contacts?.length ?? 0) > 0
2484
+ ).length, w = t.projects.filter((m) => {
2485
+ const x = m.metadata.documentation;
2486
+ return x === !0 || x === "true";
2487
+ }).length;
2488
+ return [
2489
+ D(
2490
+ "architectural-entropy",
2491
+ "Architectural Entropy",
2492
+ "architecture",
2493
+ d / Math.max(a, 1)
2494
+ ),
2495
+ D(
2496
+ "dependency-complexity",
2497
+ "Dependency Complexity",
2498
+ "architecture",
2499
+ a / r / 4
2500
+ ),
2501
+ D(
2502
+ "domain-integrity",
2503
+ "Domain Integrity",
2504
+ "boundaries",
2505
+ l / Math.max(a, 1)
2506
+ ),
2507
+ D(
2508
+ "ownership-coverage",
2509
+ "Ownership Coverage",
2510
+ "ownership",
2511
+ u / r,
2512
+ !0
2513
+ ),
2514
+ D(
2515
+ "documentation-completeness",
2516
+ "Documentation Completeness",
2517
+ "documentation",
2518
+ w / r,
2519
+ !0
2520
+ ),
2521
+ D(
2522
+ "layer-integrity",
2523
+ "Layer Integrity",
2524
+ "boundaries",
2525
+ c / Math.max(a, 1)
2526
+ )
2527
+ ];
2528
+ }
2529
+ const Ar = ct;
2530
+ function D(e, t, n, o, r = !1) {
2531
+ const i = Math.max(0, Math.min(1, o)), s = Number(i.toFixed(4)), a = Math.round(r ? s * 100 : (1 - s) * 100);
2532
+ return {
2533
+ id: e,
2534
+ name: t,
2535
+ family: n,
2536
+ value: s,
2537
+ score: a,
2538
+ maxScore: 100,
2539
+ unit: "ratio"
411
2540
  };
412
2541
  }
413
- const w = {
2542
+ function ro(e) {
2543
+ const t = /* @__PURE__ */ new Map();
2544
+ for (const n of e) {
2545
+ const o = t.get(n.type) ?? {
2546
+ type: n.type,
2547
+ count: 0,
2548
+ weight: 0
2549
+ };
2550
+ o.count += 1, o.weight += ao(n.severity), t.set(n.type, o);
2551
+ }
2552
+ return [...t.values()];
2553
+ }
2554
+ function io(e, t) {
2555
+ return e.filter(t).reduce((n, o) => n + o.count, 0);
2556
+ }
2557
+ function ce(e, t) {
2558
+ return e.filter(t).reduce((n, o) => n + o.weight, 0);
2559
+ }
2560
+ function so(e) {
2561
+ return e.type === "cross-domain-dependency" || e.type === "missing-domain-context" || e.type === "circular-dependency";
2562
+ }
2563
+ function ao(e) {
2564
+ switch (e) {
2565
+ case "error":
2566
+ return 1;
2567
+ case "warning":
2568
+ return 0.6;
2569
+ default:
2570
+ return 0.25;
2571
+ }
2572
+ }
2573
+ const O = {
414
2574
  id: "domain-boundary",
415
2575
  name: "Domain Boundary",
416
2576
  description: "Enforces allowed dependencies between projects in different domains.",
417
2577
  category: "boundary",
418
2578
  defaultSeverity: "error",
419
- evaluate({ workspace: e, profile: n }) {
420
- if (!n)
2579
+ evaluate({ workspace: e, profile: t }) {
2580
+ if (!t)
421
2581
  return {};
422
- const o = m(n).rules[w.id];
2582
+ const o = j(t).rules[O.id];
423
2583
  if (o?.enabled === !1)
424
2584
  return {};
425
- const r = o?.options, i = o?.severity ?? w.defaultSeverity, a = L(e.projects);
426
- return { violations: e.dependencies.flatMap((s) => {
427
- const l = a.get(s.source), u = a.get(s.target);
428
- return Q(
2585
+ const r = o?.options, i = o?.severity ?? O.defaultSeverity, s = ye(e.projects);
2586
+ return { violations: e.dependencies.flatMap((d) => {
2587
+ const c = s.get(d.source), l = s.get(d.target);
2588
+ return lt(
2589
+ c,
429
2590
  l,
430
- u,
431
- s,
2591
+ d,
432
2592
  r ?? {
433
- allowedDependencies: n.allowedDomainDependencies
2593
+ allowedDependencies: t.allowedDomainDependencies
434
2594
  },
435
2595
  i
436
2596
  );
437
2597
  }) };
438
2598
  }
439
- }, I = {
2599
+ }, V = {
440
2600
  id: "layer-boundary",
441
2601
  name: "Layer Boundary",
442
2602
  description: "Enforces allowed dependencies between declared architectural layers.",
443
2603
  category: "boundary",
444
2604
  defaultSeverity: "warning",
445
- evaluate({ workspace: e, profile: n }) {
446
- if (!n)
2605
+ evaluate({ workspace: e, profile: t }) {
2606
+ if (!t)
447
2607
  return {};
448
- const o = m(n).rules[I.id];
2608
+ const o = j(t).rules[V.id];
449
2609
  if (o?.enabled === !1)
450
2610
  return {};
451
2611
  const i = o?.options ?? {
452
- allowedDependencies: n.allowedLayerDependencies ?? z(n.layers),
453
- layers: [...n.layers],
454
- usesExplicitDependencies: n.allowedLayerDependencies !== void 0
455
- }, a = o?.severity ?? I.defaultSeverity, c = L(e.projects), s = new Set(i.layers);
456
- return { violations: e.dependencies.flatMap((u) => {
457
- const y = c.get(u.source), g = c.get(u.target);
458
- return X(
459
- y,
460
- g,
2612
+ allowedDependencies: t.allowedLayerDependencies ?? ge(t.layers),
2613
+ layers: [...t.layers],
2614
+ usesExplicitDependencies: t.allowedLayerDependencies !== void 0
2615
+ }, s = o?.severity ?? V.defaultSeverity, a = ye(e.projects), d = new Set(i.layers);
2616
+ return { violations: e.dependencies.flatMap((l) => {
2617
+ const u = a.get(l.source), w = a.get(l.target);
2618
+ return ut(
461
2619
  u,
462
- s,
2620
+ w,
2621
+ l,
2622
+ d,
463
2623
  i,
464
- a
2624
+ s
465
2625
  );
466
2626
  }) };
467
2627
  }
468
- }, P = {
2628
+ }, A = {
469
2629
  id: "ownership-presence",
470
2630
  name: "Ownership Presence",
471
2631
  description: "Requires ownership metadata or CODEOWNERS coverage when profiles demand it.",
472
2632
  category: "ownership",
473
2633
  defaultSeverity: "warning",
474
- evaluate({ workspace: e, profile: n }) {
475
- if (!n)
2634
+ evaluate({ workspace: e, profile: t }) {
2635
+ if (!t)
476
2636
  return {};
477
- const o = m(n).rules[P.id];
2637
+ const o = j(t).rules[A.id];
478
2638
  if (o?.enabled === !1)
479
2639
  return {};
480
2640
  const i = o?.options ?? {
481
- required: n.ownership.required,
482
- metadataField: n.ownership.metadataField
483
- }, a = o?.severity ?? P.defaultSeverity;
2641
+ required: t.ownership.required,
2642
+ metadataField: t.ownership.metadataField
2643
+ }, s = o?.severity ?? A.defaultSeverity;
484
2644
  return i.required ? { violations: e.projects.flatMap(
485
- (s) => Z(s, a)
2645
+ (d) => pt(d, s)
486
2646
  ) } : {};
487
2647
  }
488
- }, j = {
2648
+ }, U = {
489
2649
  id: "project-name-convention",
490
2650
  name: "Project Name Convention",
491
2651
  description: "Validates project names against an explicitly configured regular expression.",
492
2652
  category: "convention",
493
2653
  defaultSeverity: "warning",
494
- evaluate({ workspace: e, profile: n }) {
495
- if (!n)
2654
+ evaluate({ workspace: e, profile: t }) {
2655
+ if (!t)
496
2656
  return {};
497
- const o = m(n).rules[j.id], r = o?.options;
2657
+ const o = j(t).rules[U.id], r = o?.options;
498
2658
  if (!o?.enabled || !r?.pattern)
499
2659
  return {};
500
- const i = new RegExp(r.pattern), a = o.severity ?? j.defaultSeverity;
2660
+ const i = new RegExp(r.pattern), s = o.severity ?? U.defaultSeverity;
501
2661
  return {
502
2662
  violations: e.projects.flatMap(
503
- (c) => ke(c, r, i, a)
2663
+ (a) => uo(a, r, i, s)
504
2664
  )
505
2665
  };
506
2666
  }
507
- }, E = {
2667
+ }, K = {
508
2668
  id: "tag-convention",
509
2669
  name: "Tag Convention",
510
2670
  description: "Validates required and allowed generic tag prefixes and tag value patterns.",
511
2671
  category: "metadata",
512
2672
  defaultSeverity: "warning",
513
- evaluate({ workspace: e, profile: n }) {
514
- if (!n)
2673
+ evaluate({ workspace: e, profile: t }) {
2674
+ if (!t)
515
2675
  return {};
516
- const o = m(n).rules[E.id], r = o?.options;
517
- if (!o?.enabled || !r || !Be(r))
2676
+ const o = j(t).rules[K.id], r = o?.options;
2677
+ if (!o?.enabled || !r || !vo(r))
518
2678
  return {};
519
- const i = o.severity ?? E.defaultSeverity, a = r.valuePattern ? new RegExp(r.valuePattern) : void 0;
2679
+ const i = o.severity ?? K.defaultSeverity, s = r.valuePattern ? new RegExp(r.valuePattern) : void 0;
520
2680
  return {
521
2681
  violations: e.projects.flatMap(
522
- (c) => xe(c, r, a, i)
2682
+ (a) => po(a, r, s, i)
523
2683
  )
524
2684
  };
525
2685
  }
526
- }, k = {
2686
+ }, Y = {
527
2687
  id: "missing-domain",
528
2688
  name: "Missing Domain",
529
2689
  description: "Requires a domain on projects when explicitly configured.",
530
2690
  category: "metadata",
531
2691
  defaultSeverity: "warning",
532
- evaluate({ workspace: e, profile: n }) {
533
- if (!n)
2692
+ evaluate({ workspace: e, profile: t }) {
2693
+ if (!t)
534
2694
  return {};
535
- const o = m(n).rules[k.id], r = o?.options;
2695
+ const o = j(t).rules[Y.id], r = o?.options;
536
2696
  if (!o?.enabled || !r?.required)
537
2697
  return {};
538
- const i = o.severity ?? k.defaultSeverity;
2698
+ const i = o.severity ?? Y.defaultSeverity;
539
2699
  return {
540
2700
  violations: e.projects.flatMap(
541
- (a) => Re(a, i)
2701
+ (s) => mo(s, i)
542
2702
  )
543
2703
  };
544
2704
  }
545
- }, x = {
2705
+ }, J = {
546
2706
  id: "missing-layer",
547
2707
  name: "Missing Layer",
548
2708
  description: "Requires a layer on projects when explicitly configured.",
549
2709
  category: "metadata",
550
2710
  defaultSeverity: "warning",
551
- evaluate({ workspace: e, profile: n }) {
552
- if (!n)
2711
+ evaluate({ workspace: e, profile: t }) {
2712
+ if (!t)
553
2713
  return {};
554
- const o = m(n).rules[x.id], r = o?.options;
2714
+ const o = j(t).rules[J.id], r = o?.options;
555
2715
  if (!o?.enabled || !r?.required)
556
2716
  return {};
557
- const i = o.severity ?? x.defaultSeverity;
2717
+ const i = o.severity ?? J.defaultSeverity;
558
2718
  return {
559
2719
  violations: e.projects.flatMap(
560
- (a) => Me(a, i)
2720
+ (s) => fo(s, i)
561
2721
  )
562
2722
  };
563
2723
  }
564
- }, Ee = [
565
- w,
566
- I,
567
- P,
568
- j,
569
- E,
570
- k,
571
- x
2724
+ }, co = [
2725
+ O,
2726
+ V,
2727
+ A,
2728
+ U,
2729
+ K,
2730
+ Y,
2731
+ J
572
2732
  ];
573
- function Sn(e) {
2733
+ function ze(e) {
574
2734
  if (!e.profile)
575
2735
  return [];
576
- const { workspace: n, profile: t } = e, o = m(t), r = o.rules[w.id], i = r?.enabled !== !1, a = r?.options ?? {
577
- allowedDependencies: t.allowedDomainDependencies
578
- }, c = r?.severity ?? w.defaultSeverity, s = o.rules[I.id], l = s?.enabled !== !1, u = s?.options ?? {
579
- allowedDependencies: t.allowedLayerDependencies ?? z(t.layers),
580
- layers: [...t.layers],
581
- usesExplicitDependencies: t.allowedLayerDependencies !== void 0
582
- }, y = s?.severity ?? I.defaultSeverity, g = o.rules[P.id], te = g?.enabled !== !1, re = g?.options ?? {
583
- required: t.ownership.required,
584
- metadataField: t.ownership.metadataField
585
- }, oe = g?.severity ?? P.defaultSeverity, G = L(n.projects), ie = new Set(u.layers), h = [];
586
- for (const f of n.dependencies) {
587
- const F = G.get(f.source), _ = G.get(f.target);
588
- i && h.push(
589
- ...Q(
590
- F,
591
- _,
592
- f,
593
- a,
594
- c
2736
+ const { workspace: t, profile: n } = e, o = j(n), r = o.rules[O.id], i = r?.enabled !== !1, s = r?.options ?? {
2737
+ allowedDependencies: n.allowedDomainDependencies
2738
+ }, a = r?.severity ?? O.defaultSeverity, d = o.rules[V.id], c = d?.enabled !== !1, l = d?.options ?? {
2739
+ allowedDependencies: n.allowedLayerDependencies ?? ge(n.layers),
2740
+ layers: [...n.layers],
2741
+ usesExplicitDependencies: n.allowedLayerDependencies !== void 0
2742
+ }, u = d?.severity ?? V.defaultSeverity, w = o.rules[A.id], m = w?.enabled !== !1, x = w?.options ?? {
2743
+ required: n.ownership.required,
2744
+ metadataField: n.ownership.metadataField
2745
+ }, z = w?.severity ?? A.defaultSeverity, T = ye(t.projects), b = new Set(l.layers), S = [];
2746
+ for (const y of t.dependencies) {
2747
+ const C = T.get(y.source), L = T.get(y.target);
2748
+ i && S.push(
2749
+ ...lt(
2750
+ C,
2751
+ L,
2752
+ y,
2753
+ s,
2754
+ a
595
2755
  )
596
- ), l && h.push(
597
- ...X(
598
- F,
599
- _,
600
- f,
601
- ie,
602
- u,
603
- y
2756
+ ), c && S.push(
2757
+ ...ut(
2758
+ C,
2759
+ L,
2760
+ y,
2761
+ b,
2762
+ l,
2763
+ u
604
2764
  )
605
2765
  );
606
2766
  }
607
- if (te && re.required)
608
- for (const f of n.projects)
609
- h.push(...Z(f, oe));
610
- for (const f of [
611
- j,
612
- E,
613
- k,
614
- x
2767
+ if (m && x.required)
2768
+ for (const y of t.projects)
2769
+ S.push(...pt(y, z));
2770
+ for (const y of [
2771
+ U,
2772
+ K,
2773
+ Y,
2774
+ J
615
2775
  ])
616
- h.push(...Ce(f, e));
617
- return h;
2776
+ S.push(...go(y, e));
2777
+ return S;
2778
+ }
2779
+ function dt(e, t) {
2780
+ return lo(e) ? ze(e) : ze({
2781
+ workspace: e,
2782
+ profile: t
2783
+ });
618
2784
  }
619
- function Q(e, n, t, o, r) {
620
- return !e || !n ? [] : !e.domain || !n.domain || e.domain === n.domain || $e(
2785
+ const Fr = dt;
2786
+ function lo(e) {
2787
+ return "workspace" in e;
2788
+ }
2789
+ function lt(e, t, n, o, r) {
2790
+ return !e || !t ? [] : !e.domain || !t.domain || e.domain === t.domain || yo(
621
2791
  o.allowedDependencies,
622
2792
  e.domain,
623
- n.domain
2793
+ t.domain
624
2794
  ) ? [] : [
625
2795
  {
626
- id: `${e.name}-${n.name}-domain`,
2796
+ id: `${e.name}-${t.name}-domain`,
627
2797
  ruleId: "domain-boundary",
628
2798
  project: e.name,
629
2799
  severity: r,
630
2800
  category: "boundary",
631
- message: `Project ${e.name} in domain ${e.domain} depends on ${n.name} in domain ${n.domain}.`,
2801
+ message: `Project ${e.name} in domain ${e.domain} depends on ${t.name} in domain ${t.domain}.`,
632
2802
  details: {
633
- targetProject: n.name,
2803
+ targetProject: t.name,
634
2804
  sourceDomain: e.domain,
635
- targetDomain: n.domain,
636
- dependencyType: t.type
2805
+ targetDomain: t.domain,
2806
+ dependencyType: n.type
637
2807
  },
638
2808
  recommendation: "Move the dependency behind an API or adjust domain boundaries in the governance profile."
639
2809
  }
640
2810
  ];
641
2811
  }
642
- function X(e, n, t, o, r, i) {
643
- return !e || !n ? [] : !e.layer || !n.layer || !o.has(e.layer) || !o.has(n.layer) || Oe(
2812
+ function ut(e, t, n, o, r, i) {
2813
+ return !e || !t ? [] : !e.layer || !t.layer || !o.has(e.layer) || !o.has(t.layer) || ho(
644
2814
  r.allowedDependencies,
645
2815
  e.layer,
646
- n.layer
2816
+ t.layer
647
2817
  ) ? [] : [
648
2818
  {
649
- id: `${e.name}-${n.name}-layer`,
2819
+ id: `${e.name}-${t.name}-layer`,
650
2820
  ruleId: "layer-boundary",
651
2821
  project: e.name,
652
2822
  severity: i,
653
2823
  category: "boundary",
654
- message: `Layer violation: ${e.name} (${e.layer}) depends on ${n.name} (${n.layer}).`,
2824
+ message: `Layer violation: ${e.name} (${e.layer}) depends on ${t.name} (${t.layer}).`,
655
2825
  details: {
656
- targetProject: n.name,
2826
+ targetProject: t.name,
657
2827
  sourceLayer: e.layer,
658
- targetLayer: n.layer,
2828
+ targetLayer: t.layer,
659
2829
  ...r.usesExplicitDependencies ? {
660
2830
  allowedTargets: r.allowedDependencies[e.layer] ?? []
661
2831
  } : {
@@ -666,642 +2836,843 @@ function X(e, n, t, o, r, i) {
666
2836
  }
667
2837
  ];
668
2838
  }
669
- function Z(e, n) {
2839
+ function pt(e, t) {
670
2840
  return e.ownership?.team || (e.ownership?.contacts?.length ?? 0) > 0 ? [] : [
671
2841
  {
672
2842
  id: `${e.name}-ownership`,
673
2843
  ruleId: "ownership-presence",
674
2844
  project: e.name,
675
- severity: n,
2845
+ severity: t,
676
2846
  category: "ownership",
677
2847
  message: `Project ${e.name} has no ownership metadata or CODEOWNERS mapping.`,
678
2848
  recommendation: "Add ownership metadata in project configuration or ensure CODEOWNERS covers the project root."
679
2849
  }
680
2850
  ];
681
2851
  }
682
- function ke(e, n, t, o) {
683
- return t.test(e.name) ? [] : [
2852
+ function uo(e, t, n, o) {
2853
+ return n.test(e.name) ? [] : [
684
2854
  {
685
2855
  id: `${e.name}-project-name-convention`,
686
2856
  ruleId: "project-name-convention",
687
2857
  project: e.name,
688
2858
  severity: o,
689
2859
  category: "convention",
690
- message: n.message ?? `Project ${e.name} does not match the configured naming convention.`,
2860
+ message: t.message ?? `Project ${e.name} does not match the configured naming convention.`,
691
2861
  details: {
692
2862
  projectName: e.name,
693
- pattern: n.pattern
2863
+ pattern: t.pattern
694
2864
  },
695
2865
  recommendation: "Rename the project or update the configured name pattern when the convention is intentional."
696
2866
  }
697
2867
  ];
698
2868
  }
699
- function xe(e, n, t, o) {
700
- const r = [], i = n.prefixSeparator ?? ":";
701
- for (const a of n.requiredPrefixes ?? [])
2869
+ function po(e, t, n, o) {
2870
+ const r = [], i = t.prefixSeparator ?? ":";
2871
+ for (const s of t.requiredPrefixes ?? [])
702
2872
  e.tags.some(
703
- (c) => c.startsWith(`${a}${i}`)
2873
+ (a) => a.startsWith(`${s}${i}`)
704
2874
  ) || r.push({
705
- id: `${e.name}-tag-convention-required-${a}`,
2875
+ id: `${e.name}-tag-convention-required-${s}`,
706
2876
  ruleId: "tag-convention",
707
2877
  project: e.name,
708
2878
  severity: o,
709
2879
  category: "metadata",
710
- message: `Project ${e.name} is missing a tag with required prefix ${a}.`,
2880
+ message: `Project ${e.name} is missing a tag with required prefix ${s}.`,
711
2881
  details: {
712
- requiredPrefix: a,
2882
+ requiredPrefix: s,
713
2883
  tags: e.tags
714
2884
  },
715
2885
  recommendation: "Add a tag with the required prefix or relax the configured requiredPrefixes list."
716
2886
  });
717
- for (const a of e.tags) {
718
- const { prefix: c, value: s } = Te(a, i);
719
- n.allowedPrefixes && n.allowedPrefixes.length > 0 && !n.allowedPrefixes.includes(c) && r.push({
720
- id: `${e.name}-tag-convention-allowed-${a}`,
2887
+ for (const s of e.tags) {
2888
+ const { prefix: a, value: d } = wo(s, i);
2889
+ t.allowedPrefixes && t.allowedPrefixes.length > 0 && !t.allowedPrefixes.includes(a) && r.push({
2890
+ id: `${e.name}-tag-convention-allowed-${s}`,
721
2891
  ruleId: "tag-convention",
722
2892
  project: e.name,
723
2893
  severity: o,
724
2894
  category: "metadata",
725
- message: `Project ${e.name} uses tag ${a} with disallowed prefix ${c}.`,
2895
+ message: `Project ${e.name} uses tag ${s} with disallowed prefix ${a}.`,
726
2896
  details: {
727
- tag: a,
728
- prefix: c,
729
- allowedPrefixes: n.allowedPrefixes
2897
+ tag: s,
2898
+ prefix: a,
2899
+ allowedPrefixes: t.allowedPrefixes
730
2900
  },
731
2901
  recommendation: "Rename the tag to use an allowed prefix or expand the allowedPrefixes rule configuration."
732
- }), t && !t.test(s) && r.push({
733
- id: `${e.name}-tag-convention-value-${a}`,
2902
+ }), n && !n.test(d) && r.push({
2903
+ id: `${e.name}-tag-convention-value-${s}`,
734
2904
  ruleId: "tag-convention",
735
2905
  project: e.name,
736
2906
  severity: o,
737
2907
  category: "metadata",
738
- message: `Project ${e.name} has tag ${a} with a value that does not match the configured pattern.`,
2908
+ message: `Project ${e.name} has tag ${s} with a value that does not match the configured pattern.`,
739
2909
  details: {
740
- tag: a,
741
- value: s,
742
- valuePattern: n.valuePattern
2910
+ tag: s,
2911
+ value: d,
2912
+ valuePattern: t.valuePattern
743
2913
  },
744
2914
  recommendation: "Normalize the tag value or update the configured valuePattern when the convention is intentional."
745
2915
  });
746
2916
  }
747
2917
  return r;
748
2918
  }
749
- function Re(e, n) {
2919
+ function mo(e, t) {
750
2920
  return e.domain ? [] : [
751
2921
  {
752
2922
  id: `${e.name}-missing-domain`,
753
2923
  ruleId: "missing-domain",
754
2924
  project: e.name,
755
- severity: n,
2925
+ severity: t,
756
2926
  category: "metadata",
757
2927
  message: `Project ${e.name} is missing domain metadata.`,
758
2928
  recommendation: "Populate the project domain through adapter normalization, metadata, or project overrides."
759
2929
  }
760
2930
  ];
761
2931
  }
762
- function Me(e, n) {
2932
+ function fo(e, t) {
763
2933
  return e.layer ? [] : [
764
2934
  {
765
2935
  id: `${e.name}-missing-layer`,
766
2936
  ruleId: "missing-layer",
767
2937
  project: e.name,
768
- severity: n,
2938
+ severity: t,
769
2939
  category: "metadata",
770
2940
  message: `Project ${e.name} is missing layer metadata.`,
771
2941
  recommendation: "Populate the project layer through adapter normalization, metadata, or project overrides."
772
2942
  }
773
2943
  ];
774
2944
  }
775
- function Ce(e, n) {
776
- return e.evaluate(n).violations ?? [];
2945
+ function go(e, t) {
2946
+ return e.evaluate(t).violations ?? [];
777
2947
  }
778
- function L(e) {
779
- return new Map(e.map((n) => [n.name, n]));
2948
+ function ye(e) {
2949
+ return new Map(e.map((t) => [t.name, t]));
780
2950
  }
781
- function $e(e, n, t) {
782
- const o = e[n];
783
- if (o && (o.includes(t) || o.includes("*")))
2951
+ function yo(e, t, n) {
2952
+ const o = e[t];
2953
+ if (o && (o.includes(n) || o.includes("*")))
784
2954
  return !0;
785
2955
  const r = e["*"];
786
- return !!(r && (r.includes(t) || r.includes("*")));
2956
+ return !!(r && (r.includes(n) || r.includes("*")));
787
2957
  }
788
- function Oe(e, n, t) {
789
- return (e[n] ?? []).includes(t);
2958
+ function ho(e, t, n) {
2959
+ return (e[t] ?? []).includes(n);
790
2960
  }
791
- function Be(e) {
2961
+ function vo(e) {
792
2962
  return (e.requiredPrefixes?.length ?? 0) > 0 || (e.allowedPrefixes?.length ?? 0) > 0 || typeof e.valuePattern == "string";
793
2963
  }
794
- function Te(e, n) {
795
- const t = e.indexOf(n);
796
- return t === -1 ? {
2964
+ function wo(e, t) {
2965
+ const n = e.indexOf(t);
2966
+ return n === -1 ? {
797
2967
  prefix: e,
798
2968
  value: e
799
2969
  } : {
800
- prefix: e.slice(0, t),
801
- value: e.slice(t + n.length)
802
- };
803
- }
804
- const ze = "core", Le = {
805
- id: ze,
806
- name: "Governance Core Built-in Rules",
807
- rules: Ee
808
- }, bn = [Le], Ge = [
809
- "graph",
810
- "conformance",
811
- "policy"
812
- ], Fe = ["info", "warning", "error"], _e = [
813
- "structural-dependency",
814
- "cross-domain-dependency",
815
- "missing-domain-context",
816
- "circular-dependency",
817
- "conformance-violation",
818
- "domain-boundary-violation",
819
- "layer-boundary-violation",
820
- "ownership-gap"
821
- ], Ae = [
822
- "architecture",
823
- "boundaries",
824
- "ownership",
825
- "documentation"
826
- ];
827
- function Dn(e, n) {
828
- return {
829
- baseline: e,
830
- current: n,
831
- metricDeltas: N(e.metrics, n.metrics),
832
- scoreDeltas: N(e.scores, n.scores),
833
- newViolations: n.violations.filter(
834
- (t) => !K(e.violations, t)
835
- ),
836
- resolvedViolations: e.violations.filter(
837
- (t) => !K(n.violations, t)
838
- ),
839
- healthDelta: qe(e, n),
840
- signalDeltas: Ve(e, n),
841
- metricFamilyDeltas: Ne(e, n),
842
- topIssueDeltas: He(e, n),
843
- deliveryImpactIndexDeltas: Ue(e, n)
2970
+ prefix: e.slice(0, n),
2971
+ value: e.slice(n + t.length)
844
2972
  };
845
2973
  }
846
- function jn(e, n = 0.02) {
847
- const t = [], o = e.scoreDeltas.find(
848
- (r) => r.id === "workspaceHealth"
849
- );
850
- o && t.push(
851
- C(
852
- "workspaceHealth",
853
- "workspace-health",
854
- "Workspace Health",
855
- o,
856
- n,
857
- e.healthDelta ? {
858
- baselineStatus: e.healthDelta.baselineStatus,
859
- currentStatus: e.healthDelta.currentStatus,
860
- baselineGrade: e.healthDelta.baselineGrade,
861
- currentGrade: e.healthDelta.currentGrade
862
- } : void 0
863
- )
864
- );
865
- for (const r of e.scoreDeltas)
866
- r.id !== "workspaceHealth" && t.push(
867
- C(
868
- r.id,
869
- "metric-score",
870
- Xe(r.id),
871
- r,
872
- n
873
- )
874
- );
875
- for (const r of e.metricFamilyDeltas ?? [])
876
- t.push(
877
- C(
878
- `metric-family:${r.family}`,
879
- "metric-family",
880
- `Metric Family: ${Ze(r.family)}`,
881
- r,
882
- n
883
- )
884
- );
885
- for (const r of e.signalDeltas?.bySource ?? [])
886
- t.push(
887
- D(
888
- `signal-source:${r.source}`,
889
- "signal-source",
890
- `Signal Source: ${r.source}`,
891
- r
892
- )
893
- );
894
- for (const r of e.signalDeltas?.byType ?? [])
895
- t.push(
896
- D(
897
- `signal-type:${r.type}`,
898
- "signal-type",
899
- `Signal Type: ${en(r.type)}`,
900
- r
901
- )
902
- );
903
- for (const r of e.signalDeltas?.bySeverity ?? [])
904
- t.push(
905
- D(
906
- `signal-severity:${r.severity}`,
907
- "signal-severity",
908
- `Signal Severity: ${r.severity}`,
909
- r
910
- )
911
- );
912
- for (const r of e.topIssueDeltas ?? [])
913
- t.push(
914
- D(
915
- Ke(r),
916
- "top-issue",
917
- `Top Issue: ${r.message}`,
918
- {
919
- baseline: r.baselineCount,
920
- current: r.currentCount,
921
- delta: r.delta
2974
+ const Io = "signal-", Te = {
2975
+ graph: 0,
2976
+ conformance: 1,
2977
+ policy: 2,
2978
+ extension: 3
2979
+ }, Le = {
2980
+ info: 0,
2981
+ warning: 1,
2982
+ error: 2
2983
+ };
2984
+ function mt(e) {
2985
+ const t = new Map(
2986
+ e.projects.map((o) => [o.id, o])
2987
+ ), n = [];
2988
+ for (const o of e.dependencies) {
2989
+ const r = t.get(o.sourceProjectId), i = t.get(o.targetProjectId), s = P(r?.domain), a = P(i?.domain), d = Q([
2990
+ o.sourceProjectId,
2991
+ o.targetProjectId
2992
+ ]);
2993
+ n.push(
2994
+ E({
2995
+ type: "structural-dependency",
2996
+ sourceProjectId: o.sourceProjectId,
2997
+ targetProjectId: o.targetProjectId,
2998
+ relatedProjectIds: d,
2999
+ severity: "info",
3000
+ category: "dependency",
3001
+ message: `Dependency: ${o.sourceProjectId} -> ${o.targetProjectId}.`,
3002
+ metadata: {
3003
+ dependencyType: o.type
922
3004
  },
923
- {
924
- type: r.type,
925
- source: r.source,
926
- severity: r.severity,
927
- ruleId: r.ruleId,
928
- projects: r.projects
929
- }
930
- )
3005
+ source: "graph",
3006
+ createdAt: e.extractedAt
3007
+ })
3008
+ ), s && a && s !== a ? n.push(
3009
+ E({
3010
+ type: "cross-domain-dependency",
3011
+ sourceProjectId: o.sourceProjectId,
3012
+ targetProjectId: o.targetProjectId,
3013
+ relatedProjectIds: d,
3014
+ severity: "warning",
3015
+ category: "boundary",
3016
+ message: `Cross-domain dependency: ${o.sourceProjectId} (${s}) -> ${o.targetProjectId} (${a}).`,
3017
+ metadata: {
3018
+ sourceDomain: s,
3019
+ targetDomain: a
3020
+ },
3021
+ source: "graph",
3022
+ createdAt: e.extractedAt
3023
+ })
3024
+ ) : (!s || !a) && n.push(
3025
+ E({
3026
+ type: "missing-domain-context",
3027
+ sourceProjectId: o.sourceProjectId,
3028
+ targetProjectId: o.targetProjectId,
3029
+ relatedProjectIds: d,
3030
+ severity: "warning",
3031
+ category: "boundary",
3032
+ message: `Missing domain context for dependency: ${o.sourceProjectId} -> ${o.targetProjectId}.`,
3033
+ metadata: {
3034
+ sourceDomain: s,
3035
+ targetDomain: a,
3036
+ missingSourceDomain: !s,
3037
+ missingTargetDomain: !a
3038
+ },
3039
+ source: "graph",
3040
+ createdAt: e.extractedAt
3041
+ })
931
3042
  );
932
- return t.push({
933
- id: "violation-footprint",
934
- kind: "violation-footprint",
935
- label: "Violation Footprint",
936
- status: ee(
937
- e.newViolations.length - e.resolvedViolations.length
938
- ),
939
- magnitude: Math.abs(
940
- e.newViolations.length - e.resolvedViolations.length
941
- ),
942
- baseline: e.baseline.violations.length,
943
- current: e.current.violations.length,
944
- delta: p(
945
- e.current.violations.length - e.baseline.violations.length
946
- ),
947
- details: {
948
- newViolations: e.newViolations.length,
949
- resolvedViolations: e.resolvedViolations.length
950
- }
951
- }), t.sort(Je);
3043
+ }
3044
+ return n.sort(ee);
3045
+ }
3046
+ function ft(e) {
3047
+ return e.findings.map(
3048
+ (t) => So(t, e.extractedAt)
3049
+ ).sort(ee);
3050
+ }
3051
+ function gt(e, t = {}) {
3052
+ const n = t.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
3053
+ return e.flatMap((o) => Po(o, n)).sort(ee);
3054
+ }
3055
+ function zr(e) {
3056
+ return ue(
3057
+ mt(e.graphSnapshot),
3058
+ e.conformanceSnapshot ? ft(e.conformanceSnapshot) : [],
3059
+ e.policyViolations ? gt(e.policyViolations, {
3060
+ createdAt: e.graphSnapshot.extractedAt
3061
+ }) : []
3062
+ );
952
3063
  }
953
- function En(e) {
954
- const n = e.filter((r) => r.status === "worsening").sort(Y), t = e.filter((r) => r.status === "improving").sort(Y), o = e.filter(
955
- (r) => r.status === "stable"
956
- ).length;
3064
+ function ue(...e) {
3065
+ const t = /* @__PURE__ */ new Map();
3066
+ for (const n of e.flat())
3067
+ t.has(n.id) || t.set(n.id, n);
3068
+ return [...t.values()].sort(ee);
3069
+ }
3070
+ function So(e, t) {
3071
+ const n = Q(
3072
+ e.relatedProjectIds
3073
+ ), o = n.length === 1 ? n[0] : void 0;
3074
+ return E({
3075
+ type: "conformance-violation",
3076
+ sourceProjectId: e.projectId,
3077
+ targetProjectId: o,
3078
+ relatedProjectIds: n,
3079
+ severity: e.severity,
3080
+ category: e.category,
3081
+ message: e.message,
3082
+ metadata: {
3083
+ ...e.ruleId ? { ruleId: e.ruleId } : {},
3084
+ ...e.metadata ? e.metadata : {}
3085
+ },
3086
+ source: "conformance",
3087
+ createdAt: t
3088
+ });
3089
+ }
3090
+ function Po(e, t) {
3091
+ const n = jo(e.ruleId);
3092
+ if (!n)
3093
+ return [];
3094
+ const o = Do(e.details), r = P(
3095
+ ko(o?.targetProject ?? o?.target)
3096
+ ), i = P(e.project), s = Q([
3097
+ i,
3098
+ r
3099
+ ]);
3100
+ return [
3101
+ E({
3102
+ type: n.type,
3103
+ sourceProjectId: i,
3104
+ targetProjectId: r,
3105
+ relatedProjectIds: s,
3106
+ severity: e.severity,
3107
+ category: n.category,
3108
+ message: e.message,
3109
+ metadata: {
3110
+ ruleId: e.ruleId,
3111
+ ...o ?? {},
3112
+ ...e.recommendation ? { recommendation: e.recommendation } : {}
3113
+ },
3114
+ source: "policy",
3115
+ sourcePluginId: e.sourcePluginId,
3116
+ createdAt: t,
3117
+ identityKey: [
3118
+ e.ruleId,
3119
+ i ?? "",
3120
+ r ?? "",
3121
+ e.message
3122
+ ].join("|")
3123
+ })
3124
+ ];
3125
+ }
3126
+ function jo(e) {
3127
+ switch (e) {
3128
+ case "domain-boundary":
3129
+ return {
3130
+ type: "domain-boundary-violation",
3131
+ category: "boundary"
3132
+ };
3133
+ case "layer-boundary":
3134
+ return {
3135
+ type: "layer-boundary-violation",
3136
+ category: "boundary"
3137
+ };
3138
+ case "ownership-presence":
3139
+ return {
3140
+ type: "ownership-gap",
3141
+ category: "ownership"
3142
+ };
3143
+ default:
3144
+ return null;
3145
+ }
3146
+ }
3147
+ function E(e) {
3148
+ const t = Q(e.relatedProjectIds), n = {
3149
+ type: e.type,
3150
+ sourceProjectId: P(e.sourceProjectId),
3151
+ targetProjectId: P(e.targetProjectId),
3152
+ relatedProjectIds: t,
3153
+ severity: e.severity,
3154
+ category: e.category,
3155
+ message: e.message,
3156
+ metadata: xo(e.metadata),
3157
+ source: e.source,
3158
+ sourcePluginId: P(e.sourcePluginId),
3159
+ createdAt: Co(e.createdAt)
3160
+ };
957
3161
  return {
958
- overallTrend: n.length > t.length ? "worsening" : t.length > n.length ? "improving" : "stable",
959
- worseningCount: n.length,
960
- improvingCount: t.length,
961
- stableCount: o,
962
- topWorsening: n.slice(0, 5),
963
- topImproving: t.slice(0, 5)
3162
+ id: `${Io}${bo(e.identityKey ?? n)}`,
3163
+ type: n.type,
3164
+ ...n.sourceProjectId ? { sourceProjectId: n.sourceProjectId } : {},
3165
+ ...n.targetProjectId ? { targetProjectId: n.targetProjectId } : {},
3166
+ relatedProjectIds: n.relatedProjectIds,
3167
+ severity: n.severity,
3168
+ category: n.category,
3169
+ message: n.message,
3170
+ ...n.metadata ? { metadata: n.metadata } : {},
3171
+ source: n.source,
3172
+ ...n.sourcePluginId ? { sourcePluginId: n.sourcePluginId } : {},
3173
+ createdAt: n.createdAt
964
3174
  };
965
3175
  }
966
- function N(e, n) {
967
- return [.../* @__PURE__ */ new Set([...Object.keys(e), ...Object.keys(n)])].sort((o, r) => o.localeCompare(r)).map((o) => {
968
- const r = e[o] ?? 0, i = n[o] ?? 0;
969
- return {
970
- id: o,
971
- baseline: r,
972
- current: i,
973
- delta: p(i - r)
974
- };
975
- });
976
- }
977
- function qe(e, n) {
978
- if (!(!e.health || !n.health))
979
- return {
980
- baselineScore: e.health.score,
981
- currentScore: n.health.score,
982
- scoreDelta: p(n.health.score - e.health.score),
983
- baselineStatus: e.health.status,
984
- currentStatus: n.health.status,
985
- baselineGrade: e.health.grade,
986
- currentGrade: n.health.grade
987
- };
3176
+ function bo(e) {
3177
+ return St("sha256").update(JSON.stringify(e)).digest("hex").slice(0, 12);
988
3178
  }
989
- function Ve(e, n) {
990
- if (!(!e.signalBreakdown || !n.signalBreakdown))
991
- return {
992
- bySource: Ge.map(
993
- (t) => We(
994
- t,
995
- H(e, t),
996
- H(n, t)
997
- )
998
- ),
999
- byType: _e.flatMap((t) => {
1000
- const o = U(e, t), r = U(n, t);
1001
- return o === 0 && r === 0 ? [] : [
1002
- {
1003
- type: t,
1004
- baseline: o,
1005
- current: r,
1006
- delta: p(r - o)
1007
- }
1008
- ];
1009
- }),
1010
- bySeverity: Fe.map(
1011
- (t) => Ye(
1012
- t,
1013
- W(e, t),
1014
- W(n, t)
1015
- )
1016
- )
1017
- };
3179
+ function Co(e) {
3180
+ const t = Date.parse(e);
3181
+ return Number.isFinite(t) ? new Date(t).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
1018
3182
  }
1019
- function Ne(e, n) {
1020
- if (!e.metricBreakdown || !n.metricBreakdown)
3183
+ function xo(e) {
3184
+ if (!e)
1021
3185
  return;
1022
- const t = new Map(
1023
- e.metricBreakdown.families.map((r) => [
1024
- r.family,
1025
- r.score
1026
- ])
1027
- ), o = new Map(
1028
- n.metricBreakdown.families.map((r) => [
1029
- r.family,
1030
- r.score
1031
- ])
1032
- );
1033
- return Ae.flatMap((r) => {
1034
- const i = t.get(r), a = o.get(r);
1035
- return i === void 0 || a === void 0 ? [] : [
1036
- {
1037
- family: r,
1038
- baseline: i,
1039
- current: a,
1040
- delta: p(a - i)
1041
- }
1042
- ];
1043
- });
3186
+ const t = Object.entries(e).filter(([, n]) => n !== void 0).sort(([n], [o]) => n.localeCompare(o));
3187
+ return t.length > 0 ? Object.fromEntries(t) : void 0;
1044
3188
  }
1045
- function He(e, n) {
1046
- if (!e.topIssues || !n.topIssues)
1047
- return;
1048
- const t = new Map(
1049
- e.topIssues.map((i) => [T(i), i])
1050
- ), o = new Map(
1051
- n.topIssues.map((i) => [T(i), i])
3189
+ function Q(e) {
3190
+ return [...new Set(e.map(P).filter($o))].sort(
3191
+ (t, n) => t.localeCompare(n)
1052
3192
  );
1053
- return [.../* @__PURE__ */ new Set([...t.keys(), ...o.keys()])].sort((i, a) => i.localeCompare(a)).map((i) => {
1054
- const a = t.get(i), c = o.get(i), s = c ?? a;
1055
- if (!s)
1056
- throw new Error(`Unable to resolve top issue delta for key "${i}".`);
1057
- const l = [
1058
- .../* @__PURE__ */ new Set([...a?.projects ?? [], ...c?.projects ?? []])
1059
- ].sort((u, y) => u.localeCompare(y));
1060
- return {
1061
- type: s.type,
1062
- source: s.source,
1063
- severity: s.severity,
1064
- ruleId: s.ruleId,
1065
- message: s.message,
1066
- baselineCount: a?.count ?? 0,
1067
- currentCount: c?.count ?? 0,
1068
- delta: p((c?.count ?? 0) - (a?.count ?? 0)),
1069
- projects: l
1070
- };
1071
- });
1072
3193
  }
1073
- function Ue(e, n) {
1074
- const t = new Map(
1075
- (e.deliveryImpact?.indices ?? []).map((i) => [i.id, i])
1076
- ), o = new Map(
1077
- (n.deliveryImpact?.indices ?? []).map((i) => [i.id, i])
1078
- ), r = [...t.keys()].filter((i) => o.has(i)).sort((i, a) => i.localeCompare(a));
1079
- if (r.length !== 0)
1080
- return r.map((i) => {
1081
- const a = t.get(i), c = o.get(i);
1082
- return {
1083
- id: i,
1084
- baselineScore: a.score,
1085
- currentScore: c.score,
1086
- scoreDelta: p(c.score - a.score),
1087
- baselineRisk: a.risk,
1088
- currentRisk: c.risk
1089
- };
1090
- });
3194
+ function P(e) {
3195
+ if (typeof e != "string")
3196
+ return;
3197
+ const t = e.trim();
3198
+ return t.length > 0 ? t : void 0;
1091
3199
  }
1092
- function C(e, n, t, o, r, i) {
1093
- return {
1094
- id: e,
1095
- kind: n,
1096
- label: t,
1097
- status: Qe(o.delta, r),
1098
- magnitude: Math.abs(o.delta),
1099
- baseline: o.baseline,
1100
- current: o.current,
1101
- delta: o.delta,
1102
- details: i
1103
- };
3200
+ function ee(e, t) {
3201
+ const n = Te[e.source] - Te[t.source];
3202
+ if (n !== 0)
3203
+ return n;
3204
+ const o = Le[e.severity] - Le[t.severity];
3205
+ if (o !== 0)
3206
+ return o;
3207
+ const r = e.type.localeCompare(t.type);
3208
+ if (r !== 0)
3209
+ return r;
3210
+ const i = [
3211
+ e.sourceProjectId ?? "",
3212
+ e.targetProjectId ?? "",
3213
+ e.relatedProjectIds.join(",")
3214
+ ].join("|").localeCompare(
3215
+ [
3216
+ t.sourceProjectId ?? "",
3217
+ t.targetProjectId ?? "",
3218
+ t.relatedProjectIds.join(",")
3219
+ ].join("|")
3220
+ );
3221
+ return i !== 0 ? i : e.id.localeCompare(t.id);
3222
+ }
3223
+ function Do(e) {
3224
+ return typeof e == "object" && e !== null && !Array.isArray(e) ? e : void 0;
3225
+ }
3226
+ function ko(e) {
3227
+ return typeof e == "string" ? e : void 0;
1104
3228
  }
1105
- function D(e, n, t, o, r) {
3229
+ function $o(e) {
3230
+ return e !== void 0;
3231
+ }
3232
+ async function Tr(e) {
3233
+ const t = Mo(e), n = [...e.extensionDiagnostics ?? []], o = [...e.diagnostics ?? []], r = [...e.capabilities ?? []], i = e.extensionRegistry, s = e.extensionContext, a = i && s ? await Bn(i, {
3234
+ workspace: t,
3235
+ profile: e.profile,
3236
+ context: s
3237
+ }) : t, d = dt({
3238
+ workspace: a,
3239
+ profile: e.profile
3240
+ }), c = nt({
3241
+ exceptions: e.exceptions ?? [],
3242
+ policyViolations: d,
3243
+ conformanceFindings: e.conformanceFindings ?? [],
3244
+ asOf: e.asOf ?? /* @__PURE__ */ new Date()
3245
+ }), l = i && s ? await Gn(i, {
3246
+ workspace: a,
3247
+ profile: e.profile,
3248
+ context: s
3249
+ }) : [], u = [
3250
+ ...c.activePolicyViolations,
3251
+ ...l
3252
+ ], w = mt(
3253
+ e.graphSnapshot ?? Eo(a)
3254
+ ), m = gt(
3255
+ c.activePolicyViolations,
3256
+ {
3257
+ createdAt: e.graphSnapshot?.extractedAt ?? (/* @__PURE__ */ new Date()).toISOString()
3258
+ }
3259
+ ), x = c.activeConformanceFindings.length > 0 ? ft({
3260
+ extractedAt: e.graphSnapshot?.extractedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
3261
+ findings: c.activeConformanceFindings
3262
+ }) : [], z = ue(
3263
+ w,
3264
+ x,
3265
+ m
3266
+ ), T = i && s ? await Nn(i, {
3267
+ workspace: a,
3268
+ profile: e.profile,
3269
+ violations: u,
3270
+ signals: z,
3271
+ context: s
3272
+ }) : [], b = ue(z, T), S = ct({
3273
+ workspace: a,
3274
+ signals: b
3275
+ }), y = i && s ? await qn(i, {
3276
+ workspace: a,
3277
+ profile: e.profile,
3278
+ signals: b,
3279
+ measurements: S,
3280
+ violations: u,
3281
+ context: s
3282
+ }) : [], C = [...S, ...y], L = Xe(b), he = at(
3283
+ u,
3284
+ C
3285
+ ), wt = st(
3286
+ C,
3287
+ e.profile.metrics,
3288
+ e.profile.health.statusThresholds,
3289
+ {
3290
+ topIssues: L
3291
+ }
3292
+ ), It = dn({
3293
+ workspace: a,
3294
+ profile: e.profile.name,
3295
+ warnings: e.warnings ?? [],
3296
+ exceptions: e.exceptions && e.exceptions.length > 0 ? ot(c) : bn(),
3297
+ violations: u,
3298
+ signals: b,
3299
+ measurements: C,
3300
+ health: wt,
3301
+ recommendations: he
3302
+ });
1106
3303
  return {
1107
- id: e,
1108
- kind: n,
1109
- label: t,
1110
- status: ee(o.delta),
1111
- magnitude: Math.abs(o.delta),
1112
- baseline: o.baseline,
1113
- current: o.current,
1114
- delta: o.delta,
1115
- details: r
3304
+ workspace: a,
3305
+ assessment: It,
3306
+ violations: u,
3307
+ signals: b,
3308
+ measurements: C,
3309
+ recommendations: he,
3310
+ exceptionApplication: c,
3311
+ extensionDiagnostics: n,
3312
+ capabilities: r,
3313
+ diagnostics: o
1116
3314
  };
1117
3315
  }
1118
- function We(e, n, t) {
3316
+ function Mo(e) {
3317
+ if (e.workspace)
3318
+ return e.workspace;
3319
+ if (e.workspaceAdapterResult)
3320
+ return X(e.workspaceAdapterResult);
3321
+ throw new Error(
3322
+ "buildGovernanceAssessmentArtifacts requires either workspace or workspaceAdapterResult."
3323
+ );
3324
+ }
3325
+ function Eo(e) {
1119
3326
  return {
1120
- source: e,
1121
- baseline: n,
1122
- current: t,
1123
- delta: p(t - n)
3327
+ extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
3328
+ projects: e.projects.map((t) => ({
3329
+ id: t.id,
3330
+ domain: t.domain
3331
+ })),
3332
+ dependencies: e.dependencies.map((t) => ({
3333
+ sourceProjectId: t.source,
3334
+ targetProjectId: t.target,
3335
+ type: t.type
3336
+ }))
1124
3337
  };
1125
3338
  }
1126
- function Ye(e, n, t) {
3339
+ function F(e, t) {
1127
3340
  return {
1128
- severity: e,
1129
- baseline: n,
1130
- current: t,
1131
- delta: p(t - n)
3341
+ useCase: e,
3342
+ request: t.request,
3343
+ analysis: t.analysis,
3344
+ ...t.payloadScope ? { payloadScope: t.payloadScope } : {},
3345
+ ...t.metadata ? { metadata: t.metadata } : {}
1132
3346
  };
1133
3347
  }
1134
- function H(e, n) {
1135
- return e.signalBreakdown?.bySource.find((t) => t.source === n)?.count ?? 0;
1136
- }
1137
- function U(e, n) {
1138
- return e.signalBreakdown?.byType.find((t) => t.type === n)?.count ?? 0;
1139
- }
1140
- function W(e, n) {
1141
- return e.signalBreakdown?.bySeverity.find(
1142
- (t) => t.severity === n
1143
- )?.count ?? 0;
1144
- }
1145
- function T(e) {
1146
- return [
1147
- e.type,
1148
- e.source,
1149
- e.severity,
1150
- e.ruleId ?? "",
1151
- e.message
1152
- ].join("|");
3348
+ function Lr(e) {
3349
+ return F("root-cause", e);
1153
3350
  }
1154
- function Ke(e) {
1155
- return `top-issue:${T(e)}`;
3351
+ function Br(e) {
3352
+ return F("pr-impact", e);
1156
3353
  }
1157
- function Je(e, n) {
1158
- return e.id.localeCompare(n.id);
3354
+ function Gr(e) {
3355
+ return F("drift", e);
1159
3356
  }
1160
- function Y(e, n) {
1161
- return n.magnitude - e.magnitude || e.id.localeCompare(n.id);
3357
+ function Nr(e) {
3358
+ return F("scorecard", e);
1162
3359
  }
1163
- function Qe(e, n) {
1164
- return Math.abs(e) < n ? "stable" : e > 0 ? "improving" : "worsening";
3360
+ function qr(e) {
3361
+ return F("management-insights", e);
1165
3362
  }
1166
- function ee(e) {
1167
- return e === 0 ? "stable" : e < 0 ? "improving" : "worsening";
3363
+ const Ro = "core", Oo = {
3364
+ id: Ro,
3365
+ name: "Governance Core Built-in Rules",
3366
+ rules: co
3367
+ }, _r = [Oo], Be = [
3368
+ "cross-domain-coordination-friction",
3369
+ "architectural-erosion-risk",
3370
+ "ownership-ambiguity",
3371
+ "change-impact-radius-pressure",
3372
+ "cost-of-change-pressure",
3373
+ "onboarding-friction",
3374
+ "delivery-predictability-pressure"
3375
+ ];
3376
+ function Vo(e) {
3377
+ const { assessment: t, comparison: n } = e, o = Ao(t, n), r = Fo(t, n, o), i = zo(
3378
+ t,
3379
+ n,
3380
+ o
3381
+ ), s = [r, i].sort(
3382
+ (a, d) => d.score - a.score || a.id.localeCompare(d.id)
3383
+ );
3384
+ return {
3385
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3386
+ profile: t.profile,
3387
+ indices: s,
3388
+ insights: To(t, s, o),
3389
+ drivers: o
3390
+ };
1168
3391
  }
1169
- function Xe(e) {
1170
- return e.split("-").map((n) => n[0]?.toUpperCase() + n.slice(1)).join(" ");
3392
+ const Wr = Vo;
3393
+ function Hr(e) {
3394
+ const t = [...e.indices].sort(
3395
+ (r, i) => i.score - r.score || r.id.localeCompare(i.id)
3396
+ )[0];
3397
+ if (!t)
3398
+ return "No delivery-impact indices were produced.";
3399
+ const n = e.drivers.slice(0, 3).map((r) => r.label), o = n.length > 0 ? ` Top drivers: ${n.join(", ")}.` : "";
3400
+ return `${t.name} is currently ${t.risk} risk at ${t.score}/100.${o}`;
1171
3401
  }
1172
- function Ze(e) {
1173
- return e[0].toUpperCase() + e.slice(1);
3402
+ function Ao(e, t) {
3403
+ return [
3404
+ k({
3405
+ id: "cross-domain-coordination-friction",
3406
+ label: "Cross-domain coordination friction",
3407
+ measurement: p(e.measurements, "domain-integrity"),
3408
+ issues: e.topIssues.filter(Bo),
3409
+ violations: e.violations.filter(qo),
3410
+ familyDelta: $(t, "boundaries")
3411
+ }),
3412
+ k({
3413
+ id: "architectural-erosion-risk",
3414
+ label: "Architectural erosion risk",
3415
+ measurement: p(e.measurements, "layer-integrity"),
3416
+ issues: e.topIssues.filter(Go),
3417
+ violations: e.violations.filter(_o),
3418
+ familyDelta: $(t, "boundaries")
3419
+ }),
3420
+ k({
3421
+ id: "ownership-ambiguity",
3422
+ label: "Ownership ambiguity",
3423
+ measurement: p(
3424
+ e.measurements,
3425
+ "ownership-coverage"
3426
+ ),
3427
+ issues: e.topIssues.filter(No),
3428
+ violations: e.violations.filter(Wo),
3429
+ familyDelta: $(t, "ownership")
3430
+ }),
3431
+ k({
3432
+ id: "change-impact-radius-pressure",
3433
+ label: "Impact radius pressure",
3434
+ measurement: p(
3435
+ e.measurements,
3436
+ "dependency-complexity"
3437
+ ),
3438
+ issues: e.topIssues.filter(Ge),
3439
+ violations: [],
3440
+ familyDelta: $(t, "architecture")
3441
+ }),
3442
+ k({
3443
+ id: "cost-of-change-pressure",
3444
+ label: "Cost of change pressure",
3445
+ measurement: p(
3446
+ e.measurements,
3447
+ "architectural-entropy"
3448
+ ),
3449
+ issues: e.topIssues.filter(Ge),
3450
+ violations: [],
3451
+ familyDelta: $(t, "architecture")
3452
+ }),
3453
+ k({
3454
+ id: "onboarding-friction",
3455
+ label: "Onboarding friction",
3456
+ measurement: p(
3457
+ e.measurements,
3458
+ "documentation-completeness"
3459
+ ),
3460
+ issues: [],
3461
+ violations: [],
3462
+ familyDelta: $(t, "documentation")
3463
+ }),
3464
+ Lo(e, t)
3465
+ ].filter(Ho).sort(
3466
+ (o, r) => Be.indexOf(o.id) - Be.indexOf(r.id)
3467
+ );
1174
3468
  }
1175
- function en(e) {
1176
- return e.split("-").map((n) => n[0]?.toUpperCase() + n.slice(1)).join(" ");
3469
+ function Fo(e, t, n) {
3470
+ const o = ht([
3471
+ f(
3472
+ p(e.measurements, "dependency-complexity")
3473
+ ),
3474
+ f(
3475
+ p(e.measurements, "architectural-entropy")
3476
+ ),
3477
+ f(
3478
+ p(e.measurements, "domain-integrity")
3479
+ ),
3480
+ f(
3481
+ p(e.measurements, "layer-integrity")
3482
+ ),
3483
+ f(
3484
+ p(e.measurements, "ownership-coverage")
3485
+ ),
3486
+ f(
3487
+ p(e.measurements, "documentation-completeness")
3488
+ ),
3489
+ t?.healthDelta ? Math.max(0, -t.healthDelta.scoreDelta) : void 0
3490
+ ]);
3491
+ return {
3492
+ id: "cost-of-change",
3493
+ name: "Cost of Change Index",
3494
+ score: o,
3495
+ risk: vt(o),
3496
+ trend: te(t?.healthDelta?.scoreDelta),
3497
+ drivers: yt(n, [
3498
+ "change-impact-radius-pressure",
3499
+ "cost-of-change-pressure",
3500
+ "architectural-erosion-risk",
3501
+ "cross-domain-coordination-friction",
3502
+ "ownership-ambiguity",
3503
+ "onboarding-friction"
3504
+ ])
3505
+ };
1177
3506
  }
1178
- function p(e) {
1179
- return Math.round(e * 1e3) / 1e3;
3507
+ function zo(e, t, n) {
3508
+ const o = ne(
3509
+ e.topIssues.filter((i) => i.type === "conformance-violation").reduce((i, s) => i + s.count * 10, 0)
3510
+ ), r = ht([
3511
+ f(
3512
+ p(e.measurements, "domain-integrity")
3513
+ ),
3514
+ f(
3515
+ p(e.measurements, "ownership-coverage")
3516
+ ),
3517
+ f(
3518
+ p(e.measurements, "dependency-complexity")
3519
+ ),
3520
+ f(
3521
+ p(e.measurements, "layer-integrity")
3522
+ ),
3523
+ f(
3524
+ p(e.measurements, "documentation-completeness")
3525
+ ),
3526
+ 100 - e.health.score,
3527
+ o,
3528
+ t?.healthDelta ? Math.max(0, -t.healthDelta.scoreDelta) : void 0
3529
+ ]);
3530
+ return {
3531
+ id: "time-to-market-risk",
3532
+ name: "Time-to-Market Risk Index",
3533
+ score: r,
3534
+ risk: vt(r),
3535
+ trend: te(t?.healthDelta?.scoreDelta),
3536
+ drivers: yt(n, [
3537
+ "cross-domain-coordination-friction",
3538
+ "ownership-ambiguity",
3539
+ "change-impact-radius-pressure",
3540
+ "architectural-erosion-risk",
3541
+ "onboarding-friction",
3542
+ "delivery-predictability-pressure"
3543
+ ])
3544
+ };
1180
3545
  }
1181
- function K(e, n) {
1182
- return e.some(
1183
- (t) => t.type === n.type && t.source === n.source && t.target === n.target
3546
+ function To(e, t, n) {
3547
+ const o = [...t].sort(
3548
+ (s, a) => a.score - s.score || s.id.localeCompare(a.id)
3549
+ )[0], r = n.slice(0, 3), i = [];
3550
+ for (const s of t)
3551
+ s.risk !== "low" && i.push({
3552
+ id: s.id,
3553
+ audience: "management",
3554
+ category: s.id === "cost-of-change" ? "cost-of-change" : "time-to-market",
3555
+ severity: s.risk,
3556
+ title: s.name,
3557
+ summary: `${s.name} is ${s.score}/100 with ${s.risk} risk.`,
3558
+ drivers: s.drivers.slice(0, 3),
3559
+ relatedMeasurements: s.drivers.map((a) => a.id),
3560
+ relatedSignals: e.topIssues.slice(0, 5).map((a) => a.type),
3561
+ relatedViolations: e.violations.slice(0, 5).map((a) => a.ruleId)
3562
+ });
3563
+ return (o || r.length > 0) && i.push({
3564
+ id: "architecture-investment-drivers",
3565
+ audience: "technical-lead",
3566
+ category: "delivery-risk",
3567
+ severity: o?.risk ?? "low",
3568
+ title: "Architecture Investment Drivers",
3569
+ summary: r.length > 0 ? `Top delivery-impact drivers are ${r.map((s) => s.label).join(", ")}.` : "No dominant delivery-impact drivers were detected.",
3570
+ drivers: r,
3571
+ relatedMeasurements: e.measurements.slice(0, 6).map((s) => s.id),
3572
+ relatedSignals: e.topIssues.slice(0, 6).map((s) => s.type),
3573
+ relatedViolations: e.violations.slice(0, 6).map((s) => s.ruleId)
3574
+ }), i.sort((s, a) => s.id.localeCompare(a.id));
3575
+ }
3576
+ function k(e) {
3577
+ const t = e.measurement ? 100 - e.measurement.score : void 0, n = e.issues.reduce((i, s) => i + s.count, 0), o = e.violations.length, r = ne(
3578
+ Math.max(t ?? 0, n * 15, o * 20)
1184
3579
  );
3580
+ if (!(r <= 0))
3581
+ return {
3582
+ id: e.id,
3583
+ label: e.label,
3584
+ score: r,
3585
+ unit: "score",
3586
+ trend: te(e.familyDelta),
3587
+ explanation: e.measurement ? `${e.measurement.name} is ${e.measurement.score}/100 with ${n} top issue(s) and ${o} violation(s).` : `${n} top issue(s) and ${o} violation(s) contribute to this driver.`
3588
+ };
1185
3589
  }
1186
- function kn(e) {
1187
- const n = v(e.id, "Exception id"), t = rn(e.source), o = v(e.reason, "Exception reason"), r = v(e.owner, "Exception owner"), i = tn(e.review), a = ne(e.scope);
1188
- if (a.source !== t)
1189
- throw new Error(
1190
- `Exception "${n}" has source "${t}" but scope source "${a.source}".`
1191
- );
3590
+ function Lo(e, t) {
1192
3591
  return {
1193
- id: n,
1194
- source: t,
1195
- scope: a,
1196
- reason: o,
1197
- owner: r,
1198
- review: i
3592
+ id: "delivery-predictability-pressure",
3593
+ label: "Delivery predictability pressure",
3594
+ score: ne(100 - e.health.score),
3595
+ unit: "score",
3596
+ trend: te(t?.healthDelta?.scoreDelta),
3597
+ explanation: `Workspace health is ${e.health.score}/100 (${e.health.status}).`
1199
3598
  };
1200
3599
  }
1201
- function xn(e) {
1202
- const n = ne(e);
1203
- return nn(n) ? [
1204
- n.source,
1205
- n.ruleId,
1206
- n.projectId,
1207
- n.targetProjectId ?? ""
1208
- ].join("|") : [
1209
- n.source,
1210
- n.ruleId ?? "",
1211
- n.category ?? "",
1212
- n.projectId ?? "",
1213
- (n.relatedProjectIds ?? []).join(",")
1214
- ].join("|");
3600
+ function yt(e, t) {
3601
+ const n = new Set(t);
3602
+ return e.filter((o) => n.has(o.id));
1215
3603
  }
1216
- function nn(e) {
1217
- return e.source === "policy";
3604
+ function p(e, t) {
3605
+ return e.find((n) => n.id === t);
1218
3606
  }
1219
- function Rn(e) {
1220
- return e.source === "conformance";
3607
+ function $(e, t) {
3608
+ return e?.metricFamilyDeltas?.find(
3609
+ (n) => n.family === t
3610
+ )?.delta;
1221
3611
  }
1222
- function tn(e) {
1223
- const n = d(e.createdAt), t = d(e.reviewBy), o = d(e.expiresAt);
1224
- if (!t && !o)
1225
- throw new Error(
1226
- "Governance exception review must define reviewBy or expiresAt."
1227
- );
1228
- return {
1229
- ...n ? { createdAt: n } : {},
1230
- ...t ? { reviewBy: t } : {},
1231
- ...o ? { expiresAt: o } : {}
1232
- };
3612
+ function f(e) {
3613
+ return e ? 100 - e.score : void 0;
3614
+ }
3615
+ function ht(e) {
3616
+ const t = e.filter(
3617
+ (n) => n !== void 0
3618
+ );
3619
+ return t.length === 0 ? 0 : ne(
3620
+ Math.round(t.reduce((n, o) => n + o, 0) / t.length)
3621
+ );
3622
+ }
3623
+ function te(e) {
3624
+ return e === void 0 || e === 0 ? "stable" : e > 0 ? "improving" : "worsening";
3625
+ }
3626
+ function vt(e) {
3627
+ return e >= 70 ? "high" : e >= 40 ? "medium" : "low";
1233
3628
  }
1234
3629
  function ne(e) {
1235
- if (e.source === "policy")
1236
- return {
1237
- source: "policy",
1238
- ruleId: v(e.ruleId, "Policy exception ruleId"),
1239
- projectId: v(
1240
- e.projectId,
1241
- "Policy exception projectId"
1242
- ),
1243
- ...d(e.targetProjectId) ? { targetProjectId: d(e.targetProjectId) } : {}
1244
- };
1245
- const n = d(e.ruleId), t = an(e.category), o = d(e.projectId), r = on(e.relatedProjectIds);
1246
- if (!n && !t && !o && r.length === 0)
1247
- throw new Error(
1248
- "Conformance exception scope must define ruleId, category, projectId, or relatedProjectIds."
1249
- );
1250
- return {
1251
- source: "conformance",
1252
- ...n ? { ruleId: n } : {},
1253
- ...t ? { category: t } : {},
1254
- ...o ? { projectId: o } : {},
1255
- ...r.length > 0 ? { relatedProjectIds: r } : {}
1256
- };
3630
+ return Math.max(0, Math.min(100, Math.round(e)));
1257
3631
  }
1258
- function rn(e) {
1259
- if (e === "policy" || e === "conformance")
1260
- return e;
1261
- throw new Error(`Unsupported governance exception source "${e}".`);
3632
+ function Bo(e) {
3633
+ return e.type === "cross-domain-dependency";
1262
3634
  }
1263
- function v(e, n) {
1264
- const t = d(e);
1265
- if (!t)
1266
- throw new Error(`${n} is required.`);
1267
- return t;
3635
+ function Go(e) {
3636
+ return e.type === "layer-boundary-violation";
1268
3637
  }
1269
- function d(e) {
1270
- if (typeof e != "string")
1271
- return;
1272
- const n = e.trim();
1273
- return n.length > 0 ? n : void 0;
3638
+ function No(e) {
3639
+ return e.type === "ownership-gap";
1274
3640
  }
1275
- function on(e) {
1276
- return Array.isArray(e) ? [
1277
- ...new Set(
1278
- e.map(d).filter((n) => !!n)
1279
- )
1280
- ].sort((n, t) => n.localeCompare(t)) : [];
3641
+ function Ge(e) {
3642
+ return e.type === "structural-dependency" || e.type === "circular-dependency";
3643
+ }
3644
+ function qo(e) {
3645
+ return e.ruleId === "domain-boundary";
3646
+ }
3647
+ function _o(e) {
3648
+ return e.ruleId === "layer-boundary";
3649
+ }
3650
+ function Wo(e) {
3651
+ return e.ruleId === "ownership-presence";
1281
3652
  }
1282
- function an(e) {
1283
- return d(e);
3653
+ function Ho(e) {
3654
+ return e !== void 0;
1284
3655
  }
1285
- async function sn(e, n) {
1286
- const t = cn();
3656
+ async function Uo(e, t) {
3657
+ const n = Ko();
1287
3658
  for (const o of e) {
1288
- const r = await o.evaluate(n);
1289
- t.violations.push(...r.violations ?? []), t.signals.push(...r.signals ?? []), t.measurements.push(...r.measurements ?? []);
3659
+ const r = await o.evaluate(t);
3660
+ n.violations.push(...r.violations ?? []), n.signals.push(...r.signals ?? []), n.measurements.push(...r.measurements ?? []);
1290
3661
  }
1291
- return t;
3662
+ return n;
1292
3663
  }
1293
- async function Mn(e, n) {
1294
- return sn(e.rules, n);
3664
+ async function Ur(e, t) {
3665
+ return Uo(e.rules, t);
1295
3666
  }
1296
- function cn() {
3667
+ function Ko() {
1297
3668
  return {
1298
3669
  violations: [],
1299
3670
  signals: [],
1300
3671
  measurements: []
1301
3672
  };
1302
3673
  }
1303
- function Cn(e, n) {
1304
- const t = Object.fromEntries(
3674
+ function Kr(e, t) {
3675
+ const n = Object.fromEntries(
1305
3676
  e.measurements.map((i) => [
1306
3677
  i.id,
1307
3678
  i.value
@@ -1318,15 +3689,15 @@ function Cn(e, n) {
1318
3689
  (i) => ({
1319
3690
  type: i.ruleId,
1320
3691
  source: i.project,
1321
- target: ln(i.details?.target),
3692
+ target: Yo(i.details?.target),
1322
3693
  ruleId: i.ruleId,
1323
3694
  severity: i.severity,
1324
3695
  message: i.message
1325
3696
  })
1326
3697
  );
1327
3698
  return {
1328
- ...n,
1329
- metrics: t,
3699
+ ...t,
3700
+ metrics: n,
1330
3701
  scores: o,
1331
3702
  violations: r,
1332
3703
  health: {
@@ -1337,251 +3708,117 @@ function Cn(e, n) {
1337
3708
  signalBreakdown: e.signalBreakdown,
1338
3709
  metricBreakdown: e.metricBreakdown,
1339
3710
  topIssues: e.topIssues,
1340
- deliveryImpact: n.deliveryImpact
3711
+ deliveryImpact: t.deliveryImpact
1341
3712
  };
1342
3713
  }
1343
- function ln(e) {
3714
+ function Yo(e) {
1344
3715
  return typeof e == "string" ? e : void 0;
1345
3716
  }
1346
- class $n {
1347
- capabilitiesById = /* @__PURE__ */ new Map();
1348
- capabilities;
1349
- constructor(n) {
1350
- const t = n.map(
1351
- (o) => Object.freeze({ ...o })
1352
- );
1353
- for (const o of t) {
1354
- if (this.capabilitiesById.has(o.id))
1355
- throw new Error(
1356
- `Duplicate governance capability id "${o.id}" is not allowed.`
1357
- );
1358
- this.capabilitiesById.set(o.id, o);
1359
- }
1360
- this.capabilities = Object.freeze([...t]);
1361
- }
1362
- has(n) {
1363
- return this.capabilitiesById.has(n);
1364
- }
1365
- get(n) {
1366
- return this.capabilitiesById.get(n);
1367
- }
1368
- list() {
1369
- return [...this.capabilities];
1370
- }
1371
- }
1372
- class $ extends Error {
1373
- diagnostics;
1374
- constructor(n, t) {
1375
- super(n), this.name = "GovernanceExtensionRegistrationError", this.diagnostics = t;
1376
- }
1377
- }
1378
- class un {
1379
- context;
1380
- registry = {
1381
- metricProviders: [],
1382
- signalProviders: [],
1383
- rulePacks: [],
1384
- enrichers: []
1385
- };
1386
- pluginId;
1387
- constructor(n, t) {
1388
- this.context = Object.freeze({
1389
- ...n,
1390
- options: Object.freeze({ ...n.options })
1391
- }), this.pluginId = t;
1392
- }
1393
- registerMetricProvider(n) {
1394
- this.registry.metricProviders.push({
1395
- pluginId: this.pluginId,
1396
- contribution: n
1397
- });
1398
- }
1399
- registerSignalProvider(n) {
1400
- this.registry.signalProviders.push({
1401
- pluginId: this.pluginId,
1402
- contribution: n
1403
- });
1404
- }
1405
- registerRulePack(n) {
1406
- this.registry.rulePacks.push({
1407
- pluginId: this.pluginId,
1408
- contribution: n
1409
- });
1410
- }
1411
- registerEnricher(n) {
1412
- this.registry.enrichers.push({
1413
- pluginId: this.pluginId,
1414
- contribution: n
1415
- });
1416
- }
1417
- toRegistry() {
1418
- return {
1419
- metricProviders: [...this.registry.metricProviders],
1420
- signalProviders: [...this.registry.signalProviders],
1421
- rulePacks: [...this.registry.rulePacks],
1422
- enrichers: [...this.registry.enrichers]
1423
- };
1424
- }
1425
- }
1426
- async function On(e, n) {
1427
- return (await dn(
1428
- e,
1429
- n
1430
- )).registry;
1431
- }
1432
- async function dn(e, n, t = {}) {
1433
- const o = {
1434
- metricProviders: [],
1435
- signalProviders: [],
1436
- rulePacks: [],
1437
- enrichers: []
1438
- }, r = [...t.diagnostics ?? []], i = /* @__PURE__ */ new Map();
1439
- for (const a of n) {
1440
- try {
1441
- fn(a);
1442
- } catch (s) {
1443
- throw r.push({
1444
- code: "governance.extension.invalid_definition",
1445
- severity: "error",
1446
- message: O(s),
1447
- packageName: a.sourceSpecifier,
1448
- moduleSpecifier: a.moduleSpecifier,
1449
- legacy: a.legacy
1450
- }), new $(
1451
- O(s),
1452
- r
1453
- );
1454
- }
1455
- const c = i.get(a.definition.id);
1456
- if (c) {
1457
- const s = `Duplicate governance extension id "${a.definition.id}" was found in "${c}" and "${a.moduleSpecifier}".`;
1458
- throw r.push({
1459
- code: "governance.extension.duplicate_id",
1460
- severity: "error",
1461
- message: s,
1462
- packageName: a.sourceSpecifier,
1463
- moduleSpecifier: a.moduleSpecifier,
1464
- extensionId: a.definition.id,
1465
- legacy: a.legacy
1466
- }), new $(s, r);
1467
- }
1468
- i.set(a.definition.id, a.moduleSpecifier);
1469
- try {
1470
- const s = new un(
1471
- e,
1472
- a.definition.id
1473
- );
1474
- await a.definition.register(s), pn(o, s.toRegistry());
1475
- } catch (s) {
1476
- const l = `Governance extension "${a.definition.id}" from "${a.moduleSpecifier}" failed during registration: ${O(s)}`;
1477
- throw r.push({
1478
- code: "governance.extension.registration_failed",
1479
- severity: "error",
1480
- message: l,
1481
- packageName: a.sourceSpecifier,
1482
- moduleSpecifier: a.moduleSpecifier,
1483
- extensionId: a.definition.id,
1484
- legacy: a.legacy
1485
- }), new $(l, r);
1486
- }
1487
- }
1488
- return {
1489
- registry: o,
1490
- diagnostics: r
1491
- };
1492
- }
1493
- async function Bn(e, n) {
1494
- let t = n.workspace;
1495
- for (const o of e.enrichers)
1496
- t = await o.contribution.enrichWorkspace({
1497
- ...n,
1498
- workspace: t
1499
- });
1500
- return t;
1501
- }
1502
- async function Tn(e, n) {
1503
- return (await Promise.all(
1504
- e.rulePacks.map(async (o) => (await o.contribution.evaluate(n)).map((i) => ({
1505
- ...i,
1506
- sourcePluginId: i.sourcePluginId ?? o.pluginId
1507
- })))
1508
- )).flat();
1509
- }
1510
- async function zn(e, n) {
1511
- return (await Promise.all(
1512
- e.signalProviders.map(async (o) => (await o.contribution.provideSignals(n)).map((i) => ({
1513
- ...i,
1514
- source: "extension",
1515
- sourcePluginId: i.sourcePluginId ?? o.pluginId
1516
- })))
1517
- )).flat();
1518
- }
1519
- async function Ln(e, n) {
1520
- return (await Promise.all(
1521
- e.metricProviders.map(async (o) => (await o.contribution.provideMetrics(n)).map((i) => ({
1522
- ...i,
1523
- sourcePluginId: i.sourcePluginId ?? o.pluginId
1524
- })))
1525
- )).flat();
1526
- }
1527
- function pn(e, n) {
1528
- e.metricProviders.push(...n.metricProviders), e.signalProviders.push(...n.signalProviders), e.rulePacks.push(...n.rulePacks), e.enrichers.push(...n.enrichers);
1529
- }
1530
- function fn(e) {
1531
- if (typeof e.definition.id != "string" || e.definition.id.trim().length === 0)
1532
- throw new Error(
1533
- `Governance extension module "${e.moduleSpecifier}" must declare a non-empty "id".`
1534
- );
1535
- }
1536
- function O(e) {
1537
- return e instanceof Error ? e.message : String(e);
1538
- }
1539
3717
  export {
1540
- ze as CORE_BUILT_IN_RULE_PACK_ID,
1541
- Pn as DEFAULT_HEALTH_STATUS_THRESHOLDS,
1542
- $n as DefaultGovernanceCapabilityRegistry,
1543
- $ as GovernanceExtensionRegistrationError,
3718
+ Ro as CORE_BUILT_IN_RULE_PACK_ID,
3719
+ q as DEFAULT_HEALTH_STATUS_THRESHOLDS,
3720
+ Er as DefaultGovernanceCapabilityRegistry,
3721
+ se as GovernanceExtensionRegistrationError,
1544
3722
  Bn as applyGovernanceEnrichers,
1545
- vn as buildAiDriftHandoffPayload,
1546
- S as buildAiHandoffPayload,
1547
- In as buildAiManagementInsightsHandoffPayload,
1548
- hn as buildAiPrImpactHandoffPayload,
1549
- gn as buildAiRootCauseHandoffPayload,
1550
- wn as buildAiScorecardHandoffPayload,
1551
- En as buildDriftSummary,
1552
- yn as buildGovernanceAssessment,
1553
- xn as buildGovernanceExceptionScopeKey,
1554
- mn as buildGovernanceWorkspace,
1555
- Pe as buildMetricBreakdown,
1556
- Cn as buildMetricSnapshot,
1557
- Ie as buildSignalBreakdown,
1558
- Se as buildTopIssues,
1559
- Ln as collectGovernanceMeasurements,
1560
- zn as collectGovernanceSignals,
1561
- Dn as compareSnapshots,
1562
- Ee as coreBuiltInPolicyRules,
1563
- Le as coreBuiltInRulePack,
1564
- bn as coreBuiltInRulePacks,
1565
- z as deriveAllowedLayerDependenciesFromLayerOrder,
1566
- w as domainBoundaryRule,
1567
- Sn as evaluateCoreBuiltInPolicyViolations,
1568
- Tn as evaluateGovernanceRulePacks,
1569
- Mn as evaluateRulePack,
1570
- sn as evaluateRules,
1571
- ve as filterMeasurementsForReportType,
1572
- we as filterSignalsForReportType,
1573
- he as filterViolationsForReportType,
1574
- Rn as isConformanceExceptionScope,
1575
- nn as isPolicyExceptionScope,
1576
- I as layerBoundaryRule,
1577
- k as missingDomainRule,
1578
- x as missingLayerRule,
1579
- kn as normalizeGovernanceException,
1580
- m as normalizeGovernanceProfile,
1581
- P as ownershipPresenceRule,
1582
- j as projectNameConventionRule,
1583
- On as registerLoadedGovernanceExtensions,
1584
- dn as registerLoadedGovernanceExtensionsWithDiagnostics,
1585
- jn as summarizeDrift,
1586
- E as tagConventionRule
3723
+ nt as applyGovernanceExceptions,
3724
+ Gr as buildAiDriftHandoffPayload,
3725
+ F as buildAiHandoffPayload,
3726
+ qr as buildAiManagementInsightsHandoffPayload,
3727
+ Br as buildAiPrImpactHandoffPayload,
3728
+ Lr as buildAiRootCauseHandoffPayload,
3729
+ Nr as buildAiScorecardHandoffPayload,
3730
+ ir as buildArchitectureRecommendationsRequest,
3731
+ Cr as buildCognitiveLoadContext,
3732
+ rr as buildCognitiveLoadRequest,
3733
+ Vo as buildDeliveryImpactAssessment,
3734
+ jr as buildDriftInterpretationAnalysis,
3735
+ Ft as buildDriftSummary,
3736
+ dn as buildGovernanceAssessment,
3737
+ Tr as buildGovernanceAssessmentArtifacts,
3738
+ ft as buildGovernanceConformanceSignals,
3739
+ ot as buildGovernanceExceptionReport,
3740
+ Qe as buildGovernanceExceptionScopeKey,
3741
+ mt as buildGovernanceGraphSignals,
3742
+ Xo as buildGovernanceInventory,
3743
+ _e as buildGovernancePayloadTruncationMetadata,
3744
+ gt as buildGovernancePolicySignals,
3745
+ at as buildGovernanceRecommendations,
3746
+ zr as buildGovernanceSignals,
3747
+ X as buildGovernanceWorkspace,
3748
+ Qo as buildGovernanceWorkspaceFromAdapterResult,
3749
+ cr as buildManagementInsightsAiRequest,
3750
+ fn as buildMetricBreakdown,
3751
+ Kr as buildMetricSnapshot,
3752
+ $r as buildOnboardingContext,
3753
+ or as buildOnboardingRequest,
3754
+ tn as buildPersistentSmellSignals,
3755
+ br as buildPrImpactContext,
3756
+ tr as buildPrImpactRequest,
3757
+ Vr as buildRecommendations,
3758
+ Dr as buildRecommendationsTrendContext,
3759
+ kr as buildRefactoringSuggestionsContext,
3760
+ ar as buildRefactoringSuggestionsRequest,
3761
+ er as buildRootCauseRequest,
3762
+ Sr as buildScopedDriftRequest,
3763
+ Ir as buildScopedRootCauseRequest,
3764
+ Pr as buildScopedScorecardRequest,
3765
+ nr as buildScorecardRequest,
3766
+ mn as buildSignalBreakdown,
3767
+ sr as buildSmellClustersRequest,
3768
+ Xe as buildTopIssues,
3769
+ Wr as calculateDeliveryImpact,
3770
+ st as calculateGovernanceHealth,
3771
+ ct as calculateGovernanceMetrics,
3772
+ Or as calculateHealthScore,
3773
+ Ar as calculateMetrics,
3774
+ qn as collectGovernanceMeasurements,
3775
+ Nn as collectGovernanceSignals,
3776
+ _ as compareGovernanceViolationsForPriority,
3777
+ vr as compareSnapshots,
3778
+ co as coreBuiltInPolicyRules,
3779
+ Oo as coreBuiltInRulePack,
3780
+ _r as coreBuiltInRulePacks,
3781
+ xr as countWorseningDriftSignals,
3782
+ bn as createEmptyGovernanceExceptionReport,
3783
+ ge as deriveAllowedLayerDependenciesFromLayerOrder,
3784
+ O as domainBoundaryRule,
3785
+ Fr as evaluateBuiltInGovernancePolicies,
3786
+ ze as evaluateCoreBuiltInPolicyViolations,
3787
+ jn as evaluateGovernanceExceptionLifecycle,
3788
+ dt as evaluateGovernancePolicies,
3789
+ Gn as evaluateGovernanceRulePacks,
3790
+ Ur as evaluateRulePack,
3791
+ Uo as evaluateRules,
3792
+ un as filterMeasurementsForReportType,
3793
+ pn as filterSignalsForReportType,
3794
+ ln as filterViolationsForReportType,
3795
+ vn as isConformanceExceptionScope,
3796
+ et as isPolicyExceptionScope,
3797
+ V as layerBoundaryRule,
3798
+ ue as mergeGovernanceSignals,
3799
+ Y as missingDomainRule,
3800
+ J as missingLayerRule,
3801
+ Mr as normalizeGovernanceException,
3802
+ j as normalizeGovernanceProfile,
3803
+ Zo as normalizeGovernanceWorkspace,
3804
+ A as ownershipPresenceRule,
3805
+ U as projectNameConventionRule,
3806
+ Mt as rankTopViolations,
3807
+ Rr as registerLoadedGovernanceExtensions,
3808
+ Ln as registerLoadedGovernanceExtensionsWithDiagnostics,
3809
+ Jt as scopeGovernanceDependencies,
3810
+ h as sliceGovernancePayloadItems,
3811
+ fr as summarizeArchitectureRecommendations,
3812
+ gr as summarizeCognitiveLoad,
3813
+ Hr as summarizeDeliveryImpact,
3814
+ wr as summarizeDrift,
3815
+ en as summarizeDriftInterpretation,
3816
+ mr as summarizeManagementInsights,
3817
+ pr as summarizeOnboarding,
3818
+ lr as summarizePrImpact,
3819
+ hr as summarizeRefactoringSuggestions,
3820
+ dr as summarizeRootCause,
3821
+ ur as summarizeScorecard,
3822
+ yr as summarizeSmellClusters,
3823
+ K as tagConventionRule
1587
3824
  };