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