@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.
Files changed (64) hide show
  1. package/dist/api/cli.js +192 -1
  2. package/dist/api/cli.js.map +1 -1
  3. package/dist/dashboard/MetricsAggregator.d.ts +38 -0
  4. package/dist/dashboard/MetricsAggregator.js +99 -0
  5. package/dist/dashboard/MetricsAggregator.js.map +1 -0
  6. package/dist/dashboard/index.d.ts +2 -0
  7. package/dist/dashboard/index.js +1 -0
  8. package/dist/dashboard/index.js.map +1 -1
  9. package/dist/dashboard/server.js +1 -1
  10. package/dist/dashboard/server.js.map +1 -1
  11. package/dist/evolution/AutoDefectCreator.d.ts +11 -2
  12. package/dist/evolution/AutoDefectCreator.js +46 -2
  13. package/dist/evolution/AutoDefectCreator.js.map +1 -1
  14. package/dist/evolution/EvolutionEngine.d.ts +3 -0
  15. package/dist/evolution/EvolutionEngine.js +18 -2
  16. package/dist/evolution/EvolutionEngine.js.map +1 -1
  17. package/dist/evolution/RuleMaturity.d.ts +39 -0
  18. package/dist/evolution/RuleMaturity.js +70 -0
  19. package/dist/evolution/RuleMaturity.js.map +1 -0
  20. package/dist/guardrails/ActiveRedTeam.d.ts +46 -0
  21. package/dist/guardrails/ActiveRedTeam.js +203 -0
  22. package/dist/guardrails/ActiveRedTeam.js.map +1 -0
  23. package/dist/guardrails/DependencyAuditor.d.ts +68 -0
  24. package/dist/guardrails/DependencyAuditor.js +331 -0
  25. package/dist/guardrails/DependencyAuditor.js.map +1 -0
  26. package/dist/hooks/HookGeneratorEnhanced.js +18 -18
  27. package/dist/index.d.ts +6 -0
  28. package/dist/index.js +5 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/output/GovernanceDashboard.d.ts +2 -0
  31. package/dist/output/GovernanceDashboard.js +31 -0
  32. package/dist/output/GovernanceDashboard.js.map +1 -1
  33. package/dist/routing/PromptCachePolicy.d.ts +37 -0
  34. package/dist/routing/PromptCachePolicy.js +97 -0
  35. package/dist/routing/PromptCachePolicy.js.map +1 -0
  36. package/dist/runtime/ModelUsageLedger.d.ts +50 -0
  37. package/dist/runtime/ModelUsageLedger.js +92 -0
  38. package/dist/runtime/ModelUsageLedger.js.map +1 -0
  39. package/dist/runtime/index.d.ts +1 -0
  40. package/dist/runtime/index.js +1 -0
  41. package/dist/runtime/index.js.map +1 -1
  42. package/dist/workflow/autonomous/BackgroundHunter.d.ts +74 -0
  43. package/dist/workflow/autonomous/BackgroundHunter.js +220 -0
  44. package/dist/workflow/autonomous/BackgroundHunter.js.map +1 -0
  45. package/dist/workflow/autonomous/index.d.ts +1 -0
  46. package/dist/workflow/autonomous/index.js +1 -0
  47. package/dist/workflow/autonomous/index.js.map +1 -1
  48. package/dist/workflow/gates/GateSystem.d.ts +10 -0
  49. package/dist/workflow/gates/GateSystem.js +62 -0
  50. package/dist/workflow/gates/GateSystem.js.map +1 -1
  51. package/dist/workflow/gates/VisualGate.d.ts +41 -0
  52. package/dist/workflow/gates/VisualGate.js +174 -0
  53. package/dist/workflow/gates/VisualGate.js.map +1 -0
  54. package/dist/workflow/index.d.ts +1 -0
  55. package/dist/workflow/index.js +1 -0
  56. package/dist/workflow/index.js.map +1 -1
  57. package/docs/ACTIVE_SECURITY_VISUAL_GATES.md +87 -0
  58. package/docs/BACKGROUND_HUNTER.md +62 -0
  59. package/docs/CONTEXT_BUDGET.md +32 -6
  60. package/docs/DEPENDENCY_AUDIT.md +89 -0
  61. package/docs/EVOLUTION_SHADOW_MODE.md +63 -0
  62. package/docs/GOVERNANCE_DASHBOARD.md +21 -5
  63. package/docs/README.md +22 -12
  64. package/package.json +13 -9
@@ -2,3 +2,4 @@ export * from './RuntimeEvidenceLedger.js';
2
2
  export * from './SessionLedger.js';
3
3
  export * from './RuntimeDoctor.js';
4
4
  export * from './FinalReportGuard.js';
5
+ export * from './ModelUsageLedger.js';
@@ -2,4 +2,5 @@ export * from './RuntimeEvidenceLedger.js';
2
2
  export * from './SessionLedger.js';
3
3
  export * from './RuntimeDoctor.js';
4
4
  export * from './FinalReportGuard.js';
5
+ export * from './ModelUsageLedger.js';
5
6
  //# sourceMappingURL=index.js.map
@@ -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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEpE,OAAO,EAAE,aAAa,EAAkB,MAAM,sBAAsB,CAAA;AACpE,OAAO,EACL,wBAAwB,GAGzB,MAAM,4BAA4B,CAAA;AAiEnC,MAAM,OAAO,gBAAgB;IAK3B,YAAY,UAAmC,EAAE;QAC/C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC9D,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAA;QAC5C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,gBAAgB,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC9G,CAAC;IAED,IAAI,CAAC,UAAuC,EAAE;QAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAA;QACrC,MAAM,eAAe,GAAG,wBAAwB,CAAC;YAC/C,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG;YACH,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CAAA;QACF,MAAM,QAAQ,GAAG;YACf,GAAG,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;YACjF,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;SAChC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;QACxC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAC9C,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;YAC/G,IAAI,CAAC,cAAc;gBAAE,OAAO,OAAO,CAAA;YACnC,OAAO;gBACL,GAAG,OAAO;gBACV,MAAM,EAAE,SAAkB;gBAC1B,YAAY,EAAE,cAAc,CAAC,MAAM;aACpC,CAAA;QACH,CAAC,CAAC,CAAA;QACF,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;YAC9B,QAAQ,EAAE,gBAAgB;YAC1B,OAAO,EAAE,qBAAqB,CAAC,gBAAgB,CAAC;YAChD,QAAQ,EAAE,eAAe,CAAC,QAAQ;SACnC,CAAA;IACH,CAAC;IAED,qBAAqB,CAAC,OAAoB;QACxC,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;IAEO,uBAAuB,CAAC,OAAmC;QACjE,MAAM,WAAW,GAAG,iBAAiB,CAAC;YACpC,uBAAuB;YACvB,OAAO,CAAC,MAAM;YACd,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;YAC1B,OAAO,CAAC,OAAO;SAChB,CAAC,CAAA;QACF,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,CAAA;QAC9B,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,MAAM,GAAgB;YAC1B,EAAE;YACF,WAAW;YACX,MAAM,EAAE,uBAAuB;YAC/B,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,eAAe,EAAE,qBAAqB,CAAC;gBACrC,EAAE;gBACF,MAAM,EAAE,uBAAuB;gBAC/B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,IAAI;gBACJ,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC;SACH,CAAA;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,cAAc,CAAC,OAAoC;QACzD,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM;YAAE,OAAO,EAAE,CAAA;QAC9D,OAAO,aAAa,CAAC;YACnB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAA;IAC7D,CAAC;IAEO,iBAAiB,CAAC,OAAsB;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACnE,MAAM,WAAW,GAAG,iBAAiB,CAAC;YACpC,iBAAiB;YACjB,OAAO,CAAC,QAAQ;YAChB,OAAO,CAAC,QAAQ;YAChB,IAAI,IAAI,EAAE;YACV,OAAO,CAAC,WAAW;YACnB,OAAO,CAAC,QAAQ,IAAI,EAAE;SACvB,CAAC,CAAA;QACF,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,CAAA;QAC9B,MAAM,QAAQ,GAAG,gCAAgC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QACnE,OAAO;YACL,EAAE;YACF,WAAW;YACX,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,MAAM;YACd,QAAQ;YACR,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,UAAU,OAAO,CAAC,QAAQ,EAAE;YACpC,IAAI;YACJ,OAAO,EAAE,OAAO,CAAC,WAAW;YAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,eAAe,EAAE,qBAAqB,CAAC;gBACrC,EAAE;gBACF,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,UAAU,OAAO,CAAC,QAAQ,EAAE;gBACpC,IAAI;gBACJ,OAAO,EAAE,OAAO,CAAC,WAAW;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC3B,CAAC;SACH,CAAA;IACH,CAAC;CACF;AAED,MAAM,OAAO,gBAAgB;IAG3B,YAAY,UAAsD,EAAE;QAClE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;QAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAA;QAC7C,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QAC9E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,uBAAuB,CAAC,CAAA;IAC9D,CAAC;IAED,WAAW;QACT,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAA;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAyB,CAAA;YACnF,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;gBAClC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC;gBACpG,CAAC,CAAC,EAAE,CAAA;QACR,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAA2B;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAClC,MAAM,IAAI,GAAG;YACX,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC;YAC7F,OAAO;SACR,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;QAChG,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAwF;IAC5H,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACvD,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI;QACtC,CAAC,CAAC,0CAA0C,OAAO,CAAC,IAAI,EAAE;QAC1D,CAAC,CAAC,wBAAwB,CAAA;IAC5B,OAAO;QACL,MAAM,EAAE,QAAQ,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE;QAC1C,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE;QAClE,mBAAmB,EAAE,mBAAmB;QACxC,eAAe,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO;QACpD,YAAY;QACZ,oBAAoB,EAAE,CAAC,mBAAmB,CAAC;KAC5C,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAuB;IACpD,MAAM,UAAU,GAAgD,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAA;IAC7F,MAAM,QAAQ,GAAsC;QAClD,uBAAuB,EAAE,CAAC;QAC1B,iBAAiB,EAAE,CAAC;KACrB,CAAA;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QACjC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IACD,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,MAAM;QACtB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM;QAClE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;QACxE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;QACrG,UAAU;QACV,QAAQ;KACT,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,CAAc,EAAE,CAAc;IACzD,OAAO,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;QACxD,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC1C,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;QAChC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAC5B,CAAC;AAED,SAAS,YAAY,CAAC,QAAqC;IACzD,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,CAAC,CAAA;IACjC,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAS,gCAAgC,CAAC,QAAmC;IAC3E,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,MAAM,CAAA;IACjE,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAA;IACxC,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAe;IACxC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAClD,CAAC;AAED,SAAS,MAAM,CAAC,WAAmB;IACjC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC5E,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAC3C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IAC7D,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;AAC1D,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export * from './WorklogManager.js';
2
2
  export * from './AutonomousDevLoop.js';
3
+ export * from './BackgroundHunter.js';
@@ -1,4 +1,5 @@
1
1
  // SCALE Engine — Autonomous Module Index
2
2
  export * from './WorklogManager.js';
3
3
  export * from './AutonomousDevLoop.js';
4
+ export * from './BackgroundHunter.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -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
  }