<!-- task=m-milestone-work-item-creation-sync/01_workspace_topology plan=0 tag=API -->

# Plan - API Workspace Topology

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

`CODE_REVIEW-local-G06.md`의 구현 에이전트 소유 섹션을 반드시 채운다. 검증 명령을 실행하고 실제 출력과 구현 메모를 남긴 뒤 active 파일을 유지한 채 리뷰 준비를 보고한다. 사용자 전용 결정, 사용자 소유 외부 환경, 범위 충돌로 막히면 review stub의 `사용자 리뷰 요청`에 근거를 기록하고 멈춘다. 구현 중 사용자에게 직접 질문하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행으로 닫을 수 있는 증거 공백은 사용자 리뷰 요청이 아니다.

## 배경

현재 Milestone은 `branches/main`, `branches/develop`, `slots/000+`를 분리해야 한다. 방금 `SlotWorkspacePath`는 `root/slots/NNN`으로 바로 수정했지만 branch workspace helper, branch sync state, checkout/provision policy는 아직 코드에 없다. 이 plan은 `cycle-workspace-topology` 완료에 필요한 남은 topology foundation만 닫는다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식으로 active review stub의 `사용자 리뷰 요청`에 기록한다. 직접 사용자 프롬프트는 금지이며, 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:
  - `cycle-workspace-topology`: project workspace root 아래 `branches/main`, `branches/develop`, `slots/000+` 구조를 준비하고 branch workspace와 agent slot 상태를 분리한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/domain/core/rules.md`
- `agent-ops/rules/project/domain/workspace-ops/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/core-smoke.md`
- `agent-test/local/workspace-ops-smoke.md`
- `agent-roadmap/current.md`
- `agent-roadmap/phase/agent-ops-mcp-control-plane/PHASE.md`
- `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/milestone-work-item-creation-sync.md`
- `services/core/internal/projectsync/config.go`
- `services/core/internal/projectsync/config_test.go`
- `services/core/internal/projectsync/checkout.go`
- `services/core/internal/projectsync/checkout_test.go`
- `services/core/internal/workitempipeline/service.go`
- `services/core/internal/workitempipeline/service_test.go`
- `services/core/internal/http/handlers_test.go`
- `services/core/internal/storage/workspace_slots.go`
- `services/core/internal/storage/workspace_slots_test.go`

### 테스트 환경 규칙

- test_env: `local`.
- `agent-test/local/rules.md` 읽음. core 변경은 `cd services/core && go test ./...`가 필수다.
- matched profiles: `agent-test/local/core-smoke.md`, `agent-test/local/workspace-ops-smoke.md`.
- 적용 명령: `cd services/core && go test ./...`, 문서/plan 변경 preflight로 `git diff --check`.
- `<확인 필요>` 값 없음. shell helper 변경이 아니므로 `bash -n bin/test bin/lint bin/build bin/dev`는 제외한다.

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

- branch workspace path/state helper는 새 단위 테스트가 필요하다.
- workspace provision policy는 실제 git clone/fetch를 실행하지 않는 policy object와 fake executor 테스트로 한정한다. 실제 remote checkout e2e는 이번 plan 범위에서 제외한다.

### 심볼 참조

- renamed/removed symbols: none.

### 분할 판단

- split decision policy를 평가했다.
- shared task group: `agent-task/m-milestone-work-item-creation-sync/`.
- `01_workspace_topology`: 독립 선행 foundation, dependencies: none.
- `02+01_iop_authoring_bridge`: predecessor `01` missing.
- `03+02_develop_match`: predecessor `02` missing.
- `04+03_plane_todo_projection`: predecessor `03` missing.
- `05+03,04_idempotency_retry`: predecessors `03`, `04` missing.

### 범위 결정 근거

- IOP `/v1/responses` 호출, authoring run 상태 저장, Plane projection, identity map migration은 후속 split plan으로 제외한다.
- 실제 git process 실행과 원격 push는 deterministic unit test로 다루기 어렵고 다음 단계 authoring/sync와 결합되므로 이번 plan에서는 interface와 policy 검증까지만 포함한다.

### 빌드 등급

- build: `local-G06`. core package 경계가 작고 테스트로 검증 가능하지만 후속 split의 foundation이라 보수적으로 G06으로 둔다.

## 구현 체크리스트

- [ ] branch workspace path helper와 branch sync state 타입을 추가하고 `main`, `develop` 고정 workspace를 agent slot과 분리한다.
- [ ] checkout/provision policy가 `branches/main`, `branches/develop`, 최소 `slots/000` 준비 계획을 만들고 missing workspace를 임의 cwd로 대체하지 않도록 오류를 반환한다.
- [ ] work item pipeline checkout metadata 또는 project sync metadata에 branch workspace root와 slot path가 함께 남도록 필요한 typed field를 추가한다.
- [ ] `cd services/core && go test ./...`와 `git diff --check`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [API-1] Branch Workspace Topology

#### 문제

[services/core/internal/projectsync/config.go](/config/workspace/nomadcode/services/core/internal/projectsync/config.go:140)는 project root와 slot path만 제공한다. Milestone은 `branches/main`, `branches/develop`, `slots/000+` 분리를 요구한다([milestone-work-item-creation-sync.md](/config/workspace/nomadcode/agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/milestone-work-item-creation-sync.md:53)).

#### 해결 방법

`projectsync`에 `BranchName`, `BranchSyncState`, `BranchWorkspacePath`, `RequiredBranchWorkspaces`를 추가한다.

```go
// Before: services/core/internal/projectsync/config.go:140
func ProjectWorkspaceRoot(workspaceBasePath, repoDirName string) (string, error) {
```

```go
// After
type BranchName string
const (
    BranchNameMain BranchName = "main"
    BranchNameDevelop BranchName = "develop"
)
func BranchWorkspacePath(workspaceBasePath, repoDirName string, branch BranchName) (string, error) {
    ...
    return filepath.Join(root, "branches", string(branch)), nil
}
```

#### 수정 파일 및 체크리스트

- [ ] `services/core/internal/projectsync/config.go`
- [ ] `services/core/internal/projectsync/config_test.go`

#### 테스트 작성

- `TestBranchWorkspacePathsUseReservedBranches` 추가: `main`, `develop` 경로와 invalid branch 거부를 검증한다.
- `TestBranchSyncStateValidation` 추가: `synced`, `stale`, `error`만 유효하게 둔다.

#### 중간 검증

```bash
cd services/core && go test ./internal/projectsync
```

### [API-2] Provision Policy

#### 문제

[services/core/internal/projectsync/checkout.go](/config/workspace/nomadcode/services/core/internal/projectsync/checkout.go:20)는 single slot checkout plan만 만든다. `branches/develop` scan 기준과 `branches/main` release 기준을 준비하는 plan이 없다.

#### 해결 방법

`TopologyPlan` 또는 `ProvisionPlan`을 추가해 root, branch workspaces, default slot, source branch를 한 번에 반환한다. 실제 git 실행은 하지 않는다.

```go
// Before: services/core/internal/projectsync/checkout.go:42
return CheckoutPlan{
```

```go
// After
type ProvisionPlan struct {
    ProjectWorkspaceRoot string
    MainBranchPath string
    DevelopBranchPath string
    DefaultSlotPath string
}
func BuildProvisionPlan(config Config) (ProvisionPlan, error) { ... }
```

#### 수정 파일 및 체크리스트

- [ ] `services/core/internal/projectsync/checkout.go`
- [ ] `services/core/internal/projectsync/checkout_test.go`

#### 테스트 작성

- `TestBuildProvisionPlanIncludesBranchAndDefaultSlotPaths` 추가.
- `TestBuildProvisionPlanRejectsInvalidConfig` 추가.

#### 중간 검증

```bash
cd services/core && go test ./internal/projectsync
```

### [API-3] Metadata Carries Branch And Slot Topology

#### 문제

[services/core/internal/workitempipeline/service.go](/config/workspace/nomadcode/services/core/internal/workitempipeline/service.go:49)는 checkout metadata에 project root와 slot만 기록한다. 후속 sync layer가 `branches/develop` 기준과 slot local path를 구분하려면 branch workspace metadata가 필요하다.

#### 해결 방법

`CheckoutMetadata`에 `DevelopBranchPath`, `MainBranchPath`를 additive field로 추가하고 `BuildProvisionPlan` 결과를 metadata에 포함한다.

```go
// Before: services/core/internal/workitempipeline/service.go:53
type CheckoutMetadata struct {
```

```go
// After
type CheckoutMetadata struct {
    ...
    MainBranchPath string `json:"main_branch_path"`
    DevelopBranchPath string `json:"develop_branch_path"`
}
```

#### 수정 파일 및 체크리스트

- [ ] `services/core/internal/workitempipeline/service.go`
- [ ] `services/core/internal/workitempipeline/service_test.go`
- [ ] `services/core/internal/http/handlers_test.go`

#### 테스트 작성

- 기존 `TestCreateTaskFromWorkItemFetchesMapsAndRecordsCheckout`에 branch path assertions를 추가한다.
- project별 slot isolation test에도 `slots/<index>`와 branch paths가 섞이지 않음을 검증한다.

#### 중간 검증

```bash
cd services/core && go test ./internal/workitempipeline ./internal/http
```

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/internal/projectsync/config.go` | API-1 |
| `services/core/internal/projectsync/config_test.go` | API-1 |
| `services/core/internal/projectsync/checkout.go` | API-2 |
| `services/core/internal/projectsync/checkout_test.go` | API-2 |
| `services/core/internal/workitempipeline/service.go` | API-3 |
| `services/core/internal/workitempipeline/service_test.go` | API-3 |
| `services/core/internal/http/handlers_test.go` | API-3 |

## 최종 검증

```bash
cd services/core && go test ./...
git diff --check
```

Go test cache output is acceptable for unchanged packages; changed packages must appear in output or be rerun directly as 중간 검증.

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