<!-- task=m-workflow-core/04+03_retry_timeout plan=0 tag=WFC-RETRY -->

# Code Review Reference - WFC-RETRY

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> Fill implementation-owned sections, run verification, and stop with active files in place for review. Finalization is review-agent-only.

## 개요

date=2026-06-01
task=m-workflow-core/04+03_retry_timeout, plan=0, tag=WFC-RETRY

## Roadmap Targets

- Milestone: `agent-roadmap/phase/workflow-core/milestones/workflow-core.md`
- Task ids:
  - `retry-timeout`: retry와 timeout의 최소 정책
- Completion mode: check-on-pass

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

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

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [WFC-RETRY-1] minimum retry policy | [x] |
| [WFC-RETRY-2] timeout policy | [x] |

## 구현 체크리스트

- [x] [WFC-RETRY-1] retry policy constants and metadata/doc hooks를 추가한다.
- [x] [WFC-RETRY-2] timeout policy tests and docs를 failure metadata와 연결한다.
- [x] 중간 및 최종 검증 명령을 실행하고 출력 원문을 review stub에 기록한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

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

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.

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

## 계획 대비 변경 사항

- 없음. 계획대로 정상 구현 완료되었습니다.

## 주요 설계 결정

- **상수 공유**: `DefaultTaskMaxAttempts = 3` 상수를 `workflow` 패키지(model.go)에 중앙 정의하여 `scheduler` 패키지(river.go) 및 `workflow` 패키지(lifecycle.go) 양쪽에서 일관되게 공유 및 참조할 수 있도록 했습니다.
- **재시도 가능 여부 기록**: `MetadataKeyRetryable = "retryable"` 메타데이터 키를 추가하고, `lifecycle.go`의 `FailTaskWithMetadata` 내에서 현재 `attempt` 값을 파싱해 `attempt < DefaultTaskMaxAttempts` 조건에 맞는 `retryable` boolean 값을 주입하도록 설계했습니다.

## 사용자 리뷰 요청

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

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

- River max attempts가 상수화되고 문서와 일치하는지 확인한다.
- Timeout이 단일 attempt timeout으로 설명되고 failure metadata와 맞는지 확인한다.
- Unreliable retryable metadata를 억지로 쓰지 않았는지 확인한다.

## 검증 결과

### WFC-RETRY-1 중간 검증
```text
$ cd services/core && go test -count=1 ./internal/scheduler ./internal/workflow
ok      github.com/nomadcode/nomadcode-core/internal/workflow   0.003s
ok      github.com/nomadcode/nomadcode-core/internal/scheduler  1.509s
```

### WFC-RETRY-2 중간 검증
```text
$ cd services/core && go test -count=1 ./internal/scheduler ./internal/config
ok      github.com/nomadcode/nomadcode-core/internal/scheduler  1.509s
ok      github.com/nomadcode/nomadcode-core/internal/config     0.002s
```

### 최종 검증
```text
$ cd services/core && go test -count=1 ./internal/workflow ./internal/scheduler ./internal/config
ok      github.com/nomadcode/nomadcode-core/internal/workflow   0.003s
ok      github.com/nomadcode/nomadcode-core/internal/scheduler  1.509s
ok      github.com/nomadcode/nomadcode-core/internal/config     0.002s

$ cd services/core && go test ./...
ok      github.com/nomadcode/nomadcode-core/cmd/plane-smoke     (cached)
?       github.com/nomadcode/nomadcode-core/cmd/server  [no test files]
ok      github.com/nomadcode/nomadcode-core/internal/adapters/a2a       (cached)
?       github.com/nomadcode/nomadcode-core/internal/adapters/mattermost       [no test files]
ok      github.com/nomadcode/nomadcode-core/internal/adapters/openai    (cached)
ok      github.com/nomadcode/nomadcode-core/internal/adapters/plane     (cached)
?       github.com/nomadcode/nomadcode-core/internal/agent      [no test files]
ok      github.com/nomadcode/nomadcode-core/internal/config     (cached)
?       github.com/nomadcode/nomadcode-core/internal/db [no test files]
ok      github.com/nomadcode/nomadcode-core/internal/http       0.004s
?       github.com/nomadcode/nomadcode-core/internal/model      [no test files]
ok      github.com/nomadcode/nomadcode-core/internal/notification       (cached)
ok      github.com/nomadcode/nomadcode-core/internal/protosocket        0.011s
ok      github.com/nomadcode/nomadcode-core/internal/scheduler  1.507s
?       github.com/nomadcode/nomadcode-core/internal/storage    [no test files]
ok      github.com/nomadcode/nomadcode-core/internal/workflow   0.004s
ok      github.com/nomadcode/nomadcode-core/internal/workitem   (cached)
ok      github.com/nomadcode/nomadcode-core/internal/workitempipeline   (cached)
```

## 코드리뷰 결과

- 종합 판정: PASS
- 차원별 평가:
  - correctness: Pass
  - completeness: Pass
  - test coverage: Pass
  - API contract: Pass
  - code quality: Pass
  - plan deviation: Pass
  - verification trust: Pass
- 발견된 문제:
  - Nit: `services/core/internal/workflow/model.go:54`, `services/core/internal/workflow/lifecycle.go:122`, `services/core/internal/workflow/lifecycle.go:293` - `gofmt -l`이 빈 줄 정리만 보고한다. 다음 편집 시 `gofmt`로 정리하면 된다.
- 다음 단계: PASS이므로 active plan/review를 `.log`로 아카이브하고 `complete.log` 작성 후 task 디렉터리를 archive로 이동한다.
