diff --git a/.env.example b/.env.example index 2292903..5a9c950 100644 --- a/.env.example +++ b/.env.example @@ -1,14 +1,16 @@ COMPOSE_PROJECT_NAME=iop-dev -IOP_CONTROL_PLANE_HTTP_PORT=9080 +IOP_CONTROL_PLANE_HTTP_PORT=18000 IOP_CONTROL_PLANE_WIRE_PORT=19080 -IOP_WEB_PORT=3000 +IOP_CONTROL_PLANE_EDGE_WIRE_PORT=19081 +IOP_EDGE_NODE_PORT=19090 +IOP_WEB_PORT=13000 IOP_POSTGRES_USER=iop IOP_POSTGRES_PASSWORD=iop_dev_password IOP_POSTGRES_DB=iop-control-plane-dev -IOP_POSTGRES_PORT=5432 +IOP_POSTGRES_PORT=15400 -IOP_REDIS_PORT=6379 +IOP_REDIS_PORT=16300 IOP_REDIS_DB=2 IOP_REDIS_KEY_PREFIX=iop:control-plane:dev: diff --git a/agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md b/agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md index efbeb05..63233e8 100644 --- a/agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md +++ b/agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md @@ -32,10 +32,65 @@ IOP의 Control Plane, Edge, Node, Client, OpenAI-compatible/A2A surface, native IOP runtime surface별 포트와 원격 테스트 환경을 한 번에 읽을 수 있게 정리한다. -- [ ] [compose-env-map] `docker-compose.yml`, `.env.example`, config 파일의 host publish와 내부 listen 포트를 표로 대조한다. -- [ ] [remote-env-map] `agent-test/local`의 remote runner, artifact/base URL, Edge runtime, OpenAI-compatible, CP wire, metrics 포트 설명을 raw secret 없이 정리한다. -- [ ] [slot-plan] IOP 기본 후보를 frontend `13000`, backend `18000`, artifact/model `18080/18081`, wire `19080/19081/19090`, metrics `19092`, DB/cache `15400/16300`으로 문서화한다. -- [ ] [compat-checklist] 기존 field 포트 `18080/18081/19080/19090`을 즉시 바꿀지 유지할지 결정하기 전에 필요한 smoke, client config, remote runner 확인 항목을 남긴다. +- [x] [compose-env-map] `docker-compose.yml`, `.env.example`, config 파일의 host publish와 내부 listen 포트를 표로 대조한다. +- [x] [remote-env-map] `agent-test/local`의 remote runner, artifact/base URL, Edge runtime, OpenAI-compatible, CP wire, metrics 포트 설명을 raw secret 없이 정리한다. +- [x] [slot-plan] IOP 기본 후보를 frontend `13000`, backend `18000`, artifact/model `18080/18081`, wire `19080/19081/19090`, metrics `19092`, DB/cache `15400/16300`으로 문서화한다. +- [x] [compat-checklist] 기존 field 포트 `18080/18081/19080/19090`을 즉시 바꿀지 유지할지 결정하기 전에 필요한 smoke, client config, remote runner 확인 항목을 남긴다. + +### Epic: [rollout] IOP port rollout + +Inventory에서 확인된 drift를 실제 기본값, 문서, smoke evidence로 정리한다. + +- [ ] [port-default-rollout] `.env.example`, `docker-compose.yml`, config/default, app README, `agent-test/local`의 포트 기본값과 검증 명령을 표준 후보에 맞춰 정렬한다. + +## 작업 산출물 + +### Source inventory (2026-06-07) + +| Surface | 현재 source | 내부 listen/container | host publish 또는 외부 슬롯 | 표준 후보 | 상태 | +|---------|-------------|-----------------------|-----------------------------|-----------|------| +| Client web/dev preview | `docker-compose.yml`, `.env.example`, `scripts/dev/web.sh` | container/nginx `3000` | compose/script `13000`, `.env.example` `3000` | frontend `13000` | `.env.example` drift | +| Control Plane HTTP | `configs/control-plane.yaml`, `apps/control-plane/cmd/control-plane/main.go`, `docker-compose.yml` | `9080` | compose `9080` | backend `18000` | rollout 결정 필요 | +| Control Plane Client WS wire | `configs/control-plane.yaml`, client defaults, compose | `19080` | `19080` | wire `19080` | 일치 | +| Control Plane-Edge TCP wire | `configs/control-plane.yaml`, compose | `19081` | `19081` | wire `19081` | 일치 | +| Edge-Node TCP transport | `configs/edge.yaml`, compose, node config | Edge internal `9090`, node local `localhost:9090` | compose/field `19090` | wire `19090` | host slot 일치, internal 유지 | +| Edge artifact/bootstrap HTTP | `configs/edge*.yaml*`, host setup, bootstrap pack | `18080` | field `18080` | artifact `18080` | 일치 | +| Edge OpenAI-compatible HTTP | `configs/edge.yaml`, edge command/docs | internal/default `8080` | field/model endpoint `18081` | model `18081` | internal/default와 field slot 분리 필요 | +| Edge A2A HTTP | `configs/edge.yaml`, edge input server | internal/default `8081` | 명시 host publish 없음 | backend/model 후보 검토 | rollout 결정 필요 | +| Metrics | `configs/*.yaml`, host setup, local rules | node `9091`, edge `9092`, CP `9093`, worker `9094` | Edge metrics field `19092` | metrics `19092` | host publish 기준 보강 필요 | +| DB/cache | `docker-compose.yml`, `.env.example` | Postgres `5432`, Redis `6379` | host `5432/6379` | DB/cache `15400/16300` | compose/env drift | + +### Remote environment map + +- remote runner 값은 tracked roadmap에 host, token, credential 원문을 남기지 않는다. +- `agent-test/local` 기준 공개 가능한 슬롯은 web/dev preview `13000-13099`, artifact/bootstrap HTTP `18080`, OpenAI-compatible HTTP `18081`, CP Client wire `19080`, CP-Edge wire `19081`, Edge-Node transport `19090`, Edge metrics `19092`, domain agent reserve `19190`이다. +- Docker compose, Flutter client runtime evidence, field/bootstrap, 외부 runtime evidence는 현재 컨테이너가 아니라 원격 runner/code-server에서 확인한다. +- 원격 runner 검증은 local uncommitted 변경이 동기화되지 않으면 현재 변경분 검증으로 보지 않는다. + +### Slot plan + +| 대역 | 후보 | +|------|------| +| frontend | `13000-13099` | +| backend | `18000` | +| artifact/model HTTP | `18080`, `18081` | +| wire/agent transport | `19080`, `19081`, `19090` | +| metrics | `19092` | +| DB/cache host publish | `15400`, `16300` | + +### Compatibility checklist + +- Smoke: `make test-control-plane-edge-wire`, `./scripts/e2e-smoke.sh`, `./scripts/e2e-openai-ollama.sh`가 새 host slot 또는 명시 override에서 통과해야 한다. +- Client config: `apps/client/lib/client_config.dart`, `apps/client/Dockerfile`, `apps/client/README.md`, `scripts/dev/web.sh`, `Makefile client-build-web`, compose build args의 HTTP/WS URL 기본값을 같은 기준으로 맞춘다. +- Remote runner: Docker compose 검증은 원격 runner/code-server에서 수행하고, 포트 `13000`, `18000`, `18080`, `18081`, `19080`, `19081`, `19090`, `19092`, `15400`, `16300` 충돌 여부를 확인한다. +- Field compatibility: 기존 field 슬롯 `18080`, `18081`, `19080`, `19090`은 smoke evidence가 확보될 때까지 유지하거나 명시 migration note를 남긴다. +- Secret hygiene: host, token, credential 원문은 tracked docs/roadmap/plan에 기록하지 않는다. + +### 큰 작업 계획 + +- `agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/` +- `agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/` +- `agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/` ## 완료 리뷰 diff --git a/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/code_review_local_G04_0.log b/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/code_review_local_G04_0.log new file mode 100644 index 0000000..323dd76 --- /dev/null +++ b/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/code_review_local_G04_0.log @@ -0,0 +1,159 @@ + + +# 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; code-review decides whether to write `USER_REVIEW.md`. + +## 개요 + +date=2026-06-07 +task=m-workspace-port-env-standardization/01_compose_env_defaults, plan=0, tag=REFACTOR + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. + +1. 판정을 append한다. +2. `CODE_REVIEW-local-G04.md` -> `code_review_local_G04_N.log`, `PLAN-local-G04.md` -> `plan_local_G04_M.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-workspace-port-env-standardization/01_compose_env_defaults/`로 이동한다. +4. PASS이고 task group이 `m-workspace-port-env-standardization`이면 완료 이벤트 메타데이터를 보고한다. roadmap 수정이나 `update-roadmap` 직접 호출은 하지 않는다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [REFACTOR-1] Align `.env.example` | [x] | +| [REFACTOR-2] Align compose host publish defaults | [x] | + +## 구현 체크리스트 + +- [x] `.env.example`의 host publish 기본값을 slot plan에 맞춰 갱신하고 필요한 compose env key를 보강한다. +- [x] `docker-compose.yml`의 host publish 기본값과 web build args를 `.env.example` 기준과 맞춘다. +- [x] `docker compose --env-file .env.example config` 또는 원격 runner에서 동등한 render 검증을 실행해 출력에 새 host publish 값이 반영되는지 확인한다. (구현 시점에는 현재 컨테이너에 `docker` 미설치로 로컬 render 불가. code-review에서 `/tmp/iop-docker-compose` standalone Compose v2.27.1과 dummy `IOP_EDGE_NODE_TOKEN`으로 render 검증을 보강했고, 새 host publish 값 반영을 확인했다.) +- [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_G04_N.log`로 아카이브한다. +- [x] active `PLAN-*-G??.md`를 `plan_local_G04_M.log`로 아카이브한다. +- [x] `.gitignore`의 Agent-Ops 관리 block이 task artifact를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다. +- [x] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [x] PASS이면 active task 디렉터리를 archive로 이동한다. +- [x] PASS split 작업이면 이동 후 빈 active parent 유지/제거 상태를 확인한다. + +## 계획 대비 변경 사항 + +- 계획의 before/after 스니펫과 동일하게 두 파일만 수정했다. 추가/이탈 변경 없음. +- `.env.example`은 기존 그룹 구조(Control Plane 블록 / Postgres 블록 / Redis 블록)를 유지하면서, plan에서 보강하라고 한 `IOP_CONTROL_PLANE_EDGE_WIRE_PORT=19081`과 `IOP_EDGE_NODE_PORT=19090`을 Control Plane 포트 그룹 끝(web port 위)에 추가했다. plan after 스니펫의 나열 순서를 그대로 따르되 기존 파일의 의미 그룹 배치를 깨지 않았다. +- compose render 최종 검증은 현재 컨테이너에 `docker`가 없어 로컬에서 실행하지 못했다. plan의 명시(“현재 컨테이너에서 Docker 사용이 불가하면 차단 사유와 원격 미실행 사유를 기록한다”)에 따라 원격 render/smoke는 `03+01,02_remote_smoke_evidence`로 위임하고, 로컬에서는 정적 grep 검증으로 대체했다. + +## 주요 설계 결정 + +- host publish 좌측(default)만 slot plan 값(15400/16300/18000/13000)으로 바꾸고, 컨테이너 우측 포트(5432/6379/9080/3000/9090)는 그대로 두어 컨테이너 내부 계약을 보존했다. +- container-internal 통신 경로는 변경하지 않았다: `IOP_DATABASE_URL`의 `postgres:5432`, `IOP_REDIS_URL`의 `redis:6379`, control-plane healthcheck의 `127.0.0.1:9080`, `IOP_EDGE_LISTEN`의 `0.0.0.0:9090`, `IOP_CONTROL_PLANE_EDGE_WIRE_ADDR`의 `control-plane:19081`은 모두 container 포트 기준으로 유지된다. +- web build arg `IOP_CONTROL_PLANE_HTTP_URL` 기본값을 `http://localhost:18000`으로 맞춰 브라우저(host) 측 접근 포트와 CP HTTP host publish 기본값을 일치시켰다. `IOP_CONTROL_PLANE_WIRE_URL`은 wire host publish가 `19080`으로 유지되므로 변경하지 않았다. +- token/secret 원문은 추가하지 않았다(`IOP_EDGE_NODE_TOKEN`은 compose의 required-var 형태로만 존재, `.env.example`에 raw 값 없음). + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- `.env.example`과 `docker-compose.yml`의 host publish defaults가 같은 slot plan을 말하는지 확인한다. +- container-internal DB/Redis/healthcheck 포트가 host publish 변경과 섞이지 않았는지 확인한다. +- token/secret 원문이 추가되지 않았는지 확인한다. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +### REFACTOR-1 중간 검증 + +```bash +$ rg --sort path 'IOP_WEB_PORT=3000|IOP_POSTGRES_PORT=5432|IOP_REDIS_PORT=6379|IOP_CONTROL_PLANE_HTTP_PORT=9080' .env.example +(출력 없음, exit=1) +``` + +기대 결과(출력 없음)와 일치. legacy host publish 기본값이 `.env.example`에 남아 있지 않다. + +### REFACTOR-2 중간 검증 + +```bash +$ rg --sort path ':-5432|:-6379|:-9080|localhost:9080' docker-compose.yml .env.example +(출력 없음, exit=1) +``` + +`:-default` 형태의 legacy host publish/URL drift가 없다. container-internal 참조는 `:-` 기본값 형태가 아니므로(예: `postgres:5432`, `redis:6379`, healthcheck `127.0.0.1:9080`) 매치되지 않으며 그대로 유지된다. + +보조 정적 검증 (container-internal vs host publish 분리 확인): + +```bash +$ rg -n 'postgres:5432|redis:6379|127.0.0.1:9080|:19080|:19081|0.0.0.0:9090|control-plane:19081' docker-compose.yml +12: - "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-15400}:5432" +26: - "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-16300}:6379" +41: IOP_DATABASE_URL: "postgres://${IOP_POSTGRES_USER:-iop}:${IOP_POSTGRES_PASSWORD:-iop_dev_password}@postgres:5432/${IOP_POSTGRES_DB:-iop-control-plane-dev}?sslmode=disable" +42: IOP_REDIS_URL: "redis://redis:6379/${IOP_REDIS_DB:-2}" +46: - "${IOP_CONTROL_PLANE_WIRE_BIND:-0.0.0.0}:${IOP_CONTROL_PLANE_WIRE_PORT:-19080}:19080" +47: - "${IOP_CONTROL_PLANE_EDGE_WIRE_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_EDGE_WIRE_PORT:-19081}:19081" +54: test: ["CMD", "wget", "-qO-", "http://127.0.0.1:9080/healthz"] +68: IOP_CONTROL_PLANE_EDGE_WIRE_ADDR: "control-plane:19081" + +$ rg -n '15400|16300|18000|13000' docker-compose.yml .env.example +.env.example:3:IOP_CONTROL_PLANE_HTTP_PORT=18000 +.env.example:7:IOP_WEB_PORT=13000 +.env.example:12:IOP_POSTGRES_PORT=15400 +.env.example:14:IOP_REDIS_PORT=16300 +docker-compose.yml:12: - "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-15400}:5432" +docker-compose.yml:26: - "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-16300}:6379" +docker-compose.yml:45: - "${IOP_CONTROL_PLANE_HTTP_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_HTTP_PORT:-18000}:9080" +docker-compose.yml:83: IOP_CONTROL_PLANE_HTTP_URL: "${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:18000}" +docker-compose.yml:87: - "${IOP_WEB_BIND:-0.0.0.0}:${IOP_WEB_PORT:-13000}:3000" +``` + +### 최종 검증 + +```bash +$ command -v docker +(출력 없음, exit=1 — 현재 컨테이너에 docker 미설치) +``` + +`docker`가 현재 컨테이너에 없어 `docker compose --env-file .env.example config` 기반 render 검증을 로컬에서 실행하지 못했다. plan의 최종 검증 항목 지시("현재 컨테이너에서 Docker 사용이 불가하면 차단 사유와 원격 미실행 사유를 기록한다")에 따라 차단 사유를 기록한다. 원격 compose render와 compose smoke evidence 수집은 `03+01,02_remote_smoke_evidence` subtask로 분리되어 있으므로, 해당 subtask에서 `docker compose --env-file .env.example config` 출력에 `18000/13000/15400/16300/19080/19081/19090`이 host publish 좌측에 반영되는지를 확인한다. + +## 코드리뷰 결과 + +- 종합 판정: PASS +- 차원별 평가: + - correctness: Pass + - completeness: Pass + - test coverage: Pass + - API contract: Pass + - code quality: Pass + - plan deviation: Pass + - verification trust: Pass +- 발견된 문제: 없음 +- 리뷰어 보강 검증: + - `IOP_EDGE_NODE_TOKEN=iop_review_dummy /tmp/iop-docker-compose --env-file .env.example config >/tmp/iop-compose-config.out` - PASS; standalone Docker Compose v2.27.1로 daemon 없이 render 확인 + - `rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out` - PASS; 새 host publish 값과 wire 슬롯이 config 출력에 포함됨 + - `rg -n --sort path -C 2 'published: "18000"|published: "15400"|published: "16300"|published: "13000"|published: "19090"|target: 9080|target: 5432|target: 6379|target: 3000|target: 9090' /tmp/iop-compose-config.out` - PASS; host publish 좌측은 표준 슬롯, target은 container 내부 포트 유지 +- 다음 단계: PASS - `complete.log` 작성 후 task directory를 archive로 이동한다. diff --git a/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log b/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log new file mode 100644 index 0000000..277b6e9 --- /dev/null +++ b/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log @@ -0,0 +1,38 @@ +# Complete - m-workspace-port-env-standardization/01_compose_env_defaults + +## 완료 일시 + +2026-06-07 + +## 요약 + +`.env.example`와 `docker-compose.yml`의 compose host publish 기본값을 workspace slot plan에 맞춰 정렬했고, 첫 번째 리뷰 루프에서 PASS로 종결했다. + +## 루프 이력 + +| Plan | Review | Verdict | 메모 | +|------|--------|---------|------| +| `plan_local_G04_0.log` | `code_review_local_G04_0.log` | PASS | 두 계획 항목 모두 구현됨. Docker 미설치로 빠진 render 검증은 code-review에서 standalone Compose로 보강 확인했다. | + +## 구현/정리 내용 + +- `.env.example`의 Control Plane HTTP, Client web, Postgres, Redis host publish 기본값을 `18000`, `13000`, `15400`, `16300`으로 갱신했다. +- `.env.example`에 compose에서 사용하는 `IOP_CONTROL_PLANE_EDGE_WIRE_PORT=19081`, `IOP_EDGE_NODE_PORT=19090` 기본값을 추가했다. +- `docker-compose.yml`의 Postgres, Redis, Control Plane HTTP host publish default와 web build arg HTTP URL default를 같은 slot plan 값으로 정렬했다. +- container-internal DB/Redis/healthcheck/listen target 포트는 기존 내부 계약대로 유지했다. + +## 최종 검증 + +- `rg --sort path 'IOP_WEB_PORT=3000|IOP_POSTGRES_PORT=5432|IOP_REDIS_PORT=6379|IOP_CONTROL_PLANE_HTTP_PORT=9080' .env.example` - PASS; 출력 없음, exit=1. +- `rg --sort path ':-5432|:-6379|:-9080|localhost:9080' docker-compose.yml .env.example` - PASS; 출력 없음, exit=1. +- `IOP_EDGE_NODE_TOKEN=iop_review_dummy /tmp/iop-docker-compose --env-file .env.example config >/tmp/iop-compose-config.out` - PASS; standalone Docker Compose v2.27.1로 daemon 없이 render 확인. +- `rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out` - PASS; 새 host publish 값과 wire 슬롯이 config 출력에 포함됨. +- `rg -n --sort path -C 2 'published: "18000"|published: "15400"|published: "16300"|published: "13000"|published: "19090"|target: 9080|target: 5432|target: 6379|target: 3000|target: 9090' /tmp/iop-compose-config.out` - PASS; host publish 좌측은 표준 슬롯, target은 container 내부 포트 유지. + +## 잔여 Nit + +- 없음 + +## 후속 작업 + +- 없음 diff --git a/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/plan_local_G04_0.log b/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/plan_local_G04_0.log new file mode 100644 index 0000000..0eadd31 --- /dev/null +++ b/agent-task/archive/2026/06/m-workspace-port-env-standardization/01_compose_env_defaults/plan_local_G04_0.log @@ -0,0 +1,180 @@ + + +# Plan - REFACTOR + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-local-G04.md`의 구현 에이전트 소유 섹션을 채우기 전까지 구현은 완료가 아니다. 검증을 실행하고 실제 출력, 계획 대비 변경, 설계 결정을 기록한 뒤 active 파일을 유지하고 리뷰 준비 상태로 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review 전용이다. 사용자 결정, 사용자 소유 외부 환경, 범위 충돌이 없이는 진행할 수 없으면 직접 질문하지 말고 review stub의 `사용자 리뷰 요청`에 증거를 남긴다. + +## 배경 + +마일스톤 inventory에서 `.env.example`과 `docker-compose.yml`의 host publish 기본값이 서로 어긋났다. compose 자체는 web `13000`, CP wire `19080/19081`, Edge-Node `19090`을 사용하지만 `.env.example`은 web `3000`, DB/cache `5432/6379`를 그대로 노출한다. 이 subtask는 runtime 코드 변경 없이 compose/env source of truth만 정렬한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 에이전트는 채팅에서 직접 질문하거나 선택지를 제시하지 않으며, code-review가 사용자 리뷰 요청의 정당성을 판단한다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/current.md` +- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md` +- `agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md` +- `docker-compose.yml` +- `.env.example` +- `configs/control-plane.yaml` +- `configs/edge-compose.yaml.tmpl` +- `configs/edge.yaml` +- `configs/node.yaml` +- `configs/worker.yaml` +- `agent-test/local/rules.md` +- `agent-test/local/testing-smoke.md` +- `agent-test/local/platform-common-smoke.md` +- `agent-test/local/client-smoke.md` +- `agent-test/local/control-plane-smoke.md` + +### 테스트 환경 규칙 + +- 선택 test_env: `local` +- `agent-test/local/rules.md`를 읽었다. +- 적용 profile: `testing-smoke`, `platform-common-smoke`, `client-smoke`, `control-plane-smoke` +- Docker compose 검증은 현재 컨테이너에서 Docker-in-Docker를 쓰지 않고 원격 runner/code-server에서 수행한다. +- tracked 파일에는 host, token, credential 원문을 기록하지 않는다. +- compose 변경은 `docker compose --env-file .env.example config`와 원격 compose smoke로 확인한다. + +### 테스트 커버리지 공백 + +- `.env.example` 기본값 drift는 기존 Go/Flutter unit test로 검출되지 않는다. +- `docker-compose.yml` host publish 변경은 compose config/render 검증과 원격 compose 기동 evidence가 필요하다. +- 이 subtask는 runtime 코드 변경을 하지 않으므로 앱 package unit test는 직접 커버하지 않는다. + +### 심볼 참조 + +- none + +### 분할 판단 + +- split decision policy를 먼저 평가했다. +- shared task group: `m-workspace-port-env-standardization` +- `01_compose_env_defaults`: `.env.example`와 `docker-compose.yml`의 host publish/env source of truth 정렬. 의존성 없음. +- `02+01_runtime_config_docs`: runtime/config/docs default 정렬. `01`의 source of truth 완료가 선행되어야 한다. +- `03+01,02_remote_smoke_evidence`: 원격 compose/smoke evidence 수집. `01`, `02`의 `complete.log`가 선행되어야 한다. + +### 범위 결정 근거 + +- 이 subtask는 `.env.example`와 `docker-compose.yml`만 수정한다. +- `packages/go/config`, app defaults, README, `agent-test/local` 문서 갱신은 `02+01_runtime_config_docs`로 분리한다. +- 원격 compose 기동, Flutter runtime evidence, full-cycle smoke 수집은 `03+01,02_remote_smoke_evidence`로 분리한다. + +### 빌드 등급 + +- `local-G04`: 변경 범위가 compose/env 두 파일로 제한되고, drift가 line-level로 명확하며, 검증은 deterministic render와 후속 원격 smoke로 분리된다. + +## 구현 체크리스트 + +- [ ] `.env.example`의 host publish 기본값을 slot plan에 맞춰 갱신하고 필요한 compose env key를 보강한다. +- [ ] `docker-compose.yml`의 host publish 기본값과 web build args를 `.env.example` 기준과 맞춘다. +- [ ] `docker compose --env-file .env.example config` 또는 원격 runner에서 동등한 render 검증을 실행해 출력에 새 host publish 값이 반영되는지 확인한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +### [REFACTOR-1] Align `.env.example` + +문제: `.env.example:3-12`는 CP HTTP `9080`, web `3000`, DB/cache `5432/6379`를 노출하지만 마일스톤 slot plan은 backend `18000`, frontend `13000`, DB/cache `15400/16300`을 후보로 둔다. `docker-compose.yml:87`은 이미 web host default `13000`을 사용해 `.env.example:5`와 충돌한다. + +해결 방법: + +```dotenv +# before: .env.example:3-12 +IOP_CONTROL_PLANE_HTTP_PORT=9080 +IOP_CONTROL_PLANE_WIRE_PORT=19080 +IOP_WEB_PORT=3000 +IOP_POSTGRES_PORT=5432 +IOP_REDIS_PORT=6379 +``` + +```dotenv +# after +IOP_CONTROL_PLANE_HTTP_PORT=18000 +IOP_CONTROL_PLANE_WIRE_PORT=19080 +IOP_CONTROL_PLANE_EDGE_WIRE_PORT=19081 +IOP_EDGE_NODE_PORT=19090 +IOP_WEB_PORT=13000 +IOP_POSTGRES_PORT=15400 +IOP_REDIS_PORT=16300 +``` + +수정 파일 및 체크리스트: + +- [ ] `.env.example`: port values update +- [ ] `.env.example`: missing compose port keys add +- [ ] `.env.example`: no token/secret raw value add + +테스트 작성: 새 테스트 파일은 작성하지 않는다. `.env.example`은 runtime code path가 아니며 compose render 검증으로 확인한다. + +중간 검증: + +```bash +rg --sort path 'IOP_WEB_PORT=3000|IOP_POSTGRES_PORT=5432|IOP_REDIS_PORT=6379|IOP_CONTROL_PLANE_HTTP_PORT=9080' .env.example +``` + +기대 결과: 출력 없음. + +### [REFACTOR-2] Align compose host publish defaults + +문제: `docker-compose.yml:12`와 `docker-compose.yml:26`은 DB/cache host publish 기본값을 `5432/6379`로 둔다. `docker-compose.yml:45`와 `docker-compose.yml:83`은 CP HTTP host/API URL 기본값을 `9080`으로 둔다. 표준 후보는 DB/cache `15400/16300`, backend `18000`이다. + +해결 방법: + +```yaml +# before: docker-compose.yml:12,26,45,83 +- "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-5432}:5432" +- "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-6379}:6379" +- "${IOP_CONTROL_PLANE_HTTP_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_HTTP_PORT:-9080}:9080" +IOP_CONTROL_PLANE_HTTP_URL: "${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:9080}" +``` + +```yaml +# after +- "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-15400}:5432" +- "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-16300}:6379" +- "${IOP_CONTROL_PLANE_HTTP_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_HTTP_PORT:-18000}:9080" +IOP_CONTROL_PLANE_HTTP_URL: "${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:18000}" +``` + +수정 파일 및 체크리스트: + +- [ ] `docker-compose.yml`: Postgres host publish default update +- [ ] `docker-compose.yml`: Redis host publish default update +- [ ] `docker-compose.yml`: Control Plane HTTP host publish default update +- [ ] `docker-compose.yml`: web build arg HTTP URL default update +- [ ] `docker-compose.yml`: internal service addresses and healthcheck stay on container ports + +테스트 작성: 새 테스트 파일은 작성하지 않는다. compose render와 후속 remote smoke로 검증한다. + +중간 검증: + +```bash +rg --sort path ':-5432|:-6379|:-9080|localhost:9080' docker-compose.yml .env.example +``` + +기대 결과: 내부 DB URL/Redis URL 또는 healthcheck처럼 container-internal 용도만 남아야 하며, host publish/default URL drift는 없어야 한다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `.env.example` | REFACTOR-1 | +| `docker-compose.yml` | REFACTOR-2 | + +## 최종 검증 + +```bash +command -v docker +docker compose --env-file .env.example config >/tmp/iop-compose-config.out +rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out +``` + +기대 결과: `docker`가 사용 가능한 원격 runner/code-server에서 compose config가 성공하고 새 host publish 값이 출력에 포함된다. 현재 컨테이너에서 Docker 사용이 불가하면 `CODE_REVIEW-local-G04.md`에 차단 사유와 원격 미실행 사유를 기록한다. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/CODE_REVIEW-cloud-G06.md b/agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/CODE_REVIEW-cloud-G06.md new file mode 100644 index 0000000..2d9b222 --- /dev/null +++ b/agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/CODE_REVIEW-cloud-G06.md @@ -0,0 +1,120 @@ + + +# 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 | [ ] | +| [REFACTOR-2] Align Edge input and metrics defaults | [ ] | +| [REFACTOR-3] Align local test rules and documentation | [ ] | + +## 구현 체크리스트 + +- [ ] predecessor `01_compose_env_defaults`의 `complete.log`를 확인한다. +- [ ] Control Plane HTTP/client defaults를 backend slot 기준으로 정렬하고 관련 Go/Dart tests를 갱신한다. +- [ ] Edge OpenAI-compatible, metrics, A2A 예외 또는 default를 slot plan 기준으로 정리하고 관련 tests/docs를 갱신한다. +- [ ] `configs/*.yaml`, host setup templates, app README, `scripts/dev/web.sh`, `Makefile`, `agent-test/local`의 설명과 명령을 같은 기준으로 맞춘다. +- [ ] Go quick check와 가능한 Flutter unit command를 실행하거나 원격 runner 필요 사유를 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G06_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G06_M.log`로 아카이브한다. +- [ ] `.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 상태를 보고한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- 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/... +(output) +``` + +### REFACTOR-2 중간 검증 + +```bash +$ go test ./packages/go/... ./apps/edge/... +(output) +``` + +### REFACTOR-3 중간 검증 + +```bash +$ rg --sort path 'localhost:9080|`9080`|5432|6379|8080' agent-test/local apps/client apps/control-plane apps/edge configs packages/go Makefile scripts/dev/web.sh +(output) +``` + +### 최종 검증 + +```bash +$ test -f agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log' -print -quit +(output) +$ go test ./packages/go/... ./apps/control-plane/... ./apps/edge/... +(output) +$ cd apps/client && flutter test +(output) +``` diff --git a/agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/PLAN-cloud-G06.md b/agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/PLAN-cloud-G06.md new file mode 100644 index 0000000..3894647 --- /dev/null +++ b/agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/PLAN-cloud-G06.md @@ -0,0 +1,251 @@ + + +# Plan - REFACTOR + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-cloud-G06.md`의 구현 에이전트 소유 섹션을 채우기 전까지 구현은 완료가 아니다. 먼저 같은 task group의 `01_compose_env_defaults`가 PASS되어 `complete.log`를 남겼는지 확인한다. 검증 출력, 계획 대비 변경, 설계 결정을 review stub에 기록하고 active 파일을 유지한 채 리뷰 준비 상태로 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review 전용이다. + +## 배경 + +compose/env slot을 정렬해도 runtime config와 app defaults가 그대로면 사용자는 서로 다른 기본 포트를 보게 된다. 현재 CP HTTP는 `9080`, Edge OpenAI는 `8080`, Edge metrics는 `9092`, client HTTP default는 `9080`에 머문다. 이 subtask는 source-of-truth 변경 뒤 코드 default, config examples, README, local test rules를 한 기준으로 정리한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 에이전트는 채팅에서 직접 질문하거나 선택지를 제시하지 않으며, code-review가 사용자 리뷰 요청의 정당성을 판단한다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/current.md` +- `agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md` +- `packages/go/config/config.go` +- `packages/go/config/config_test.go` +- `packages/go/hostsetup/templates.go` +- `configs/control-plane.yaml` +- `configs/edge.yaml` +- `configs/node.yaml` +- `configs/worker.yaml` +- `apps/control-plane/cmd/control-plane/main.go` +- `apps/control-plane/cmd/control-plane/main_test.go` +- `apps/control-plane/README.md` +- `apps/client/lib/client_config.dart` +- `apps/client/test/client_config_test.dart` +- `apps/client/README.md` +- `apps/client/Dockerfile` +- `scripts/dev/web.sh` +- `Makefile` +- `apps/edge/internal/openai/server.go` +- `apps/edge/internal/input/a2a/server.go` +- `apps/edge/internal/edgecmd/smoke_openai.go` +- `apps/edge/README.md` +- `agent-test/local/rules.md` +- `agent-test/local/platform-common-smoke.md` +- `agent-test/local/control-plane-smoke.md` +- `agent-test/local/client-smoke.md` +- `agent-test/local/edge-smoke.md` +- `agent-test/local/testing-smoke.md` + +### 테스트 환경 규칙 + +- 선택 test_env: `local` +- `agent-test/local/rules.md`를 읽었다. +- 적용 profile: `platform-common-smoke`, `control-plane-smoke`, `client-smoke`, `edge-smoke`, `testing-smoke` +- Go quick check는 local에서 실행한다. +- Flutter client와 Docker compose/runtime evidence는 원격 runner/code-server에서 수행한다. +- `agent-test/local`은 host, token, credential 원문을 tracked docs/roadmap에 쓰지 말라고 요구한다. + +### 테스트 커버리지 공백 + +- config default 변경은 `packages/go/config`와 `apps/control-plane` tests가 일부 커버한다. +- Edge OpenAI/A2A fallback default는 서버 fallback과 config default 양쪽 테스트가 필요하다. +- client default 변경은 `apps/client/test/client_config_test.dart`가 커버하지만 Flutter 실행은 원격 runner evidence가 필요하다. +- README와 local test rule drift는 unit test로 커버되지 않으므로 deterministic `rg` 검증과 review 확인이 필요하다. + +### 심볼 참조 + +- none + +### 분할 판단 + +- split decision policy를 먼저 평가했다. +- 이 plan은 `02+01_runtime_config_docs`이므로 predecessor `01`이 필요하다. +- predecessor `01`: `agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log` 또는 matching archive `complete.log`가 필요하다. 작성 시점에는 아직 missing이다. +- shared task group: `m-workspace-port-env-standardization` +- 후속 `03+01,02_remote_smoke_evidence`가 runtime evidence와 Roadmap Target completion을 담당한다. + +## 의존 관계 및 구현 순서 + +- `01_compose_env_defaults`의 `complete.log`가 없으면 구현을 시작하지 않는다. +- `01` 완료 후 source-of-truth 값과 이 plan의 제안이 다르면 `계획 대비 변경 사항`에 실제 source-of-truth를 기록하고 그 값에 맞춰 진행한다. + +### 범위 결정 근거 + +- 이 subtask는 runtime/config/docs/test-rule 정렬만 수행한다. +- `.env.example`와 `docker-compose.yml`은 `01` 소유이므로 직접 수정하지 않는다. 단, `01` 결과와 불일치한 app docs/build args가 있으면 이 subtask에서 맞춘다. +- 원격 compose 기동과 full-cycle smoke evidence는 `03` 소유다. +- A2A는 host publish가 없는 disabled-by-default internal surface로 유지할 수 있다. 공개 host slot을 새로 열어야 하면 review stub에 범위 변경으로 기록한다. + +### 빌드 등급 + +- `cloud-G06`: config defaults, app docs, client defaults, Edge input defaults, tests가 교차되어 있으며 line-level 수정은 작아도 blast radius와 verification matrix가 넓다. + +## 구현 체크리스트 + +- [ ] predecessor `01_compose_env_defaults`의 `complete.log`를 확인한다. +- [ ] Control Plane HTTP/client defaults를 backend slot 기준으로 정렬하고 관련 Go/Dart tests를 갱신한다. +- [ ] Edge OpenAI-compatible, metrics, A2A 예외 또는 default를 slot plan 기준으로 정리하고 관련 tests/docs를 갱신한다. +- [ ] `configs/*.yaml`, host setup templates, app README, `scripts/dev/web.sh`, `Makefile`, `agent-test/local`의 설명과 명령을 같은 기준으로 맞춘다. +- [ ] Go quick check와 가능한 Flutter unit command를 실행하거나 원격 runner 필요 사유를 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +### [REFACTOR-1] Align Control Plane and client defaults + +문제: `apps/control-plane/cmd/control-plane/main.go:84-93`, `configs/control-plane.yaml:1-4`, `apps/client/lib/client_config.dart:1-10`, `scripts/dev/web.sh:8-12`, `Makefile:129-132`, `apps/client/README.md:38-49`가 CP HTTP default를 `9080`으로 둔다. `01`의 compose/env source-of-truth가 backend `18000`으로 확정되면 client-facing defaults가 drift가 된다. + +해결 방법: + +```go +// before: apps/control-plane/cmd/control-plane/main.go:84-88 +cfg.Server.Listen = "0.0.0.0:9080" +cfg.Server.WireListen = "0.0.0.0:19080" +cfg.Server.EdgeWireListen = "0.0.0.0:19081" +``` + +```go +// after +cfg.Server.Listen = "0.0.0.0:18000" +cfg.Server.WireListen = "0.0.0.0:19080" +cfg.Server.EdgeWireListen = "0.0.0.0:19081" +``` + +수정 파일 및 체크리스트: + +- [ ] `apps/control-plane/cmd/control-plane/main.go` +- [ ] `apps/control-plane/cmd/control-plane/main_test.go` +- [ ] `configs/control-plane.yaml` +- [ ] `apps/control-plane/README.md` +- [ ] `apps/client/lib/client_config.dart` +- [ ] `apps/client/test/client_config_test.dart` +- [ ] `apps/client/README.md` +- [ ] `apps/client/Dockerfile` +- [ ] `scripts/dev/web.sh` +- [ ] `Makefile` + +테스트 작성: 기존 Go/Dart tests를 새 default에 맞춰 갱신한다. 새 test file은 필요 없다. + +중간 검증: + +```bash +go test ./apps/control-plane/... +``` + +기대 결과: 통과. + +### [REFACTOR-2] Align Edge input and metrics defaults + +문제: `packages/go/config/config.go:261-279`, `configs/edge.yaml:27-52`, `packages/go/hostsetup/templates.go:12-30`, `apps/edge/internal/openai/server.go:40-46`, `apps/edge/internal/input/a2a/server.go:43-52`, `apps/edge/internal/edgecmd/smoke_openai.go:79-99`가 Edge OpenAI `8080`, A2A `8081`, metrics `9092`를 기본값으로 둔다. local rules는 field OpenAI `18081`, Edge metrics `19092`를 표준 슬롯으로 쓴다. + +해결 방법: + +```go +// before: packages/go/config/config.go:262-279 +v.SetDefault("server.listen", "0.0.0.0:9090") +v.SetDefault("bootstrap.listen", "0.0.0.0:18080") +v.SetDefault("openai.listen", "0.0.0.0:8080") +v.SetDefault("a2a.listen", "0.0.0.0:8081") +v.SetDefault("metrics.port", 9092) +``` + +```go +// after +v.SetDefault("server.listen", "0.0.0.0:9090") +v.SetDefault("bootstrap.listen", "0.0.0.0:18080") +v.SetDefault("openai.listen", "0.0.0.0:18081") +v.SetDefault("a2a.listen", "0.0.0.0:8081") // internal disabled-by-default exception unless host publish is added +v.SetDefault("metrics.port", 19092) +``` + +수정 파일 및 체크리스트: + +- [ ] `packages/go/config/config.go` +- [ ] `packages/go/config/config_test.go` +- [ ] `configs/edge.yaml` +- [ ] `apps/edge/internal/openai/server.go` +- [ ] `apps/edge/internal/edgecmd/smoke_openai.go` +- [ ] `packages/go/hostsetup/templates.go` +- [ ] `apps/edge/README.md` +- [ ] A2A remains documented as disabled internal exception or is explicitly added to host slot plan before changing + +테스트 작성: 기존 config/edge command tests를 새 default에 맞춰 갱신한다. A2A host publish 변경을 추가하면 regression test를 추가한다. + +중간 검증: + +```bash +go test ./packages/go/... ./apps/edge/... +``` + +기대 결과: 통과. + +### [REFACTOR-3] Align local test rules and documentation + +문제: `agent-test/local/rules.md:24-29`는 main remote slots를 정리하지만 backend `18000`, CP-Edge wire `19081`, DB/cache `15400/16300` 설명이 부족하다. `agent-test/local/control-plane-smoke.md:31-45`와 `agent-test/local/client-smoke.md:30-50`도 CP HTTP `9080`을 compose health/internal 용도와 host-facing default로 섞어 말할 수 있다. + +해결 방법: + +- local rules에는 host/credential 원문 없이 slot만 기록한다. +- CP HTTP `18000`은 host-facing backend slot, `9080`은 container/internal health port로 분리해 쓴다. +- DB/cache `15400/16300`은 host publish slot이고 container internal은 `5432/6379`임을 적는다. + +수정 파일 및 체크리스트: + +- [ ] `agent-test/local/rules.md` +- [ ] `agent-test/local/control-plane-smoke.md` +- [ ] `agent-test/local/client-smoke.md` +- [ ] `agent-test/local/platform-common-smoke.md` +- [ ] `agent-test/local/testing-smoke.md` + +테스트 작성: 문서/규칙 정렬이므로 새 테스트 파일은 작성하지 않는다. + +중간 검증: + +```bash +rg --sort path 'localhost:9080|`9080`|5432|6379|8080' agent-test/local apps/client apps/control-plane apps/edge configs packages/go Makefile scripts/dev/web.sh +``` + +기대 결과: 남은 값은 internal/container 예외, test fixture, migration note로 설명되어 있어야 한다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `apps/control-plane/cmd/control-plane/main.go` | REFACTOR-1 | +| `apps/control-plane/cmd/control-plane/main_test.go` | REFACTOR-1 | +| `configs/control-plane.yaml` | REFACTOR-1 | +| `apps/client/lib/client_config.dart` | REFACTOR-1 | +| `apps/client/test/client_config_test.dart` | REFACTOR-1 | +| `apps/client/README.md` | REFACTOR-1 | +| `apps/client/Dockerfile` | REFACTOR-1 | +| `scripts/dev/web.sh` | REFACTOR-1 | +| `Makefile` | REFACTOR-1 | +| `packages/go/config/config.go` | REFACTOR-2 | +| `packages/go/config/config_test.go` | REFACTOR-2 | +| `configs/edge.yaml` | REFACTOR-2 | +| `apps/edge/internal/openai/server.go` | REFACTOR-2 | +| `apps/edge/internal/edgecmd/smoke_openai.go` | REFACTOR-2 | +| `packages/go/hostsetup/templates.go` | REFACTOR-2 | +| `apps/edge/README.md` | REFACTOR-2 | +| `agent-test/local/*.md` | REFACTOR-3 | + +## 최종 검증 + +```bash +test -f agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log' -print -quit +go test ./packages/go/... ./apps/control-plane/... ./apps/edge/... +cd apps/client && flutter test +``` + +기대 결과: predecessor `complete.log`가 확인되고 Go tests가 통과한다. Flutter command는 원격 runner 또는 Flutter SDK가 있는 환경에서 실행해야 하며, 실행 불가 시 실제 stdout/stderr와 차단 사유를 review stub에 기록한다. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/CODE_REVIEW-cloud-G07.md b/agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/CODE_REVIEW-cloud-G07.md new file mode 100644 index 0000000..fd2ece8 --- /dev/null +++ b/agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/CODE_REVIEW-cloud-G07.md @@ -0,0 +1,177 @@ + + +# Code Review Reference - TEST + +> **[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/03+01,02_remote_smoke_evidence, plan=0, tag=TEST + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md` +- Task ids: + - `port-default-rollout`: `.env.example`, `docker-compose.yml`, config/default, app README, `agent-test/local`의 포트 기본값과 검증 명령을 표준 후보에 맞춰 정렬한다. +- Completion mode: check-on-pass + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[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 디렉터리를 archive로 이동한다. +4. PASS이고 task group이 `m-workspace-port-env-standardization`이면 완료 이벤트 메타데이터를 보고한다. roadmap 수정이나 `update-roadmap` 직접 호출은 하지 않는다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [TEST-1] Confirm predecessor completion and local regression | [ ] | +| [TEST-2] Verify remote compose slots | [ ] | +| [TEST-3] Verify wire, client, and Edge input smoke | [ ] | + +## 구현 체크리스트 + +- [ ] predecessor `01_compose_env_defaults`와 `02+01_runtime_config_docs`의 `complete.log`를 확인한다. +- [ ] local quick regression을 실행하고 결과를 기록한다. +- [ ] 원격 runner/code-server에서 compose render와 compose service health를 새 host slot으로 확인한다. +- [ ] Control Plane-Edge wire, edge-node smoke, OpenAI-compatible smoke 중 변경 범위에 맞는 smoke를 실행하고 pass/blocker를 분리해 기록한다. +- [ ] 검증 결과에 host/token/credential 원문이 남지 않도록 출력 sanitization 여부를 확인한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G07_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 task artifact를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다. +- [ ] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리를 archive로 이동한다. +- [ ] PASS이고 task group이 `m-workspace-port-env-standardization`이면 Roadmap Completion metadata를 보고한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- predecessor `01`, `02` 완료 근거가 확인되었는지 확인한다. +- remote compose output에서 token/host secret이 노출되지 않았는지 확인한다. +- OpenAI smoke 실패가 port regression인지 외부 provider/environment blocker인지 분리되었는지 확인한다. +- PASS이면 `Roadmap Targets`의 `port-default-rollout`만 completion 대상으로 보고한다. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +### TEST-1 중간 검증 + +```bash +$ test -f agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log' -print -quit +(output) +$ test -f agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log' -print -quit +(output) +$ go test ./... +(output) +``` + +### TEST-2 중간 검증 + +```bash +$ test -n "${IOP_EDGE_NODE_TOKEN:?set IOP_EDGE_NODE_TOKEN in the remote shell}" +(output) +$ docker compose --env-file .env.example config >/tmp/iop-compose-config.out +(output) +$ rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out +(output) +$ docker compose --env-file .env.example up --build -d postgres redis control-plane edge web +(output) +$ curl -fsS http://127.0.0.1:18000/healthz +(output) +$ curl -fsS http://127.0.0.1:18000/readyz +(output) +$ docker compose ps +(output) +$ docker compose down +(output) +``` + +### TEST-3 중간 검증 + +```bash +$ make test-control-plane-edge-wire +(output) +$ cd apps/client && flutter test +(output) +$ make client-build-web +(output) +$ ./scripts/e2e-smoke.sh +(output) +$ ./scripts/e2e-openai-ollama.sh +(output) +``` + +### 최종 검증 + +```bash +$ test -f agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log' -print -quit +(output) +$ test -f agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log' -print -quit +(output) +$ go test ./... +(output) +$ test -n "${IOP_EDGE_NODE_TOKEN:?set IOP_EDGE_NODE_TOKEN in the remote shell}" +(output) +$ docker compose --env-file .env.example config >/tmp/iop-compose-config.out +(output) +$ rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out +(output) +$ docker compose --env-file .env.example up --build -d postgres redis control-plane edge web +(output) +$ curl -fsS http://127.0.0.1:18000/healthz +(output) +$ curl -fsS http://127.0.0.1:18000/readyz +(output) +$ docker compose down +(output) +$ make test-control-plane-edge-wire +(output) +$ cd apps/client && flutter test +(output) +$ make client-build-web +(output) +$ ./scripts/e2e-smoke.sh +(output) +$ ./scripts/e2e-openai-ollama.sh +(output) +``` diff --git a/agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/PLAN-cloud-G07.md b/agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/PLAN-cloud-G07.md new file mode 100644 index 0000000..6c4258a --- /dev/null +++ b/agent-task/m-workspace-port-env-standardization/03+01,02_remote_smoke_evidence/PLAN-cloud-G07.md @@ -0,0 +1,213 @@ + + +# Plan - TEST + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 채우기 전까지 구현은 완료가 아니다. 먼저 같은 task group의 `01_compose_env_defaults`와 `02+01_runtime_config_docs`가 PASS되어 `complete.log`를 남겼는지 확인한다. 이 plan은 원격 runner/code-server evidence가 중심이므로 실행 불가 상태를 숨기지 말고 실제 stdout/stderr와 blocker를 review stub에 기록한다. + +## 배경 + +포트 기본값 rollout은 line-level 수정만으로 완료할 수 없다. Docker compose, Control Plane wire, client build/runtime URL, Edge/OpenAI smoke가 새 슬롯에서 같이 동작해야 한다. 이 subtask는 앞선 두 split 작업의 결과를 실제 검증으로 묶고 roadmap task completion evidence를 남긴다. + +## 사용자 리뷰 요청 흐름 + +구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 에이전트는 채팅에서 직접 질문하거나 선택지를 제시하지 않으며, code-review가 사용자 리뷰 요청의 정당성을 판단한다. + +## Roadmap Targets + +- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md` +- Task ids: + - `port-default-rollout`: `.env.example`, `docker-compose.yml`, config/default, app README, `agent-test/local`의 포트 기본값과 검증 명령을 표준 후보에 맞춰 정렬한다. +- Completion mode: check-on-pass + +## 분석 결과 + +### 읽은 파일 + +- `agent-roadmap/current.md` +- `agent-roadmap/phase/automation-runtime-bridge/milestones/workspace-port-env-standardization.md` +- `docker-compose.yml` +- `.env.example` +- `scripts/e2e-control-plane-edge-wire.sh` +- `scripts/e2e-smoke.sh` +- `scripts/e2e-openai-ollama.sh` +- `scripts/dev/web.sh` +- `Makefile` +- `agent-test/local/rules.md` +- `agent-test/local/testing-smoke.md` +- `agent-test/local/platform-common-smoke.md` +- `agent-test/local/client-smoke.md` +- `agent-test/local/control-plane-smoke.md` +- `agent-test/local/edge-smoke.md` +- `agent-test/local/node-smoke.md` + +### 테스트 환경 규칙 + +- 선택 test_env: `local` +- `agent-test/local/rules.md`를 읽었다. +- 적용 profile: `testing-smoke`, `platform-common-smoke`, `client-smoke`, `control-plane-smoke`, `edge-smoke`, `node-smoke` +- Docker compose, Flutter client runtime, field/bootstrap, external runtime evidence는 원격 runner/code-server에서 수행한다. +- local uncommitted 변경이 원격 checkout에 동기화되지 않으면 원격 검증 완료로 보지 않는다. +- token/secret 원문은 tracked 파일과 review output에 기록하지 않는다. + +### 테스트 커버리지 공백 + +- 앞선 split의 unit tests는 default parsing과 일부 client config를 커버하지만 실제 port collision, compose service health, browser-facing URL은 커버하지 않는다. +- `make test-control-plane-edge-wire`는 Control Plane-Edge wire를 커버하지만 compose web service와 DB/cache host publish는 별도 compose evidence가 필요하다. +- OpenAI-compatible field slot `18081`은 provider/runtime 상태에 의존하므로 failure는 환경 blocker와 제품 regression을 구분해 기록해야 한다. + +### 심볼 참조 + +- none + +### 분할 판단 + +- split decision policy를 먼저 평가했다. +- 이 plan은 `03+01,02_remote_smoke_evidence`이므로 predecessors `01`, `02`가 필요하다. +- predecessor `01`: `agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log` 또는 matching archive `complete.log`가 필요하다. 작성 시점에는 아직 missing이다. +- predecessor `02`: `agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log` 또는 matching archive `complete.log`가 필요하다. 작성 시점에는 아직 missing이다. +- 이 final validation split만 `Roadmap Targets`를 포함해 `port-default-rollout`을 check-on-pass 대상으로 둔다. + +## 의존 관계 및 구현 순서 + +- `01_compose_env_defaults`와 `02+01_runtime_config_docs`의 `complete.log`가 모두 없으면 구현을 시작하지 않는다. +- predecessor 완료 후 local checkout과 원격 runner checkout이 같은 commit 또는 같은 patch 상태인지 확인한다. +- 원격 runner에서 Docker compose와 Flutter/client runtime evidence를 수집한다. + +### 범위 결정 근거 + +- 이 subtask는 검증/evidence와 필요한 test-rule 문구 보정만 수행한다. +- port default 코드와 compose/env 변경은 predecessors 소유다. +- provider 계정, token, private endpoint를 tracked 파일에 기록하지 않는다. +- code-server 컨테이너 재시작은 사용자가 명시하지 않으면 수행하지 않는다. + +### 빌드 등급 + +- `cloud-G07`: 원격 runner, Docker compose, client runtime, e2e smoke, external runtime blocker 판정이 중심이라 local-only agent가 증거를 안전하게 완결하기 어렵다. + +## 구현 체크리스트 + +- [ ] predecessor `01_compose_env_defaults`와 `02+01_runtime_config_docs`의 `complete.log`를 확인한다. +- [ ] local quick regression을 실행하고 결과를 기록한다. +- [ ] 원격 runner/code-server에서 compose render와 compose service health를 새 host slot으로 확인한다. +- [ ] Control Plane-Edge wire, edge-node smoke, OpenAI-compatible smoke 중 변경 범위에 맞는 smoke를 실행하고 pass/blocker를 분리해 기록한다. +- [ ] 검증 결과에 host/token/credential 원문이 남지 않도록 출력 sanitization 여부를 확인한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +### [TEST-1] Confirm predecessor completion and local regression + +문제: `port-default-rollout`은 compose/env와 runtime/config/docs split이 모두 완료된 뒤에만 완료 evidence를 낼 수 있다. predecessor 완료 없이 smoke만 실행하면 어떤 default가 검증된 것인지 불명확하다. + +해결 방법: + +- active 또는 archived `complete.log`로 `01`, `02` 완료를 확인한다. +- local Go regression을 먼저 실행해 원격 runner 비용 전에 compile/test regression을 줄인다. + +수정 파일 및 체크리스트: + +- [ ] source 수정 없음 +- [ ] `CODE_REVIEW-cloud-G07.md`: predecessor complete.log path 기록 + +테스트 작성: 검증-only task이므로 새 테스트 파일은 작성하지 않는다. + +중간 검증: + +```bash +test -f agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log' -print -quit +test -f agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log' -print -quit +go test ./... +``` + +기대 결과: 두 predecessor complete log가 확인되고 `go test ./...`가 통과한다. + +### [TEST-2] Verify remote compose slots + +문제: `docker-compose.yml` 변경은 현재 컨테이너에서 Docker-in-Docker로 검증하지 않는다. 원격 runner/code-server에서 새 host publish slot이 충돌 없이 render/health를 통과해야 한다. + +해결 방법: + +- 변경분을 원격 runner checkout에 동기화한다. +- 원격 runner에서 `.env.example` 기준 compose config와 service health를 확인한다. +- `IOP_EDGE_NODE_TOKEN`은 원격 shell 환경에만 둔다. + +수정 파일 및 체크리스트: + +- [ ] source 수정 없음 +- [ ] `CODE_REVIEW-cloud-G07.md`: 원격 runner path, sync 상태, compose command output 기록 + +테스트 작성: 새 테스트 파일은 작성하지 않는다. + +중간 검증: + +```bash +test -n "${IOP_EDGE_NODE_TOKEN:?set IOP_EDGE_NODE_TOKEN in the remote shell}" +docker compose --env-file .env.example config >/tmp/iop-compose-config.out +rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out +docker compose --env-file .env.example up --build -d postgres redis control-plane edge web +curl -fsS http://127.0.0.1:18000/healthz +curl -fsS http://127.0.0.1:18000/readyz +docker compose ps +docker compose down +``` + +기대 결과: compose render, service startup, health/readiness가 성공한다. 실패 시 port collision, token missing, Docker unavailable, service regression을 구분해 기록한다. + +### [TEST-3] Verify wire, client, and Edge input smoke + +문제: CP HTTP, wire, web, OpenAI-compatible slots는 별도 entrypoint에서 사용된다. compose health만으로 client config나 Edge input smoke가 새 기준을 따른다고 볼 수 없다. + +해결 방법: + +- Control Plane-Edge wire smoke를 실행한다. +- client build 또는 Flutter test를 원격 runner에서 실행한다. +- Edge/OpenAI smoke는 provider/runtime 접근 가능 여부를 먼저 기록하고 가능한 경우 실행한다. + +수정 파일 및 체크리스트: + +- [ ] source 수정 없음 +- [ ] `CODE_REVIEW-cloud-G07.md`: smoke command output 기록 + +테스트 작성: 새 테스트 파일은 작성하지 않는다. + +중간 검증: + +```bash +make test-control-plane-edge-wire +cd apps/client && flutter test +make client-build-web +./scripts/e2e-smoke.sh +./scripts/e2e-openai-ollama.sh +``` + +기대 결과: wire/client/e2e smoke가 통과한다. 외부 model/provider 상태 때문에 OpenAI smoke가 불가능하면 실행 전 확인 command와 blocker를 기록하고, 실패가 port regression인지 환경 문제인지 분리한다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `CODE_REVIEW-cloud-G07.md` | TEST-1, TEST-2, TEST-3 | + +## 최종 검증 + +```bash +test -f agent-task/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/01_compose_env_defaults/complete.log' -print -quit +test -f agent-task/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log || find agent-task/archive -path '*/m-workspace-port-env-standardization/02+01_runtime_config_docs/complete.log' -print -quit +go test ./... +test -n "${IOP_EDGE_NODE_TOKEN:?set IOP_EDGE_NODE_TOKEN in the remote shell}" +docker compose --env-file .env.example config >/tmp/iop-compose-config.out +rg --sort path '18000|13000|15400|16300|19080|19081|19090' /tmp/iop-compose-config.out +docker compose --env-file .env.example up --build -d postgres redis control-plane edge web +curl -fsS http://127.0.0.1:18000/healthz +curl -fsS http://127.0.0.1:18000/readyz +docker compose down +make test-control-plane-edge-wire +cd apps/client && flutter test +make client-build-web +./scripts/e2e-smoke.sh +./scripts/e2e-openai-ollama.sh +``` + +기대 결과: predecessor completion, local regression, remote compose, wire/client/edge smoke가 통과한다. 불가능한 외부 runtime 검증은 `사용자 리뷰 요청`이 아니라 blocker evidence로 기록하되, port regression과 환경 문제를 구분한다. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/docker-compose.yml b/docker-compose.yml index cd8ada5..06e9382 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: POSTGRES_PASSWORD: ${IOP_POSTGRES_PASSWORD:-iop_dev_password} POSTGRES_DB: ${IOP_POSTGRES_DB:-iop-control-plane-dev} ports: - - "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-5432}:5432" + - "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-15400}:5432" volumes: - control-plane-postgres:/var/lib/postgresql/data healthcheck: @@ -23,7 +23,7 @@ services: restart: unless-stopped command: ["redis-server", "--appendonly", "yes"] ports: - - "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-6379}:6379" + - "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-16300}:6379" volumes: - control-plane-redis:/data healthcheck: @@ -42,7 +42,7 @@ services: IOP_REDIS_URL: "redis://redis:6379/${IOP_REDIS_DB:-2}" IOP_REDIS_KEY_PREFIX: "${IOP_REDIS_KEY_PREFIX:-iop:control-plane:dev:}" ports: - - "${IOP_CONTROL_PLANE_HTTP_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_HTTP_PORT:-9080}:9080" + - "${IOP_CONTROL_PLANE_HTTP_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_HTTP_PORT:-18000}:9080" - "${IOP_CONTROL_PLANE_WIRE_BIND:-0.0.0.0}:${IOP_CONTROL_PLANE_WIRE_PORT:-19080}:19080" - "${IOP_CONTROL_PLANE_EDGE_WIRE_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_EDGE_WIRE_PORT:-19081}:19081" depends_on: @@ -80,7 +80,7 @@ services: context: .. dockerfile: iop/apps/client/Dockerfile args: - IOP_CONTROL_PLANE_HTTP_URL: "${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:9080}" + IOP_CONTROL_PLANE_HTTP_URL: "${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:18000}" IOP_CONTROL_PLANE_WIRE_URL: "${IOP_CONTROL_PLANE_WIRE_URL:-ws://localhost:19080/client}" restart: unless-stopped ports: