AI Agents SDE Task Viewer
      • Context
      • Plan
      • Prd
  1. Home
  2. AgentSDE
  3. agent-core
  4. gh-444
  5. plan
  6. context.json
context.json(6.0 KB)· Apr 13, 2026
{
  "meta": {
    "agent": "planner",
    "task_id": "444",
    "title": "AW-8: Migrate EventEmitter2 events to EventBusService",
    "created_at": "2026-04-13T12:00:00Z"
  },
  "inputs": [
    {
      "name": "issue-444",
      "type": "context",
      "ref": "https://github.com/AgentSDE/agent-core/issues/444",
      "notes": "Full migration spec with 6 rounds"
    },
    {
      "name": "AGENTS.md",
      "type": "context",
      "ref": "AGENTS.md",
      "notes": "Codebase conventions and architecture"
    }
  ],
  "outputs": [
    {
      "name": "plan.md",
      "type": "plan",
      "format": "md",
      "content": "6-round incremental migration plan"
    }
  ],
  "files": [
    {
      "path": "src/task-state/task-state.service.ts",
      "action": "modify",
      "reason": "R1: Replace EventEmitter2 with EventBusService for task.updated emits"
    },
    {
      "path": "src/task-state/task-state.module.ts",
      "action": "modify",
      "reason": "R1: Import EventBusModule"
    },
    {
      "path": "src/ws-gateway/ws-gateway.service.ts",
      "action": "modify",
      "reason": "R1-4: Replace all @OnEvent decorators with eventBus.on() handlers"
    },
    {
      "path": "src/ws-gateway/ws-gateway.module.ts",
      "action": "modify",
      "reason": "R1+R6: Import EventBusModule, remove EventEmitterModule"
    },
    {
      "path": "src/metrics/metrics.cache.ts",
      "action": "modify",
      "reason": "R1: Replace @OnEvent with eventBus.on()"
    },
    {
      "path": "src/metrics/metrics.module.ts",
      "action": "modify",
      "reason": "R1: Import EventBusModule"
    },
    {
      "path": "src/watchdog/watchdog.service.ts",
      "action": "modify",
      "reason": "R2: Replace EventEmitter2 with EventBusService"
    },
    {
      "path": "src/watchdog/watchdog.module.ts",
      "action": "modify",
      "reason": "R2: Import EventBusModule"
    },
    {
      "path": "src/phase-router/phase-router.service.ts",
      "action": "modify",
      "reason": "R3: Replace EventEmitter2 with EventBusService"
    },
    {
      "path": "src/phase-router/phase-router.module.ts",
      "action": "modify",
      "reason": "R3: Import EventBusModule"
    },
    {
      "path": "src/queue/sqlite-job-queue.ts",
      "action": "modify",
      "reason": "R4-5: Migrate job events, replace self-trigger with direct call"
    },
    {
      "path": "src/queue/queue.module.ts",
      "action": "modify",
      "reason": "R4: Import EventBusModule"
    },
    {
      "path": "package.json",
      "action": "modify",
      "reason": "R6: Remove @nestjs/event-emitter"
    }
  ],
  "steps": [
    {
      "id": "S1",
      "summary": "Round 1: Migrate task.updated — replace 4 emits in TaskStateService, 2 @OnEvent listeners in WsGatewayService and MetricsCache, update 3 modules and specs",
      "acceptance": [
        "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"
      ],
      "depends_on": []
    },
    {
      "id": "S2",
      "summary": "Round 2: Migrate task.stuck — replace 1 emit in WatchdogService, 1 @OnEvent in WsGatewayService, update module and specs",
      "acceptance": [
        "WatchdogService uses EventBusService.emit('task.stuck') with try/catch",
        "WsGatewayService.onTaskStuck registered via eventBus.on() in onModuleInit",
        "npm run build && npm run test pass"
      ],
      "depends_on": [
        "S1"
      ]
    },
    {
      "id": "S3",
      "summary": "Round 3: Migrate artefacts.synced — replace 2 emits in PhaseRouterService, 1 @OnEvent in WsGatewayService, update module and specs",
      "acceptance": [
        "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"
      ],
      "depends_on": [
        "S2"
      ]
    },
    {
      "id": "S4",
      "summary": "Round 4: Migrate job.completed and job.failed — replace 2 emits in SqliteJobQueue, 2 @OnEvent in WsGatewayService, update module and specs",
      "acceptance": [
        "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"
      ],
      "depends_on": [
        "S3"
      ]
    },
    {
      "id": "S5",
      "summary": "Round 5: Migrate job.created — replace 3 self-trigger emits with direct void this.processNext(), also emit to Redis, remove @OnEvent from processNext(), update specs",
      "acceptance": [
        "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"
      ],
      "depends_on": [
        "S4"
      ]
    },
    {
      "id": "S6",
      "summary": "Round 6: Remove @nestjs/event-emitter — delete EventEmitterModule.forRoot() from all modules, npm uninstall, verify no remaining imports",
      "acceptance": [
        "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"
      ],
      "depends_on": [
        "S5"
      ]
    }
  ],
  "risks": [
    {
      "risk": "Round 5 job.created is pipeline-critical — broken self-trigger stops all phase execution",
      "mitigation": "Direct processNext() call is simpler than pub/sub; validate in test environment with E2E before merging"
    },
    {
      "risk": "AW-7 dependency — EventBusService must exist before any round begins",
      "mitigation": "Plan blocked until #443 merges; re-evaluate if AW-7 scope changes"
    }
  ],
  "assumptions": [
    "EventBusService from AW-7 (#443) exposes emit() and on() methods compatible with the migration pattern",
    "EventBusService is provided via an EventBusModule that can be imported per-consumer module",
    "Redis connection is available in all environments (dev, test, prod)"
  ],
  "open_questions": []
}
Plan