contradiction-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +536 -0
- package/bin/cli.js +182 -0
- package/dist/analysis/claimMatcher.d.ts +48 -0
- package/dist/analysis/claimMatcher.js +131 -0
- package/dist/analysis/claimMatcher.js.map +1 -0
- package/dist/analysis/claimRelationship.d.ts +15 -0
- package/dist/analysis/claimRelationship.js +12 -0
- package/dist/analysis/claimRelationship.js.map +1 -0
- package/dist/analysis/confidenceScorer.d.ts +40 -0
- package/dist/analysis/confidenceScorer.js +59 -0
- package/dist/analysis/confidenceScorer.js.map +1 -0
- package/dist/analysis/contextAnalyzer.d.ts +13 -0
- package/dist/analysis/contextAnalyzer.js +187 -0
- package/dist/analysis/contextAnalyzer.js.map +1 -0
- package/dist/analysis/contradictionClassifier.d.ts +16 -0
- package/dist/analysis/contradictionClassifier.js +141 -0
- package/dist/analysis/contradictionClassifier.js.map +1 -0
- package/dist/analysis/contradictionEngine.d.ts +29 -0
- package/dist/analysis/contradictionEngine.js +284 -0
- package/dist/analysis/contradictionEngine.js.map +1 -0
- package/dist/analysis/explanationBuilder.d.ts +36 -0
- package/dist/analysis/explanationBuilder.js +77 -0
- package/dist/analysis/explanationBuilder.js.map +1 -0
- package/dist/analysis/valueComparator.d.ts +38 -0
- package/dist/analysis/valueComparator.js +418 -0
- package/dist/analysis/valueComparator.js.map +1 -0
- package/dist/config/env.d.ts +46 -0
- package/dist/config/env.js +34 -0
- package/dist/config/env.js.map +1 -0
- package/dist/connectors/base/connectorUtils.d.ts +26 -0
- package/dist/connectors/base/connectorUtils.js +63 -0
- package/dist/connectors/base/connectorUtils.js.map +1 -0
- package/dist/connectors/base/security.d.ts +11 -0
- package/dist/connectors/base/security.js +9 -0
- package/dist/connectors/base/security.js.map +1 -0
- package/dist/connectors/connectorRegistry.d.ts +43 -0
- package/dist/connectors/connectorRegistry.js +91 -0
- package/dist/connectors/connectorRegistry.js.map +1 -0
- package/dist/connectors/document/documentConnector.d.ts +45 -0
- package/dist/connectors/document/documentConnector.js +410 -0
- package/dist/connectors/document/documentConnector.js.map +1 -0
- package/dist/connectors/github/githubClient.d.ts +52 -0
- package/dist/connectors/github/githubClient.js +207 -0
- package/dist/connectors/github/githubClient.js.map +1 -0
- package/dist/connectors/github/githubConnector.d.ts +26 -0
- package/dist/connectors/github/githubConnector.js +169 -0
- package/dist/connectors/github/githubConnector.js.map +1 -0
- package/dist/connectors/github/githubExtractor.d.ts +26 -0
- package/dist/connectors/github/githubExtractor.js +469 -0
- package/dist/connectors/github/githubExtractor.js.map +1 -0
- package/dist/connectors/github/githubNormalizer.d.ts +11 -0
- package/dist/connectors/github/githubNormalizer.js +24 -0
- package/dist/connectors/github/githubNormalizer.js.map +1 -0
- package/dist/connectors/github/githubTypes.d.ts +55 -0
- package/dist/connectors/github/githubTypes.js +2 -0
- package/dist/connectors/github/githubTypes.js.map +1 -0
- package/dist/connectors/syncService.d.ts +60 -0
- package/dist/connectors/syncService.js +176 -0
- package/dist/connectors/syncService.js.map +1 -0
- package/dist/connectors/types/connector.d.ts +34 -0
- package/dist/connectors/types/connector.js +2 -0
- package/dist/connectors/types/connector.js.map +1 -0
- package/dist/connectors/types/fetchResult.d.ts +39 -0
- package/dist/connectors/types/fetchResult.js +2 -0
- package/dist/connectors/types/fetchResult.js.map +1 -0
- package/dist/connectors/website/ssrfGuard.d.ts +11 -0
- package/dist/connectors/website/ssrfGuard.js +122 -0
- package/dist/connectors/website/ssrfGuard.js.map +1 -0
- package/dist/connectors/website/websiteConnector.d.ts +30 -0
- package/dist/connectors/website/websiteConnector.js +231 -0
- package/dist/connectors/website/websiteConnector.js.map +1 -0
- package/dist/discovery/candidateGenerator.d.ts +12 -0
- package/dist/discovery/candidateGenerator.js +110 -0
- package/dist/discovery/candidateGenerator.js.map +1 -0
- package/dist/discovery/contradictionScanner.d.ts +30 -0
- package/dist/discovery/contradictionScanner.js +47 -0
- package/dist/discovery/contradictionScanner.js.map +1 -0
- package/dist/discovery/discoveryService.d.ts +37 -0
- package/dist/discovery/discoveryService.js +131 -0
- package/dist/discovery/discoveryService.js.map +1 -0
- package/dist/discovery/rankingService.d.ts +34 -0
- package/dist/discovery/rankingService.js +52 -0
- package/dist/discovery/rankingService.js.map +1 -0
- package/dist/discovery/similarityIndex.d.ts +20 -0
- package/dist/discovery/similarityIndex.js +89 -0
- package/dist/discovery/similarityIndex.js.map +1 -0
- package/dist/domain/entities/claim.d.ts +99 -0
- package/dist/domain/entities/claim.js +92 -0
- package/dist/domain/entities/claim.js.map +1 -0
- package/dist/domain/entities/contradiction.d.ts +110 -0
- package/dist/domain/entities/contradiction.js +74 -0
- package/dist/domain/entities/contradiction.js.map +1 -0
- package/dist/domain/entities/source.d.ts +43 -0
- package/dist/domain/entities/source.js +35 -0
- package/dist/domain/entities/source.js.map +1 -0
- package/dist/domain/types/common.d.ts +46 -0
- package/dist/domain/types/common.js +74 -0
- package/dist/domain/types/common.js.map +1 -0
- package/dist/httpServer.d.ts +25 -0
- package/dist/httpServer.js +164 -0
- package/dist/httpServer.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/dist/intelligence/authorityScorer.d.ts +20 -0
- package/dist/intelligence/authorityScorer.js +103 -0
- package/dist/intelligence/authorityScorer.js.map +1 -0
- package/dist/intelligence/entityResolver.d.ts +33 -0
- package/dist/intelligence/entityResolver.js +152 -0
- package/dist/intelligence/entityResolver.js.map +1 -0
- package/dist/intelligence/evidenceEvaluator.d.ts +15 -0
- package/dist/intelligence/evidenceEvaluator.js +63 -0
- package/dist/intelligence/evidenceEvaluator.js.map +1 -0
- package/dist/intelligence/freshnessScorer.d.ts +25 -0
- package/dist/intelligence/freshnessScorer.js +90 -0
- package/dist/intelligence/freshnessScorer.js.map +1 -0
- package/dist/intelligence/provenanceAnalyzer.d.ts +19 -0
- package/dist/intelligence/provenanceAnalyzer.js +33 -0
- package/dist/intelligence/provenanceAnalyzer.js.map +1 -0
- package/dist/intelligence/resolutionAdvisor.d.ts +40 -0
- package/dist/intelligence/resolutionAdvisor.js +118 -0
- package/dist/intelligence/resolutionAdvisor.js.map +1 -0
- package/dist/intelligence/semanticMatcher.d.ts +21 -0
- package/dist/intelligence/semanticMatcher.js +71 -0
- package/dist/intelligence/semanticMatcher.js.map +1 -0
- package/dist/scripts/comprehensiveVerification.d.ts +5 -0
- package/dist/scripts/comprehensiveVerification.js +961 -0
- package/dist/scripts/comprehensiveVerification.js.map +1 -0
- package/dist/scripts/finalLiveDemo.d.ts +5 -0
- package/dist/scripts/finalLiveDemo.js +226 -0
- package/dist/scripts/finalLiveDemo.js.map +1 -0
- package/dist/scripts/liveMcpSmoke.d.ts +1 -0
- package/dist/scripts/liveMcpSmoke.js +89 -0
- package/dist/scripts/liveMcpSmoke.js.map +1 -0
- package/dist/scripts/seedDemoData.d.ts +6 -0
- package/dist/scripts/seedDemoData.js +179 -0
- package/dist/scripts/seedDemoData.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.js +1264 -0
- package/dist/server.js.map +1 -0
- package/dist/services/analysisService.d.ts +40 -0
- package/dist/services/analysisService.js +65 -0
- package/dist/services/analysisService.js.map +1 -0
- package/dist/services/healthService.d.ts +42 -0
- package/dist/services/healthService.js +50 -0
- package/dist/services/healthService.js.map +1 -0
- package/dist/services/metricsService.d.ts +35 -0
- package/dist/services/metricsService.js +57 -0
- package/dist/services/metricsService.js.map +1 -0
- package/dist/services/rateLimiter.d.ts +23 -0
- package/dist/services/rateLimiter.js +45 -0
- package/dist/services/rateLimiter.js.map +1 -0
- package/dist/services/reviewService.d.ts +32 -0
- package/dist/services/reviewService.js +94 -0
- package/dist/services/reviewService.js.map +1 -0
- package/dist/services/schedulerService.d.ts +30 -0
- package/dist/services/schedulerService.js +89 -0
- package/dist/services/schedulerService.js.map +1 -0
- package/dist/storage/backupService.d.ts +14 -0
- package/dist/storage/backupService.js +90 -0
- package/dist/storage/backupService.js.map +1 -0
- package/dist/storage/database.d.ts +119 -0
- package/dist/storage/database.js +935 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/migrations/001_initial.sql +63 -0
- package/dist/storage/migrations/002_discovery_uniqueness.sql +8 -0
- package/dist/storage/migrations/003_connector_identity.sql +7 -0
- package/dist/storage/migrations/004_claim_context.sql +15 -0
- package/dist/storage/migrations/005_claim_history.sql +26 -0
- package/dist/storage/migrations/006_contradiction_resolution.sql +27 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.js +48 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
export class EntityResolver {
|
|
2
|
+
defaultAliases = new Map();
|
|
3
|
+
constructor() {
|
|
4
|
+
this.registerDefaultAliases();
|
|
5
|
+
}
|
|
6
|
+
registerDefaultAliases() {
|
|
7
|
+
const aliasGroups = [
|
|
8
|
+
['api', 'api-server', 'backend', 'api_service', 'core-api'],
|
|
9
|
+
['frontend', 'web', 'ui', 'client', 'web-app', 'webapp'],
|
|
10
|
+
['gateway', 'api-gateway', 'platform-gateway-service', 'ingress'],
|
|
11
|
+
['auth', 'authentication', 'auth-service', 'idp', 'identity'],
|
|
12
|
+
['db', 'database', 'postgres', 'postgresql', 'mysql', 'sqlite'],
|
|
13
|
+
];
|
|
14
|
+
for (const group of aliasGroups) {
|
|
15
|
+
const set = new Set(group.map((s) => this.normalize(s)));
|
|
16
|
+
for (const item of group) {
|
|
17
|
+
this.defaultAliases.set(this.normalize(item), set);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Canonicalizes an entity name by stripping delimiters, common redundant words, and casing.
|
|
23
|
+
*/
|
|
24
|
+
normalize(raw) {
|
|
25
|
+
if (!raw)
|
|
26
|
+
return '';
|
|
27
|
+
return raw
|
|
28
|
+
.trim()
|
|
29
|
+
.toLowerCase()
|
|
30
|
+
.replace(/^(@[a-z0-9_-]+\/)/i, '') // strip npm scopes
|
|
31
|
+
.replace(/^(https?:\/\/)?(www\.)?/i, '') // strip web protocols
|
|
32
|
+
.replace(/[._\-\s/]+/g, '') // remove separators
|
|
33
|
+
.replace(/(service|server|daemon|app|application|client|pkg|package)$/i, ''); // strip redundant noun suffixes
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Compares two entity references across sources.
|
|
37
|
+
*/
|
|
38
|
+
resolveEntityMatch(entityA, entityB, options) {
|
|
39
|
+
const rawA = (entityA || '').trim();
|
|
40
|
+
const rawB = (entityB || '').trim();
|
|
41
|
+
if (!rawA || !rawB) {
|
|
42
|
+
return {
|
|
43
|
+
isMatch: false,
|
|
44
|
+
confidence: 0.0,
|
|
45
|
+
matchType: 'NONE',
|
|
46
|
+
reason: 'Empty entity string provided',
|
|
47
|
+
isAmbiguous: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// 1. Exact string match
|
|
51
|
+
if (rawA === rawB) {
|
|
52
|
+
return {
|
|
53
|
+
isMatch: true,
|
|
54
|
+
confidence: 1.0,
|
|
55
|
+
matchType: 'EXACT',
|
|
56
|
+
reason: 'Exact verbatim entity name match',
|
|
57
|
+
isAmbiguous: false,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// 2. Exact case-insensitive match
|
|
61
|
+
if (rawA.toLowerCase() === rawB.toLowerCase()) {
|
|
62
|
+
return {
|
|
63
|
+
isMatch: true,
|
|
64
|
+
confidence: 0.98,
|
|
65
|
+
matchType: 'EXACT',
|
|
66
|
+
reason: 'Exact case-insensitive match',
|
|
67
|
+
isAmbiguous: false,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// 3. Normalized representation match
|
|
71
|
+
const normA = this.normalize(rawA);
|
|
72
|
+
const normB = this.normalize(rawB);
|
|
73
|
+
if (normA && normB && normA === normB) {
|
|
74
|
+
return {
|
|
75
|
+
isMatch: true,
|
|
76
|
+
confidence: 0.92,
|
|
77
|
+
matchType: 'NORMALIZED',
|
|
78
|
+
reason: `Normalized representations match ('${normA}')`,
|
|
79
|
+
isAmbiguous: false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// 4. Custom & Built-in Aliases check
|
|
83
|
+
if (options?.customAliases) {
|
|
84
|
+
for (const [key, aliases] of Object.entries(options.customAliases)) {
|
|
85
|
+
const normKey = this.normalize(key);
|
|
86
|
+
const normAliases = aliases.map((a) => this.normalize(a));
|
|
87
|
+
const all = [normKey, ...normAliases];
|
|
88
|
+
if (all.includes(normA) && all.includes(normB)) {
|
|
89
|
+
return {
|
|
90
|
+
isMatch: true,
|
|
91
|
+
confidence: 0.95,
|
|
92
|
+
matchType: 'ALIAS',
|
|
93
|
+
reason: `Matched via custom configured alias group '${key}'`,
|
|
94
|
+
isAmbiguous: false,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const defaultSetA = this.defaultAliases.get(normA);
|
|
100
|
+
if (defaultSetA && defaultSetA.has(normB)) {
|
|
101
|
+
return {
|
|
102
|
+
isMatch: true,
|
|
103
|
+
confidence: 0.88,
|
|
104
|
+
matchType: 'ALIAS',
|
|
105
|
+
reason: 'Matched via standard industry service alias dictionary',
|
|
106
|
+
isAmbiguous: false,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// 5. Substring / Prefix / Suffix inclusion with caution
|
|
110
|
+
if (normA.length >= 4 && normB.length >= 4) {
|
|
111
|
+
if (normA.includes(normB) || normB.includes(normA)) {
|
|
112
|
+
const ratio = Math.min(normA.length, normB.length) / Math.max(normA.length, normB.length);
|
|
113
|
+
if (ratio >= 0.6) {
|
|
114
|
+
return {
|
|
115
|
+
isMatch: true,
|
|
116
|
+
confidence: Number((0.7 + ratio * 0.15).toFixed(2)),
|
|
117
|
+
matchType: 'SUFFIX_PREFIX',
|
|
118
|
+
reason: `Significant component substring overlap ('${normA}' and '${normB}')`,
|
|
119
|
+
isAmbiguous: ratio < 0.75,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// No confident match
|
|
125
|
+
return {
|
|
126
|
+
isMatch: false,
|
|
127
|
+
confidence: 0.1,
|
|
128
|
+
matchType: 'NONE',
|
|
129
|
+
reason: `Entities '${rawA}' and '${rawB}' do not correspond deterministically`,
|
|
130
|
+
isAmbiguous: false,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Evaluates query against multiple candidate entities, sorting by confidence.
|
|
135
|
+
*/
|
|
136
|
+
findMatches(query, candidates, options) {
|
|
137
|
+
const minThreshold = options?.minConfidenceThreshold ?? 0.7;
|
|
138
|
+
const matches = [];
|
|
139
|
+
for (const candidate of candidates) {
|
|
140
|
+
const res = this.resolveEntityMatch(query, candidate, options);
|
|
141
|
+
if (res.isMatch && res.confidence >= minThreshold) {
|
|
142
|
+
matches.push({
|
|
143
|
+
candidate,
|
|
144
|
+
confidence: res.confidence,
|
|
145
|
+
matchType: res.matchType,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return matches.sort((a, b) => b.confidence - a.confidence);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=entityResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entityResolver.js","sourceRoot":"","sources":["../../src/intelligence/entityResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Claim } from '../domain/entities/claim.js';
|
|
2
|
+
export interface EvidenceQualityResult {
|
|
3
|
+
quality: 'STRONG' | 'MODERATE' | 'WEAK' | 'INDIRECT';
|
|
4
|
+
score: number;
|
|
5
|
+
hasLineProvenance: boolean;
|
|
6
|
+
hasVerbatimSnippet: boolean;
|
|
7
|
+
extractionMethod: string;
|
|
8
|
+
reasons: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare class EvidenceEvaluator {
|
|
11
|
+
/**
|
|
12
|
+
* Assesses the empirical solidity and verifiable directness of a claim's evidence.
|
|
13
|
+
*/
|
|
14
|
+
evaluateEvidence(claim: Claim): EvidenceQualityResult;
|
|
15
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export class EvidenceEvaluator {
|
|
2
|
+
/**
|
|
3
|
+
* Assesses the empirical solidity and verifiable directness of a claim's evidence.
|
|
4
|
+
*/
|
|
5
|
+
evaluateEvidence(claim) {
|
|
6
|
+
const reasons = [];
|
|
7
|
+
let score = 0.4;
|
|
8
|
+
const metadata = claim.metadata || {};
|
|
9
|
+
const snippet = typeof metadata.snippet === 'string' ? metadata.snippet.trim() : '';
|
|
10
|
+
const hasSnippet = snippet.length > 0;
|
|
11
|
+
const hasLine = metadata.line !== undefined ||
|
|
12
|
+
(metadata.startLine !== undefined && metadata.endLine !== undefined);
|
|
13
|
+
const extractionMethod = typeof metadata.extractionMethod === 'string' ? metadata.extractionMethod : 'heuristic';
|
|
14
|
+
if (hasLine) {
|
|
15
|
+
score += 0.25;
|
|
16
|
+
const lineStr = metadata.line !== undefined
|
|
17
|
+
? `line ${metadata.line}`
|
|
18
|
+
: `lines ${metadata.startLine}-${metadata.endLine}`;
|
|
19
|
+
reasons.push(`Claim verified with exact line provenance: ${lineStr}`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
reasons.push('Claim lacks exact line number citation');
|
|
23
|
+
}
|
|
24
|
+
if (hasSnippet) {
|
|
25
|
+
score += 0.25;
|
|
26
|
+
reasons.push(`Claim includes verbatim source snippet (${snippet.length} chars)`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
reasons.push('No textual evidence snippet captured');
|
|
30
|
+
}
|
|
31
|
+
if (extractionMethod === 'json_parse' || extractionMethod === 'ast') {
|
|
32
|
+
score += 0.1;
|
|
33
|
+
reasons.push(`Structured deterministic extraction method: ${extractionMethod}`);
|
|
34
|
+
}
|
|
35
|
+
else if (extractionMethod === 'regex' || extractionMethod === 'yaml_parse') {
|
|
36
|
+
score += 0.05;
|
|
37
|
+
reasons.push(`Pattern-based extraction method: ${extractionMethod}`);
|
|
38
|
+
}
|
|
39
|
+
score = Math.min(1.0, score);
|
|
40
|
+
let quality;
|
|
41
|
+
if (score >= 0.8) {
|
|
42
|
+
quality = 'STRONG';
|
|
43
|
+
}
|
|
44
|
+
else if (score >= 0.6) {
|
|
45
|
+
quality = 'MODERATE';
|
|
46
|
+
}
|
|
47
|
+
else if (score >= 0.4) {
|
|
48
|
+
quality = 'WEAK';
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
quality = 'INDIRECT';
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
quality,
|
|
55
|
+
score: Number(score.toFixed(2)),
|
|
56
|
+
hasLineProvenance: hasLine,
|
|
57
|
+
hasVerbatimSnippet: hasSnippet,
|
|
58
|
+
extractionMethod,
|
|
59
|
+
reasons,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=evidenceEvaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidenceEvaluator.js","sourceRoot":"","sources":["../../src/intelligence/evidenceEvaluator.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,iBAAiB;IAC5B;;OAEG;IACI,gBAAgB,CAAC,KAAY;QAClC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,KAAK,GAAG,GAAG,CAAC;QAEhB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACtC,MAAM,OAAO,GACX,QAAQ,CAAC,IAAI,KAAK,SAAS;YAC3B,CAAC,QAAQ,CAAC,SAAS,KAAK,SAAS,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;QAEvE,MAAM,gBAAgB,GACpB,OAAO,QAAQ,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;QAE1F,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,IAAI,IAAI,CAAC;YACd,MAAM,OAAO,GACX,QAAQ,CAAC,IAAI,KAAK,SAAS;gBACzB,CAAC,CAAC,QAAQ,QAAQ,CAAC,IAAI,EAAE;gBACzB,CAAC,CAAC,SAAS,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,8CAA8C,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,KAAK,IAAI,IAAI,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,2CAA2C,OAAO,CAAC,MAAM,SAAS,CAAC,CAAC;QACnF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,gBAAgB,KAAK,YAAY,IAAI,gBAAgB,KAAK,KAAK,EAAE,CAAC;YACpE,KAAK,IAAI,GAAG,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,+CAA+C,gBAAgB,EAAE,CAAC,CAAC;QAClF,CAAC;aAAM,IAAI,gBAAgB,KAAK,OAAO,IAAI,gBAAgB,KAAK,YAAY,EAAE,CAAC;YAC7E,KAAK,IAAI,IAAI,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,oCAAoC,gBAAgB,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE7B,IAAI,OAAoD,CAAC;QACzD,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjB,OAAO,GAAG,QAAQ,CAAC;QACrB,CAAC;aAAM,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,OAAO,GAAG,UAAU,CAAC;QACvB,CAAC;aAAM,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,OAAO,GAAG,MAAM,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,UAAU,CAAC;QACvB,CAAC;QAED,OAAO;YACL,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC/B,iBAAiB,EAAE,OAAO;YAC1B,kBAAkB,EAAE,UAAU;YAC9B,gBAAgB;YAChB,OAAO;SACR,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Claim } from '../domain/entities/claim.js';
|
|
2
|
+
import { Source } from '../domain/entities/source.js';
|
|
3
|
+
export interface FreshnessScoreResult {
|
|
4
|
+
score: number;
|
|
5
|
+
observedAgeDays: number;
|
|
6
|
+
isHistorical: boolean;
|
|
7
|
+
reasoning: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class FreshnessScorer {
|
|
10
|
+
/**
|
|
11
|
+
* Evaluates the recency and temporal validity of a claim.
|
|
12
|
+
* Employs an exponential decay heuristic calibrated over days.
|
|
13
|
+
*/
|
|
14
|
+
scoreFreshness(claim: Claim, source?: Source | null, referenceDate?: Date): FreshnessScoreResult;
|
|
15
|
+
/**
|
|
16
|
+
* Compares the freshness of two claims directly.
|
|
17
|
+
*/
|
|
18
|
+
compareFreshness(claimA: Claim, claimB: Claim, sourceA?: Source | null, sourceB?: Source | null, referenceDate?: Date): {
|
|
19
|
+
winner: 'claimA' | 'claimB' | 'tie';
|
|
20
|
+
claimAScore: number;
|
|
21
|
+
claimBScore: number;
|
|
22
|
+
differenceDays: number;
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export class FreshnessScorer {
|
|
2
|
+
/**
|
|
3
|
+
* Evaluates the recency and temporal validity of a claim.
|
|
4
|
+
* Employs an exponential decay heuristic calibrated over days.
|
|
5
|
+
*/
|
|
6
|
+
scoreFreshness(claim, source, referenceDate = new Date()) {
|
|
7
|
+
const reasoning = [];
|
|
8
|
+
const refMs = referenceDate.getTime();
|
|
9
|
+
// 1. Historical flag penalty
|
|
10
|
+
if (claim.isHistorical) {
|
|
11
|
+
reasoning.push('Claim explicitly flagged as historical (freshness penalty: 0.10 baseline)');
|
|
12
|
+
return {
|
|
13
|
+
score: 0.1,
|
|
14
|
+
observedAgeDays: Math.max(0, (refMs - claim.observedAt.getTime()) / (1000 * 60 * 60 * 24)),
|
|
15
|
+
isHistorical: true,
|
|
16
|
+
reasoning,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
// 2. Temporal validity window check
|
|
20
|
+
if (claim.validUntil && claim.validUntil.getTime() < refMs) {
|
|
21
|
+
reasoning.push(`Claim validity expired on ${claim.validUntil.toISOString()} (freshness penalty: 0.15 baseline)`);
|
|
22
|
+
return {
|
|
23
|
+
score: 0.15,
|
|
24
|
+
observedAgeDays: Math.max(0, (refMs - claim.observedAt.getTime()) / (1000 * 60 * 60 * 24)),
|
|
25
|
+
isHistorical: false,
|
|
26
|
+
reasoning,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// 3. Observed Age Decay
|
|
30
|
+
// Compare observation time and source last fetched time
|
|
31
|
+
const effectiveTime = source?.lastFetchedAt
|
|
32
|
+
? Math.max(claim.observedAt.getTime(), source.lastFetchedAt.getTime())
|
|
33
|
+
: claim.observedAt.getTime();
|
|
34
|
+
const ageMs = Math.max(0, refMs - effectiveTime);
|
|
35
|
+
const ageDays = ageMs / (1000 * 60 * 60 * 24);
|
|
36
|
+
// Half-life model: score = exp(-0.693 * ageDays / halfLifeDays)
|
|
37
|
+
// 180 days half-life for technical documentation & runtime assertions
|
|
38
|
+
const halfLifeDays = 180;
|
|
39
|
+
let baseFreshness = Math.exp((-0.693 * ageDays) / halfLifeDays);
|
|
40
|
+
baseFreshness = Math.max(0.2, Math.min(1.0, baseFreshness));
|
|
41
|
+
reasoning.push(`Observed age: ${ageDays.toFixed(1)} days ago (base freshness: ${baseFreshness.toFixed(2)})`);
|
|
42
|
+
// 4. Boost if validFrom is explicit and active
|
|
43
|
+
if (claim.validFrom && claim.validFrom.getTime() <= refMs) {
|
|
44
|
+
baseFreshness = Math.min(1.0, baseFreshness + 0.05);
|
|
45
|
+
reasoning.push(`Active validity window starting ${claim.validFrom.toISOString()}`);
|
|
46
|
+
}
|
|
47
|
+
const score = Number(baseFreshness.toFixed(4));
|
|
48
|
+
return {
|
|
49
|
+
score,
|
|
50
|
+
observedAgeDays: Number(ageDays.toFixed(1)),
|
|
51
|
+
isHistorical: false,
|
|
52
|
+
reasoning,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Compares the freshness of two claims directly.
|
|
57
|
+
*/
|
|
58
|
+
compareFreshness(claimA, claimB, sourceA, sourceB, referenceDate = new Date()) {
|
|
59
|
+
const freshA = this.scoreFreshness(claimA, sourceA, referenceDate);
|
|
60
|
+
const freshB = this.scoreFreshness(claimB, sourceB, referenceDate);
|
|
61
|
+
const diffDays = Math.abs(freshA.observedAgeDays - freshB.observedAgeDays);
|
|
62
|
+
const scoreDiff = freshA.score - freshB.score;
|
|
63
|
+
if (Math.abs(scoreDiff) < 0.05) {
|
|
64
|
+
return {
|
|
65
|
+
winner: 'tie',
|
|
66
|
+
claimAScore: freshA.score,
|
|
67
|
+
claimBScore: freshB.score,
|
|
68
|
+
differenceDays: diffDays,
|
|
69
|
+
reason: `Both claims have comparable temporal freshness (scores: ${freshA.score.toFixed(2)} vs ${freshB.score.toFixed(2)})`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (freshA.score > freshB.score) {
|
|
73
|
+
return {
|
|
74
|
+
winner: 'claimA',
|
|
75
|
+
claimAScore: freshA.score,
|
|
76
|
+
claimBScore: freshB.score,
|
|
77
|
+
differenceDays: diffDays,
|
|
78
|
+
reason: `Claim A is fresher (${freshA.observedAgeDays.toFixed(0)}d old vs ${freshB.observedAgeDays.toFixed(0)}d old)`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
winner: 'claimB',
|
|
83
|
+
claimAScore: freshA.score,
|
|
84
|
+
claimBScore: freshB.score,
|
|
85
|
+
differenceDays: diffDays,
|
|
86
|
+
reason: `Claim B is fresher (${freshB.observedAgeDays.toFixed(0)}d old vs ${freshA.observedAgeDays.toFixed(0)}d old)`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=freshnessScorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freshnessScorer.js","sourceRoot":"","sources":["../../src/intelligence/freshnessScorer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Claim } from '../domain/entities/claim.js';
|
|
2
|
+
import { Source } from '../domain/entities/source.js';
|
|
3
|
+
export interface ProvenanceTrace {
|
|
4
|
+
sourceId: string;
|
|
5
|
+
sourceType: string;
|
|
6
|
+
sourceName: string;
|
|
7
|
+
sourceUri?: string | null;
|
|
8
|
+
filePath?: string | null;
|
|
9
|
+
commitHash?: string | null;
|
|
10
|
+
observedAt: Date;
|
|
11
|
+
isTraceable: boolean;
|
|
12
|
+
summary: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class ProvenanceAnalyzer {
|
|
15
|
+
/**
|
|
16
|
+
* Traces and validates the chain of custody for a given claim.
|
|
17
|
+
*/
|
|
18
|
+
analyzeProvenance(claim: Claim, source?: Source | null): ProvenanceTrace;
|
|
19
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class ProvenanceAnalyzer {
|
|
2
|
+
/**
|
|
3
|
+
* Traces and validates the chain of custody for a given claim.
|
|
4
|
+
*/
|
|
5
|
+
analyzeProvenance(claim, source) {
|
|
6
|
+
const metadata = claim.metadata || {};
|
|
7
|
+
const filePath = typeof metadata.filePath === 'string' ? metadata.filePath : null;
|
|
8
|
+
const commitHash = typeof metadata.commitSha === 'string'
|
|
9
|
+
? metadata.commitSha
|
|
10
|
+
: typeof metadata.commit === 'string'
|
|
11
|
+
? metadata.commit
|
|
12
|
+
: null;
|
|
13
|
+
const sourceUri = source?.uri || (typeof metadata.uri === 'string' ? metadata.uri : null);
|
|
14
|
+
const isTraceable = Boolean(source && (sourceUri || filePath));
|
|
15
|
+
const locationDesc = filePath ? ` at ${filePath}` : sourceUri ? ` at ${sourceUri}` : '';
|
|
16
|
+
const commitDesc = commitHash ? ` (rev ${commitHash.substring(0, 7)})` : '';
|
|
17
|
+
const summary = source
|
|
18
|
+
? `Extracted from ${source.type} source '${source.name}'${locationDesc}${commitDesc}, observed ${claim.observedAt.toISOString()}`
|
|
19
|
+
: `Unlinked claim observed ${claim.observedAt.toISOString()}`;
|
|
20
|
+
return {
|
|
21
|
+
sourceId: claim.sourceId,
|
|
22
|
+
sourceType: source?.type || 'unknown',
|
|
23
|
+
sourceName: source?.name || 'unknown',
|
|
24
|
+
sourceUri,
|
|
25
|
+
filePath,
|
|
26
|
+
commitHash,
|
|
27
|
+
observedAt: claim.observedAt,
|
|
28
|
+
isTraceable,
|
|
29
|
+
summary,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=provenanceAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenanceAnalyzer.js","sourceRoot":"","sources":["../../src/intelligence/provenanceAnalyzer.ts"],"names":[],"mappings":"AAeA,MAAM,OAAO,kBAAkB;IAC7B;;OAEG;IACI,iBAAiB,CAAC,KAAY,EAAE,MAAsB;QAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAClF,MAAM,UAAU,GACd,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ;YACpC,CAAC,CAAC,QAAQ,CAAC,SAAS;YACpB,CAAC,CAAC,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ;gBACnC,CAAC,CAAC,QAAQ,CAAC,MAAM;gBACjB,CAAC,CAAC,IAAI,CAAC;QAEb,MAAM,SAAS,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1F,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC;QAE/D,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5E,MAAM,OAAO,GAAG,MAAM;YACpB,CAAC,CAAC,kBAAkB,MAAM,CAAC,IAAI,YAAY,MAAM,CAAC,IAAI,IAAI,YAAY,GAAG,UAAU,cAAc,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE;YACjI,CAAC,CAAC,2BAA2B,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;QAEhE,OAAO;YACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,UAAU,EAAE,MAAM,EAAE,IAAI,IAAI,SAAS;YACrC,UAAU,EAAE,MAAM,EAAE,IAAI,IAAI,SAAS;YACrC,SAAS;YACT,QAAQ;YACR,UAAU;YACV,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW;YACX,OAAO;SACR,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Claim } from '../domain/entities/claim.js';
|
|
2
|
+
import { Source } from '../domain/entities/source.js';
|
|
3
|
+
import { Contradiction } from '../domain/entities/contradiction.js';
|
|
4
|
+
import { AuthorityScoreResult } from './authorityScorer.js';
|
|
5
|
+
import { FreshnessScoreResult } from './freshnessScorer.js';
|
|
6
|
+
import { EvidenceQualityResult } from './evidenceEvaluator.js';
|
|
7
|
+
export interface ResolutionAdvice {
|
|
8
|
+
likelyCurrentClaim: 'claimA' | 'claimB' | 'neither' | 'uncertain';
|
|
9
|
+
confidence: number;
|
|
10
|
+
recommendedAction: string;
|
|
11
|
+
reason: string;
|
|
12
|
+
authorityComparison: {
|
|
13
|
+
claimAScore: number;
|
|
14
|
+
claimBScore: number;
|
|
15
|
+
winner: 'claimA' | 'claimB' | 'tie';
|
|
16
|
+
details: AuthorityScoreResult;
|
|
17
|
+
};
|
|
18
|
+
freshnessComparison: {
|
|
19
|
+
claimAScore: number;
|
|
20
|
+
claimBScore: number;
|
|
21
|
+
winner: 'claimA' | 'claimB' | 'tie';
|
|
22
|
+
details: FreshnessScoreResult;
|
|
23
|
+
};
|
|
24
|
+
evidenceComparison: {
|
|
25
|
+
claimAQuality: EvidenceQualityResult;
|
|
26
|
+
claimBQuality: EvidenceQualityResult;
|
|
27
|
+
};
|
|
28
|
+
remainingUncertainty: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare class ResolutionAdvisor {
|
|
31
|
+
private readonly authorityScorer;
|
|
32
|
+
private readonly freshnessScorer;
|
|
33
|
+
private readonly evidenceEvaluator;
|
|
34
|
+
constructor();
|
|
35
|
+
/**
|
|
36
|
+
* Generates comprehensive advisory recommendation for resolving a contradiction.
|
|
37
|
+
* Advisory-only; does not mutate external or database state.
|
|
38
|
+
*/
|
|
39
|
+
adviseResolution(contradiction: Contradiction, claimA: Claim, claimB: Claim, sourceA?: Source | null, sourceB?: Source | null): ResolutionAdvice;
|
|
40
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { AuthorityScorer } from './authorityScorer.js';
|
|
2
|
+
import { FreshnessScorer } from './freshnessScorer.js';
|
|
3
|
+
import { EvidenceEvaluator } from './evidenceEvaluator.js';
|
|
4
|
+
export class ResolutionAdvisor {
|
|
5
|
+
authorityScorer;
|
|
6
|
+
freshnessScorer;
|
|
7
|
+
evidenceEvaluator;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.authorityScorer = new AuthorityScorer();
|
|
10
|
+
this.freshnessScorer = new FreshnessScorer();
|
|
11
|
+
this.evidenceEvaluator = new EvidenceEvaluator();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generates comprehensive advisory recommendation for resolving a contradiction.
|
|
15
|
+
* Advisory-only; does not mutate external or database state.
|
|
16
|
+
*/
|
|
17
|
+
adviseResolution(contradiction, claimA, claimB, sourceA, sourceB) {
|
|
18
|
+
const authA = this.authorityScorer.scoreAuthority(claimA, sourceA);
|
|
19
|
+
const authB = this.authorityScorer.scoreAuthority(claimB, sourceB);
|
|
20
|
+
const freshA = this.freshnessScorer.scoreFreshness(claimA, sourceA);
|
|
21
|
+
const freshB = this.freshnessScorer.scoreFreshness(claimB, sourceB);
|
|
22
|
+
const evidA = this.evidenceEvaluator.evaluateEvidence(claimA);
|
|
23
|
+
const evidB = this.evidenceEvaluator.evaluateEvidence(claimB);
|
|
24
|
+
const remainingUncertainty = [];
|
|
25
|
+
// Authority comparison
|
|
26
|
+
const authDiff = authA.score - authB.score;
|
|
27
|
+
const authWinner = Math.abs(authDiff) < 0.08 ? 'tie' : authDiff > 0 ? 'claimA' : 'claimB';
|
|
28
|
+
// Freshness comparison
|
|
29
|
+
const freshDiff = freshA.score - freshB.score;
|
|
30
|
+
const freshWinner = Math.abs(freshDiff) < 0.08 ? 'tie' : freshDiff > 0 ? 'claimA' : 'claimB';
|
|
31
|
+
let likelyCurrentClaim;
|
|
32
|
+
let confidence;
|
|
33
|
+
let recommendedAction = 'Review both sources manually before updating.';
|
|
34
|
+
let reason = 'Both claims exhibit similar authority and freshness levels.';
|
|
35
|
+
if (authWinner === 'claimA' && (freshWinner === 'claimA' || freshWinner === 'tie')) {
|
|
36
|
+
likelyCurrentClaim = 'claimA';
|
|
37
|
+
confidence = Math.min(0.95, Number((0.6 + Math.abs(authDiff) * 0.4).toFixed(2)));
|
|
38
|
+
reason = `Claim A represents a higher-confidence candidate for current truth because it carries higher operational authority (${authA.score.toFixed(2)} vs ${authB.score.toFixed(2)}) and is at least as fresh.`;
|
|
39
|
+
recommendedAction = `Accept Claim A ('${claimA.value}') and update the conflicting source '${sourceB?.name || claimB.sourceId}'.`;
|
|
40
|
+
}
|
|
41
|
+
else if (authWinner === 'claimB' && (freshWinner === 'claimB' || freshWinner === 'tie')) {
|
|
42
|
+
likelyCurrentClaim = 'claimB';
|
|
43
|
+
confidence = Math.min(0.95, Number((0.6 + Math.abs(authDiff) * 0.4).toFixed(2)));
|
|
44
|
+
reason = `Claim B represents a higher-confidence candidate for current truth because it carries higher operational authority (${authB.score.toFixed(2)} vs ${authA.score.toFixed(2)}) and is at least as fresh.`;
|
|
45
|
+
recommendedAction = `Accept Claim B ('${claimB.value}') and update the conflicting source '${sourceA?.name || claimA.sourceId}'.`;
|
|
46
|
+
}
|
|
47
|
+
else if (authWinner === 'claimA' && freshWinner === 'claimB') {
|
|
48
|
+
// Conflict between authority and recency
|
|
49
|
+
if (authA.score >= 0.85 &&
|
|
50
|
+
(claimB.sourceRole === 'documentation' || claimB.sourceRole === 'example')) {
|
|
51
|
+
likelyCurrentClaim = 'claimA';
|
|
52
|
+
confidence = 0.72;
|
|
53
|
+
reason = `Claim A is operational configuration with high authority (${authA.score.toFixed(2)}), outweighing the more recent documentation claim B.`;
|
|
54
|
+
recommendedAction = `Verify whether documentation in '${sourceB?.name || 'source B'}' is outdated or describes a future planned version.`;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
likelyCurrentClaim = 'uncertain';
|
|
58
|
+
confidence = 0.45;
|
|
59
|
+
reason = `Trade-off detected: Claim A has higher authority (${authA.score.toFixed(2)}) but Claim B is significantly more recent (${freshB.score.toFixed(2)}).`;
|
|
60
|
+
remainingUncertainty.push('Authority and freshness indicators favor opposing claims.');
|
|
61
|
+
recommendedAction =
|
|
62
|
+
'Investigate git commit history or deploy logs to confirm whether Claim B represents a deliberate recent migration.';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (authWinner === 'claimB' && freshWinner === 'claimA') {
|
|
66
|
+
if (authB.score >= 0.85 &&
|
|
67
|
+
(claimA.sourceRole === 'documentation' || claimA.sourceRole === 'example')) {
|
|
68
|
+
likelyCurrentClaim = 'claimB';
|
|
69
|
+
confidence = 0.72;
|
|
70
|
+
reason = `Claim B is operational configuration with high authority (${authB.score.toFixed(2)}), outweighing the more recent documentation claim A.`;
|
|
71
|
+
recommendedAction = `Verify whether documentation in '${sourceA?.name || 'source A'}' is outdated or describes a future planned version.`;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
likelyCurrentClaim = 'uncertain';
|
|
75
|
+
confidence = 0.45;
|
|
76
|
+
reason = `Trade-off detected: Claim B has higher authority (${authB.score.toFixed(2)}) but Claim A is significantly more recent (${freshA.score.toFixed(2)}).`;
|
|
77
|
+
remainingUncertainty.push('Authority and freshness indicators favor opposing claims.');
|
|
78
|
+
recommendedAction =
|
|
79
|
+
'Investigate git commit history or deploy logs to confirm whether Claim A represents a deliberate recent migration.';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
likelyCurrentClaim = 'uncertain';
|
|
84
|
+
confidence = 0.5;
|
|
85
|
+
remainingUncertainty.push('Neither claim exhibits decisive authority or freshness dominance.');
|
|
86
|
+
}
|
|
87
|
+
if (evidA.quality === 'WEAK' && evidB.quality === 'STRONG') {
|
|
88
|
+
remainingUncertainty.push('Claim A has weak evidence quality compared to Claim B.');
|
|
89
|
+
}
|
|
90
|
+
else if (evidB.quality === 'WEAK' && evidA.quality === 'STRONG') {
|
|
91
|
+
remainingUncertainty.push('Claim B has weak evidence quality compared to Claim A.');
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
likelyCurrentClaim,
|
|
95
|
+
confidence,
|
|
96
|
+
recommendedAction,
|
|
97
|
+
reason,
|
|
98
|
+
authorityComparison: {
|
|
99
|
+
claimAScore: authA.score,
|
|
100
|
+
claimBScore: authB.score,
|
|
101
|
+
winner: authWinner,
|
|
102
|
+
details: authA,
|
|
103
|
+
},
|
|
104
|
+
freshnessComparison: {
|
|
105
|
+
claimAScore: freshA.score,
|
|
106
|
+
claimBScore: freshB.score,
|
|
107
|
+
winner: freshWinner,
|
|
108
|
+
details: freshA,
|
|
109
|
+
},
|
|
110
|
+
evidenceComparison: {
|
|
111
|
+
claimAQuality: evidA,
|
|
112
|
+
claimBQuality: evidB,
|
|
113
|
+
},
|
|
114
|
+
remainingUncertainty,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=resolutionAdvisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolutionAdvisor.js","sourceRoot":"","sources":["../../src/intelligence/resolutionAdvisor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface SemanticMatchResult {
|
|
2
|
+
matched: boolean;
|
|
3
|
+
confidence: number;
|
|
4
|
+
reason: string;
|
|
5
|
+
matchedFeatures: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface SemanticMatcherConfig {
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
threshold?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class SemanticMatcher {
|
|
12
|
+
private readonly enabled;
|
|
13
|
+
private readonly threshold;
|
|
14
|
+
constructor(config?: SemanticMatcherConfig);
|
|
15
|
+
isEnabled(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Compares two phrases or textual predicates using an explainable n-gram and token-set similarity algorithm.
|
|
18
|
+
*/
|
|
19
|
+
match(textA: string, textB: string): SemanticMatchResult;
|
|
20
|
+
private tokenize;
|
|
21
|
+
}
|