# Milestone: OpenAI Workspace Agent Execution Contract

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`

## 목표

외부 소비자, 특히 NomadCode는 IOP와 CLI로 통신하지 않고 IOP Edge의 OpenAI-compatible HTTP 표면(`/v1/responses`, `/v1/chat/completions`)으로 요청한다.
이 마일스톤은 그 HTTP 요청의 `metadata.workspace`가 IOP 내부 `adapter + target` 실행 경로를 지나 실제 workspace agent process의 작업 디렉터리까지 전달되도록 만든다.
완료 지점은 NomadCode가 workspace slot path를 `metadata.workspace`로 넘겨 IOP Edge HTTP 호출 한 번으로 Codex 같은 내부 agent target이 해당 checkout 안에 roadmap Milestone 산출물을 만들 수 있는 상태다.
현재 제1 목표인 `../nomadcode` 지원을 위해 provider 확장보다 먼저 완료해야 하는 contract/serving hardening 작업으로 둔다.

## 상태

[완료]

## 구현 잠금

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

## 범위

- OpenAI-compatible 요청의 `metadata.workspace` 파싱과 검증
- OpenAI-compatible `model` route를 IOP 내부 `adapter + target` 실행으로 해석하는 기준
- Edge service가 workspace를 명시 실행 필드로 받아 Node `RunRequest.Workspace`로 전달하는 흐름
- Node CLI adapter 계열이 `ExecutionSpec.Workspace`를 process working directory로 적용하는 흐름
- target/session 재사용 시 workspace가 섞이지 않도록 하는 logical session 기준
- NomadCode Core가 workspace slot path, task id, source를 OpenAI-compatible metadata로 넘기는 소비자 호출 shape
- NomadCode workspace slot 기반 authoring run을 검증할 수 있는 HTTP smoke/test 기준

## 기능

### Epic: [metadata-workspace] OpenAI Metadata Workspace Ingress

OpenAI-compatible 입력 표면에서 workspace agent 실행 문맥을 별도 wrapper 없이 `metadata.workspace`로 받는 계약을 구현한다.

- [x] [metadata-schema] `/v1/responses`와 `/v1/chat/completions`가 flat `metadata.workspace`를 파싱해 run workspace로 전달한다. 검증: 기존 `metadata.request_id`, `metadata.nomadcode.*`, `metadata.inference.target`은 유지되고 `metadata.cli`는 계속 거부된다.
- [x] [workspace-required] 내부 실행 route가 workspace-bound agent target이면 workspace가 비어 있거나 상대 경로일 때 OpenAI-compatible error로 거부한다. 검증: workspace가 필요 없는 inference route는 기존 동작을 유지하고, workspace-bound route만 필수 조건을 적용한다.
- [x] [route-catalog] 외부 `model` route가 내부 `adapter + target`으로 해석되는 기준을 config와 smoke fixture에 남긴다. 검증: `model: "codex"` 같은 route가 명시적으로 workspace-bound agent target으로 수렴한다.

### Epic: [edge-node-workspace] Edge-Node Workspace Propagation

Edge service와 Node runtime 사이에서 workspace가 metadata 문자열로만 남지 않고 실행 spec의 작업 디렉터리로 이어지게 한다.

- [x] [run-workspace] `SubmitRunRequest`와 `BuildRunRequest`가 workspace를 명시 필드로 갖고 proto `RunRequest.Workspace`에 채운다. 검증: service unit test가 metadata와 workspace를 별도 필드로 보존하는지 확인한다.
- [x] [node-spec] Node router가 `RunRequest.Workspace`를 `ExecutionSpec.Workspace`로 유지한다. 검증: router/node test에서 workspace 값이 adapter execution spec까지 보존된다.
- [x] [agent-cwd] workspace-bound agent process 실행기가 `ExecutionSpec.Workspace`를 process working directory로 적용한다. 검증: 이 마일스톤에서 지원하는 agent target profile의 cwd 적용 test가 통과한다.
- [x] [session-workspace] logical session이 다른 workspace를 같은 target/session으로 재사용하지 않는다. 검증: 같은 target/session이라도 workspace가 다르면 별도 session을 만들거나 명시 오류를 반환한다.

### Epic: [nomad-http-smoke] NomadCode Todo Authoring Readiness

NomadCode가 Plane `Todo` projection 전 단계에서 IOP Edge HTTP 호출로 workspace agent 산출물을 만들 수 있는 최소 실행 증거를 확보한다.

- [x] [workspace-authoring-smoke] `metadata.workspace`가 가리키는 임시 checkout에서 workspace-bound agent target이 파일을 생성/수정할 수 있음을 검증한다. 검증: OpenAI-compatible `/v1/responses` smoke가 workspace 안 marker 또는 git diff를 남기고, 프로세스 cwd가 workspace 밖으로 벗어나지 않는다.
- [x] [nomad-metadata-shape] NomadCode Core가 workspace slot path를 flat `metadata.workspace`로, task/source context를 `metadata.task_id`/`metadata.source` 또는 `metadata.nomadcode.*`로 전달하는 호출 shape를 맞춘다. 검증: `../nomadcode`의 OpenAI Responses client/scheduler fixture와 IOP Edge smoke fixture가 같은 metadata contract를 사용한다.
- [x] [nomad-handoff-contract] NomadCode authoring 호출 shape를 계약 문서와 운영 문서에 연결한다. 검증: 외부 호출은 `model`, `input`, `metadata.workspace`, task/source metadata만으로 충분하며 `metadata.cli`, root-level `iop` wrapper, IOP CLI 직접 실행을 요구하지 않는다.
- [x] [failure-surface] workspace 누락, 존재하지 않는 경로, 권한 오류, agent process exit failure가 호출자에게 구분 가능한 실패로 드러난다. 검증: 잘못된 workspace 요청이 조용히 기본 cwd에서 실행되지 않는다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-06-14
- 완료 근거: OpenAI metadata schema와 workspace-required/failure-surface unit coverage가 `go test ./apps/edge/...`와 관련 Node/Service 패키지 테스트로 통과했다.
- 완료 근거: `./scripts/e2e-openai-cli-workspace.sh`가 임시 checkout 안 marker 생성, repo root/temp parent 누수 방지, `iop-edge smoke openai --workspace --expect-file` 검증까지 통과했다.
- 완료 근거: 코드 레벨 완료 리뷰에서 blocker를 찾지 못했고, NomadCode Core의 OpenAI Responses client/scheduler fixture도 같은 flat metadata contract를 사용함을 확인했다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 2026-06-14 코드 레벨 리뷰와 재검증 결과 완료로 전환하고 archive 이동을 진행했다.

## 범위 제외

- NomadCode가 IOP CLI를 직접 실행하는 통신 경로
- NomadCode의 Plane `Todo` projection, Plane 댓글/본문/상태 갱신 구현
- NomadCode의 `develop` push 성공 판정, milestone/work item identity map, 재시도 정책
- OpenAI-compatible API에 terminal 제어 기능을 싣는 일
- IOP native remote terminal bridge 구현
- MCP/tool policy, approval flow, artifact store, RAG/context compression 구현

## 작업 컨텍스트

- 관련 경로: `agent-contract/provided/openai-compatible-api.md`, `apps/edge/internal/openai/`, `apps/edge/internal/service/`, `apps/node/internal/router/`, `apps/node/internal/node/`, `apps/node/internal/adapters/cli/`, `proto/iop/runtime.proto`, `configs/edge.yaml`, `agent-test/local/`
- 표준선(선택): 외부 통신은 IOP Edge OpenAI-compatible HTTP 표면을 사용한다. 내부 실행은 `adapter + target`과 `RunRequest.Workspace`로 변환한다. workspace agent process의 작업 디렉터리는 prompt 본문, `metadata.cli` wrapper, IOP CLI 직접 실행이 아니라 `metadata.workspace`에서 온다.
- 우선순위: provider 상태/capacity queue, Lemonade provider, vLLM/SGLang provider 확장은 이 마일스톤으로 NomadCode workspace 실행 계약을 먼저 닫은 뒤 진행한다.
- 선행 작업: `OpenAI Responses Input Surface`, `Codex App Server 스트리밍 전환`
- 후속 작업: NomadCode `Milestone Work Item Creation Sync`, `원격 터미널 브리지 POC`
- 확인 필요: 없음
