# Milestone: 워크스페이스 포트/환경 표준화

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/agent-ops-mcp-control-plane/PHASE.md`

## 목표

NomadCode의 Flutter client, core service, compose/local run, code-server preview, IOP Edge 연동 endpoint를 workspace 공통 포트 대역으로 정리한다. 기존 `8080` 기반 local core와 web preview 관례는 바로 깨지지 않게 compatibility note를 남기고, host publish와 remote runner 문서부터 같은 대역 언어로 맞춘다.

## 상태

[완료]

## 구현 잠금

- 상태: 해제
- 결정 필요: 없음

## 범위

- Flutter/client web preview와 code-server proxy preview를 frontend 대역 후보로 정리
- Core HTTP/API host publish와 local default `8080` compatibility note 정리
- PostgreSQL/Redis host publish는 필요할 때만 DB/cache offset 대역으로 노출하고, compose 내부 통신은 service DNS를 우선한다는 기준 정리
- IOP Edge OpenAI-compatible Responses endpoint, model provider URL, remote Android runner 환경 변수를 private 값 없이 문서화
- Plane, Mattermost, Jira, Firebase 같은 외부 integration 값은 endpoint 책임 경계만 기록하고 token/secret은 tracked 문서에서 제외

## 기능

### Epic: [inventory] NomadCode environment inventory

NomadCode가 직접 소유한 client/core 포트와 외부 IOP/Nexo/Plane 연동 endpoint를 현재 repo baseline 기준으로 분리해 정리한다.

- [x] [client-preview] Flutter web/code-server preview는 현재 local smoke 기준 `8081` 계열 임시 포트와 `/proxy/<port>/` base href를 사용한다. frontend 대역 후보 `13010`으로 정리할 때 기존 preview 흐름과 workspace mock URL의 `localhost:8080` code-server entry 호환성을 기록한다.
- [x] [core-port] Core HTTP/API는 `HTTP_ADDR=:8080`, Docker `EXPOSE 8080`을 internal compatibility로 유지하고, compose host publish 기본값을 `18010:8080`으로 맞춘다. 기존 `8080` host publish가 필요하면 `NOMADCODE_CORE_HOST_PORT=8080` override로 확인한다.
- [x] [infra-ports] PostgreSQL/Redis는 현재 compose 내부에서 `code-server-postgres:5432`, `code-server-redis:6379` service DNS를 사용하고 별도 host publish를 갖지 않는다. 필요한 경우만 DB/cache offset 대역 `15410/16310` 노출 후보를 문서화한다.
- [x] [external-endpoints] IOP Edge OpenAI-compatible endpoint는 현재 `MODEL_BASE_URL`, `MODEL_API_KEY`, `MODEL_NAME`, `MODEL_CONTEXT_SIZE`, `MODEL_TIMEOUT_SEC`로 설정하고, A2A/proto-socket/provider 연동은 `A2A_*`, `PROTO_SOCKET_*`, `PLANE_*`, `JIRA_*`, `MATTERMOST_*` env로 분리한다. raw secret 없이 source of truth와 책임 경계만 남긴다.

## 완료 리뷰

- 상태: 완료
- 요청일: 2026-06-07
- 완료일: 2026-06-08
- 완료 근거:
  - `README.md`, `services/core/README.md`, `apps/client/README.md`, `agent-test/local/mobile-smoke.md`, `packages/contracts/notes/flutter-core-api-candidates.md`에 workspace 포트 대역과 compatibility baseline을 문서화했다.
  - Flutter preview `13010+`, Core host publish `18010:8080`, PostgreSQL/Redis host publish 후보 `15410/16310`, IOP/provider env group의 secret-free 책임 경계를 분리했다.
  - `agent-test/local/*`의 기본 host를 standard remote runner 기준으로 정리하고 Android/Mattermost remote smoke의 포트 기준을 채웠다.
  - Core compose host publish 기본값을 `18010:8080`으로 바꾸고, 기존 `8080` host publish는 `NOMADCODE_CORE_HOST_PORT=8080` override로 남겼다.
  - 검증: `git diff --check` PASS.
  - 검증: standard remote runner에서 `zsh -lc 'docker compose ... config'`로 compose 렌더링을 확인했다. 기본 publish는 `published: "18010"`, `NOMADCODE_CORE_HOST_PORT=8080` override는 `published: "8080"`으로 확인했다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 작은 문서화 작업은 바로 처리했으며, 별도 large plan 대상은 남기지 않았다. 2026-06-08 사용자가 `https://nomadcode.toki-labs.com/proxy/13010/` 정상 노출을 확인했고, 마일스톤 완료와 다음 이동을 요청했다.

## 범위 제외

- Plane/Jira work item sync 구현
- Workbench/provider slot UI 구현
- IOP 모델 라우팅, RAG, MCP/tool policy 구현
- token, password, Firebase/Jira/Plane secret 기록
- remote Android runner 또는 code-server host 즉시 재배포

## 작업 컨텍스트

- 관련 경로: `apps/client/`, `services/core/`, `docker-compose.yml`, `.env.example`, `agent-test/local/`, `packages/contracts/`
- 외부 관련 경로: `../iop/`, `../nexo/packages/messaging_flutter/`, `../proto-socket/dart/`
- 표준선(선택): container 내부 포트와 기존 local default는 compatibility baseline으로 유지하고, host publish, preview, remote runner 문서부터 workspace 대역으로 정렬한다.
- 현재 작업 동기화:
  - 활성 로드맵 포인터는 `Agent-Ops MCP Control Plane` Phase와 이 Milestone을 가리키며, active `agent-task/` 작업 파일은 없다.
  - Core baseline source는 `services/core/internal/config/config.go`, `services/core/Makefile`, `services/core/docker-compose.yml`, `services/core/Dockerfile`, `services/core/README.md`에 흩어져 있고, internal compatibility port는 `8080`, compose host publish 기본값은 `18010`이다.
  - Client preview baseline source는 `agent-test/local/mobile-smoke.md`이며, human web preview는 code-server `/proxy/<port>/`와 기본 `13010+`, legacy/ad hoc `8081` 호환을 함께 사용한다.
  - Workspace mock entry는 `apps/client/lib/src/features/workspaces/domain/project_workspace.dart`에서 code-server `localhost:8080` URL을 사용한다.
  - Proto-socket client endpoint는 `apps/client/lib/src/integrations/proto_socket/proto_socket_endpoint_config.dart`의 `PROTO_SOCKET_*` env에서 오며, host가 없으면 비활성화된다.
  - external provider/model endpoint 값은 tracked roadmap에 실제 token/password를 기록하지 않고 env 이름과 책임 경계만 동기화한다.
- 선행 작업: workspace 공통 포트 inventory 정리
- 후속 작업: compose/env/test smoke 갱신과 drift 방지
- 확인 필요: 없음
