@hongmaple0820/scale-engine 0.21.2 → 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 (135) hide show
  1. package/README.en.md +35 -11
  2. package/README.md +54 -23
  3. package/dist/api/cli.js +476 -5
  4. package/dist/api/cli.js.map +1 -1
  5. package/dist/api/doctor.d.ts +1 -0
  6. package/dist/api/doctor.js +83 -0
  7. package/dist/api/doctor.js.map +1 -1
  8. package/dist/artifact/types.d.ts +1 -1
  9. package/dist/artifact/types.js.map +1 -1
  10. package/dist/cli/phaseCommands.js +22 -6
  11. package/dist/cli/phaseCommands.js.map +1 -1
  12. package/dist/cli/runCommand.d.ts +39 -0
  13. package/dist/cli/runCommand.js +113 -0
  14. package/dist/cli/runCommand.js.map +1 -0
  15. package/dist/config/profiles.d.ts +52 -0
  16. package/dist/config/profiles.js +162 -0
  17. package/dist/config/profiles.js.map +1 -0
  18. package/dist/context/ContextBudget.d.ts +25 -1
  19. package/dist/context/ContextBudget.js +72 -7
  20. package/dist/context/ContextBudget.js.map +1 -1
  21. package/dist/context/ProjectAnatomy.d.ts +18 -0
  22. package/dist/context/ProjectAnatomy.js +287 -0
  23. package/dist/context/ProjectAnatomy.js.map +1 -0
  24. package/dist/dashboard/DashboardServer.d.ts +3 -0
  25. package/dist/dashboard/DashboardServer.js +114 -0
  26. package/dist/dashboard/DashboardServer.js.map +1 -1
  27. package/dist/dashboard/MetricsAggregator.d.ts +38 -0
  28. package/dist/dashboard/MetricsAggregator.js +99 -0
  29. package/dist/dashboard/MetricsAggregator.js.map +1 -0
  30. package/dist/dashboard/index.d.ts +2 -0
  31. package/dist/dashboard/index.js +1 -0
  32. package/dist/dashboard/index.js.map +1 -1
  33. package/dist/dashboard/server.js +1 -1
  34. package/dist/dashboard/server.js.map +1 -1
  35. package/dist/evolution/AutoDefectCreator.d.ts +11 -2
  36. package/dist/evolution/AutoDefectCreator.js +46 -2
  37. package/dist/evolution/AutoDefectCreator.js.map +1 -1
  38. package/dist/evolution/EvolutionEngine.d.ts +3 -0
  39. package/dist/evolution/EvolutionEngine.js +18 -2
  40. package/dist/evolution/EvolutionEngine.js.map +1 -1
  41. package/dist/evolution/RuleMaturity.d.ts +39 -0
  42. package/dist/evolution/RuleMaturity.js +70 -0
  43. package/dist/evolution/RuleMaturity.js.map +1 -0
  44. package/dist/guardrails/ActiveRedTeam.d.ts +46 -0
  45. package/dist/guardrails/ActiveRedTeam.js +203 -0
  46. package/dist/guardrails/ActiveRedTeam.js.map +1 -0
  47. package/dist/guardrails/DependencyAuditor.d.ts +68 -0
  48. package/dist/guardrails/DependencyAuditor.js +331 -0
  49. package/dist/guardrails/DependencyAuditor.js.map +1 -0
  50. package/dist/hooks/BugPatternDetector.d.ts +36 -0
  51. package/dist/hooks/BugPatternDetector.js +207 -0
  52. package/dist/hooks/BugPatternDetector.js.map +1 -0
  53. package/dist/hooks/HookGeneratorEnhanced.js +301 -5
  54. package/dist/hooks/HookGeneratorEnhanced.js.map +1 -1
  55. package/dist/hooks/WorkflowHooksManager.js +24 -0
  56. package/dist/hooks/WorkflowHooksManager.js.map +1 -1
  57. package/dist/index.d.ts +10 -0
  58. package/dist/index.js +7 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/knowledge/CerebrumManager.d.ts +25 -0
  61. package/dist/knowledge/CerebrumManager.js +127 -0
  62. package/dist/knowledge/CerebrumManager.js.map +1 -0
  63. package/dist/knowledge/SQLiteKnowledgeBase.d.ts +1 -0
  64. package/dist/knowledge/SQLiteKnowledgeBase.js +31 -3
  65. package/dist/knowledge/SQLiteKnowledgeBase.js.map +1 -1
  66. package/dist/knowledge/TfidfIndex.d.ts +50 -0
  67. package/dist/knowledge/TfidfIndex.js +177 -0
  68. package/dist/knowledge/TfidfIndex.js.map +1 -0
  69. package/dist/output/GovernanceDashboard.d.ts +2 -0
  70. package/dist/output/GovernanceDashboard.js +31 -0
  71. package/dist/output/GovernanceDashboard.js.map +1 -1
  72. package/dist/routing/PromptCachePolicy.d.ts +37 -0
  73. package/dist/routing/PromptCachePolicy.js +97 -0
  74. package/dist/routing/PromptCachePolicy.js.map +1 -0
  75. package/dist/runtime/ModelUsageLedger.d.ts +50 -0
  76. package/dist/runtime/ModelUsageLedger.js +92 -0
  77. package/dist/runtime/ModelUsageLedger.js.map +1 -0
  78. package/dist/runtime/index.d.ts +1 -0
  79. package/dist/runtime/index.js +1 -0
  80. package/dist/runtime/index.js.map +1 -1
  81. package/dist/skills/SkillDiscovery.js +1 -1
  82. package/dist/skills/SkillDiscovery.js.map +1 -1
  83. package/dist/tools/CommandOutputCompressor.d.ts +28 -0
  84. package/dist/tools/CommandOutputCompressor.js +242 -0
  85. package/dist/tools/CommandOutputCompressor.js.map +1 -0
  86. package/dist/tools/CommandRunLedger.d.ts +77 -0
  87. package/dist/tools/CommandRunLedger.js +111 -0
  88. package/dist/tools/CommandRunLedger.js.map +1 -0
  89. package/dist/tools/index.d.ts +2 -0
  90. package/dist/tools/index.js +2 -0
  91. package/dist/tools/index.js.map +1 -1
  92. package/dist/workflow/EngineeringStandards.js +91 -2
  93. package/dist/workflow/EngineeringStandards.js.map +1 -1
  94. package/dist/workflow/GovernanceTemplatePacks.js +2 -2
  95. package/dist/workflow/GovernanceTemplates.js +93 -92
  96. package/dist/workflow/GovernanceTemplates.js.map +1 -1
  97. package/dist/workflow/TaskLevelDetector.d.ts +41 -0
  98. package/dist/workflow/TaskLevelDetector.js +219 -0
  99. package/dist/workflow/TaskLevelDetector.js.map +1 -0
  100. package/dist/workflow/WorkflowOrchestrator.d.ts +59 -0
  101. package/dist/workflow/WorkflowOrchestrator.js +326 -0
  102. package/dist/workflow/WorkflowOrchestrator.js.map +1 -0
  103. package/dist/workflow/autonomous/BackgroundHunter.d.ts +74 -0
  104. package/dist/workflow/autonomous/BackgroundHunter.js +220 -0
  105. package/dist/workflow/autonomous/BackgroundHunter.js.map +1 -0
  106. package/dist/workflow/autonomous/index.d.ts +1 -0
  107. package/dist/workflow/autonomous/index.js +1 -0
  108. package/dist/workflow/autonomous/index.js.map +1 -1
  109. package/dist/workflow/gates/GateSystem.d.ts +33 -6
  110. package/dist/workflow/gates/GateSystem.js +176 -25
  111. package/dist/workflow/gates/GateSystem.js.map +1 -1
  112. package/dist/workflow/gates/MetaGovernanceGates.d.ts +70 -0
  113. package/dist/workflow/gates/MetaGovernanceGates.js +617 -0
  114. package/dist/workflow/gates/MetaGovernanceGates.js.map +1 -0
  115. package/dist/workflow/gates/VisualGate.d.ts +41 -0
  116. package/dist/workflow/gates/VisualGate.js +174 -0
  117. package/dist/workflow/gates/VisualGate.js.map +1 -0
  118. package/dist/workflow/index.d.ts +1 -0
  119. package/dist/workflow/index.js +1 -0
  120. package/dist/workflow/index.js.map +1 -1
  121. package/dist/workflow/types.d.ts +6 -1
  122. package/docs/ACTIVE_SECURITY_VISUAL_GATES.md +87 -0
  123. package/docs/BACKGROUND_HUNTER.md +62 -0
  124. package/docs/CONTEXT_BUDGET.md +32 -6
  125. package/docs/DEPENDENCY_AUDIT.md +89 -0
  126. package/docs/EVOLUTION_SHADOW_MODE.md +63 -0
  127. package/docs/GOVERNANCE_DASHBOARD.md +21 -5
  128. package/docs/README.md +24 -12
  129. package/docs/start/README.md +29 -3
  130. package/docs/start/artifact-lifecycle.md +326 -0
  131. package/docs/start/workflow-upgrade.md +150 -0
  132. package/image/wechat-public.jpg +0 -0
  133. package/image/wxPay.jpg +0 -0
  134. package/image/zfb.jpg +0 -0
  135. package/package.json +7 -2
@@ -0,0 +1,41 @@
1
+ import type { IGate } from './GateSystem.js';
2
+ import type { GateResult, GateStage } from '../types.js';
3
+ export type VisualFindingSeverity = 'critical' | 'high' | 'medium' | 'low';
4
+ export interface VisualGateConfig {
5
+ enabled?: boolean;
6
+ baseUrl?: string;
7
+ specPath?: string;
8
+ routes?: string[];
9
+ reportPath?: string;
10
+ blockingSeverities?: VisualFindingSeverity[];
11
+ }
12
+ export interface VisualGateFinding {
13
+ severity: VisualFindingSeverity;
14
+ route?: string;
15
+ message: string;
16
+ evidence?: string;
17
+ }
18
+ export interface VisualGateReport {
19
+ screenshots?: Array<{
20
+ route: string;
21
+ path: string;
22
+ }>;
23
+ findings?: VisualGateFinding[];
24
+ }
25
+ export interface VisualGateOptions {
26
+ projectDir?: string;
27
+ config?: VisualGateConfig;
28
+ }
29
+ export declare class VisualGate implements IGate {
30
+ stage: GateStage;
31
+ name: string;
32
+ description: string;
33
+ requiredLevel: 'S' | 'M' | 'L' | 'ALWAYS' | 'CRITICAL';
34
+ private projectDir;
35
+ private config?;
36
+ constructor(options?: VisualGateOptions);
37
+ execute(): Promise<GateResult>;
38
+ private validateConfig;
39
+ private resolvePath;
40
+ private result;
41
+ }
@@ -0,0 +1,174 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { isAbsolute, join } from 'node:path';
3
+ const DEFAULT_BLOCKING_SEVERITIES = ['critical', 'high'];
4
+ export class VisualGate {
5
+ constructor(options = {}) {
6
+ this.stage = 'G9';
7
+ this.name = 'Visual Gate';
8
+ this.description = 'Validates structured visual review evidence against UI spec routes.';
9
+ this.requiredLevel = 'M';
10
+ this.projectDir = options.projectDir ?? process.cwd();
11
+ this.config = options.config;
12
+ }
13
+ async execute() {
14
+ const start = Date.now();
15
+ if (!this.config?.enabled) {
16
+ return this.result({
17
+ passed: true,
18
+ status: 'PASSED',
19
+ evidenceItems: [
20
+ createEvidence({
21
+ kind: 'manual',
22
+ label: 'Visual gate skipped',
23
+ passed: true,
24
+ detail: 'Visual checks are not enabled for this task.',
25
+ }),
26
+ ],
27
+ blockers: [],
28
+ start,
29
+ });
30
+ }
31
+ const validation = this.validateConfig(this.config);
32
+ if (validation.blockers.length > 0) {
33
+ return this.result({
34
+ passed: false,
35
+ status: 'FAILED',
36
+ evidenceItems: [
37
+ createEvidence({
38
+ kind: 'manual',
39
+ label: 'Visual gate configuration',
40
+ passed: false,
41
+ detail: validation.blockers.join('; '),
42
+ }),
43
+ ],
44
+ blockers: validation.blockers,
45
+ start,
46
+ });
47
+ }
48
+ const reportPath = this.resolvePath(this.config.reportPath);
49
+ let report;
50
+ try {
51
+ report = JSON.parse(readFileSync(reportPath, 'utf-8'));
52
+ }
53
+ catch (error) {
54
+ const detail = error instanceof Error ? error.message : String(error);
55
+ return this.result({
56
+ passed: false,
57
+ status: 'FAILED',
58
+ evidenceItems: [
59
+ createEvidence({
60
+ kind: 'file',
61
+ label: 'Visual report parse',
62
+ passed: false,
63
+ path: reportPath,
64
+ detail,
65
+ }),
66
+ ],
67
+ blockers: [`visual report could not be parsed: ${detail}`],
68
+ start,
69
+ });
70
+ }
71
+ const findings = normalizeFindings(report.findings ?? []);
72
+ const blockingSeverities = this.config.blockingSeverities ?? DEFAULT_BLOCKING_SEVERITIES;
73
+ const blockers = findings
74
+ .filter(finding => blockingSeverities.includes(finding.severity))
75
+ .map(finding => `${finding.severity} visual finding${finding.route ? ` on ${finding.route}` : ''}: ${finding.message}`);
76
+ const evidenceItems = [
77
+ createEvidence({
78
+ kind: 'file',
79
+ label: 'Visual report',
80
+ passed: blockers.length === 0,
81
+ path: reportPath,
82
+ detail: renderFindingSummary(findings, report.screenshots?.length ?? 0),
83
+ }),
84
+ ];
85
+ return this.result({
86
+ passed: blockers.length === 0,
87
+ status: blockers.length === 0 ? 'PASSED' : 'FAILED',
88
+ evidenceItems,
89
+ blockers,
90
+ start,
91
+ });
92
+ }
93
+ validateConfig(config) {
94
+ const blockers = [];
95
+ if (!config.baseUrl) {
96
+ blockers.push('visual.baseUrl is required');
97
+ }
98
+ else {
99
+ try {
100
+ const url = new URL(config.baseUrl);
101
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
102
+ blockers.push('visual.baseUrl must use http or https');
103
+ }
104
+ }
105
+ catch {
106
+ blockers.push('visual.baseUrl must be a valid URL');
107
+ }
108
+ }
109
+ if (!config.specPath) {
110
+ blockers.push('visual.specPath is required');
111
+ }
112
+ else if (!existsSync(this.resolvePath(config.specPath))) {
113
+ blockers.push(`visual spec does not exist: ${config.specPath}`);
114
+ }
115
+ if (!config.routes || config.routes.length === 0) {
116
+ blockers.push('visual.routes must contain at least one route');
117
+ }
118
+ if (!config.reportPath) {
119
+ blockers.push('visual report path is required');
120
+ }
121
+ else if (!existsSync(this.resolvePath(config.reportPath))) {
122
+ blockers.push(`visual report does not exist: ${config.reportPath}`);
123
+ }
124
+ return { blockers };
125
+ }
126
+ resolvePath(path) {
127
+ return isAbsolute(path) ? path : join(this.projectDir, ...path.split('/'));
128
+ }
129
+ result(input) {
130
+ return {
131
+ gate: this.stage,
132
+ status: input.status,
133
+ passed: input.passed,
134
+ evidence: textEvidence(input.evidenceItems),
135
+ evidenceItems: input.evidenceItems,
136
+ blockers: input.blockers,
137
+ durationMs: Date.now() - input.start,
138
+ };
139
+ }
140
+ }
141
+ function normalizeFindings(findings) {
142
+ return findings.map(finding => ({
143
+ ...finding,
144
+ severity: normalizeSeverity(finding.severity),
145
+ }));
146
+ }
147
+ function normalizeSeverity(severity) {
148
+ const normalized = severity.toLowerCase();
149
+ if (normalized === 'critical' || normalized === 'high' || normalized === 'medium' || normalized === 'low') {
150
+ return normalized;
151
+ }
152
+ return 'medium';
153
+ }
154
+ function renderFindingSummary(findings, screenshotCount) {
155
+ if (findings.length === 0) {
156
+ return `No visual findings. screenshots=${screenshotCount}`;
157
+ }
158
+ const lines = findings.map(finding => {
159
+ const route = finding.route ? ` route=${finding.route}` : '';
160
+ const evidence = finding.evidence ? ` evidence=${finding.evidence}` : '';
161
+ return `[${finding.severity}]${route} ${finding.message}${evidence}`;
162
+ });
163
+ return `screenshots=${screenshotCount}; findings=${findings.length}\n${lines.join('\n')}`;
164
+ }
165
+ function createEvidence(input) {
166
+ return {
167
+ id: `EVID-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
168
+ ...input,
169
+ };
170
+ }
171
+ function textEvidence(items) {
172
+ return items.map(item => `${item.label}: ${item.detail}`).join('\n');
173
+ }
174
+ //# sourceMappingURL=VisualGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualGate.js","sourceRoot":"","sources":["../../../src/workflow/gates/VisualGate.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export * from './types.js';
2
2
  export * from './gates/GateSystem.js';
3
+ export * from './gates/VisualGate.js';
3
4
  export * from './quality/HonestDelivery.js';
4
5
  export * from './quality/KarpathyEvaluator.js';
5
6
  export * from './cognitive/AmbiguityScorer.js';
@@ -1,6 +1,7 @@
1
1
  // SCALE Engine - Workflow Module Index
2
2
  export * from './types.js';
3
3
  export * from './gates/GateSystem.js';
4
+ export * from './gates/VisualGate.js';
4
5
  export * from './quality/HonestDelivery.js';
5
6
  export * from './quality/KarpathyEvaluator.js';
6
7
  export * from './cognitive/AmbiguityScorer.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workflow/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,cAAc,YAAY,CAAA;AAC1B,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workflow/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAEvC,cAAc,YAAY,CAAA;AAC1B,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,mCAAmC,CAAA;AACjD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA"}
@@ -1,4 +1,4 @@
1
- export type GateStage = 'G0' | 'G1' | 'G2' | 'G3' | 'G4' | 'G5' | 'G6' | 'G7' | 'G8';
1
+ export type GateStage = 'G0' | 'G1' | 'G2' | 'G3' | 'G4' | 'G5' | 'G6' | 'G7' | 'G8' | 'G9' | 'G10' | 'G11' | 'G12' | 'G13' | 'G14' | 'G15';
2
2
  export type GateStatus = 'PENDING' | 'PASSED' | 'FAILED' | 'BLOCKED';
3
3
  export type ModelTier = 'LOW' | 'MEDIUM' | 'HIGH';
4
4
  export type Verdict = 'APPROVE' | 'ITERATE' | 'REJECT';
@@ -18,6 +18,11 @@ export interface GateEvidence {
18
18
  stdoutTail?: string;
19
19
  stderrTail?: string;
20
20
  outputHash?: string;
21
+ rawEstimatedTokens?: number;
22
+ compressedEstimatedTokens?: number;
23
+ savedEstimatedTokens?: number;
24
+ compressionRatio?: number;
25
+ commandRunEvidenceId?: string;
21
26
  source?: string;
22
27
  }
23
28
  export interface GateResult {
@@ -0,0 +1,87 @@
1
+ # Active Security And Visual Gates
2
+
3
+ SCALE V2 adds two optional verification layers for projects that can provide a runnable local target:
4
+
5
+ - `ActiveRedTeam`: bounded dynamic security probes for configured HTTP targets.
6
+ - `VisualGate`: structured visual review evidence for UI routes and UI specs.
7
+
8
+ Both are conditional. A library or backend project with no runtime target should not pay the cost.
9
+
10
+ ## Active Security
11
+
12
+ Active security is configured under `.scale/verification.json`:
13
+
14
+ ```json
15
+ {
16
+ "security": {
17
+ "active": {
18
+ "enabled": true,
19
+ "baseUrl": "http://localhost:3000",
20
+ "startCommand": "npm run dev",
21
+ "targets": ["/api/login", "/api/users"],
22
+ "timeoutMs": 5000,
23
+ "maxRequests": 20
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ Behavior:
30
+
31
+ - missing or disabled config returns `SKIPPED`
32
+ - invalid enabled config returns `FAILED` before sending probes
33
+ - probes are capped by `maxRequests`
34
+ - every request has a timeout
35
+ - reflected probe payloads are `HIGH` findings and block
36
+ - request errors and server errors are recorded as findings, but only configured blocker severity should fail the gate
37
+
38
+ The first implementation exposes `runActiveRedTeam()` as a library API. It does not start a server by itself yet. CLI orchestration can wire `startCommand` later, but startup failure must become a `FAILED` result when that runner is added.
39
+
40
+ ## Visual Gate
41
+
42
+ Visual verification is configured under `.scale/verification.json`:
43
+
44
+ ```json
45
+ {
46
+ "visual": {
47
+ "enabled": true,
48
+ "baseUrl": "http://localhost:5173",
49
+ "specPath": "docs/ui/UI-SPEC.md",
50
+ "routes": ["/", "/settings"],
51
+ "reportPath": "docs/worklog/tasks/TASK-123/visual-report.json",
52
+ "blockingSeverities": ["critical", "high"]
53
+ }
54
+ }
55
+ ```
56
+
57
+ `VisualGate` consumes a structured report:
58
+
59
+ ```json
60
+ {
61
+ "screenshots": [
62
+ { "route": "/", "path": "screenshots/home.png" }
63
+ ],
64
+ "findings": [
65
+ {
66
+ "severity": "high",
67
+ "route": "/",
68
+ "message": "Primary action overlaps the navigation bar.",
69
+ "evidence": "overlap ratio 0.42"
70
+ }
71
+ ]
72
+ }
73
+ ```
74
+
75
+ Behavior:
76
+
77
+ - missing or disabled config passes with a `Visual gate skipped` evidence item
78
+ - enabled config requires `baseUrl`, `specPath`, `routes`, and `reportPath`
79
+ - missing or invalid visual report fails
80
+ - default blockers are `critical` and `high`
81
+ - VLM comments may be recorded in the report, but the gate blocks only on structured severity thresholds
82
+
83
+ ## Gate Numbering
84
+
85
+ `VisualGate` uses `G9` when explicitly registered. It is not registered by default because meta governance also uses the G9-G15 range. Projects should register it only in UI verification profiles or dedicated task flows.
86
+
87
+ Active security remains a security sub-check instead of a fractional gate number. It belongs under the broader G7 security lifecycle when wired into a concrete workflow.
@@ -0,0 +1,62 @@
1
+ # Background Hunter
2
+
3
+ Background Hunter is the readonly proactive scan layer for SCALE Engine V2.
4
+ It turns existing governance signals into an actionable hunt queue without editing application code.
5
+
6
+ ## Boundary
7
+
8
+ Default behavior is intentionally conservative:
9
+
10
+ - scan only, no automatic code changes
11
+ - no automatic LLM repair
12
+ - no automatic commit or pull request
13
+ - no release bypass
14
+ - ignore decisions are explicit and written to `.scale/hunt/ignored-findings.json`
15
+
16
+ The hunter reuses existing checks instead of creating a second rule system. The first implementation consumes:
17
+
18
+ - `EngineeringStandards`
19
+ - `ReviewAnalyzer` when status and diff input are provided by callers
20
+
21
+ ## Commands
22
+
23
+ ```bash
24
+ scale hunt scan
25
+ scale hunt scan --json
26
+ scale hunt report
27
+ scale hunt diagnose <finding-id>
28
+ scale hunt ignore <finding-id> --reason "Accepted legacy debt tracked elsewhere"
29
+ ```
30
+
31
+ `hunt scan` and `hunt report` do not modify source files. They classify findings as `open` or `ignored`.
32
+
33
+ `hunt diagnose <finding-id>` creates a normal `DiagnosticLoop` from the finding. This keeps the debugging workflow evidence-first:
34
+
35
+ - reproducible command
36
+ - expected failure
37
+ - changed files
38
+ - verification commands
39
+ - hypotheses and cleanup checklist
40
+
41
+ `hunt ignore` records the finding id and stable fingerprint. The same finding will remain visible in the report as `ignored`, but it is removed from the open queue.
42
+
43
+ ## Finding Identity
44
+
45
+ Every finding gets:
46
+
47
+ - `id`: short deterministic SHA-256 id derived from the fingerprint
48
+ - `fingerprint`: stable source/rule/path/line/message tuple
49
+ - `source`: currently `engineering-standards` or `review-analyzer`
50
+ - `diagnosticInput`: ready-to-use `DiagnosticLoopInput`
51
+
52
+ This allows repeated scans to avoid noisy duplicates and lets teams explicitly accept or defer known debt.
53
+
54
+ ## Recommended Flow
55
+
56
+ 1. Run `scale hunt scan --json`.
57
+ 2. Triage open findings.
58
+ 3. For real issues, run `scale hunt diagnose <finding-id> --json`.
59
+ 4. Fix through the normal plan/TDD/verify workflow.
60
+ 5. For accepted legacy debt, run `scale hunt ignore <finding-id> --reason "..."`
61
+
62
+ Do not promote Background Hunter to automatic repair until the project has enough evidence that its findings are stable and low-noise.
@@ -7,11 +7,18 @@ This feature keeps SCALE from becoming its own context pollution source. It sepa
7
7
 
8
8
  ## Commands
9
9
 
10
- Report token cost by context category:
11
-
12
- ```bash
13
- scale context budget --json
14
- ```
10
+ Report token cost by context category:
11
+
12
+ ```bash
13
+ scale context budget --json
14
+ ```
15
+
16
+ Include provider-specific prompt cache policy:
17
+
18
+ ```bash
19
+ scale context budget --provider anthropic --json
20
+ scale context budget --provider openai --json
21
+ ```
15
22
 
16
23
  Write the report to `.scale/context-budget.json`:
17
24
 
@@ -64,7 +71,26 @@ scale governance roi \
64
71
  | `on-demand` | Domain docs and governance guides | Load only when task trigger matches |
65
72
  | `evidence` | Runtime evidence and task artifacts | Summarize and reference by path |
66
73
  | `archive` | Historical plans and old roadmap context | Do not load unless explicitly requested |
67
- | `generated` | HTML reports, screenshots, graph outputs, generated artifacts | Keep manifest-only by default |
74
+ | `generated` | HTML reports, screenshots, graph outputs, generated artifacts | Keep manifest-only by default |
75
+
76
+ ## Prompt Cache Policy
77
+
78
+ V2.0 adds a cache policy layer for stable context. The policy is intentionally conservative:
79
+
80
+ - `always` is cache-eligible by default because it contains stable entrypoint rules and governance source-of-truth config.
81
+ - `on-demand` is not cache-eligible by default because it changes with task intent and can break stable prefix reuse.
82
+ - `evidence`, `archive`, and `generated` are never cache-eligible by default.
83
+ - Unsupported providers still write usage evidence; they do not pretend to support prompt caching.
84
+
85
+ Provider behavior:
86
+
87
+ | Provider | Strategy | Usage fields |
88
+ | --- | --- | --- |
89
+ | Anthropic | `anthropic-ephemeral` | `cache_creation_input_tokens`, `cache_read_input_tokens` |
90
+ | OpenAI | `openai-automatic` | `prompt_tokens_details.cached_tokens` |
91
+ | Other | `usage-ledger-only` | normal input/output usage only |
92
+
93
+ The cache policy does not live in `ModelRouter`. `ModelRouter` selects a model; provider request builders or adapters apply provider-specific cache controls.
68
94
 
69
95
  ## Progressive Governance
70
96
 
@@ -0,0 +1,89 @@
1
+ # Dependency Audit
2
+
3
+ Dependency Audit is the G7 dependency sub-gate for SCALE Engine.
4
+ It adds supply-chain checks without introducing a separate gate number such as `G6.8`.
5
+
6
+ ## Scope
7
+
8
+ The auditor is intentionally bounded:
9
+
10
+ - reads `package-lock.json`
11
+ - audits direct dependencies by default
12
+ - supports `--changed-packages` for lockfile-diff workflows
13
+ - scans only selected package roots under `node_modules`
14
+ - caps package count and files per package
15
+ - does not contact the registry by default
16
+ - does not run install scripts
17
+
18
+ This keeps local verification usable while still catching high-risk dependency behavior.
19
+
20
+ ## Commands
21
+
22
+ ```bash
23
+ scale dependency audit
24
+ scale dependency audit --json
25
+ scale dependency audit --mode strict
26
+ scale dependency audit --changed-packages left-pad,@scope/tool --json
27
+ ```
28
+
29
+ The command exits non-zero when the active mode has blocking findings.
30
+
31
+ ## G7 Integration
32
+
33
+ `SecurityGate` now emits two first-class evidence sources:
34
+
35
+ - `built-in-security-scan`: source code security scan
36
+ - `dependency-audit`: dependency supply-chain scan
37
+
38
+ Both remain under `G7 Security`.
39
+
40
+ ## Policy
41
+
42
+ Policy lives at `.scale/security/dependency-policy.json`:
43
+
44
+ ```json
45
+ {
46
+ "version": 1,
47
+ "mode": "compatibility",
48
+ "maxPackages": 50,
49
+ "maxPackageFiles": 25,
50
+ "allowPackages": [],
51
+ "baselineFindings": []
52
+ }
53
+ ```
54
+
55
+ Modes:
56
+
57
+ - `compatibility`: blocks `CRITICAL`
58
+ - `strict`: blocks `CRITICAL` and `HIGH`
59
+ - `offline`: keeps local-only behavior; current offline findings follow compatibility blocking
60
+
61
+ Use `baselineFindings` for accepted legacy dependency risk:
62
+
63
+ ```json
64
+ {
65
+ "baselineFindings": [
66
+ {
67
+ "packageName": "legacy-tool",
68
+ "version": "1.2.3",
69
+ "ruleId": "dependency.install-script",
70
+ "reason": "Pinned and reviewed during migration window."
71
+ }
72
+ ]
73
+ }
74
+ ```
75
+
76
+ Prefer a baseline over `allowPackages` when only one finding is accepted. `allowPackages` suppresses all findings for that package.
77
+
78
+ ## Current Findings
79
+
80
+ The first implementation detects:
81
+
82
+ - install lifecycle scripts
83
+ - executable bin scripts
84
+ - deprecated packages from lockfile metadata
85
+ - dynamic code execution: `eval`, `new Function`
86
+ - shell execution patterns
87
+ - suspicious network access patterns
88
+
89
+ Future network-backed checks can add npm registry metadata and `npm audit --json` ingestion, but they should stay optional and evidence-backed.
@@ -0,0 +1,63 @@
1
+ # Evolution Shadow Mode
2
+
3
+ SCALE V2 keeps self-evolution useful without letting one-off failures become hard blockers too early.
4
+
5
+ ## Flow
6
+
7
+ ```text
8
+ Gate Failure
9
+ -> Defect
10
+ -> Lesson
11
+ -> Proposed Rule
12
+ -> Shadow Rule
13
+ -> Candidate Hook
14
+ -> Approved Blocking Hook
15
+ ```
16
+
17
+ ## Gate Failure To Defect
18
+
19
+ `GateSystem` emits `gate.failed` for failed gate results. `AutoDefectCreator` tracks consecutive failures per session and gate stage.
20
+
21
+ Default behavior:
22
+
23
+ - three consecutive failures create one `Defect`
24
+ - a passing `gate.executed` event resets the streak
25
+ - defect payload uses `rootCauseCategory=gate_failure`
26
+ - the original blockers, evidence, evidence record id, stage, and streak count are stored in defect context
27
+
28
+ This is evidence capture only. It does not change source code or generate a hook.
29
+
30
+ ## Rule Maturity
31
+
32
+ New rules start in `shadow` mode. Shadow rules can record hits, but they do not block development.
33
+
34
+ Promotion requires:
35
+
36
+ - shadow hits >= 10
37
+ - at least one defect evidence id
38
+ - rollback method present
39
+ - false positive rate within threshold
40
+ - explicit approval before a blocking hook is allowed
41
+
42
+ `RuleMaturity` exposes:
43
+
44
+ - `createShadowRuleMaturity`
45
+ - `recordShadowHit`
46
+ - `evaluateRulePromotion`
47
+ - `approveRuleMaturity`
48
+
49
+ ## Hook Boundary
50
+
51
+ `HookGenerator` still requires `rule.approved === true`.
52
+
53
+ For V2 rules that carry maturity metadata, it also requires:
54
+
55
+ ```text
56
+ rule.maturity.stage === "approved-blocking"
57
+ ```
58
+
59
+ That means proposed or shadow rules can be observed and improved, but cannot become blocking hooks until explicitly promoted.
60
+
61
+ ## Current Scope
62
+
63
+ This release slice wires the core library path and gate events. CLI approval commands and persistent rule-maturity storage can be added later without changing the safety model.
@@ -32,11 +32,27 @@ The dashboard reads existing local evidence:
32
32
 
33
33
  | Area | Source |
34
34
  | --- | --- |
35
- | Runtime evidence | `.scale/evidence/runtime/` |
36
- | Workflow eval | `.scale/evals/runs/` and `.scale/evals/failures/` |
37
- | Memory Brain | `.scale/memory/brain.sqlite` |
38
- | Resource Governance | workspace files plus `.scale/resource-policy.json` and `.scale/assets.json` |
39
- | HTML artifacts | task artifact manifests and rendered HTML files |
35
+ | Runtime evidence | `.scale/evidence/runtime/` |
36
+ | Workflow eval | `.scale/evals/runs/` and `.scale/evals/failures/` |
37
+ | Workflow metrics | `.scale/metrics/tasks.jsonl` |
38
+ | Gate evidence | `.scale/evidence/GATE-*.json` |
39
+ | Command runs | `.scale/evidence/command-runs/` |
40
+ | Model usage | `.scale/model-usage/usage.jsonl` |
41
+ | Memory Brain | `.scale/memory/brain.sqlite` |
42
+ | Resource Governance | workspace files plus `.scale/resource-policy.json` and `.scale/assets.json` |
43
+ | HTML artifacts | task artifact manifests and rendered HTML files |
44
+
45
+ ## Aggregated Metrics
46
+
47
+ V2.0 adds `MetricsAggregator` as the dashboard aggregation layer. It keeps the dashboard read-only and derives the following metrics from existing evidence:
48
+
49
+ - recent task count and first-pass rate
50
+ - average fix iterations
51
+ - gate failure distribution
52
+ - command output compression token savings
53
+ - model usage and prompt-cache savings
54
+
55
+ Each number must trace back to local JSON/JSONL evidence. If a source is absent, the dashboard reports zero rather than inventing values.
40
56
 
41
57
  ## Status Model
42
58