tribunal-kit 9.2.6 → 9.2.7

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 (63) hide show
  1. package/.agent/ARCHITECTURE.md +2 -2
  2. package/.agent/history/architecture-intelligence.html +1487 -401
  3. package/.agent/history/architecture-model.json +9365 -5697
  4. package/.agent/history/architecture-verification.json +37 -9
  5. package/.agent/routing_index.json +2069 -3340
  6. package/.agent/rules/GEMINI.md +1 -1
  7. package/.agent/scripts/adaptive_execution.js +511 -0
  8. package/.agent/scripts/architecture_diff.js +303 -260
  9. package/.agent/scripts/architecture_extractor.js +792 -753
  10. package/.agent/scripts/architecture_health.js +293 -256
  11. package/.agent/scripts/architecture_intelligence.js +3100 -0
  12. package/.agent/scripts/architecture_verifier.js +303 -270
  13. package/.agent/scripts/architecture_visualizer.js +880 -873
  14. package/.agent/scripts/blast_radius_engine.js +274 -234
  15. package/.agent/scripts/capability_evolution.js +453 -0
  16. package/.agent/scripts/concept_extractor.js +240 -0
  17. package/.agent/scripts/consideration_engine.js +284 -0
  18. package/.agent/scripts/coverage_engine.js +102 -0
  19. package/.agent/scripts/cross_domain_engine.js +1883 -0
  20. package/.agent/scripts/engineering_memory.js +1313 -0
  21. package/.agent/scripts/integrity_manifest.js +1 -5
  22. package/.agent/scripts/judgment_engine.js +790 -0
  23. package/.agent/scripts/materiality_engine.js +251 -0
  24. package/.agent/scripts/outcome_engine.js +624 -0
  25. package/.agent/scripts/outcome_optimization_engine.js +1632 -0
  26. package/.agent/scripts/simulation_engine.js +1478 -0
  27. package/.agent/scripts/skill_intelligence.js +1371 -0
  28. package/.agent/scripts/validation_engine.js +236 -236
  29. package/.agent/scripts/verification_auditor.js +266 -0
  30. package/.agent/skill-intelligence/taxonomy/engineering-concepts.json +555 -0
  31. package/.agent/skill_topic_map.json +301 -341
  32. package/.agent/skills_inventory.json +4272 -6922
  33. package/.agent/workflows/arch.md +96 -80
  34. package/.agent/workflows/skill-intelligence.md +216 -0
  35. package/CONTRIBUTING.md +2 -2
  36. package/README.md +24 -24
  37. package/bin/adapter-install.js +1 -1
  38. package/package.json +8 -9
  39. package/plugins/core-plugin.json +1 -1
  40. package/plugins/gemini/extension.json +1 -1
  41. package/src/browser/index.js +2 -1
  42. package/src/browser/launcher.js +41 -1
  43. package/src/cli.js +3 -1
  44. package/src/commands/arch.js +261 -172
  45. package/src/commands/context.js +27 -8
  46. package/src/commands/learn.js +21 -6
  47. package/src/commands/memory.js +10 -1
  48. package/src/commands/native.js +12 -3
  49. package/src/commands/skill-intelligence.js +1165 -0
  50. package/src/commands/system1.js +105 -4
  51. package/src/context/ranker.js +337 -339
  52. package/src/evolution/engine.js +296 -295
  53. package/src/synthesis/claim_check_separator.js +294 -271
  54. package/src/system1/browser_intelligence.js +300 -0
  55. package/src/system1/constants.js +49 -0
  56. package/src/system1/decision_engine.js +498 -0
  57. package/src/system1/evidence_engine.js +602 -0
  58. package/src/system1/evolution_pipeline.js +581 -0
  59. package/src/system1/index.d.ts +114 -0
  60. package/src/system1/index.js +102 -0
  61. package/src/system1/reviewer_orchestrator.js +477 -0
  62. package/src/tui/banner.js +1 -1
  63. package/src/utils/fs.js +27 -0
@@ -1,271 +1,294 @@
1
- 'use strict';
2
-
3
- /**
4
- * claim_check_separator.js — Strict Separation of Implementation Checks vs Evidence Claims
5
- * =========================================================================================
6
- * System-1 Capability 3:
7
- * Separates what Tribunal Kit actually verified by deterministic execution from what
8
- * an AI reviewer merely claimed.
9
- *
10
- * Directives:
11
- * 1. Never represent an evidence claim as a verified implementation fact.
12
- * 2. Synthesis distinguishes VERIFIED from CLAIMED.
13
- * 3. Preserve provenance for every check and claim.
14
- * 4. Do not fabricate confidence scores (if unavailable, mark as 'UNAVAILABLE').
15
- * 5. Resolve conflicts deterministically (verified execution > AI claims).
16
- */
17
-
18
- const crypto = require('crypto');
19
-
20
- /**
21
- * Creates a verified implementation check record.
22
- * Must be produced by deterministic executable verification.
23
- */
24
- function createImplementationCheck({
25
- check,
26
- command = null,
27
- result,
28
- details = null,
29
- timestamp = null,
30
- runId = null,
31
- }) {
32
- if (!check || typeof check !== 'string') {
33
- throw new Error('Implementation check must specify a valid check name.');
34
- }
35
-
36
- const normalizedResult = String(result).toUpperCase();
37
- if (!['PASSED', 'FAILED', 'ERROR'].includes(normalizedResult)) {
38
- throw new Error(`Invalid check result: ${result}. Must be PASSED, FAILED, or ERROR.`);
39
- }
40
-
41
- const ts = timestamp || new Date().toISOString();
42
- const id = runId || `chk_${crypto.randomBytes(6).toString('hex')}`;
43
-
44
- return {
45
- check,
46
- command: command || null,
47
- result: normalizedResult,
48
- details: details || null,
49
- timestamp: ts,
50
- run_id: id,
51
- provenance: {
52
- type: 'IMPLEMENTATION_CHECK',
53
- command: command || null,
54
- timestamp: ts,
55
- run_id: id,
56
- verified_by: 'executable_runner',
57
- },
58
- };
59
- }
60
-
61
- /**
62
- * Creates an evidence claim record.
63
- * Produced by LLM or inferred from non-executable review.
64
- */
65
- function createEvidenceClaim({
66
- claimId = null,
67
- reviewer,
68
- source = null,
69
- file = null,
70
- line = null,
71
- evidence = null,
72
- assertion,
73
- category = 'general',
74
- confidence = 'UNAVAILABLE',
75
- }) {
76
- if (!reviewer || typeof reviewer !== 'string') {
77
- throw new Error('Evidence claim must specify a reviewer name.');
78
- }
79
- if (!assertion || typeof assertion !== 'string') {
80
- throw new Error('Evidence claim must specify an assertion statement.');
81
- }
82
-
83
- const id = claimId || `clm_${crypto.randomBytes(6).toString('hex')}`;
84
-
85
- let normConfidence = 'UNAVAILABLE';
86
- if (confidence !== 'UNAVAILABLE' && confidence !== null && confidence !== undefined) {
87
- if (typeof confidence === 'number' && !isNaN(confidence) && confidence >= 0 && confidence <= 1) {
88
- normConfidence = parseFloat(confidence.toFixed(2));
89
- } else if (typeof confidence === 'string' && ['L1', 'L2', 'L3', 'L4', 'L5'].includes(confidence.toUpperCase())) {
90
- normConfidence = confidence.toUpperCase();
91
- }
92
- }
93
-
94
- return {
95
- claim_id: id,
96
- reviewer,
97
- source: source || reviewer,
98
- assertion,
99
- category,
100
- status: 'CLAIMED', // Claims can never initialize as VERIFIED
101
- confidence: normConfidence,
102
- provenance: {
103
- reviewer,
104
- source: source || reviewer,
105
- file: file || null,
106
- line: typeof line === 'number' ? line : null,
107
- evidence: evidence || null,
108
- },
109
- };
110
- }
111
-
112
- /**
113
- * Correlates and synthesizes implementation checks with reviewer claims.
114
- */
115
- function synthesizeReviewResults({
116
- checks = [],
117
- claims = [],
118
- runId = null,
119
- timestamp = null,
120
- }) {
121
- const ts = timestamp || new Date().toISOString();
122
- const synthesisId = runId || `syn_${crypto.randomBytes(6).toString('hex')}`;
123
-
124
- const validChecks = checks.map(c => (c.provenance ? c : createImplementationCheck(c)));
125
- const validClaims = claims.map(c => (c.provenance ? c : createEvidenceClaim(c)));
126
-
127
- const conflicts = [];
128
- const verifiedItems = [];
129
- const claimedItems = [];
130
-
131
- // Categorize checks
132
- const passedChecks = validChecks.filter(c => c.result === 'PASSED');
133
- const failedChecks = validChecks.filter(c => c.result === 'FAILED' || c.result === 'ERROR');
134
-
135
- for (const check of passedChecks) {
136
- verifiedItems.push({
137
- item: check.check,
138
- status: 'VERIFIED',
139
- provenance: check.provenance,
140
- });
141
- }
142
-
143
- // Detect conflicts between checks and claims
144
- for (const claim of validClaims) {
145
- const claimText = (claim.assertion + ' ' + (claim.provenance?.evidence || '')).toLowerCase();
146
-
147
- // Conflict Scenario 1: Check passed but reviewer claims failure/vulnerability in that area
148
- if (claim.category === 'test' && claimText.includes('fail') && passedChecks.some(c => c.check === 'tests_passed')) {
149
- conflicts.push({
150
- type: 'CHECK_PASSED_CLAIM_FAILED',
151
- description: `Reviewer ${claim.reviewer} claimed tests failed, but tests_passed check PASSED deterministically.`,
152
- check: 'tests_passed',
153
- claim_id: claim.claim_id,
154
- resolution: 'DETERMINISTIC_CHECK_PRESERVED',
155
- });
156
- claim.status = 'CLAIM_OVERRULED_BY_CHECK';
157
- } else if (claim.category === 'lint' && claimText.includes('fail') && passedChecks.some(c => c.check === 'lint_passed')) {
158
- conflicts.push({
159
- type: 'CHECK_PASSED_CLAIM_FAILED',
160
- description: `Reviewer ${claim.reviewer} claimed lint failed, but lint_passed check PASSED deterministically.`,
161
- check: 'lint_passed',
162
- claim_id: claim.claim_id,
163
- resolution: 'DETERMINISTIC_CHECK_PRESERVED',
164
- });
165
- claim.status = 'CLAIM_OVERRULED_BY_CHECK';
166
- }
167
-
168
- // Conflict Scenario 2: Check failed but reviewer claims success or approves
169
- if (claimText.includes('passed') || claimText.includes('success') || claimText.includes('approved')) {
170
- const relatedFailedCheck = failedChecks.find(fc => {
171
- const checkBase = fc.check.replace('_passed', '').toLowerCase();
172
- const checkSpace = checkBase.replace(/_/g, ' ');
173
- return (
174
- claimText.includes(checkBase) ||
175
- claimText.includes(checkSpace) ||
176
- (claim.category && claim.category.toLowerCase().includes(checkBase.split('_')[0]))
177
- );
178
- });
179
- if (relatedFailedCheck) {
180
- conflicts.push({
181
- type: 'CHECK_FAILED_CLAIM_PASSED',
182
- description: `Reviewer ${claim.reviewer} claimed success, but ${relatedFailedCheck.check} FAILED. Reviewer claim cannot override failing check.`,
183
- check: relatedFailedCheck.check,
184
- claim_id: claim.claim_id,
185
- resolution: 'CHECK_FAILURE_ENFORCED',
186
- });
187
- claim.status = 'CLAIM_REJECTED_CHECK_FAILED';
188
- }
189
- }
190
-
191
- // Add to claimedItems preserving claim status and provenance
192
- claimedItems.push({
193
- claim_id: claim.claim_id,
194
- reviewer: claim.reviewer,
195
- assertion: claim.assertion,
196
- status: claim.status,
197
- confidence: claim.confidence,
198
- provenance: claim.provenance,
199
- });
200
- }
201
-
202
- // Detect reviewer vs reviewer conflicts on same file:line
203
- const claimMap = new Map();
204
- for (const claim of validClaims) {
205
- const loc = claim.provenance?.file
206
- ? `${claim.provenance.file}:${claim.provenance.line || 0}`
207
- : null;
208
- if (loc) {
209
- if (!claimMap.has(loc)) claimMap.set(loc, []);
210
- claimMap.get(loc).push(claim);
211
- }
212
- }
213
-
214
- for (const [loc, locClaims] of claimMap.entries()) {
215
- if (locClaims.length >= 2) {
216
- const revA = locClaims[0];
217
- const revB = locClaims[1];
218
- const textA = revA.assertion.toLowerCase();
219
- const textB = revB.assertion.toLowerCase();
220
-
221
- const aSaysIssue = textA.includes('vulnerab') || textA.includes('insecure') || textA.includes('bug') || textA.includes('error');
222
- const bSaysSafe = textB.includes('safe') || textB.includes('correct') || textB.includes('approved') || textB.includes('clean');
223
-
224
- if ((aSaysIssue && bSaysSafe) || (textA.includes('safe') && textB.includes('bug'))) {
225
- conflicts.push({
226
- type: 'REVIEWER_OPPOSITE_CLAIMS',
227
- description: `Reviewer ${revA.reviewer} and ${revB.reviewer} make opposite claims regarding ${loc}.`,
228
- location: loc,
229
- claim_ids: [revA.claim_id, revB.claim_id],
230
- resolution: 'UNVERIFIED_CONFLICT_PRESERVED',
231
- });
232
- revA.status = 'CLAIM_CONFLICT';
233
- revB.status = 'CLAIM_CONFLICT';
234
- }
235
- }
236
- }
237
-
238
- // Compute final verdict
239
- let verdict = 'VERIFIED';
240
- if (failedChecks.length > 0) {
241
- verdict = 'FAILED_CHECKS';
242
- } else if (conflicts.length > 0) {
243
- verdict = 'CONFLICT';
244
- } else if (verifiedItems.length === 0 && claimedItems.length > 0) {
245
- verdict = 'CLAIMED';
246
- }
247
-
248
- return {
249
- synthesis_id: synthesisId,
250
- timestamp: ts,
251
- checks: validChecks,
252
- claims: validClaims,
253
- summary: {
254
- total_checks: validChecks.length,
255
- passed_checks: passedChecks.length,
256
- failed_checks: failedChecks.length,
257
- total_claims: validClaims.length,
258
- conflict_count: conflicts.length,
259
- verdict,
260
- },
261
- verified_items: verifiedItems,
262
- claimed_items: claimedItems,
263
- conflicts,
264
- };
265
- }
266
-
267
- module.exports = {
268
- createImplementationCheck,
269
- createEvidenceClaim,
270
- synthesizeReviewResults,
271
- };
1
+ 'use strict';
2
+
3
+ /**
4
+ * claim_check_separator.js — Strict Separation of Implementation Checks vs Evidence Claims
5
+ * =========================================================================================
6
+ * System-1 Capability 3:
7
+ * Separates what Tribunal Kit actually verified by deterministic execution from what
8
+ * an AI reviewer merely claimed.
9
+ *
10
+ * Directives:
11
+ * 1. Never represent an evidence claim as a verified implementation fact.
12
+ * 2. Synthesis distinguishes VERIFIED from CLAIMED.
13
+ * 3. Preserve provenance for every check and claim.
14
+ * 4. Do not fabricate confidence scores (if unavailable, mark as 'UNAVAILABLE').
15
+ * 5. Resolve conflicts deterministically (verified execution > AI claims).
16
+ */
17
+
18
+ const crypto = require('crypto');
19
+
20
+ /**
21
+ * Creates a verified implementation check record.
22
+ * Must be produced by deterministic executable verification.
23
+ */
24
+ function createImplementationCheck({
25
+ check,
26
+ command = null,
27
+ result,
28
+ details = null,
29
+ timestamp = null,
30
+ runId = null,
31
+ }) {
32
+ if (!check || typeof check !== 'string') {
33
+ throw new Error('Implementation check must specify a valid check name.');
34
+ }
35
+
36
+ const normalizedResult = String(result).toUpperCase();
37
+ if (!['PASSED', 'FAILED', 'ERROR'].includes(normalizedResult)) {
38
+ throw new Error(`Invalid check result: ${result}. Must be PASSED, FAILED, or ERROR.`);
39
+ }
40
+
41
+ const ts = timestamp || new Date().toISOString();
42
+ const id = runId || `chk_${crypto.randomBytes(6).toString('hex')}`;
43
+
44
+ return {
45
+ check,
46
+ command: command || null,
47
+ result: normalizedResult,
48
+ details: details || null,
49
+ timestamp: ts,
50
+ run_id: id,
51
+ provenance: {
52
+ type: 'IMPLEMENTATION_CHECK',
53
+ command: command || null,
54
+ timestamp: ts,
55
+ run_id: id,
56
+ verified_by: 'executable_runner',
57
+ },
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Creates an evidence claim record.
63
+ * Produced by LLM or inferred from non-executable review.
64
+ */
65
+ function createEvidenceClaim({
66
+ claimId = null,
67
+ reviewer,
68
+ source = null,
69
+ file = null,
70
+ line = null,
71
+ evidence = null,
72
+ assertion,
73
+ category = 'general',
74
+ confidence = 'UNAVAILABLE',
75
+ }) {
76
+ if (!reviewer || typeof reviewer !== 'string') {
77
+ throw new Error('Evidence claim must specify a reviewer name.');
78
+ }
79
+ if (!assertion || typeof assertion !== 'string') {
80
+ throw new Error('Evidence claim must specify an assertion statement.');
81
+ }
82
+
83
+ const id = claimId || `clm_${crypto.randomBytes(6).toString('hex')}`;
84
+
85
+ let normConfidence = 'UNAVAILABLE';
86
+ if (confidence !== 'UNAVAILABLE' && confidence !== null && confidence !== undefined) {
87
+ if (
88
+ typeof confidence === 'number' &&
89
+ !isNaN(confidence) &&
90
+ confidence >= 0 &&
91
+ confidence <= 1
92
+ ) {
93
+ normConfidence = parseFloat(confidence.toFixed(2));
94
+ } else if (
95
+ typeof confidence === 'string' &&
96
+ ['L1', 'L2', 'L3', 'L4', 'L5'].includes(confidence.toUpperCase())
97
+ ) {
98
+ normConfidence = confidence.toUpperCase();
99
+ }
100
+ }
101
+
102
+ return {
103
+ claim_id: id,
104
+ reviewer,
105
+ source: source || reviewer,
106
+ assertion,
107
+ category,
108
+ status: 'CLAIMED', // Claims can never initialize as VERIFIED
109
+ confidence: normConfidence,
110
+ provenance: {
111
+ reviewer,
112
+ source: source || reviewer,
113
+ file: file || null,
114
+ line: typeof line === 'number' ? line : null,
115
+ evidence: evidence || null,
116
+ },
117
+ };
118
+ }
119
+
120
+ /**
121
+ * Correlates and synthesizes implementation checks with reviewer claims.
122
+ */
123
+ function synthesizeReviewResults({ checks = [], claims = [], runId = null, timestamp = null }) {
124
+ const ts = timestamp || new Date().toISOString();
125
+ const synthesisId = runId || `syn_${crypto.randomBytes(6).toString('hex')}`;
126
+
127
+ const validChecks = checks.map(c => (c.provenance ? c : createImplementationCheck(c)));
128
+ const validClaims = claims.map(c => (c.provenance ? c : createEvidenceClaim(c)));
129
+
130
+ const conflicts = [];
131
+ const verifiedItems = [];
132
+ const claimedItems = [];
133
+
134
+ // Categorize checks
135
+ const passedChecks = validChecks.filter(c => c.result === 'PASSED');
136
+ const failedChecks = validChecks.filter(c => c.result === 'FAILED' || c.result === 'ERROR');
137
+
138
+ for (const check of passedChecks) {
139
+ verifiedItems.push({
140
+ item: check.check,
141
+ status: 'VERIFIED',
142
+ provenance: check.provenance,
143
+ });
144
+ }
145
+
146
+ // Detect conflicts between checks and claims
147
+ for (const claim of validClaims) {
148
+ const claimText = (claim.assertion + ' ' + (claim.provenance?.evidence || '')).toLowerCase();
149
+
150
+ // Conflict Scenario 1: Check passed but reviewer claims failure/vulnerability in that area
151
+ if (
152
+ claim.category === 'test' &&
153
+ claimText.includes('fail') &&
154
+ passedChecks.some(c => c.check === 'tests_passed')
155
+ ) {
156
+ conflicts.push({
157
+ type: 'CHECK_PASSED_CLAIM_FAILED',
158
+ description: `Reviewer ${claim.reviewer} claimed tests failed, but tests_passed check PASSED deterministically.`,
159
+ check: 'tests_passed',
160
+ claim_id: claim.claim_id,
161
+ resolution: 'DETERMINISTIC_CHECK_PRESERVED',
162
+ });
163
+ claim.status = 'CLAIM_OVERRULED_BY_CHECK';
164
+ } else if (
165
+ claim.category === 'lint' &&
166
+ claimText.includes('fail') &&
167
+ passedChecks.some(c => c.check === 'lint_passed')
168
+ ) {
169
+ conflicts.push({
170
+ type: 'CHECK_PASSED_CLAIM_FAILED',
171
+ description: `Reviewer ${claim.reviewer} claimed lint failed, but lint_passed check PASSED deterministically.`,
172
+ check: 'lint_passed',
173
+ claim_id: claim.claim_id,
174
+ resolution: 'DETERMINISTIC_CHECK_PRESERVED',
175
+ });
176
+ claim.status = 'CLAIM_OVERRULED_BY_CHECK';
177
+ }
178
+
179
+ // Conflict Scenario 2: Check failed but reviewer claims success or approves
180
+ if (
181
+ claimText.includes('passed') ||
182
+ claimText.includes('success') ||
183
+ claimText.includes('approved')
184
+ ) {
185
+ const relatedFailedCheck = failedChecks.find(fc => {
186
+ const checkBase = fc.check.replace('_passed', '').toLowerCase();
187
+ const checkSpace = checkBase.replace(/_/g, ' ');
188
+ return (
189
+ claimText.includes(checkBase) ||
190
+ claimText.includes(checkSpace) ||
191
+ (claim.category && claim.category.toLowerCase().includes(checkBase.split('_')[0]))
192
+ );
193
+ });
194
+ if (relatedFailedCheck) {
195
+ conflicts.push({
196
+ type: 'CHECK_FAILED_CLAIM_PASSED',
197
+ description: `Reviewer ${claim.reviewer} claimed success, but ${relatedFailedCheck.check} FAILED. Reviewer claim cannot override failing check.`,
198
+ check: relatedFailedCheck.check,
199
+ claim_id: claim.claim_id,
200
+ resolution: 'CHECK_FAILURE_ENFORCED',
201
+ });
202
+ claim.status = 'CLAIM_REJECTED_CHECK_FAILED';
203
+ }
204
+ }
205
+
206
+ // Add to claimedItems preserving claim status and provenance
207
+ claimedItems.push({
208
+ claim_id: claim.claim_id,
209
+ reviewer: claim.reviewer,
210
+ assertion: claim.assertion,
211
+ status: claim.status,
212
+ confidence: claim.confidence,
213
+ provenance: claim.provenance,
214
+ });
215
+ }
216
+
217
+ // Detect reviewer vs reviewer conflicts on same file:line
218
+ const claimMap = new Map();
219
+ for (const claim of validClaims) {
220
+ const loc = claim.provenance?.file
221
+ ? `${claim.provenance.file}:${claim.provenance.line || 0}`
222
+ : null;
223
+ if (loc) {
224
+ if (!claimMap.has(loc)) claimMap.set(loc, []);
225
+ claimMap.get(loc).push(claim);
226
+ }
227
+ }
228
+
229
+ for (const [loc, locClaims] of claimMap.entries()) {
230
+ if (locClaims.length >= 2) {
231
+ const revA = locClaims[0];
232
+ const revB = locClaims[1];
233
+ const textA = revA.assertion.toLowerCase();
234
+ const textB = revB.assertion.toLowerCase();
235
+
236
+ const aSaysIssue =
237
+ textA.includes('vulnerab') ||
238
+ textA.includes('insecure') ||
239
+ textA.includes('bug') ||
240
+ textA.includes('error');
241
+ const bSaysSafe =
242
+ textB.includes('safe') ||
243
+ textB.includes('correct') ||
244
+ textB.includes('approved') ||
245
+ textB.includes('clean');
246
+
247
+ if ((aSaysIssue && bSaysSafe) || (textA.includes('safe') && textB.includes('bug'))) {
248
+ conflicts.push({
249
+ type: 'REVIEWER_OPPOSITE_CLAIMS',
250
+ description: `Reviewer ${revA.reviewer} and ${revB.reviewer} make opposite claims regarding ${loc}.`,
251
+ location: loc,
252
+ claim_ids: [revA.claim_id, revB.claim_id],
253
+ resolution: 'UNVERIFIED_CONFLICT_PRESERVED',
254
+ });
255
+ revA.status = 'CLAIM_CONFLICT';
256
+ revB.status = 'CLAIM_CONFLICT';
257
+ }
258
+ }
259
+ }
260
+
261
+ // Compute final verdict
262
+ let verdict = 'VERIFIED';
263
+ if (failedChecks.length > 0) {
264
+ verdict = 'FAILED_CHECKS';
265
+ } else if (conflicts.length > 0) {
266
+ verdict = 'CONFLICT';
267
+ } else if (verifiedItems.length === 0 && claimedItems.length > 0) {
268
+ verdict = 'CLAIMED';
269
+ }
270
+
271
+ return {
272
+ synthesis_id: synthesisId,
273
+ timestamp: ts,
274
+ checks: validChecks,
275
+ claims: validClaims,
276
+ summary: {
277
+ total_checks: validChecks.length,
278
+ passed_checks: passedChecks.length,
279
+ failed_checks: failedChecks.length,
280
+ total_claims: validClaims.length,
281
+ conflict_count: conflicts.length,
282
+ verdict,
283
+ },
284
+ verified_items: verifiedItems,
285
+ claimed_items: claimedItems,
286
+ conflicts,
287
+ };
288
+ }
289
+
290
+ module.exports = {
291
+ createImplementationCheck,
292
+ createEvidenceClaim,
293
+ synthesizeReviewResults,
294
+ };