Skip to content

Commit 37ffeee

Browse files
author
Lalit
committed
Merge remote-tracking branch 'origin/main' into QCSD-agents
2 parents 7494076 + ee6b230 commit 37ffeee

File tree

26 files changed

+6355
-91
lines changed

26 files changed

+6355
-91
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "agentic-qe",
3-
"version": "3.3.1",
3+
"version": "3.3.2",
44
"description": "Agentic Quality Engineering V3 - Domain-Driven Design Architecture with 12 Bounded Contexts, O(log n) coverage analysis, ReasoningBank learning, 51 specialized QE agents, mathematical Coherence verification, deep Claude Flow integration",
55
"main": "./v3/dist/index.js",
66
"types": "./v3/dist/index.d.ts",

v3/CHANGELOG.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,52 @@ All notable changes to Agentic QE will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.3.2] - 2026-01-26
9+
10+
### 🎯 Highlights
11+
12+
**Automatic Dream Scheduling** - Dream Cycles are now actively triggered by QE agents instead of being passive-only. This upgrade brings QE v3 agent utilization to full capacity with cross-domain pattern consolidation.
13+
14+
### Added
15+
16+
#### DreamScheduler Service
17+
- **dream-scheduler.ts** - Central scheduling service for automatic dream cycles
18+
- Multiple trigger types:
19+
| Trigger | When | Duration | Priority |
20+
|---------|------|----------|----------|
21+
| `scheduled` | Every 1 hour (configurable) | 30s | Low |
22+
| `experience_threshold` | After 20 tasks accumulated | 10s | Medium |
23+
| `quality_gate_failure` | On quality gate failure | 5s (quick) | High |
24+
| `domain_milestone` | On domain milestone | 10s | Medium |
25+
| `manual` | On-demand API call | Configurable | Varies |
26+
27+
#### Cross-Domain Dream Integration
28+
- **EventBus integration** - `learning-optimization.dream.completed` event broadcasts insights
29+
- **TestGenerationCoordinator** - Subscribes to dream insights, auto-applies high-confidence patterns
30+
- **QualityAssessmentCoordinator** - Subscribes to dream insights for quality threshold tuning
31+
- **LearningOptimizationCoordinator** - Records task experiences, manages DreamScheduler lifecycle
32+
33+
#### New Tests (84 total)
34+
- `dream-scheduler.test.ts` (unit) - 38 tests for scheduler triggers, lifecycle, status
35+
- `dream-scheduler.test.ts` (integration) - 46 tests for full pipeline, cross-domain events
36+
37+
### Changed
38+
39+
- **LearningOptimizationCoordinator** - Now initializes and manages DreamScheduler
40+
- **interfaces.ts** - Added `publishDreamCycleCompleted()` method
41+
- **domain-events.ts** - Added `DreamCycleCompletedPayload` type
42+
43+
### Fixed
44+
45+
- **fix(coordination)**: Wire Queen-Domain direct task execution integration
46+
- **fix(learning)**: Close ReasoningBank integration gaps for full learning pipeline
47+
48+
### Documentation
49+
50+
- `DREAM_SCHEDULER_DESIGN.md` - Architecture design document with trigger specifications
51+
52+
---
53+
854
## [3.3.1] - 2026-01-25
955

1056
### 🎯 Highlights

v3/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

v3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@agentic-qe/v3",
3-
"version": "3.3.1",
3+
"version": "3.3.2",
44
"description": "Agentic QE v3 - Domain-Driven Design Architecture with 12 Bounded Contexts, O(log n) coverage analysis, ReasoningBank learning, 51 specialized QE agents",
55
"type": "module",
66
"main": "./dist/index.js",

v3/src/coordination/queen-coordinator.ts

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {
3131
DomainHealth,
3232
MemoryBackend,
3333
QEKernel,
34+
DomainTaskRequest,
35+
DomainTaskResult,
3436
} from '../kernel/interfaces';
3537
import {
3638
CrossDomainRouter,
@@ -1153,6 +1155,62 @@ export class QueenCoordinator implements IQueenCoordinator {
11531155
}
11541156
}
11551157

1158+
/**
1159+
* Handle task completion callback from domain plugin
1160+
* Queen-Domain Integration Fix: Direct task execution callback handler
1161+
*/
1162+
private async handleTaskCompletion(result: DomainTaskResult): Promise<void> {
1163+
const execution = this.tasks.get(result.taskId);
1164+
if (!execution) {
1165+
console.warn(`[Queen] Received completion for unknown task: ${result.taskId}`);
1166+
return;
1167+
}
1168+
1169+
// Update task status
1170+
const updated: TaskExecution = {
1171+
...execution,
1172+
status: result.success ? 'completed' : 'failed',
1173+
completedAt: new Date(),
1174+
result: result.data,
1175+
error: result.error,
1176+
};
1177+
this.tasks.set(result.taskId, updated);
1178+
1179+
// Update counters
1180+
if (result.success) {
1181+
this.tasksCompleted++;
1182+
this.taskDurations.push(result.duration);
1183+
1184+
// SEC-003: Log task completion
1185+
this.auditLogger.logComplete(result.taskId, execution.assignedAgents[0]);
1186+
} else {
1187+
this.tasksFailed++;
1188+
1189+
// SEC-003: Log task failure
1190+
this.auditLogger.logFail(result.taskId, execution.assignedAgents[0], result.error || 'Unknown error');
1191+
}
1192+
1193+
// CC-002: Decrement running task counter
1194+
this.runningTaskCounter = Math.max(0, this.runningTaskCounter - 1);
1195+
1196+
// Stop assigned agents
1197+
for (const agentId of execution.assignedAgents) {
1198+
await this.agentCoordinator.stop(agentId);
1199+
}
1200+
1201+
// Publish event
1202+
await this.publishEvent(result.success ? 'TaskCompleted' : 'TaskFailed', {
1203+
taskId: result.taskId,
1204+
domain: execution.assignedDomain,
1205+
result: result.data,
1206+
error: result.error,
1207+
duration: result.duration,
1208+
});
1209+
1210+
// Process queue for next task
1211+
await this.processQueue();
1212+
}
1213+
11561214
private async assignTask(task: QueenTask): Promise<Result<string, Error>> {
11571215
const targetDomains = task.targetDomains.length > 0
11581216
? task.targetDomains
@@ -1246,9 +1304,50 @@ export class QueenCoordinator implements IQueenCoordinator {
12461304
agentIds,
12471305
});
12481306

1249-
// Invoke domain API if available
1307+
// INTEGRATION FIX: Invoke domain plugin directly for task execution
12501308
if (this.domainPlugins) {
12511309
const plugin = this.domainPlugins.get(domain);
1310+
1311+
// Check if plugin supports direct task execution
1312+
if (plugin?.executeTask && plugin.canHandleTask?.(task.type)) {
1313+
// Build task request
1314+
const request: DomainTaskRequest = {
1315+
taskId: task.id,
1316+
taskType: task.type,
1317+
payload: task.payload,
1318+
priority: task.priority,
1319+
timeout: task.timeout,
1320+
correlationId: task.correlationId,
1321+
};
1322+
1323+
// Execute task with callback to handleTaskCompletion
1324+
const execResult = await plugin.executeTask(
1325+
request,
1326+
(result) => this.handleTaskCompletion(result)
1327+
);
1328+
1329+
if (!execResult.success) {
1330+
// Domain rejected task - update status and decrement counter
1331+
this.tasks.set(task.id, {
1332+
...execution,
1333+
status: 'failed',
1334+
error: execResult.error.message,
1335+
completedAt: new Date(),
1336+
});
1337+
this.runningTaskCounter = Math.max(0, this.runningTaskCounter - 1);
1338+
this.tasksFailed++;
1339+
1340+
// SEC-003: Log rejection
1341+
this.auditLogger.logFail(task.id, agentIds[0], execResult.error.message);
1342+
1343+
return err(execResult.error);
1344+
}
1345+
1346+
// Task accepted and running - will complete via callback
1347+
return ok(task.id);
1348+
}
1349+
1350+
// Fallback: Send event to plugin (for domains not yet updated)
12521351
if (plugin) {
12531352
try {
12541353
await plugin.handleEvent({
@@ -1259,8 +1358,10 @@ export class QueenCoordinator implements IQueenCoordinator {
12591358
correlationId: task.correlationId,
12601359
payload: { task },
12611360
});
1361+
console.warn(`[Queen] Domain ${domain} has no executeTask handler, using event fallback`);
12621362
} catch (error) {
12631363
// Log but don't fail - domain will handle via event bus
1364+
console.warn(`[Queen] Failed to invoke domain ${domain} event handler:`, error);
12641365
}
12651366
}
12661367
}
@@ -1481,12 +1582,20 @@ export class QueenCoordinator implements IQueenCoordinator {
14811582

14821583
/**
14831584
* Create a Queen Coordinator from a QE Kernel
1585+
*
1586+
* @param kernel - The QE Kernel instance
1587+
* @param router - Cross-domain event router
1588+
* @param protocolExecutor - Optional protocol executor for cross-domain protocols
1589+
* @param workflowExecutor - Optional workflow executor
1590+
* @param domainPlugins - Map of domain plugins for direct task execution (Integration Fix)
1591+
* @param config - Optional configuration overrides
14841592
*/
14851593
export function createQueenCoordinator(
14861594
kernel: QEKernel,
14871595
router: CrossDomainRouter,
14881596
protocolExecutor?: ProtocolExecutor,
14891597
workflowExecutor?: WorkflowExecutor,
1598+
domainPlugins?: Map<DomainName, DomainPlugin>,
14901599
config?: Partial<QueenConfig>
14911600
): QueenCoordinator {
14921601
return new QueenCoordinator(
@@ -1496,7 +1605,7 @@ export function createQueenCoordinator(
14961605
router,
14971606
protocolExecutor,
14981607
workflowExecutor,
1499-
undefined,
1608+
domainPlugins,
15001609
config
15011610
);
15021611
}

v3/src/domains/coverage-analysis/plugin.ts

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
* Plugin implementation for the microkernel architecture
44
*/
55

6-
import { DomainName, DomainEvent } from '../../shared/types';
6+
import { DomainName, DomainEvent, Result, ok, err } from '../../shared/types';
77
import { EventBus, MemoryBackend, DomainHealth } from '../../kernel/interfaces';
8-
import { BaseDomainPlugin } from '../domain-interface';
8+
import { BaseDomainPlugin, TaskHandler } from '../domain-interface';
99
import { TestExecutionEvents } from '../../shared/events';
1010
import { CoverageAnalysisAPI } from './interfaces';
1111
import { CoverageAnalysisCoordinator } from './coordinator';
@@ -55,6 +55,88 @@ export class CoverageAnalysisPlugin extends BaseDomainPlugin {
5555
return this.coordinator;
5656
}
5757

58+
// ============================================================================
59+
// Task Handlers (Queen-Domain Integration)
60+
// ============================================================================
61+
62+
/**
63+
* Get task handlers for direct Queen-Domain integration
64+
* Maps task types to coordinator methods
65+
*/
66+
protected override getTaskHandlers(): Map<string, TaskHandler> {
67+
return new Map([
68+
// Analyze coverage task - main task type for this domain
69+
['analyze-coverage', async (payload): Promise<Result<unknown, Error>> => {
70+
const coverageData = payload.coverageData as Parameters<CoverageAnalysisAPI['analyze']>[0]['coverageData'] | undefined;
71+
72+
if (!coverageData) {
73+
return err(new Error('Invalid analyze-coverage payload: missing coverageData'));
74+
}
75+
76+
this._activeAnalyses++;
77+
this.updateAgentMetrics();
78+
79+
try {
80+
return await this.coordinator.analyze({
81+
coverageData,
82+
threshold: payload.threshold as number | undefined,
83+
includeFileDetails: payload.includeFileDetails as boolean | undefined,
84+
});
85+
} finally {
86+
this._activeAnalyses--;
87+
this.updateAgentMetrics();
88+
}
89+
}],
90+
91+
// Detect gaps task
92+
['detect-gaps', async (payload): Promise<Result<unknown, Error>> => {
93+
const coverageData = payload.coverageData as Parameters<CoverageAnalysisAPI['detectGaps']>[0]['coverageData'] | undefined;
94+
95+
if (!coverageData) {
96+
return err(new Error('Invalid detect-gaps payload: missing coverageData'));
97+
}
98+
99+
this._activeAnalyses++;
100+
this.updateAgentMetrics();
101+
102+
try {
103+
return await this.coordinator.detectGaps({
104+
coverageData,
105+
minCoverage: payload.minCoverage as number | undefined,
106+
prioritize: payload.prioritize as 'risk' | 'size' | 'recent-changes' | undefined,
107+
});
108+
} finally {
109+
this._activeAnalyses--;
110+
this.updateAgentMetrics();
111+
}
112+
}],
113+
114+
// Calculate risk task
115+
['calculate-risk', async (payload): Promise<Result<unknown, Error>> => {
116+
const file = payload.file as string | undefined;
117+
const uncoveredLines = payload.uncoveredLines as number[] | undefined;
118+
119+
if (!file || !uncoveredLines) {
120+
return err(new Error('Invalid calculate-risk payload: missing file or uncoveredLines'));
121+
}
122+
123+
this._activeAnalyses++;
124+
this.updateAgentMetrics();
125+
126+
try {
127+
return await this.coordinator.calculateRisk({
128+
file,
129+
uncoveredLines,
130+
factors: payload.factors as Parameters<CoverageAnalysisAPI['calculateRisk']>[0]['factors'] | undefined,
131+
});
132+
} finally {
133+
this._activeAnalyses--;
134+
this.updateAgentMetrics();
135+
}
136+
}],
137+
]);
138+
}
139+
58140
// ============================================================================
59141
// Lifecycle Hooks
60142
// ============================================================================

0 commit comments

Comments
 (0)