@oddessentials/odd-ai-reviewers 1.10.0 → 1.11.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/dist/agents/control_flow/types.d.ts +1 -1
- package/dist/agents/control_flow/types.js +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/benchmark/adapter.d.ts +4 -0
- package/dist/benchmark/adapter.d.ts.map +1 -1
- package/dist/benchmark/adapter.js +47 -17
- package/dist/benchmark/adapter.js.map +1 -1
- package/dist/cli/commands/local-review.d.ts.map +1 -1
- package/dist/cli/commands/local-review.js +9 -4
- package/dist/cli/commands/local-review.js.map +1 -1
- package/dist/phases/report.d.ts +15 -0
- package/dist/phases/report.d.ts.map +1 -1
- package/dist/phases/report.js +37 -4
- package/dist/phases/report.js.map +1 -1
- package/dist/prompts/shared-conventions.generated.d.ts +3 -3
- package/dist/prompts/shared-conventions.generated.d.ts.map +1 -1
- package/dist/prompts/shared-conventions.generated.js +3 -3
- package/dist/prompts/shared-conventions.generated.js.map +1 -1
- package/dist/report/finding-validator.d.ts +2 -1
- package/dist/report/finding-validator.d.ts.map +1 -1
- package/dist/report/finding-validator.js +93 -1
- package/dist/report/finding-validator.js.map +1 -1
- package/dist/report/framework-pattern-filter.d.ts +1 -1
- package/dist/report/framework-pattern-filter.d.ts.map +1 -1
- package/dist/report/framework-pattern-filter.js +357 -14
- package/dist/report/framework-pattern-filter.js.map +1 -1
- package/dist/security-logger.d.ts +1 -1
- package/dist/security-logger.js +1 -1
- package/package.json +6 -6
- package/dist/__tests__/hermetic-setup.d.ts +0 -55
- package/dist/__tests__/hermetic-setup.d.ts.map +0 -1
- package/dist/__tests__/hermetic-setup.js +0 -62
- package/dist/__tests__/hermetic-setup.js.map +0 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* using a closed, default-deny matcher table. Runs in Stage 1 validation
|
|
6
6
|
* (after self-contradiction filter, before Stage 2 diff-bound validation).
|
|
7
7
|
*
|
|
8
|
-
* The matcher table is CLOSED: only these
|
|
8
|
+
* The matcher table is CLOSED: only these 9 matchers exist.
|
|
9
9
|
* Adding a new matcher requires a spec amendment.
|
|
10
10
|
*/
|
|
11
11
|
// =============================================================================
|
|
@@ -67,14 +67,14 @@ function extractLinesNearFinding(diffSection, findingLine, windowSize = 10) {
|
|
|
67
67
|
}
|
|
68
68
|
// =============================================================================
|
|
69
69
|
// Closed Matcher Table — DEFAULT DENY
|
|
70
|
-
// Only these
|
|
70
|
+
// Only these 9 matchers. No additions without spec change.
|
|
71
71
|
// =============================================================================
|
|
72
72
|
const FRAMEWORK_MATCHERS = [
|
|
73
73
|
// T019: Express Error Middleware
|
|
74
74
|
{
|
|
75
75
|
id: 'express-error-mw',
|
|
76
76
|
name: 'Express Error Middleware',
|
|
77
|
-
messagePattern: /unused.*param/i,
|
|
77
|
+
messagePattern: /unused.*param|declared\s+but\s+never\s+referenced|dead\s+code.*never\s+called|parameter\s+not\s+referenced/i,
|
|
78
78
|
evidenceValidator(finding, diffContent) {
|
|
79
79
|
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
80
80
|
if (!fileSection)
|
|
@@ -134,11 +134,11 @@ const FRAMEWORK_MATCHERS = [
|
|
|
134
134
|
},
|
|
135
135
|
suppressionReason: 'Exhaustive switch with assertNever/throw — all cases handled at compile time',
|
|
136
136
|
},
|
|
137
|
-
// T022: React Query
|
|
137
|
+
// T022: React Query Advisory (dedup, error handling, data fetching concerns)
|
|
138
138
|
{
|
|
139
139
|
id: 'react-query-dedup',
|
|
140
|
-
name: 'React Query
|
|
141
|
-
messagePattern: /duplicate|double.?fetch|redundant.*query|multiple.*useQuery/i,
|
|
140
|
+
name: 'React Query Advisory',
|
|
141
|
+
messagePattern: /duplicate|double.?fetch|redundant.*query|multiple.*useQuery|(?:verify|ensure|validate).*(?:endpoint|api|fetch).*(?:return|format|response|error|handle)|missing.*error.*handling.*(?:fetch|query|useQuery)|error.?handling.*(?:useQuery|useSWR)/i,
|
|
142
142
|
evidenceValidator(finding, diffContent) {
|
|
143
143
|
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
144
144
|
if (!fileSection)
|
|
@@ -159,15 +159,69 @@ const FRAMEWORK_MATCHERS = [
|
|
|
159
159
|
if (/api\s*call|http\s*request|\bfetch\s*\(/.test(finding.message.toLowerCase())) {
|
|
160
160
|
return false;
|
|
161
161
|
}
|
|
162
|
+
// Evidence 4: When the finding is about missing error handling, require BOTH:
|
|
163
|
+
// (a) error/isError is destructured from the hook result, AND
|
|
164
|
+
// (b) the destructured binding is used in a conditional branch on error state
|
|
165
|
+
// (if-check, short-circuit, ternary). Property access alone (error?.message)
|
|
166
|
+
// is NOT sufficient — logging or rendering a field without branching does
|
|
167
|
+
// not prove the component handles the error for the user.
|
|
168
|
+
const isErrorHandlingFinding = /missing.*error|error.*handling/i.test(finding.message);
|
|
169
|
+
if (isErrorHandlingFinding) {
|
|
170
|
+
// Step (a): error/isError must appear in a destructuring pattern.
|
|
171
|
+
// Extract the actual binding name (handles aliases like { error: queryError }).
|
|
172
|
+
const errorBindings = [];
|
|
173
|
+
// Match shorthand `{ ..., error, ... }` or `{ ..., isError, ... }`
|
|
174
|
+
// and aliased `{ ..., error: NAME, ... }` or `{ ..., isError: NAME, ... }`
|
|
175
|
+
const destructuringBlock = nearbyText.match(/\{\s*([^}]*\b(?:error|isError)\b[^}]*)\}/);
|
|
176
|
+
if (!destructuringBlock?.[1])
|
|
177
|
+
return false;
|
|
178
|
+
const blockContent = destructuringBlock[1];
|
|
179
|
+
// Check for alias pattern: `error: someAlias` or `isError: someAlias`
|
|
180
|
+
const aliasMatches = blockContent.matchAll(/\b(?:error|isError)\s*:\s*(\w+)/g);
|
|
181
|
+
for (const m of aliasMatches) {
|
|
182
|
+
if (m[1])
|
|
183
|
+
errorBindings.push(m[1]);
|
|
184
|
+
}
|
|
185
|
+
// Check for shorthand: `error` or `isError` without `: alias`
|
|
186
|
+
if (/\berror\b(?!\s*:)/.test(blockContent)) {
|
|
187
|
+
errorBindings.push('error');
|
|
188
|
+
}
|
|
189
|
+
if (/\bisError\b(?!\s*:)/.test(blockContent)) {
|
|
190
|
+
errorBindings.push('isError');
|
|
191
|
+
}
|
|
192
|
+
if (errorBindings.length === 0)
|
|
193
|
+
return false;
|
|
194
|
+
// Step (b): At least one extracted binding must appear in a conditional branch
|
|
195
|
+
// on error state: if-check, short-circuit (&&), or ternary (?).
|
|
196
|
+
// SAFETY: bindings are from \w+ match — only [a-zA-Z0-9_], no regex special chars.
|
|
197
|
+
//
|
|
198
|
+
// Fail-open patterns (not checked, finding passes through):
|
|
199
|
+
// - binding used only as callback argument
|
|
200
|
+
// - binding only logged (console.log/console.error)
|
|
201
|
+
// - property access without conditional guard (error?.message)
|
|
202
|
+
// - nested destructuring from the binding
|
|
203
|
+
const hasErrorUsage = errorBindings.some((binding) => {
|
|
204
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
205
|
+
const ifCheck = new RegExp('\\bif\\s*\\(\\s*' + binding + '\\b');
|
|
206
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
207
|
+
const shortCircuit = new RegExp('\\b' + binding + '\\s*&&');
|
|
208
|
+
// Ternary: `binding ? ... : ...` — must exclude optional chaining `binding?.`
|
|
209
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
210
|
+
const ternary = new RegExp('\\b' + binding + '\\s*\\?(?!\\.)');
|
|
211
|
+
return (ifCheck.test(nearbyText) || shortCircuit.test(nearbyText) || ternary.test(nearbyText));
|
|
212
|
+
});
|
|
213
|
+
if (!hasErrorUsage)
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
162
216
|
return true;
|
|
163
217
|
},
|
|
164
|
-
suppressionReason: 'Query library
|
|
218
|
+
suppressionReason: 'Query library handles caching, dedup, and error state — advisory is redundant',
|
|
165
219
|
},
|
|
166
|
-
// T023: Promise.allSettled Order
|
|
220
|
+
// T023: Promise.allSettled Convention (Order + Error Handling)
|
|
167
221
|
{
|
|
168
222
|
id: 'promise-allsettled-order',
|
|
169
|
-
name: 'Promise.allSettled
|
|
170
|
-
messagePattern: /allSettled.*(?:order|sequence)|(?:order|sequence).*allSettled|allSettled.*results.*not.*(?:match|correspond|align)/i,
|
|
223
|
+
name: 'Promise.allSettled Convention',
|
|
224
|
+
messagePattern: /allSettled.*(?:order|sequence|reject|unhandled|error.?handling|silent)|(?:order|sequence).*allSettled|(?:unhandled|missing|silent).*(?:reject|error|exception).*(?:promise|settled)|allSettled.*results.*not.*(?:match|correspond|align)|(?:additional|need).*error.*handling.*(?:promise|fetch|request|response|processing)|verify.*(?:fetch|request).*(?:error|handling|additional|response)/i,
|
|
171
225
|
evidenceValidator(finding, diffContent) {
|
|
172
226
|
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
173
227
|
if (!fileSection)
|
|
@@ -177,13 +231,302 @@ const FRAMEWORK_MATCHERS = [
|
|
|
177
231
|
const nearbyText = nearbyLines.join('\n');
|
|
178
232
|
if (!/Promise\.allSettled\s*\(/.test(nearbyText))
|
|
179
233
|
return false;
|
|
180
|
-
// Evidence 2:
|
|
181
|
-
|
|
182
|
-
|
|
234
|
+
// Evidence 2+3: Iteration and .status must be BOUND to the allSettled result variable.
|
|
235
|
+
// Unscoped checks (any .forEach + any .status in nearbyText) allow false suppression
|
|
236
|
+
// when unrelated iteration or HTTP .status references exist nearby.
|
|
237
|
+
// Step 2a: Extract the result variable name.
|
|
238
|
+
// Primary: `const/let/var X = await Promise.allSettled(...)`
|
|
239
|
+
const allSettledVarMatch = nearbyText.match(/\b(?:const|let|var)\s+(\w+)\s*=\s*await\s+Promise\.allSettled\s*\(/);
|
|
240
|
+
let varName = allSettledVarMatch?.[1];
|
|
241
|
+
// Fallback: `.then()` chain — `Promise.allSettled(...).then((X) => ...)` or
|
|
242
|
+
// `.then(X => ...)` or `.then(function(X) { ... })`.
|
|
243
|
+
// NOTE: This is a bounded heuristic over the ±10-line diff window, not a
|
|
244
|
+
// structurally correct parser. The lazy [\s\S]*? relies on regex backtracking
|
|
245
|
+
// to find the closing paren of allSettled(...) when nested parens are present.
|
|
246
|
+
// This is acceptable given the small window size but is not balanced-paren parsing.
|
|
247
|
+
// Fail-open patterns (not checked):
|
|
248
|
+
// - separated await: `const p = Promise.allSettled(...); const r = await p;`
|
|
249
|
+
// - named function reference: `.then(handleResults)`
|
|
250
|
+
// - generator patterns
|
|
251
|
+
if (!varName) {
|
|
252
|
+
const thenMatch = nearbyText.match(/Promise\.allSettled\s*\([\s\S]*?\)\.then\s*\(\s*(?:function\s*\(\s*(\w+)|(\w+)\s*=>|\(\s*(\w+)\s*\)\s*=>)/);
|
|
253
|
+
varName = thenMatch?.[1] ?? thenMatch?.[2] ?? thenMatch?.[3];
|
|
254
|
+
}
|
|
255
|
+
if (!varName)
|
|
256
|
+
return false; // Cannot identify result variable — fail open
|
|
257
|
+
// Step 2b: Require iteration to reference the allSettled result variable.
|
|
258
|
+
// SAFETY: varName is from \w+ match — only [a-zA-Z0-9_], no regex special chars.
|
|
259
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
260
|
+
const iterationPattern = new RegExp('\\b' +
|
|
261
|
+
varName +
|
|
262
|
+
'\\s*\\.\\s*forEach\\s*\\(' +
|
|
263
|
+
'|for\\s*\\([^)]*\\s+of\\s+' +
|
|
264
|
+
varName +
|
|
265
|
+
'\\b' +
|
|
266
|
+
'|\\b' +
|
|
267
|
+
varName +
|
|
268
|
+
'\\s*\\[');
|
|
269
|
+
if (!iterationPattern.test(nearbyText))
|
|
270
|
+
return false;
|
|
271
|
+
// Step 2c: .status check must appear on the iteration callback parameter,
|
|
272
|
+
// not on an unrelated variable. Extract the callback/loop variable name
|
|
273
|
+
// and require PARAM.status in nearbyText.
|
|
274
|
+
let hasStatusCheck = false;
|
|
275
|
+
// Pattern A: VARNAME.forEach((PARAM, ...) => { ... PARAM.status ... })
|
|
276
|
+
const forEachParamMatch = nearbyText.match(
|
|
277
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
278
|
+
new RegExp('\\b' + varName + '\\s*\\.\\s*forEach\\s*\\(\\s*(?:\\(\\s*)?(\\w+)'));
|
|
279
|
+
if (forEachParamMatch?.[1]) {
|
|
280
|
+
const cbParam = forEachParamMatch[1];
|
|
281
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
282
|
+
hasStatusCheck = new RegExp('\\b' + cbParam + '\\.status\\b').test(nearbyText);
|
|
283
|
+
}
|
|
284
|
+
// Pattern B: for (const LOOPVAR of VARNAME) { ... LOOPVAR.status ... }
|
|
285
|
+
if (!hasStatusCheck) {
|
|
286
|
+
const forOfMatch = nearbyText.match(
|
|
287
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
288
|
+
new RegExp('for\\s*\\(\\s*(?:const|let|var)\\s+(\\w+)\\s+of\\s+' + varName + '\\b'));
|
|
289
|
+
if (forOfMatch?.[1]) {
|
|
290
|
+
const loopVar = forOfMatch[1];
|
|
291
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
292
|
+
hasStatusCheck = new RegExp('\\b' + loopVar + '\\.status\\b').test(nearbyText);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
// Pattern C: indexed access VARNAME[i].status
|
|
296
|
+
if (!hasStatusCheck) {
|
|
297
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
298
|
+
hasStatusCheck = new RegExp('\\b' + varName + '\\s*\\[\\w+\\]\\s*\\.\\s*status\\b').test(nearbyText);
|
|
299
|
+
}
|
|
300
|
+
if (!hasStatusCheck)
|
|
301
|
+
return false;
|
|
302
|
+
return true;
|
|
303
|
+
},
|
|
304
|
+
suppressionReason: 'Promise.allSettled convention — results handled per ECMAScript spec',
|
|
305
|
+
},
|
|
306
|
+
// T025: Safe Local File Read
|
|
307
|
+
{
|
|
308
|
+
id: 'safe-local-file-read',
|
|
309
|
+
name: 'Safe Local File Read',
|
|
310
|
+
messagePattern: /path.*traversal|directory.*traversal|local.*file.*read|file.*inclusion|readFileSync.*block|synchronous.*file.*read|block.*event.*loop.*(?:read|file)/i,
|
|
311
|
+
evidenceValidator(finding, diffContent) {
|
|
312
|
+
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
313
|
+
if (!fileSection)
|
|
314
|
+
return false;
|
|
315
|
+
const nearbyLines = extractLinesNearFinding(fileSection, finding.line, 10);
|
|
316
|
+
// Single-line only: check each line individually (per FR-011 scope limitation)
|
|
317
|
+
const canonicalPattern = /path\.(join|resolve)\s*\(\s*(?:__dirname|__filename|import\.meta\.(?:dirname|filename|url))\s*(?:,\s*(['"])[^'"]*\2\s*)*\)/;
|
|
318
|
+
let match = null;
|
|
319
|
+
for (const line of nearbyLines) {
|
|
320
|
+
match = canonicalPattern.exec(line);
|
|
321
|
+
if (match)
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
if (!match)
|
|
325
|
+
return false;
|
|
326
|
+
// Extract the full matched path expression for safety checks
|
|
327
|
+
const matchedExpr = match[0];
|
|
328
|
+
// B1: Reject if any string literal segment contains '..' (path traversal)
|
|
329
|
+
const stringSegments = matchedExpr.match(/(['"])[^'"]*\1/g);
|
|
330
|
+
if (stringSegments) {
|
|
331
|
+
for (const seg of stringSegments) {
|
|
332
|
+
const content = seg.slice(1, -1);
|
|
333
|
+
if (content.includes('..'))
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// B2: Reject if any string literal segment starts with '/' or drive letter (absolute path)
|
|
338
|
+
if (stringSegments) {
|
|
339
|
+
for (const seg of stringSegments) {
|
|
340
|
+
const content = seg.slice(1, -1);
|
|
341
|
+
if (content.startsWith('/'))
|
|
342
|
+
return false;
|
|
343
|
+
if (/^[a-zA-Z]:/.test(content))
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// B3: Performance findings (sync I/O blocking) require module-top-level scope.
|
|
348
|
+
// Path safety only proves the read is traversal-safe, NOT that blocking I/O
|
|
349
|
+
// is acceptable. Sync reads inside functions, callbacks, or request handlers
|
|
350
|
+
// are legitimate performance concerns that must not be suppressed.
|
|
351
|
+
//
|
|
352
|
+
// Criteria: a finding is "performance-typed" if its message matches the sync-read
|
|
353
|
+
// patterns but NOT the security patterns (traversal/inclusion). For such findings:
|
|
354
|
+
// 1. The readFileSync call must be a direct module-scope declaration (const/let/var
|
|
355
|
+
// at ≤2 leading spaces — not nested inside any function, arrow, or callback body)
|
|
356
|
+
// 2. No request-handler or event-listener context within ±10 lines
|
|
357
|
+
const isPerformanceFinding = /readFileSync.*block|synchronous.*file.*read|block.*event.*loop/i.test(finding.message) &&
|
|
358
|
+
!/path.*traversal|directory.*traversal|file.*inclusion/i.test(finding.message);
|
|
359
|
+
if (isPerformanceFinding) {
|
|
360
|
+
// Require that at least one nearby line is a module-top-level declaration
|
|
361
|
+
// (starts with at most 2 spaces of indentation followed by const/let/var/export).
|
|
362
|
+
// Lines indented ≥4 spaces are inside a function body (not top-level).
|
|
363
|
+
const hasTopLevelDecl = nearbyLines.some((l) => /^\s{0,2}(?:export\s+)?(?:const|let|var)\s+\w+\s*=/.test(l));
|
|
364
|
+
if (!hasTopLevelDecl)
|
|
365
|
+
return false;
|
|
366
|
+
// Reject if a request-handler, middleware, or event-listener pattern appears
|
|
367
|
+
// anywhere within the ±10-line window (nearbyText).
|
|
368
|
+
const nearbyText = nearbyLines.join('\n');
|
|
369
|
+
if (/\b(?:app|router)\s*\.\s*(?:get|post|put|patch|delete|use|all)\s*\(/.test(nearbyText) ||
|
|
370
|
+
/\.on\s*\(\s*['"]/.test(nearbyText) ||
|
|
371
|
+
/addEventListener\s*\(/.test(nearbyText) ||
|
|
372
|
+
/(?:req|request)\s*,\s*(?:res|response)\s*[,)]/.test(nearbyText))
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
return true;
|
|
376
|
+
},
|
|
377
|
+
suppressionReason: 'Safe local file read — path.join/resolve with __dirname and string literals only',
|
|
378
|
+
},
|
|
379
|
+
// T026: Exhaustive Type-Narrowed Switch
|
|
380
|
+
{
|
|
381
|
+
id: 'exhaustive-type-narrowed-switch',
|
|
382
|
+
name: 'Exhaustive Type-Narrowed Switch',
|
|
383
|
+
messagePattern: /missing.*(?:case|default)|no.*default|add.*default|non-?exhaustive/i,
|
|
384
|
+
evidenceValidator(finding, diffContent) {
|
|
385
|
+
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
386
|
+
if (!fileSection)
|
|
387
|
+
return false;
|
|
388
|
+
const nearbyLines = extractLinesNearFinding(fileSection, finding.line, 10);
|
|
389
|
+
const nearbyText = nearbyLines.join('\n');
|
|
390
|
+
// Evidence 1: switch target must be a simple identifier (not a property access).
|
|
391
|
+
// Property-access targets like switch(node.type) or switch(event.kind) cannot
|
|
392
|
+
// have their type proven from a local annotation — fail open (do not suppress).
|
|
393
|
+
const switchTargetMatch = nearbyText.match(/\bswitch\s*\((\w+)\)/);
|
|
394
|
+
if (!switchTargetMatch)
|
|
395
|
+
return false;
|
|
396
|
+
const varName = switchTargetMatch[1];
|
|
397
|
+
// Safety constraint: reject if the switch target variable is typed as string or number.
|
|
398
|
+
// A string/number-typed switch is inherently open-domain — not exhaustive.
|
|
399
|
+
// SAFETY: varName is from \w+ match — only [a-zA-Z0-9_], no regex special chars.
|
|
400
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
401
|
+
const varPrimitivePattern = new RegExp('\\b' + varName + '\\s*:\\s*(?:string|number)\\b');
|
|
402
|
+
if (varPrimitivePattern.test(nearbyText))
|
|
403
|
+
return false;
|
|
404
|
+
// Evidence 2: the switch variable must have a named type annotation (PascalCase),
|
|
405
|
+
// and that exact named type must be declared as a string-literal union in the
|
|
406
|
+
// visible diff/file section. Inferred types (no annotation) and imported types
|
|
407
|
+
// (not defined in the diff) MUST NOT trigger suppression — fail open.
|
|
408
|
+
//
|
|
409
|
+
// Step 2a: extract the type name from the variable's annotation in ±10 lines.
|
|
410
|
+
// e.g., `function f(theme: Theme)` → typeName = 'Theme'
|
|
411
|
+
// SAFETY: varName is from \w+ match — only [a-zA-Z0-9_], no regex special chars.
|
|
412
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
413
|
+
const varTypePattern = new RegExp('\\b' + varName + '\\s*:\\s*([A-Z][\\w]*)');
|
|
414
|
+
const typeNameMatch = nearbyText.match(varTypePattern);
|
|
415
|
+
if (!typeNameMatch?.[1])
|
|
416
|
+
return false; // no visible annotation → cannot prove union
|
|
417
|
+
const typeName = typeNameMatch[1];
|
|
418
|
+
// Step 2b: verify that typeName is defined as a string-literal union in the file
|
|
419
|
+
// diff section. Only string-literal unions declared in the visible diff count.
|
|
420
|
+
// e.g., `type Theme = 'light' | 'dark'`
|
|
421
|
+
// SAFETY: typeName is from [A-Z][\w]* match — only [a-zA-Z0-9_], no regex special chars.
|
|
422
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
423
|
+
const unionDeclarationPattern = new RegExp('\\btype\\s+' + typeName + '\\s*=\\s*((?:[\'"][^\'"]+[\'"]\\s*\\|?\\s*)+)');
|
|
424
|
+
const unionMatch = fileSection.match(unionDeclarationPattern);
|
|
425
|
+
if (!unionMatch?.[1])
|
|
426
|
+
return false;
|
|
427
|
+
// Step 2c: verify every union member VALUE has a corresponding case branch.
|
|
428
|
+
// Uses set-membership (not count comparison) to prevent duplicate case values
|
|
429
|
+
// from inflating the count. e.g., case 'light', case 'light' = 1 unique value,
|
|
430
|
+
// not 2 — so a 3-member union with a duplicate case is correctly rejected.
|
|
431
|
+
const unionMemberQuoted = unionMatch[1].match(/['"][^'"]+['"]/g) ?? [];
|
|
432
|
+
if (unionMemberQuoted.length === 0)
|
|
433
|
+
return false;
|
|
434
|
+
// Extract raw string values (without quotes) from union members
|
|
435
|
+
const unionMemberValues = unionMemberQuoted.map((m) => m.slice(1, -1));
|
|
436
|
+
// Extract raw string values from case branches (deduplicated via Set)
|
|
437
|
+
const caseBranchMatches = nearbyText.match(/\bcase\s+['"]([^'"]+)['"]\s*:/g) ?? [];
|
|
438
|
+
const caseValues = new Set(caseBranchMatches.map((m) => {
|
|
439
|
+
const val = m.match(/['"]([^'"]+)['"]/);
|
|
440
|
+
return val?.[1] ?? '';
|
|
441
|
+
}));
|
|
442
|
+
// Every union member must have a matching case branch (set membership)
|
|
443
|
+
const allMembersCovered = unionMemberValues.every((member) => caseValues.has(member));
|
|
444
|
+
if (!allMembersCovered)
|
|
445
|
+
return false;
|
|
446
|
+
return true;
|
|
447
|
+
},
|
|
448
|
+
suppressionReason: 'Exhaustive type-narrowed switch — union type with all members covered',
|
|
449
|
+
},
|
|
450
|
+
// Convention 18: Error Object XSS
|
|
451
|
+
{
|
|
452
|
+
id: 'error-object-xss',
|
|
453
|
+
name: 'Error Object XSS',
|
|
454
|
+
messagePattern: /(?:xss|inject).*(?:error|err)\b.*(?:message|\.message)|(?:error|err)\b.*(?:message|\.message).*(?:xss|inject|innerHTML|template)|(?:xss|inject).*error.*(?:directly|message)|error\s+message.*(?:xss|inject|innerHTML)/i,
|
|
455
|
+
evidenceValidator(finding, diffContent) {
|
|
456
|
+
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
457
|
+
if (!fileSection)
|
|
458
|
+
return false;
|
|
459
|
+
const nearbyLines = extractLinesNearFinding(fileSection, finding.line, 10);
|
|
460
|
+
const nearbyText = nearbyLines.join('\n');
|
|
461
|
+
// MANDATORY: catch clause visible (structural proof of error origin)
|
|
462
|
+
// No naming heuristics, no function-name matching (security-engineer mandate)
|
|
463
|
+
if (!/\bcatch\s*\(\s*\w+/.test(nearbyText))
|
|
464
|
+
return false;
|
|
465
|
+
// MANDATORY: error.message usage visible (the flagged construct)
|
|
466
|
+
if (!/\.\s*message\b/.test(nearbyText))
|
|
467
|
+
return false;
|
|
468
|
+
// REJECT: error constructed from user input or external API data.
|
|
469
|
+
// Errors built from req.body, query params, or external input can contain
|
|
470
|
+
// attacker-controlled data — suppression would hide real XSS.
|
|
471
|
+
if (/new\s+(?:\w+)?Error\s*\(\s*(?:req\.|request\.|body\.|params\.|query\.|input\.|data\.|payload\.)/.test(nearbyText))
|
|
472
|
+
return false;
|
|
473
|
+
// REJECT: direct DOM manipulation (browser-side sinks)
|
|
474
|
+
if (/\.innerHTML\s*=|\.outerHTML\s*=|document\.write\s*\(|insertAdjacentHTML\s*\(/.test(nearbyText))
|
|
475
|
+
return false;
|
|
476
|
+
// REJECT: React dangerouslySetInnerHTML (always renders raw HTML)
|
|
477
|
+
if (/dangerouslySetInnerHTML/.test(nearbyText))
|
|
478
|
+
return false;
|
|
479
|
+
// REJECT: server-side HTTP response sinks that render error.message as HTML.
|
|
480
|
+
// Only triggers when BOTH a response output call AND .message appear within
|
|
481
|
+
// the same ±10-line window (nearbyText), proving the error data flows into
|
|
482
|
+
// the response. Plain-text responses (res.send(err.message) without HTML
|
|
483
|
+
// markup) are excluded by requiring an HTML indicator (< or template literal).
|
|
484
|
+
if (/\bres\s*\.\s*(?:send|write|end)\s*\(/.test(nearbyText)) {
|
|
485
|
+
// Check for HTML evidence: template literal with tags, or string with '<'
|
|
486
|
+
const hasHtmlInResponse = /\bres\s*\.\s*(?:send|write|end)\s*\(\s*`[^`]*</.test(nearbyText) ||
|
|
487
|
+
/\bres\s*\.\s*(?:send|write|end)\s*\([^)]*['"][^'"]*</.test(nearbyText) ||
|
|
488
|
+
/\bres\s*\.\s*(?:send|write|end)\s*\([^)]*\+[^)]*['"]?\s*</.test(nearbyText);
|
|
489
|
+
if (hasHtmlInResponse)
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
// REJECT: template engine render calls (always produce HTML output)
|
|
493
|
+
if (/\bres\s*\.\s*render\s*\(/.test(nearbyText) ||
|
|
494
|
+
/\b(?:ejs|pug|handlebars|hbs|nunjucks|mustache)\s*[.(]/.test(nearbyText))
|
|
495
|
+
return false;
|
|
496
|
+
return true;
|
|
497
|
+
},
|
|
498
|
+
suppressionReason: 'Error from catch clause — error.message is runtime exception, not user input',
|
|
499
|
+
},
|
|
500
|
+
// Convention 19: Thin Wrapper Stdlib
|
|
501
|
+
{
|
|
502
|
+
id: 'thin-wrapper-stdlib',
|
|
503
|
+
name: 'Thin Wrapper Stdlib',
|
|
504
|
+
messagePattern: /(?:missing|add|no).*try.?catch|(?:could|may|might).*throw|unhandled.*(?:error|exception).*(?:JSON\.parse|parseInt|parseFloat|new\s+URL|Buffer\.from|decodeURI)|directly.*(?:return|call).*(?:JSON\.parse|parseInt|parseFloat)/i,
|
|
505
|
+
evidenceValidator(finding, diffContent) {
|
|
506
|
+
const fileSection = extractFileDiffSection(finding, diffContent);
|
|
507
|
+
if (!fileSection)
|
|
508
|
+
return false;
|
|
509
|
+
const nearbyLines = extractLinesNearFinding(fileSection, finding.line, 5);
|
|
510
|
+
const nearbyText = nearbyLines.join('\n');
|
|
511
|
+
// Evidence 1: WHITELISTED stdlib call present (no open patterns)
|
|
512
|
+
const SAFE_STDLIB = /\b(?:JSON\.parse|JSON\.stringify|parseInt|parseFloat|Number\(|new\s+URL|Buffer\.from|decodeURIComponent|decodeURI|atob|btoa)\s*\(/;
|
|
513
|
+
if (!SAFE_STDLIB.test(nearbyText))
|
|
514
|
+
return false;
|
|
515
|
+
// Evidence 2: thin wrapper structure (return + stdlib)
|
|
516
|
+
if (!/\breturn\s+/.test(nearbyText))
|
|
517
|
+
return false;
|
|
518
|
+
// REJECT: I/O operations (not pure stdlib delegation)
|
|
519
|
+
if (/\b(?:fs\.|fetch\s*\(|await\s|\.readFile|\.writeFile|database|\.query\s*\()/.test(nearbyText))
|
|
520
|
+
return false;
|
|
521
|
+
// REJECT: conditional logic (not a thin wrapper)
|
|
522
|
+
if (/\b(?:if\s*\(|else\b|switch\s*\()/.test(nearbyText))
|
|
523
|
+
return false;
|
|
524
|
+
// REJECT: request handler context (caller responsibility matters here)
|
|
525
|
+
if (/\b(?:req\.|request\.|res\.|response\.|app\.\w+\(|router\.\w+\()/.test(nearbyText))
|
|
183
526
|
return false;
|
|
184
527
|
return true;
|
|
185
528
|
},
|
|
186
|
-
suppressionReason: '
|
|
529
|
+
suppressionReason: 'Thin wrapper around stdlib function — try-catch is caller responsibility',
|
|
187
530
|
},
|
|
188
531
|
];
|
|
189
532
|
// =============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-pattern-filter.js","sourceRoot":"","sources":["../../src/report/framework-pattern-filter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"framework-pattern-filter.js","sourceRoot":"","sources":["../../src/report/framework-pattern-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Consistent structured format across all events
|
|
11
11
|
*
|
|
12
12
|
* @see FR-021, FR-022, FR-023, FR-024
|
|
13
|
-
* @see specs/006-quality-enforcement/contracts/security-event.ts
|
|
13
|
+
* @see specs/archive/006-quality-enforcement/contracts/security-event.ts
|
|
14
14
|
*/
|
|
15
15
|
import { z } from 'zod';
|
|
16
16
|
/**
|
package/dist/security-logger.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Consistent structured format across all events
|
|
11
11
|
*
|
|
12
12
|
* @see FR-021, FR-022, FR-023, FR-024
|
|
13
|
-
* @see specs/006-quality-enforcement/contracts/security-event.ts
|
|
13
|
+
* @see specs/archive/006-quality-enforcement/contracts/security-event.ts
|
|
14
14
|
*/
|
|
15
15
|
import { createHash } from 'crypto';
|
|
16
16
|
import { z } from 'zod';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oddessentials/odd-ai-reviewers",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.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",
|
|
@@ -32,19 +32,19 @@
|
|
|
32
32
|
"homepage": "https://github.com/oddessentials/odd-ai-reviewers#readme",
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@actions/cache": "5.0.5",
|
|
35
|
-
"@anthropic-ai/sdk": "0.
|
|
35
|
+
"@anthropic-ai/sdk": "0.78.0",
|
|
36
36
|
"@octokit/rest": "^22.0.1",
|
|
37
37
|
"commander": "^14.0.3",
|
|
38
38
|
"minimatch": "^10.2.4",
|
|
39
|
-
"openai": "^6.
|
|
39
|
+
"openai": "^6.29.0",
|
|
40
40
|
"typescript": "5.9.3",
|
|
41
41
|
"yaml": "^2.8.2",
|
|
42
42
|
"zod": "^4.3.6"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@types/node": "25.
|
|
46
|
-
"@vitest/coverage-v8": "4.0
|
|
47
|
-
"vitest": "^4.0
|
|
45
|
+
"@types/node": "25.5.0",
|
|
46
|
+
"@vitest/coverage-v8": "4.1.0",
|
|
47
|
+
"vitest": "^4.1.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=22.0.0"
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hermetic Test Setup Utilities
|
|
3
|
-
*
|
|
4
|
-
* Shared test infrastructure for deterministic, isolated tests.
|
|
5
|
-
* Located in __tests__/ directory which is classified as test code
|
|
6
|
-
* by dependency-cruiser, allowing legitimate vitest imports.
|
|
7
|
-
*
|
|
8
|
-
* Provides:
|
|
9
|
-
* - Frozen time (no wall-clock dependencies)
|
|
10
|
-
* - Deterministic teardown
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* import { describe, it, beforeEach, afterEach } from 'vitest';
|
|
15
|
-
* import {
|
|
16
|
-
* FROZEN_TIMESTAMP,
|
|
17
|
-
* setupHermeticTest,
|
|
18
|
-
* teardownHermeticTest,
|
|
19
|
-
* } from '../hermetic-setup.js';
|
|
20
|
-
*
|
|
21
|
-
* describe('MyFeature', () => {
|
|
22
|
-
* beforeEach(() => setupHermeticTest());
|
|
23
|
-
* afterEach(() => teardownHermeticTest());
|
|
24
|
-
*
|
|
25
|
-
* it('works with frozen time', () => {
|
|
26
|
-
* expect(new Date().toISOString()).toBe(FROZEN_TIMESTAMP);
|
|
27
|
-
* });
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
/**
|
|
32
|
-
* Frozen test timestamp - use consistently across all hermetic tests
|
|
33
|
-
*/
|
|
34
|
-
export declare const FROZEN_TIMESTAMP = "2026-01-29T00:00:00.000Z";
|
|
35
|
-
export declare const FROZEN_DATE: Date;
|
|
36
|
-
/**
|
|
37
|
-
* Setup hermetic test environment
|
|
38
|
-
*
|
|
39
|
-
* Configures:
|
|
40
|
-
* - Frozen system time to FROZEN_TIMESTAMP
|
|
41
|
-
*
|
|
42
|
-
* Call this in beforeEach()
|
|
43
|
-
*/
|
|
44
|
-
export declare function setupHermeticTest(): void;
|
|
45
|
-
/**
|
|
46
|
-
* Teardown hermetic test environment
|
|
47
|
-
*
|
|
48
|
-
* Restores:
|
|
49
|
-
* - Real system time
|
|
50
|
-
* - All mocks
|
|
51
|
-
*
|
|
52
|
-
* Call this in afterEach()
|
|
53
|
-
*/
|
|
54
|
-
export declare function teardownHermeticTest(): void;
|
|
55
|
-
//# sourceMappingURL=hermetic-setup.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hermetic-setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/hermetic-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH;;GAEG;AACH,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAC3D,eAAO,MAAM,WAAW,MAA6B,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hermetic Test Setup Utilities
|
|
3
|
-
*
|
|
4
|
-
* Shared test infrastructure for deterministic, isolated tests.
|
|
5
|
-
* Located in __tests__/ directory which is classified as test code
|
|
6
|
-
* by dependency-cruiser, allowing legitimate vitest imports.
|
|
7
|
-
*
|
|
8
|
-
* Provides:
|
|
9
|
-
* - Frozen time (no wall-clock dependencies)
|
|
10
|
-
* - Deterministic teardown
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* import { describe, it, beforeEach, afterEach } from 'vitest';
|
|
15
|
-
* import {
|
|
16
|
-
* FROZEN_TIMESTAMP,
|
|
17
|
-
* setupHermeticTest,
|
|
18
|
-
* teardownHermeticTest,
|
|
19
|
-
* } from '../hermetic-setup.js';
|
|
20
|
-
*
|
|
21
|
-
* describe('MyFeature', () => {
|
|
22
|
-
* beforeEach(() => setupHermeticTest());
|
|
23
|
-
* afterEach(() => teardownHermeticTest());
|
|
24
|
-
*
|
|
25
|
-
* it('works with frozen time', () => {
|
|
26
|
-
* expect(new Date().toISOString()).toBe(FROZEN_TIMESTAMP);
|
|
27
|
-
* });
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
import { vi } from 'vitest';
|
|
32
|
-
/**
|
|
33
|
-
* Frozen test timestamp - use consistently across all hermetic tests
|
|
34
|
-
*/
|
|
35
|
-
export const FROZEN_TIMESTAMP = '2026-01-29T00:00:00.000Z';
|
|
36
|
-
export const FROZEN_DATE = new Date(FROZEN_TIMESTAMP);
|
|
37
|
-
/**
|
|
38
|
-
* Setup hermetic test environment
|
|
39
|
-
*
|
|
40
|
-
* Configures:
|
|
41
|
-
* - Frozen system time to FROZEN_TIMESTAMP
|
|
42
|
-
*
|
|
43
|
-
* Call this in beforeEach()
|
|
44
|
-
*/
|
|
45
|
-
export function setupHermeticTest() {
|
|
46
|
-
vi.useFakeTimers();
|
|
47
|
-
vi.setSystemTime(FROZEN_DATE);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Teardown hermetic test environment
|
|
51
|
-
*
|
|
52
|
-
* Restores:
|
|
53
|
-
* - Real system time
|
|
54
|
-
* - All mocks
|
|
55
|
-
*
|
|
56
|
-
* Call this in afterEach()
|
|
57
|
-
*/
|
|
58
|
-
export function teardownHermeticTest() {
|
|
59
|
-
vi.useRealTimers();
|
|
60
|
-
vi.restoreAllMocks();
|
|
61
|
-
}
|
|
62
|
-
//# sourceMappingURL=hermetic-setup.js.map
|