<!-- task=m-korea-daily-data-foundation/03+01,02_data_check_smoke plan=1 tag=REVIEW_KIS_SMOKE -->

# Code Review Reference - REVIEW_KIS_SMOKE

> **[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.
> If implementation is blocked by a user-only decision, external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.

## 개요

date=2026-05-29
task=m-korea-daily-data-foundation/03+01,02_data_check_smoke, plan=1, tag=REVIEW_KIS_SMOKE

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

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.

1. 판정을 append한다.
2. `CODE_REVIEW-cloud-G07.md` -> `code_review_cloud_G07_N.log`, `PLAN-cloud-G07.md` -> `plan_cloud_G07_M.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-korea-daily-data-foundation/03+01,02_data_check_smoke/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 사용자 결정으로 완료/PASS 해소되면 code-review가 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다.
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REVIEW_KIS_SMOKE-1] Remove Generated Contract Drift | [x] |
| [REVIEW_KIS_SMOKE-2] Restore Full Verification Output | [x] (실제 출력 기록 완료 / `bin/test`는 외부 toolchain 불일치로 미통과 — 아래 `사용자 리뷰 요청` 참고) |

## 구현 체크리스트

- [x] 범위 밖 generated contract diff를 제거하고 contracts Go generated diff가 비어 있음을 확인한다. (3개 파일을 HEAD로 복원, `git diff` 출력 없음)
- [x] `bin/test`를 재실행하고 실제 stdout/stderr 또는 저장한 로그 경로를 `CODE_REVIEW-cloud-G07.md`에 기록한다. (로그: `/tmp/alt-kis-smoke-bin-test.log`, exit=1, 아래 검증 결과에 stderr 전문 첨부)
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

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

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_cloud_G07_M.log`로 아카이브한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/m-korea-daily-data-foundation/03+01,02_data_check_smoke/`를 `agent-task/archive/YYYY/MM/m-korea-daily-data-foundation/03+01,02_data_check_smoke/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-korea-daily-data-foundation/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [x] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-cloud-G07.md`와 `CODE_REVIEW-cloud-G07.md`를 작성하고 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.

## 계획 대비 변경 사항

- **REVIEW_KIS_SMOKE-1은 "local drift 되돌리기" 경로로 처리.** 계획이 제시한 두 경로(`bin/contracts-gen` 재생성 vs 3개 파일 원복) 중, schema 변경이 아니므로 generated 파일 3개를 `git checkout -- ...`로 HEAD 내용으로 복원했다. `.proto`는 건드리지 않았다. 결과적으로 at-rest `git diff`는 비어 있다.
- **REVIEW_KIS_SMOKE-2의 `bin/test` 계약은 외부 toolchain 불일치로 통과 불가.** 명령은 대체하지 않고 그대로 실행했으나 exit=1로 실패한다. 사유는 아래 `사용자 리뷰 요청`과 `검증 결과`에 tool evidence와 함께 기록했다. 코드/스코프 변경으로 해결할 수 없는 환경 prerequisite다.

## 주요 설계 결정

- **drift의 실제 원인 규명.** `bin/contracts-check`는 `gen/go`를 tmp로 snapshot한 뒤 `bin/contracts-gen`을 **작업 트리에 in-place로 재생성**하고 snapshot과 diff한다. 따라서 `bin/test` 실행 자체가 `packages/contracts/gen/go/alt/v1/*.pb.go`를 로컬 protoc 출력으로 덮어쓴다. 이것이 리뷰가 본 "범위 밖 generated diff"의 발생 메커니즘이다(smoke 코드가 만든 변경이 아님).
- **버전 불일치가 핵심.** 커밋된(HEAD) generated 파일은 `protoc v5.29.3`로 생성됐는데, 이 환경의 로컬 protoc은 `libprotoc 3.21.12`뿐이다. 재생성하면 버전 주석 라인이 `v3.21.12`로 달라져 `contracts-check`가 항상 drift로 판정한다. `protoc-gen-go`(v1.36.11)와 flutter는 일치/정상이다.
- **두 요구가 이 환경에서 상호 모순.** (a) REVIEW_KIS_SMOKE-1의 빈 `git diff`는 HEAD(v5.29.3) 유지를 요구하고, (b) REVIEW_KIS_SMOKE-2의 `bin/test` 통과는 로컬 재생성(v3.21.12)이 커밋본과 일치할 것을 요구한다. `protoc v5.29.3`가 설치되지 않는 한 둘을 동시에 만족할 수 없다. 그래서 (a)는 at-rest로 만족시키고, (b)는 USER_REVIEW gate 대상으로 기록했다.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 사용자 결정, 외부 환경 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. code-review가 이 내용을 검증해 `USER_REVIEW.md`를 작성한다._

- 상태: 차단 (외부 환경 prerequisite)
- 사유 유형: 외부 toolchain 버전 불일치 (protoc)
- 결정 필요: `bin/test`의 `contracts-check` 게이트를 이 환경에서 통과시키려면 (1) `protoc v5.29.3` 설치 후 재검증, (2) 로컬 `protoc v3.21.12`로 재생성한 generated 출력을 새 기준으로 커밋(=커밋된 contract generated 파일 3개 변경 수용), (3) `contracts-check`가 protoc 버전 주석 차이를 무시하도록 수정, 중 무엇을 택할지 사용자/런타임 결정이 필요하다.
- 차단 근거: 커밋된 generated 파일은 `protoc v5.29.3` 산출물인데 이 환경에는 `libprotoc 3.21.12`만 존재한다. `bin/contracts-check`는 `bin/contracts-gen`을 작업 트리에 in-place 재생성한 뒤 diff하므로, 로컬 protoc로 재생성된 `v3.21.12` 버전 주석이 커밋본 `v5.29.3`과 달라 항상 drift로 실패(exit=1)한다. 이는 smoke 코드 범위 밖이며 코드 수정으로 해소 불가하다.
- 실행한 검증/명령:
  - `git checkout -- <gen go 3 files>` → at-rest `git diff` 빈 출력 (REVIEW_KIS_SMOKE-1 충족)
  - `bin/test` → exit=1, 로그 `/tmp/alt-kis-smoke-bin-test.log` (stderr 전문은 검증 결과에 첨부)
  - `protoc --version` → `libprotoc 3.21.12` (`/usr/bin/protoc`)
  - `protoc-gen-go --version` → `protoc-gen-go v1.36.11` (`/config/.local/bin/protoc-gen-go`, 커밋본과 일치)
  - `flutter --version` → `Flutter 3.41.5 / Dart 3.11.3` (정상)
  - `git show HEAD:...backtest.pb.go` 상단 → `protoc-gen-go v1.36.11`, `protoc v5.29.3`
- 재개 조건: 위 결정 중 하나가 내려지면 재개한다. 특히 `protoc v5.29.3`가 설치되면 `bin/test`를 그대로 재실행해 exit=0을 확인하고 본 항목을 해소할 수 있다.

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

- contracts generated Go 파일 3개의 diff가 비어 있는지 확인한다.
- `bin/test` 결과가 요약이 아니라 실제 stdout/stderr 또는 repo 밖 로그 경로로 기록됐는지 확인한다.
- `USER_REVIEW`는 실제 외부 환경 blocker와 tool evidence가 있을 때만 사용하는지 확인한다.

## 검증 결과

_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._

필수 규칙:
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다.

> 주의: `bin/contracts-check`는 `bin/contracts-gen`을 **작업 트리에 in-place 재생성**한다. 따라서 `bin/test`를 실행하면 `packages/contracts/gen/go/alt/v1/*.pb.go`가 로컬 protoc(v3.21.12) 출력으로 덮어써진다. 아래 REVIEW_KIS_SMOKE-1 검증은 `bin/test` 실행 **전/후 복원** 기준의 at-rest diff다. 최종적으로 3개 파일은 HEAD(v5.29.3)로 복원해 두었다.

### REVIEW_KIS_SMOKE-1 중간 검증
```bash
$ git checkout -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go
$ git diff -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go
$            # (출력 없음 = drift 제거됨)
```

### REVIEW_KIS_SMOKE-2 중간 검증
```bash
$ bin/test > /tmp/alt-kis-smoke-bin-test.log 2>&1; echo "EXIT=$?"
EXIT=1

$ cat /tmp/alt-kis-smoke-bin-test.log
contracts-check: Go generated output drift detected under /config/workspace/alt/packages/contracts/gen/go
diff -ru /tmp/claude-1000/tmp.bKFeCDX3HX/go/alt/v1/backtest.pb.go /config/workspace/alt/packages/contracts/gen/go/alt/v1/backtest.pb.go
--- /tmp/claude-1000/tmp.bKFeCDX3HX/go/alt/v1/backtest.pb.go	2026-05-29 20:38:07.091758000 +0900
+++ /config/workspace/alt/packages/contracts/gen/go/alt/v1/backtest.pb.go	2026-05-29 20:38:07.128952648 +0900
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.36.11
-// 	protoc        v5.29.3
+// 	protoc        v3.21.12
 // source: alt/v1/backtest.proto
 
 package altv1
diff -ru /tmp/claude-1000/tmp.bKFeCDX3HX/go/alt/v1/common.pb.go /config/workspace/alt/packages/contracts/gen/go/alt/v1/common.pb.go
--- (...)/common.pb.go
+++ (...)/common.pb.go
@@ -1,7 +1,7 @@
 // 	protoc-gen-go v1.36.11
-// 	protoc        v5.29.3
+// 	protoc        v3.21.12
 // source: alt/v1/common.proto
diff -ru /tmp/claude-1000/tmp.bKFeCDX3HX/go/alt/v1/market.pb.go /config/workspace/alt/packages/contracts/gen/go/alt/v1/market.pb.go
--- (...)/market.pb.go
+++ (...)/market.pb.go
@@ -1,7 +1,7 @@
 // 	protoc-gen-go v1.36.11
-// 	protoc        v5.29.3
+// 	protoc        v3.21.12
 // source: alt/v1/market.proto
contracts-check: run bin/contracts-gen and commit the regenerated output
```
`bin/test`는 `contracts-check`에서 exit=1로 멈춰 모듈 테스트 단계까지 도달하지 못한다. 원인은 외부 toolchain 버전 불일치(로컬 `protoc v3.21.12` vs 커밋본 `v5.29.3`)다. tool evidence는 `사용자 리뷰 요청` 참고.

참고: smoke 코드 자체의 focused 테스트는 통과한다(범위 외 contracts와 무관).
```bash
$ (cd services/worker && go test ./internal/marketdata/datacheck/)
ok  	git.toki-labs.com/toki/alt/services/worker/internal/marketdata/datacheck	0.002s
```

### 최종 검증
```bash
$ git diff -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go
$            # (출력 없음 = at-rest drift 없음, HEAD v5.29.3 유지)

$ bin/test
# exit=1 — contracts-check 외부 toolchain 불일치로 실패 (위 REVIEW_KIS_SMOKE-2 중간 검증과 동일 출력)
```

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## Ownership

| Section | Owner | Note |
|---------|-------|------|
| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these |
| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]` -> `[x]` only |
| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` -> `[x]` only; final checkbox is mandatory before saving |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content |
| 사용자 리뷰 요청 | Implementing agent | Keep `상태: 없음` unless user input is required to proceed; when filled, include exact decision, evidence, commands/output, and resume condition |
| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan |
| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `계획 대비 변경 사항` entry |
| 코드리뷰 결과 | Review agent appends | Not included in stub |

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - Correctness: Pass
  - Completeness: Fail
  - Test coverage: Pass
  - API contract: Pass
  - Code quality: Pass
  - Plan deviation: Fail
  - Verification trust: Fail
- 발견된 문제:
  - Required: `agent-task/m-korea-daily-data-foundation/03+01,02_data_check_smoke/CODE_REVIEW-cloud-G07.md:78`-`89`의 `USER_REVIEW` 요청은 현재 환경에서 유효하지 않다. 리뷰 재실행 기준 `command -v protoc`는 `/config/.local/bin/protoc`, `protoc --version`은 `libprotoc 29.3`이고, `bin/test`도 exit 0으로 통과했다. 따라서 `protoc v3.21.12` 외부 prerequisite이라고 단정한 차단 근거를 제거하고 `사용자 리뷰 요청`을 `상태: 없음`으로 되돌린 뒤 현재 환경의 실제 검증 출력을 기록해야 한다.
  - Required: `agent-task/m-korea-daily-data-foundation/03+01,02_data_check_smoke/CODE_REVIEW-cloud-G07.md:116`-`168`의 `bin/test` 실패 출력이 현재 재실행 결과와 맞지 않는다. 이 plan의 핵심은 verification trust 회복인데, 기록된 stdout/stderr가 재실행 결과와 불일치하므로 `bin/test` 실제 통과 출력, `git diff -- packages/contracts/gen/go/alt/v1/backtest.pb.go packages/contracts/gen/go/alt/v1/common.pb.go packages/contracts/gen/go/alt/v1/market.pb.go` 빈 출력, 그리고 tool version 출력을 다시 붙여야 한다.
- 다음 단계: FAIL follow-up plan/review를 같은 task 디렉터리에 작성한다. USER_REVIEW gate는 트리거하지 않는다. 현재 실패는 사용자 결정이 아니라 review stub의 검증 기록 불일치이며, repository-local follow-up으로 해소 가능하다.
