<!-- task=m-milestone-work-item-creation-sync/03+01,02_project_binding_checkout plan=1 tag=REVIEW_API -->

# Implementation Plan - REVIEW_API

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

구현 완료는 active `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운 뒤에만 성립한다. 검증을 실행하고, 실제 변경/출력을 기록하고, active 파일은 그대로 둔 채 리뷰 준비를 보고한다. 종료 처리, log rename, `complete.log`, archive 이동은 code-review 스킬 전용이다. 구현 중 사용자만 결정할 수 있는 범위 변경, 외부 환경/secret 준비, scope 충돌이 있으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 근거를 적고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하거나 `USER_REVIEW.md`를 만들지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 공백은 사용자 리뷰 요청이 아니다.

## 배경

1차 구현은 project sync config resolver와 순수 `CheckoutPlan` 타입을 추가했지만, work item task 생성 런타임 경로에서 workspace slot을 예약하지 않고 checkout plan도 task payload/metadata에 남기지 않는다. 따라서 `workspace-checkout` 완료 조건이 닫히지 않았다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 해당 섹션은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식을 따른다. 구현 에이전트는 직접 사용자 프롬프트를 만들지 않고, code-review가 사용자 리뷰 요청의 타당성과 실제 `USER_REVIEW.md` 작성을 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/milestone-work-item-creation-sync.md`
- Task ids:
  - `project-bind`: Plane-origin 생성 동기화가 project sync 설정을 통해 Plane project, git repository, 작업 workspace를 해석하도록 한다.
  - `workspace-checkout`: Git repository checkout 정책을 project sync 설정과 연결한다.
- Completion mode: check-on-pass

## 범위 결정 근거

- 실제 `git clone`, `git fetch`, `git checkout` 프로세스 실행은 여전히 범위 밖이다.
- 후속 범위는 1차 리뷰 Required 이슈 하나만 닫는다: project sync config, reserved workspace slot, checkout plan을 runtime task creation path에 연결하고 검증한다.
- 기존 predecessor `01_project_sync_store`, `02+01_workspace_slot_store`는 archive `complete.log`로 완료 근거가 확인됐다.

## 빌드 등급

- `cloud-G07`: storage-provided project sync/slot boundary를 pipeline, HTTP wiring, workflow task metadata에 연결하는 cross-boundary 보완이다. 실제 terminal checkout 실행은 제외하지만 런타임 task 계약과 테스트 범위를 안전하게 붙여야 한다.

## 구현 체크리스트

- [x] workitempipeline에 project sync setting ID와 workspace slot reservation을 포함한 runtime binding을 연결한다. 검증: config lookup 후 `ReserveWorkspaceSlot`가 setting ID로 호출되고, no config/no available slot/error는 task creation을 차단한다.
- [x] checkout plan을 reserved slot과 project sync config에서 만들어 task payload 또는 metadata에 기록한다. 검증: git remote/source branch는 project sync config에서, slot path/index는 reserved slot/checkout plan에서 나오며 같은 project는 config를 공유하고 slot은 독립 path를 기록한다.
- [x] Binding/checkout runtime 테스트를 추가/갱신한다.
- [x] `cd services/core && go test -count=1 ./internal/workitempipeline ./internal/http ./internal/projectsync`, `cd services/core && go test -count=1 ./...`, `git diff --check`를 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [REVIEW_API-1] Runtime slot reservation and checkout plan propagation

- 문제: `services/core/internal/workitempipeline/service.go`는 project sync config를 resolve/normalize하지만 workspace slot store를 호출하지 않는다. `services/core/internal/projectsync/checkout.go`의 `BuildCheckoutPlan`도 테스트에서만 호출된다. 따라서 생성된 workflow task에는 git remote, source branch, workspace root, slot path/index가 남지 않고 실제 작업 slot 독립성이 보장되지 않는다.
- 해결 방법:
  - `workitempipeline`에 narrow slot reserver 의존성을 추가한다. 예: `ReserveWorkspaceSlot(ctx, projectSyncSettingID int64) (db.WorkspaceSlot, error)` 또는 `projectsync.WorkspaceSlot`을 반환하는 adapter.
  - resolver가 project sync setting ID를 보존할 수 있게 한다. `projectsync.Config`에 ID를 추가하거나, pipeline 전용 resolved binding struct로 `SettingID`와 normalized config를 함께 반환한다.
  - `CreateTaskFromWorkItem`에서 config resolve/normalize 후 setting ID로 slot을 예약하고, `projectsync.SlotFromDBRecord`와 `projectsync.BuildCheckoutPlan`으로 checkout plan을 만든다.
  - checkout plan을 `workflow.CreateTaskInput.Metadata` 또는 payload에 안정적인 JSON 계약으로 기록한다. 최소 필드는 project sync setting ID, workspace ID, git remote URL, source branch, project workspace root, slot ID, slot index, slot path다.
  - `storage.ErrNoAvailableWorkspaceSlot` 등 reservation 실패는 workflow task creation 전에 반환하고 HTTP error mapping을 추가/검증한다.
- 수정 파일 및 체크리스트:
  - [x] `services/core/internal/workitempipeline/service.go`
  - [x] `services/core/internal/workitempipeline/service_test.go`
  - [x] `services/core/internal/http/handlers.go`
  - [x] `services/core/internal/http/handlers_test.go`
  - [x] `services/core/cmd/server/main.go` (binder wiring; signature 변경 반영)
  - [x] 필요한 경우 `services/core/internal/projectsync/config.go`, `services/core/internal/projectsync/checkout.go`, 관련 tests → 기존 `CheckoutPlan`/`BuildCheckoutPlan` 재사용으로 추가 수정 불필요
- 테스트 작성:
  - same project tickets: 같은 setting/config remote와 workspace root를 기록하되 reserved slot index/path가 task metadata에 반영되는지 검증한다.
  - different project tickets: resolver가 반환한 project별 setting ID/config가 섞이지 않고 각각의 slot reservation으로 task metadata가 작성되는지 검증한다.
  - missing config, invalid config, no available slot, slot reservation DB error는 provider fetch/task creation 전에 차단되는지 검증한다.
  - HTTP handler는 project sync missing, resolver unconfigured, no available slot의 status mapping을 검증한다.
- 중간 검증:
  - `cd services/core && go test -count=1 ./internal/workitempipeline ./internal/http ./internal/projectsync`

## 최종 검증

```bash
cd services/core && go test -count=1 ./internal/workitempipeline ./internal/http ./internal/projectsync
cd services/core && go test -count=1 ./...
git diff --check
```

기대 결과: 모든 명령이 exit code 0. Go test cache output은 허용하지 않으므로 `-count=1`을 유지한다.

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