{
"meta": {
"agent": "planner",
"task_id": "352",
"title": "MT-8: Migrate InternalAdapterService from SignalResult to PhaseResult",
"created_at": "2026-04-08T22:10:00Z"
},
"inputs": [
{
"name": "issue-352",
"type": "context",
"ref": "https://github.com/AgentSDE/agent-core/issues/352",
"notes": "Phase 2 consumer migration — InternalAdapter adopts PhaseResult"
},
{
"name": "internal-adapter.service.ts",
"type": "file",
"ref": "src/internal-adapter/internal-adapter.service.ts",
"notes": "Contains SignalKind type and handleSignal dispatch logic (578 lines)"
},
{
"name": "internal-adapter.service.spec.ts",
"type": "file",
"ref": "src/internal-adapter/internal-adapter.service.spec.ts",
"notes": "Unit tests using SignalKind strings (631 lines)"
},
{
"name": "phase-router.service.ts",
"type": "file",
"ref": "src/phase-router/phase-router.service.ts",
"notes": "Contains toSignalKind() converter and 3 handleSignal call sites"
},
{
"name": "signal-result.ts",
"type": "file",
"ref": "src/invoke/signal-result.ts",
"notes": "Current SignalResult interface — will be superseded by PhaseResult from #346"
}
],
"outputs": [
{
"name": "plan",
"type": "spec",
"format": "md",
"content": "plan.md"
}
],
"files": [
{
"path": "src/internal-adapter/internal-adapter.service.ts",
"action": "modify",
"reason": "Remove SignalKind, update handleSignal to accept PhaseResult, rewrite dispatch logic"
},
{
"path": "src/internal-adapter/internal-adapter.service.spec.ts",
"action": "modify",
"reason": "Update all test cases to pass PhaseResult objects instead of SignalKind strings"
},
{
"path": "src/phase-router/phase-router.service.ts",
"action": "modify",
"reason": "Remove toSignalKind(), update 3 handleSignal call sites to pass PhaseResult"
},
{
"path": "src/internal-adapter/internal-adapter.module.ts",
"action": "inspect",
"reason": "Verify no SignalParser provider — already clean"
}
],
"steps": [
{
"id": "S1",
"summary": "Update handleSignal signature and dispatch logic in internal-adapter.service.ts — remove SignalKind, import PhaseResult, dispatch on result.status/blockedType with unrecognized-status fallback",
"acceptance": [
"No import of SignalKind, SignalResult, or SignalParser in any internal-adapter file",
"handleSignal(taskId, phase, result: PhaseResult) signature in place",
"Dispatch covers: complete, skip, blocked:transient, blocked:persistent, blocked:conflict",
"Unrecognized result.status logs warning and treated as blocked:transient"
],
"depends_on": []
},
{
"id": "S2",
"summary": "Update PhaseRouterService call sites — remove toSignalKind(), construct PhaseResult from SignalResult, update 3 handleSignal calls",
"acceptance": [
"toSignalKind() method removed from PhaseRouterService",
"All 3 handleSignal call sites pass PhaseResult objects",
"review_approved and worktree-failure paths construct valid PhaseResult"
],
"depends_on": [
"S1"
]
},
{
"id": "S3",
"summary": "Update all unit tests in internal-adapter.service.spec.ts to use PhaseResult objects and add unrecognized-status fallback test",
"acceptance": [
"All handleSignal calls in tests pass PhaseResult objects (no SignalKind strings)",
"New test: unrecognized status → blocked:transient fallback with warning log",
"tsc --noEmit passes",
"npm run test passes",
"npm run lint passes"
],
"depends_on": [
"S1"
]
}
],
"risks": [
{
"risk": "Blocked by #346 — PhaseResult type must exist",
"mitigation": "Do not start implementation until #346 merges; verify PhaseResult shape matches expected fields"
},
{
"risk": "Parallel merge conflict with #351 (PhaseRouter caller-side)",
"mitigation": "Coordinate merge order — #352 should merge after #351, or merge together in a stack"
}
],
"assumptions": [
"PhaseResult from #346 will have fields: status, blockedType, reason, retryAfter, conflictMetadata",
"internal-adapter.module.ts has no SignalParser provider (confirmed by inspection)",
"PhaseResult.status values will be: 'complete', 'skip', 'blocked' (matching current SignalType minus 'partial' and 'none')"
],
"open_questions": [
"How will 'partial' and 'none' SignalTypes map to PhaseResult.status? Currently treated as blocked:transient via toSignalKind() — should PhaseResult preserve these as distinct statuses or collapse them?"
]
}