framework-mcp 1.1.0 → 1.1.1
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 +92 -9
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +312 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +399 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "framework-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "MCP server for analyzing vendor responses against CIS Controls Framework using 4 GRC attributes (Governance, Facilitates, Coverage, Validates)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
package/src/index.ts
CHANGED
|
@@ -84,6 +84,25 @@ interface AnalysisResult {
|
|
|
84
84
|
recommendations: string[];
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
interface ValidationResult {
|
|
88
|
+
vendor: string;
|
|
89
|
+
safeguard_id: string;
|
|
90
|
+
safeguard_title: string;
|
|
91
|
+
claimed_capability: string;
|
|
92
|
+
validation_status: 'SUPPORTED' | 'QUESTIONABLE' | 'UNSUPPORTED';
|
|
93
|
+
confidence_score: number; // 0-100
|
|
94
|
+
evidence_analysis: {
|
|
95
|
+
core_requirements_coverage: number;
|
|
96
|
+
sub_elements_coverage: number;
|
|
97
|
+
governance_alignment: number;
|
|
98
|
+
language_consistency: number;
|
|
99
|
+
};
|
|
100
|
+
gaps_identified: string[];
|
|
101
|
+
strengths_identified: string[];
|
|
102
|
+
recommendations: string[];
|
|
103
|
+
detailed_feedback: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
87
106
|
// Enhanced CIS Controls Framework Data with color-coded categorization
|
|
88
107
|
const CIS_SAFEGUARDS: Record<string, SafeguardElement> = {
|
|
89
108
|
"1.1": {
|
|
@@ -5633,6 +5652,35 @@ export class GRCAnalysisServer {
|
|
|
5633
5652
|
}
|
|
5634
5653
|
}
|
|
5635
5654
|
}
|
|
5655
|
+
} as Tool,
|
|
5656
|
+
{
|
|
5657
|
+
name: 'validate_vendor_mapping',
|
|
5658
|
+
description: 'Validate whether a vendor\'s stated capability mapping (Full/Partial/Facilitates/Governance/Validates) is actually supported by their explanatory text for a specific CIS safeguard',
|
|
5659
|
+
inputSchema: {
|
|
5660
|
+
type: 'object',
|
|
5661
|
+
properties: {
|
|
5662
|
+
vendor_name: {
|
|
5663
|
+
type: 'string',
|
|
5664
|
+
description: 'Name of the vendor (optional)',
|
|
5665
|
+
default: 'Unknown Vendor'
|
|
5666
|
+
},
|
|
5667
|
+
safeguard_id: {
|
|
5668
|
+
type: 'string',
|
|
5669
|
+
description: 'CIS Control safeguard ID (e.g., "5.1", "1.1", "6.3")',
|
|
5670
|
+
pattern: '^[0-9]+\\.[0-9]+$'
|
|
5671
|
+
},
|
|
5672
|
+
claimed_capability: {
|
|
5673
|
+
type: 'string',
|
|
5674
|
+
enum: ['full', 'partial', 'facilitates', 'governance', 'validates'],
|
|
5675
|
+
description: 'Vendor\'s claimed capability mapping for this safeguard'
|
|
5676
|
+
},
|
|
5677
|
+
supporting_text: {
|
|
5678
|
+
type: 'string',
|
|
5679
|
+
description: 'Vendor\'s supporting text blob explaining how they meet the claimed capability'
|
|
5680
|
+
}
|
|
5681
|
+
},
|
|
5682
|
+
required: ['safeguard_id', 'claimed_capability', 'supporting_text']
|
|
5683
|
+
}
|
|
5636
5684
|
} as Tool
|
|
5637
5685
|
],
|
|
5638
5686
|
}));
|
|
@@ -5650,6 +5698,8 @@ export class GRCAnalysisServer {
|
|
|
5650
5698
|
return await this.validateCoverageClaim(args);
|
|
5651
5699
|
case 'list_available_safeguards':
|
|
5652
5700
|
return await this.listAvailableSafeguards(args);
|
|
5701
|
+
case 'validate_vendor_mapping':
|
|
5702
|
+
return await this.validateVendorMapping(args);
|
|
5653
5703
|
default:
|
|
5654
5704
|
throw new Error(`Unknown tool: ${name}`);
|
|
5655
5705
|
}
|
|
@@ -5817,6 +5867,11 @@ export class GRCAnalysisServer {
|
|
|
5817
5867
|
'improve', 'enhance', 'optimize', 'faster', 'better', 'stronger', 'automate',
|
|
5818
5868
|
'streamline', 'efficiency', 'facilitate', 'support', 'enable', 'accelerate',
|
|
5819
5869
|
'api', 'integration', 'data', 'export', 'import', 'sync', 'feed',
|
|
5870
|
+
// Data provision and enrichment
|
|
5871
|
+
'provides data', 'data source', 'data feeds', 'enrichment', 'data enrichment',
|
|
5872
|
+
'supplemental data', 'additional data', 'contextual data', 'threat data',
|
|
5873
|
+
'intelligence feeds', 'data aggregation', 'data collection', 'data gathering',
|
|
5874
|
+
'feeds data', 'populates', 'informs', 'enriches', 'supplements',
|
|
5820
5875
|
// Governance/process facilitation (new keywords for tools like Upolicy)
|
|
5821
5876
|
'enables compliance', 'facilitates implementation', 'supports compliance',
|
|
5822
5877
|
'creates framework', 'enables organizations', 'infrastructure', 'foundation',
|
|
@@ -5827,9 +5882,9 @@ export class GRCAnalysisServer {
|
|
|
5827
5882
|
|
|
5828
5883
|
const validatesKeywords = [
|
|
5829
5884
|
'audit', 'report', 'evidence', 'verify', 'validate', 'check', 'monitor',
|
|
5830
|
-
'compliance report', 'assessment', 'logging', 'tracking', 'review', 'attest',
|
|
5885
|
+
'compliance', 'compliance report', 'assessment', 'logging', 'tracking', 'review', 'attest',
|
|
5831
5886
|
'dashboard', 'metrics', 'analytics', 'visibility', 'alert', 'attestation',
|
|
5832
|
-
'compliance tracking', 'audit trail', 'reporting capabilities'
|
|
5887
|
+
'compliance tracking', 'audit trail', 'reporting capabilities', 'audit capabilities'
|
|
5833
5888
|
];
|
|
5834
5889
|
|
|
5835
5890
|
// Analyze element coverage (binary: covered or not)
|
|
@@ -5865,19 +5920,25 @@ export class GRCAnalysisServer {
|
|
|
5865
5920
|
];
|
|
5866
5921
|
const hasNonImplementationLanguage = nonImplementationPatterns.some(pattern => text.includes(pattern));
|
|
5867
5922
|
|
|
5868
|
-
// Determine if full or partial coverage (based on core + sub-taxonomical elements)
|
|
5869
|
-
|
|
5870
|
-
|
|
5923
|
+
// Determine if full or partial coverage (based on core + sub-taxonomical elements WITHIN SCOPE)
|
|
5924
|
+
// Full = addresses majority of core requirements + substantial sub-elements within their stated scope
|
|
5925
|
+
// Partial = addresses some core requirements with clear scope boundaries
|
|
5926
|
+
|
|
5927
|
+
const corePercentage = safeguard.coreRequirements.length > 0 ?
|
|
5928
|
+
(coreCoverage.coveredElements.length / safeguard.coreRequirements.length) * 100 : 0;
|
|
5929
|
+
const subElementPercentage = safeguard.subTaxonomicalElements.length > 0 ?
|
|
5930
|
+
(subElementCoverage.coveredElements.length / safeguard.subTaxonomicalElements.length) * 100 : 0;
|
|
5871
5931
|
|
|
5872
5932
|
let fullCapability = false;
|
|
5873
5933
|
let partialCapability = false;
|
|
5874
5934
|
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5935
|
+
// Full capability: High coverage of core requirements + reasonable sub-element coverage
|
|
5936
|
+
if (corePercentage >= 70 && subElementPercentage >= 50) {
|
|
5937
|
+
fullCapability = true;
|
|
5938
|
+
}
|
|
5939
|
+
// Partial capability: Moderate core coverage OR clear scope-limited implementation
|
|
5940
|
+
else if (corePercentage >= 30 || (coreCoverage.coveredElements.length > 0 && subElementPercentage >= 20)) {
|
|
5941
|
+
partialCapability = true;
|
|
5881
5942
|
}
|
|
5882
5943
|
|
|
5883
5944
|
// Enhanced primary capability logic
|
|
@@ -5914,6 +5975,8 @@ export class GRCAnalysisServer {
|
|
|
5914
5975
|
// Calculate confidence based on evidence strength and keyword matches
|
|
5915
5976
|
const keywordConfidence = (governanceScore + facilitatesScore + validatesScore) / 3;
|
|
5916
5977
|
|
|
5978
|
+
const totalCoreAndSubElements = safeguard.coreRequirements.length + safeguard.subTaxonomicalElements.length;
|
|
5979
|
+
const coveredCoreAndSubElements = coreCoverage.coveredElements.length + subElementCoverage.coveredElements.length;
|
|
5917
5980
|
const coverageConfidence = totalCoreAndSubElements > 0 ?
|
|
5918
5981
|
coveredCoreAndSubElements / totalCoreAndSubElements : 0;
|
|
5919
5982
|
|
|
@@ -6262,6 +6325,331 @@ export class GRCAnalysisServer {
|
|
|
6262
6325
|
return validation;
|
|
6263
6326
|
}
|
|
6264
6327
|
|
|
6328
|
+
private async validateVendorMapping(args: any) {
|
|
6329
|
+
const { vendor_name = 'Unknown Vendor', safeguard_id, claimed_capability, supporting_text } = args;
|
|
6330
|
+
|
|
6331
|
+
const safeguard = CIS_SAFEGUARDS[safeguard_id];
|
|
6332
|
+
if (!safeguard) {
|
|
6333
|
+
throw new Error(`Safeguard ${safeguard_id} not found. Available safeguards: ${Object.keys(CIS_SAFEGUARDS).join(', ')}`);
|
|
6334
|
+
}
|
|
6335
|
+
|
|
6336
|
+
const validation = this.validateCapabilityClaim(
|
|
6337
|
+
vendor_name,
|
|
6338
|
+
safeguard,
|
|
6339
|
+
claimed_capability,
|
|
6340
|
+
supporting_text
|
|
6341
|
+
);
|
|
6342
|
+
|
|
6343
|
+
return {
|
|
6344
|
+
content: [
|
|
6345
|
+
{
|
|
6346
|
+
type: 'text',
|
|
6347
|
+
text: JSON.stringify(validation, null, 2),
|
|
6348
|
+
},
|
|
6349
|
+
],
|
|
6350
|
+
};
|
|
6351
|
+
}
|
|
6352
|
+
|
|
6353
|
+
private validateCapabilityClaim(
|
|
6354
|
+
vendorName: string,
|
|
6355
|
+
safeguard: SafeguardElement,
|
|
6356
|
+
claimedCapability: string,
|
|
6357
|
+
supportingText: string
|
|
6358
|
+
): ValidationResult {
|
|
6359
|
+
const text = supportingText.toLowerCase();
|
|
6360
|
+
|
|
6361
|
+
// Perform actual analysis of the supporting text
|
|
6362
|
+
const actualAnalysis = this.performEnhancedSafeguardAnalysis(vendorName, safeguard, supportingText);
|
|
6363
|
+
|
|
6364
|
+
// Calculate coverage percentages
|
|
6365
|
+
const coreCoverage = this.analyzeBinaryElementCoverage(text, safeguard.coreRequirements);
|
|
6366
|
+
const subElementCoverage = this.analyzeBinaryElementCoverage(text, safeguard.subTaxonomicalElements);
|
|
6367
|
+
const governanceCoverage = this.analyzeBinaryElementCoverage(text, safeguard.governanceElements);
|
|
6368
|
+
|
|
6369
|
+
const corePercentage = safeguard.coreRequirements.length > 0 ?
|
|
6370
|
+
(coreCoverage.coveredElements.length / safeguard.coreRequirements.length) * 100 : 0;
|
|
6371
|
+
const subElementPercentage = safeguard.subTaxonomicalElements.length > 0 ?
|
|
6372
|
+
(subElementCoverage.coveredElements.length / safeguard.subTaxonomicalElements.length) * 100 : 0;
|
|
6373
|
+
const governancePercentage = safeguard.governanceElements.length > 0 ?
|
|
6374
|
+
(governanceCoverage.coveredElements.length / safeguard.governanceElements.length) * 100 : 0;
|
|
6375
|
+
|
|
6376
|
+
// Validate claim against criteria
|
|
6377
|
+
const validation = this.assessClaimAlignment(
|
|
6378
|
+
claimedCapability,
|
|
6379
|
+
actualAnalysis,
|
|
6380
|
+
corePercentage,
|
|
6381
|
+
subElementPercentage,
|
|
6382
|
+
governancePercentage,
|
|
6383
|
+
text
|
|
6384
|
+
);
|
|
6385
|
+
|
|
6386
|
+
return {
|
|
6387
|
+
vendor: vendorName,
|
|
6388
|
+
safeguard_id: safeguard.id,
|
|
6389
|
+
safeguard_title: safeguard.title,
|
|
6390
|
+
claimed_capability: claimedCapability,
|
|
6391
|
+
validation_status: validation.status,
|
|
6392
|
+
confidence_score: validation.confidence,
|
|
6393
|
+
evidence_analysis: {
|
|
6394
|
+
core_requirements_coverage: Math.round(corePercentage),
|
|
6395
|
+
sub_elements_coverage: Math.round(subElementPercentage),
|
|
6396
|
+
governance_alignment: Math.round(governancePercentage),
|
|
6397
|
+
language_consistency: validation.languageConsistency
|
|
6398
|
+
},
|
|
6399
|
+
gaps_identified: validation.gaps,
|
|
6400
|
+
strengths_identified: validation.strengths,
|
|
6401
|
+
recommendations: validation.recommendations,
|
|
6402
|
+
detailed_feedback: validation.feedback
|
|
6403
|
+
};
|
|
6404
|
+
}
|
|
6405
|
+
|
|
6406
|
+
private assessClaimAlignment(
|
|
6407
|
+
claimedCapability: string,
|
|
6408
|
+
actualAnalysis: VendorAnalysis,
|
|
6409
|
+
corePercentage: number,
|
|
6410
|
+
subElementPercentage: number,
|
|
6411
|
+
governancePercentage: number,
|
|
6412
|
+
text: string
|
|
6413
|
+
): {
|
|
6414
|
+
status: 'SUPPORTED' | 'QUESTIONABLE' | 'UNSUPPORTED';
|
|
6415
|
+
confidence: number;
|
|
6416
|
+
languageConsistency: number;
|
|
6417
|
+
gaps: string[];
|
|
6418
|
+
strengths: string[];
|
|
6419
|
+
recommendations: string[];
|
|
6420
|
+
feedback: string;
|
|
6421
|
+
} {
|
|
6422
|
+
const gaps: string[] = [];
|
|
6423
|
+
const strengths: string[] = [];
|
|
6424
|
+
const recommendations: string[] = [];
|
|
6425
|
+
let languageConsistency = 0;
|
|
6426
|
+
let alignmentScore = 0;
|
|
6427
|
+
|
|
6428
|
+
switch (claimedCapability.toLowerCase()) {
|
|
6429
|
+
case 'full':
|
|
6430
|
+
// Validate FULL claim
|
|
6431
|
+
if (corePercentage >= 70 && subElementPercentage >= 40) {
|
|
6432
|
+
alignmentScore = 85;
|
|
6433
|
+
strengths.push('High coverage of core requirements and sub-elements');
|
|
6434
|
+
} else if (corePercentage >= 80 && subElementPercentage >= 30) {
|
|
6435
|
+
// Alternative path: very high core with moderate sub-elements
|
|
6436
|
+
alignmentScore = 80;
|
|
6437
|
+
strengths.push('Very high core requirements coverage with adequate sub-element coverage');
|
|
6438
|
+
} else {
|
|
6439
|
+
alignmentScore = Math.max(0, (corePercentage + subElementPercentage) / 2 - 15);
|
|
6440
|
+
if (corePercentage < 70) gaps.push(`Core requirements coverage (${Math.round(corePercentage)}%) below FULL threshold (70%)`);
|
|
6441
|
+
if (subElementPercentage < 40) gaps.push(`Sub-element coverage (${Math.round(subElementPercentage)}%) below FULL threshold (40%)`);
|
|
6442
|
+
}
|
|
6443
|
+
|
|
6444
|
+
// Check for conflicting facilitation language
|
|
6445
|
+
if (this.hasFacilitationLanguage(text)) {
|
|
6446
|
+
alignmentScore -= 30;
|
|
6447
|
+
gaps.push('Contains facilitation language inconsistent with FULL implementation claim');
|
|
6448
|
+
}
|
|
6449
|
+
|
|
6450
|
+
languageConsistency = this.assessImplementationLanguage(text);
|
|
6451
|
+
break;
|
|
6452
|
+
|
|
6453
|
+
case 'partial':
|
|
6454
|
+
// Validate PARTIAL claim
|
|
6455
|
+
if (corePercentage >= 30 || (corePercentage > 0 && subElementPercentage >= 20)) {
|
|
6456
|
+
alignmentScore = 75;
|
|
6457
|
+
strengths.push('Appropriate coverage level for PARTIAL implementation');
|
|
6458
|
+
} else {
|
|
6459
|
+
alignmentScore = Math.max(0, corePercentage + subElementPercentage - 10);
|
|
6460
|
+
gaps.push(`Coverage too low even for PARTIAL claim: ${Math.round(corePercentage)}% core, ${Math.round(subElementPercentage)}% sub-elements`);
|
|
6461
|
+
}
|
|
6462
|
+
|
|
6463
|
+
// Check for scope boundary definition
|
|
6464
|
+
if (this.hasScopeBoundaries(text)) {
|
|
6465
|
+
strengths.push('Clearly defines scope boundaries and limitations');
|
|
6466
|
+
alignmentScore += 10;
|
|
6467
|
+
} else {
|
|
6468
|
+
gaps.push('Should clearly define scope boundaries for PARTIAL implementation');
|
|
6469
|
+
recommendations.push('Specify exactly which elements are covered and which are not');
|
|
6470
|
+
}
|
|
6471
|
+
|
|
6472
|
+
languageConsistency = this.assessImplementationLanguage(text);
|
|
6473
|
+
break;
|
|
6474
|
+
|
|
6475
|
+
case 'facilitates':
|
|
6476
|
+
// Validate FACILITATES claim
|
|
6477
|
+
if (this.hasFacilitationLanguage(text) || actualAnalysis.capabilities.facilitates) {
|
|
6478
|
+
alignmentScore = 80;
|
|
6479
|
+
strengths.push('Contains appropriate facilitation and enablement language');
|
|
6480
|
+
} else {
|
|
6481
|
+
alignmentScore = 40;
|
|
6482
|
+
gaps.push('Lacks clear facilitation language (enables, supports, provides framework)');
|
|
6483
|
+
}
|
|
6484
|
+
|
|
6485
|
+
// Check that it doesn't claim direct implementation
|
|
6486
|
+
if (this.hasDirectImplementationLanguage(text)) {
|
|
6487
|
+
// Special handling: If it lacks facilitation language AND claims implementation, stay QUESTIONABLE
|
|
6488
|
+
if (alignmentScore <= 40) {
|
|
6489
|
+
alignmentScore = 45; // Keep it in QUESTIONABLE range
|
|
6490
|
+
} else {
|
|
6491
|
+
alignmentScore -= 15;
|
|
6492
|
+
}
|
|
6493
|
+
gaps.push('Claims direct implementation, inconsistent with FACILITATES capability');
|
|
6494
|
+
}
|
|
6495
|
+
|
|
6496
|
+
languageConsistency = this.assessFacilitationLanguage(text);
|
|
6497
|
+
break;
|
|
6498
|
+
|
|
6499
|
+
case 'governance':
|
|
6500
|
+
// Validate GOVERNANCE claim
|
|
6501
|
+
if (governancePercentage >= 60 || actualAnalysis.capabilities.governance) {
|
|
6502
|
+
alignmentScore = 85;
|
|
6503
|
+
strengths.push('Strong governance element coverage and policy management language');
|
|
6504
|
+
} else {
|
|
6505
|
+
alignmentScore = Math.max(30, governancePercentage);
|
|
6506
|
+
gaps.push(`Governance element coverage (${Math.round(governancePercentage)}%) below expected threshold (60%)`);
|
|
6507
|
+
}
|
|
6508
|
+
|
|
6509
|
+
languageConsistency = this.assessGovernanceLanguage(text);
|
|
6510
|
+
break;
|
|
6511
|
+
|
|
6512
|
+
case 'validates':
|
|
6513
|
+
// Validate VALIDATES claim
|
|
6514
|
+
if (actualAnalysis.capabilities.validates) {
|
|
6515
|
+
alignmentScore = 85;
|
|
6516
|
+
strengths.push('Contains evidence collection and reporting capabilities');
|
|
6517
|
+
} else {
|
|
6518
|
+
alignmentScore = 30;
|
|
6519
|
+
gaps.push('Lacks validation language (audit, report, evidence, verify, monitor)');
|
|
6520
|
+
}
|
|
6521
|
+
|
|
6522
|
+
languageConsistency = this.assessValidationLanguage(text);
|
|
6523
|
+
break;
|
|
6524
|
+
|
|
6525
|
+
default:
|
|
6526
|
+
alignmentScore = 0;
|
|
6527
|
+
gaps.push(`Unknown capability type: ${claimedCapability}`);
|
|
6528
|
+
languageConsistency = 0;
|
|
6529
|
+
}
|
|
6530
|
+
|
|
6531
|
+
// Determine overall status
|
|
6532
|
+
let status: 'SUPPORTED' | 'QUESTIONABLE' | 'UNSUPPORTED';
|
|
6533
|
+
if (alignmentScore >= 70) {
|
|
6534
|
+
status = 'SUPPORTED';
|
|
6535
|
+
} else if (alignmentScore >= 40) {
|
|
6536
|
+
status = 'QUESTIONABLE';
|
|
6537
|
+
} else {
|
|
6538
|
+
status = 'UNSUPPORTED';
|
|
6539
|
+
}
|
|
6540
|
+
|
|
6541
|
+
// Generate recommendations
|
|
6542
|
+
if (gaps.length > 0) {
|
|
6543
|
+
recommendations.push('Address identified gaps to strengthen capability claim');
|
|
6544
|
+
}
|
|
6545
|
+
if (status === 'QUESTIONABLE') {
|
|
6546
|
+
recommendations.push('Provide additional evidence or clarify scope to support claim');
|
|
6547
|
+
}
|
|
6548
|
+
|
|
6549
|
+
const feedback = this.generateValidationFeedback(claimedCapability, status, gaps, strengths, alignmentScore);
|
|
6550
|
+
|
|
6551
|
+
return {
|
|
6552
|
+
status,
|
|
6553
|
+
confidence: Math.round(alignmentScore),
|
|
6554
|
+
languageConsistency: Math.round(languageConsistency),
|
|
6555
|
+
gaps,
|
|
6556
|
+
strengths,
|
|
6557
|
+
recommendations,
|
|
6558
|
+
feedback
|
|
6559
|
+
};
|
|
6560
|
+
}
|
|
6561
|
+
|
|
6562
|
+
private hasFacilitationLanguage(text: string): boolean {
|
|
6563
|
+
const facilitationPatterns = [
|
|
6564
|
+
'enables', 'facilitates', 'supports', 'helps', 'provides framework',
|
|
6565
|
+
'creates infrastructure', 'enables organizations', 'supports compliance',
|
|
6566
|
+
'provides data', 'enriches', 'supplements', 'feeds data'
|
|
6567
|
+
];
|
|
6568
|
+
return facilitationPatterns.some(pattern => text.includes(pattern));
|
|
6569
|
+
}
|
|
6570
|
+
|
|
6571
|
+
private hasScopeBoundaries(text: string): boolean {
|
|
6572
|
+
const boundaryPatterns = [
|
|
6573
|
+
'covers', 'but not', 'limited to', 'specifically', 'only', 'excludes',
|
|
6574
|
+
'scope includes', 'scope excludes', 'within', 'applies to'
|
|
6575
|
+
];
|
|
6576
|
+
return boundaryPatterns.some(pattern => text.includes(pattern));
|
|
6577
|
+
}
|
|
6578
|
+
|
|
6579
|
+
private hasDirectImplementationLanguage(text: string): boolean {
|
|
6580
|
+
const implementationPatterns = [
|
|
6581
|
+
'directly implements', 'performs', 'executes', 'scans', 'catalogs',
|
|
6582
|
+
'inventories', 'manages assets', 'controls access', 'blocks threats'
|
|
6583
|
+
];
|
|
6584
|
+
return implementationPatterns.some(pattern => text.includes(pattern));
|
|
6585
|
+
}
|
|
6586
|
+
|
|
6587
|
+
private assessImplementationLanguage(text: string): number {
|
|
6588
|
+
const implementationKeywords = [
|
|
6589
|
+
'implements', 'performs', 'executes', 'manages', 'controls', 'maintains',
|
|
6590
|
+
'establishes', 'configures', 'monitors', 'tracks', 'inventories'
|
|
6591
|
+
];
|
|
6592
|
+
return this.calculateKeywordScore(text, implementationKeywords) * 100;
|
|
6593
|
+
}
|
|
6594
|
+
|
|
6595
|
+
private assessFacilitationLanguage(text: string): number {
|
|
6596
|
+
const facilitationKeywords = [
|
|
6597
|
+
'enables', 'facilitates', 'supports', 'helps', 'enhances', 'improves',
|
|
6598
|
+
'streamlines', 'automates', 'optimizes', 'provides framework'
|
|
6599
|
+
];
|
|
6600
|
+
return this.calculateKeywordScore(text, facilitationKeywords) * 100;
|
|
6601
|
+
}
|
|
6602
|
+
|
|
6603
|
+
private assessGovernanceLanguage(text: string): number {
|
|
6604
|
+
const governanceKeywords = [
|
|
6605
|
+
'policy', 'governance', 'compliance', 'oversight', 'management',
|
|
6606
|
+
'framework', 'procedures', 'processes', 'controls', 'standards'
|
|
6607
|
+
];
|
|
6608
|
+
return this.calculateKeywordScore(text, governanceKeywords) * 100;
|
|
6609
|
+
}
|
|
6610
|
+
|
|
6611
|
+
private assessValidationLanguage(text: string): number {
|
|
6612
|
+
const validationKeywords = [
|
|
6613
|
+
'audit', 'validate', 'verify', 'report', 'evidence', 'monitor',
|
|
6614
|
+
'assess', 'check', 'review', 'attest', 'compliance', 'compliance tracking',
|
|
6615
|
+
'compliance reports', 'audit capabilities', 'audit trail', 'reporting capabilities'
|
|
6616
|
+
];
|
|
6617
|
+
return this.calculateKeywordScore(text, validationKeywords) * 100;
|
|
6618
|
+
}
|
|
6619
|
+
|
|
6620
|
+
private generateValidationFeedback(
|
|
6621
|
+
claimedCapability: string,
|
|
6622
|
+
status: string,
|
|
6623
|
+
gaps: string[],
|
|
6624
|
+
strengths: string[],
|
|
6625
|
+
score: number
|
|
6626
|
+
): string {
|
|
6627
|
+
let feedback = `Validation of ${claimedCapability.toUpperCase()} capability claim: ${status} (${Math.round(score)}% alignment)\n\n`;
|
|
6628
|
+
|
|
6629
|
+
if (strengths.length > 0) {
|
|
6630
|
+
feedback += `STRENGTHS:\n${strengths.map(s => `• ${s}`).join('\n')}\n\n`;
|
|
6631
|
+
}
|
|
6632
|
+
|
|
6633
|
+
if (gaps.length > 0) {
|
|
6634
|
+
feedback += `GAPS IDENTIFIED:\n${gaps.map(g => `• ${g}`).join('\n')}\n\n`;
|
|
6635
|
+
}
|
|
6636
|
+
|
|
6637
|
+
feedback += `ASSESSMENT: `;
|
|
6638
|
+
switch (status) {
|
|
6639
|
+
case 'SUPPORTED':
|
|
6640
|
+
feedback += 'The vendor\'s supporting evidence strongly aligns with their claimed capability.';
|
|
6641
|
+
break;
|
|
6642
|
+
case 'QUESTIONABLE':
|
|
6643
|
+
feedback += 'The vendor\'s evidence partially supports their claim but has notable gaps or inconsistencies.';
|
|
6644
|
+
break;
|
|
6645
|
+
case 'UNSUPPORTED':
|
|
6646
|
+
feedback += 'The vendor\'s evidence does not adequately support their claimed capability.';
|
|
6647
|
+
break;
|
|
6648
|
+
}
|
|
6649
|
+
|
|
6650
|
+
return feedback;
|
|
6651
|
+
}
|
|
6652
|
+
|
|
6265
6653
|
async run() {
|
|
6266
6654
|
const transport = new StdioServerTransport();
|
|
6267
6655
|
await this.server.connect(transport);
|