# Plan: NomadCode Core IOP Smoke

## 작업 범위

`01_iop_responses_surface`가 완료된 뒤, NomadCode Core를 standard remote runner에서 실제 IOP Edge Responses listener에 연결하고 task create/enqueue/poll smoke를 수행한다. 이 subtask가 통과해야 Milestone `[iop-responses]`를 완료로 주장할 수 있다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- 완료 대상 Task id: `iop-responses`

## 분석 결과

- NomadCode Core의 local test rule은 standard remote runner `toki@toki-labs.com`, checkout `$HOME/agent-work/nomadcode`, Core compose host publish `18010:8080`을 기본으로 둔다.
- Core process/container internal port는 `8080`, compose host publish 기본은 `18010:8080`이다.
- Core compose는 DB/Redis service DNS 때문에 host direct `go run`보다 Docker network 실행이 기준에 더 가깝다.
- 원격 DB에는 `nomad-core-dev`, `nomadcode-core-local`, `tasks`, `river_job`이 존재한다.
- 현 상태에서 원격 IOP `18081` HTTP smoke는 empty reply이고, sibling IOP repo도 `/v1/responses`를 아직 계획 표면으로 본다. 따라서 이 subtask는 `01_iop_responses_surface` 완료 후에만 실행 가능하다.
- 분할 의존성: 이 subtask는 `01_iop_responses_surface`의 `complete.log`가 필요하다.

## 구현 계획

1. 시작 전 `agent-task/m-external-integration/01_iop_responses_surface/complete.log` 또는 archive된 같은 index의 `complete.log`를 확인한다.
2. remote runner의 NomadCode checkout이 현재 변경분과 동기화되어 있는지 확인한다. 필요한 경우 전체 `services/core`를 안전하게 동기화하되, unrelated remote user changes를 덮어쓰지 않는다.
3. remote runner에서 IOP Edge Responses listener를 확인하거나 기동한다. 표준 포트는 IOP local rule 기준 Edge OpenAI-compatible HTTP `18081`이다.
4. IOP Edge에 실제 node가 연결되어 non-streaming Responses 요청을 완료할 수 있는지 `/healthz`, `/v1/models`, `/v1/responses` smoke로 확인한다.
5. NomadCode Core compose를 `NOMADCODE_CORE_HOST_PORT=18010` 기준으로 기동한다. Docker container에서 IOP Edge host endpoint에 닿는 주소는 runner 환경에 맞게 검증해서 설정한다.
6. Core `/healthz`와 authenticated `/readyz`를 확인한다. `AUTH_PASSWORD`를 설정한 경우 raw value는 기록하지 않는다.
7. Core `POST /api/tasks`로 smoke task를 만들고, payload에 작고 deterministic한 prompt를 둔다.
8. Core `POST /api/tasks/{id}/enqueue`를 호출하고, `GET /api/tasks/{id}`를 poll 해서 `completed` 상태와 result `mode=openai_responses`를 확인한다.
9. IOP Responses handler/service test 또는 sanitized runtime evidence로 metadata key `task_id`와 `source`가 IOP boundary까지 전달됐음을 확인한다.
10. 실패 시 HTTP status, sanitized body, process logs의 non-secret summary를 남기고 마일스톤은 `[진행중]`으로 유지한다.

## 검증 계획

- NomadCode local: `cd services/core && go test ./internal/adapters/openai ./internal/scheduler`
- NomadCode remote: `cd "$HOME/agent-work/nomadcode/services/core" && go test ./... && go vet ./...`
- IOP remote: `/healthz`, `/v1/models`, `POST /v1/responses` smoke against the active Edge listener.
- Core remote smoke: `POST /api/tasks`, `POST /api/tasks/{id}/enqueue`, `GET /api/tasks/{id}` polling to `completed`.
- Final roadmap update only after all required smoke evidence is present.

## 위험과 주의점

- 이 검증은 실제 서버 프로세스와 포트 상태에 의존한다. 포트 충돌, stale process, Docker network address 문제를 완료로 포장하지 않는다.
- IOP Edge가 아직 Responses를 지원하지 않으면 Core fallback이나 mock으로 완료 처리하지 않는다.
- mock OpenAI-compatible server는 회귀 보조로만 사용할 수 있고, Milestone 완료 근거는 실제 IOP Edge Responses listener여야 한다.
- smoke payload와 metadata marker는 secret이 아닌 값만 쓴다.
