<!-- task=m-milestone-work-item-creation-sync/13+12_slot_terminal_state plan=0 tag=API -->

# Code Review Reference - API

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> Do not ask the user directly; use `사용자 리뷰 요청` for blockers.
> Finalization is review-agent-only.

## 개요

date=2026-06-15
task=m-milestone-work-item-creation-sync/13+12_slot_terminal_state, plan=0, tag=API

## Roadmap Targets

- Milestone: `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/milestone-work-item-creation-sync.md`
- Task ids:
  - `slot-terminal-state`: authoring 또는 projection이 terminal outcome에 도달하면 reserved workspace slot이 정책에 따라 `available`, `dirty`, `error` 중 하나로 전환된다.
- Completion mode: check-on-pass

## 이 파일을 읽는 리뷰 에이전트에게

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다.

각 항목의 구현을 실제 소스 파일과 대조하고 검증 출력을 확인하세요.

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [API-1] Add slot terminal policy helper | [x] |
| [API-2] Apply slot release on terminal paths | [x] |

## 구현 체크리스트

- [x] checkout metadata에서 `slot_id`를 읽는 helper를 추가하고 missing slot id는 slot update를 skip하되 task completion/failure를 막지 않도록 기록한다.
- [x] success projection은 reserved slot을 `available`로, dirty/conflict/push failure는 `dirty` 또는 `error`로 전환하는 정책 helper를 추가한다.
- [x] TaskWorker failure path와 RoadmapCreationSync finalizer path가 같은 slot release policy를 사용하도록 연결한다.
- [x] `cd services/core && go test -count=1 ./internal/projectsync ./internal/storage ./internal/scheduler ./internal/workflow`를 통과시킨다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 코드리뷰 전용 체크리스트

- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [ ] active review/plan 파일을 `.log`로 아카이브한다.
- [ ] PASS이면 `complete.log`를 작성하고 active task 디렉터리를 archive로 이동한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고하고 roadmap을 직접 수정하지 않는다.

## 계획 대비 변경 사항

- `CompleteTaskByExternalRef`가 완료된 `storage.Task`를 반환하도록 보강했다. Roadmap creation sync projection success 이후 같은 task metadata의 `checkout.slot_id`를 읽어 slot을 `available`로 전환하기 위해 필요했다.
- slot update 실패나 missing `slot_id`는 task terminal 처리 자체를 막지 않고 warning/skip으로 처리했다. projection side effect 재시도와 task failure 기록을 slot cleanup 오류로 되감지 않기 위한 결정이다.

## 주요 설계 결정

- `authoring.SlotStateForAuthoringOutcome`으로 terminal outcome 정책을 모았다. `succeeded`는 `available`, `dirty_workspace`/`conflict`/`push_failed`는 `dirty`, 그 외 failed category는 `error`로 매핑한다.
- scheduler의 `WorkspaceSlotStateUpdater`는 optional seam으로 두고, 서버 wiring에서는 기존 `storage.Store`를 주입했다.
- `TaskWorker` authoring failure path와 `RoadmapCreationSyncWorker` projected/complete finalizer path 모두 `applyTaskSlotTerminalState` helper를 사용한다.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._

- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

## 코드리뷰 결과

### 종합 판정

PASS

### 차원별 평가

| 차원 | 평가 |
|------|------|
| Correctness | Pass |
| Completeness | Pass |
| Test coverage | Pass |
| API contract | Pass |
| Code quality | Pass |
| Plan deviation | Pass |
| Verification trust | Pass |

### 발견된 문제

- **Nit** `services/core/internal/scheduler/river_test.go:160` `TestRoadmapCreationSyncWorkerFinalizesExternalTaskOnComplete`가 `SlotUpdater`를 주입하지 않아 `SyncActionComplete` 경로의 slot update를 검증하지 않는다. `SyncActionProjected`와 동일한 코드 경로라 정확성에는 영향 없음; 향후 테스트 구체성 개선 여지.

### 다음 단계

PASS — complete.log 작성 및 archive 이동.

---

## 리뷰어를 위한 체크포인트

- success projection이 slot을 `available`로 되돌리는지 확인한다.
- dirty/conflict/push failure가 원인에 맞는 slot terminal state를 남기는지 확인한다.
- missing slot metadata가 task finalization 자체를 깨지 않는지 확인한다.

## 검증 결과

### API-1 중간 검증
```text
$ cd services/core && go test -count=1 ./internal/authoring ./internal/projectsync
ok  	github.com/nomadcode/nomadcode-core/internal/authoring	0.004s
ok  	github.com/nomadcode/nomadcode-core/internal/projectsync	0.004s
```

### API-2 중간 검증
```text
$ cd services/core && go test -count=1 ./internal/scheduler ./internal/storage
ok  	github.com/nomadcode/nomadcode-core/internal/scheduler	2.018s
ok  	github.com/nomadcode/nomadcode-core/internal/storage	0.004s
```

### 최종 검증
```text
$ cd services/core && go test -count=1 ./internal/projectsync ./internal/storage ./internal/authoring ./internal/scheduler ./internal/workflow
ok  	github.com/nomadcode/nomadcode-core/internal/projectsync	0.009s
ok  	github.com/nomadcode/nomadcode-core/internal/storage	0.004s
ok  	github.com/nomadcode/nomadcode-core/internal/authoring	0.004s
ok  	github.com/nomadcode/nomadcode-core/internal/scheduler	2.016s
ok  	github.com/nomadcode/nomadcode-core/internal/workflow	0.003s
$ cd services/core && go test ./...
PASS; all services/core packages passed.
$ cd services/core && go vet ./...
PASS; no output.
$ git diff --check
PASS; no output.
```
