@oddessentials/odd-ai-reviewers 1.8.0 → 1.9.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.
Files changed (40) hide show
  1. package/dist/agents/ai_semantic_review.d.ts.map +1 -1
  2. package/dist/agents/ai_semantic_review.js +3 -0
  3. package/dist/agents/ai_semantic_review.js.map +1 -1
  4. package/dist/agents/control_flow/safe-source-detector.d.ts.map +1 -1
  5. package/dist/agents/control_flow/safe-source-detector.js +11 -1
  6. package/dist/agents/control_flow/safe-source-detector.js.map +1 -1
  7. package/dist/agents/control_flow/scope-stack.d.ts +54 -0
  8. package/dist/agents/control_flow/scope-stack.d.ts.map +1 -1
  9. package/dist/agents/control_flow/scope-stack.js +128 -0
  10. package/dist/agents/control_flow/scope-stack.js.map +1 -1
  11. package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -1
  12. package/dist/agents/control_flow/vulnerability-detector.js +380 -2
  13. package/dist/agents/control_flow/vulnerability-detector.js.map +1 -1
  14. package/dist/agents/opencode.d.ts.map +1 -1
  15. package/dist/agents/opencode.js +3 -0
  16. package/dist/agents/opencode.js.map +1 -1
  17. package/dist/agents/pr_agent.d.ts.map +1 -1
  18. package/dist/agents/pr_agent.js +4 -1
  19. package/dist/agents/pr_agent.js.map +1 -1
  20. package/dist/benchmark/adapter.d.ts +48 -0
  21. package/dist/benchmark/adapter.d.ts.map +1 -1
  22. package/dist/benchmark/adapter.js +81 -0
  23. package/dist/benchmark/adapter.js.map +1 -1
  24. package/dist/cli/dependencies/schemas.d.ts +3 -3
  25. package/dist/main.d.ts.map +1 -1
  26. package/dist/main.js +1 -1
  27. package/dist/main.js.map +1 -1
  28. package/dist/phases/report.d.ts +1 -1
  29. package/dist/phases/report.d.ts.map +1 -1
  30. package/dist/phases/report.js +28 -3
  31. package/dist/phases/report.js.map +1 -1
  32. package/dist/report/finding-validator.d.ts +27 -1
  33. package/dist/report/finding-validator.d.ts.map +1 -1
  34. package/dist/report/finding-validator.js +79 -5
  35. package/dist/report/finding-validator.js.map +1 -1
  36. package/dist/report/framework-pattern-filter.d.ts +53 -0
  37. package/dist/report/framework-pattern-filter.d.ts.map +1 -0
  38. package/dist/report/framework-pattern-filter.js +189 -0
  39. package/dist/report/framework-pattern-filter.js.map +1 -0
  40. package/package.json +1 -1
@@ -12,6 +12,16 @@ import { buildLineResolver, normalizeFindingsForDiff, computeDriftSignal, comput
12
12
  * When combined with info severity and no actionable suggestion,
13
13
  * the finding is likely a false positive.
14
14
  */
15
+ /**
16
+ * Strip zero-width and invisible Unicode characters that can bypass word-boundary regex matching.
17
+ * Only strips invisible characters — visible non-Latin characters are preserved.
18
+ *
19
+ * Characters stripped: U+200B (ZWSP), U+200C (ZWNJ), U+200D (ZWJ), U+200E (LRM),
20
+ * U+200F (RLM), U+2028 (Line Sep), U+2029 (Para Sep), U+FEFF (BOM/ZWNBS)
21
+ */
22
+ export function normalizeUnicode(text) {
23
+ return text.replace(/[\u200B-\u200F\u2028\u2029\uFEFF]/g, '');
24
+ }
15
25
  const DISMISSIVE_PATTERNS = [
16
26
  /\bno action required\b/i,
17
27
  /\bacceptable as[- ]is\b/i,
@@ -38,21 +48,71 @@ function hasActionableSuggestion(suggestion) {
38
48
  .trim();
39
49
  return residual.length > 0;
40
50
  }
51
+ /**
52
+ * Regex to extract action signals from PR title/description.
53
+ * Captures a verb (add, fix, remove, rename, update, refactor) followed by a subject.
54
+ */
55
+ const PR_INTENT_PATTERN = /\b(add|fix|remove|rename|update|refactor)\s+(.+)/i;
56
+ /**
57
+ * FR-014: Diagnostic PR intent contradiction logging.
58
+ *
59
+ * Extracts action signals from PR title/description and logs warnings when
60
+ * finding messages appear to contradict the stated PR intent.
61
+ * DIAGNOSTIC ONLY — no suppression, no filtering, no modification of findings.
62
+ *
63
+ * @param findings - Array of findings to check against PR intent
64
+ * @param prDescription - Combined PR title and description text
65
+ */
66
+ export function logPRIntentContradictions(findings, prDescription) {
67
+ const match = PR_INTENT_PATTERN.exec(prDescription);
68
+ if (!match)
69
+ return;
70
+ const verb = (match[1] ?? '').toLowerCase();
71
+ const subject = (match[2] ?? '').toLowerCase().trim();
72
+ for (const finding of findings) {
73
+ const messageLower = finding.message.toLowerCase();
74
+ // Check if the finding message references the same subject as the PR intent
75
+ // and appears to contradict the action (e.g., PR says "add X" but finding says "remove X")
76
+ if (!messageLower.includes(subject.slice(0, Math.min(subject.length, 30))))
77
+ continue;
78
+ const contradictionVerbs = {
79
+ add: ['remove', 'delete', 'drop', 'unnecessary'],
80
+ fix: ['break', 'revert', 'undo'],
81
+ remove: ['add', 'keep', 'preserve', 'missing'],
82
+ rename: ['revert', 'undo', 'original name'],
83
+ update: ['revert', 'downgrade', 'old version'],
84
+ refactor: ['revert', 'undo', 'original'],
85
+ };
86
+ const opposites = contradictionVerbs[verb] ?? [];
87
+ const hasContradiction = opposites.some((opp) => messageLower.includes(opp));
88
+ if (hasContradiction) {
89
+ console.log('[router] [finding-validator] [pr-intent]', {
90
+ warning: 'Finding may contradict PR intent',
91
+ prIntent: `${verb} ${subject}`,
92
+ findingFile: finding.file,
93
+ findingLine: finding.line,
94
+ findingMessage: finding.message.slice(0, 120),
95
+ });
96
+ }
97
+ }
98
+ }
41
99
  /**
42
100
  * Stage 1: Semantic-only validation (no lineResolver needed).
43
101
  *
44
102
  * Performs ONLY normalization-independent checks:
45
103
  * - Classification (inline / file-level / global / cross-file)
46
104
  * - Self-contradiction detection (info severity + dismissive language + no suggestion)
105
+ * - PR intent contradiction logging (FR-014, diagnostic only)
47
106
  * - NO line validation, NO path validation against diff
48
107
  *
49
108
  * Used in processFindings() BEFORE platform reporters run normalizeFindingsForDiff().
50
109
  * This ensures renamed-file and stale-line findings survive to be salvaged by normalization.
51
110
  *
52
111
  * @param findings - Array of findings to validate
112
+ * @param prDescription - Optional PR title/description for intent contradiction logging
53
113
  * @returns Validation summary with valid findings, filtered findings, and stats
54
114
  */
55
- export function validateFindingsSemantics(findings) {
115
+ export function validateFindingsSemantics(findings, prDescription) {
56
116
  const results = [];
57
117
  const stats = {
58
118
  total: findings.length,
@@ -93,10 +153,15 @@ export function validateFindingsSemantics(findings) {
93
153
  // Only filter info severity - NEVER filter warning/error
94
154
  if (result.finding.severity !== 'info')
95
155
  continue;
96
- const matchedPattern = DISMISSIVE_PATTERNS.find((p) => p.test(result.finding.message));
156
+ // FR-015: Normalize Unicode before matching to prevent zero-width character bypass
157
+ const normalizedMessage = normalizeUnicode(result.finding.message);
158
+ const matchedPattern = DISMISSIVE_PATTERNS.find((p) => p.test(normalizedMessage));
97
159
  if (!matchedPattern)
98
160
  continue;
99
- if (hasActionableSuggestion(result.finding.suggestion))
161
+ const normalizedSuggestion = result.finding.suggestion
162
+ ? normalizeUnicode(result.finding.suggestion)
163
+ : undefined;
164
+ if (hasActionableSuggestion(normalizedSuggestion))
100
165
  continue;
101
166
  // All 3 conditions met: info + dismissive + no actionable suggestion
102
167
  result.valid = false;
@@ -121,6 +186,10 @@ export function validateFindingsSemantics(findings) {
121
186
  filtered.push(result);
122
187
  }
123
188
  }
189
+ // FR-014: Diagnostic PR intent logging (no suppression, no filtering)
190
+ if (prDescription) {
191
+ logPRIntentContradictions(validFindings, prDescription);
192
+ }
124
193
  return { validFindings, filtered, stats };
125
194
  }
126
195
  /**
@@ -195,10 +264,15 @@ export function validateNormalizedFindings(findings, lineResolver, diffFiles) {
195
264
  continue;
196
265
  if (result.finding.severity !== 'info')
197
266
  continue;
198
- const matchedPattern = DISMISSIVE_PATTERNS.find((p) => p.test(result.finding.message));
267
+ // FR-015: Normalize Unicode before matching to prevent zero-width character bypass
268
+ const normalizedMessage = normalizeUnicode(result.finding.message);
269
+ const matchedPattern = DISMISSIVE_PATTERNS.find((p) => p.test(normalizedMessage));
199
270
  if (!matchedPattern)
200
271
  continue;
201
- if (hasActionableSuggestion(result.finding.suggestion))
272
+ const normalizedSuggestion = result.finding.suggestion
273
+ ? normalizeUnicode(result.finding.suggestion)
274
+ : undefined;
275
+ if (hasActionableSuggestion(normalizedSuggestion))
202
276
  continue;
203
277
  result.valid = false;
204
278
  result.filterReason = `Self-contradicting: info severity with dismissive language (${matchedPattern.source})`;
@@ -1 +1 @@
1
- {"version":3,"file":"finding-validator.js","sourceRoot":"","sources":["../../src/report/finding-validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"finding-validator.js","sourceRoot":"","sources":["../../src/report/finding-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Framework Pattern Filter (FR-013)
3
+ *
4
+ * Deterministic post-processing filter that catches Pattern B false positives
5
+ * using a closed, default-deny matcher table. Runs in Stage 1 validation
6
+ * (after self-contradiction filter, before Stage 2 diff-bound validation).
7
+ *
8
+ * The matcher table is CLOSED: only these 3 matchers exist.
9
+ * Adding a new matcher requires a spec amendment.
10
+ */
11
+ import type { Finding } from '../agents/types.js';
12
+ export interface FrameworkPatternMatcher {
13
+ /** Unique matcher identifier */
14
+ readonly id: string;
15
+ /** Human-readable name */
16
+ readonly name: string;
17
+ /** Regex that triggers evaluation when matched against finding.message */
18
+ readonly messagePattern: RegExp;
19
+ /**
20
+ * Validates structural evidence in diff content.
21
+ * Returns true if evidence confirms the framework pattern (suppress finding).
22
+ * Returns false if evidence is missing or ambiguous (pass finding through).
23
+ */
24
+ evidenceValidator: (finding: Finding, diffContent: string) => boolean;
25
+ /** Diagnostic reason logged when finding is suppressed */
26
+ readonly suppressionReason: string;
27
+ }
28
+ export interface FrameworkFilterResult {
29
+ finding: Finding;
30
+ suppressed: boolean;
31
+ matcherId?: string;
32
+ reason?: string;
33
+ }
34
+ export interface FrameworkFilterSummary {
35
+ total: number;
36
+ suppressed: number;
37
+ passed: number;
38
+ results: FrameworkFilterResult[];
39
+ }
40
+ /**
41
+ * Evaluate findings against the closed matcher table.
42
+ * Default-deny: only exact matches with validated evidence are suppressed.
43
+ *
44
+ * @param findings - Findings that passed Stage 1 semantic validation
45
+ * @param diffContent - Raw diff content for evidence validation
46
+ * @returns Summary with suppressed/passed findings and diagnostic details
47
+ */
48
+ export declare function filterFrameworkConventionFindings(findings: Finding[], diffContent: string): FrameworkFilterSummary;
49
+ /**
50
+ * Get the list of valid findings (non-suppressed) from a filter summary.
51
+ */
52
+ export declare function getValidFindings(summary: FrameworkFilterSummary): Finding[];
53
+ //# sourceMappingURL=framework-pattern-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-pattern-filter.d.ts","sourceRoot":"","sources":["../../src/report/framework-pattern-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAMlD,MAAM,WAAW,uBAAuB;IACtC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;IACtE,0DAA0D;IAC1D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,qBAAqB,EAAE,CAAC;CAClC;AAkKD;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,OAAO,EAAE,EACnB,WAAW,EAAE,MAAM,GAClB,sBAAsB,CAuCxB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,EAAE,CAE3E"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Framework Pattern Filter (FR-013)
3
+ *
4
+ * Deterministic post-processing filter that catches Pattern B false positives
5
+ * using a closed, default-deny matcher table. Runs in Stage 1 validation
6
+ * (after self-contradiction filter, before Stage 2 diff-bound validation).
7
+ *
8
+ * The matcher table is CLOSED: only these 3 matchers exist.
9
+ * Adding a new matcher requires a spec amendment.
10
+ */
11
+ // =============================================================================
12
+ // Evidence Helpers
13
+ // =============================================================================
14
+ /**
15
+ * Extract lines near a finding's line from diff content, scoped to the finding's file.
16
+ * Returns the relevant file's diff section for evidence scanning.
17
+ */
18
+ function extractFileDiffSection(finding, diffContent) {
19
+ if (!finding.file || !diffContent)
20
+ return '';
21
+ // Normalize Windows backslashes to forward slashes for diff header matching
22
+ const normalizedPath = finding.file.replace(/\\/g, '/');
23
+ // Split diff by file boundaries
24
+ const fileSections = diffContent.split(/^diff --git /m);
25
+ for (const section of fileSections) {
26
+ // Match against the finding's file path (check both a/ and b/ paths)
27
+ if (section.includes(`a/${normalizedPath} `) ||
28
+ section.includes(`b/${normalizedPath}`) ||
29
+ section.includes(`a/${normalizedPath}\n`) ||
30
+ section.includes(`b/${normalizedPath}\n`)) {
31
+ return section;
32
+ }
33
+ }
34
+ return '';
35
+ }
36
+ /**
37
+ * Extract lines near a specific line number from a diff section.
38
+ * Returns lines within a window around the target line.
39
+ */
40
+ function extractLinesNearFinding(diffSection, findingLine, windowSize = 10) {
41
+ if (findingLine === undefined)
42
+ return diffSection.split('\n');
43
+ const lines = diffSection.split('\n');
44
+ const result = [];
45
+ let currentLine = 0;
46
+ for (const line of lines) {
47
+ // Track line numbers from hunk headers
48
+ const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)/);
49
+ if (hunkMatch?.[1]) {
50
+ currentLine = parseInt(hunkMatch[1], 10) - 1;
51
+ continue;
52
+ }
53
+ if (line.startsWith('-'))
54
+ continue; // Skip removed lines
55
+ currentLine++;
56
+ if (currentLine >= findingLine - windowSize && currentLine <= findingLine + windowSize) {
57
+ // Strip diff prefix for content analysis
58
+ const content = line.startsWith('+')
59
+ ? line.slice(1)
60
+ : line.startsWith(' ')
61
+ ? line.slice(1)
62
+ : line;
63
+ result.push(content);
64
+ }
65
+ }
66
+ return result;
67
+ }
68
+ // =============================================================================
69
+ // Closed Matcher Table — DEFAULT DENY
70
+ // Only these 3 matchers. No additions without spec change.
71
+ // =============================================================================
72
+ const FRAMEWORK_MATCHERS = [
73
+ // T019: Express Error Middleware
74
+ {
75
+ id: 'express-error-mw',
76
+ name: 'Express Error Middleware',
77
+ messagePattern: /unused.*param/i,
78
+ evidenceValidator(finding, diffContent) {
79
+ const fileSection = extractFileDiffSection(finding, diffContent);
80
+ if (!fileSection)
81
+ return false;
82
+ // Must have a 4-parameter function near the finding line
83
+ // Express error middleware signature: (err, req, res, next) or variants
84
+ const nearbyLines = extractLinesNearFinding(fileSection, finding.line, 5);
85
+ const nearbyText = nearbyLines.join('\n');
86
+ // Match 4-param function: (param1, param2, param3, param4) with optional type annotations
87
+ const fourParamPattern = /\(\s*\w+\s*(?::\s*[^,)]+)?\s*,\s*\w+\s*(?::\s*[^,)]+)?\s*,\s*\w+\s*(?::\s*[^,)]+)?\s*,\s*\w+\s*(?::\s*[^,)]+)?\s*\)/;
88
+ const hasFourParams = fourParamPattern.test(nearbyText);
89
+ if (!hasFourParams)
90
+ return false;
91
+ // At least one Express indicator required (in the file section):
92
+ // - .use() middleware registration call
93
+ // - import from 'express' package
94
+ // - Express type annotations (Request, Response, NextFunction, ErrorRequestHandler)
95
+ const hasUseCall = /\.use\s*\(/.test(fileSection);
96
+ const hasExpressImport = /from\s+['"]express['"]/.test(fileSection);
97
+ const hasExpressTypes = /:\s*(?:Request|Response|NextFunction|ErrorRequestHandler)\b/.test(nearbyText);
98
+ return hasUseCall || hasExpressImport || hasExpressTypes;
99
+ },
100
+ suppressionReason: 'Express 4-param error middleware — unused params required by framework',
101
+ },
102
+ // T020: TypeScript Unused Prefix
103
+ {
104
+ id: 'ts-unused-prefix',
105
+ name: 'TypeScript Unused Prefix',
106
+ messagePattern: /unused.*(variable|parameter|binding|import)/i,
107
+ evidenceValidator(finding, _diffContent) {
108
+ // Extract identifier names from the finding message.
109
+ // Look for words that could be binding names (alphanumeric + underscore).
110
+ // Confirm at least one is underscore-prefixed (the TS convention).
111
+ const words = finding.message.match(/\b(\w+)\b/g);
112
+ if (!words)
113
+ return false;
114
+ // The binding name must start with underscore and have at least one more char
115
+ return words.some((word) => /^_\w+$/.test(word));
116
+ },
117
+ suppressionReason: 'TypeScript _prefix convention for intentionally unused bindings',
118
+ },
119
+ // T021: Exhaustive Switch
120
+ {
121
+ id: 'exhaustive-switch',
122
+ name: 'Exhaustive Switch',
123
+ messagePattern: /missing.*case|unhandled.*case|default.*unreachable/i,
124
+ evidenceValidator(finding, diffContent) {
125
+ const fileSection = extractFileDiffSection(finding, diffContent);
126
+ if (!fileSection)
127
+ return false;
128
+ // Scan near finding line for assertNever( or exhaustive throw
129
+ const nearbyLines = extractLinesNearFinding(fileSection, finding.line, 8);
130
+ const nearbyText = nearbyLines.join('\n');
131
+ const hasAssertNever = /assertNever\s*\(/.test(nearbyText);
132
+ const hasExhaustiveThrow = /throw\s+new\s+\w*[Ee]rror\s*\(\s*['"`].*(?:exhaustive|unreachable|unexpected)/i.test(nearbyText);
133
+ return hasAssertNever || hasExhaustiveThrow;
134
+ },
135
+ suppressionReason: 'Exhaustive switch with assertNever/throw — all cases handled at compile time',
136
+ },
137
+ ];
138
+ // =============================================================================
139
+ // Public API
140
+ // =============================================================================
141
+ /**
142
+ * Evaluate findings against the closed matcher table.
143
+ * Default-deny: only exact matches with validated evidence are suppressed.
144
+ *
145
+ * @param findings - Findings that passed Stage 1 semantic validation
146
+ * @param diffContent - Raw diff content for evidence validation
147
+ * @returns Summary with suppressed/passed findings and diagnostic details
148
+ */
149
+ export function filterFrameworkConventionFindings(findings, diffContent) {
150
+ const results = [];
151
+ let suppressed = 0;
152
+ for (const finding of findings) {
153
+ let matched = false;
154
+ for (const matcher of FRAMEWORK_MATCHERS) {
155
+ // Step 1: Does the message pattern match?
156
+ if (!matcher.messagePattern.test(finding.message))
157
+ continue;
158
+ // Step 2: Does structural evidence confirm the pattern?
159
+ if (matcher.evidenceValidator(finding, diffContent)) {
160
+ results.push({
161
+ finding,
162
+ suppressed: true,
163
+ matcherId: matcher.id,
164
+ reason: matcher.suppressionReason,
165
+ });
166
+ suppressed++;
167
+ matched = true;
168
+ console.log(`[router] [framework-filter] Suppressed: ${matcher.id} — ${finding.file}:${finding.line ?? '?'} — ${matcher.suppressionReason}`);
169
+ break; // First matching matcher wins
170
+ }
171
+ }
172
+ if (!matched) {
173
+ results.push({ finding, suppressed: false });
174
+ }
175
+ }
176
+ return {
177
+ total: findings.length,
178
+ suppressed,
179
+ passed: findings.length - suppressed,
180
+ results,
181
+ };
182
+ }
183
+ /**
184
+ * Get the list of valid findings (non-suppressed) from a filter summary.
185
+ */
186
+ export function getValidFindings(summary) {
187
+ return summary.results.filter((r) => !r.suppressed).map((r) => r.finding);
188
+ }
189
+ //# sourceMappingURL=framework-pattern-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-pattern-filter.js","sourceRoot":"","sources":["../../src/report/framework-pattern-filter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddessentials/odd-ai-reviewers",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "AI-powered code review CLI - run locally or in CI/CD pipelines",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",