Plan: Migrate InternalAdapterService from SignalResult to PhaseResult#
Summary#
Replace the SignalKind string union and handleSignal(taskId, phase, signal: SignalKind, output?) signature with handleSignal(taskId, phase, result: PhaseResult) so the internal adapter consumes the normalized PhaseResult type directly — eliminating the lossy toSignalKind() conversion in PhaseRouterService and removing all SignalKind/SignalParser references from the internal-adapter module.
Files#
| File | Action | Description |
|---|---|---|
src/internal-adapter/internal-adapter.service.ts | modify | Remove SignalKind type, update handleSignal to accept PhaseResult, dispatch on result.status/result.blockedType, read result.reason/result.retryAfter/result.conflictMetadata |
src/internal-adapter/internal-adapter.module.ts | inspect | Verify no SignalParser provider — currently clean, no change needed |
src/internal-adapter/internal-adapter.service.spec.ts | modify | Rewrite all handleSignal calls to pass PhaseResult objects instead of SignalKind strings |
src/phase-router/phase-router.service.ts | modify | Remove toSignalKind() method, pass SignalResult→PhaseResult mapping directly to handleSignal, update all call sites |
Steps#
- Import
PhaseResultand updatehandleSignalsignature ininternal-adapter.service.ts— removeSignalKindtype export, importPhaseResultfrom#346's type location, change signature tohandleSignal(taskId: number, phase: string, result: PhaseResult). - Rewrite dispatch logic in
handleSignal— switch onresult.status(complete,skip,blocked) withresult.blockedTypesub-dispatch (transient,persistent,conflict). Passresult.reasonto handlers instead of the oldoutputparameter. Add fallback: unrecognizedresult.statuslogs a warning and is treated asblocked:transient. - Update handler methods —
handleComplete/handleSkip/handleTransientBlock/handlePersistentBlock/handleConflictBlockto read fields fromPhaseResult(reason,retryAfter,conflictMetadata) instead of the genericoutputstring. - Update
PhaseRouterServicecall sites — removetoSignalKind()private method, constructPhaseResultfrom the existingSignalResultfields, pass it tohandleSignal. Update the 3 directhandleSignalcalls (review_approved, worktree failure, post-invocation). - Update all unit tests in
internal-adapter.service.spec.ts— replace everyhandleSignal(id, phase, 'COMPLETE', output)call withhandleSignal(id, phase, { status: 'complete', reason: '...' })PhaseResult objects. Add a test for unrecognizedstatus→blocked:transientfallback.
Verification#
tsc --noEmitpasses with noSignalKindorSignalParserimports insrc/internal-adapter/npm run test— all existing dispatch behavior preserved, new unrecognized-status test passesnpm run lint— zero warnings
Risks#
- Blocked by #346 —
PhaseResulttype must exist before implementation starts. If #346'sPhaseResultshape differs from what the issue describes (status/blockedType/reason/retryAfter/conflictMetadata), the dispatch mapping will need adjustment. - Parallel merge with #351 — #351 modifies
PhaseRouterServicecaller side. Merge order matters; coordinate to avoid a broken intermediate state wherehandleSignalexpectsPhaseResultbut callers still passSignalKind.