<!-- task=m-node-provider-execution-liveness-recovery/10+09_stall_recovery plan=6 tag=REVIEW_API milestone-task=bounded-retry -->

# Finish Disabled-Semantic Compatibility and S05 Lifecycle Evidence

## For the Implementing Agent

Implement only the two direct fixes below and run every verification command exactly as written. Filling the implementation-owned sections of `CODE_REVIEW-cloud-G08.md` with actual notes and complete raw output is mandatory. Keep the active pair in place and report ready for review; finalization belongs to the code-review skill. 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`.

## Background

The current partial implementation correctly separates supported-path response ownership from semantic activation and suppresses configured semantic registrations when the flag is false. It does not yet adapt the always-on runtime to the established disabled-semantic Chat/Responses behavior, and the package suite now fails across cancellation, validation, reasoning/finish rendering, tunnel ordering/error, and write-failure variants. The two named matrix tests still stop at private registry/filter assertions, so they cannot close SDD S05.

## Archive Evidence Snapshot

- The reviewed plan=5 pair is archived in this task directory as `plan_cloud_G08_5.log` and `code_review_cloud_G08_5.log` with verdict `FAIL`.
- Required R1: `openAIResponseRuntimeOwned()` is unconditional, but the disabled-semantic release/event-source adapters do not preserve endpoint-native Chat/Responses normalized, buffered SSE, tunnel, cancellation, validation, reasoning/finish, usage, and write-failure behavior; complete the compatibility adapter, remove unreachable ownerless selection, and synchronize active contracts/specs.
- Required R2: `TestOpenAIStallRecoveryMatrix` still invokes the private filter directly and `TestOpenAISemanticGateDisabledCompatibility` only checks the flag and registration count; replace them with deterministic production handler/runtime fixtures proving dispatch, provider selection, new identity, shared budget, old-transport close, safety terminals, cancellation, and exactly-once rendering.
- Fresh reviewer reruns passed the two named matrix commands but the exact package integration command failed across the compatibility variants. Verification 5 through Verification 11 were not executed or recorded, and the implementation artifact substituted a focused command for Verification 4; evidence integrity is not trusted.

## Finding Resolution Map

| Finding | Mode | Exact Fix / Evidence | Changed or Satisfied Precondition |
|---------|------|----------------------|-----------------------------------|
| Required R1 | `direct-fix` | Finish an explicit semantic-disabled compatibility mode in the existing request runtime, event sources, and release sinks; retire constant owner-selection branches while keeping only semantic policy/candidate admission flag-controlled; synchronize the six active contract/spec documents. | All supported entry points already route toward the request runtime and semantic registrations are already split, so this loop can repair one owner instead of reintroducing an ownerless fallback. The failing package tests are deterministic compatibility oracles. |
| Required R2 | `direct-fix` | Replace direct registry/filter assertions with deterministic production handler/runtime fixtures for S05 recovery and guard-terminal rows, then record all eleven commands separately. | Handler entry points, fake RunEvent/tunnel transports, provider-pool fakes, usage recorders, response writers, and close/cancel counters already exist in the package and can exercise the real lifecycle without external services. |

## Analysis

### Files Read

- `apps/edge/internal/openai/stream_gate_runtime.go`
- `apps/edge/internal/openai/stream_gate_release_sink.go`
- `apps/edge/internal/openai/responses_stream_gate.go`
- `apps/edge/internal/openai/stream_gate_policy.go`
- `apps/edge/internal/openai/chat_handler.go`
- `apps/edge/internal/openai/responses_handler.go`
- `apps/edge/internal/openai/chat_completion.go`
- `apps/edge/internal/openai/buffered_sse.go`
- `apps/edge/internal/openai/normalized_sse.go`
- `apps/edge/internal/openai/provider_tunnel.go`
- `apps/edge/internal/openai/stream_gate_stall_recovery_test.go`
- `apps/edge/internal/openai/cancellation_routes_test.go`
- `apps/edge/internal/openai/chat_stream_reasoning_test.go`
- `apps/edge/internal/openai/provider_tunnel_test.go`
- `apps/edge/internal/openai/provider_tool_validation_test.go`
- `agent-contract/inner/execution-runtime.md`
- `agent-contract/inner/edge-config-runtime-refresh.md`
- `agent-contract/outer/openai-compatible-api.md`
- `agent-spec/runtime/stream-evidence-gate.md`
- `agent-spec/input/openai-compatible-surface.md`
- `agent-spec/runtime/edge-node-execution.md`
- `agent-roadmap/phase/operational-observability-provider-management/PHASE.md`
- `agent-roadmap/phase/operational-observability-provider-management/milestones/node-provider-execution-liveness-recovery.md`
- `agent-roadmap/sdd/operational-observability-provider-management/node-provider-execution-liveness-recovery/SDD.md`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`
- `agent-test/local/platform-common-smoke.md`

### SDD Criteria

- SDD: `agent-roadmap/sdd/operational-observability-provider-management/node-provider-execution-liveness-recovery/SDD.md`; status `[Approved]`, implementation lock released, no user review gate.
- Header contribution id: `milestone-task=bounded-retry`.
- Acceptance Scenario S05 permits replay only for a confirmed, uncommitted, side-effect-safe OpenAI request, through the shared StreamGate recovery budget and a new run identity; post-commit, unconfirmed, unsafe, cancelled, missing-snapshot, exhausted-budget, unsupported, and no-owner cases terminate without re-admission.
- Evidence Map S05 requires commit-boundary/shared-budget, provider-pool failover/no-owner, recovery-owner gating, new run identity, and bounded dispatch-count assertions through the production lifecycle.

### Verification Context

- No external handoff was supplied. Inputs are the active implementation, the approved SDD, current contracts/specs, repository source/tests, the archived plan=5 verdict, and fresh reviewer reruns.
- Reviewer reruns: `TestOpenAIStallRecoveryMatrix` and `TestOpenAISemanticGateDisabledCompatibility` pass only their current shallow assertions; the exact package command fails in the OpenAI package while StreamGate, service, and control-plane packages pass.
- Local preconditions are available at repository root `/config/workspace/iop-s1`: Go module tests, separate race runs, vet, repository-local e2e smoke, fake-mode vLLM smoke, provider-capacity smoke, and diff validation. No command requires a remote runner.
- Focused tests must repeat 10-20 times, package integration uses `-count=1`, race packages run separately with `-count=3`, vet emits no diagnostics, all three smokes report PASS, and `git diff --check` is clean. Each invocation needs fresh, complete stdout/stderr in the review artifact.

### Test Coverage Gaps

- Compatibility: no production test proves disabled-semantic Chat/Responses normalized and tunnel behavior for JSON/SSE status, headers, bytes/order, validation, reasoning, finish reason, usage, cancellation, write failure, and exactly one terminal.
- Recovery lifecycle: no named matrix proves alternate or permitted same-provider re-admission, new identity, one shared-budget debit, failed-provider avoidance, confirmed old-transport close, or bounded dispatch count.
- Terminal guards: no named matrix proves zero recovery for unconfirmed, committed, caller-cancelled, tool/side-effect, missing-snapshot, exhausted-budget, unsupported, and no-owner cases.
- Documentation: the active execution/config/OpenAI contracts and matching specs still describe typed-stall ownership as runtime-enabled and make the semantic flag control response-runtime ownership.

### Symbol References

- `openAIResponseRuntimeOwned()` is constant true in `stream_gate_runtime.go` and remains selected in `chat_completion.go`, `buffered_sse.go`, `normalized_sse.go`, `provider_tunnel.go`, `chat_handler.go`, and `responses_handler.go`; remove the unreachable selection branches and call the existing runtime owner directly on supported results.
- `streamGateSemanticEnabled()` is used for provider candidate admission in `chat_handler.go` and `responses_handler.go`; keep it semantic-only and do not use it to select response ownership.
- `openAIOutputFilterRegistrations()` already suppresses configured semantic registrations while disabled; preserve the private request-local typed-stall mechanics and request-local tool validation.
- `TestOpenAIStallRecoveryMatrix` and `TestOpenAISemanticGateDisabledCompatibility` in `stream_gate_stall_recovery_test.go` currently exercise only private filter/registration state and must be replaced, not merely renamed.

### Split Judgment

Keep one plan. Response commit, caller cancellation, semantic-disabled compatibility, shared budget, attempt transport close, provider avoidance, re-admission, and final rendering are one request-local correctness boundary. Splitting the compatibility adapter from its production lifecycle matrix would recreate the shallow-evidence failure this follow-up must close.

### Scope Rationale

Do not add a retry loop, liveness counter, config field, metric, wire field, Core/Node/service recovery owner, or non-OpenAI owner. Do not change the typed failure mapper, service candidate policy, raw provider error policy, or unsupported-surface behavior. Modify only the listed OpenAI owner/adapters/tests and matching active contracts/specs, and preserve unrelated dirty-worktree changes.

### Final Routing

- `status=routed`; `evaluation_mode=isolated-reassessment`; `finalizer=finalize-task-policy.sh`; `finalizer_mode=pair`.
- Build closures: scope/context/verification/evidence/ownership/decision all true; capability gap absent. Scores `(2,2,1,1,2)` produce G08 with base `local-fit`; `large_indivisible_context=false`.
- Positive loop risks: `temporal_state`, `concurrent_consistency`, `boundary_contract`, `variant_product`; count 4 and risk boundary matched.
- Recovery signals: `review_rework_count=3`, `evidence_integrity_failure=true`; recovery boundary matched and build route is `recovery-boundary`, cloud, `PLAN-cloud-G08.md`.
- Review closures are all true; scores `(2,2,1,1,2)` produce G08. Official review is cloud Codex `gpt-5.6-sol` xhigh at `CODE_REVIEW-cloud-G08.md`.

## Implementation Checklist

- [ ] REVIEW_API-1 completes the disabled-semantic compatibility adapter, gives every supported Chat/Responses normalized/tunnel request exactly one private liveness owner, keeps semantic policy/candidate admission flag-controlled, and removes unreachable ownerless selection.
- [ ] REVIEW_API-2 replaces private registry/filter assertions with deterministic production handler/runtime S05 recovery and guard-terminal matrices.
- [ ] Synchronize the active execution/config/OpenAI contracts and matching specs, then run and record every exact verification command separately.
- [ ] Fill implementation-owned sections in `CODE_REVIEW-cloud-G08.md` with actual implementation notes and complete raw output.

### [REVIEW_API-1] Complete the supported-path compatibility adapter

**Problem:** The constant response owner is the correct liveness direction, but the existing event-source and release-sink behavior was written for semantic-enabled execution. With semantic activation false it now changes cancellation status, strict/tool validation, reasoning/finish rendering, tunnel response/error ordering, write-failure cancellation, and usage/terminal behavior. Retaining the current `if openAIResponseRuntimeOwned()` selections also leaves ownerless legacy branches unreachable.

**Solution:** Carry an explicit semantic-disabled compatibility mode from runtime construction through Chat, Responses, normalized/buffered SSE, and tunnel event/release adapters. In that mode, preserve the established endpoint-native status, headers, response envelopes, SSE ordering/sentinel, tool-validation retry/error contract, reasoning visibility/fallback, finish reason, usage finalization, caller cancellation, and write-failure cancellation while the same request runtime remains the sole liveness/recovery owner. Directly enter that owner at all supported result call sites and remove or reuse former legacy paths so no dead owner-selection branch remains. The configuration flag must continue to control only configured semantic filters and provider capability admission; the private typed-stall registration remains active for supported hosts.

**Modified Files and Checklist:**

- [ ] `apps/edge/internal/openai/stream_gate_runtime.go`: propagate explicit semantic compatibility state through one supported response runtime and remove the constant ownership selector.
- [ ] `apps/edge/internal/openai/stream_gate_release_sink.go`: preserve Chat normalized/buffered SSE compatibility for success, validation, reasoning/finish, cancellation, error, usage, write failure, and exactly-one terminal behavior.
- [ ] `apps/edge/internal/openai/responses_stream_gate.go`: preserve Responses normalized compatibility and the same terminal/cancellation invariants.
- [ ] `apps/edge/internal/openai/chat_completion.go`, `apps/edge/internal/openai/buffered_sse.go`, `apps/edge/internal/openai/normalized_sse.go`, `apps/edge/internal/openai/provider_tunnel.go`: directly enter the runtime owner and eliminate unreachable ownerless selection while retaining reusable compatibility rendering only where the adapter calls it.
- [ ] `apps/edge/internal/openai/chat_handler.go`, `apps/edge/internal/openai/responses_handler.go`: keep candidate admission semantic-only and directly route provider-pool normalized/tunnel results into the request runtime.
- [ ] `agent-contract/inner/execution-runtime.md`, `agent-contract/inner/edge-config-runtime-refresh.md`, `agent-contract/outer/openai-compatible-api.md`: state always-on supported-path liveness ownership, semantic-only flag behavior, and preserved public compatibility.
- [ ] `agent-spec/runtime/stream-evidence-gate.md`, `agent-spec/input/openai-compatible-surface.md`, `agent-spec/runtime/edge-node-execution.md`: synchronize the current owner boundary and production evidence pointers.

**Test Strategy:** Add handler-level disabled-semantic fixtures in `stream_gate_stall_recovery_test.go`, reusing package fake RunEvent/tunnel services, response writers, usage recorders, and cancel/close counters. Cover Chat and Responses normalized and tunnel success/error/cancel paths plus strict/tool, reasoning/finish, buffered SSE sentinel/order, tunnel header/body/error ordering, and write failure. Assert public compatibility and exactly one terminal, not helper predicates.

**Verification:** Run commands 3-7 and 11 after the compatibility fixtures pass. The exact package and race commands are required regression oracles; no focused substitute closes this item.

### [REVIEW_API-2] Prove the production S05 lifecycle matrix

**Problem:** The named tests currently evaluate the private filter and registration count directly. They cannot detect missing handler ownership or prove dispatch, provider selection, attempt identity, budget consumption, old-transport close, cancellation, or public terminal behavior.

**Solution:** Replace those shallow assertions with deterministic fixtures that enter the Chat/Responses handlers and drive the existing request runtime over normalized/tunnel and semantic false/true variants. For confirmed uncommitted safe stalls, assert alternate recovery for `available|unavailable|unknown`; allow same-provider-only recovery only for `available`; require a terminal for unavailable/unknown same-only. Assert exactly one replacement dispatch, a new run/attempt identity, one shared-budget debit, failed-provider avoidance, confirmed old-transport close without duplicate cancel, and one public terminal. Add zero-recovery terminal rows for generic/unconfirmed, committed, caller-cancelled, tool/side-effect, missing-snapshot, exhausted-budget, unsupported, and no-owner cases. Keep raw provider failures private and public errors sanitized.

**Modified Files and Checklist:**

- [ ] `apps/edge/internal/openai/stream_gate_stall_recovery_test.go`: implement production lifecycle, compatibility, recovery-selection, identity/budget/close, and guard-terminal matrices.
- [ ] `agent-task/m-node-provider-execution-liveness-recovery/10+09_stall_recovery/CODE_REVIEW-cloud-G08.md`: record implementation decisions and complete raw output for every command.

**Test Strategy:** Rewrite `TestOpenAIStallRecoveryMatrix` and `TestOpenAISemanticGateDisabledCompatibility` around production handlers and runtime adapters. Use deterministic channels and fake clocks/timeouts where needed; assert dispatch and identity records, StreamGate budget state, selected provider, transport close/cancel counts, response bytes/order, usage completion, and exactly-one terminal. Retain existing mapper/filter tests only as lower-level regressions.

**Verification:** Run all eleven commands. Both named tests must exercise the production endpoint/path/config products repeatedly, and the package/race/vet/smoke/diff checks must pass from separate fresh invocations.

## Dependencies and Execution Order

1. Complete REVIEW_API-1 and its disabled-semantic compatibility assertions first.
2. Complete REVIEW_API-2 against the repaired production lifecycle.
3. Synchronize the active contracts/specs, then run all eleven commands separately and fill the review artifact.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/edge/internal/openai/stream_gate_runtime.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/stream_gate_release_sink.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/responses_stream_gate.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/chat_handler.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/responses_handler.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/chat_completion.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/buffered_sse.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/normalized_sse.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/provider_tunnel.go` | REVIEW_API-1 |
| `apps/edge/internal/openai/stream_gate_stall_recovery_test.go` | REVIEW_API-1, REVIEW_API-2 |
| `agent-contract/inner/execution-runtime.md` | REVIEW_API-1 |
| `agent-contract/inner/edge-config-runtime-refresh.md` | REVIEW_API-1 |
| `agent-contract/outer/openai-compatible-api.md` | REVIEW_API-1 |
| `agent-spec/runtime/stream-evidence-gate.md` | REVIEW_API-1 |
| `agent-spec/input/openai-compatible-surface.md` | REVIEW_API-1 |
| `agent-spec/runtime/edge-node-execution.md` | REVIEW_API-1 |
| `agent-task/m-node-provider-execution-liveness-recovery/10+09_stall_recovery/CODE_REVIEW-cloud-G08.md` | REVIEW_API-1, REVIEW_API-2 |

## Final Verification

Fresh output is required. Record each command and its complete stdout/stderr separately; Go cached output is not acceptable where `-count` is present.

1. `go test -count=20 ./apps/edge/internal/openai -run '^(TestOpenAIStallRecoveryFilter|TestOpenAIAttemptControllerConfirmedStall|TestOpenAIAttemptDispatcherStalledProvider)$'` — PASS every iteration.
2. `go test -count=10 ./apps/edge/internal/openai -run '^TestOpenAIStallRecoveryMatrix$'` — PASS every production endpoint/path/config/recovery/terminal row.
3. `go test -count=10 ./apps/edge/internal/openai -run '^TestOpenAISemanticGateDisabledCompatibility$'` — PASS every production endpoint-native compatibility row.
4. `go test -count=1 ./packages/go/streamgate ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/controlplane` — PASS.
5. `go test -race -count=3 ./apps/edge/internal/service` — PASS with no race report.
6. `go test -race -count=3 ./apps/edge/internal/openai` — PASS with no race report.
7. `go vet ./packages/go/streamgate ./apps/edge/internal/service ./apps/edge/internal/openai ./apps/edge/internal/controlplane` — no diagnostics.
8. `./scripts/e2e-smoke.sh` — PASS.
9. `IOP_VLLM_MODE=fake ./scripts/e2e-openai-vllm.sh` — PASS.
10. `./scripts/e2e-provider-capacity-smoke.sh` — PASS.
11. `git diff --check` — no whitespace errors.

After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-cloud-G08.md`.
