<!-- task=m-iop-hot-path-one-shot-execution/14+13_anthropic_gate plan=2 tag=REVIEW_API milestone-task=terminal-control,anthropic-gate -->

# Repair Anthropic Hot Path identity, token budgeting, and live streaming

## For the Implementing Agent

Implement every checklist item, record actual changes and fresh command output in `CODE_REVIEW-cloud-G10.md`, and leave the active pair in place for review. Do not archive task artifacts, write `complete.log`, classify the next state, or start orchestration.

## Background

The first Anthropic caller-codec implementation passes its recorded race suites, but review found three contract failures. A continuation response can expose the IOP logical request ID instead of the first provider response ID, `max_tokens` is approximated with rune and byte counts, and the production handler buffers provider tunnel frames through `END` before writing SSE. This follow-up keeps the existing normalized stage boundary and repairs those behaviors without moving provider-wire decoding into the endpoint codec.

## Archive Evidence Snapshot

- `plan_cloud_G09_1.log` requested the initial caller-facing Anthropic Messages codec, caller cap propagation, and handler-level wire fixtures.
- `code_review_cloud_G10_1.log` records `FAIL` with three Required findings: provider response identity was replaced by logical request identity, token limits were enforced as characters/bytes, and the production tunnel was fully buffered while the post-commit error test bypassed the handler.
- Reviewer verification was fresh and trustworthy: the targeted race test, common race suite, and `git diff --check` all exited 0. The follow-up is required for behavior and coverage, not evidence-integrity repair.

## Analysis

### Files Read

- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`
- `agent-contract/outer/anthropic-compatible-api.md`
- `agent-spec/input/openai-compatible-surface.md`
- `apps/edge/internal/openai/anthropic_handler.go`
- `apps/edge/internal/openai/anthropic_stream.go`
- `apps/edge/internal/openai/hot_path_direct.go`
- `apps/edge/internal/openai/hot_path_dispatch.go`
- `apps/edge/internal/openai/hot_path_light.go`
- `apps/edge/internal/openai/hot_path_stage_stream.go`
- `apps/edge/internal/openai/hot_path_terminal_control.go`
- `apps/edge/internal/openai/hot_path_anthropic_gate_test.go`
- `apps/edge/internal/openai/hot_path_terminal_control_test.go`
- `apps/edge/internal/openai/anthropic_bridge_test.go`
- `apps/edge/internal/openai/anthropic_native_test.go`
- `agent-test/local/rules.md`

### SDD and Contract Criteria

- S10 requires one outer envelope, stable block/tool identity, aggregate usage, one HTTP-turn terminal, and terminal-only hold across internal stages.
- S11 requires Anthropic-native event ordering and stop/error shapes through direct/light continuation.
- The approved SDD requires nonterminal stage deltas to be released in endpoint-native order without whole-stage buffering and applies the caller output cap across the outer response.
- The Anthropic contract requires a provider-reported response ID for virtual-preset success, including `message_start.message.id`, and forbids an IOP request/run/transport fallback.
- `max_tokens` is a token limit and response usage remains provider-reported; character or UTF-8 byte counts are not token usage.

### Current Failure Mechanisms

- `runHotPathLightStage` creates the request-local outer turn with `iop_logical_request_id`. `bindResponseID` refuses to replace it after a stage has started, so the public message and generated tool namespace retain transport identity.
- `newHotPathCallerCappedOuterTurn` converts the token cap to four runes per token, truncates released content locally, and computes later-stage remaining budget from the maximum of visible UTF-8 bytes and provider usage.
- `collectPresetTunnelResult` buffers BODY frames until END. `runInitialPresetTurn` calls it before dispatching the outer turn, so no caller-visible SSE can flush while the provider tunnel remains open.
- The post-commit error test invokes `startStream` and `writeError` directly; it does not exercise tunnel ERROR handling after a handler-visible delta.

### Verification Context

- Deterministic channel-controlled handler tests can prove true progressive flush by keeping the fake provider tunnel open and observing the response writer before END.
- Token-budget tests must distinguish visible character length from reported token usage, verify remaining budget sent to a later stage, and cover missing-usage fail-closed behavior without inventing a tokenizer.
- Ordinary native passthrough and Chat bridge behavior remain regression surfaces and must continue to pass.

### Symbol References

- No public symbol rename or removal is planned.
- Provider protocol decoders remain in `hot_path_stage_stream.go`; the Anthropic codec remains caller-wire-only.

### Split Judgment

- The three findings are coupled through one request-local outer turn: provider identity must bind before the first live release, usage determines subsequent stage admission, and the same sink owns the final Anthropic terminal. Splitting them would duplicate and race changes to the same state machine.

### Scope Rationale

- This follow-up repairs only the three Required review findings and their deterministic tests. It excludes the sibling Chat codec, the broader error/cancel matrix, observability, real-provider smoke, roadmap updates, and unrelated dirty-worktree changes.

### Final Routing

- evaluation_mode=isolated-reassessment; finalizer=`finalize-task-policy.sh pair`.
- build scores=2/2/2/1/2; risks=`temporal_state,boundary_contract,structured_interpretation,variant_product` (4); base basis=`grade-boundary`; `large_indivisible_context=false`; review rework=1; evidence integrity failure=false.
- Finalizer result: build=`PLAN-cloud-G09.md`, review=`CODE_REVIEW-cloud-G10.md` with official cloud G10 review.

## Implementation Checklist

- [ ] [API-1] Bind the first validated provider response ID before any caller-visible envelope or delta and keep logical request identity internal.
- [ ] [API-2] Enforce `max_tokens` and inter-stage remaining budget with provider-reported token usage, without rune/byte truncation or fabricated token counts.
- [ ] [API-3] Connect production Anthropic Hot Path dispatch to the incremental normalized stage source/sink and prove handler-level pre-END flush plus post-commit provider error behavior.
- [ ] Fill every implementation-owned section in `CODE_REVIEW-cloud-G10.md` with actual changes, deviations, decisions, and fresh verification output.

### [API-1] Provider response identity

**Problem:** A light continuation initializes the outer turn with the logical request ID. Once stage sequencing or release begins, the later provider response ID cannot become the public message identity, and generated tool IDs inherit the wrong namespace.

**Solution:** Separate internal correlation identity from public provider response identity. Require and bind the first validated provider-reported response ID before opening the Anthropic envelope or releasing any delta. Keep that identity stable across the HTTP turn and use it for `message_start.message.id` and turn-scoped tool IDs. Missing or conflicting identity must fail closed using the existing endpoint-standard pre/post-commit error policy.

**Modified Files and Checklist:**

- [ ] Modify `apps/edge/internal/openai/anthropic_stream.go` to open the codec only after provider identity is bound and never fall back to logical request identity.
- [ ] Modify `apps/edge/internal/openai/hot_path_light.go` so continuation correlation state is distinct from the public response identity.
- [ ] Modify `apps/edge/internal/openai/hot_path_stage_stream.go` to surface the first validated stage response identity before the first live release.
- [ ] Modify `apps/edge/internal/openai/hot_path_terminal_control.go` to bind one public provider identity atomically before response start and tool-id allocation.
- [ ] Modify `apps/edge/internal/openai/hot_path_anthropic_gate_test.go` to assert provider identity, inequality from the logical request ID, stable tool IDs, and missing/conflicting identity failure.

**Test Strategy:** Use distinct logical, first-stage provider, and later-stage provider IDs. Assert that only the first provider ID is public and later internal IDs never appear.

**Verification:** The targeted API command exits 0 under `-race`.

### [API-2] Provider-token output budget

**Problem:** The outer turn treats four runes as one token for truncation and UTF-8 bytes as a conservative token upper bound. This corrupts provider-compliant text and endpoint terminal semantics even when reported output usage is within the caller cap.

**Solution:** Track the caller limit and aggregate reported output usage in tokens. Preserve a stage payload and provider terminal when its reported usage is within the cap. Subtract actual deduplicated provider output tokens before dispatching a later stage and pass the exact remaining value as that stage's `max_tokens`. When a stage omits required usage under a limited multi-stage turn, fail closed deterministically before an unsafe continuation; do not truncate text or invent token usage from characters or bytes. Preserve a current tool terminal that legitimately reaches the cap and use `max_tokens` only when provider-reported aggregate usage exhausts the public turn.

**Modified Files and Checklist:**

- [ ] Modify `apps/edge/internal/openai/hot_path_terminal_control.go` to remove rune/byte token approximations and base remaining/exhaustion state on deduplicated provider-reported usage.
- [ ] Modify `apps/edge/internal/openai/hot_path_direct.go` and `apps/edge/internal/openai/hot_path_light.go` to apply reported-token admission and deterministic missing-usage failure before later stages.
- [ ] Modify `apps/edge/internal/openai/hot_path_terminal_control_test.go` to cover within-cap long text, exact remaining budget, true reported exhaustion, tool-terminal continuity, Unicode, deduplication, and missing usage.
- [ ] Modify `apps/edge/internal/openai/hot_path_anthropic_gate_test.go` so the non-stream cap fixture preserves provider-compliant content and `end_turn`, and add a multi-stage exact-remaining-budget case.

**Test Strategy:** Make content length intentionally unrelated to `usage.output_tokens`; assert no local truncation and inspect the next provider request's `max_tokens`.

**Verification:** Targeted outer-turn and Anthropic commands exit 0 under `-race`.

### [API-3] Production live stage release

**Problem:** The initial provider tunnel is collected into a buffer through END before `dispatchPresetTurn` and the Anthropic codec run. Existing incremental stage sources are tested only below the handler, and the post-commit error fixture calls codec methods directly.

**Solution:** Adapt the already-dispatched initial tunnel and later Hot Path stage tunnels to the normalized stage source/sink used by the outer turn. Incrementally decode provider frames, structurally gate safe releases, bind identity, flush Anthropic `message_start` and block deltas as they become caller-visible, and hold provider stage terminals until the outer decision is final. A provider ERROR before commitment remains one JSON `api_error`; after any SSE release it becomes exactly one native `error` event with no `message_delta` or `message_stop`. Preserve one submission for the initial selector and avoid double-decoding provider wire in the endpoint codec.

**Modified Files and Checklist:**

- [ ] Modify `apps/edge/internal/openai/anthropic_handler.go` to hand the already-dispatched provider result to the live Hot Path runner and select pre/post-commit error output from actual codec state.
- [ ] Modify `apps/edge/internal/openai/anthropic_stream.go` to encode normalized releases incrementally and finalize exactly one endpoint-native terminal.
- [ ] Modify `apps/edge/internal/openai/hot_path_dispatch.go` to replace the Hot Path whole-tunnel collection path with the existing incremental stage source while retaining structural classification and one-submit ownership.
- [ ] Modify `apps/edge/internal/openai/hot_path_stage_stream.go` to expose the stage lifecycle needed by production dispatch without moving endpoint encoding into provider decoders.
- [ ] Modify `apps/edge/internal/openai/hot_path_direct.go` and `apps/edge/internal/openai/hot_path_light.go` to consume one live outer-stage result without replaying collected deltas or nested terminals.
- [ ] Modify `apps/edge/internal/openai/hot_path_anthropic_gate_test.go` with a channel-controlled handler test that observes flushed SSE before END, then injects ERROR and asserts one `error` with no `message_stop`; retain fragmentation, mixed-provider, direct/light, and non-stream cases.
- [ ] Record implementation evidence in `agent-task/m-iop-hot-path-one-shot-execution/14+13_anthropic_gate/CODE_REVIEW-cloud-G10.md`.

**Test Strategy:** Run the handler in a goroutine with an observable flush-capable writer. Send RESPONSE_START and a fragmented safe delta, require a flush before sending END, then separately inject a tunnel ERROR after that release and assert the terminal event sequence.

**Verification:** The targeted handler command and the common race suite exit 0, with no goroutine leaks or duplicate terminal events.

## Dependencies and Execution Order

1. Preserve the completed outer-turn/stage-stream baseline already present in the worktree; do not start or monitor orchestration.
2. Implement API-1 identity binding before enabling API-3 live release.
3. Implement API-2 token budgeting before admitting a second live stage.
4. Complete API-3 handler integration and channel-controlled tests, then run Final Verification.

## Modified Files Summary

| File | Item |
|---|---|
| `apps/edge/internal/openai/anthropic_handler.go` | API-3 |
| `apps/edge/internal/openai/anthropic_stream.go` | API-1, API-3 |
| `apps/edge/internal/openai/hot_path_direct.go` | API-2, API-3 |
| `apps/edge/internal/openai/hot_path_dispatch.go` | API-3 |
| `apps/edge/internal/openai/hot_path_light.go` | API-1, API-2, API-3 |
| `apps/edge/internal/openai/hot_path_stage_stream.go` | API-1, API-3 |
| `apps/edge/internal/openai/hot_path_terminal_control.go` | API-1, API-2 |
| `apps/edge/internal/openai/hot_path_anthropic_gate_test.go` | API-1, API-2, API-3 |
| `apps/edge/internal/openai/hot_path_terminal_control_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/14+13_anthropic_gate/CODE_REVIEW-cloud-G10.md` | API-3 evidence |

## Final Verification

```bash
go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPathAnthropic|TestHotPathOuterTurn|TestHotPathStage|TestAnthropic(ChatBridge|Native)'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
git diff --check
```

Expected: all commands exit 0; Anthropic virtual-preset output uses the first provider response ID, preserves token-compliant content, supplies exact remaining tokens to later stages, flushes safe SSE before provider END, and emits exactly one endpoint-native success or error terminal.

After completing all code changes, fill the implementation-owned sections in `CODE_REVIEW-cloud-G10.md` and leave the active pair for review.
