<!-- task=m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration plan=3 tag=REVIEW_REVIEW_API milestone-task=terminal-control -->

# Preserve tool continuation ownership at the caller output cap

## For the Implementing Agent

Implement only the two review findings below. Run every verification command, fill all implementation-owned sections in `CODE_REVIEW-*-G??.md` with actual notes and output, keep the active files in place, and report ready for review. If blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence fields. Do not ask the user, call user-input tools, create control-plane stop files, classify the next state, archive logs, or write `complete.log`; finalization belongs to the code-review skill.

## Background

The second integration review proved that output-cap exhaustion is resolved before the current stage's tool-terminal ownership. Chat and Messages can therefore expose a public tool id after the logical request has already been deleted. The same review found that usage-less stages estimate one token per four runes, which is not a conservative tokenizer-independent dispatch bound.

## Archive Evidence Snapshot

- `code_review_cloud_G09_2.log` records the current FAIL verdict: one Required finding covering cap-at-tool-terminal continuation ownership and optimistic usage-less budgeting. Fresh targeted handler, package race, vet, and diff commands passed, but a focused real Chat/Messages handler reproducer returned a public `read_file` tool call and then observed `logical request count=0` for both protocols.
- `plan_cloud_G09_2.log` is the superseded cap/compatibility plan. This follow-up is limited to the unclosed Required finding; the `terminal-control` roadmap contribution scope remains unchanged.

## Analysis

### Files Read

- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/iop-hot-path-one-shot-execution.md`
- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`
- `agent-spec/runtime/stream-evidence-gate.md`
- `agent-spec/input/openai-compatible-surface.md`
- `agent-contract/outer/openai-chat-completions-http.md`
- `agent-contract/outer/anthropic-messages-http.md`
- `agent-task/m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration/PLAN-cloud-G09.md`
- `agent-task/m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration/CODE_REVIEW-cloud-G09.md`
- `agent-task/m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration/code_review_cloud_G09_1.log`
- `agent-task/m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration/plan_cloud_G08_1.log`
- `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/12+10,11_outer_turn_core/complete.log`
- `apps/edge/internal/openai/hot_path_terminal_control.go`
- `apps/edge/internal/openai/hot_path_direct.go`
- `apps/edge/internal/openai/artifact_pair.go`
- `apps/edge/internal/openai/hot_path_light.go`
- `apps/edge/internal/openai/hot_path_cleanup.go`
- `apps/edge/internal/openai/hot_path_terminal_control_test.go`
- `apps/edge/internal/openai/hot_path_light_test.go`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`

### SDD Criteria

- Approved SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`; status `approved`, review `approved`, lock `unlocked`.
- First-line scope: `milestone-task=terminal-control`.
- Targeted Acceptance Scenario: S10, one outer response envelope across same-HTTP internal stages with public tool/block identity, ordered deltas, summed usage, caller output-cap enforcement, and exactly one terminal.
- Evidence Map: the S10 Edge unit/integration row requires sequence, output-cap, identity, usage, terminal, and race evidence. It shapes REVIEW_REVIEW_API-1 around one terminal/frontier owner and REVIEW_REVIEW_API-2 around Chat/Messages handler regressions plus race verification.

### Verification Context

- No external handoff was supplied. Evidence comes from the current dirty checkout and the repository-native source, contract, spec, domain, and test files listed above.
- Fresh review commands passed on Go `go1.26.2 linux/arm64`: `go test -race -count=1 -v ./apps/edge/internal/openai -run 'TestHotPath(OuterTurnIntegration|OuterTurnCompatibility|Direct|Light|Cleanup)'`, the four-package race set, `go vet ./apps/edge/...`, and `git diff --check`.
- A temporary focused handler regression, removed after execution, sent a small `read_file` terminal with caller cap 4 and provider-reported output usage 4. Both OpenAI and Anthropic published a public tool id, but the expected logical frontier count was 0 instead of 1. This directly disproves the claimed cap-terminal contract.
- Verification is deterministic, local, credential-free, and requires no external runner, host, port, or artifact. Fresh `-count=1` race output is required; cached test output is not acceptable.

### Test Coverage Gaps

- Existing tests cover ordinary tool continuation and content-only cap exhaustion, but not their cross-product: a terminal tool emitted exactly when the caller cap becomes exhausted.
- Existing handler matrices cover Chat and Messages, but do not assert that every caller-visible tool id retains one live expected-result frontier at cap.
- Existing budget tests use provider-reported usage or ASCII payloads. No usage-less multistage Unicode row proves that dispatch admission never exceeds a model-independent conservative upper bound.
- Direct, artifact, light, and cleanup paths each check exhaustion before or adjacent to frontier projection/registration; their shared invariant lacks one regression matrix.

### Symbol References

- None. No public or internal symbol rename/removal is planned.

### Split Judgment

- Keep one implementation packet. Budget admission, terminal selection, public tool identity, and expected-result frontier registration form one indivisible caller-visible invariant.
- Predecessor `12+10,11_outer_turn_core` is satisfied by `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/12+10,11_outer_turn_core/complete.log`.

### Scope Rationale

- Include only the shared outer budget/terminal logic, the direct/artifact/light/cleanup tool-frontier call sites, and deterministic Edge tests needed to close the Required finding.
- Exclude endpoint codec replacement, live provider/node smoke, telemetry, schema changes, non-Hot-Path cleanup redesign, and later S14-S16 work because none is required to preserve a live continuation frontier or conservatively admit the next internal stage.

### Final Routing

- `evaluation_mode=isolated-reassessment`; finalizer `finalize-task-policy.sh`, mode `pair`.
- Build closures: `scope_closed=true`, `context_closed=true`, `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`; closure basis is the complete follow-up packet plus deterministic local handler/race evidence. Capability gap: none.
- Build closure scores: scope=2, state/concurrency=2, blast/irreversibility=1, evidence/diagnosis=2, verification=2; lane `cloud`, grade G09, base/route basis `grade-boundary`.
- Positive loop-risk signatures: `temporal_state`, `concurrent_consistency`, `boundary_contract`, `variant_product` (4); `large_indivisible_context=false`.
- Recovery signals: `review_rework_count=2`, `evidence_integrity_failure=false`; `risk=true`, `recovery=true`. No capability gap is present.
- Review closures: `scope_closed=true`, `context_closed=true`, `verification_closed=true`, `evidence_trusted=true`, `ownership_closed=true`, `decision_closed=true`; closure basis is the fixed review checkpoints and exact rerunnable gates. Capability gap: none.
- Review closure scores: scope=2, state/concurrency=2, blast/irreversibility=1, evidence/diagnosis=2, verification=2; `official-review`, lane `cloud`, grade G09, adapter `codex`, model `gpt-5.6-sol`, reasoning effort `xhigh`.
- Canonical active files: `PLAN-cloud-G09.md` and `CODE_REVIEW-cloud-G09.md`.

## Implementation Checklist

- [ ] [REVIEW_REVIEW_API-1] Preserve one live tool-result frontier when the current stage reaches the caller cap, and use conservative model-independent admission for usage-less stages across direct, artifact, light, and cleanup paths.
- [ ] [REVIEW_REVIEW_API-2] Add Chat/Messages handler regressions for cap-at-tool-terminal continuity and usage-less multistage Unicode budgeting, then run the exact fresh race, vet, and diff gates.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_API-1] Cap-terminal and frontier ownership

**Problem:** `apps/edge/internal/openai/hot_path_direct.go:46`, `artifact_pair.go:222`, `hot_path_light.go:812`, and `hot_path_cleanup.go:175` resolve exhaustion before the emitted tool terminal is registered as an expected-result frontier. `hot_path_terminal_control.go:149` gives each token four public runes and `hot_path_terminal_control.go:439` reuses that optimistic estimate for usage-less stage admission. The current code can expose a tool that cannot be continued or dispatch another internal stage after a caller budget is already consumed.

**Solution:** Separate “may dispatch another provider stage” from “must preserve the current terminal tool frontier.” Aggregate the current stage first. If its compatibility output contains tool calls, project stable public ids, fingerprint exactly that visible output, register the matching expected-result frontier, and return the protocol-native tool terminal even when no further same-HTTP provider dispatch is allowed. Only content/reasoning completion with no tool continuation may convert exhaustion into `length` and delete the request. Replace the four-runes-per-token usage-less admission estimate with a fail-closed UTF-8 byte upper bound over all model-authored public payload channels, including text, reasoning, tool names, and serialized arguments; combine it with provider-reported output usage by taking the larger consumed bound. Keep public truncation UTF-8 safe and keep a caller continuation's new HTTP-turn cap independent from the exhausted prior turn.

Before (`apps/edge/internal/openai/hot_path_direct.go:46`):

```go
if turn.OuterTurn.outputBudget().Exhausted {
	turn.OuterTurn.commitLengthTerminal()
	visible = hotPathCompatibilityOutput(turn.OuterTurn, output, turn.Protocol)
	s.terminalPresetRequest(turn.RequestID, turn.OwnerEdgeID)
	return s.writeDirectResponse(turn, visible)
}
```

After:

```go
visible = hotPathCompatibilityOutput(turn.OuterTurn, output, turn.Protocol)
if len(visible.ToolCalls) == 0 && turn.OuterTurn.outputBudget().Exhausted {
	turn.OuterTurn.commitLengthTerminal()
	s.terminalPresetRequest(turn.RequestID, turn.OwnerEdgeID)
	return s.writeDirectResponse(turn, hotPathCompatibilityOutput(turn.OuterTurn, output, turn.Protocol))
}
// Tool terminals continue through the normal public-id and frontier path.
```

Before (`apps/edge/internal/openai/hot_path_terminal_control.go:439`):

```go
estimatedVisibleTokens := (t.consumedRunes + 3) / 4
remaining := t.outputCapTokens - estimatedVisibleTokens
```

After:

```go
consumedUpperBound := t.consumedOutputTokenUpperBound()
remaining := t.outputCapTokens - consumedUpperBound
// Provider usage may tighten, but never loosen, this model-independent bound.
```

**Modified Files and Checklist:**

- [ ] Modify `apps/edge/internal/openai/hot_path_terminal_control.go` to expose conservative usage-less consumed budget and a terminal/tool-aware next-stage admission decision.
- [ ] Modify `apps/edge/internal/openai/hot_path_direct.go` to register a visible tool frontier before any destructive cap cleanup.
- [ ] Modify `apps/edge/internal/openai/artifact_pair.go` to keep mapped artifact tool ids, issued hash, pending payloads, and the cap-terminal frontier aligned.
- [ ] Modify `apps/edge/internal/openai/hot_path_light.go` to preserve local/review tool continuations at cap while preventing a later provider submission.
- [ ] Modify `apps/edge/internal/openai/hot_path_cleanup.go` to register the synthetic cleanup tool continuation even when the same outer turn has no remaining provider budget.

**Test Strategy:** Write regressions in `hot_path_terminal_control_test.go` for conservative Unicode/no-usage accounting and terminal selection. Use valid UTF-8 multibyte payloads and assert zero later dispatch once the byte upper bound exhausts the cap. The handler matrix in REVIEW_REVIEW_API-2 proves the public-id/frontier invariant.

**Verification:** `go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPath(OuterTurnIntegration|OuterTurnCompatibility|OuterTurnCap|Direct|Light|Cleanup)'` exits 0 with no race and no post-cap provider submission.

### [REVIEW_REVIEW_API-2] Protocol handler regression matrix

**Problem:** `apps/edge/internal/openai/hot_path_light_test.go:54` and `:175` cover same-HTTP stage composition and compatibility, while `hot_path_terminal_control_test.go:488` covers output truncation. None combines a caller cap, terminal tool output, response identity remapping, live expected-result frontier, and later provider-submission count for both protocols.

**Solution:** Extend the existing scripted handler fixtures rather than add a parallel harness. Add OpenAI Chat and Anthropic Messages rows that (1) emit a small ordinary tool exactly at provider-reported exhaustion, (2) assert the wire response contains the public tool id and endpoint-native terminal reason, (3) inspect the coordinator for exactly one matching expected result, (4) submit the correlated continuation and prove it is accepted once, and (5) assert no same-HTTP provider stage was submitted after exhaustion. Add usage-less Unicode multistage rows that omit provider usage and assert the conservative bound prevents the next local/review dispatch. Cover mapped artifact and cleanup terminals through their existing fixtures or focused package tests, with exact pending/frontier hashes and counts.

Before (`apps/edge/internal/openai/hot_path_light_test.go:54`):

```go
func TestHotPathOuterTurnIntegration(t *testing.T) {
	for _, protocol := range []string{"openai", "anthropic"} {
		// Existing transition rows do not combine cap exhaustion with tool continuation.
	}
}
```

After:

```go
func TestHotPathOuterTurnIntegration(t *testing.T) {
	for _, protocol := range []string{"openai", "anthropic"} {
		// Existing rows plus cap-at-tool terminal and usage-less Unicode rows.
	}
}
```

**Modified Files and Checklist:**

- [ ] Extend `apps/edge/internal/openai/hot_path_terminal_control_test.go` with `TestHotPathOuterTurnCapTerminalContinuity` budget/terminal cases and Unicode usage-less upper-bound assertions.
- [ ] Extend `apps/edge/internal/openai/hot_path_light_test.go` with real Chat/Messages cap-at-tool and Unicode multistage rows, exact provider submission counts, and coordinator frontier assertions.
- [ ] Fill `agent-task/m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration/CODE_REVIEW-cloud-G09.md` with actual design decisions, deviations, and raw verification output.

**Test Strategy:** Regression tests are mandatory because this is a correctness and outer API contract bug. Use the existing scripted provider service and in-package coordinator inspection; do not add live transports or repository-local generated artifacts. Each protocol row must fail if the tool frontier is absent, if a later provider request occurs, or if the continuation is accepted more than once.

**Verification:** Run every command in Final Verification with `-count=1`; the targeted command must execute the named cap-terminal test and both real handler suites.

## Dependencies and Execution Order

1. Preserve the completed predecessor contract recorded at `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/12+10,11_outer_turn_core/complete.log`.
2. Implement REVIEW_REVIEW_API-1 before updating handler expectations.
3. Implement REVIEW_REVIEW_API-2, then run Final Verification and fill the review evidence.

## Modified Files Summary

| File | Item |
|---|---|
| `apps/edge/internal/openai/hot_path_terminal_control.go` | REVIEW_REVIEW_API-1 |
| `apps/edge/internal/openai/hot_path_direct.go` | REVIEW_REVIEW_API-1 |
| `apps/edge/internal/openai/artifact_pair.go` | REVIEW_REVIEW_API-1 |
| `apps/edge/internal/openai/hot_path_light.go` | REVIEW_REVIEW_API-1 |
| `apps/edge/internal/openai/hot_path_cleanup.go` | REVIEW_REVIEW_API-1 |
| `apps/edge/internal/openai/hot_path_terminal_control_test.go` | REVIEW_REVIEW_API-2 |
| `apps/edge/internal/openai/hot_path_light_test.go` | REVIEW_REVIEW_API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/13+12_outer_turn_integration/CODE_REVIEW-cloud-G09.md` | REVIEW_REVIEW_API-2 |

## Final Verification

```bash
go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPath(OuterTurnIntegration|OuterTurnCompatibility|OuterTurnCap|Direct|Light|Cleanup)'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
go vet ./apps/edge/...
git diff --check
```

Expected: every command exits 0; the targeted output executes `TestHotPathOuterTurnCapTerminalContinuity`, the OpenAI and Anthropic cap-at-tool rows expose one public tool id with one matching live frontier, the correlated continuation is accepted exactly once, usage-less Unicode exhaustion causes no later provider submission, and no race or diff error is reported.

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