@hongmaple0820/scale-engine 0.23.0 → 0.24.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/api/cli.js +192 -1
- package/dist/api/cli.js.map +1 -1
- package/dist/dashboard/MetricsAggregator.d.ts +38 -0
- package/dist/dashboard/MetricsAggregator.js +99 -0
- package/dist/dashboard/MetricsAggregator.js.map +1 -0
- package/dist/dashboard/index.d.ts +2 -0
- package/dist/dashboard/index.js +1 -0
- package/dist/dashboard/index.js.map +1 -1
- package/dist/dashboard/server.js +1 -1
- package/dist/dashboard/server.js.map +1 -1
- package/dist/evolution/AutoDefectCreator.d.ts +11 -2
- package/dist/evolution/AutoDefectCreator.js +46 -2
- package/dist/evolution/AutoDefectCreator.js.map +1 -1
- package/dist/evolution/EvolutionEngine.d.ts +3 -0
- package/dist/evolution/EvolutionEngine.js +18 -2
- package/dist/evolution/EvolutionEngine.js.map +1 -1
- package/dist/evolution/RuleMaturity.d.ts +39 -0
- package/dist/evolution/RuleMaturity.js +70 -0
- package/dist/evolution/RuleMaturity.js.map +1 -0
- package/dist/guardrails/ActiveRedTeam.d.ts +46 -0
- package/dist/guardrails/ActiveRedTeam.js +203 -0
- package/dist/guardrails/ActiveRedTeam.js.map +1 -0
- package/dist/guardrails/DependencyAuditor.d.ts +68 -0
- package/dist/guardrails/DependencyAuditor.js +331 -0
- package/dist/guardrails/DependencyAuditor.js.map +1 -0
- package/dist/hooks/HookGeneratorEnhanced.js +18 -18
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/output/GovernanceDashboard.d.ts +2 -0
- package/dist/output/GovernanceDashboard.js +31 -0
- package/dist/output/GovernanceDashboard.js.map +1 -1
- package/dist/routing/PromptCachePolicy.d.ts +37 -0
- package/dist/routing/PromptCachePolicy.js +97 -0
- package/dist/routing/PromptCachePolicy.js.map +1 -0
- package/dist/runtime/ModelUsageLedger.d.ts +50 -0
- package/dist/runtime/ModelUsageLedger.js +92 -0
- package/dist/runtime/ModelUsageLedger.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/workflow/autonomous/BackgroundHunter.d.ts +74 -0
- package/dist/workflow/autonomous/BackgroundHunter.js +220 -0
- package/dist/workflow/autonomous/BackgroundHunter.js.map +1 -0
- package/dist/workflow/autonomous/index.d.ts +1 -0
- package/dist/workflow/autonomous/index.js +1 -0
- package/dist/workflow/autonomous/index.js.map +1 -1
- package/dist/workflow/gates/GateSystem.d.ts +10 -0
- package/dist/workflow/gates/GateSystem.js +62 -0
- package/dist/workflow/gates/GateSystem.js.map +1 -1
- package/dist/workflow/gates/VisualGate.d.ts +41 -0
- package/dist/workflow/gates/VisualGate.js +174 -0
- package/dist/workflow/gates/VisualGate.js.map +1 -0
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.js +1 -0
- package/dist/workflow/index.js.map +1 -1
- package/docs/ACTIVE_SECURITY_VISUAL_GATES.md +87 -0
- package/docs/BACKGROUND_HUNTER.md +62 -0
- package/docs/CONTEXT_BUDGET.md +32 -6
- package/docs/DEPENDENCY_AUDIT.md +89 -0
- package/docs/EVOLUTION_SHADOW_MODE.md +63 -0
- package/docs/GOVERNANCE_DASHBOARD.md +21 -5
- package/docs/README.md +22 -12
- package/package.json +13 -9
package/dist/runtime/index.d.ts
CHANGED
package/dist/runtime/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type DiffInput } from '../ReviewAnalyzer.js';
|
|
2
|
+
import { type EngineeringStandardSeverity } from '../EngineeringStandards.js';
|
|
3
|
+
import type { DiagnosticLoopInput } from '../DiagnosticLoop.js';
|
|
4
|
+
export type HuntFindingSource = 'engineering-standards' | 'review-analyzer';
|
|
5
|
+
export type HuntFindingStatus = 'open' | 'ignored';
|
|
6
|
+
export interface HuntFinding {
|
|
7
|
+
id: string;
|
|
8
|
+
fingerprint: string;
|
|
9
|
+
source: HuntFindingSource;
|
|
10
|
+
status: HuntFindingStatus;
|
|
11
|
+
severity: EngineeringStandardSeverity;
|
|
12
|
+
category: string;
|
|
13
|
+
ruleId: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
line?: number;
|
|
16
|
+
message: string;
|
|
17
|
+
evidence?: string;
|
|
18
|
+
fix?: string;
|
|
19
|
+
ignoreReason?: string;
|
|
20
|
+
diagnosticInput: DiagnosticLoopInput;
|
|
21
|
+
}
|
|
22
|
+
export interface HuntSummary {
|
|
23
|
+
total: number;
|
|
24
|
+
open: number;
|
|
25
|
+
ignored: number;
|
|
26
|
+
blocking: number;
|
|
27
|
+
bySeverity: Record<EngineeringStandardSeverity, number>;
|
|
28
|
+
bySource: Record<HuntFindingSource, number>;
|
|
29
|
+
}
|
|
30
|
+
export interface HuntScanReport {
|
|
31
|
+
projectDir: string;
|
|
32
|
+
generatedAt: string;
|
|
33
|
+
findings: HuntFinding[];
|
|
34
|
+
summary: HuntSummary;
|
|
35
|
+
warnings: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface BackgroundHunterOptions {
|
|
38
|
+
projectDir?: string;
|
|
39
|
+
scaleDir?: string;
|
|
40
|
+
store?: HuntFindingStore;
|
|
41
|
+
}
|
|
42
|
+
export interface BackgroundHunterScanOptions {
|
|
43
|
+
now?: Date;
|
|
44
|
+
changedFiles?: string[];
|
|
45
|
+
statusOutput?: string;
|
|
46
|
+
diffs?: DiffInput[];
|
|
47
|
+
}
|
|
48
|
+
export interface IgnoredHuntFinding {
|
|
49
|
+
id: string;
|
|
50
|
+
fingerprint: string;
|
|
51
|
+
reason?: string;
|
|
52
|
+
ignoredAt: string;
|
|
53
|
+
}
|
|
54
|
+
export declare class BackgroundHunter {
|
|
55
|
+
private readonly projectDir;
|
|
56
|
+
private readonly scaleDir;
|
|
57
|
+
private readonly store;
|
|
58
|
+
constructor(options?: BackgroundHunterOptions);
|
|
59
|
+
scan(options?: BackgroundHunterScanOptions): HuntScanReport;
|
|
60
|
+
createDiagnosticInput(finding: HuntFinding): DiagnosticLoopInput;
|
|
61
|
+
private fromEngineeringStandard;
|
|
62
|
+
private reviewFindings;
|
|
63
|
+
private fromReviewFinding;
|
|
64
|
+
}
|
|
65
|
+
export declare class HuntFindingStore {
|
|
66
|
+
private readonly path;
|
|
67
|
+
constructor(options?: {
|
|
68
|
+
projectDir?: string;
|
|
69
|
+
scaleDir?: string;
|
|
70
|
+
});
|
|
71
|
+
listIgnored(): IgnoredHuntFinding[];
|
|
72
|
+
ignore(finding: IgnoredHuntFinding): IgnoredHuntFinding;
|
|
73
|
+
}
|
|
74
|
+
export declare function createDiagnosticInput(finding: Pick<HuntFinding, 'id' | 'source' | 'ruleId' | 'path' | 'message' | 'evidence'>): DiagnosticLoopInput;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { analyzeReview } from '../ReviewAnalyzer.js';
|
|
5
|
+
import { scanEngineeringStandards, } from '../EngineeringStandards.js';
|
|
6
|
+
export class BackgroundHunter {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.projectDir = resolve(options.projectDir ?? process.cwd());
|
|
9
|
+
this.scaleDir = options.scaleDir ?? '.scale';
|
|
10
|
+
this.store = options.store ?? new HuntFindingStore({ projectDir: this.projectDir, scaleDir: this.scaleDir });
|
|
11
|
+
}
|
|
12
|
+
scan(options = {}) {
|
|
13
|
+
const now = options.now ?? new Date();
|
|
14
|
+
const standardsReport = scanEngineeringStandards({
|
|
15
|
+
projectDir: this.projectDir,
|
|
16
|
+
scaleDir: this.scaleDir,
|
|
17
|
+
now,
|
|
18
|
+
changedFiles: options.changedFiles,
|
|
19
|
+
});
|
|
20
|
+
const findings = [
|
|
21
|
+
...standardsReport.findings.map(finding => this.fromEngineeringStandard(finding)),
|
|
22
|
+
...this.reviewFindings(options),
|
|
23
|
+
].sort(compareHuntFindings);
|
|
24
|
+
const ignored = this.store.listIgnored();
|
|
25
|
+
const resolvedFindings = findings.map(finding => {
|
|
26
|
+
const ignoredFinding = ignored.find(item => item.id === finding.id || item.fingerprint === finding.fingerprint);
|
|
27
|
+
if (!ignoredFinding)
|
|
28
|
+
return finding;
|
|
29
|
+
return {
|
|
30
|
+
...finding,
|
|
31
|
+
status: 'ignored',
|
|
32
|
+
ignoreReason: ignoredFinding.reason,
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
projectDir: this.projectDir,
|
|
37
|
+
generatedAt: now.toISOString(),
|
|
38
|
+
findings: resolvedFindings,
|
|
39
|
+
summary: summarizeHuntFindings(resolvedFindings),
|
|
40
|
+
warnings: standardsReport.warnings,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
createDiagnosticInput(finding) {
|
|
44
|
+
return createDiagnosticInput(finding);
|
|
45
|
+
}
|
|
46
|
+
fromEngineeringStandard(finding) {
|
|
47
|
+
const fingerprint = stableFingerprint([
|
|
48
|
+
'engineering-standards',
|
|
49
|
+
finding.ruleId,
|
|
50
|
+
normalizePath(finding.path),
|
|
51
|
+
String(finding.line ?? ''),
|
|
52
|
+
finding.message,
|
|
53
|
+
]);
|
|
54
|
+
const id = huntId(fingerprint);
|
|
55
|
+
const path = normalizePath(finding.path);
|
|
56
|
+
const result = {
|
|
57
|
+
id,
|
|
58
|
+
fingerprint,
|
|
59
|
+
source: 'engineering-standards',
|
|
60
|
+
status: 'open',
|
|
61
|
+
severity: finding.severity,
|
|
62
|
+
category: finding.category,
|
|
63
|
+
ruleId: finding.ruleId,
|
|
64
|
+
path,
|
|
65
|
+
line: finding.line,
|
|
66
|
+
message: finding.message,
|
|
67
|
+
evidence: finding.evidence,
|
|
68
|
+
fix: finding.fix,
|
|
69
|
+
diagnosticInput: createDiagnosticInput({
|
|
70
|
+
id,
|
|
71
|
+
source: 'engineering-standards',
|
|
72
|
+
ruleId: finding.ruleId,
|
|
73
|
+
path,
|
|
74
|
+
message: finding.message,
|
|
75
|
+
evidence: finding.evidence,
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
reviewFindings(options) {
|
|
81
|
+
if (!options.statusOutput || !options.diffs?.length)
|
|
82
|
+
return [];
|
|
83
|
+
return analyzeReview({
|
|
84
|
+
statusOutput: options.statusOutput,
|
|
85
|
+
diffs: options.diffs,
|
|
86
|
+
}).findings.map(finding => this.fromReviewFinding(finding));
|
|
87
|
+
}
|
|
88
|
+
fromReviewFinding(finding) {
|
|
89
|
+
const path = finding.file ? normalizePath(finding.file) : undefined;
|
|
90
|
+
const fingerprint = stableFingerprint([
|
|
91
|
+
'review-analyzer',
|
|
92
|
+
finding.category,
|
|
93
|
+
finding.severity,
|
|
94
|
+
path ?? '',
|
|
95
|
+
finding.description,
|
|
96
|
+
finding.evidence ?? '',
|
|
97
|
+
]);
|
|
98
|
+
const id = huntId(fingerprint);
|
|
99
|
+
const severity = reviewSeverityToStandardSeverity(finding.severity);
|
|
100
|
+
return {
|
|
101
|
+
id,
|
|
102
|
+
fingerprint,
|
|
103
|
+
source: 'review-analyzer',
|
|
104
|
+
status: 'open',
|
|
105
|
+
severity,
|
|
106
|
+
category: finding.category,
|
|
107
|
+
ruleId: `review-${finding.category}`,
|
|
108
|
+
path,
|
|
109
|
+
message: finding.description,
|
|
110
|
+
evidence: finding.evidence,
|
|
111
|
+
diagnosticInput: createDiagnosticInput({
|
|
112
|
+
id,
|
|
113
|
+
source: 'review-analyzer',
|
|
114
|
+
ruleId: `review-${finding.category}`,
|
|
115
|
+
path,
|
|
116
|
+
message: finding.description,
|
|
117
|
+
evidence: finding.evidence,
|
|
118
|
+
}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export class HuntFindingStore {
|
|
123
|
+
constructor(options = {}) {
|
|
124
|
+
const projectDir = resolve(options.projectDir ?? process.cwd());
|
|
125
|
+
const scaleDir = options.scaleDir ?? '.scale';
|
|
126
|
+
const scaleRoot = isAbsolute(scaleDir) ? scaleDir : join(projectDir, scaleDir);
|
|
127
|
+
this.path = join(scaleRoot, 'hunt', 'ignored-findings.json');
|
|
128
|
+
}
|
|
129
|
+
listIgnored() {
|
|
130
|
+
if (!existsSync(this.path))
|
|
131
|
+
return [];
|
|
132
|
+
try {
|
|
133
|
+
const parsed = JSON.parse(readFileSync(this.path, 'utf-8'));
|
|
134
|
+
return Array.isArray(parsed.ignored)
|
|
135
|
+
? parsed.ignored.filter(item => typeof item.id === 'string' && typeof item.fingerprint === 'string')
|
|
136
|
+
: [];
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
ignore(finding) {
|
|
143
|
+
const current = this.listIgnored();
|
|
144
|
+
const next = [
|
|
145
|
+
...current.filter(item => item.id !== finding.id && item.fingerprint !== finding.fingerprint),
|
|
146
|
+
finding,
|
|
147
|
+
].sort((a, b) => a.id.localeCompare(b.id));
|
|
148
|
+
const dir = this.path.slice(0, this.path.lastIndexOf(sep));
|
|
149
|
+
if (!existsSync(dir))
|
|
150
|
+
mkdirSync(dir, { recursive: true });
|
|
151
|
+
writeFileSync(this.path, JSON.stringify({ version: 1, ignored: next }, null, 2) + '\n', 'utf-8');
|
|
152
|
+
return finding;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export function createDiagnosticInput(finding) {
|
|
156
|
+
const changedFiles = finding.path ? [finding.path] : [];
|
|
157
|
+
const verificationCommand = finding.path
|
|
158
|
+
? `scale standards doctor --changed-files ${finding.path}`
|
|
159
|
+
: 'scale standards doctor';
|
|
160
|
+
return {
|
|
161
|
+
taskId: `HUNT-${finding.id.toUpperCase()}`,
|
|
162
|
+
symptom: `${finding.source} ${finding.ruleId}: ${finding.message}`,
|
|
163
|
+
reproductionCommand: verificationCommand,
|
|
164
|
+
expectedFailure: finding.evidence ?? finding.message,
|
|
165
|
+
changedFiles,
|
|
166
|
+
verificationCommands: [verificationCommand],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function summarizeHuntFindings(findings) {
|
|
170
|
+
const bySeverity = { info: 0, warn: 0, fail: 0 };
|
|
171
|
+
const bySource = {
|
|
172
|
+
'engineering-standards': 0,
|
|
173
|
+
'review-analyzer': 0,
|
|
174
|
+
};
|
|
175
|
+
for (const finding of findings) {
|
|
176
|
+
bySeverity[finding.severity] += 1;
|
|
177
|
+
bySource[finding.source] += 1;
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
total: findings.length,
|
|
181
|
+
open: findings.filter(finding => finding.status === 'open').length,
|
|
182
|
+
ignored: findings.filter(finding => finding.status === 'ignored').length,
|
|
183
|
+
blocking: findings.filter(finding => finding.status === 'open' && finding.severity === 'fail').length,
|
|
184
|
+
bySeverity,
|
|
185
|
+
bySource,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function compareHuntFindings(a, b) {
|
|
189
|
+
return severityRank(b.severity) - severityRank(a.severity) ||
|
|
190
|
+
(a.path ?? '').localeCompare(b.path ?? '') ||
|
|
191
|
+
a.ruleId.localeCompare(b.ruleId) ||
|
|
192
|
+
a.id.localeCompare(b.id);
|
|
193
|
+
}
|
|
194
|
+
function severityRank(severity) {
|
|
195
|
+
if (severity === 'fail')
|
|
196
|
+
return 3;
|
|
197
|
+
if (severity === 'warn')
|
|
198
|
+
return 2;
|
|
199
|
+
return 1;
|
|
200
|
+
}
|
|
201
|
+
function reviewSeverityToStandardSeverity(severity) {
|
|
202
|
+
if (severity === 'CRITICAL' || severity === 'HIGH')
|
|
203
|
+
return 'fail';
|
|
204
|
+
if (severity === 'MEDIUM')
|
|
205
|
+
return 'warn';
|
|
206
|
+
return 'info';
|
|
207
|
+
}
|
|
208
|
+
function stableFingerprint(parts) {
|
|
209
|
+
return parts.map(part => part.trim()).join('\0');
|
|
210
|
+
}
|
|
211
|
+
function huntId(fingerprint) {
|
|
212
|
+
return createHash('sha256').update(fingerprint).digest('hex').slice(0, 12);
|
|
213
|
+
}
|
|
214
|
+
function normalizePath(path) {
|
|
215
|
+
const normalized = path.replace(/\\/g, '/');
|
|
216
|
+
if (!isAbsolute(path))
|
|
217
|
+
return normalized.replace(/^\.\//, '');
|
|
218
|
+
return relative(process.cwd(), path).replace(/\\/g, '/');
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=BackgroundHunter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BackgroundHunter.js","sourceRoot":"","sources":["../../../src/workflow/autonomous/BackgroundHunter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/workflow/autonomous/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/workflow/autonomous/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA"}
|
|
@@ -4,6 +4,7 @@ import { WorkflowArtifactWriter } from '../WorkflowArtifactWriter.js';
|
|
|
4
4
|
import { type ResolvedVerificationCommand, type VerificationCommandConfig, type VerificationRuntimeEvidenceConfig } from '../VerificationCommands.js';
|
|
5
5
|
import { type CommandOutputCompressionResult } from '../../tools/CommandOutputCompressor.js';
|
|
6
6
|
import { type CommandRunEvidenceOptions } from '../../tools/CommandRunLedger.js';
|
|
7
|
+
import { type DependencyAuditMode } from '../../guardrails/DependencyAuditor.js';
|
|
7
8
|
export interface IGate {
|
|
8
9
|
stage: GateStage;
|
|
9
10
|
name: string;
|
|
@@ -36,6 +37,10 @@ export interface SecurityGateOptions {
|
|
|
36
37
|
maxFileBytes?: number;
|
|
37
38
|
maxFindings?: number;
|
|
38
39
|
strict?: boolean;
|
|
40
|
+
scaleDir?: string;
|
|
41
|
+
dependencyAudit?: boolean;
|
|
42
|
+
dependencyAuditMode?: DependencyAuditMode;
|
|
43
|
+
dependencyAuditChangedPackages?: string[];
|
|
39
44
|
}
|
|
40
45
|
export declare function runShellCommand(command: string, timeout: number, cwd?: string, options?: RunShellCommandOptions): Promise<CommandResult>;
|
|
41
46
|
export declare class GateSystem {
|
|
@@ -141,6 +146,10 @@ export declare class SecurityGate implements IGate {
|
|
|
141
146
|
private maxFileBytes;
|
|
142
147
|
private maxFindings;
|
|
143
148
|
private strict;
|
|
149
|
+
private scaleDir;
|
|
150
|
+
private dependencyAudit;
|
|
151
|
+
private dependencyAuditMode?;
|
|
152
|
+
private dependencyAuditChangedPackages?;
|
|
144
153
|
constructor(options?: SecurityGateOptions);
|
|
145
154
|
execute(): Promise<GateResult>;
|
|
146
155
|
private scan;
|
|
@@ -149,6 +158,7 @@ export declare class SecurityGate implements IGate {
|
|
|
149
158
|
private rulesForFile;
|
|
150
159
|
private findEmptyCatchBlocks;
|
|
151
160
|
private summarize;
|
|
161
|
+
private dependencyEvidence;
|
|
152
162
|
private isTestPath;
|
|
153
163
|
private isRuleDefinition;
|
|
154
164
|
private isSecurityTestFixture;
|
|
@@ -9,6 +9,7 @@ import { createHash } from 'node:crypto';
|
|
|
9
9
|
import { RuntimeEvidenceLedger } from '../../runtime/RuntimeEvidenceLedger.js';
|
|
10
10
|
import { compressCommandOutput } from '../../tools/CommandOutputCompressor.js';
|
|
11
11
|
import { CommandRunLedger } from '../../tools/CommandRunLedger.js';
|
|
12
|
+
import { auditDependencies } from '../../guardrails/DependencyAuditor.js';
|
|
12
13
|
function tail(value, maxLength = 1000) {
|
|
13
14
|
return value.length > maxLength ? value.slice(-maxLength) : value;
|
|
14
15
|
}
|
|
@@ -137,6 +138,15 @@ export class GateSystem {
|
|
|
137
138
|
this.persistEvidence(result);
|
|
138
139
|
this.recordCompletedGate(stage, result);
|
|
139
140
|
this.eventBus.emit('gate.executed', { stage, passed: result.passed });
|
|
141
|
+
if (!result.passed) {
|
|
142
|
+
this.eventBus.emit('gate.failed', {
|
|
143
|
+
stage,
|
|
144
|
+
status: result.status,
|
|
145
|
+
blockers: result.blockers,
|
|
146
|
+
evidence: result.evidence,
|
|
147
|
+
evidenceRecordId: result.evidenceRecordId,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
140
150
|
return result;
|
|
141
151
|
}
|
|
142
152
|
catch (e) {
|
|
@@ -158,6 +168,14 @@ export class GateSystem {
|
|
|
158
168
|
};
|
|
159
169
|
this.results.set(stage, result);
|
|
160
170
|
this.persistEvidence(result);
|
|
171
|
+
this.eventBus.emit('gate.executed', { stage, passed: false });
|
|
172
|
+
this.eventBus.emit('gate.failed', {
|
|
173
|
+
stage,
|
|
174
|
+
status: result.status,
|
|
175
|
+
blockers: result.blockers,
|
|
176
|
+
evidence: result.evidence,
|
|
177
|
+
evidenceRecordId: result.evidenceRecordId,
|
|
178
|
+
});
|
|
161
179
|
return result;
|
|
162
180
|
}
|
|
163
181
|
}
|
|
@@ -793,12 +811,23 @@ export class SecurityGate {
|
|
|
793
811
|
this.maxFileBytes = options.maxFileBytes ?? 300_000;
|
|
794
812
|
this.maxFindings = options.maxFindings ?? 50;
|
|
795
813
|
this.strict = options.strict ?? false;
|
|
814
|
+
this.scaleDir = options.scaleDir ?? '.scale';
|
|
815
|
+
this.dependencyAudit = options.dependencyAudit ?? true;
|
|
816
|
+
this.dependencyAuditMode = options.dependencyAuditMode;
|
|
817
|
+
this.dependencyAuditChangedPackages = options.dependencyAuditChangedPackages;
|
|
796
818
|
}
|
|
797
819
|
async execute() {
|
|
798
820
|
const findings = await this.scan();
|
|
821
|
+
const dependencyReport = this.dependencyAudit ? auditDependencies({
|
|
822
|
+
projectDir: this.rootDir,
|
|
823
|
+
scaleDir: this.scaleDir,
|
|
824
|
+
mode: this.dependencyAuditMode ?? (this.strict ? 'strict' : undefined),
|
|
825
|
+
changedPackages: this.dependencyAuditChangedPackages,
|
|
826
|
+
}) : null;
|
|
799
827
|
const blockers = findings
|
|
800
828
|
.filter(finding => finding.severity === 'CRITICAL' || (this.strict && finding.severity === 'HIGH'))
|
|
801
829
|
.map(finding => `${finding.severity} ${finding.ruleId} in ${finding.file}:${finding.line} - ${finding.description}`);
|
|
830
|
+
blockers.push(...(dependencyReport?.blockers ?? []));
|
|
802
831
|
const passed = blockers.length === 0;
|
|
803
832
|
const summary = this.summarize(findings);
|
|
804
833
|
const evidenceItems = [
|
|
@@ -820,6 +849,7 @@ export class SecurityGate {
|
|
|
820
849
|
detail: `${finding.severity} line ${finding.line}: ${finding.description}; ${finding.evidence}`,
|
|
821
850
|
source: 'built-in-security-scan',
|
|
822
851
|
})),
|
|
852
|
+
...this.dependencyEvidence(dependencyReport),
|
|
823
853
|
];
|
|
824
854
|
return {
|
|
825
855
|
gate: this.stage,
|
|
@@ -1006,6 +1036,38 @@ export class SecurityGate {
|
|
|
1006
1036
|
LOW: findings.filter(f => f.severity === 'LOW').length,
|
|
1007
1037
|
};
|
|
1008
1038
|
}
|
|
1039
|
+
dependencyEvidence(report) {
|
|
1040
|
+
if (!report) {
|
|
1041
|
+
return [
|
|
1042
|
+
createEvidence({
|
|
1043
|
+
kind: 'scan',
|
|
1044
|
+
label: 'G7 dependency audit',
|
|
1045
|
+
passed: true,
|
|
1046
|
+
detail: 'dependency audit disabled',
|
|
1047
|
+
source: 'dependency-audit',
|
|
1048
|
+
}),
|
|
1049
|
+
];
|
|
1050
|
+
}
|
|
1051
|
+
const summary = report.summary;
|
|
1052
|
+
return [
|
|
1053
|
+
createEvidence({
|
|
1054
|
+
kind: 'scan',
|
|
1055
|
+
label: 'G7 dependency audit',
|
|
1056
|
+
passed: report.ok,
|
|
1057
|
+
path: report.lockfilePath,
|
|
1058
|
+
detail: `${summary.packagesAudited} package(s) audited, findings=${summary.totalFindings}, critical=${summary.bySeverity.CRITICAL}, high=${summary.bySeverity.HIGH}, medium=${summary.bySeverity.MEDIUM}, low=${summary.bySeverity.LOW}, mode=${report.mode}`,
|
|
1059
|
+
source: 'dependency-audit',
|
|
1060
|
+
}),
|
|
1061
|
+
...report.findings.slice(0, this.maxFindings).map(finding => createEvidence({
|
|
1062
|
+
kind: 'scan',
|
|
1063
|
+
label: `Dependency finding ${finding.ruleId}`,
|
|
1064
|
+
passed: !report.blockers.some(blocker => blocker.includes(finding.ruleId) && blocker.includes(finding.packageName)),
|
|
1065
|
+
path: finding.path,
|
|
1066
|
+
detail: `${finding.severity} ${finding.packageName}${finding.version ? `@${finding.version}` : ''}: ${finding.message}; ${finding.evidence ?? 'no detail'}`,
|
|
1067
|
+
source: 'dependency-audit',
|
|
1068
|
+
})),
|
|
1069
|
+
];
|
|
1070
|
+
}
|
|
1009
1071
|
isTestPath(file) {
|
|
1010
1072
|
return /(^|\/)(tests?|__tests__)\//i.test(file) || /\.(test|spec)\.(ts|tsx|js|jsx|mjs|cjs)$/i.test(file);
|
|
1011
1073
|
}
|