<!-- task=m-iop-owned-single-request-agent-execution/20+19_review_stage plan=0 tag=API milestone-task=review-stage -->

# Review, repair, and composite activation

## For the Implementing Agent

Filling the implementation-owned sections of `CODE_REVIEW-cloud-G09.md` is the mandatory last implementation step. Run every verification command, paste actual output, keep both active files in place, and report ready for review; only the official code-review skill may append a verdict, archive files, write `complete.log`, or classify the next state. If blocked, record the exact blocker, attempted commands/output, and resume condition only in the review evidence fields; do not ask the user, call a user-input tool, create a control-plane stop file, or change the owner or scope.

## Background

The artifact, Plan, and Work packets establish the service-owned lifecycle and private provider/tool primitives without installing a production executor. This final Epic slice implements the fixed Gemini Review/repair loop, composes all three stages behind the existing service executor/continuation contracts, installs that composite at Edge startup, and updates the current contract/spec. Actual Claude/provider qualification remains the separate S12 `claude-smoke` work item.

## Analysis

### Files Read

- `AGENTS.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/iop-owned-single-request-agent-execution.md`
- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-owned-single-request-agent-execution/SDD.md`
- `agent-spec/runtime/edge-node-execution.md`
- `agent-contract/outer/anthropic-compatible-api.md`
- `agent-contract/inner/execution-runtime.md`
- `apps/edge/internal/service/single_request.go`
- `apps/edge/internal/service/single_request_types.go`
- `apps/edge/internal/service/single_request_tool_types.go`
- `apps/edge/internal/service/single_request_tool_loop.go`
- `apps/edge/internal/service/single_request_test.go`
- `apps/edge/internal/service/single_request_cleanup_test.go`
- `apps/edge/internal/openai/server.go`
- `apps/edge/internal/openai/anthropic_handler.go`
- `apps/edge/internal/openai/single_request_preset_binding.go`
- `apps/edge/internal/input/manager.go`
- `apps/edge/internal/input/manager_test.go`

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-owned-single-request-agent-execution/SDD.md`, `[승인됨]`, `SDD 잠금: 해제`.
- S10 requires Gemini Review with high reasoning, strict pass output, exactly one IOP repair tool call for a defect, `repairing -> internal_tool(saved repairing) -> repairing`, re-review after repair, Review artifact persistence, and only then finalization.
- The production executor must keep all provider stage outcomes private, return only the reviewer-approved final output, and preserve the service coordinator's monotonic lifecycle and cleanup ownership.
- First-line contribution id: `review-stage`.

### Current Behavior and Root Cause

- `apps/edge/internal/service/single_request.go` already invokes a `SingleRequestExecutor`, but no production constructor is installed through `SetSingleRequestExecutor`.
- The preceding packets intentionally stop after a private Work completion candidate. Without Review, repair, and composite ownership, accepting that candidate would bypass S10 and expose an internal stage result as caller output.
- `apps/edge/internal/input/manager.go` creates the OpenAI service and installs its dependencies, making it the narrow production composition point. The existing service lifecycle and public Anthropic handler remain the external boundary and must not be duplicated.
- The outer contract and implementation spec currently defer production execution. They must be updated only after installation and deterministic end-to-end fixtures exist.

### Direct-Small Classification

No slice is direct-small. Review/repair changes provider dispatch and internal-tool temporal behavior; composite execution introduces shared continuation/concurrency ownership; installation changes a runtime responsibility boundary; and contract/spec synchronization depends on those behaviors. They are one ordered large slice with explicit verification.

### Routing Decision

- Plan finalizer input: mode `build`, task key `m-iop-owned-single-request-agent-execution/20+19_review_stage`, plan index `0`, tag `API`, milestone contribution `review-stage`, candidate `agent-task/m-iop-owned-single-request-agent-execution/20+19_review_stage/PLAN.md`.
- Build closures: scope/context/verification/evidence/ownership/decision all true. Scores `2/2/2/1/2` => G09, base and route `grade-boundary`, `worker/cloud/G09`, `PLAN-cloud-G09.md`.
- Review closures: all true. Scores `2/2/2/1/2` => G09, `official-review`, `review/cloud/G09`, `CODE_REVIEW-cloud-G09.md`.
- `large_indivisible_context=false`; positive loop risks: `temporal_state`, `concurrent_consistency`, `boundary_contract`, `structured_interpretation` (4); `review_rework_count=0`; `evidence_integrity_failure=false`; no capability gap.

## Dependencies and Execution Order

1. Do not implement until `agent-task/m-iop-owned-single-request-agent-execution/19+18_work_stage/complete.log` exists. No archive candidate exists yet at plan creation.
2. Implement Review/repair against the predecessor's exact artifact, provider-stage, Work result, and tool-continuation contracts; do not reopen their ownership or wire shapes.
3. Compose Plan → Work → Review and prove deterministic lifecycle/tool behavior before installing the constructor in `apps/edge/internal/input/manager.go`.
4. Update the outer contract and current implementation spec last. Do not mark S12 external provider/Claude qualification complete.

## Implementation Checklist

- [ ] Implement the Gemini high-reasoning Review runner that reads PLAN and Work evidence, accepts only strict pass output, persists REVIEW before finalization, and fails closed on malformed or provider-error outcomes.
- [ ] Implement the one-tool-at-a-time repair path with `repairing -> internal_tool(saved repairing) -> repairing`, exact continuation correlation, bounded re-review, and no release of an unreviewed Work candidate.
- [ ] Add the concurrent request-safe composite executor that drives Plan → Work → Review through one controller, exposes the predecessor's continuation bridge, and returns only reviewer-approved final output.
- [ ] Install the composite executor at Edge input startup and add deterministic S10, full lifecycle, concurrent isolation, cancellation, cleanup, and installation fixtures without altering the public Anthropic schema.
- [ ] Update the current outer contract and implementation spec, then run dependency, focused race, installation, regression, vet, deterministic contract/spec, and diff checks while leaving S12 external evidence deferred.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Implement strict Review and persisted pass evidence

**Problem**

Work produces only an internal completion candidate and verification evidence. Returning it directly would skip the independently routed Gemini reviewer and omit the required durable REVIEW artifact.

**Solution**

Create `single_request_review_stage.go` with a runner that reads the private PLAN artifact, receives the bounded Work result, submits `reviewing`, and sends a fixed high-reasoning Gemini request containing the immutable task, plan, candidate, and verification evidence. Decode a closed result union: pass requires non-empty bounded final output and review summary; defect requires a single repair instruction represented by exactly one admitted IOP workspace tool call. On pass, write `SingleRequestArtifactReview`, then submit `finalizing`, and only then return cloned final bytes. Reject free-form/mixed/multiple/oversized results and sanitize provider failures.

**Modified Files and Checklist**

- [ ] Add the Review prompt, high-option dispatch, closed pass/defect decode, REVIEW write-before-finalize ordering, and bounded result DTO in `apps/edge/internal/openai/single_request_review_stage.go`.
- [ ] Add pass ordering, exact request-body, malformed/mixed/multiple/provider-error, artifact-failure, and cancellation tests in `apps/edge/internal/openai/single_request_review_stage_test.go`.

**Test Strategy**

Use a deterministic provider fake and recording controller. Assert every Review request targets the frozen Gemini route with effective `reasoning_effort=high`; pass writes REVIEW before `finalizing`; no raw provider payload or candidate escapes any failure.

**Verification**

Run `go test -race ./apps/edge/internal/openai -run 'TestSingleRequestReviewStage' -count=1`; pass and fail-closed cases must succeed without races.

### [API-2] Drive bounded repair and mandatory re-review

**Problem**

A defect cannot be finalized or handed back to Work. S10 assigns repair to the Review runner and requires the coordinator's saved-stage internal-tool round trip followed by another independent Review decision.

**Solution**

For a defect response, require exactly one known tool and admitted operation. Submit `repairing`, register the predecessor's correlation bridge, submit `internal_tool` with saved `repairing`, wait for the exact result, submit the saved-stage return, append a bounded sanitized tool exchange, and redispatch Review. Enforce coordinator and local review bounds, reject recursive/multiple/unknown calls, and never expose the pre-repair candidate. Only a later strict pass may persist REVIEW and finalize.

**Modified Files and Checklist**

- [ ] Add the repair/re-review loop to `apps/edge/internal/openai/single_request_review_stage.go` using the predecessor bridge and controller API.
- [ ] Add defect→repair→re-review→pass, correlation, tool/provider failure, bound, duplicate/stale result, and cancel fixtures to `apps/edge/internal/openai/single_request_review_stage_test.go`.

**Test Strategy**

Record exact states and envelopes for a defect fixture. Require `reviewing -> repairing -> internal_tool(saved repairing) -> repairing -> reviewing -> finalizing`, exact tool identity, high reasoning on both Review dispatches, and zero retained waiters.

**Verification**

Run the focused Review race test and inspect its state-order assertion; no defect fixture may reach finalizing before a re-review pass.

### [API-3] Compose the three private stages

**Problem**

Installing stage runners independently would split lifecycle ownership, allow a Work candidate to become terminal, and leave `ContinueInternalTool` without a stable executor instance for concurrent requests.

**Solution**

Create `single_request_executor.go` implementing the existing service executor and tool-continuation interfaces. For each request, run Plan, Work, and Review in order against the same controller and immutable binding. Delegate tool results to the request-safe bridge, preserve cancellation and generic errors, and return only the reviewer-approved final output. The shared executor must contain no per-request mutable state outside keyed bridge entries and must clean every entry on all terminal paths.

**Modified Files and Checklist**

- [ ] Add the composite implementation and exported production constructor in `apps/edge/internal/openai/single_request_executor.go`.
- [ ] Add full pass, repair, concurrent request isolation, cancellation, stage failure, final-output provenance, and waiter cleanup tests in `apps/edge/internal/openai/single_request_executor_test.go`.

**Test Strategy**

Drive a deterministic full lifecycle through the real service controller, including one Work tool and one Review repair tool. Assert the monotonic envelope sequence, artifact order, only the reviewer output at terminal, concurrent identity isolation under `-race`, and cleanup after every injected failure.

**Verification**

Run `go test -race ./apps/edge/internal/openai -run 'TestSingleRequest(ReviewStage|Executor)' -count=1` and the existing service cleanup/tool-loop tests.

### [API-4] Install and synchronize the active contract

**Problem**

Even a complete composite remains unreachable until Edge startup installs it. Once installed, the outer contract/spec must stop claiming that managed single-request execution is unavailable, while still distinguishing deterministic local coverage from S12 external qualification.

**Solution**

Construct and install the executor in `apps/edge/internal/input/manager.go` after the OpenAI service and required runtime dependencies exist. Add an input-layer fixture that exercises the existing single-request path far enough to prove the executor is installed rather than receiving the current unavailable error; do not add a public getter or change the Anthropic request/stream schema. Update the outer contract and current spec with the active ownership, stage ordering, generic failure behavior, local evidence, and explicit S12 deferral.

**Modified Files and Checklist**

- [ ] Install `openai.NewSingleRequestExecutor(...)` through the existing service setter in `apps/edge/internal/input/manager.go`.
- [ ] Add installation and unavailable-regression coverage in `apps/edge/internal/input/manager_test.go`.
- [ ] Update `agent-contract/outer/anthropic-compatible-api.md` and `agent-spec/runtime/edge-node-execution.md` without changing request/event schemas or claiming external qualification.

**Test Strategy**

Use the existing input construction seam and deterministic dependencies. Prove the production manager no longer leaves the executor unset, then run public handler/stream regressions unchanged.

**Verification**

Run the input installation test, broader Edge tests, and deterministic searches for constructor installation, stage order, REVIEW-before-finalize, active contract wording, and deferred S12 evidence.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/openai/single_request_review_stage.go` | API-1, API-2 |
| `apps/edge/internal/openai/single_request_review_stage_test.go` | API-1, API-2 |
| `apps/edge/internal/openai/single_request_executor.go` | API-3 |
| `apps/edge/internal/openai/single_request_executor_test.go` | API-3 |
| `apps/edge/internal/input/manager.go` | API-4 |
| `apps/edge/internal/input/manager_test.go` | API-4 |
| `agent-contract/outer/anthropic-compatible-api.md` | API-4 |
| `agent-spec/runtime/edge-node-execution.md` | API-4 |
| `agent-task/m-iop-owned-single-request-agent-execution/20+19_review_stage/CODE_REVIEW-cloud-G09.md` | API-1, API-2, API-3, API-4 |

## Final Verification

Fresh output is required; Go tests use `-count=1` and cached output is not acceptable.

1. `test -f agent-task/m-iop-owned-single-request-agent-execution/19+18_work_stage/complete.log` — predecessor completion evidence exists before implementation or review.
2. `go test -race ./apps/edge/internal/openai -run 'TestSingleRequest(ReviewStage|Executor)' -count=1` — S10, repair, composite, concurrency, cancellation, and failure fixtures pass without races.
3. `go test ./apps/edge/internal/input -run 'TestManager.*SingleRequestExecutor' -count=1` — production construction installs the executor and does not regress to unavailable.
4. `go test ./apps/edge/internal/service ./apps/edge/internal/openai ./apps/edge/internal/input -count=1` — coordinator, public handler/stream, OpenAI, and input regressions pass freshly.
5. `go vet ./apps/edge/internal/service ./apps/edge/internal/openai ./apps/edge/internal/input && go test ./apps/edge/... -count=1` — changed packages vet cleanly and broader Edge regression passes.
6. `rg --sort path -n 'NewSingleRequestExecutor|SetSingleRequestExecutor|reasoning_effort|SingleRequestArtifactReview|finalizing|repairing' apps/edge/internal/openai apps/edge/internal/input --glob '*.go'` — installation, high Review option, repair, REVIEW persistence, and finalization ordering are explicit and test-covered.
7. `rg --sort path -n 'Plan|Work|Review|repair|active|claude-smoke|S12|deferred' agent-contract/outer/anthropic-compatible-api.md agent-spec/runtime/edge-node-execution.md` — documents describe active local behavior and leave external qualification deferred.
8. `git diff --check` — no whitespace errors.

Actual provider/Claude full-cycle evidence remains intentionally outside this packet and belongs to SDD S12 `claude-smoke`.

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