#!/usr/bin/env tsx /** * Schema Compliance Audit Script * * Uses verifier with JSON Schema draft-07 support. * Verifies all implementations against canonical schemas from schemas.kya-os.ai * Generates a comprehensive compliance report. */ import { createSchemaVerifier, type SchemaMetadata, } from '../src/compliance/schema-verifier'; import { getAllSchemas, getCriticalSchemas, getSchemasByCategory, } from '../src/compliance/schema-registry'; // Import all available implementations from contracts import type { HandshakeRequest, SessionContext, NonceCache, NonceCacheEntry, NonceCacheConfig, ProofMeta, DetachedProof, CanonicalHashes, AuditRecord, } from '@kya-os/contracts'; // Import delegation and VC types import type { VerifiableCredential, VerifiablePresentation, CredentialStatus, StatusList2021Credential, Proof, DelegationCredential, DelegationRecord, DelegationConstraints, BudgetConstraint, ScopeConstraint, TimeConstraint, } from '@kya-os/contracts'; /** * Sample implementations for each schema type */ function createSampleImplementations(): Map { const implementations = new Map(); // =================================================================== // W3C Verifiable Credentials // =================================================================== // Sample VerifiableCredential const sampleVC: VerifiableCredential = { '@context': [ 'https://www.w3.org/2018/credentials/v1', ], id: 'urn:uuid:sample-vc-123', type: ['VerifiableCredential'], issuer: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', issuanceDate: '2025-10-17T00:00:00Z', credentialSubject: { id: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', }, proof: { type: 'Ed25519Signature2020', created: '2025-10-17T00:00:00Z', verificationMethod: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', proofPurpose: 'assertionMethod', proofValue: 'z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz', }, }; implementations.set('verifiable-credential', sampleVC); // Sample VerifiablePresentation const sampleVP: VerifiablePresentation = { '@context': [ 'https://www.w3.org/2018/credentials/v1', ], id: 'urn:uuid:sample-vp-123', type: ['VerifiablePresentation'], holder: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', verifiableCredential: [sampleVC], proof: { type: 'Ed25519Signature2020', created: '2025-10-17T00:00:00Z', verificationMethod: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', proofPurpose: 'authentication', proofValue: 'z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz', }, }; implementations.set('verifiable-presentation', sampleVP); // Sample CredentialStatus const sampleCredentialStatus: CredentialStatus = { id: 'https://example.com/status/revocation/v1#12345', type: 'StatusList2021Entry', statusPurpose: 'revocation', statusListIndex: '12345', statusListCredential: 'https://example.com/status/revocation/v1', }; implementations.set('credential-status', sampleCredentialStatus); // Sample StatusList2021Credential const sampleStatusList: StatusList2021Credential = { '@context': [ 'https://www.w3.org/2018/credentials/v1', 'https://w3id.org/vc/status-list/2021/v1', ], id: 'https://example.com/status/revocation/v1', type: ['VerifiableCredential', 'StatusList2021Credential'], issuer: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', issuanceDate: '2025-10-17T00:00:00Z', credentialSubject: { id: 'https://example.com/status/revocation/v1#list', type: 'StatusList2021', statusPurpose: 'revocation', encodedList: 'H4sIAAAAAAAAA-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA', }, proof: { type: 'Ed25519Signature2020', created: '2025-10-17T00:00:00Z', verificationMethod: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', proofPurpose: 'assertionMethod', proofValue: 'z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz', }, }; implementations.set('statuslist2021-credential', sampleStatusList); // Sample Proof const sampleProof: Proof = { type: 'Ed25519Signature2020', created: '2025-10-17T00:00:00Z', verificationMethod: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', proofPurpose: 'assertionMethod', proofValue: 'z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz', }; implementations.set('proof', sampleProof); // =================================================================== // MCP-I Protocol // =================================================================== // Sample ProofMeta (matches contracts/src/proof.ts ProofMetaSchema) const sampleProofMeta: ProofMeta = { did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', kid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', ts: 1729123200, // Unix timestamp (number) nonce: 'nonce-123', audience: 'https://example.com', sessionId: 'session-123', requestHash: 'sha256:' + 'a'.repeat(64), responseHash: 'sha256:' + 'b'.repeat(64), scopeId: 'scope-123', delegationRef: 'delegation-123', }; implementations.set('proof-meta', sampleProofMeta); // Sample DetachedProof (matches contracts/src/proof.ts DetachedProofSchema) const sampleDetachedProof: DetachedProof = { jws: 'eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa2hhWGdCWkR2b3REa0w1MjU3ZmFpenRpR2lDMlF0S0xHcGJubkVHdGEyZG9LI3o2TWtoYVhnQlpEdm90RGtMNTI1N2ZhaXp0aUdpQzJRdEtMR3Bibm5FR3RhMmRvSyJ9.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tIiwic3ViIjoic2Vzc2lvbi0xMjMiLCJpc3MiOiJkaWQ6a2V5Ono2TWtoYVhnQlpEdm90RGtMNTI1N2ZhaXp0aUdpQzJRdEtMR3Bibm5FR3RhMmRvSyIsIm5vbmNlIjoibm9uY2UtMTIzIiwicmVxSGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsInJlc0hhc2giOiJzaGEyNTY6YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIn0.z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz', meta: sampleProofMeta, }; implementations.set('detached-proof', sampleDetachedProof); // Sample CanonicalHashes (matches contracts/src/proof.ts CanonicalHashesSchema) const sampleCanonicalHashes: CanonicalHashes = { requestHash: 'sha256:' + 'a'.repeat(64), responseHash: 'sha256:' + 'b'.repeat(64), }; implementations.set('canonical-hashes', sampleCanonicalHashes); // Sample HandshakeRequest (matches contracts/src/handshake.ts HandshakeRequestSchema) const sampleHandshake: HandshakeRequest = { nonce: 'nonce-123', audience: 'https://example.com', timestamp: 1729123200, // Unix timestamp (number) agentDid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', }; implementations.set('handshake-request', sampleHandshake); // Sample HandshakeResponse const sampleHandshakeResponse = { session_id: 'session-123', server_did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', nonce: 'nonce-456', timestamp: '2025-10-17T00:00:01Z', capabilities: ['tool_execution', 'delegation'], }; implementations.set('handshake-response', sampleHandshakeResponse); // Sample SessionContext (matches contracts/src/handshake.ts SessionContextSchema) const sampleSession: SessionContext = { sessionId: 'session-123', audience: 'https://example.com', nonce: 'nonce-123', timestamp: 1729123200, createdAt: 1729123200, lastActivity: 1729123500, ttlMinutes: 30, agentDid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', }; implementations.set('session-context', sampleSession); // =================================================================== // Delegation System // =================================================================== // Sample DelegationConstraints const sampleConstraints: DelegationConstraints = { budget: { maxCost: 100, currency: 'USD', }, scope: { allowedTools: ['tool-1', 'tool-2'], allowedResources: ['resource-1'], }, time: { notBefore: '2025-10-17T00:00:00Z', notAfter: '2025-10-18T00:00:00Z', }, }; implementations.set('delegation-constraints', sampleConstraints); // Sample BudgetConstraint const sampleBudget: BudgetConstraint = { maxCost: 100, currency: 'USD', }; implementations.set('budget-constraint', sampleBudget); // Sample ScopeConstraint const sampleScope: ScopeConstraint = { allowedTools: ['tool-1', 'tool-2'], allowedResources: ['resource-1'], }; implementations.set('scope-constraint', sampleScope); // Sample TimeConstraint const sampleTime: TimeConstraint = { notBefore: '2025-10-17T00:00:00Z', notAfter: '2025-10-18T00:00:00Z', }; implementations.set('time-constraint', sampleTime); // Sample DelegationRecord const sampleDelegationRecord: DelegationRecord = { id: 'delegation-123', issuerDid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', subjectDid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', constraints: sampleConstraints, issuedAt: '2025-10-17T00:00:00Z', expiresAt: '2025-10-18T00:00:00Z', }; implementations.set('delegation-record', sampleDelegationRecord); // Sample DelegationCredential const sampleDelegationVC: DelegationCredential = { '@context': [ 'https://www.w3.org/2018/credentials/v1', 'https://mcp-i.org/contexts/delegation/v1', ], id: 'urn:uuid:delegation-123', type: ['VerifiableCredential', 'DelegationCredential'], issuer: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', issuanceDate: '2025-10-17T00:00:00Z', expirationDate: '2025-10-18T00:00:00Z', credentialSubject: { id: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', delegation: sampleDelegationRecord, }, credentialStatus: sampleCredentialStatus, proof: { type: 'Ed25519Signature2020', created: '2025-10-17T00:00:00Z', verificationMethod: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', proofPurpose: 'assertionMethod', proofValue: 'z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz', }, }; implementations.set('delegation-credential', sampleDelegationVC); // =================================================================== // Audit & Logging // =================================================================== // Sample AuditRecord (matches contracts/src/proof.ts AuditRecordSchema) const sampleAudit: AuditRecord = { version: 'audit.v1', ts: 1729123200, session: 'session-123', audience: 'https://example.com', did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', kid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', reqHash: 'sha256:' + 'a'.repeat(64), resHash: 'sha256:' + 'b'.repeat(64), verified: 'yes', scope: 'tool-execution', }; implementations.set('audit-record', sampleAudit); // Sample AuditEntry (similar to AuditRecord but might have different structure) const sampleAuditEntry = { timestamp: '2025-10-17T00:00:00Z', action: 'tool_execution', actor: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', result: 'success', metadata: { tool_name: 'example-tool', session_id: 'session-123', }, }; implementations.set('audit-entry', sampleAuditEntry); // =================================================================== // Nonce Cache // =================================================================== // Sample NonceCacheEntry (matches contracts/src/handshake.ts NonceCacheEntrySchema) const sampleNonceEntry: NonceCacheEntry = { sessionId: 'session-123', expiresAt: 1729123500, }; implementations.set('nonce-cache-entry', sampleNonceEntry); // Sample NonceCacheConfig const sampleNonceConfig: NonceCacheConfig = { ttl: 300, maxSize: 10000, }; implementations.set('nonce-cache-config', sampleNonceConfig); // =================================================================== // Agent Identity // =================================================================== // Sample AgentIdentity const sampleAgentIdentity = { did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', publicKey: 'base64-encoded-public-key', privateKey: 'base64-encoded-private-key', kid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', }; implementations.set('agent-identity', sampleAgentIdentity); // Sample DIDDocument const sampleDIDDocument = { '@context': ['https://www.w3.org/ns/did/v1'], id: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', verificationMethod: [ { id: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', type: 'Ed25519VerificationKey2020', controller: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', publicKeyMultibase: 'z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', }, ], authentication: [ 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', ], assertionMethod: [ 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', ], }; implementations.set('did-document', sampleDIDDocument); // Sample VerificationMethod const sampleVerificationMethod = { id: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', type: 'Ed25519VerificationKey2020', controller: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', publicKeyMultibase: 'z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', }; implementations.set('verification-method', sampleVerificationMethod); // =================================================================== // Tool Protection // =================================================================== // Sample ToolProtection const sampleToolProtection = { toolName: 'example-tool', requiresDelegation: true, requiredCapabilities: ['tool_execution'], budgetLimit: 100, }; implementations.set('tool-protection', sampleToolProtection); // Sample ToolProtectionConfig const sampleToolProtectionConfig = { enabled: true, defaultRequiresDelegation: false, protectedTools: ['sensitive-tool-1', 'sensitive-tool-2'], }; implementations.set('tool-protection-config', sampleToolProtectionConfig); // =================================================================== // MCP Tools & Resources // =================================================================== // Sample MCP Tool const sampleMCPTool = { name: 'example-tool', description: 'An example tool', inputSchema: { type: 'object', properties: { input: { type: 'string' }, }, required: ['input'], }, }; implementations.set('mcp-tool', sampleMCPTool); // Sample MCP Resource const sampleMCPResource = { uri: 'file:///example.txt', name: 'Example Resource', mimeType: 'text/plain', description: 'An example resource', }; implementations.set('mcp-resource', sampleMCPResource); // Sample MCP Prompt const sampleMCPPrompt = { name: 'example-prompt', description: 'An example prompt template', arguments: [ { name: 'input', description: 'Input parameter', required: true, }, ], }; implementations.set('mcp-prompt', sampleMCPPrompt); // =================================================================== // Registry & Discovery // =================================================================== // Sample AgentRegistryEntry const sampleRegistryEntry = { did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK', name: 'Example Agent', description: 'An example agent', endpoint: 'https://example.com/mcp', capabilities: ['tool_execution', 'delegation'], registeredAt: '2025-10-17T00:00:00Z', }; implementations.set('agent-registry-entry', sampleRegistryEntry); // Sample ServiceEndpoint const sampleServiceEndpoint = { id: 'https://example.com/mcp', type: 'MCPService', serviceEndpoint: 'https://example.com/mcp', description: 'MCP service endpoint', }; implementations.set('service-endpoint', sampleServiceEndpoint); // =================================================================== // Verifier Service // =================================================================== // Sample VerifierRequest const sampleVerifierRequest = { credential: sampleDelegationVC, options: { checkStatus: true, checkSignature: true, }, }; implementations.set('verifier-request', sampleVerifierRequest); // Sample VerifierResponse const sampleVerifierResponse = { valid: true, credential: sampleDelegationVC, checks: { signature: { valid: true }, status: { valid: true }, expiration: { valid: true }, }, }; implementations.set('verifier-response', sampleVerifierResponse); // Sample VerificationResult const sampleVerificationResult = { valid: true, checks: [ { name: 'signature', passed: true }, { name: 'status', passed: true }, { name: 'expiration', passed: true }, ], errors: [], warnings: [], }; implementations.set('verification-result', sampleVerificationResult); // =================================================================== // CLI & Configuration // =================================================================== // Sample CLIConfig const sampleCLIConfig = { identityPath: '.mcp-i/identity.json', registryUrl: 'https://registry.example.com', verifierUrl: 'https://verifier.example.com', defaultCapabilities: ['tool_execution'], }; implementations.set('cli-config', sampleCLIConfig); // Sample EnvironmentConfig const sampleEnvConfig = { environment: 'development', debug: true, logLevel: 'info', }; implementations.set('environment-config', sampleEnvConfig); // =================================================================== // TLKRC (Tool-Level Key Rotation Config) // =================================================================== // Sample TLKRCConfig const sampleTLKRCConfig = { enabled: true, rotationIntervalDays: 30, maxKeyAge: 90, }; implementations.set('tlkrc-config', sampleTLKRCConfig); // Sample TLKRCEntry const sampleTLKRCEntry = { toolName: 'example-tool', kid: 'key-123', createdAt: '2025-10-17T00:00:00Z', expiresAt: '2025-11-17T00:00:00Z', rotated: false, }; implementations.set('tlkrc-entry', sampleTLKRCEntry); // =================================================================== // Runtime Configuration // =================================================================== // Sample RuntimeConfig const sampleRuntimeConfig = { identityEnabled: true, delegationEnabled: true, auditEnabled: true, nonceCacheType: 'memory', sessionTTL: 3600, }; implementations.set('runtime-config', sampleRuntimeConfig); // Sample PlatformConfig const samplePlatformConfig = { platform: 'node', version: '1.0.0', features: ['crypto', 'storage', 'networking'], }; implementations.set('platform-config', samplePlatformConfig); return implementations; } /** * Run compliance audit */ async function runAudit() { console.log('================================================================================'); console.log('SCHEMA COMPLIANCE AUDIT'); console.log('Enhanced with JSON Schema draft-07 support'); console.log('================================================================================\n'); const verifier = createSchemaVerifier({ schemasBaseUrl: 'https://schema.modelcontextprotocol-identity.io/xmcp-i', }); const implementations = createSampleImplementations(); console.log(`Total implementations: ${implementations.size}\n`); // Phase 1: Verify Critical Schemas (must be 100% compliant) console.log('================================================================================'); console.log('PHASE 1: CRITICAL SCHEMAS (Must be 100% Compliant)'); console.log('================================================================================\n'); const criticalSchemas = getCriticalSchemas(); const criticalResults: Array<{ schema: SchemaMetadata; compliant: boolean; percentage: number }> = []; for (const schema of criticalSchemas) { const implementation = implementations.get(schema.id); if (!implementation) { console.log(`❌ ${schema.id}: Missing implementation\n`); criticalResults.push({ schema, compliant: false, percentage: 0 }); continue; } console.log(`Verifying ${schema.id}...`); const report = await verifier.verifySchema(schema, implementation); const status = report.compliant ? '✅' : report.compliancePercentage >= 80 ? '⚠️ ' : '❌'; console.log(`${status} ${schema.id}: ${report.compliancePercentage.toFixed(1)}%`); if (report.issues.length > 0) { console.log(` Issues:`); report.issues.slice(0, 5).forEach((issue) => console.log(` - ${issue}`)); if (report.issues.length > 5) { console.log(` ... and ${report.issues.length - 5} more issues`); } } if (report.warnings.length > 0) { console.log(` Warnings:`); report.warnings.forEach((warning) => console.log(` - ${warning}`)); } console.log(); criticalResults.push({ schema, compliant: report.compliant, percentage: report.compliancePercentage, }); } // Phase 2: Verify All Schemas console.log('================================================================================'); console.log('PHASE 2: ALL SCHEMAS'); console.log('================================================================================\n'); const allSchemas = getAllSchemas(); const fullReport = await verifier.verifyAll(allSchemas, implementations); console.log(verifier.generateFullReport(fullReport)); // Phase 3: Verify by Category console.log('\n================================================================================'); console.log('PHASE 3: COMPLIANCE BY CATEGORY'); console.log('================================================================================\n'); const categories = [ 'w3c', 'delegation', 'identity', 'protocol', 'tool-protection', 'audit', 'nonce', 'mcp', 'registry', 'verifier', 'config', 'tlkrc', ]; for (const category of categories) { const schemas = getSchemasByCategory(category); const categoryReport = await verifier.verifyAll(schemas, implementations); console.log(`${category.toUpperCase()}:`); console.log(` Schemas: ${categoryReport.totalSchemas}`); console.log(` Compliant: ${categoryReport.compliantSchemas}/${categoryReport.totalSchemas}`); console.log(` Overall: ${categoryReport.overallCompliance.toFixed(1)}%`); if (categoryReport.criticalIssues.length > 0) { console.log(` Issues:`); categoryReport.criticalIssues.forEach((issue) => console.log(` - ${issue}`)); } console.log(); } // Summary console.log('================================================================================'); console.log('AUDIT SUMMARY'); console.log('================================================================================\n'); const criticalCompliant = criticalResults.filter((r) => r.compliant).length; const criticalTotal = criticalResults.length; const avgCriticalCompliance = criticalResults.reduce((sum, r) => sum + r.percentage, 0) / criticalTotal; console.log(`Critical Schemas: ${criticalCompliant}/${criticalTotal} fully compliant`); console.log(`Critical Schemas Avg: ${avgCriticalCompliance.toFixed(1)}%`); console.log(`All Schemas: ${fullReport.compliantSchemas}/${fullReport.totalSchemas} compliant`); console.log(`Overall Compliance: ${fullReport.overallCompliance.toFixed(1)}%`); if (fullReport.criticalIssues.length > 0) { console.log(`\n🚨 CRITICAL ISSUES (${fullReport.criticalIssues.length}):`); fullReport.criticalIssues.forEach((issue, i) => { console.log(` ${i + 1}. ${issue}`); }); } // Exit code based on average critical compliance if (avgCriticalCompliance >= 95) { console.log('\n✅ AUDIT PASSED: Critical schemas >= 95% compliant on average'); process.exit(0); } else if (avgCriticalCompliance >= 80) { console.log('\n⚠️ AUDIT WARNING: Critical schemas 80-95% compliant - improvements needed'); process.exit(1); } else { console.log('\n❌ AUDIT FAILED: Critical schemas < 80% compliant'); process.exit(1); } } // Run audit runAudit().catch((error) => { console.error('Audit failed with error:', error); process.exit(1); });