agentic-qe 3.8.5 → 3.8.6
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/.claude/skills/skills-manifest.json +1 -1
- package/dist/cli/bundle.js +543 -543
- package/dist/coordination/mincut/phase-executor.d.ts +27 -0
- package/dist/coordination/mincut/phase-executor.js +70 -0
- package/dist/coordination/mincut/time-crystal-analysis.d.ts +35 -0
- package/dist/coordination/mincut/time-crystal-analysis.js +237 -0
- package/dist/coordination/mincut/time-crystal-persistence.d.ts +35 -0
- package/dist/coordination/mincut/time-crystal-persistence.js +81 -0
- package/dist/coordination/mincut/time-crystal-scheduling.d.ts +34 -0
- package/dist/coordination/mincut/time-crystal-scheduling.js +213 -0
- package/dist/coordination/mincut/time-crystal-types.d.ts +278 -0
- package/dist/coordination/mincut/time-crystal-types.js +67 -0
- package/dist/coordination/mincut/time-crystal.d.ts +8 -438
- package/dist/coordination/mincut/time-crystal.js +87 -905
- package/dist/learning/agent-routing.d.ts +53 -0
- package/dist/learning/agent-routing.js +142 -0
- package/dist/learning/embedding-utils.d.ts +34 -0
- package/dist/learning/embedding-utils.js +95 -0
- package/dist/learning/pattern-promotion.d.ts +63 -0
- package/dist/learning/pattern-promotion.js +187 -0
- package/dist/learning/pretrained-patterns.d.ts +14 -0
- package/dist/learning/pretrained-patterns.js +726 -0
- package/dist/learning/qe-reasoning-bank-types.d.ts +174 -0
- package/dist/learning/qe-reasoning-bank-types.js +24 -0
- package/dist/learning/qe-reasoning-bank.d.ts +9 -192
- package/dist/learning/qe-reasoning-bank.js +48 -1093
- package/dist/mcp/bundle.js +320 -320
- package/dist/shared/security/command-validator.js +2 -2
- package/dist/shared/security/input-sanitizer.js +1 -1
- package/dist/shared/security/path-traversal-validator.js +1 -1
- package/dist/shared/security/regex-safety-validator.js +7 -7
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Default Phase Executor
|
|
3
|
+
* ADR-032: Kuramoto CPG oscillators for self-sustaining scheduling
|
|
4
|
+
*
|
|
5
|
+
* Default implementation of the PhaseExecutor interface that simulates
|
|
6
|
+
* test execution. Replace with real test runner integration in production.
|
|
7
|
+
*/
|
|
8
|
+
import type { CPGTestPhase, CPGPhaseResult } from './kuramoto-cpg';
|
|
9
|
+
import type { PhaseExecutor } from './time-crystal-types';
|
|
10
|
+
/**
|
|
11
|
+
* Default phase executor that simulates test execution
|
|
12
|
+
* Replace with real test runner integration in production
|
|
13
|
+
*/
|
|
14
|
+
export declare class DefaultPhaseExecutor implements PhaseExecutor {
|
|
15
|
+
private readonly name;
|
|
16
|
+
private ready;
|
|
17
|
+
constructor(name?: string);
|
|
18
|
+
execute(phase: CPGTestPhase): Promise<CPGPhaseResult>;
|
|
19
|
+
isReady(): boolean;
|
|
20
|
+
getName(): string;
|
|
21
|
+
setReady(ready: boolean): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a default phase executor
|
|
25
|
+
*/
|
|
26
|
+
export declare function createDefaultPhaseExecutor(name?: string): DefaultPhaseExecutor;
|
|
27
|
+
//# sourceMappingURL=phase-executor.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Default Phase Executor
|
|
3
|
+
* ADR-032: Kuramoto CPG oscillators for self-sustaining scheduling
|
|
4
|
+
*
|
|
5
|
+
* Default implementation of the PhaseExecutor interface that simulates
|
|
6
|
+
* test execution. Replace with real test runner integration in production.
|
|
7
|
+
*/
|
|
8
|
+
import { secureRandom, secureRandomInt, secureRandomFloat } from '../../shared/utils/crypto-random.js';
|
|
9
|
+
/**
|
|
10
|
+
* Default phase executor that simulates test execution
|
|
11
|
+
* Replace with real test runner integration in production
|
|
12
|
+
*/
|
|
13
|
+
export class DefaultPhaseExecutor {
|
|
14
|
+
name;
|
|
15
|
+
ready = true;
|
|
16
|
+
constructor(name = 'default-executor') {
|
|
17
|
+
this.name = name;
|
|
18
|
+
}
|
|
19
|
+
async execute(phase) {
|
|
20
|
+
const startTime = Date.now();
|
|
21
|
+
// Simulate test execution with some variance
|
|
22
|
+
const basePassRate = phase.qualityThresholds.minPassRate;
|
|
23
|
+
const variance = (secureRandom() - 0.5) * 0.1; // ±5% variance
|
|
24
|
+
const actualPassRate = Math.min(1, Math.max(0, basePassRate + variance));
|
|
25
|
+
const testsRun = secureRandomInt(50, 150);
|
|
26
|
+
const testsPassed = Math.floor(testsRun * actualPassRate);
|
|
27
|
+
const testsFailed = testsRun - testsPassed;
|
|
28
|
+
// Simulate execution time with variance
|
|
29
|
+
const expectedDuration = phase.expectedDuration;
|
|
30
|
+
const durationVariance = (secureRandom() - 0.5) * 0.3; // ±15% variance
|
|
31
|
+
const actualDuration = Math.floor(expectedDuration * (1 + durationVariance));
|
|
32
|
+
// Simulate wait (scaled down for testing - use 1% of expected duration)
|
|
33
|
+
const simulatedWait = Math.min(100, actualDuration * 0.01);
|
|
34
|
+
await new Promise((resolve) => setTimeout(resolve, simulatedWait));
|
|
35
|
+
const flakyRatio = secureRandom() * phase.qualityThresholds.maxFlakyRatio;
|
|
36
|
+
const coverage = secureRandomFloat(phase.qualityThresholds.minCoverage, phase.qualityThresholds.minCoverage + 0.1);
|
|
37
|
+
const qualityMet = actualPassRate >= phase.qualityThresholds.minPassRate &&
|
|
38
|
+
flakyRatio <= phase.qualityThresholds.maxFlakyRatio &&
|
|
39
|
+
coverage >= phase.qualityThresholds.minCoverage;
|
|
40
|
+
return {
|
|
41
|
+
phaseId: phase.id,
|
|
42
|
+
phaseName: phase.name,
|
|
43
|
+
passRate: actualPassRate,
|
|
44
|
+
flakyRatio,
|
|
45
|
+
coverage: Math.min(1, coverage),
|
|
46
|
+
duration: Date.now() - startTime,
|
|
47
|
+
testsRun,
|
|
48
|
+
testsPassed,
|
|
49
|
+
testsFailed,
|
|
50
|
+
testsSkipped: 0,
|
|
51
|
+
qualityMet,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
isReady() {
|
|
55
|
+
return this.ready;
|
|
56
|
+
}
|
|
57
|
+
getName() {
|
|
58
|
+
return this.name;
|
|
59
|
+
}
|
|
60
|
+
setReady(ready) {
|
|
61
|
+
this.ready = ready;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a default phase executor
|
|
66
|
+
*/
|
|
67
|
+
export function createDefaultPhaseExecutor(name) {
|
|
68
|
+
return new DefaultPhaseExecutor(name);
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=phase-executor.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Time Crystal Analysis & Observation
|
|
3
|
+
* ADR-047: MinCut Self-Organizing QE Integration - Phase 4
|
|
4
|
+
*
|
|
5
|
+
* Pure functions for metrics collection, attractor detection,
|
|
6
|
+
* anomaly detection, phase prediction, and stabilization decisions.
|
|
7
|
+
*/
|
|
8
|
+
import type { ExecutionMetrics, TimeCrystalPhase, CrystalAnomaly, CrystalObservation, TemporalAttractor, StabilizationAction, TimeCrystalConfig } from './time-crystal-types';
|
|
9
|
+
import type { StrangeLoopController } from './strange-loop';
|
|
10
|
+
import type { MinCutHealthMonitor } from './mincut-health-monitor';
|
|
11
|
+
import type { TestFailureCausalGraph } from './causal-discovery';
|
|
12
|
+
/**
|
|
13
|
+
* Collect current execution metrics from available monitors
|
|
14
|
+
*/
|
|
15
|
+
export declare function collectMetrics(observations: CrystalObservation[], config: TimeCrystalConfig, healthMonitor?: MinCutHealthMonitor, strangeLoop?: StrangeLoopController): ExecutionMetrics;
|
|
16
|
+
/**
|
|
17
|
+
* Detect the current attractor state from metrics
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectAttractor(metrics: ExecutionMetrics, config: TimeCrystalConfig, healthMonitor?: MinCutHealthMonitor): TemporalAttractor;
|
|
20
|
+
/**
|
|
21
|
+
* Detect anomalies in the metrics
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectAnomalies(metrics: ExecutionMetrics, metricsHistory: ExecutionMetrics[], phases: Map<string, TimeCrystalPhase>, config: TimeCrystalConfig, causalGraph?: TestFailureCausalGraph): CrystalAnomaly[];
|
|
24
|
+
/**
|
|
25
|
+
* Predict the next phase based on observation history
|
|
26
|
+
*/
|
|
27
|
+
export declare function predictPhase(observations: CrystalObservation[], minObservationsForPattern: number): {
|
|
28
|
+
phase: string | undefined;
|
|
29
|
+
confidence: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Determine the stabilization action to move toward stable attractor
|
|
33
|
+
*/
|
|
34
|
+
export declare function determineStabilization(observations: CrystalObservation[], causalGraph?: TestFailureCausalGraph): StabilizationAction;
|
|
35
|
+
//# sourceMappingURL=time-crystal-analysis.d.ts.map
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Time Crystal Analysis & Observation
|
|
3
|
+
* ADR-047: MinCut Self-Organizing QE Integration - Phase 4
|
|
4
|
+
*
|
|
5
|
+
* Pure functions for metrics collection, attractor detection,
|
|
6
|
+
* anomaly detection, phase prediction, and stabilization decisions.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Collect current execution metrics from available monitors
|
|
10
|
+
*/
|
|
11
|
+
export function collectMetrics(observations, config, healthMonitor, strangeLoop) {
|
|
12
|
+
// Get health metrics if available
|
|
13
|
+
const health = healthMonitor?.getHealth();
|
|
14
|
+
// Get Strange Loop stats if available
|
|
15
|
+
const loopStats = strangeLoop?.getStats();
|
|
16
|
+
// Calculate throughput from recent observations
|
|
17
|
+
const recentObs = observations.slice(-10);
|
|
18
|
+
const recentMetrics = recentObs.map(o => o.metrics);
|
|
19
|
+
const avgTestCount = recentMetrics.length > 0
|
|
20
|
+
? recentMetrics.reduce((s, m) => s + m.testCount, 0) / recentMetrics.length
|
|
21
|
+
: 0;
|
|
22
|
+
const avgBuildDuration = recentMetrics.length > 0
|
|
23
|
+
? recentMetrics.reduce((s, m) => s + m.avgBuildDuration, 0) / recentMetrics.length
|
|
24
|
+
: 0;
|
|
25
|
+
// Estimate resource utilization from health status
|
|
26
|
+
let resourceUtilization = 0.5;
|
|
27
|
+
if (health) {
|
|
28
|
+
resourceUtilization = health.status === 'healthy' ? 0.6 :
|
|
29
|
+
health.status === 'warning' ? 0.8 : 0.95;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
timestamp: new Date(),
|
|
33
|
+
buildCount: loopStats?.totalCycles ?? 1,
|
|
34
|
+
successfulBuilds: loopStats?.successfulActions ?? 1,
|
|
35
|
+
testCount: Math.floor(avgTestCount * 1.1), // Slight increase for current window
|
|
36
|
+
testsPassed: Math.floor(avgTestCount * 0.9),
|
|
37
|
+
testsFailed: Math.floor(avgTestCount * 0.1),
|
|
38
|
+
avgBuildDuration: avgBuildDuration || 30000,
|
|
39
|
+
avgTestDuration: 5000,
|
|
40
|
+
resourceUtilization,
|
|
41
|
+
queueDepth: health?.weakVertexCount ?? 0,
|
|
42
|
+
throughput: avgTestCount / (config.observationIntervalMs / 60000),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Detect the current attractor state from metrics
|
|
47
|
+
*/
|
|
48
|
+
export function detectAttractor(metrics, config, healthMonitor) {
|
|
49
|
+
const passRate = metrics.testCount > 0
|
|
50
|
+
? metrics.testsPassed / metrics.testCount
|
|
51
|
+
: 1;
|
|
52
|
+
const buildSuccessRate = metrics.buildCount > 0
|
|
53
|
+
? metrics.successfulBuilds / metrics.buildCount
|
|
54
|
+
: 1;
|
|
55
|
+
// Get health info if available
|
|
56
|
+
const health = healthMonitor?.getHealth();
|
|
57
|
+
const healthFactor = health
|
|
58
|
+
? (health.status === 'healthy' ? 1 : health.status === 'warning' ? 0.7 : 0.3)
|
|
59
|
+
: 0.8;
|
|
60
|
+
// Combined stability score
|
|
61
|
+
const stabilityScore = (passRate * 0.4 + buildSuccessRate * 0.3 + healthFactor * 0.3);
|
|
62
|
+
if (stabilityScore >= config.stabilityThreshold) {
|
|
63
|
+
return 'stable';
|
|
64
|
+
}
|
|
65
|
+
else if (stabilityScore >= config.stabilityThreshold * 0.5) {
|
|
66
|
+
return 'degraded';
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return 'chaotic';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Detect anomalies in the metrics
|
|
74
|
+
*/
|
|
75
|
+
export function detectAnomalies(metrics, metricsHistory, phases, config, causalGraph) {
|
|
76
|
+
const anomalies = [];
|
|
77
|
+
// Check for throughput drop
|
|
78
|
+
if (metricsHistory.length >= 5) {
|
|
79
|
+
const recent = metricsHistory.slice(-5);
|
|
80
|
+
const older = metricsHistory.slice(-10, -5);
|
|
81
|
+
if (older.length >= 5) {
|
|
82
|
+
const recentAvg = recent.reduce((s, m) => s + m.throughput, 0) / recent.length;
|
|
83
|
+
const olderAvg = older.reduce((s, m) => s + m.throughput, 0) / older.length;
|
|
84
|
+
if (recentAvg < olderAvg * (1 - config.anomalySensitivity * 0.5)) {
|
|
85
|
+
anomalies.push({
|
|
86
|
+
type: 'throughput-drop',
|
|
87
|
+
severity: Math.min(1, (olderAvg - recentAvg) / olderAvg),
|
|
88
|
+
affected: [],
|
|
89
|
+
description: `Throughput dropped from ${olderAvg.toFixed(1)} to ${recentAvg.toFixed(1)} items/min`,
|
|
90
|
+
suggestion: 'Consider increasing parallelism or checking for resource contention',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Check for resource contention
|
|
96
|
+
if (metrics.resourceUtilization > 0.9) {
|
|
97
|
+
anomalies.push({
|
|
98
|
+
type: 'resource-contention',
|
|
99
|
+
severity: metrics.resourceUtilization,
|
|
100
|
+
affected: [],
|
|
101
|
+
description: `High resource utilization: ${(metrics.resourceUtilization * 100).toFixed(0)}%`,
|
|
102
|
+
suggestion: 'Reduce parallelism or scale up resources',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Check for cascade failures using causal graph
|
|
106
|
+
if (causalGraph) {
|
|
107
|
+
const recentFailures = causalGraph.getAllFailures()
|
|
108
|
+
.filter(f => Date.now() - f.timestamp.getTime() < config.phaseDetectionWindowMs);
|
|
109
|
+
if (recentFailures.length >= 5) {
|
|
110
|
+
// Check if failures are cascading
|
|
111
|
+
for (const failure of recentFailures.slice(0, 3)) {
|
|
112
|
+
const effects = causalGraph.getEffects(failure.id);
|
|
113
|
+
if (effects.length >= 3) {
|
|
114
|
+
anomalies.push({
|
|
115
|
+
type: 'cascade-failure',
|
|
116
|
+
severity: Math.min(1, effects.length / 10),
|
|
117
|
+
affected: [failure.testId, ...effects.map(e => e.testId)],
|
|
118
|
+
description: `Test ${failure.testName} is causing ${effects.length} cascading failures`,
|
|
119
|
+
suggestion: 'Isolate the root cause test and fix before continuing',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Check for phase drift
|
|
126
|
+
for (const [id, phase] of Array.from(phases.entries())) {
|
|
127
|
+
if (phase.executionCount >= 5 && phase.avgActualDuration > phase.expectedDuration * 1.5) {
|
|
128
|
+
anomalies.push({
|
|
129
|
+
type: 'phase-drift',
|
|
130
|
+
severity: Math.min(1, (phase.avgActualDuration - phase.expectedDuration) / phase.expectedDuration),
|
|
131
|
+
affected: [id],
|
|
132
|
+
description: `Phase ${phase.name} is taking ${((phase.avgActualDuration / phase.expectedDuration - 1) * 100).toFixed(0)}% longer than expected`,
|
|
133
|
+
suggestion: 'Review tests in this phase for performance issues',
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return anomalies;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Predict the next phase based on observation history
|
|
141
|
+
*/
|
|
142
|
+
export function predictPhase(observations, minObservationsForPattern) {
|
|
143
|
+
if (observations.length < minObservationsForPattern) {
|
|
144
|
+
return { phase: undefined, confidence: 0 };
|
|
145
|
+
}
|
|
146
|
+
// Analyze phase transition patterns
|
|
147
|
+
const transitions = new Map();
|
|
148
|
+
for (let i = 1; i < observations.length; i++) {
|
|
149
|
+
const prev = observations[i - 1].activePhases;
|
|
150
|
+
const curr = observations[i].activePhases;
|
|
151
|
+
for (const prevPhase of prev) {
|
|
152
|
+
for (const currPhase of curr) {
|
|
153
|
+
if (!transitions.has(prevPhase)) {
|
|
154
|
+
transitions.set(prevPhase, new Map());
|
|
155
|
+
}
|
|
156
|
+
const count = transitions.get(prevPhase).get(currPhase) || 0;
|
|
157
|
+
transitions.get(prevPhase).set(currPhase, count + 1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Find most likely next phase
|
|
162
|
+
const currentPhases = observations[observations.length - 1]?.activePhases || [];
|
|
163
|
+
let bestNext;
|
|
164
|
+
let bestCount = 0;
|
|
165
|
+
let totalCount = 0;
|
|
166
|
+
for (const currentPhase of currentPhases) {
|
|
167
|
+
const nextTransitions = transitions.get(currentPhase);
|
|
168
|
+
if (nextTransitions) {
|
|
169
|
+
for (const [next, count] of Array.from(nextTransitions.entries())) {
|
|
170
|
+
totalCount += count;
|
|
171
|
+
if (count > bestCount) {
|
|
172
|
+
bestCount = count;
|
|
173
|
+
bestNext = next;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const confidence = totalCount > 0 ? bestCount / totalCount : 0;
|
|
179
|
+
return { phase: bestNext, confidence };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Determine the stabilization action to move toward stable attractor
|
|
183
|
+
*/
|
|
184
|
+
export function determineStabilization(observations, causalGraph) {
|
|
185
|
+
const lastObs = observations[observations.length - 1];
|
|
186
|
+
if (!lastObs) {
|
|
187
|
+
return { type: 'no_action', reason: 'No observations available' };
|
|
188
|
+
}
|
|
189
|
+
// Handle chaotic state
|
|
190
|
+
if (lastObs.attractor === 'chaotic') {
|
|
191
|
+
// Find flaky tests to isolate
|
|
192
|
+
if (causalGraph) {
|
|
193
|
+
const rootCauses = [];
|
|
194
|
+
const failures = causalGraph.getAllFailures().slice(-20);
|
|
195
|
+
for (const failure of failures) {
|
|
196
|
+
const analyses = causalGraph.findRootCauses(failure.id);
|
|
197
|
+
for (const analysis of analyses) {
|
|
198
|
+
if (analysis.confidence > 0.7 && analysis.impact >= 3) {
|
|
199
|
+
rootCauses.push(analysis.rootCauseTest);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (rootCauses.length > 0) {
|
|
204
|
+
return {
|
|
205
|
+
type: 'isolate_flaky',
|
|
206
|
+
testIds: Array.from(new Set(rootCauses)),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Reduce parallelism to stabilize
|
|
211
|
+
return { type: 'reduce_parallelism', by: 2 };
|
|
212
|
+
}
|
|
213
|
+
// Handle degraded state
|
|
214
|
+
if (lastObs.attractor === 'degraded') {
|
|
215
|
+
const metrics = lastObs.metrics;
|
|
216
|
+
// Check for resource contention
|
|
217
|
+
if (metrics.resourceUtilization > 0.85) {
|
|
218
|
+
return { type: 'reduce_parallelism', by: 1 };
|
|
219
|
+
}
|
|
220
|
+
// Check for queue buildup
|
|
221
|
+
if (metrics.queueDepth > 10) {
|
|
222
|
+
return { type: 'throttle', durationMs: 5000 };
|
|
223
|
+
}
|
|
224
|
+
// Try warming caches
|
|
225
|
+
return {
|
|
226
|
+
type: 'warm_cache',
|
|
227
|
+
cacheKeys: ['test-deps', 'build-artifacts', 'node-modules'],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// System is stable - consider increasing parallelism if throughput is low
|
|
231
|
+
const metrics = lastObs.metrics;
|
|
232
|
+
if (metrics.resourceUtilization < 0.5 && metrics.throughput < 10) {
|
|
233
|
+
return { type: 'increase_parallelism', by: 1 };
|
|
234
|
+
}
|
|
235
|
+
return { type: 'no_action', reason: 'System is stable' };
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=time-crystal-analysis.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Time Crystal Persistence
|
|
3
|
+
* ADR-047: MinCut Self-Organizing QE Integration - Phase 4
|
|
4
|
+
*
|
|
5
|
+
* Standalone persistence functions for Time Crystal state snapshots.
|
|
6
|
+
* These operate on state passed as parameters rather than accessing class internals.
|
|
7
|
+
*/
|
|
8
|
+
import { type UnifiedMemoryManager } from '../../kernel/unified-memory.js';
|
|
9
|
+
import type { CrystalObservation, TimeCrystalPhase, ExecutionMetrics, TemporalAttractor } from './time-crystal-types';
|
|
10
|
+
/** Persist every N state changes */
|
|
11
|
+
export declare const PERSIST_INTERVAL = 20;
|
|
12
|
+
/**
|
|
13
|
+
* Snapshot shape persisted to / loaded from kv_store
|
|
14
|
+
*/
|
|
15
|
+
export interface TimeCrystalSnapshot {
|
|
16
|
+
observations: CrystalObservation[];
|
|
17
|
+
phases: [string, TimeCrystalPhase][];
|
|
18
|
+
metricsHistory: ExecutionMetrics[];
|
|
19
|
+
currentAttractor: TemporalAttractor;
|
|
20
|
+
stats: Record<string, unknown>;
|
|
21
|
+
savedAt: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Initialize kv_store persistence - returns the UnifiedMemoryManager or null on failure
|
|
25
|
+
*/
|
|
26
|
+
export declare function initializeTimeCrystalDb(): Promise<UnifiedMemoryManager | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Persist current state snapshot to kv_store
|
|
29
|
+
*/
|
|
30
|
+
export declare function persistTimeCrystalToKv(db: UnifiedMemoryManager, observations: CrystalObservation[], phases: Map<string, TimeCrystalPhase>, metricsHistory: ExecutionMetrics[], currentAttractor: TemporalAttractor, stats: Record<string, unknown>): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Load state snapshot from kv_store and return restored state (or null if no snapshot)
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadTimeCrystalFromKv(db: UnifiedMemoryManager): Promise<TimeCrystalSnapshot | null>;
|
|
35
|
+
//# sourceMappingURL=time-crystal-persistence.d.ts.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Time Crystal Persistence
|
|
3
|
+
* ADR-047: MinCut Self-Organizing QE Integration - Phase 4
|
|
4
|
+
*
|
|
5
|
+
* Standalone persistence functions for Time Crystal state snapshots.
|
|
6
|
+
* These operate on state passed as parameters rather than accessing class internals.
|
|
7
|
+
*/
|
|
8
|
+
import { getUnifiedMemory } from '../../kernel/unified-memory.js';
|
|
9
|
+
import { toErrorMessage } from '../../shared/error-utils.js';
|
|
10
|
+
/** kv_store namespace for time crystal metrics */
|
|
11
|
+
const KV_NAMESPACE = 'time-crystal-metrics';
|
|
12
|
+
/** kv_store key for the state snapshot */
|
|
13
|
+
const KV_KEY = 'time-crystal-snapshot';
|
|
14
|
+
/** TTL for persisted snapshots (24 hours) */
|
|
15
|
+
const KV_TTL = 86400;
|
|
16
|
+
/** Persist every N state changes */
|
|
17
|
+
export const PERSIST_INTERVAL = 20;
|
|
18
|
+
/**
|
|
19
|
+
* Initialize kv_store persistence - returns the UnifiedMemoryManager or null on failure
|
|
20
|
+
*/
|
|
21
|
+
export async function initializeTimeCrystalDb() {
|
|
22
|
+
try {
|
|
23
|
+
const db = getUnifiedMemory();
|
|
24
|
+
if (!db.isInitialized())
|
|
25
|
+
await db.initialize();
|
|
26
|
+
return db;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.warn('[TimeCrystalController] DB init failed, using memory-only:', toErrorMessage(error));
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Persist current state snapshot to kv_store
|
|
35
|
+
*/
|
|
36
|
+
export async function persistTimeCrystalToKv(db, observations, phases, metricsHistory, currentAttractor, stats) {
|
|
37
|
+
const snapshot = {
|
|
38
|
+
observations: observations.slice(-100),
|
|
39
|
+
phases: Array.from(phases.entries()),
|
|
40
|
+
metricsHistory: metricsHistory.slice(-100),
|
|
41
|
+
currentAttractor,
|
|
42
|
+
stats,
|
|
43
|
+
savedAt: Date.now(),
|
|
44
|
+
};
|
|
45
|
+
await db.kvSet(KV_KEY, snapshot, KV_NAMESPACE, KV_TTL);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Load state snapshot from kv_store and return restored state (or null if no snapshot)
|
|
49
|
+
*/
|
|
50
|
+
export async function loadTimeCrystalFromKv(db) {
|
|
51
|
+
const snapshot = await db.kvGet(KV_KEY, KV_NAMESPACE);
|
|
52
|
+
if (!snapshot)
|
|
53
|
+
return null;
|
|
54
|
+
// Convert Date strings back to Date objects in observations
|
|
55
|
+
if (snapshot.observations?.length) {
|
|
56
|
+
snapshot.observations = snapshot.observations.map(obs => ({
|
|
57
|
+
...obs,
|
|
58
|
+
timestamp: new Date(obs.timestamp),
|
|
59
|
+
metrics: { ...obs.metrics, timestamp: new Date(obs.metrics.timestamp) },
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
// Convert Date strings in phases
|
|
63
|
+
if (snapshot.phases?.length) {
|
|
64
|
+
snapshot.phases = snapshot.phases.map(([key, phase]) => [
|
|
65
|
+
key,
|
|
66
|
+
{
|
|
67
|
+
...phase,
|
|
68
|
+
lastActivation: phase.lastActivation ? new Date(phase.lastActivation) : undefined,
|
|
69
|
+
},
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
// Convert Date strings in metrics history
|
|
73
|
+
if (snapshot.metricsHistory?.length) {
|
|
74
|
+
snapshot.metricsHistory = snapshot.metricsHistory.map(m => ({
|
|
75
|
+
...m,
|
|
76
|
+
timestamp: new Date(m.timestamp),
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
return snapshot;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=time-crystal-persistence.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Time Crystal Scheduling Algorithms
|
|
3
|
+
* ADR-047: MinCut Self-Organizing QE Integration - Phase 4
|
|
4
|
+
*
|
|
5
|
+
* Pure functions for computing optimal execution order, topological sorting,
|
|
6
|
+
* parallel execution groups, and schedule optimization decisions.
|
|
7
|
+
*/
|
|
8
|
+
import type { CrystalLattice, CrystalObservation, ScheduleOptimization } from './time-crystal-types';
|
|
9
|
+
import type { TestFailureCausalGraph } from './causal-discovery';
|
|
10
|
+
/**
|
|
11
|
+
* Compute optimal execution order based on priority and execution time
|
|
12
|
+
*/
|
|
13
|
+
export declare function computeOptimalOrder(lattice: CrystalLattice): string[];
|
|
14
|
+
/**
|
|
15
|
+
* Topological sort respecting dependencies (Kahn's algorithm)
|
|
16
|
+
*/
|
|
17
|
+
export declare function topologicalSort(nodeIds: string[], lattice: CrystalLattice): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Compute parallel execution groups respecting dependencies and conflicts
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeParallelGroups(lattice: CrystalLattice, maxParallelGroups: number): string[][];
|
|
22
|
+
/**
|
|
23
|
+
* Check if two execution orders differ significantly (>20% positions changed)
|
|
24
|
+
*/
|
|
25
|
+
export declare function ordersDiffer(a: string[], b: string[]): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Determine the optimal schedule optimization action
|
|
28
|
+
*/
|
|
29
|
+
export declare function determineOptimization(lattice: CrystalLattice, observations: CrystalObservation[], causalGraph: TestFailureCausalGraph | undefined, maxParallelGroups: number): ScheduleOptimization;
|
|
30
|
+
/**
|
|
31
|
+
* Rebuild lattice from a causal graph's failure data
|
|
32
|
+
*/
|
|
33
|
+
export declare function rebuildLatticeFromCausalGraph(lattice: CrystalLattice, causalGraph: TestFailureCausalGraph, maxParallelGroups: number): void;
|
|
34
|
+
//# sourceMappingURL=time-crystal-scheduling.d.ts.map
|