mcp-adr-analysis-server 2.7.35 → 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.
Files changed (30) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/src/resources/deployment-history-resource.d.ts +1 -0
  3. package/dist/src/resources/deployment-history-resource.d.ts.map +1 -1
  4. package/dist/src/resources/deployment-history-resource.js +7 -14
  5. package/dist/src/resources/deployment-history-resource.js.map +1 -1
  6. package/dist/src/resources/pattern-by-name-resource.d.ts.map +1 -1
  7. package/dist/src/resources/pattern-by-name-resource.js +1 -2
  8. package/dist/src/resources/pattern-by-name-resource.js.map +1 -1
  9. package/dist/src/resources/rule-by-id-resource.d.ts +1 -0
  10. package/dist/src/resources/rule-by-id-resource.d.ts.map +1 -1
  11. package/dist/src/resources/rule-by-id-resource.js +7 -19
  12. package/dist/src/resources/rule-by-id-resource.js.map +1 -1
  13. package/dist/src/resources/technology-by-name-resource.d.ts.map +1 -1
  14. package/dist/src/resources/technology-by-name-resource.js +2 -5
  15. package/dist/src/resources/technology-by-name-resource.js.map +1 -1
  16. package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
  17. package/dist/src/tools/deployment-readiness-tool.js +187 -112
  18. package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
  19. package/dist/src/types/memory-entities.d.ts +6 -6
  20. package/dist/src/types/memory-entities.js +3 -3
  21. package/dist/src/types/memory-entities.js.map +1 -1
  22. package/dist/src/utils/pattern-research-utility.d.ts +1 -0
  23. package/dist/src/utils/pattern-research-utility.d.ts.map +1 -1
  24. package/dist/src/utils/pattern-research-utility.js +3 -2
  25. package/dist/src/utils/pattern-research-utility.js.map +1 -1
  26. package/dist/src/utils/research-orchestrator.d.ts +7 -4
  27. package/dist/src/utils/research-orchestrator.d.ts.map +1 -1
  28. package/dist/src/utils/research-orchestrator.js +25 -17
  29. package/dist/src/utils/research-orchestrator.js.map +1 -1
  30. 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: 0, // Default - could be enhanced with actual security scan data
157
- securityScore: 0.8, // Default - could be enhanced with actual security analysis
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
- adrCompliance: readinessData.adrComplianceResult.score / 100, // Convert to 0-1 range
201
- regulatoryCompliance: [], // Could be enhanced with actual compliance data
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 > 20
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
- confidence: 85,
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
- recentDeployments: [],
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.successRate < args.deploymentSuccessThreshold) {
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.rollbackRate > args.rollbackFrequencyThreshold) {
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: Math.min(analysis.successRate, 100 - analysis.rollbackRate),
973
- confidence: 80,
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
- const successRate = recentDeployments.length > 0 ? (successCount / recentDeployments.length) * 100 : 100;
1028
- const rollbackRate = recentDeployments.length > 0 ? (rollbackCount / recentDeployments.length) * 100 : 0;
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
- score: Math.min(100, 70 + relatedCodeResult.confidence * 30),
1177
- compliantAdrs: discoveryResult.adrs.length,
1178
- totalAdrs: discoveryResult.adrs.length,
1179
- missingImplementations: deploymentCriticalFiles.length === 0
1180
- ? ['Deployment-specific implementations not found in related code']
1181
- : [],
1182
- recommendations: [
1183
- ...(deploymentCriticalFiles.length > 0
1184
- ? [`Found ${deploymentCriticalFiles.length} deployment-critical files linked to ADRs`]
1185
- : ['Consider documenting deployment procedures in ADRs']),
1186
- ...(relatedCodeResult.relatedFiles.length > 10
1187
- ? ['High code-ADR linkage indicates good architectural documentation']
1188
- : ['Consider improving ADR-to-code traceability']),
1189
- ...(relatedCodeResult.confidence > 0.8
1190
- ? ['Strong architectural alignment detected between ADRs and implementation']
1191
- : ['Review ADR implementation alignment before deployment']),
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
- confidence: 50, // Lower confidence for overrides
1320
- codeQualityAnalysis: createDefaultCodeQualityAnalysis(100, 0, 0),
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
- recentDeployments: [],
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.score}%
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}% (Required: ${args.deploymentSuccessThreshold}%)
1560
- **Rollback Rate**: ${result.deploymentHistoryAnalysis.rollbackRate}% (Threshold: ${args.rollbackFrequencyThreshold}%)
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(qualityScore = 75, productionIndicators = 10, mockIndicators = 2) {
1708
+ function createDefaultCodeQualityAnalysis() {
1642
1709
  return {
1643
- qualityScore,
1644
- productionIndicators,
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 -= criticalSecurity * 20 + highSecurity * 10;
1769
- // Deduct for dangerous imports
1770
- qualityScore -= Math.min(baseAnalysis.dependencyAnalysis.dangerousImports.length * 5, 20);
1771
- // Deduct for high complexity
1772
- qualityScore -= Math.min(highComplexityFiles.length * 2, 15);
1773
- // Bonus for security libraries
1774
- qualityScore += Math.min(baseAnalysis.dependencyAnalysis.securityLibraries.length * 2, 10);
1775
- baseAnalysis.qualityScore = Math.max(0, Math.min(100, qualityScore));
1776
- // Update production/mock indicators based on analysis
1777
- baseAnalysis.productionIndicators = Math.max(10, baseAnalysis.qualityScore - 20);
1778
- baseAnalysis.mockIndicators = Math.max(0, 100 - baseAnalysis.qualityScore) / 10;
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) {