<!-- task=m-workflow-core/01_lifecycle_model plan=1 tag=REVIEW_WFC-LIFECYCLE -->

# Review Follow-up Plan - REVIEW_WFC-LIFECYCLE

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

이 계획은 직전 코드리뷰에서 발견된 Required 문제만 다룬다. 구현 후 `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 내용과 검증 출력으로 채우는 것까지 포함한다. 구현 중 사용자 결정, 사용자 소유 외부 환경, 또는 범위 충돌이 필요하면 review stub의 `사용자 리뷰 요청` 섹션에 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식으로 기록하고 active 파일을 유지한 채 멈춘다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review 전용이다.

## 배경

`WFC-LIFECYCLE` 1차 구현은 lifecycle store interface와 fake-store 기반 테스트를 추가했다. 다만 `services/core/internal/workflow/service_test.go`의 호출 순서 검증이 메서드별 호출 slice만 확인해, 실제 순서가 뒤바뀌어도 테스트가 통과할 수 있다. 이 후속 작업은 테스트의 의미를 보강하는 데만 집중한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/workflow-core/milestones/workflow-core.md`
- Task ids:
  - `lifecycle-model`: task lifecycle 상태 모델 점검
- Completion mode: check-on-pass

## 이전 리뷰 요약

- Archived plan: `agent-task/m-workflow-core/01_lifecycle_model/plan_cloud_G07_0.log`
- Archived review: `agent-task/m-workflow-core/01_lifecycle_model/code_review_cloud_G07_0.log`
- Verdict: FAIL
- Required: fake store 테스트가 `UpdateMetadata` 이후 `UpdateStatus`/`CompleteTask`/`FailTask` 호출 순서를 전역 순서로 검증하지 못한다.

## 범위 결정 근거

- production lifecycle 코드는 이번 후속 범위가 아니다.
- 수정 대상은 기본적으로 `services/core/internal/workflow/service_test.go` 하나다.
- 테스트 보강 중 helper 구조상 필요한 경우에만 같은 파일 안에서 fake store 타입을 조정한다.

## 구현 체크리스트

- [ ] [REVIEW_WFC-LIFECYCLE-1] fakeTaskStore에 전역 operation log를 추가하고 StartTask/CompleteTask/FailTask 테스트가 metadata 이후 대상 write 순서를 직접 검증하게 한다.
- [ ] 중간 및 최종 검증 명령을 실행하고 출력 원문을 review stub에 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [REVIEW_WFC-LIFECYCLE-1] Fake Store Operation Order Assertions

### 문제

`services/core/internal/workflow/service_test.go:358` 근처의 테스트는 "Verify store calls in order"라고 적고 있지만, fake store가 `metadataCalls`, `statusCalls`, `completeCalls`, `failCalls`를 별도 slice로 기록한다. 이 구조에서는 실제 호출 순서가 `UpdateStatus -> UpdateMetadata`로 바뀌어도 각 slice 길이 검사는 통과한다.

### 해결 방법

`fakeTaskStore`에 전역 operation log를 추가한다.

Before:

```go
type fakeTaskStore struct {
	tasks         map[string]storage.Task
	metadataCalls []metadataCall
	statusCalls   []statusCall
	completeCalls []completeCall
	failCalls     []failCall
}
```

After 예시:

```go
type fakeTaskStore struct {
	tasks         map[string]storage.Task
	operations    []string
	metadataCalls []metadataCall
	statusCalls   []statusCall
	completeCalls []completeCall
	failCalls     []failCall
}
```

각 fake method에서 operation을 append하고, 테스트에서 순서를 직접 assert한다.

예시:

```go
f.operations = append(f.operations, "metadata:"+id)
f.operations = append(f.operations, "status:"+id+":"+status)
```

검증 기대:

- start pending: `metadata:task-1` 다음 `status:task-1:running`
- complete running: `metadata:task-3` 다음 `complete:task-3`
- fail running: `metadata:task-4` 다음 `fail:task-4`

문자열 대신 작은 struct를 써도 된다. 핵심은 메서드별 slice가 아니라 하나의 전역 log로 순서를 확인하는 것이다.

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

- [ ] `services/core/internal/workflow/service_test.go`: `fakeTaskStore`에 전역 operation log를 추가한다.
- [ ] `services/core/internal/workflow/service_test.go`: `UpdateMetadata`, `UpdateStatus`, `CompleteTask`, `FailTask` fake method가 같은 log에 호출 순서를 기록한다.
- [ ] `services/core/internal/workflow/service_test.go`: StartTask/CompleteTask/FailTask subtest가 operation log 순서를 직접 assert한다.

### 테스트 작성

- Required. 직전 FAIL의 원인이 테스트 의미 부족이므로, 테스트 자체가 실패를 잡을 수 있는지 분명히 보이게 만든다.

### 중간 검증

```bash
cd services/core && go test -count=1 ./internal/workflow
```

Expected: workflow package tests pass.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `services/core/internal/workflow/service_test.go` | REVIEW_WFC-LIFECYCLE-1 |

## 최종 검증

```bash
cd services/core && go test -count=1 ./internal/workflow
cd services/core && go test ./...
```

Expected: all commands exit 0. Fresh `-count=1` is required for the focused workflow package; package cache is acceptable for the final `go test ./...` rerun if Go reports cached packages.

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