AI Agents SDE Task Viewer
      • Context
      • Plan
      • Prd
  1. Home
  2. AgentSDE
  3. agent-core
  4. gh-444
  5. plan
  6. prd.json
prd.json(3.6 KB)· Apr 13, 2026
{
  "issueNumber": 444,
  "branchName": "feat/444-migrate-eventemitter2-to-eventbus",
  "generatedAt": "2026-04-13T12:00:00Z",
  "stories": [
    {
      "id": "S1",
      "title": "Round 1: Migrate task.updated — replace 4 emits in TaskStateService, 2 @OnEvent listeners in WsGatewayService and MetricsCache, update 3 modules and specs",
      "priority": 1,
      "dependsOn": [],
      "acceptanceCriteria": [
        "TaskStateService uses EventBusService.emit('task.updated') with try/catch at all 4 call sites",
        "WsGatewayService.onTaskUpdated registered via eventBus.on() in onModuleInit",
        "MetricsCache.invalidate registered via eventBus.on() in onModuleInit",
        "npm run build && npm run test pass"
      ],
      "passes": false,
      "completedAt": null
    },
    {
      "id": "S2",
      "title": "Round 2: Migrate task.stuck — replace 1 emit in WatchdogService, 1 @OnEvent in WsGatewayService, update module and specs",
      "priority": 2,
      "dependsOn": [
        "S1"
      ],
      "acceptanceCriteria": [
        "WatchdogService uses EventBusService.emit('task.stuck') with try/catch",
        "WsGatewayService.onTaskStuck registered via eventBus.on() in onModuleInit",
        "npm run build && npm run test pass"
      ],
      "passes": false,
      "completedAt": null
    },
    {
      "id": "S3",
      "title": "Round 3: Migrate artefacts.synced — replace 2 emits in PhaseRouterService, 1 @OnEvent in WsGatewayService, update module and specs",
      "priority": 3,
      "dependsOn": [
        "S2"
      ],
      "acceptanceCriteria": [
        "PhaseRouterService uses EventBusService.emit('artefacts.synced') with try/catch at both call sites",
        "WsGatewayService.onArtefactsSynced registered via eventBus.on() in onModuleInit",
        "npm run build && npm run test pass"
      ],
      "passes": false,
      "completedAt": null
    },
    {
      "id": "S4",
      "title": "Round 4: Migrate job.completed and job.failed — replace 2 emits in SqliteJobQueue, 2 @OnEvent in WsGatewayService, update module and specs",
      "priority": 4,
      "dependsOn": [
        "S3"
      ],
      "acceptanceCriteria": [
        "SqliteJobQueue uses EventBusService.emit() for job.completed and job.failed with try/catch",
        "WsGatewayService listeners registered via eventBus.on() in onModuleInit",
        "npm run build && npm run test pass"
      ],
      "passes": false,
      "completedAt": null
    },
    {
      "id": "S5",
      "title": "Round 5: Migrate job.created — replace self-trigger with direct processNext(), emit to Redis, remove @OnEvent, update specs",
      "priority": 5,
      "dependsOn": [
        "S4"
      ],
      "acceptanceCriteria": [
        "SqliteJobQueue calls void this.processNext() directly instead of emitting job.created",
        "Redis emit added for future multi-instance support",
        "@OnEvent('job.created') decorator removed from processNext()",
        "No EventEmitter2 import remains in SqliteJobQueue",
        "Job queue processes pending jobs end-to-end",
        "npm run build && npm run test pass"
      ],
      "passes": false,
      "completedAt": null
    },
    {
      "id": "S6",
      "title": "Round 6: Remove @nestjs/event-emitter — delete EventEmitterModule from all modules, uninstall package, verify clean removal",
      "priority": 6,
      "dependsOn": [
        "S5"
      ],
      "acceptanceCriteria": [
        "No EventEmitter2 or OnEvent imports in the codebase",
        "No EventEmitterModule.forRoot() calls in any module",
        "@nestjs/event-emitter removed from package.json",
        "npm run build && npm run test pass"
      ],
      "passes": false,
      "completedAt": null
    }
  ]
}
PlanPr description