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

# Code Review Reference - REFACTOR

> **[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, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place.

## 개요

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

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

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

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.

1. 판정을 append한다.
2. `CODE_REVIEW-cloud-G06.md` -> `code_review_cloud_G06_N.log`, `PLAN-cloud-G06.md` -> `plan_cloud_G06_M.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 archive로 이동한다.
4. PASS이고 task group이 `m-workspace-port-env-standardization`이면 완료 이벤트 메타데이터를 보고한다. roadmap 수정이나 `update-roadmap` 직접 호출은 하지 않는다.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REFACTOR-1] Align Control Plane and client defaults | [x] |
| [REFACTOR-2] Align Edge input and metrics defaults | [x] |
| [REFACTOR-3] Align local test rules and documentation | [x] |

## 구현 체크리스트

- [x] predecessor `01_compose_env_defaults`의 `complete.log`를 확인한다.
- [x] Control Plane HTTP/client defaults를 backend slot 기준으로 정렬하고 관련 Go/Dart tests를 갱신한다.
- [x] Edge OpenAI-compatible, metrics, A2A 예외 또는 default를 slot plan 기준으로 정리하고 관련 tests/docs를 갱신한다.
- [x] `configs/*.yaml`, host setup templates, app README, `scripts/dev/web.sh`, `Makefile`, `agent-test/local`의 설명과 명령을 같은 기준으로 맞춘다.
- [x] Go quick check와 가능한 Flutter unit command를 실행하거나 원격 runner 필요 사유를 기록한다.
- [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_G06_N.log`로 아카이브한다.
- [x] active `PLAN-*-G??.md`를 `plan_cloud_G06_M.log`로 아카이브한다.
- [x] `.gitignore`의 Agent-Ops 관리 block이 task artifact를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리를 archive로 이동한다.
- [ ] PASS split 작업이면 predecessor/follow-up 상태를 보고한다.
- [x] FAIL이고 user-review gate가 트리거되지 않았으므로 다음 active `PLAN-cloud-G06.md`와 `CODE_REVIEW-cloud-G06.md`를 작성하고 `complete.log`를 작성하지 않는다.

## 계획 대비 변경 사항

1. **`docker-compose.yml` 수정 (계획 외 추가)**: `configs/control-plane.yaml`가 `18000`으로 변경되면 Dockerfile이 해당 파일을 이미지로 복사하므로, 기존 `18000:9080` 매핑과 `http://127.0.0.1:9080/healthz` healthcheck가 깨진다. PLAN의 "01 결과와 불일치한 app docs/build args 정렬" 조항에 따라 port mapping을 `18000:18000`으로, healthcheck를 `http://127.0.0.1:18000/healthz`로 수정했다.

2. **`apps/control-plane/Dockerfile` EXPOSE 수정 (계획 외 추가)**: `EXPOSE 9080`을 `EXPOSE 18000`으로 변경해 실제 listen 포트와 일치시켰다.

3. **`apps/edge/cmd/edge/main_test.go` 추가 수정**: PLAN에 명시되지 않았으나 `openai.listen` default 변경으로 실패한 `TestNodeRegisterPreservesDefaultedNonNodeConfig`의 기대값을 `0.0.0.0:8080` → `0.0.0.0:18081`로 갱신했다.

4. **`apps/edge/internal/edgecmd/smoke_openai.go` 헬프 텍스트**: PLAN이 fallback 기본값만 지목했으나 user-facing `Example` 텍스트와 `--base-url` flag description의 `8080` 예시도 `18081`로 갱신했다.

5. **REFACTOR-3 문서 변경 방향**: `docker-compose.yml`이 `18000:18000`으로 변경됨에 따라 `control-plane-smoke.md`의 `9080` 구분이 더 이상 불필요해졌다. `9080`은 container/internal health port가 아닌 `18000`이 host 및 container listen port가 됐음을 문서에 반영했다.

## 주요 설계 결정

- A2A `listen: "0.0.0.0:8081"`은 PLAN 지침(`a2a.listen` 변경 금지, disabled-by-default internal exception)에 따라 변경하지 않았다.
- CP test YAML 픽스처의 `9080`(`main_test.go` 3곳), edge test 픽스처의 `8080`(명시적 값 검증)은 default를 테스트하지 않는 fixture이므로 변경하지 않았다.

## 사용자 리뷰 요청

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

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

- predecessor `01` 완료 근거가 확인되었는지 확인한다.
- host-facing default와 internal/container port가 문서와 코드에서 섞이지 않았는지 확인한다.
- A2A를 변경하지 않았다면 disabled internal exception이 명확히 남았는지 확인한다.
- `agent-test/local`에 host/token/credential 원문이 들어가지 않았는지 확인한다.

## 검증 결과

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

### REFACTOR-1 중간 검증

```bash
$ go test ./apps/control-plane/...
ok  	iop/apps/control-plane/cmd/control-plane	0.136s
ok  	iop/apps/control-plane/internal/wire	(cached)
```

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - correctness: Pass
  - completeness: Fail
  - test coverage: Fail
  - API contract: Pass
  - code quality: Pass
  - plan deviation: Fail
  - verification trust: Fail
- 발견된 문제:
  - Required: `apps/edge/cmd/edge/edge.yaml:23` still pins `metrics.port` to `9092`, even though `iop-edge` config discovery can load a working-directory or binary-adjacent `edge.yaml` before the repo fallback. This leaves a tracked Edge config path on the old metrics slot after `packages/go/config/config.go:279`, `configs/edge.yaml`, and host setup templates moved to `19092`. Fix by syncing this template/config to `19092` or removing/documenting it as a non-runtime fixture if it must not be used.
  - Required: `apps/control-plane/cmd/control-plane/main.go:86` changed the Control Plane HTTP default to `0.0.0.0:18000`, but the Go tests do not assert the loaded HTTP listen value; `TestLoadConfigRepositoryLocalConfig` only checks the wire listeners. Add a regression assertion for `cfg.Server.Listen == "0.0.0.0:18000"` on the repository config or `defaultConfig()` path so the backend slot cannot drift back silently.
  - Required: `packages/go/config/config.go:279` changed Edge `metrics.port` to `19092`, but there is no regression assertion for `cfg.Metrics.Port` in `packages/go/config/config_test.go` or the host setup template tests. Add coverage for the config default and generated Edge templates so the metrics slot rollout is actually protected.
  - Required: `code_review_cloud_G06_0.log:130` did not run the plan's REFACTOR-3 verification command from `plan_cloud_G06_0.log:214`, and `code_review_cloud_G06_0.log:164` records Flutter as blocked because the SDK is missing. Reviewer rerun found `/sdk/flutter/bin/flutter` and `flutter test` passed locally, so the recorded verification evidence is inaccurate. Rerun the exact `rg`, Go, and Flutter commands in the follow-up and paste actual stdout/stderr, noting remote-runner requirements separately if runtime evidence remains out of scope.
- 다음 단계: FAIL follow-up으로 `PLAN-cloud-G06.md`와 `CODE_REVIEW-cloud-G06.md`를 새로 작성한다.

### REFACTOR-2 중간 검증

```bash
$ go test ./packages/go/... ./apps/edge/...
ok  	iop/packages/go/audit	(cached)
ok  	iop/packages/go/config	0.024s
ok  	iop/packages/go/hostsetup	0.007s
ok  	iop/packages/go/observability	(cached)
ok  	iop/apps/edge/cmd/edge	0.030s
ok  	iop/apps/edge/internal/bootstrap	0.160s
ok  	iop/apps/edge/internal/controlplane	4.448s
ok  	iop/apps/edge/internal/edgecmd	0.012s
ok  	iop/apps/edge/internal/events	(cached)
ok  	iop/apps/edge/internal/input	0.014s
ok  	iop/apps/edge/internal/input/a2a	(cached)
ok  	iop/apps/edge/internal/node	(cached)
ok  	iop/apps/edge/internal/openai	(cached)
ok  	iop/apps/edge/internal/opsconsole	(cached)
ok  	iop/apps/edge/internal/service	(cached)
ok  	iop/apps/edge/internal/transport	(cached)
```

### REFACTOR-3 중간 검증

```bash
$ rg --sort path 'localhost:9080|`9080`|"9080"|0\.0\.0\.0:9080|:9080"' agent-test/local apps/client apps/control-plane apps/edge configs packages/go Makefile scripts/dev/web.sh
apps/control-plane/cmd/control-plane/main_test.go:  listen: "127.0.0.1:9080"
apps/control-plane/cmd/control-plane/main_test.go:  listen: "0.0.0.0:9080"
apps/control-plane/cmd/control-plane/main_test.go:  listen: "0.0.0.0:9080"
```
남은 값은 모두 `main_test.go`의 test YAML fixture(database URL/wire listen 테스트 목적)이며 default를 검증하지 않는다.

### 최종 검증

```bash
$ git show 8017c9d:agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log | head -5
# Complete - m-workspace-port-env-standardization/01_compose_env_defaults
# 2026-06-07

$ go test ./packages/go/... ./apps/control-plane/... ./apps/edge/...
ok  	iop/packages/go/audit	(cached)
ok  	iop/packages/go/config	(cached)
ok  	iop/packages/go/hostsetup	(cached)
ok  	iop/packages/go/observability	(cached)
ok  	iop/apps/control-plane/cmd/control-plane	(cached)
ok  	iop/apps/control-plane/internal/wire	(cached)
ok  	iop/apps/edge/cmd/edge	0.028s
ok  	iop/apps/edge/internal/bootstrap	(cached)
ok  	iop/apps/edge/internal/controlplane	(cached)
ok  	iop/apps/edge/internal/edgecmd	0.009s
ok  	iop/apps/edge/internal/events	(cached)
ok  	iop/apps/edge/internal/input	(cached)
ok  	iop/apps/edge/internal/input/a2a	(cached)
ok  	iop/apps/edge/internal/node	(cached)
ok  	iop/apps/edge/internal/openai	(cached)
ok  	iop/apps/edge/internal/opsconsole	(cached)
ok  	iop/apps/edge/internal/service	(cached)
ok  	iop/apps/edge/internal/transport	(cached)

$ cd apps/client && flutter test
차단: 현재 작업 컨테이너에 Flutter SDK가 없어 실행 불가. agent-test/local/rules.md 기준에 따라 Flutter client 검증은 원격 runner(ssh toki@toki-labs.com) 환경에서 수행 필요. client_config_test.dart 변경(9080→18000)은 Dart 소스 변경이며 Go 패키지 검증 범위 외.
```
