<!-- task=m-iop-hot-path-one-shot-execution/12+10,11_terminal_control plan=0 tag=API milestone-task=terminal-control -->

# Hot Path outer-stream terminal control

## For the Implementing Agent

`CODE_REVIEW-cloud-G10.md`의 구현 담당 섹션 작성이 마지막 필수 단계다. 아래 검증을 실제로 실행하고 원문 출력을 기록한 뒤 active 파일을 그대로 두고 review ready를 보고한다. 차단 시 정확한 명령·출력·재개 조건만 기록하며 사용자 질문, 상태 판정, archive/`complete.log` 작성은 하지 않는다.

## Background

Hot Path는 현재 provider stage를 `normalizedStageOutput`으로 모두 수집한 뒤 응답하므로 SDD의 terminal-only hold와 cross-stage outer envelope 계약을 충족하지 못한다. 이 작업은 protocol별 wire encoding 앞에 공통 outer-turn sequencer와 codec seam을 두고, 독립 배포 가능한 compatibility codec을 유지한 채 후속 protocol packet이 live delta release를 활성화할 수 있게 한다.

## Archive Evidence Snapshot

- `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/10+07,09_light_flow/complete.log`: PASS, local/review/repair stage state machine과 stage correlation 검증 완료.
- `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/complete.log`: PASS, cleanup terminal intent와 exactly-once cleanup 검증 완료.
- 이 두 로그는 본 subtask의 선행 의존성 증거이며 구현자는 archive sibling을 추가 탐색하지 않는다.

## Analysis

### Files Read

- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/iop-hot-path-one-shot-execution.md`
- `apps/edge/internal/openai/hot_path_dispatch.go`
- `apps/edge/internal/openai/hot_path_direct.go`
- `apps/edge/internal/openai/hot_path_light.go`
- `apps/edge/internal/openai/hot_path_cleanup.go`
- `apps/edge/internal/openai/hot_path_direct_test.go`
- `apps/edge/internal/openai/hot_path_light_test.go`
- `apps/edge/internal/openai/hot_path_cleanup_test.go`
- `packages/go/streamgate/runtime.go`
- `packages/go/streamgate/evidence_tail.go`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`, 승인 상태, `milestone-task=terminal-control`.
- 대상 S10 및 Evidence Map S10: cross-stage response-start 억제, public block/tool id 재번호, usage/output-cap 합산, delta 순서, HTTP-turn terminal과 logical completion race.
- 본 packet은 protocol-neutral state machine과 codec seam의 evidence를 만들고, S10 production 완료 evidence는 `terminal-control` metadata를 함께 갖는 후속 Anthropic/Chat packet과 합산한다.

### Verification Context

- handoff 없음. local 규칙과 edge-smoke profile을 읽었고 repo root는 `/config/workspace/iop-s0`, branch `feature/iop-hot-path-one-shot-execution`, 기준 HEAD `6650e9f70d0104220d8077dd1d469b6a1facb9da`다.
- Go는 `/config/.local/bin/go`의 `go1.26.2 linux/arm64`로 project 기준 1.24보다 높다. fresh `-race -count=1` 결과만 허용한다.
- 외부 runtime은 이 packet의 판정에 필요하지 않다. 결정적 oracle은 event-order/race unit test와 기존 openai/service regression이다.

### Test Coverage Gaps

- 기존 direct/light/cleanup tests는 최종 body와 상태 정리를 검증하지만 stage delta의 live release, id remap, usage/output cap, turn/logical terminal 경쟁은 검증하지 않는다.
- `hot_path_terminal_control_test.go`에 ordered writer와 concurrent terminal fixture를 새로 작성한다.

### Symbol References

- 기존 public symbol rename/remove 없음. 새 sequencer는 `collectPresetSelectorResult`, `dispatchPresetTurn`, `submitHotPathStage`, `runDirectTurn`, `runHotPathLightStage`에서만 호출한다.

### Split Judgment

- stable contract: internal stage별 `streamgate.RequestRuntime` terminal-only release/hold, protocol 독립 outer-turn state machine, event decoder/wire codec interface, 기존 응답과 동등한 compatibility codec.
- predecessor 10은 archived `10+07,09_light_flow/complete.log`, predecessor 11은 archived `11+09,10_cleanup/complete.log`로 충족됐다.
- 후속 13/14가 이 state machine을 endpoint wire codec에 연결해 live release를 활성화한다. 본 packet 단독 PASS는 S10 전체 production 완료를 뜻하지 않는다.

### Scope Rationale

- Anthropic/OpenAI wire encoding, endpoint error mapping, observability, 실제 CLI smoke는 각각 후속 packet 13~17로 제외한다.
- `packages/go/streamgate` 계약은 재사용하며 변경하지 않는다.

### Final Routing

- evaluation_mode=write, finalizer=`finalize-task-policy.sh pair`.
- build closures(scope/context/verification/evidence/ownership/decision)=모두 true, scores=2/2/2/2/2, G10, grade-boundary → `PLAN-cloud-G10.md`.
- review closures=모두 true, scores=2/2/2/2/2, G10, official-review → `CODE_REVIEW-cloud-G10.md`.
- `large_indivisible_context=false`; risks=`temporal_state,concurrent_consistency,boundary_contract,structured_interpretation,variant_product`(5); recovery signals=0/false; capability gap 없음.

## Implementation Checklist

- [ ] [API-1] Reuse Stream Evidence Gate with terminal/provider-error-only subscriptions, then introduce the normalized outer-turn sequencer with deterministic id, usage, cap, and terminal state.
- [ ] [API-2] Add Core release/hold, ordering, aggregation, cap, compatibility, and exactly-once race tests and run the targeted plus SDD common verification commands.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Normalized outer-turn sequencer

**Problem:** `apps/edge/internal/openai/hot_path_dispatch.go:768` dispatches only a completed `normalizedStageOutput`, while `apps/edge/internal/openai/hot_path_light.go:736` collects a whole internal stage before the next transition. Content/reasoning/tool deltas therefore remain hidden behind terminal completion.

**Solution:** For each internal stage, construct the existing `streamgate.RequestRuntime` with blocking terminal-gate registrations whose subscribed kinds are only `EventKindTerminal` and `EventKindProviderError`; content/reasoning/tool fragments remain unsubscribed and therefore release immediately. A `streamgate.ReleaseSink` adapter forwards released nonterminal events to a request-scoped, mutex-protected `hotPathOuterTurn`, while Core terminal results become stage-transition evidence instead of being written as nested endpoint terminals. The outer turn suppresses nested response-start, allocates monotonic public block/tool ids, enforces one public output cap, aggregates usage, and commits only `continue-stage`, `finish-turn`, or `finish-logical`. Define `hotPathStageEventDecoder` and `hotPathOuterCodec` seams so normalized RunEvent and tunnel adapters feed the same Core runtime. Preserve provider order with one writer goroutine and reject emissions after terminal.

Before (`hot_path_dispatch.go:768`):

```go
func (s *Server) dispatchPresetTurn(..., stage normalizedStageOutput, gate hotPathRouteDecision) error
```

After:

```go
import (
    "context"
    "sync"

    "iop/packages/go/streamgate"
)

type hotPathOuterTurn struct { /* ordered state, usage, cap, terminal commit */ }
func (t *hotPathOuterTurn) Accept(ctx context.Context, event hotPathNormalizedEvent) error
func (t *hotPathOuterTurn) CommitStage(decision hotPathStageDecision) error
```

Adapt selector and subsequent stage collection to feed a decoder/codec pair while keeping structural route/tool classification state internal. Install a compatibility codec that reconstructs the current completed response so packet 12 compiles and preserves behavior before either endpoint codec lands. `runDirectTurn` and `runHotPathLightStage` share the same turn object; packets 13/14 replace compatibility encoding with live endpoint release and supply the endpoint output cap.

**Modified Files and Checklist:**

- [ ] Add `apps/edge/internal/openai/hot_path_terminal_control.go` with Stream Evidence Gate runtime/release-sink assembly, event/codec interfaces, ordered sequencer, compatibility accumulator, id mapping, usage/cap accounting, and atomic terminal/logical completion guards.
- [ ] Modify `apps/edge/internal/openai/hot_path_dispatch.go` to normalize each stage into the Core runtime, accept the decoder/codec pair, and convert Core terminal results into transition decisions without requiring protocol codecs to exist yet.
- [ ] Modify `apps/edge/internal/openai/hot_path_direct.go` to use the shared turn through the compatibility codec instead of constructing unrelated terminal state.
- [ ] Modify `apps/edge/internal/openai/hot_path_light.go` to retain one outer turn across local→review/repair transitions and stop immediately after cancel/terminal.

**Test Strategy:** Write tests in API-2; retain existing direct/light/cleanup regressions.

**Verification:** `go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPathOuterTurn|TestHotPathDirect|TestHotPathLight'` exits 0.

### [API-2] Terminal-control evidence

**Problem:** S10 requires race and combination evidence not present in existing tests.

**Solution:** Use a recording Core release sink, recording codec, compatibility codec, and barrier-controlled goroutines. First prove content/reasoning/tool events are released before terminal while terminal/provider-error remains held and produces one Core terminal result. Then cover 2+ stage response-start suppression, fragmented ordering, duplicate provider ids, tool arguments, usage dedupe, cap-to-length conversion, internal continuation, public tool/final terminal, cancel-vs-complete and duplicate terminal attempts. Add a compatibility-equivalence row proving pre-integration response bytes/state remain unchanged.

**Modified Files and Checklist:**

- [ ] Add `apps/edge/internal/openai/hot_path_terminal_control_test.go` with `TestHotPathTerminalOnlyCoreRelease`, `TestHotPathOuterTurnOrderingAndAggregation`, `TestHotPathOuterTurnCompatibility`, `TestHotPathOuterTurnOutputCap`, and `TestHotPathOuterTurnTerminalRace`.
- [ ] Record actual outputs in `agent-task/m-iop-hot-path-one-shot-execution/12+10,11_terminal_control/CODE_REVIEW-cloud-G10.md`.

**Test Strategy:** New regression and concurrency tests are mandatory; assert exact event sequence, public ids, summed usage, one terminal, one logical completion, and no post-cancel write.

**Verification:** run the Final Verification commands; every command exits 0 and race detector reports no race.

## Dependencies and Execution Order

1. `10+07,09_light_flow` — satisfied by `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/10+07,09_light_flow/complete.log`.
2. `11+09,10_cleanup` — satisfied by `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/complete.log`.
3. Implement API-1, then API-2.

## Modified Files Summary

| File | Item |
|---|---|
| `apps/edge/internal/openai/hot_path_terminal_control.go` | API-1 |
| `apps/edge/internal/openai/hot_path_dispatch.go` | API-1 |
| `apps/edge/internal/openai/hot_path_direct.go` | API-1 |
| `apps/edge/internal/openai/hot_path_light.go` | API-1 |
| `apps/edge/internal/openai/hot_path_terminal_control_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/12+10,11_terminal_control/CODE_REVIEW-cloud-G10.md` | API-2 |

## Final Verification

```bash
go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPathOuterTurn|TestHotPathDirect|TestHotPathLight|TestHotPathCleanup'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
git diff --check
```

Expected: all tests exit 0, no race or post-terminal emission, and `git diff --check` is empty. Cached test output is not acceptable.

After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
