<!-- task=m-persistence-worker-backbone plan=0 tag=TEST -->

# Plan - TEST

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

`CODE_REVIEW-cloud-G06.md`의 구현 에이전트 소유 섹션을 채우는 것이 필수 마지막 단계다. 아래 검증 명령을 실제로 실행하고, 실제 stdout/stderr를 붙여 넣고, active 파일을 그대로 둔 채 리뷰 준비를 보고한다. 사용자 결정, 외부 환경 준비, 또는 범위 충돌 없이는 계속할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션을 정확한 근거와 함께 채우고 멈춘다. `USER_REVIEW.md`, archive log, `complete.log` 작성은 code-review 전용이다.

## 배경

`Persistence and Worker Backbone`의 코드 산출물 대부분은 이미 들어와 있고 `bin/test`, `bin/lint`, `bin/build`, `bin/worker-storage-check`가 통과했다. 남은 Milestone Task는 `db-migrations`의 local PostgreSQL/Redis smoke 검증이다. 현재 컨테이너는 Docker와 DB client가 없어 `bin/infra-check`를 완료할 수 없으므로, repo 표준 local compose 환경에서 migration entrypoint를 실제로 실행해 증거를 남긴다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 active `CODE_REVIEW-cloud-G06.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 섹션 형식은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 기준이며, code-review가 검증 후 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/foundation-alignment/PHASE.md`
- `agent-roadmap/phase/foundation-alignment/milestones/persistence-worker-backbone.md`
- `agent-ops/rules/project/domain/worker/rules.md`
- `agent-ops/rules/project/domain/operations/rules.md`
- `agent-ops/rules/project/domain/domain-model/rules.md`
- `agent-ops/rules/private/testing-env.md`
- `services/worker/README.md`
- `services/worker/cmd/alt-worker/main.go`
- `services/worker/cmd/alt-worker-migrate/main.go`
- `services/worker/cmd/alt-worker-migrate/main_test.go`
- `services/worker/internal/config/config.go`
- `services/worker/internal/config/config_test.go`
- `services/worker/internal/jobs/builtin.go`
- `services/worker/internal/jobs/job.go`
- `services/worker/internal/jobs/runner.go`
- `services/worker/internal/jobs/runner_test.go`
- `services/worker/internal/rediskeys/keys.go`
- `services/worker/internal/rediskeys/keys_test.go`
- `services/worker/internal/storage/ports.go`
- `services/worker/internal/storage/postgres/mapping.go`
- `services/worker/internal/storage/postgres/mapping_test.go`
- `services/worker/internal/storage/postgres/migrate.go`
- `services/worker/internal/storage/postgres/migrate_test.go`
- `services/worker/internal/storage/postgres/migrations/000001_worker_backbone.up.sql`
- `services/worker/internal/storage/postgres/migrations/000001_worker_backbone.down.sql`
- `services/worker/internal/storage/postgres/queries/queries.sql`
- `services/worker/internal/storage/postgres/sqlc/db.go`
- `services/worker/internal/storage/postgres/sqlc/models.go`
- `services/worker/internal/storage/postgres/sqlc/queries.sql.go`
- `services/worker/internal/storage/postgres/store.go`
- `services/worker/sqlc.yaml`
- `services/worker/tools.go`
- `services/worker/go.mod`
- `packages/domain/backtest/types.go`
- `packages/domain/market/types.go`
- `packages/domain/go.mod`
- `deployments/local/docker-compose.yml`
- `bin/infra-check`
- `bin/worker-storage-check`
- `bin/worker-storage-gen`
- `bin/test`
- `bin/lint`
- `bin/build`
- `go.work`

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

- `db-migrations`: `services/worker/internal/storage/postgres/migrate_test.go`는 embedded migration 파일 구조를 검증하고, `cmd/alt-worker-migrate/main_test.go`는 DB URL redaction만 검증한다. 실제 PostgreSQL에 `RunMigrations`를 적용하고 Redis health까지 확인하는 integration smoke는 아직 없다.
- `infra-check`: `bin/infra-check`는 shell smoke entrypoint이며 자동 테스트가 없다. 성공 여부는 repo local compose 또는 동등한 명시 환경에서 실제 실행 출력으로 확인해야 한다.

### 심볼 참조

- none. 심볼 rename/remove 계획이 없다.

### 분할 판단

split decision policy를 계획 파일 선택 전에 평가했다. 남은 작업은 local compose 준비, `bin/infra-check`, migration entrypoint 실행, 기존 전체 검증 재확인의 한 흐름이다. API foundation, call-site rollout, schema 변경, test strategy 분리가 없고 한 번의 smoke 증거가 Milestone의 남은 Task를 닫으므로 single-plan이 더 안전하다. task group은 Milestone-linked 규칙에 따라 `agent-task/m-persistence-worker-backbone/`를 사용한다.

### 범위 결정 근거

- `services/worker/internal/storage/postgres/migrations/*.sql`, `queries.sql`, `sqlc/**`는 수정하지 않는다. `bin/worker-storage-check`가 통과했고 drift가 없다.
- `services/worker/internal/jobs/**`, `internal/rediskeys/**`, `internal/storage/ports.go`, `store.go`는 수정하지 않는다. 해당 Milestone Task는 이미 로드맵에 완료 반영했다.
- `deployments/local/docker-compose.yml`와 `bin/infra-check`는 smoke 실행 대상으로만 사용한다. local compose 자체가 깨진 증거가 나오기 전까지 스크립트나 compose를 확장하지 않는다.
- `apps/client/**`, `services/api/**`, `packages/contracts/**`는 범위 밖이다.

### 빌드 등급

- build lane: `cloud-G07`, review lane: `cloud-G06`. 성공 조건이 real Docker/compose, shell entrypoint, stdout/stderr 증거에 의존하는 terminal-agent smoke라서 cloud-G07이 필요하다.

## 구현 체크리스트

- [ ] [TEST-1] repo 표준 local compose 환경에서 PostgreSQL/Redis health와 worker migration entrypoint를 검증한다. 검증: `env -u DATABASE_URL -u REDIS_URL bin/infra-check`와 `(cd services/worker && env -u DATABASE_URL -u REDIS_URL go run ./cmd/alt-worker-migrate)`가 통과한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [TEST-1] Run local migration smoke against repo compose

#### 문제

`services/worker/cmd/alt-worker-migrate/main.go:30`-`51`는 migration entrypoint를 제공하고, `services/worker/internal/storage/postgres/migrate.go:19`-`98`는 embedded migrations를 순서대로 실행한다. 하지만 현재 남은 `db-migrations` Task의 검증은 실제 local PostgreSQL/Redis health와 worker config read를 요구한다. `bin/infra-check:17`-`30`는 default local compose를 Docker로 확인하고, `bin/infra-check:33`-`48`는 env override 시 `pg_isready`/`redis-cli`를 요구하므로 현재 컨테이너에서는 완료 증거가 부족하다.

#### 해결 방법

소스 코드는 수정하지 않는다. Docker가 있는 repo local 환경에서 표준 compose 서비스를 띄우고, ambient `DATABASE_URL`/`REDIS_URL` override를 제거한 상태로 health check와 migration entrypoint를 실행한다. 실패가 코드 결함이면 review stub의 `계획 대비 변경 사항`에 범위 변경을 기록하고 최소 수정한다. 실패가 외부 환경 준비 문제이면 `사용자 리뷰 요청`에 실행 명령과 실제 출력을 남긴다.

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

- [ ] `deployments/local/docker-compose.yml` 서비스를 실행 대상으로 사용한다.
- [ ] `bin/infra-check`를 default local compose mode로 실행한다.
- [ ] `services/worker/cmd/alt-worker-migrate/main.go`를 `go run` smoke 대상으로 실행한다.
- [ ] `CODE_REVIEW-cloud-G06.md`에 실제 명령 출력과 환경 차단 여부를 기록한다.

#### 테스트 작성

새 테스트는 작성하지 않는다. 이 계획의 목적은 unit coverage가 닿지 않는 live local infra smoke 증거를 남기는 것이다. 기존 테스트는 `services/worker/internal/storage/postgres/migrate_test.go`, `services/worker/cmd/alt-worker-migrate/main_test.go`, `bin/test`로 재확인한다.

#### 중간 검증

```bash
command -v docker
docker compose -f deployments/local/docker-compose.yml up -d postgres redis
env -u DATABASE_URL -u REDIS_URL bin/infra-check
(cd services/worker && env -u DATABASE_URL -u REDIS_URL go run ./cmd/alt-worker-migrate)
```

예상 결과: 모든 명령 exit code 0. `bin/infra-check`는 `postgres: ok`, `redis: ok`를 출력하고, migration command는 `migrations completed successfully`를 출력한다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `deployments/local/docker-compose.yml` | TEST-1 실행 대상, 수정 없음 |
| `bin/infra-check` | TEST-1 실행 대상, 수정 없음 |
| `services/worker/cmd/alt-worker-migrate/main.go` | TEST-1 실행 대상, 수정 없음 |
| `CODE_REVIEW-cloud-G06.md` | TEST-1 결과 기록 |

## 최종 검증

```bash
command -v docker
docker compose -f deployments/local/docker-compose.yml up -d postgres redis
env -u DATABASE_URL -u REDIS_URL bin/infra-check
(cd services/worker && env -u DATABASE_URL -u REDIS_URL go run ./cmd/alt-worker-migrate)
bin/test
bin/lint
bin/build
```

Go test cache output is acceptable for `bin/test` because this plan does not change Go or Dart source. Smoke commands must be executed live and their actual stdout/stderr must be recorded.

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