auditor-lambda 0.2.14 → 0.2.15
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isNodeModulesOrGit, isBuildOutput, isVendorPath, isBinaryArtifact, isLicensePath, isLockfilePath, isLogPath, isDocPath, isAuditArtifactPath, isGeneratedInstallArtifactPath, normalizeExtractorPath, } from "./pathPatterns.js";
|
|
1
|
+
import { isNodeModulesOrGit, isBuildOutput, isVendorPath, isBinaryArtifact, isLicensePath, isLockfilePath, isLogPath, isDocPath, isAuditArtifactPath, isGeneratedInstallArtifactPath, isExamplesOrFixturesPath, normalizeExtractorPath, } from "./pathPatterns.js";
|
|
2
2
|
function inferDisposition(path) {
|
|
3
3
|
const normalized = normalizeExtractorPath(path);
|
|
4
4
|
if (isNodeModulesOrGit(normalized)) {
|
|
@@ -43,6 +43,9 @@ function inferDisposition(path) {
|
|
|
43
43
|
reason: "Generated install/bootstrap artifact.",
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
+
if (isExamplesOrFixturesPath(normalized)) {
|
|
47
|
+
return { path, status: "doc_only", reason: "Examples and fixtures are support artifacts, not auditable code." };
|
|
48
|
+
}
|
|
46
49
|
return {
|
|
47
50
|
path,
|
|
48
51
|
status: "included",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export declare const EXTRACTOR_HEURISTIC_NOTE = "Heuristic path classification normalizes case and path separators, then matches conservative keyword groups; confirm unusual repo layouts manually.";
|
|
7
7
|
export declare function normalizeExtractorPath(path: string): string;
|
|
8
|
+
export declare function pathTokens(normalized: string): string[];
|
|
8
9
|
export declare function isNodeModulesOrGit(normalized: string): boolean;
|
|
9
10
|
export declare function isBuildOutput(normalized: string): boolean;
|
|
10
11
|
export declare function isVendorPath(normalized: string): boolean;
|
|
@@ -20,6 +21,7 @@ export declare function isInterfacePath(normalized: string): boolean;
|
|
|
20
21
|
export declare function isDataLayerPath(normalized: string): boolean;
|
|
21
22
|
export declare function isSecuritySensitivePath(normalized: string): boolean;
|
|
22
23
|
export declare function isConcurrencyPath(normalized: string): boolean;
|
|
24
|
+
export declare function isExamplesOrFixturesPath(normalized: string): boolean;
|
|
23
25
|
export declare function isScriptPath(normalized: string): boolean;
|
|
24
26
|
export declare function isDeploymentConfigPath(normalized: string): boolean;
|
|
25
27
|
export declare function isGeneratedPath(normalized: string): boolean;
|
|
@@ -32,11 +32,17 @@ const SECURITY_KEYWORDS = [
|
|
|
32
32
|
];
|
|
33
33
|
const CONCURRENCY_KEYWORDS = [
|
|
34
34
|
"queue",
|
|
35
|
+
"queues",
|
|
35
36
|
"worker",
|
|
37
|
+
"workers",
|
|
36
38
|
"job",
|
|
39
|
+
"jobs",
|
|
37
40
|
"cache",
|
|
41
|
+
"caches",
|
|
38
42
|
"retry",
|
|
43
|
+
"retries",
|
|
39
44
|
"lock",
|
|
45
|
+
"locks",
|
|
40
46
|
];
|
|
41
47
|
const SCRIPT_KEYWORDS = ["script"];
|
|
42
48
|
const DEPLOYMENT_KEYWORDS = [
|
|
@@ -75,7 +81,7 @@ function baseName(normalized) {
|
|
|
75
81
|
const segments = splitSegments(normalized);
|
|
76
82
|
return segments.at(-1) ?? normalized;
|
|
77
83
|
}
|
|
78
|
-
function pathTokens(normalized) {
|
|
84
|
+
export function pathTokens(normalized) {
|
|
79
85
|
return normalized.split(/[^a-z0-9]+/).filter(Boolean);
|
|
80
86
|
}
|
|
81
87
|
function hasToken(normalized, values) {
|
|
@@ -131,7 +137,10 @@ export function isSecuritySensitivePath(normalized) {
|
|
|
131
137
|
return includesAny(normalized, SECURITY_KEYWORDS);
|
|
132
138
|
}
|
|
133
139
|
export function isConcurrencyPath(normalized) {
|
|
134
|
-
return
|
|
140
|
+
return hasToken(normalized, CONCURRENCY_KEYWORDS);
|
|
141
|
+
}
|
|
142
|
+
export function isExamplesOrFixturesPath(normalized) {
|
|
143
|
+
return hasSegment(normalized, "examples") || hasSegment(normalized, "fixtures");
|
|
135
144
|
}
|
|
136
145
|
export function isScriptPath(normalized) {
|
|
137
146
|
return (includesAny(normalized, SCRIPT_KEYWORDS) ||
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { bucketFile } from "../extractors/bucketing.js";
|
|
2
2
|
import { isAuditExcludedStatus } from "../extractors/disposition.js";
|
|
3
|
+
import { pathTokens, normalizeExtractorPath } from "../extractors/pathPatterns.js";
|
|
3
4
|
const LENS_MAP = {
|
|
4
5
|
runtime: ["correctness", "maintainability", "tests"],
|
|
5
6
|
interface: ["correctness", "security", "reliability", "tests"],
|
|
@@ -50,13 +51,20 @@ function inferUnitId(path, kind) {
|
|
|
50
51
|
if ((parts[0] === "tests" || parts[0] === "test") && parts.length >= 2) {
|
|
51
52
|
return `tests-${parts[1]}`.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
52
53
|
}
|
|
53
|
-
if (parts.length >=
|
|
54
|
+
if (parts.length >= 3) {
|
|
54
55
|
return `${parts[0]}-${parts[1]}`.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
55
56
|
}
|
|
56
|
-
if (
|
|
57
|
+
if (parts.length === 2) {
|
|
58
|
+
return parts[0].replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
59
|
+
}
|
|
60
|
+
if (normalized.endsWith(".json") ||
|
|
61
|
+
normalized.endsWith(".yaml") ||
|
|
57
62
|
normalized.endsWith(".yml") ||
|
|
58
|
-
normalized.endsWith(".
|
|
59
|
-
|
|
63
|
+
normalized.endsWith(".toml") ||
|
|
64
|
+
normalized.endsWith(".sh") ||
|
|
65
|
+
normalized.includes("docker") ||
|
|
66
|
+
normalized.startsWith(".")) {
|
|
67
|
+
return "root-config";
|
|
60
68
|
}
|
|
61
69
|
return `${kind}-${path.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
|
|
62
70
|
}
|
|
@@ -75,6 +83,16 @@ function sortLenses(lenses) {
|
|
|
75
83
|
const set = new Set(lenses);
|
|
76
84
|
return LENS_ORDER.filter((lens) => set.has(lens));
|
|
77
85
|
}
|
|
86
|
+
function applyExtensionLensGuards(path, lenses) {
|
|
87
|
+
const n = path.toLowerCase();
|
|
88
|
+
if (n.endsWith(".schema.json") || n.endsWith(".schema.ts")) {
|
|
89
|
+
return lenses.filter((l) => l === "data_integrity");
|
|
90
|
+
}
|
|
91
|
+
if (n.endsWith(".json") || n.endsWith(".yaml") || n.endsWith(".yml")) {
|
|
92
|
+
return lenses.filter((l) => l !== "tests" && l !== "performance");
|
|
93
|
+
}
|
|
94
|
+
return lenses;
|
|
95
|
+
}
|
|
78
96
|
export function deriveRequiredLensesForPath(path) {
|
|
79
97
|
const assignment = bucketFile(path);
|
|
80
98
|
const required = new Set();
|
|
@@ -83,29 +101,25 @@ export function deriveRequiredLensesForPath(path) {
|
|
|
83
101
|
required.add(lens);
|
|
84
102
|
}
|
|
85
103
|
}
|
|
86
|
-
return sortLenses(required);
|
|
104
|
+
return applyExtensionLensGuards(path, sortLenses(required));
|
|
87
105
|
}
|
|
88
106
|
function inferCriticalFlows(files, requiredLenses) {
|
|
89
107
|
const flows = new Set();
|
|
90
|
-
const
|
|
91
|
-
if (
|
|
92
|
-
combined.includes("session") ||
|
|
93
|
-
combined.includes("token")) {
|
|
108
|
+
const tokens = new Set(files.flatMap((f) => pathTokens(normalizeExtractorPath(f))));
|
|
109
|
+
if (tokens.has("auth") || tokens.has("session") || tokens.has("token")) {
|
|
94
110
|
flows.add("auth-session");
|
|
95
111
|
}
|
|
96
|
-
if (
|
|
97
|
-
combined.includes("invoice") ||
|
|
98
|
-
combined.includes("payment")) {
|
|
112
|
+
if (tokens.has("billing") || tokens.has("invoice") || tokens.has("payment")) {
|
|
99
113
|
flows.add("billing-payment");
|
|
100
114
|
}
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
if (tokens.has("queue") ||
|
|
116
|
+
tokens.has("worker") ||
|
|
117
|
+
tokens.has("job") ||
|
|
104
118
|
requiredLenses.includes("reliability")) {
|
|
105
119
|
flows.add("async-processing");
|
|
106
120
|
}
|
|
107
|
-
if (
|
|
108
|
-
|
|
121
|
+
if (tokens.has("deploy") ||
|
|
122
|
+
tokens.has("docker") ||
|
|
109
123
|
requiredLenses.includes("config_deployment")) {
|
|
110
124
|
flows.add("deployment-config");
|
|
111
125
|
}
|
|
@@ -26,9 +26,11 @@ export function renderWorkerPrompt(task) {
|
|
|
26
26
|
" If the task includes file_line_counts, use those values for file_coverage.total_lines.",
|
|
27
27
|
" total_lines must match the file's current total line count.",
|
|
28
28
|
" Each finding must include:",
|
|
29
|
-
" id, title, category, severity, confidence, lens, summary
|
|
30
|
-
"
|
|
29
|
+
" id, title, category, severity, confidence, lens, summary",
|
|
30
|
+
" affected_files: [{path, line_start?, line_end?, symbol?}] — path is repo-relative, NOT a plain string",
|
|
31
|
+
" evidence: array of plain strings only, at least one excerpt or line reference from the file you read",
|
|
31
32
|
" Example evidence entry: src/foo.ts:42 - variable overwritten before use",
|
|
33
|
+
" Example affected_files entry: {\"path\": \"src/foo.ts\", \"line_start\": 42, \"line_end\": 55, \"symbol\": \"myFunction\"}",
|
|
32
34
|
" Optional finding fields: impact, likelihood, reproduction, systemic, related_findings",
|
|
33
35
|
" Low-priority tasks still require a real review. Use findings: [] only when you genuinely found nothing notable.",
|
|
34
36
|
task.timeout_ms
|