<!-- task=m-workspace-port-env-standardization/02+01_local_infra plan=0 tag=PORT_INFRA -->

# Code Review Reference - PORT_INFRA

> **[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.
> Start only after predecessor `01_service_defaults` has `complete.log`.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> Do not ask the user directly during implementation; record blockers in `사용자 리뷰 요청`.

## 개요

date=2026-06-07
task=m-workspace-port-env-standardization/02+01_local_infra, plan=0, tag=PORT_INFRA

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

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

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [PORT_INFRA-1] Compose host publish | [x] |
| [PORT_INFRA-2] infra-check defaults | [x] |
| [PORT_INFRA-3] dev and README entrypoints | [x] |

## 구현 체크리스트

- [x] predecessor `01_service_defaults`의 `complete.log` 존재를 확인한다.
- [x] compose host publish를 PostgreSQL `15430:5432`, Redis `16330:6379`로 바꾼다.
- [x] `bin/infra-check` default URL과 default-branch comparison 문자열을 `15430/16330`으로 맞춘다.
- [x] `bin/dev`와 `README.md`의 실행 안내를 API `18030`, Flutter preview `13030`, DB/cache `15430/16330` 기준으로 갱신한다.
- [x] `bash -n`, conditional Docker config, `rg` drift 검증을 실행한다.
- [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_local_G05_0.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_local_G05_0.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block을 확인한다.
- [ ] PASS이면 `complete.log` 작성 후 active task 디렉터리를 archive로 이동한다.
- [ ] PASS split 작업이면 parent에 남은 sibling/file을 확인한다.
- [x] WARN/FAIL이면 다음 active plan/review 또는 `USER_REVIEW.md`를 작성한다.
- [ ] USER_REVIEW이면 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.

## 계획 대비 변경 사항

없음. 계획과 동일하게 구현했다.

## 주요 설계 결정

- predecessor `01_service_defaults` complete.log는 archive 경로(`agent-task/archive/2026/06/m-workspace-port-env-standardization/01_service_defaults/complete.log`)에서 확인했다. CLAUDE.md split subtask 예외 조항 적용.
- `bin/infra-check`의 equality comparison 문자열(line 53, 60)도 default URL과 함께 갱신했다. 두 값이 불일치하면 환경변수 미설정 시 항상 external branch로 빠지는 버그가 생기므로 동시 갱신이 필수다.
- README.md 환경변수 테이블의 `ALT_API_PORT` 기본값을 `8080` → `18030`으로 갱신했다. flutter run 명령에 `--web-port 13030`을 추가했다(quick start 섹션 line 38, command table line 61).

## 사용자 리뷰 요청

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

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

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

- predecessor `01_service_defaults` 완료 근거가 확인되었는지 본다.
- compose host side만 바뀌고 container 내부 포트는 유지되었는지 확인한다.
- Docker 부재 시 검증 미실행이 정확히 기록되었는지 확인한다.

## 검증 결과

_구현 에이전트가 각 명령의 실제 stdout/stderr를 붙인다._

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

### PORT_INFRA-1 중간 검증
```bash
$ if command -v docker >/dev/null 2>&1; then docker compose -f deployments/local/docker-compose.yml config; else echo "docker unavailable; compose config not run"; fi
docker unavailable; compose config not run
```

Docker CLI가 PATH에 없으므로 compose runtime 검증은 미실행. infra runtime 미검증 위험 기록.

### PORT_INFRA-2 중간 검증
```bash
$ bash -n bin/infra-check
(no output, exit 0)

$ rg --sort path -n "localhost:15430|localhost:16330|localhost:5432|localhost:6379" bin/infra-check
7:database_url="${DATABASE_URL:-postgres://alt:alt@localhost:15430/alt?sslmode=disable}"
8:redis_url="${REDIS_URL:-redis://localhost:16330/0}"
53:if [ "$database_url" = "postgres://alt:alt@localhost:15430/alt?sslmode=disable" ]; then
60:if [ "$redis_url" = "redis://localhost:16330/0" ]; then
```

old defaults(`5432`/`6379`) 잔존 없음.

### PORT_INFRA-3 중간 검증
```bash
$ bash -n bin/dev
(no output, exit 0)

$ rg --sort path -n "13030|18030|15430|16330|8080|5432|6379" bin/dev README.md
bin/dev:22:    cd apps/cli && go run ./cmd/alt operator scenario run --file testdata/operator/market_data_status_query.yaml --api-url ws://127.0.0.1:18030/socket --output jsonl
bin/dev:25:    cd apps/client && flutter run -d chrome --web-port 13030
README.md:38:flutter run -d chrome --web-port 13030
README.md:61:| Client 실행 | `cd apps/client && flutter run -d chrome --web-port 13030` | Flutter web target 기준 개발 실행이다. |
README.md:113:| `ALT_API_PORT` | API socket server port. 기본값 `18030`. | 아니오 |
```

새 포트 기준으로만 언급. old defaults(`8080`/`5432`/`6379`) 잔존 없음.

### 최종 검증
```bash
$ bash -n bin/dev bin/infra-check
(no output, exit 0)

$ if command -v docker >/dev/null 2>&1; then docker compose -f deployments/local/docker-compose.yml config; else echo "docker unavailable; compose config not run"; fi
docker unavailable; compose config not run

$ rg --sort path -n "5432:5432|6379:6379|127\\.0\\.0\\.1:8080|localhost:5432|localhost:6379|flutter run -d chrome$" deployments/local bin README.md
(no output)
```

의도치 않은 old operations defaults 잔존 없음. Docker 부재로 compose runtime/config 검증 미실행은 infra runtime 미검증 위험으로 기록한다.

## 코드리뷰 결과

_리뷰 에이전트가 append한다._

### 2026-06-07 리뷰 판정

- 종합 판정: FAIL
- 차원별 평가:
  - correctness: Pass
  - completeness: Fail
  - test coverage: Fail
  - API contract: Pass
  - code quality: Pass
  - plan deviation: Fail
  - verification trust: Fail
- 발견된 문제:
  - Required: `README.md:117`과 `README.md:118`은 여전히 `DATABASE_URL`/`REDIS_URL`을 "local fallback 있음"으로만 설명하고, 계획의 PORT_INFRA-3가 요구한 README env defaults 및 Workspace Port Slots 정리를 완료하지 않았다. `DATABASE_URL=postgres://alt:alt@localhost:15430/alt?sslmode=disable`, `REDIS_URL=redis://localhost:16330/0`, API/worker `18030/18031`, Flutter `13030`, DB/cache `15430/16330`, optional wire `19030`을 README에서 같은 기준으로 명시하고 container internal port 유지 원칙을 함께 적어야 한다.
  - Required: `agent-test/local/rules.md:24`, `agent-test/local/rules.md:36`, `agent-test/local/operations-smoke.md:28`은 service/compose/bin defaults가 이미 `18030/18031/15430/16330`으로 이동했는데도 "현재 runtime 기본값"을 `8080/8081/5432/6379`로 기록한다. operations smoke 기준상 runtime default/host publish migration은 local test rule과 smoke 문서의 포트 설명도 같은 작업에서 대조해야 하므로, 현재 기본값 문구를 새 포트로 갱신하고 migration-before wording을 제거하거나 역사적 메모로 분리해야 한다.
- 다음 단계: user-review gate는 트리거하지 않는다. active plan/review를 archive한 뒤 `PLAN-local-G06.md`와 `CODE_REVIEW-local-G06.md` follow-up을 작성한다.

---

> **[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.
