tryassay 0.28.2 → 0.30.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.
Files changed (93) hide show
  1. package/dist/cli.js +10 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/assess.js +4 -2
  4. package/dist/commands/assess.js.map +1 -1
  5. package/dist/commands/generate.js +1 -0
  6. package/dist/commands/generate.js.map +1 -1
  7. package/dist/commands/harvest.d.ts +9 -0
  8. package/dist/commands/harvest.js +76 -0
  9. package/dist/commands/harvest.js.map +1 -0
  10. package/dist/lib/__tests__/learned-rules.test.d.ts +1 -0
  11. package/dist/lib/__tests__/learned-rules.test.js +260 -0
  12. package/dist/lib/__tests__/learned-rules.test.js.map +1 -0
  13. package/dist/lib/__tests__/pr-harvester-types.test.d.ts +1 -0
  14. package/dist/lib/__tests__/pr-harvester-types.test.js +43 -0
  15. package/dist/lib/__tests__/pr-harvester-types.test.js.map +1 -0
  16. package/dist/lib/__tests__/pr-harvester.test.d.ts +1 -0
  17. package/dist/lib/__tests__/pr-harvester.test.js +341 -0
  18. package/dist/lib/__tests__/pr-harvester.test.js.map +1 -0
  19. package/dist/lib/__tests__/rule-harvester.test.d.ts +1 -0
  20. package/dist/lib/__tests__/rule-harvester.test.js +526 -0
  21. package/dist/lib/__tests__/rule-harvester.test.js.map +1 -0
  22. package/dist/lib/claim-extractor.d.ts +1 -0
  23. package/dist/lib/claim-extractor.js +116 -15
  24. package/dist/lib/claim-extractor.js.map +1 -1
  25. package/dist/lib/code-verifier.d.ts +12 -1
  26. package/dist/lib/code-verifier.js +155 -12
  27. package/dist/lib/code-verifier.js.map +1 -1
  28. package/dist/lib/learned-rules/category-map.d.ts +28 -0
  29. package/dist/lib/learned-rules/category-map.js +110 -0
  30. package/dist/lib/learned-rules/category-map.js.map +1 -0
  31. package/dist/lib/learned-rules/index.d.ts +105 -0
  32. package/dist/lib/learned-rules/index.js +198 -0
  33. package/dist/lib/learned-rules/index.js.map +1 -0
  34. package/dist/lib/learned-rules/learned-catalog.d.ts +62 -0
  35. package/dist/lib/learned-rules/learned-catalog.js +161 -0
  36. package/dist/lib/learned-rules/learned-catalog.js.map +1 -0
  37. package/dist/lib/learned-rules/pattern-extractor.d.ts +25 -0
  38. package/dist/lib/learned-rules/pattern-extractor.js +351 -0
  39. package/dist/lib/learned-rules/pattern-extractor.js.map +1 -0
  40. package/dist/lib/learned-rules/rule-codifier.d.ts +41 -0
  41. package/dist/lib/learned-rules/rule-codifier.js +138 -0
  42. package/dist/lib/learned-rules/rule-codifier.js.map +1 -0
  43. package/dist/lib/learned-rules/starter-catalog.d.ts +16 -0
  44. package/dist/lib/learned-rules/starter-catalog.js +402 -0
  45. package/dist/lib/learned-rules/starter-catalog.js.map +1 -0
  46. package/dist/lib/learned-rules/types.d.ts +196 -0
  47. package/dist/lib/learned-rules/types.js +9 -0
  48. package/dist/lib/learned-rules/types.js.map +1 -0
  49. package/dist/lib/learned-rules/validation-harness.d.ts +26 -0
  50. package/dist/lib/learned-rules/validation-harness.js +260 -0
  51. package/dist/lib/learned-rules/validation-harness.js.map +1 -0
  52. package/dist/lib/llm-provider.d.ts +7 -0
  53. package/dist/lib/llm-provider.js +99 -6
  54. package/dist/lib/llm-provider.js.map +1 -1
  55. package/dist/lib/rule-harvester/diff-parser.d.ts +9 -0
  56. package/dist/lib/rule-harvester/diff-parser.js +77 -0
  57. package/dist/lib/rule-harvester/diff-parser.js.map +1 -0
  58. package/dist/lib/rule-harvester/file-selector.d.ts +10 -0
  59. package/dist/lib/rule-harvester/file-selector.js +59 -0
  60. package/dist/lib/rule-harvester/file-selector.js.map +1 -0
  61. package/dist/lib/rule-harvester/ground-truth.d.ts +19 -0
  62. package/dist/lib/rule-harvester/ground-truth.js +156 -0
  63. package/dist/lib/rule-harvester/ground-truth.js.map +1 -0
  64. package/dist/lib/rule-harvester/harvest.d.ts +26 -0
  65. package/dist/lib/rule-harvester/harvest.js +307 -0
  66. package/dist/lib/rule-harvester/harvest.js.map +1 -0
  67. package/dist/lib/rule-harvester/pr-discovery.d.ts +49 -0
  68. package/dist/lib/rule-harvester/pr-discovery.js +168 -0
  69. package/dist/lib/rule-harvester/pr-discovery.js.map +1 -0
  70. package/dist/lib/rule-harvester/pr-harvest.d.ts +53 -0
  71. package/dist/lib/rule-harvester/pr-harvest.js +326 -0
  72. package/dist/lib/rule-harvester/pr-harvest.js.map +1 -0
  73. package/dist/lib/rule-harvester/progress.d.ts +13 -0
  74. package/dist/lib/rule-harvester/progress.js +50 -0
  75. package/dist/lib/rule-harvester/progress.js.map +1 -0
  76. package/dist/lib/rule-harvester/reporter.d.ts +35 -0
  77. package/dist/lib/rule-harvester/reporter.js +46 -0
  78. package/dist/lib/rule-harvester/reporter.js.map +1 -0
  79. package/dist/lib/rule-harvester/rule-generalizer.d.ts +25 -0
  80. package/dist/lib/rule-harvester/rule-generalizer.js +135 -0
  81. package/dist/lib/rule-harvester/rule-generalizer.js.map +1 -0
  82. package/dist/lib/rule-harvester/scanner.d.ts +20 -0
  83. package/dist/lib/rule-harvester/scanner.js +37 -0
  84. package/dist/lib/rule-harvester/scanner.js.map +1 -0
  85. package/dist/runtime/types.d.ts +1 -1
  86. package/dist/sdk/forward-verify.d.ts +3 -1
  87. package/dist/sdk/forward-verify.js +68 -5
  88. package/dist/sdk/forward-verify.js.map +1 -1
  89. package/dist/sdk/index.d.ts +1 -1
  90. package/dist/sdk/index.js +7 -5
  91. package/dist/sdk/index.js.map +1 -1
  92. package/dist/sdk/types.d.ts +21 -0
  93. package/package.json +1 -1
@@ -1,5 +1,11 @@
1
1
  import { MODEL } from './anthropic.js';
2
2
  import { getProvider } from './llm-provider.js';
3
+ // ── Multi-Pass Configuration ────────────────────────────────────
4
+ // Proven in LUCID audit: multi-pass extraction eliminates 0-claim dead zones.
5
+ // Single-pass: 46 claims across 5 files (3 files returned 0).
6
+ // Multi-pass (3x): 165 claims across 5 files (0 files returned 0).
7
+ const EXTRACT_PASSES = parseInt(process.env.ASSAY_EXTRACT_PASSES ?? '3');
8
+ const SIMILARITY_THRESHOLD = parseFloat(process.env.ASSAY_SIMILARITY_THRESHOLD ?? '0.6');
3
9
  const EXTRACTION_SYSTEM_PROMPT = `You are a legal and technical claim extractor. Your job is to read a document (Terms of Service, Privacy Policy, API documentation, or user manual) and extract every declarative promise, commitment, or factual claim the document makes.
4
10
 
5
11
  EXTRACTION RULES:
@@ -68,17 +74,46 @@ function validateClaim(raw, index) {
68
74
  testable: typeof raw.testable === 'boolean' ? raw.testable : true,
69
75
  };
70
76
  }
71
- export async function extractClaims(document, onProgress) {
72
- onProgress?.('Sending document to Claude for claim extraction...');
73
- const result = await getProvider().complete({
74
- model: MODEL,
75
- maxTokens: 32_000,
76
- systemPrompt: EXTRACTION_SYSTEM_PROMPT,
77
- userPrompt: `Extract all claims from this document:\n\n${document}`,
78
- });
79
- const rawText = result.content;
80
- onProgress?.('Parsing extraction results...');
81
- // Strip markdown code fences if present, then find the JSON array
77
+ // ── Claim Deduplication (from LUCID multi-pass pattern) ─────────
78
+ function normalizeForComparison(s) {
79
+ return s.toLowerCase().replace(/[^a-z0-9]/g, ' ').replace(/\s+/g, ' ').trim();
80
+ }
81
+ function stringSimilarity(a, b) {
82
+ if (a === b)
83
+ return 1.0;
84
+ const aWords = new Set(a.split(' '));
85
+ const bWords = new Set(b.split(' '));
86
+ const intersection = new Set([...aWords].filter(w => bWords.has(w)));
87
+ const union = new Set([...aWords, ...bWords]);
88
+ return union.size > 0 ? intersection.size / union.size : 0;
89
+ }
90
+ function deduplicateClaims(allPasses) {
91
+ const merged = [];
92
+ const signatures = [];
93
+ for (const passClaims of allPasses) {
94
+ for (const claim of passClaims) {
95
+ const sig = normalizeForComparison(claim.text);
96
+ let isDuplicate = false;
97
+ for (const existingSig of signatures) {
98
+ if (stringSimilarity(sig, existingSig) > SIMILARITY_THRESHOLD) {
99
+ isDuplicate = true;
100
+ break;
101
+ }
102
+ }
103
+ if (!isDuplicate) {
104
+ const newClaim = {
105
+ ...claim,
106
+ id: `CLAIM-${String(merged.length + 1).padStart(3, '0')}`,
107
+ };
108
+ merged.push(newClaim);
109
+ signatures.push(sig);
110
+ }
111
+ }
112
+ }
113
+ return merged;
114
+ }
115
+ // ── Single-pass extraction (internal) ───────────────────────────
116
+ function parseExtractionResponse(rawText, onProgress) {
82
117
  let jsonText = rawText.trim();
83
118
  // Remove opening code fence
84
119
  if (jsonText.startsWith('```')) {
@@ -95,7 +130,6 @@ export async function extractClaims(document, onProgress) {
95
130
  jsonText = jsonText.trim();
96
131
  // If response was truncated (no closing ]), try to repair by closing the array
97
132
  if (!jsonText.endsWith(']')) {
98
- // Find the last complete object (ends with })
99
133
  const lastCloseBrace = jsonText.lastIndexOf('}');
100
134
  if (lastCloseBrace !== -1) {
101
135
  jsonText = jsonText.slice(0, lastCloseBrace + 1) + '\n]';
@@ -107,11 +141,33 @@ export async function extractClaims(document, onProgress) {
107
141
  parsed = JSON.parse(jsonText);
108
142
  }
109
143
  catch {
110
- throw new Error(`Failed to parse Claude's response as JSON.\n` +
111
- `First 200 chars: ${jsonText.slice(0, 200)}`);
144
+ // Try to extract array from wrapped object (e.g. {"claims": [...]})
145
+ try {
146
+ const obj = JSON.parse(jsonText.replace(/^\{/, '').replace(/\}$/, ''));
147
+ if (Array.isArray(obj))
148
+ parsed = obj;
149
+ }
150
+ catch {
151
+ // Fall through
152
+ }
153
+ if (!parsed) {
154
+ throw new Error(`Failed to parse response as JSON.\n` +
155
+ `First 200 chars: ${jsonText.slice(0, 200)}`);
156
+ }
112
157
  }
113
158
  if (!Array.isArray(parsed)) {
114
- throw new Error('Expected a JSON array of claims from Claude.');
159
+ // Check if it's a wrapper object with an array inside
160
+ if (parsed && typeof parsed === 'object') {
161
+ for (const val of Object.values(parsed)) {
162
+ if (Array.isArray(val)) {
163
+ parsed = val;
164
+ break;
165
+ }
166
+ }
167
+ }
168
+ if (!Array.isArray(parsed)) {
169
+ throw new Error('Expected a JSON array of claims.');
170
+ }
115
171
  }
116
172
  const claims = [];
117
173
  for (let i = 0; i < parsed.length; i++) {
@@ -120,10 +176,55 @@ export async function extractClaims(document, onProgress) {
120
176
  claims.push(validated);
121
177
  }
122
178
  }
179
+ return claims;
180
+ }
181
+ async function singlePassExtract(document, onProgress) {
182
+ const result = await getProvider().complete({
183
+ model: MODEL,
184
+ maxTokens: 32_000,
185
+ systemPrompt: EXTRACTION_SYSTEM_PROMPT,
186
+ userPrompt: `Extract all claims from this document:\n\n${document}`,
187
+ });
188
+ const claims = parseExtractionResponse(result.content, onProgress);
123
189
  return {
124
190
  claims,
125
191
  inputTokens: result.inputTokens ?? 0,
126
192
  outputTokens: result.outputTokens ?? 0,
127
193
  };
128
194
  }
195
+ // ── Public API: Multi-Pass Extraction ───────────────────────────
196
+ export async function extractClaims(document, onProgress) {
197
+ const passes = EXTRACT_PASSES;
198
+ let totalInput = 0;
199
+ let totalOutput = 0;
200
+ const allPasses = [];
201
+ const passDetails = [];
202
+ for (let pass = 0; pass < passes; pass++) {
203
+ onProgress?.(`Extraction pass ${pass + 1}/${passes}...`);
204
+ try {
205
+ let result = await singlePassExtract(document, onProgress);
206
+ // Retry once if 0 claims (model inconsistency — proven in LUCID audit)
207
+ if (result.claims.length === 0 && pass < passes - 1) {
208
+ onProgress?.(`Pass ${pass + 1} returned 0 claims, retrying...`);
209
+ result = await singlePassExtract(document, onProgress);
210
+ }
211
+ allPasses.push(result.claims);
212
+ passDetails.push(result.claims.length);
213
+ totalInput += result.inputTokens;
214
+ totalOutput += result.outputTokens;
215
+ onProgress?.(`Pass ${pass + 1}: ${result.claims.length} claims extracted`);
216
+ }
217
+ catch (err) {
218
+ onProgress?.(`Pass ${pass + 1} failed: ${err.message}`);
219
+ allPasses.push([]);
220
+ passDetails.push(0);
221
+ }
222
+ }
223
+ // Deduplicate across all passes → locked claim set
224
+ const claims = passes > 1
225
+ ? deduplicateClaims(allPasses)
226
+ : allPasses[0] ?? [];
227
+ onProgress?.(`Locked claim set: ${claims.length} claims (from ${passDetails.join('+')} across ${passes} passes)`);
228
+ return { claims, inputTokens: totalInput, outputTokens: totalOutput, passDetails };
229
+ }
129
230
  //# sourceMappingURL=claim-extractor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claim-extractor.js","sourceRoot":"","sources":["../../src/lib/claim-extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claim-extractor.js","sourceRoot":"","sources":["../../src/lib/claim-extractor.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,18 @@
1
1
  import type { CodebaseIndex } from './codebase-indexer.js';
2
- import type { Claim, ClaimVerification } from '../types.js';
2
+ import type { Claim, ClaimVerification, Verdict } from '../types.js';
3
3
  export declare function verifyClaims(claims: Claim[], index: CodebaseIndex, onProgress?: (msg: string) => void): Promise<{
4
4
  verifications: ClaimVerification[];
5
5
  inputTokens: number;
6
6
  outputTokens: number;
7
+ voteDetails?: {
8
+ passes: number;
9
+ minConfidence: number;
10
+ votes: Array<{
11
+ claimId: string;
12
+ finalVerdict: Verdict;
13
+ confidence: number;
14
+ votes: Verdict[];
15
+ unanimous: boolean;
16
+ }>;
17
+ };
7
18
  }>;
@@ -1,6 +1,11 @@
1
1
  import { MODEL } from './anthropic.js';
2
2
  import { getProvider } from './llm-provider.js';
3
3
  import { readFileContent } from './codebase-indexer.js';
4
+ // ── Multi-Pass Configuration ────────────────────────────────────
5
+ // Proven in LUCID audit: majority-vote verification filters verifier noise.
6
+ // Single-pass: 5 unfiltered findings. Multi-pass (3x): 35 confident findings.
7
+ const VERIFY_PASSES = parseInt(process.env.ASSAY_VERIFY_PASSES ?? '3');
8
+ const MIN_CONFIDENCE = parseFloat(process.env.ASSAY_MIN_CONFIDENCE ?? '0.67');
4
9
  const VALID_VERDICTS = ['PASS', 'PARTIAL', 'FAIL', 'N/A'];
5
10
  // Step 1: Ask Claude which files to examine for a batch of claims
6
11
  const FILE_SELECTION_SYSTEM = `You are a code auditor. Given a list of claims and a codebase file tree, identify which files are most likely to contain evidence for or against each claim.
@@ -117,7 +122,50 @@ function parseFileSelectionResponse(rawText) {
117
122
  // Larger batches = fewer API round-trips. 25 is the sweet spot:
118
123
  // still fits comfortably in context, but cuts batch count ~40% vs 15.
119
124
  const BATCH_SIZE = 25;
120
- export async function verifyClaims(claims, index, onProgress) {
125
+ function majorityVote(claimId, allPassResults) {
126
+ const votes = [];
127
+ const reasonings = new Map();
128
+ for (const passResults of allPassResults) {
129
+ const v = passResults.find((r) => r.claimId === claimId);
130
+ if (v) {
131
+ votes.push(v.verdict);
132
+ reasonings.set(v.verdict, v.reasoning);
133
+ }
134
+ }
135
+ if (votes.length === 0) {
136
+ return {
137
+ claimId,
138
+ finalVerdict: 'N/A',
139
+ confidence: 0,
140
+ votes: [],
141
+ reasoning: 'No verification data',
142
+ unanimous: false,
143
+ };
144
+ }
145
+ const counts = { PASS: 0, PARTIAL: 0, FAIL: 0, 'N/A': 0 };
146
+ for (const v of votes)
147
+ counts[v]++;
148
+ let finalVerdict = 'N/A';
149
+ let maxCount = 0;
150
+ for (const [verdict, count] of Object.entries(counts)) {
151
+ if (count > maxCount) {
152
+ maxCount = count;
153
+ finalVerdict = verdict;
154
+ }
155
+ }
156
+ const confidence = maxCount / votes.length;
157
+ const unanimous = maxCount === votes.length && votes.length > 1;
158
+ return {
159
+ claimId,
160
+ finalVerdict,
161
+ confidence,
162
+ votes,
163
+ reasoning: reasonings.get(finalVerdict) ?? 'No reasoning available',
164
+ unanimous,
165
+ };
166
+ }
167
+ // ── Single-Pass Verification (internal) ─────────────────────────
168
+ async function singlePassVerify(claims, index, passLabel, onProgress) {
121
169
  const testableClaims = claims.filter((c) => c.testable);
122
170
  const verifications = [];
123
171
  let totalInputTokens = 0;
@@ -141,7 +189,7 @@ export async function verifyClaims(claims, index, onProgress) {
141
189
  const batch = testableClaims.slice(i, i + BATCH_SIZE);
142
190
  const batchNum = Math.floor(i / BATCH_SIZE) + 1;
143
191
  const totalBatches = Math.ceil(testableClaims.length / BATCH_SIZE);
144
- onProgress?.(`Batch ${batchNum}/${totalBatches}: selecting files for ${batch.length} claims...`);
192
+ onProgress?.(`${passLabel} Batch ${batchNum}/${totalBatches}: selecting files for ${batch.length} claims...`);
145
193
  // Step 1: Ask which files to examine
146
194
  const claimList = batch
147
195
  .map((c) => `${c.id}: ${c.text} [${c.category}]`)
@@ -159,7 +207,6 @@ export async function verifyClaims(claims, index, onProgress) {
159
207
  fileSelections = parseFileSelectionResponse(fileSelResult.content);
160
208
  }
161
209
  catch {
162
- // If parsing fails, use key files as fallback
163
210
  fileSelections = {};
164
211
  for (const claim of batch) {
165
212
  fileSelections[claim.id] = index.keyFiles.slice(0, 5).map((f) => f.path);
@@ -171,7 +218,7 @@ export async function verifyClaims(claims, index, onProgress) {
171
218
  for (const f of files)
172
219
  uniqueFiles.add(f);
173
220
  }
174
- onProgress?.(`Batch ${batchNum}/${totalBatches}: reading ${uniqueFiles.size} files...`);
221
+ onProgress?.(`${passLabel} Batch ${batchNum}/${totalBatches}: reading ${uniqueFiles.size} files...`);
175
222
  const fileContents = new Map();
176
223
  for (const filePath of uniqueFiles) {
177
224
  const content = await readFileContent(index.rootPath, filePath);
@@ -180,17 +227,14 @@ export async function verifyClaims(claims, index, onProgress) {
180
227
  }
181
228
  }
182
229
  // Step 3: Verify claims against file contents
183
- onProgress?.(`Batch ${batchNum}/${totalBatches}: verifying ${batch.length} claims...`);
184
- // Build context with file contents for this batch
230
+ onProgress?.(`${passLabel} Batch ${batchNum}/${totalBatches}: verifying ${batch.length} claims...`);
185
231
  let evidenceContext = '';
186
232
  for (const [path, content] of fileContents) {
187
- // Limit each file to keep total context manageable
188
233
  const truncated = content.length > 10_000
189
234
  ? content.slice(0, 10_000) + '\n[... truncated]'
190
235
  : content;
191
236
  evidenceContext += `\n--- FILE: ${path} ---\n${truncated}\n`;
192
237
  }
193
- // If total context is too large, truncate
194
238
  if (evidenceContext.length > 100_000) {
195
239
  evidenceContext = evidenceContext.slice(0, 100_000) + '\n[... context truncated]';
196
240
  }
@@ -204,7 +248,6 @@ export async function verifyClaims(claims, index, onProgress) {
204
248
  totalOutputTokens += verifyResult.outputTokens ?? 0;
205
249
  try {
206
250
  const batchResults = parseVerificationResponse(verifyResult.content);
207
- // Attach claim text
208
251
  for (const result of batchResults) {
209
252
  const claim = batch.find((c) => c.id === result.claimId);
210
253
  if (claim) {
@@ -212,7 +255,6 @@ export async function verifyClaims(claims, index, onProgress) {
212
255
  verifications.push(result);
213
256
  }
214
257
  }
215
- // Any claims not covered in response get N/A
216
258
  for (const claim of batch) {
217
259
  if (!batchResults.some((r) => r.claimId === claim.id)) {
218
260
  verifications.push({
@@ -226,7 +268,6 @@ export async function verifyClaims(claims, index, onProgress) {
226
268
  }
227
269
  }
228
270
  catch {
229
- // If verification parsing fails, mark batch as N/A
230
271
  for (const claim of batch) {
231
272
  verifications.push({
232
273
  claimId: claim.id,
@@ -238,7 +279,6 @@ export async function verifyClaims(claims, index, onProgress) {
238
279
  }
239
280
  }
240
281
  }
241
- // Sort by claim ID
242
282
  verifications.sort((a, b) => a.claimId.localeCompare(b.claimId));
243
283
  return {
244
284
  verifications,
@@ -246,4 +286,107 @@ export async function verifyClaims(claims, index, onProgress) {
246
286
  outputTokens: totalOutputTokens,
247
287
  };
248
288
  }
289
+ // ── Public API: Multi-Pass Verification with Majority Vote ──────
290
+ export async function verifyClaims(claims, index, onProgress) {
291
+ const passes = VERIFY_PASSES;
292
+ let totalInput = 0;
293
+ let totalOutput = 0;
294
+ if (passes <= 1) {
295
+ // Single-pass mode (backward compatible)
296
+ onProgress?.('Running single-pass verification...');
297
+ const result = await singlePassVerify(claims, index, '', onProgress);
298
+ return {
299
+ verifications: result.verifications,
300
+ inputTokens: result.inputTokens,
301
+ outputTokens: result.outputTokens,
302
+ };
303
+ }
304
+ // Multi-pass mode: verify N times, then majority vote
305
+ const allPassResults = [];
306
+ for (let pass = 0; pass < passes; pass++) {
307
+ const passLabel = `[Pass ${pass + 1}/${passes}]`;
308
+ onProgress?.(`Verification pass ${pass + 1}/${passes}...`);
309
+ try {
310
+ const result = await singlePassVerify(claims, index, passLabel, onProgress);
311
+ allPassResults.push(result.verifications);
312
+ totalInput += result.inputTokens;
313
+ totalOutput += result.outputTokens;
314
+ const passCount = result.verifications.filter((v) => v.verdict === 'PASS').length;
315
+ const failCount = result.verifications.filter((v) => v.verdict === 'FAIL').length;
316
+ onProgress?.(`Pass ${pass + 1}: ${result.verifications.length} results (${passCount} pass, ${failCount} fail)`);
317
+ }
318
+ catch (err) {
319
+ onProgress?.(`Verification pass ${pass + 1} failed: ${err.message}`);
320
+ allPassResults.push([]);
321
+ }
322
+ }
323
+ // Majority vote across all passes
324
+ const testableClaims = claims.filter((c) => c.testable);
325
+ const nonTestableClaims = claims.filter((c) => !c.testable);
326
+ const voteResults = [];
327
+ for (const claim of testableClaims) {
328
+ voteResults.push(majorityVote(claim.id, allPassResults));
329
+ }
330
+ // Build final verifications from vote results
331
+ const verifications = [];
332
+ // Non-testable claims
333
+ for (const claim of nonTestableClaims) {
334
+ verifications.push({
335
+ claimId: claim.id,
336
+ claim: claim.text,
337
+ verdict: 'N/A',
338
+ evidence: [],
339
+ reasoning: 'Claim is not testable against code.',
340
+ });
341
+ }
342
+ // Voted claims — use evidence from the pass that matches the majority verdict
343
+ for (const vote of voteResults) {
344
+ const claim = claims.find((c) => c.id === vote.claimId);
345
+ if (!claim)
346
+ continue;
347
+ // Find the best evidence from a pass that agreed with the majority
348
+ let bestEvidence = [];
349
+ let bestReasoning = vote.reasoning;
350
+ for (const passResults of allPassResults) {
351
+ const match = passResults.find((r) => r.claimId === vote.claimId && r.verdict === vote.finalVerdict);
352
+ if (match && match.evidence.length > bestEvidence.length) {
353
+ bestEvidence = match.evidence;
354
+ bestReasoning = match.reasoning;
355
+ }
356
+ }
357
+ // Apply confidence filtering: low-confidence results get downgraded
358
+ let finalVerdict = vote.finalVerdict;
359
+ if (vote.confidence < MIN_CONFIDENCE && finalVerdict !== 'PASS') {
360
+ // Low confidence non-PASS → treat as noise, upgrade to N/A
361
+ finalVerdict = 'N/A';
362
+ bestReasoning = `Low confidence (${(vote.confidence * 100).toFixed(0)}%) — ${vote.votes.join('/')} — filtered as noise. Original: ${bestReasoning}`;
363
+ }
364
+ verifications.push({
365
+ claimId: vote.claimId,
366
+ claim: claim.text,
367
+ verdict: finalVerdict,
368
+ evidence: bestEvidence,
369
+ reasoning: bestReasoning,
370
+ });
371
+ }
372
+ verifications.sort((a, b) => a.claimId.localeCompare(b.claimId));
373
+ const confidentFindings = voteResults.filter((v) => v.finalVerdict !== 'PASS' && v.confidence >= MIN_CONFIDENCE).length;
374
+ onProgress?.(`Majority vote complete: ${confidentFindings} confident findings (>=${(MIN_CONFIDENCE * 100).toFixed(0)}% confidence)`);
375
+ return {
376
+ verifications,
377
+ inputTokens: totalInput,
378
+ outputTokens: totalOutput,
379
+ voteDetails: {
380
+ passes,
381
+ minConfidence: MIN_CONFIDENCE,
382
+ votes: voteResults.map((v) => ({
383
+ claimId: v.claimId,
384
+ finalVerdict: v.finalVerdict,
385
+ confidence: v.confidence,
386
+ votes: v.votes,
387
+ unanimous: v.unanimous,
388
+ })),
389
+ },
390
+ };
391
+ }
249
392
  //# sourceMappingURL=code-verifier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-verifier.js","sourceRoot":"","sources":["../../src/lib/code-verifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-verifier.js","sourceRoot":"","sources":["../../src/lib/code-verifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Canonical Category Map — normalizes the fragmented claim categories
3
+ * (37 variants) down to ~12 canonical categories.
4
+ *
5
+ * Used in two places:
6
+ * 1. Rule creation (harvester + pattern extractor) — new rules get canonical categories
7
+ * 2. Rule loading (catalog) — existing rules get mapped at load time
8
+ */
9
+ /**
10
+ * The canonical set of claim categories for all learned rules.
11
+ */
12
+ export declare const CANONICAL_CATEGORIES: readonly ["security", "error-handling", "data-validation", "async", "resource-management", "api-contract", "state-management", "i18n", "performance", "type-safety", "ui-logic", "code-quality"];
13
+ export type CanonicalCategory = (typeof CANONICAL_CATEGORIES)[number];
14
+ /**
15
+ * Maps every known raw category string to its canonical form.
16
+ *
17
+ * When adding new mappings, keep the keys lowercase and hyphenated.
18
+ */
19
+ export declare const CATEGORY_MAP: Readonly<Record<string, CanonicalCategory>>;
20
+ /**
21
+ * Normalize a raw category string to its canonical form.
22
+ *
23
+ * Lookup order:
24
+ * 1. Exact match in CATEGORY_MAP
25
+ * 2. Lowercase + trim exact match
26
+ * 3. Fallback to 'code-quality' (the broadest bucket)
27
+ */
28
+ export declare function normalizeCategory(raw: string): CanonicalCategory;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Canonical Category Map — normalizes the fragmented claim categories
3
+ * (37 variants) down to ~12 canonical categories.
4
+ *
5
+ * Used in two places:
6
+ * 1. Rule creation (harvester + pattern extractor) — new rules get canonical categories
7
+ * 2. Rule loading (catalog) — existing rules get mapped at load time
8
+ */
9
+ /**
10
+ * The canonical set of claim categories for all learned rules.
11
+ */
12
+ export const CANONICAL_CATEGORIES = [
13
+ 'security',
14
+ 'error-handling',
15
+ 'data-validation',
16
+ 'async',
17
+ 'resource-management',
18
+ 'api-contract',
19
+ 'state-management',
20
+ 'i18n',
21
+ 'performance',
22
+ 'type-safety',
23
+ 'ui-logic',
24
+ 'code-quality',
25
+ ];
26
+ /**
27
+ * Maps every known raw category string to its canonical form.
28
+ *
29
+ * When adding new mappings, keep the keys lowercase and hyphenated.
30
+ */
31
+ export const CATEGORY_MAP = {
32
+ // ── security ────────────────────────────────────────────────
33
+ 'security': 'security',
34
+ // ── error-handling ──────────────────────────────────────────
35
+ 'error-handling': 'error-handling',
36
+ 'null-safety': 'error-handling',
37
+ 'logging': 'error-handling',
38
+ // ── data-validation ─────────────────────────────────────────
39
+ 'data-validation': 'data-validation',
40
+ 'validation-safety': 'data-validation',
41
+ 'data-integrity': 'data-validation',
42
+ 'data-accuracy': 'data-validation',
43
+ 'data-consistency': 'data-validation',
44
+ 'database-integrity': 'data-validation',
45
+ // ── async ───────────────────────────────────────────────────
46
+ 'async': 'async',
47
+ 'concurrency': 'async',
48
+ 'race-condition': 'async',
49
+ 'race-conditions': 'async',
50
+ // ── resource-management ─────────────────────────────────────
51
+ 'resource-management': 'resource-management',
52
+ // ── api-contract ────────────────────────────────────────────
53
+ 'api-contract': 'api-contract',
54
+ 'dependency-injection': 'api-contract',
55
+ // ── state-management ────────────────────────────────────────
56
+ 'state-management': 'state-management',
57
+ // ── i18n ────────────────────────────────────────────────────
58
+ 'i18n': 'i18n',
59
+ 'i18n-compliance': 'i18n',
60
+ 'i18n-safety': 'i18n',
61
+ 'i18n-support': 'i18n',
62
+ 'internationalization': 'i18n',
63
+ 'localization': 'i18n',
64
+ // ── performance ─────────────────────────────────────────────
65
+ 'performance': 'performance',
66
+ 'react-optimization': 'performance',
67
+ // ── type-safety ─────────────────────────────────────────────
68
+ 'type-safety': 'type-safety',
69
+ // ── ui-logic ────────────────────────────────────────────────
70
+ 'ui-logic': 'ui-logic',
71
+ 'ui-ux': 'ui-logic',
72
+ 'react-antipatterns': 'ui-logic',
73
+ 'react-best-practices': 'ui-logic',
74
+ 'react-patterns': 'ui-logic',
75
+ // ── code-quality ────────────────────────────────────────────
76
+ 'code-quality': 'code-quality',
77
+ 'code-convention': 'code-quality',
78
+ 'documentation': 'code-quality',
79
+ 'test-reliability': 'code-quality',
80
+ 'test-robustness': 'code-quality',
81
+ // ── catch-all for logic variants ────────────────────────────
82
+ 'logic': 'error-handling',
83
+ 'logic-error': 'error-handling',
84
+ 'logic-flow': 'error-handling',
85
+ 'logic-control-flow': 'error-handling',
86
+ 'bug-fix': 'error-handling',
87
+ 'business-logic': 'data-validation',
88
+ };
89
+ /**
90
+ * Normalize a raw category string to its canonical form.
91
+ *
92
+ * Lookup order:
93
+ * 1. Exact match in CATEGORY_MAP
94
+ * 2. Lowercase + trim exact match
95
+ * 3. Fallback to 'code-quality' (the broadest bucket)
96
+ */
97
+ export function normalizeCategory(raw) {
98
+ // 1. Exact match
99
+ const exact = CATEGORY_MAP[raw];
100
+ if (exact)
101
+ return exact;
102
+ // 2. Normalized match (lowercase, trimmed)
103
+ const normalized = raw.toLowerCase().trim();
104
+ const normMatch = CATEGORY_MAP[normalized];
105
+ if (normMatch)
106
+ return normMatch;
107
+ // 3. Fallback
108
+ return 'code-quality';
109
+ }
110
+ //# sourceMappingURL=category-map.js.map