<!-- task=m-external-integration/02+01_adapter_boundary plan=1 tag=REVIEW_TEST -->

# Adapter Boundary Follow-up Plan

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-local-G05.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 이 follow-up은 직전 리뷰의 Required 이슈 하나만 해소한다. code-review 전용 종결 절차는 실행하지 않는다. 사용자 결정이나 외부 환경이 필요한 차단만 `사용자 리뷰 요청`에 기록한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백은 사용자 리뷰 요청이 아니다.

## 배경

직전 리뷰에서 core 테스트는 통과했지만, 계획이 boundary check 대상으로 둔 `createPlaneTaskRequest`가 현재 checkout에 남아 있음이 확인됐다. 구현 기록에는 해당 grep이 no-output으로 적혀 있어 검증 신뢰도도 깨졌다. 이번 follow-up은 legacy Plane compatibility route를 유지하면서 내부 DTO/helper/test 명칭과 검증 기록을 boundary 조건에 맞게 정리한다.

## 사용자 리뷰 요청 흐름

구현 중 차단이 생기면 active `CODE_REVIEW-local-G05.md`의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 그 요청을 검증하고 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- Task ids:
  - `adapter-boundary`: 외부 provider별 구현 경계 점검
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/private/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-roadmap/current.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`
- `agent-ops/rules/project/domain/core/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/core-smoke.md`
- `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- `agent-task/m-external-integration/02+01_adapter_boundary/plan_local_G04_0.log`
- `agent-task/m-external-integration/02+01_adapter_boundary/code_review_local_G04_0.log`
- `agent-task/archive/2026/06/m-external-integration/01_provider_intake_registry/complete.log`
- `services/core/internal/http/handlers.go`
- `services/core/internal/http/router.go`
- `services/core/internal/http/handlers_test.go`
- `services/core/internal/workitem/provider.go`
- `services/core/internal/workitempipeline/service.go`
- `services/core/cmd/server/main.go`
- `services/core/README.md`
- `.gitignore`

### 테스트 환경 규칙

- test_env: `local`.
- `agent-test/local/rules.md`를 읽었고, core 변경이므로 `agent-test/local/core-smoke.md`를 적용한다.
- 필수 검증: `cd services/core && go test ./...`.
- 이 follow-up은 HTTP handler naming과 tests에 닿으므로 focused fresh test로 `cd services/core && go test -count=1 ./internal/http ./internal/workitem ./internal/workitempipeline`를 함께 실행한다.
- boundary evidence는 deterministic `rg --sort path` 명령으로 수집한다.

### 테스트 커버리지 공백

- legacy Plane compatibility route 동작과 generic provider route 동작은 `services/core/internal/http/handlers_test.go`가 커버한다.
- 이번 Required 이슈는 동작 실패가 아니라 boundary naming/evidence 실패다. 의미 있는 추가 behavior test보다 기존 test rename/update와 deterministic grep evidence가 필요하다.

### 심볼 참조

- 변경 대상 심볼:
  - `createPlaneTaskRequest`: `services/core/internal/http/handlers.go:95`, `services/core/internal/http/handlers.go:110`, `services/core/internal/http/handlers.go:177`, `services/core/internal/http/handlers_test.go:139`.
- `planeWorkItemTasks`, `jiraWorkItemTasks`는 현재 checkout에서 발견되지 않았다.

### 분할 판단

- 이 task는 기존 split subtask `m-external-integration/02+01_adapter_boundary`의 follow-up이다.
- predecessor index `01`은 기존 active plan이 `01_provider_intake_registry`로 구체화했고, `agent-task/archive/2026/06/m-external-integration/01_provider_intake_registry/complete.log`가 PASS임을 확인했다.
- broad index lookup에는 `01_plane_adapter`도 있어 index-only 증거는 모호하다. 이 follow-up은 새 predecessor를 선택하지 않고, 이미 선택된 active task와 명시 predecessor 경로를 유지한다.
- 추가 split은 불필요하다. 수정 범위는 HTTP handler/test naming과 재검증 기록으로 닫힌다.

### 범위 결정 근거

- 새 provider, 새 route, live adapter behavior를 추가하지 않는다.
- `/api/integrations/plane/tasks` compatibility route 자체와 Plane legacy JSON field names는 public backward compatibility로 유지할 수 있다.
- handler 내부 DTO/helper/test 이름은 provider-neutral compatibility naming으로 정리한다. 예외를 남길 경우에는 grep 조건과 review evidence가 일치하도록 명시한다.
- roadmap 문서는 수정하지 않는다. `m-<milestone-slug>` PASS completion event 처리는 runtime 책임이다.

### 빌드 등급

- build: `local-G05`, review: `local-G05`.
- 이유: Required 이슈는 명확하고 deterministic grep/test로 닫을 수 있지만, 직전 루프에서 verification trust가 실패했으므로 local grade를 한 단계 올린다.

## 구현 체크리스트

- [ ] `createPlaneTaskRequest`와 관련 helper/test 명칭을 provider-neutral compatibility naming으로 정리하고 legacy Plane JSON field compatibility는 유지한다.
- [ ] boundary grep checks를 재실행해 adapter import 검색은 no-output이고 `planeWorkItemTasks|jiraWorkItemTasks|createPlaneTaskRequest` 검색은 no-output임을 실제 stdout/stderr로 기록한다.
- [ ] `cd services/core && go test -count=1 ./internal/http ./internal/workitem ./internal/workitempipeline`, `cd services/core && go test ./...`, `git diff --check`를 통과시킨다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_TEST-1] Boundary Naming And Evidence Repair

문제: [services/core/internal/http/handlers.go](/config/workspace/nomadcode/services/core/internal/http/handlers.go:95)의 `createPlaneTaskRequest`가 boundary grep 조건을 위반하고, 직전 구현 기록은 이 명령을 no-output으로 잘못 기록했다.

해결 방법: legacy Plane compatibility handler는 유지하되 내부 request/helper/test 명칭을 provider-neutral compatibility naming으로 바꾼다. 예:

```go
// before
type createPlaneTaskRequest struct { ... }
func (input createPlaneTaskRequest) workItemRef() (workitem.Ref, error) { ... }

// after
type legacyWorkItemTaskRequest struct { ... }
func (input legacyWorkItemTaskRequest) workItemRef(provider workitem.ProviderID) (workitem.Ref, error) { ... }
```

수정 파일 및 체크리스트:

- [ ] `services/core/internal/http/handlers.go`: `createPlaneTaskRequest` 이름과 관련 method receiver를 provider-neutral compatibility naming으로 변경한다.
- [ ] `services/core/internal/http/handlers_test.go`: 관련 test name과 struct reference를 새 명칭으로 변경한다.
- [ ] legacy `/api/integrations/plane/tasks` JSON field names인 `workspace_slug`, `project_id`, `work_item_id`는 compatibility contract로 유지한다.

테스트 작성: 새 behavior test는 추가하지 않는다. 기존 route/test의 이름과 참조를 업데이트하고 기존 assertions를 유지한다.

중간 검증:

```bash
rg --sort path -n 'planeWorkItemTasks|jiraWorkItemTasks|createPlaneTaskRequest' services/core/internal/http services/core/cmd/server/main.go
cd services/core && go test -count=1 ./internal/http
```

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/internal/http/handlers.go` | REVIEW_TEST-1 |
| `services/core/internal/http/handlers_test.go` | REVIEW_TEST-1 |

## 최종 검증

```bash
rg --sort path -n 'internal/adapters/(plane|jira|mattermost)' services/core/internal/workflow services/core/internal/workitem services/core/internal/workitempipeline services/core/internal/http
rg --sort path -n 'planeWorkItemTasks|jiraWorkItemTasks|createPlaneTaskRequest' services/core/internal/http services/core/cmd/server/main.go
cd services/core && go test -count=1 ./internal/http ./internal/workitem ./internal/workitempipeline
cd services/core && go test ./...
git diff --check
```

두 `rg` 명령은 no-output exit code 1을 PASS evidence로 기록한다. `go test ./...`의 cached package는 허용하고, 변경 package는 `-count=1`로 fresh 실행한다.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
