# Milestone: [route-02] IOP 단일 요청 Agent 실행

## 위치

- Roadmap: [ROADMAP.md](../../../../ROADMAP.md)
- Phase: [PHASE.md](../../../../phase/knowledge-tool-optimization-extension/PHASE.md)
- SDD: [SDD.md](../../../sdd/knowledge-tool-optimization-extension/iop-owned-single-request-agent-execution/SDD.md)

## 목표

Claude가 IOP의 Anthropic-compatible model을 호출할 때 `/v1/messages` POST를 정확히 한 번만 보내고, IOP가 그 연결 안에서 Plan → Work → Review/repair를 모두 완료한다.
초기 실행 preset은 Gemini 3.6 Flash `high`가 작은 plan을 만들고, `ornith-fast`가 operator 승인 IOP Node의 request-scoped workspace 도구로 작업·검증하며, 같은 Gemini 3.6 Flash `high`가 결과를 review하고 잔존 작업을 수정한 뒤 하나의 model 응답처럼 최종 terminal을 반환한다.

## 상태

[완료]

## 구현 잠금

- 상태: 해제
- SDD: 필요
- SDD 문서: [IOP 단일 요청 Agent 실행 SDD](../../../sdd/knowledge-tool-optimization-extension/iop-owned-single-request-agent-execution/SDD.md)
- SDD 사유: Anthropic streaming, Edge coordinator, Edge-Node wire, request-scoped workspace/tool 권한, 취소·cleanup과 provider stage 계약을 함께 변경한다.
- SDD 상태: 승인됨
- SDD 잠금: 해제
- SDD 사용자 리뷰: 없음
- 잠금 해제 조건: 아래 체크리스트
  - [x] SDD 잠금이 해제되어 있다.
  - [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
  - [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
  - [x] Evidence Map이 완료 시 `complete.log`의 `milestone-task` id별 집계와 최종 검증 evidence로 검증 가능하게 연결되어 있다.
- 결정 필요: 없음

## 범위

### 1. 외부 단일 요청 불변 조건

- Claude는 사용자 요청 하나에 대해 IOP `/v1/messages`를 정확히 한 번 호출한다.
- IOP는 최초 Anthropic response envelope와 SSE 연결을 Plan, Work, Review/repair 전체 수명 동안 유지하고 최종 endpoint-native terminal을 한 번만 반환한다.
- internal provider/tool stage의 response-start, finish reason, tool call과 tool result는 coordinator가 소비한다. Claude에 `tool_use` terminal을 반환해 두 번째 Messages 요청을 요구하지 않는다.
- external request count 1은 `request_id` 하나나 사용자 prompt 하나와 동의어가 아니라 실제 Edge ingress POST 수로 검증한다.

### 2. Execution preset과 model binding

- exposed model은 기존 canonical model/provider route 대신 fixed `light` single-request execution preset에 매핑된다. 이 마일스톤은 요청별 mode selector를 실행하지 않는다.
- 초기 preset의 `plan`과 `review` stage는 canonical `gemini-3.6-flash` model reference와 `reasoning_effort=high`를 사용한다.
- `work` stage는 canonical `ornith-fast` model reference를 사용하며 Gemini의 `high` 옵션을 복제하지 않는다.
- model/provider endpoint와 credential은 core에 하드코딩하지 않고 기존 principal projection, route authorization, provider-pool resolution과 lease를 stage마다 재사용한다.

### 3. IOP-owned request-scoped workspace/tool runtime

- preset은 operator가 승인한 IOP Node의 `workspace_ref`를 가리키며 caller가 임의 absolute path나 Node를 선택하지 못한다. Node 운영체제는 기능 요구가 아니다.
- IOP Node는 해당 root 아래 request-scoped execution context를 만들고 canonical read/list/write/delete/command tool을 실행한다.
- `.iop/job/<request_id>/plan.md`와 `review.md`는 IOP-owned workspace operation으로 생성·읽기·갱신·정리한다.
- tool argument, cwd containment, symlink escape, command process group, 환경 변수 allowlist, stdout/stderr 상한, timeout과 cancel을 fail-closed로 검증한다.
- cleanup은 request-owned `.iop/job/<request_id>` artifact와 실행 process만 대상으로 하며 사용자가 요청한 workspace 결과 파일은 삭제하거나 rollback하지 않는다.
- 범용 interactive terminal, desktop session, 독립 scheduler와 장기 agent process는 포함하지 않는다.

### 4. Plan → Work → Review/repair

- `plan`: Gemini 3.6 Flash high가 immutable 사용자 요청에서 작은 plan과 검증 기준을 만들고 `plan.md`를 내부 tool로 기록한다.
- `work`: ornith-fast가 사용자 요청과 plan을 받아 IOP Node tool loop로 workspace를 수정·검증하고 completion candidate를 만든다.
- `review`: Gemini 3.6 Flash high가 사용자 요청, plan, workspace 결과와 검증 evidence를 검사해 pass이면 finalize하고 defect이면 같은 stage 안에서 잔존 작업을 수정·재검증한다.
- provider repetition/no-progress와 malformed tool output은 stage별 tool-iteration/output/deadline과 request 전체 wall-clock budget 안에서 중단하며 외부 Claude 재호출로 복구하지 않는다. 이 fixed `light` 경로는 짧은 작업만 대상으로 한다.

## 기능

### Epic: [single-request] Single-request Coordinator

- [x] [single-ingress] Claude `/v1/messages` POST 하나를 immutable request/preset/stage identity에 고정하고 추가 caller ingress 없이 완료하는 coordinator와 Anthropic API 계약을 구현한다.
- [x] [preset-binding] exposed model을 Gemini plan/review와 ornith-fast work 및 승인된 IOP Node workspace resource를 포함한 immutable fixed `light` execution preset에 매핑하고 unsupported dynamic mode binding을 fail-closed하며 config/runtime-refresh 계약을 동기화한다.
- [x] [stream-terminal] internal stage envelope과 terminal을 소비하고 private model reasoning/tool protocol은 숨긴 채 진행 요약, 연결 유지 ping과 최종 terminal 하나를 Anthropic SSE로 합성한다.

### Epic: [workspace-runtime] IOP Node Workspace Tool Runtime

- [x] [workspace-binding] principal/preset에 승인된 IOP Node `workspace_ref`를 admission하고 request-scoped workspace identity와 containment를 고정한다.
- [x] [tool-executor] provider `RunRequest`/closed `NodeCommand`와 분리된 typed Edge-Node workspace runtime으로 read/list/write/delete/command를 bounded output, cwd/symlink/env/process 안전 경계와 함께 실행하고 protobuf·Edge-Node wire 계약을 동기화한다.
- [x] [tool-loop] internal model tool call/result를 IOP coordinator와 Node executor 사이에서 반복하고 Claude-facing `tool_use` continuation을 만들지 않는다.
- [x] [cleanup-observation] 성공·오류·취소의 request-owned process/artifact cleanup과 raw-free request/stage/tool/total timing 관측을 구현하고 사용자 결과 파일은 보존한다.

### Epic: [plan-work-review] Plan, Work, Review

- [x] [plan-stage] Gemini 3.6 Flash high가 작은 plan·검증 기준을 만들고 IOP-owned `plan.md`에 기록한다.
- [x] [work-stage] ornith-fast가 plan을 읽고 internal tool loop로 실제 workspace 작업과 검증을 완료한다.
- [x] [review-stage] Gemini 3.6 Flash high가 결과를 review하고 pass 또는 잔존 작업 수정·재검증·finalize까지 수행한다.

### Epic: [quality-gate] 오류와 실제 검증

- [x] [error-cancel] provider/tool timeout, bounded stage/request budget, repetition/no-progress, malformed call, context/output limit, caller disconnect를 추가 외부 요청 없이 표준 오류·취소·length terminal로 수렴시킨다.
- [x] [claude-smoke] 실제 Claude에서 작은 workspace 작업을 한 번 요청해 Edge의 `/v1/messages` ingress count가 정확히 1이고 Gemini → ornith-fast → Gemini stage, stage/total 순수 시간, 최종 파일·검증·terminal이 모두 확인되는 smoke를 통과한다.

## 완료 리뷰

- 상태: 통과
- 요청일: 2026-08-08
- 종료일: 2026-08-09
- 완료 근거: 동일 Milestone task group의 canonical PASS `complete.log` 25건과 현재 코드·계약·테스트를 Task id별로 집계해 12개 기능 Task와 SDD S01~S12의 구현·검증 연결을 확인했다.
- 완료 근거: `error-cancel`은 request/stage budget·provider/tool timeout·malformed/repetition·disconnect가 추가 ingress나 partial success 없이 단일 오류·취소·length terminal로 수렴하는 matrix/race 검증을 통과했다.
- 완료 근거: [`claude-smoke` canonical PASS](../../../../../agent-task/archive/2026/08/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/complete.log)는 실제 Claude `sole-live-18` 한 번으로 ingress `0→1`, Gemini→ornith-fast→Gemini, stage/total timing, Work write·Review read·cleanup, 정확한 42-byte 결과와 단일 `end_turn`을 redacted manifest로 검증했다.
- 계약 동기화: [Anthropic-Compatible Messages API](../../../../../agent-contract/outer/anthropic-compatible-api.md)의 S12 보류 표기를 실제 qualification 완료 상태로 갱신했다.
- Spec 동기화: [Edge-Node Provider Execution](../../../../../agent-spec/runtime/edge-node-execution.md)과 [OpenAI-Compatible 입력 표면](../../../../../agent-spec/input/openai-compatible-surface.md)에 S12 complete-log evidence와 현재 qualification 상태를 반영했다.
- 검토 항목: 모든 기능 Task, SDD Acceptance/Evidence, 계약·Spec 동기화가 충족되었으며 남은 구현·검증·결정 차단 항목은 없다.
- 리뷰 코멘트: 종료 검토를 통과해 `[완료]`로 전환하고 2026-08-09 archive로 이동했다.

## 범위 제외

- Pi/OpenAI Chat Completions를 이 마일스톤의 target agent/protocol로 추가하는 작업
- 장기 작업의 재계획, 여러 review cycle와 durable resume를 제공하는 `heavy` mode
- 범용 interactive shell, desktop/PTY session, 독립 scheduler, CI/CD와 사람 승인 workflow
- caller가 임의 Node, absolute workspace path, credential 또는 preset 밖 model/tool을 선택하는 기능
- cross-Edge state replication과 Edge restart 뒤 동일 SSE resume

## 작업 컨텍스트

- 관련 경로: `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/node`, `apps/node/internal/transport`, `packages/go/config`, `packages/go/streamgate`, `proto/iop`, `configs/edge.yaml`
- 구현 기준선: 완료·아카이빙한 [[route-01] IOP 실행 프리셋과 Hot Path](iop-hot-path-one-shot-execution.md)의 execution preset/config generation, coordinator, endpoint codec, Stream Evidence Gate, authorization/lease, error·cleanup·observability 기반과 현재 Anthropic↔Gemini Chat bridge를 재사용한다. 과도기 caller tool-result smoke는 이 마일스톤의 선행 차단이 아니며, exact single-request E2E는 이 마일스톤이 직접 검증한다.
- 표준선: one-shot의 완료 기준은 logical `request_id`가 아니라 실제 Claude→IOP `/v1/messages` POST count 1이다.
- 표준선: request-scoped workspace/tool execution은 IOP Edge와 승인된 IOP Node가 소유하며 외부 Claude tool callback에 의존하지 않는다.
- 큐 배치: 완료·아카이빙된 `[route-01]` 다음인 route lane의 `[route-02]` 2번으로 실행했으며, 완료 archive와 함께 active queue에서 제거했다.
- 실행 순서와 차단 관계: [전역 마일스톤 실행 순서](../../../../priority-queue.md)
- 후속: [Heavy Plan/Review 실행과 검증 MVP](../../../../phase/knowledge-tool-optimization-extension/milestones/knowledge-tool-validation-optimization.md), [Execution Preset 하이브리드 Mode 라우팅](../../../../phase/knowledge-tool-optimization-extension/milestones/openai-compatible-hybrid-request-execution-routing.md)
- 추가 비교 검증: 정식 기능과 `[claude-smoke]` 완료 이후 [[bench-02] IOP 원샷 Agent 모델 비교 벤치마크](../../../../phase/knowledge-tool-optimization-extension/milestones/iop-one-shot-agent-model-comparison.md)에서 수행하며, [[bench-01] Agent 비교 벤치마크 파이프라인 준비](../../../../phase/knowledge-tool-optimization-extension/milestones/agent-comparison-benchmark-pipeline.md)는 이 Milestone과 병렬로 진행할 수 있다. 이 비교는 현재 Milestone의 완료 Task나 필수 smoke를 대체하지 않는다.
- 확인 필요: 없음
