<!-- task=m-iop-hot-path-one-shot-execution/16+14,15_terminal_disposition plan=2 tag=API milestone-task=error-cancel -->

# Hot Path terminal disposition and active-stage cancellation

## For the Implementing Agent

구현 후 `CODE_REVIEW-cloud-G10.md`의 구현 담당 섹션에 실제 변경·검증 출력을 채우고 active 파일을 유지한다. 차단 시 정확한 blocker와 재개 조건만 기록하며 archive/`complete.log` 작성이나 상태 판정은 하지 않는다.

## Background

Child 12는 stage runtime/source control을, child 14/15는 caller codec을 제공한다. 이 child는 공통 terminal disposition을 닫고 cancellation이 현재 active provider run 하나에만 정확히 전달되도록 lifecycle과 cleanup 책임을 연결한다.

## Archive Evidence Snapshot

- 이전 active plan/review pair는 구현 전에 source reanalysis로 대체됐다. 구현 evidence와 verdict는 없다.

## Analysis

### Files Read

- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.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`
- `packages/go/streamgate/runtime.go`
- `packages/go/streamgate/terminal.go`
- `agent-contract/inner/edge-node-runtime-wire.md`
- `agent-test/local/rules.md`

### SDD Criteria

- 승인 SDD S10/S13: success/tool_turn/length/provider_error/validation_error/timeout/caller_cancel의 typed ownership, one winner, exact active `CancelRun`, silent caller-cancel wire, cleanup/orphan continuation.

### Verification Context

- fake active-stage controller, barriers, canceled contexts, fresh race tests로 닫는다.

### Test Coverage Gaps

- active handle 교체와 cancel target 정확성, cancel-vs-terminal race, disposition→cleanup handoff를 한 lifecycle에서 검증하지 않는다.

### Symbol References

- public rename/remove 없음. Predecessor core의 internal stage controller/terminal evidence를 확장한다.

### Split Judgment

- stable contract: stage outcomes/context → one typed outer disposition + exact active cancellation. Endpoint-specific bytes/status mapping은 child 17이다.

### Scope Rationale

- endpoint error body matrix, observation schema, external smoke는 제외한다.

### Final Routing

- evaluation_mode=isolated-reassessment, finalizer=`finalize-task-policy.sh pair`.
- build scores=2/2/2/1/2, risks=`temporal_state,concurrent_consistency,boundary_contract,variant_product`(4), grade-boundary → `PLAN-cloud-G09.md`.
- review → `CODE_REVIEW-cloud-G10.md`; `large_indivisible_context=false`, recovery=0/false.

## Implementation Checklist

- [ ] [API-1] Normalize terminal dispositions and wire one exact active-stage cancellation/cleanup handoff across direct/light transitions.
- [ ] [API-2] Add cancel/timeout/error/length/tool/success race and exact-target regression evidence.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Disposition and cancellation ownership

**Problem:** current provider handles are collector-local, caller cancellation disconnects the request but does not reliably target the exact active run, and stage/outer terminals can race.

**Solution:** Define a closed internal disposition set (`success`, `tool_turn`, `length`, `provider_error`, `validation_error`, `timeout`, `caller_cancel`) with cause/source/stage ownership. Extend the outer turn with an atomic active-stage controller registration that replaces only after prior-stage closure. On timeout/caller cancel, win the terminal guard once, invoke `CancelRun(CANCEL_RUN)` on the exact active controller once, suppress caller-cancel endpoint bytes, and pass typed terminal intent to existing cleanup/orphan handling. Ignore stale stage callbacks and duplicate terminal attempts.

**Modified Files and Checklist:**

- [ ] Modify `apps/edge/internal/openai/hot_path_terminal_control.go` with closed dispositions, winner election, active-stage controller registration, and stale-generation guards.
- [ ] Modify `apps/edge/internal/openai/hot_path_stage_stream.go` to expose exact cancel control and terminal cause without owning endpoint policy.
- [ ] Modify `apps/edge/internal/openai/hot_path_dispatch.go` to register/unregister stage controllers and translate dispatch/validation failure.
- [ ] Modify `apps/edge/internal/openai/hot_path_light.go` to replace active control safely across local/review/repair.
- [ ] Modify `apps/edge/internal/openai/hot_path_cleanup.go` to consume typed terminal intent for cleanup/orphan responsibility.

**Test Strategy:** barrier-controlled two-stage fake runs expose stale handles and cancel/complete races.

**Verification:** targeted API-2 command exits 0.

### [API-2] Terminal race evidence

**Problem:** no exact oracle proves one disposition winner and one active provider cancellation.

**Solution:** Add every disposition, pre/post-stage replacement cancellation, timeout, cancel-vs-complete, provider-error-vs-cap, duplicate callback, stale handle, cleanup failure, and orphan handoff rows. Assert exact cancellation target/count, no post-terminal stage/write, and one cleanup owner.

**Modified Files and Checklist:**

- [ ] Extend `apps/edge/internal/openai/hot_path_terminal_control_test.go` with disposition, active-controller, and race cases.
- [ ] Extend `apps/edge/internal/openai/hot_path_cleanup_test.go` with typed terminal cleanup/orphan cases.
- [ ] Record actual output in `agent-task/m-iop-hot-path-one-shot-execution/16+14,15_terminal_disposition/CODE_REVIEW-cloud-G10.md`.

**Test Strategy:** exact trace and invocation counts are the oracle; run under race detector.

**Verification:** run Final Verification; all commands exit 0 without race.

## Dependencies and Execution Order

1. Directory dependency `14` must produce `agent-task/m-iop-hot-path-one-shot-execution/14+13_anthropic_gate/complete.log`.
2. Directory dependency `15` must produce `agent-task/m-iop-hot-path-one-shot-execution/15+13_chat_gate/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_stage_stream.go` | API-1 |
| `apps/edge/internal/openai/hot_path_dispatch.go` | API-1 |
| `apps/edge/internal/openai/hot_path_light.go` | API-1 |
| `apps/edge/internal/openai/hot_path_cleanup.go` | API-1 |
| `apps/edge/internal/openai/hot_path_terminal_control_test.go` | API-2 |
| `apps/edge/internal/openai/hot_path_cleanup_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/16+14,15_terminal_disposition/CODE_REVIEW-cloud-G10.md` | API-2 |

## Final Verification

```bash
go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPath(TerminalDisposition|ActiveStageCancel|CancelCompleteRace|Cleanup)'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
git diff --check
```

Expected: exit 0, one typed disposition winner, one exact active `CancelRun`, silent caller cancel, deterministic cleanup/orphan ownership, no race.

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