mcp-adr-analysis-server 2.7.36 → 2.7.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/resources/deployment-history-resource.d.ts +1 -0
- package/dist/src/resources/deployment-history-resource.d.ts.map +1 -1
- package/dist/src/resources/deployment-history-resource.js +7 -14
- package/dist/src/resources/deployment-history-resource.js.map +1 -1
- package/dist/src/resources/pattern-by-name-resource.d.ts.map +1 -1
- package/dist/src/resources/pattern-by-name-resource.js +1 -2
- package/dist/src/resources/pattern-by-name-resource.js.map +1 -1
- package/dist/src/resources/rule-by-id-resource.d.ts +1 -0
- package/dist/src/resources/rule-by-id-resource.d.ts.map +1 -1
- package/dist/src/resources/rule-by-id-resource.js +7 -19
- package/dist/src/resources/rule-by-id-resource.js.map +1 -1
- package/dist/src/resources/technology-by-name-resource.d.ts.map +1 -1
- package/dist/src/resources/technology-by-name-resource.js +2 -5
- package/dist/src/resources/technology-by-name-resource.js.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
- package/dist/src/tools/deployment-readiness-tool.js +187 -112
- package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
- package/dist/src/types/memory-entities.d.ts +6 -6
- package/dist/src/types/memory-entities.js +3 -3
- package/dist/src/types/memory-entities.js.map +1 -1
- package/dist/src/utils/pattern-research-utility.d.ts +1 -0
- package/dist/src/utils/pattern-research-utility.d.ts.map +1 -1
- package/dist/src/utils/pattern-research-utility.js +3 -2
- package/dist/src/utils/pattern-research-utility.js.map +1 -1
- package/dist/src/utils/research-orchestrator.d.ts +7 -4
- package/dist/src/utils/research-orchestrator.d.ts.map +1 -1
- package/dist/src/utils/research-orchestrator.js +25 -17
- package/dist/src/utils/research-orchestrator.js.map +1 -1
- package/package.json +1 -1
|
@@ -118,6 +118,41 @@ const DeploymentReadinessSchema = z.object({
|
|
|
118
118
|
.default(0.7)
|
|
119
119
|
.describe('Minimum confidence for environment research (0-1)'),
|
|
120
120
|
});
|
|
121
|
+
function unmeasuredAdrCompliance(totalAdrs, reason) {
|
|
122
|
+
return {
|
|
123
|
+
measured: false,
|
|
124
|
+
omittedReason: reason,
|
|
125
|
+
totalAdrs,
|
|
126
|
+
missingImplementations: [],
|
|
127
|
+
recommendations: [],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function unmeasuredHistory(reason) {
|
|
131
|
+
return {
|
|
132
|
+
recentDeployments: [],
|
|
133
|
+
measured: false,
|
|
134
|
+
omittedReason: reason,
|
|
135
|
+
failurePatterns: [],
|
|
136
|
+
environmentStability: {
|
|
137
|
+
measured: false,
|
|
138
|
+
riskLevel: 'unknown',
|
|
139
|
+
recommendation: reason,
|
|
140
|
+
},
|
|
141
|
+
recommendedAction: 'unknown',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function fmtMeasuredPct(value, measured) {
|
|
145
|
+
return measured && value !== undefined ? `${value}%` : 'not measured';
|
|
146
|
+
}
|
|
147
|
+
function fmtAdrScore(result) {
|
|
148
|
+
if (!result.measured || result.score === undefined) {
|
|
149
|
+
return result.omittedReason ? `not measured (${result.omittedReason})` : 'not measured';
|
|
150
|
+
}
|
|
151
|
+
return `${result.score}%`;
|
|
152
|
+
}
|
|
153
|
+
function fmtScoreField(value, measured) {
|
|
154
|
+
return measured ? `${value}%` : 'not measured';
|
|
155
|
+
}
|
|
121
156
|
/**
|
|
122
157
|
* Deployment Memory Manager for tracking deployment assessments and patterns
|
|
123
158
|
* Supports dependency injection for improved testability
|
|
@@ -153,14 +188,21 @@ class DeploymentMemoryManager {
|
|
|
153
188
|
criticalFailures: readinessData.testValidationResult.criticalTestFailures.map(f => f.testName),
|
|
154
189
|
},
|
|
155
190
|
securityValidation: {
|
|
156
|
-
vulnerabilities:
|
|
157
|
-
|
|
191
|
+
vulnerabilities: readinessData.codeQualityAnalysis.securityIssues.length,
|
|
192
|
+
...(readinessData.codeQualityAnalysis.qualityMeasured
|
|
193
|
+
? {
|
|
194
|
+
securityScore: Math.max(0, 1 -
|
|
195
|
+
readinessData.codeQualityAnalysis.securityIssues.filter(i => i.severity === 'critical').length *
|
|
196
|
+
0.3 -
|
|
197
|
+
readinessData.codeQualityAnalysis.securityIssues.filter(i => i.severity === 'high').length *
|
|
198
|
+
0.15),
|
|
199
|
+
}
|
|
200
|
+
: {}),
|
|
158
201
|
criticalIssues: readinessData.criticalBlockers
|
|
159
202
|
.filter(b => b.category === 'adr_compliance')
|
|
160
203
|
.map(b => b.title),
|
|
161
204
|
},
|
|
162
205
|
performanceValidation: {
|
|
163
|
-
performanceScore: Math.max(0, (readinessData.overallScore - 20) / 80), // Derived from overall score
|
|
164
206
|
bottlenecks: [],
|
|
165
207
|
resourceUtilization: {},
|
|
166
208
|
},
|
|
@@ -197,13 +239,19 @@ class DeploymentMemoryManager {
|
|
|
197
239
|
: 'Cannot deploy - blockers present',
|
|
198
240
|
},
|
|
199
241
|
complianceChecks: {
|
|
200
|
-
|
|
201
|
-
|
|
242
|
+
...(readinessData.adrComplianceResult.measured &&
|
|
243
|
+
readinessData.adrComplianceResult.score !== undefined
|
|
244
|
+
? { adrCompliance: readinessData.adrComplianceResult.score / 100 }
|
|
245
|
+
: {}),
|
|
246
|
+
regulatoryCompliance: [],
|
|
202
247
|
auditTrail: [
|
|
203
248
|
`Deployment assessment completed at ${new Date().toISOString()}`,
|
|
204
249
|
`Test validation: ${readinessData.testValidationResult.overallTestStatus}`,
|
|
205
250
|
`Overall readiness score: ${readinessData.overallScore}%`,
|
|
206
251
|
`Git push status: ${readinessData.gitPushStatus}`,
|
|
252
|
+
readinessData.adrComplianceResult.measured
|
|
253
|
+
? `ADR compliance measured: ${readinessData.adrComplianceResult.score}`
|
|
254
|
+
: `ADR compliance omitted: ${readinessData.adrComplianceResult.omittedReason}`,
|
|
207
255
|
],
|
|
208
256
|
},
|
|
209
257
|
};
|
|
@@ -219,7 +267,8 @@ class DeploymentMemoryManager {
|
|
|
219
267
|
`score-${Math.floor(readinessData.overallScore / 10) * 10}`,
|
|
220
268
|
...(readinessData.criticalBlockers.length > 0 ? ['critical-issues'] : []),
|
|
221
269
|
...(readinessData.testValidationResult.failureCount > 0 ? ['test-failures'] : []),
|
|
222
|
-
...(readinessData.deploymentHistoryAnalysis.rollbackRate
|
|
270
|
+
...(readinessData.deploymentHistoryAnalysis.rollbackRate !== undefined &&
|
|
271
|
+
readinessData.deploymentHistoryAnalysis.rollbackRate > 20
|
|
223
272
|
? ['high-rollback-risk']
|
|
224
273
|
: []),
|
|
225
274
|
],
|
|
@@ -381,11 +430,9 @@ class DeploymentMemoryManager {
|
|
|
381
430
|
},
|
|
382
431
|
securityValidation: {
|
|
383
432
|
vulnerabilities: 0,
|
|
384
|
-
securityScore: 0.8,
|
|
385
433
|
criticalIssues: [],
|
|
386
434
|
},
|
|
387
435
|
performanceValidation: {
|
|
388
|
-
performanceScore: deployment.status === 'success' ? 0.8 : 0.2,
|
|
389
436
|
bottlenecks: [],
|
|
390
437
|
resourceUtilization: {},
|
|
391
438
|
},
|
|
@@ -751,29 +798,13 @@ async function performTestValidation(args, projectPath) {
|
|
|
751
798
|
return {
|
|
752
799
|
isDeploymentReady: testBlockers.length === 0,
|
|
753
800
|
overallScore: calculateTestScore(testResult, args),
|
|
754
|
-
|
|
801
|
+
scoreMeasured: testResult.overallTestStatus !== 'not_run',
|
|
802
|
+
confidence: calculateTestScore(testResult, args),
|
|
803
|
+
confidenceMeasured: testResult.overallTestStatus !== 'not_run',
|
|
755
804
|
codeQualityAnalysis: await analyzeCodeQualityWithTreeSitter(args.projectPath || process.cwd(), args.enableTreeSitterAnalysis, args.treeSitterLanguages),
|
|
756
805
|
testValidationResult: testResult,
|
|
757
|
-
deploymentHistoryAnalysis:
|
|
758
|
-
|
|
759
|
-
successRate: 100,
|
|
760
|
-
rollbackRate: 0,
|
|
761
|
-
averageDeploymentTime: 0,
|
|
762
|
-
failurePatterns: [],
|
|
763
|
-
environmentStability: {
|
|
764
|
-
stabilityScore: 100,
|
|
765
|
-
riskLevel: 'low',
|
|
766
|
-
recommendation: 'Proceed with deployment',
|
|
767
|
-
},
|
|
768
|
-
recommendedAction: 'proceed',
|
|
769
|
-
},
|
|
770
|
-
adrComplianceResult: {
|
|
771
|
-
score: 100,
|
|
772
|
-
compliantAdrs: 0,
|
|
773
|
-
totalAdrs: 0,
|
|
774
|
-
missingImplementations: [],
|
|
775
|
-
recommendations: [],
|
|
776
|
-
},
|
|
806
|
+
deploymentHistoryAnalysis: unmeasuredHistory('test validation does not load deployment history'),
|
|
807
|
+
adrComplianceResult: unmeasuredAdrCompliance(0, 'ADR compliance is not evaluated on the test-validation path'),
|
|
777
808
|
criticalBlockers: testBlockers.filter(b => b.severity === 'critical'),
|
|
778
809
|
testFailureBlockers: testBlockers,
|
|
779
810
|
deploymentHistoryBlockers: [],
|
|
@@ -931,8 +962,10 @@ async function performDeploymentHistoryAnalysis(args, historyPath) {
|
|
|
931
962
|
const history = loadDeploymentHistory(historyPath);
|
|
932
963
|
const analysis = analyzeDeploymentHistory(history, args.targetEnvironment);
|
|
933
964
|
const historyBlockers = [];
|
|
934
|
-
// Check success rate
|
|
935
|
-
if (analysis.
|
|
965
|
+
// Check success rate only when history was actually measured
|
|
966
|
+
if (analysis.measured &&
|
|
967
|
+
analysis.successRate !== undefined &&
|
|
968
|
+
analysis.successRate < args.deploymentSuccessThreshold) {
|
|
936
969
|
historyBlockers.push({
|
|
937
970
|
category: 'deployment_history',
|
|
938
971
|
title: 'Low Deployment Success Rate',
|
|
@@ -950,7 +983,9 @@ async function performDeploymentHistoryAnalysis(args, historyPath) {
|
|
|
950
983
|
});
|
|
951
984
|
}
|
|
952
985
|
// Check rollback rate
|
|
953
|
-
if (analysis.
|
|
986
|
+
if (analysis.measured &&
|
|
987
|
+
analysis.rollbackRate !== undefined &&
|
|
988
|
+
analysis.rollbackRate > args.rollbackFrequencyThreshold) {
|
|
954
989
|
historyBlockers.push({
|
|
955
990
|
category: 'deployment_history',
|
|
956
991
|
title: 'High Rollback Frequency',
|
|
@@ -969,8 +1004,12 @@ async function performDeploymentHistoryAnalysis(args, historyPath) {
|
|
|
969
1004
|
}
|
|
970
1005
|
return {
|
|
971
1006
|
isDeploymentReady: historyBlockers.length === 0,
|
|
972
|
-
overallScore:
|
|
973
|
-
|
|
1007
|
+
overallScore: analysis.measured && analysis.successRate !== undefined
|
|
1008
|
+
? Math.min(analysis.successRate, 100 - (analysis.rollbackRate ?? 0))
|
|
1009
|
+
: 0,
|
|
1010
|
+
scoreMeasured: analysis.measured,
|
|
1011
|
+
confidence: analysis.measured ? Math.min(100, analysis.recentDeployments.length * 10) : 0,
|
|
1012
|
+
confidenceMeasured: analysis.measured,
|
|
974
1013
|
codeQualityAnalysis: await analyzeCodeQualityWithTreeSitter(args.projectPath || process.cwd(), args.enableTreeSitterAnalysis, args.treeSitterLanguages),
|
|
975
1014
|
testValidationResult: {
|
|
976
1015
|
testSuitesExecuted: [],
|
|
@@ -983,13 +1022,7 @@ async function performDeploymentHistoryAnalysis(args, historyPath) {
|
|
|
983
1022
|
lastTestRun: '',
|
|
984
1023
|
},
|
|
985
1024
|
deploymentHistoryAnalysis: analysis,
|
|
986
|
-
adrComplianceResult:
|
|
987
|
-
score: 100,
|
|
988
|
-
compliantAdrs: 0,
|
|
989
|
-
totalAdrs: 0,
|
|
990
|
-
missingImplementations: [],
|
|
991
|
-
recommendations: [],
|
|
992
|
-
},
|
|
1025
|
+
adrComplianceResult: unmeasuredAdrCompliance(0, 'ADR compliance is not evaluated on the history-analysis path'),
|
|
993
1026
|
criticalBlockers: historyBlockers.filter(b => b.severity === 'critical'),
|
|
994
1027
|
testFailureBlockers: [],
|
|
995
1028
|
deploymentHistoryBlockers: historyBlockers,
|
|
@@ -1024,11 +1057,15 @@ function analyzeDeploymentHistory(history, environment) {
|
|
|
1024
1057
|
.slice(0, 10);
|
|
1025
1058
|
const successCount = recentDeployments.filter(d => d.status === 'success').length;
|
|
1026
1059
|
const rollbackCount = recentDeployments.filter(d => d.rollbackRequired).length;
|
|
1027
|
-
|
|
1028
|
-
|
|
1060
|
+
if (recentDeployments.length === 0) {
|
|
1061
|
+
return unmeasuredHistory(`no deployment records for ${environment}`);
|
|
1062
|
+
}
|
|
1063
|
+
const successRate = (successCount / recentDeployments.length) * 100;
|
|
1064
|
+
const rollbackRate = (rollbackCount / recentDeployments.length) * 100;
|
|
1029
1065
|
const failurePatterns = analyzeFailurePatterns(recentDeployments.filter(d => d.status === 'failed'));
|
|
1030
1066
|
return {
|
|
1031
1067
|
recentDeployments,
|
|
1068
|
+
measured: true,
|
|
1032
1069
|
successRate,
|
|
1033
1070
|
rollbackRate,
|
|
1034
1071
|
averageDeploymentTime: calculateAverageDeploymentTime(recentDeployments),
|
|
@@ -1172,25 +1209,36 @@ async function performFullAudit(args, projectPath, historyPath) {
|
|
|
1172
1209
|
return deploymentKeywords.some(keyword => file.path.toLowerCase().includes(keyword) ||
|
|
1173
1210
|
file.directory.toLowerCase().includes(keyword));
|
|
1174
1211
|
});
|
|
1175
|
-
adrComplianceResult =
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
: [
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
:
|
|
1192
|
-
|
|
1193
|
-
|
|
1212
|
+
adrComplianceResult =
|
|
1213
|
+
relatedCodeResult.relatedFiles.length === 0
|
|
1214
|
+
? {
|
|
1215
|
+
measured: true,
|
|
1216
|
+
score: 0,
|
|
1217
|
+
compliantAdrs: 0,
|
|
1218
|
+
totalAdrs: discoveryResult.adrs.length,
|
|
1219
|
+
missingImplementations: [
|
|
1220
|
+
'No related implementation files found for discovered ADRs',
|
|
1221
|
+
],
|
|
1222
|
+
recommendations: [
|
|
1223
|
+
'ADR compliance failed: ADRs exist but no linked implementation was found',
|
|
1224
|
+
],
|
|
1225
|
+
}
|
|
1226
|
+
: {
|
|
1227
|
+
measured: false,
|
|
1228
|
+
omittedReason: 'related-code linking is not a per-ADR compliance verdict; refusing to mark every ADR compliant',
|
|
1229
|
+
totalAdrs: discoveryResult.adrs.length,
|
|
1230
|
+
missingImplementations: deploymentCriticalFiles.length === 0
|
|
1231
|
+
? ['Deployment-specific implementations not found in related code']
|
|
1232
|
+
: [],
|
|
1233
|
+
recommendations: [
|
|
1234
|
+
...(deploymentCriticalFiles.length > 0
|
|
1235
|
+
? [
|
|
1236
|
+
`Found ${deploymentCriticalFiles.length} deployment-critical files linked to ADRs`,
|
|
1237
|
+
]
|
|
1238
|
+
: ['Consider documenting deployment procedures in ADRs']),
|
|
1239
|
+
'Do not treat file linkage as ADR compliance',
|
|
1240
|
+
],
|
|
1241
|
+
};
|
|
1194
1242
|
smartCodeAnalysis = `
|
|
1195
1243
|
|
|
1196
1244
|
## 🔗 Smart Code Linking - Deployment Analysis
|
|
@@ -1261,11 +1309,43 @@ ${deploymentCriticalFiles.length > 0
|
|
|
1261
1309
|
}
|
|
1262
1310
|
});
|
|
1263
1311
|
}
|
|
1312
|
+
const adrBlockers = [];
|
|
1313
|
+
if (args.requireAdrCompliance &&
|
|
1314
|
+
adrComplianceResult.measured &&
|
|
1315
|
+
adrComplianceResult.score === 0) {
|
|
1316
|
+
adrBlockers.push({
|
|
1317
|
+
category: 'adr_compliance',
|
|
1318
|
+
title: 'ADR compliance failed',
|
|
1319
|
+
description: adrComplianceResult.missingImplementations.join('; ') ||
|
|
1320
|
+
'ADRs exist but compliance could not be established',
|
|
1321
|
+
severity: 'critical',
|
|
1322
|
+
impact: 'Blocks deployment: architectural decisions are not shown as implemented',
|
|
1323
|
+
resolutionSteps: ['Link ADRs to implementing code', 'Or document why an ADR has no code yet'],
|
|
1324
|
+
estimatedResolutionTime: '1-4 hours',
|
|
1325
|
+
blocksDeployment: true,
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
const securityBlockers = [];
|
|
1329
|
+
const criticalSecurity = testResult.codeQualityAnalysis.securityIssues.filter(i => i.severity === 'critical');
|
|
1330
|
+
if (testResult.codeQualityAnalysis.qualityMeasured && criticalSecurity.length > 0) {
|
|
1331
|
+
securityBlockers.push({
|
|
1332
|
+
category: 'code_quality',
|
|
1333
|
+
title: 'Critical security findings',
|
|
1334
|
+
description: `${criticalSecurity.length} critical security issue(s) in scanned files`,
|
|
1335
|
+
severity: 'critical',
|
|
1336
|
+
impact: 'Blocks deployment: security issues were measured, not assumed',
|
|
1337
|
+
resolutionSteps: criticalSecurity.slice(0, 5).map(i => `Fix ${i.type} in ${i.file}`),
|
|
1338
|
+
estimatedResolutionTime: '1-8 hours',
|
|
1339
|
+
blocksDeployment: true,
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1264
1342
|
const allBlockers = [
|
|
1265
1343
|
...testResult.criticalBlockers,
|
|
1266
1344
|
...testResult.testFailureBlockers,
|
|
1267
1345
|
...historyResult.deploymentHistoryBlockers,
|
|
1268
1346
|
...environmentBlockers,
|
|
1347
|
+
...adrBlockers,
|
|
1348
|
+
...securityBlockers,
|
|
1269
1349
|
];
|
|
1270
1350
|
// Adjust overall score based on environment research confidence
|
|
1271
1351
|
const baseScore = (testResult.overallScore + historyResult.overallScore) / 2;
|
|
@@ -1275,7 +1355,9 @@ ${deploymentCriticalFiles.length > 0
|
|
|
1275
1355
|
const result = {
|
|
1276
1356
|
isDeploymentReady: isReady,
|
|
1277
1357
|
overallScore,
|
|
1358
|
+
scoreMeasured: testResult.scoreMeasured || historyResult.scoreMeasured,
|
|
1278
1359
|
confidence: Math.min(testResult.confidence, historyResult.confidence, environmentResearch.confidence * 100),
|
|
1360
|
+
confidenceMeasured: testResult.confidenceMeasured || historyResult.confidenceMeasured,
|
|
1279
1361
|
codeQualityAnalysis: testResult.codeQualityAnalysis,
|
|
1280
1362
|
testValidationResult: testResult.testValidationResult,
|
|
1281
1363
|
deploymentHistoryAnalysis: historyResult.deploymentHistoryAnalysis,
|
|
@@ -1316,8 +1398,10 @@ async function performEmergencyOverride(args, projectPath) {
|
|
|
1316
1398
|
return {
|
|
1317
1399
|
isDeploymentReady: true,
|
|
1318
1400
|
overallScore: 100,
|
|
1319
|
-
|
|
1320
|
-
|
|
1401
|
+
scoreMeasured: false,
|
|
1402
|
+
confidence: 0,
|
|
1403
|
+
confidenceMeasured: false,
|
|
1404
|
+
codeQualityAnalysis: createDefaultCodeQualityAnalysis(),
|
|
1321
1405
|
testValidationResult: {
|
|
1322
1406
|
testSuitesExecuted: [],
|
|
1323
1407
|
overallTestStatus: 'not_run',
|
|
@@ -1328,26 +1412,8 @@ async function performEmergencyOverride(args, projectPath) {
|
|
|
1328
1412
|
testExecutionTime: 0,
|
|
1329
1413
|
lastTestRun: '',
|
|
1330
1414
|
},
|
|
1331
|
-
deploymentHistoryAnalysis:
|
|
1332
|
-
|
|
1333
|
-
successRate: 100,
|
|
1334
|
-
rollbackRate: 0,
|
|
1335
|
-
averageDeploymentTime: 0,
|
|
1336
|
-
failurePatterns: [],
|
|
1337
|
-
environmentStability: {
|
|
1338
|
-
stabilityScore: 50,
|
|
1339
|
-
riskLevel: 'medium',
|
|
1340
|
-
recommendation: 'Monitor closely post-deployment',
|
|
1341
|
-
},
|
|
1342
|
-
recommendedAction: 'proceed',
|
|
1343
|
-
},
|
|
1344
|
-
adrComplianceResult: {
|
|
1345
|
-
score: 100,
|
|
1346
|
-
compliantAdrs: 0,
|
|
1347
|
-
totalAdrs: 0,
|
|
1348
|
-
missingImplementations: [],
|
|
1349
|
-
recommendations: [],
|
|
1350
|
-
},
|
|
1415
|
+
deploymentHistoryAnalysis: unmeasuredHistory('emergency override bypassed history measurement'),
|
|
1416
|
+
adrComplianceResult: unmeasuredAdrCompliance(0, 'emergency override bypassed ADR compliance measurement'),
|
|
1351
1417
|
criticalBlockers: [],
|
|
1352
1418
|
testFailureBlockers: [],
|
|
1353
1419
|
deploymentHistoryBlockers: [],
|
|
@@ -1384,6 +1450,7 @@ function assessEnvironmentStability(successRate, rollbackRate) {
|
|
|
1384
1450
|
else
|
|
1385
1451
|
riskLevel = 'critical';
|
|
1386
1452
|
return {
|
|
1453
|
+
measured: true,
|
|
1387
1454
|
stabilityScore,
|
|
1388
1455
|
riskLevel,
|
|
1389
1456
|
recommendation: riskLevel === 'low' ? 'Proceed with deployment' : 'Investigate before deployment',
|
|
@@ -1456,8 +1523,8 @@ function generateSuccessResponse(result, args) {
|
|
|
1456
1523
|
|
|
1457
1524
|
## 🎯 Overall Assessment
|
|
1458
1525
|
- **Deployment Ready**: ✅ **YES**
|
|
1459
|
-
- **Readiness Score**: ${result.overallScore}
|
|
1460
|
-
- **Confidence**: ${result.confidence}
|
|
1526
|
+
- **Readiness Score**: ${fmtScoreField(result.overallScore, result.scoreMeasured)}
|
|
1527
|
+
- **Confidence**: ${fmtScoreField(result.confidence, result.confidenceMeasured)}
|
|
1461
1528
|
- **Target Environment**: ${args.targetEnvironment}
|
|
1462
1529
|
- **Fast File Discovery**: ✅ Enhanced with fast-glob
|
|
1463
1530
|
|
|
@@ -1468,13 +1535,13 @@ function generateSuccessResponse(result, args) {
|
|
|
1468
1535
|
- **Execution Time**: ${result.testValidationResult.testExecutionTime}ms
|
|
1469
1536
|
|
|
1470
1537
|
## 📊 Deployment History
|
|
1471
|
-
- **Success Rate**: ${result.deploymentHistoryAnalysis.successRate}
|
|
1472
|
-
- **Rollback Rate**: ${result.deploymentHistoryAnalysis.rollbackRate}
|
|
1538
|
+
- **Success Rate**: ${fmtMeasuredPct(result.deploymentHistoryAnalysis.successRate, result.deploymentHistoryAnalysis.measured)}
|
|
1539
|
+
- **Rollback Rate**: ${fmtMeasuredPct(result.deploymentHistoryAnalysis.rollbackRate, result.deploymentHistoryAnalysis.measured)}
|
|
1473
1540
|
- **Environment Stability**: ${result.deploymentHistoryAnalysis.environmentStability.riskLevel}
|
|
1474
1541
|
|
|
1475
1542
|
## 🏛️ ADR Compliance
|
|
1476
|
-
- **Compliance Score**: ${result.adrComplianceResult
|
|
1477
|
-
- **ADRs Analyzed**: ${result.adrComplianceResult.compliantAdrs}/${result.adrComplianceResult.totalAdrs}
|
|
1543
|
+
- **Compliance Score**: ${fmtAdrScore(result.adrComplianceResult)}
|
|
1544
|
+
- **ADRs Analyzed**: ${result.adrComplianceResult.measured ? `${result.adrComplianceResult.compliantAdrs}/${result.adrComplianceResult.totalAdrs}` : `not measured (${result.adrComplianceResult.totalAdrs} discovered)`}
|
|
1478
1545
|
- **Missing Implementations**: ${result.adrComplianceResult.missingImplementations.length} items
|
|
1479
1546
|
|
|
1480
1547
|
${result.environmentResearch
|
|
@@ -1525,8 +1592,8 @@ function generateBlockedResponse(result, args) {
|
|
|
1525
1592
|
text: `# 🚨 DEPLOYMENT BLOCKED - Critical Issues Detected
|
|
1526
1593
|
|
|
1527
1594
|
## ⚠️ Deployment Readiness: ${result.isDeploymentReady ? '✅ READY' : '❌ BLOCKED'}
|
|
1528
|
-
- **Overall Score**: ${result.overallScore}/100
|
|
1529
|
-
- **Confidence**: ${result.confidence}
|
|
1595
|
+
- **Overall Score**: ${result.scoreMeasured ? `${result.overallScore}/100` : 'not measured'}
|
|
1596
|
+
- **Confidence**: ${fmtScoreField(result.confidence, result.confidenceMeasured)}
|
|
1530
1597
|
- **Target Environment**: ${args.targetEnvironment}
|
|
1531
1598
|
- **Tree-sitter Analysis**: ${args.enableTreeSitterAnalysis ? '✅ Enhanced' : '❌ Basic'}
|
|
1532
1599
|
- **Fast File Discovery**: ✅ Enhanced with fast-glob
|
|
@@ -1556,8 +1623,8 @@ ${result.testValidationResult.criticalTestFailures.map(f => `- ❌ ${f.testSuite
|
|
|
1556
1623
|
## 📊 Deployment History Issues
|
|
1557
1624
|
${result.deploymentHistoryBlockers.length > 0
|
|
1558
1625
|
? `
|
|
1559
|
-
**Success Rate**: ${result.deploymentHistoryAnalysis.successRate}
|
|
1560
|
-
**Rollback Rate**: ${result.deploymentHistoryAnalysis.rollbackRate}
|
|
1626
|
+
**Success Rate**: ${fmtMeasuredPct(result.deploymentHistoryAnalysis.successRate, result.deploymentHistoryAnalysis.measured)} (Required: ${args.deploymentSuccessThreshold}%)
|
|
1627
|
+
**Rollback Rate**: ${fmtMeasuredPct(result.deploymentHistoryAnalysis.rollbackRate, result.deploymentHistoryAnalysis.measured)} (Threshold: ${args.rollbackFrequencyThreshold}%)
|
|
1561
1628
|
|
|
1562
1629
|
### Recent Failure Patterns:
|
|
1563
1630
|
${result.deploymentHistoryAnalysis.failurePatterns.map(p => `- **${p.pattern}**: ${p.frequency} occurrences`).join('\n')}
|
|
@@ -1638,11 +1705,10 @@ npm run deploy:emergency -- --justification="Critical security fix"
|
|
|
1638
1705
|
/**
|
|
1639
1706
|
* Create default CodeQualityAnalysis structure
|
|
1640
1707
|
*/
|
|
1641
|
-
function createDefaultCodeQualityAnalysis(
|
|
1708
|
+
function createDefaultCodeQualityAnalysis() {
|
|
1642
1709
|
return {
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
mockIndicators,
|
|
1710
|
+
qualityMeasured: false,
|
|
1711
|
+
indicatorsMeasured: false,
|
|
1646
1712
|
failingFiles: [],
|
|
1647
1713
|
recommendations: [],
|
|
1648
1714
|
securityIssues: [],
|
|
@@ -1676,9 +1742,21 @@ async function analyzeCodeQualityWithTreeSitter(projectPath, enableTreeSitter, _
|
|
|
1676
1742
|
const filesToAnalyze = sourceFiles.slice(0, 20);
|
|
1677
1743
|
let totalComplexity = 0;
|
|
1678
1744
|
let totalFunctions = 0;
|
|
1745
|
+
let productionIndicators = 0;
|
|
1746
|
+
let mockIndicators = 0;
|
|
1679
1747
|
const highComplexityFiles = [];
|
|
1680
1748
|
for (const filePath of filesToAnalyze) {
|
|
1681
1749
|
try {
|
|
1750
|
+
const pathLower = filePath.toLowerCase();
|
|
1751
|
+
if (pathLower.includes('mock') ||
|
|
1752
|
+
pathLower.includes('.test.') ||
|
|
1753
|
+
pathLower.includes('.spec.') ||
|
|
1754
|
+
pathLower.includes('__tests__')) {
|
|
1755
|
+
mockIndicators++;
|
|
1756
|
+
}
|
|
1757
|
+
else {
|
|
1758
|
+
productionIndicators++;
|
|
1759
|
+
}
|
|
1682
1760
|
const analysis = await analyzer.analyzeFile(filePath);
|
|
1683
1761
|
// Security issues
|
|
1684
1762
|
if (analysis.hasSecrets && analysis.secrets.length > 0) {
|
|
@@ -1760,22 +1838,19 @@ async function analyzeCodeQualityWithTreeSitter(projectPath, enableTreeSitter, _
|
|
|
1760
1838
|
highComplexityFiles: highComplexityFiles.slice(0, 10), // Limit to top 10
|
|
1761
1839
|
totalFunctions,
|
|
1762
1840
|
};
|
|
1763
|
-
// Calculate enhanced quality score
|
|
1764
|
-
let qualityScore = 85; // Base score
|
|
1765
|
-
// Deduct for security issues
|
|
1766
1841
|
const criticalSecurity = baseAnalysis.securityIssues.filter(i => i.severity === 'critical').length;
|
|
1767
1842
|
const highSecurity = baseAnalysis.securityIssues.filter(i => i.severity === 'high').length;
|
|
1768
|
-
qualityScore
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
baseAnalysis.
|
|
1776
|
-
|
|
1777
|
-
baseAnalysis.
|
|
1778
|
-
baseAnalysis.
|
|
1843
|
+
const qualityScore = Math.max(0, Math.min(100, 100 -
|
|
1844
|
+
criticalSecurity * 20 -
|
|
1845
|
+
highSecurity * 10 -
|
|
1846
|
+
Math.min(baseAnalysis.dependencyAnalysis.dangerousImports.length * 5, 20) -
|
|
1847
|
+
Math.min(highComplexityFiles.length * 2, 15) +
|
|
1848
|
+
Math.min(baseAnalysis.dependencyAnalysis.securityLibraries.length * 2, 10)));
|
|
1849
|
+
baseAnalysis.qualityScore = qualityScore;
|
|
1850
|
+
baseAnalysis.qualityMeasured = true;
|
|
1851
|
+
baseAnalysis.productionIndicators = productionIndicators;
|
|
1852
|
+
baseAnalysis.mockIndicators = mockIndicators;
|
|
1853
|
+
baseAnalysis.indicatorsMeasured = true;
|
|
1779
1854
|
return baseAnalysis;
|
|
1780
1855
|
}
|
|
1781
1856
|
catch (error) {
|