<!-- task=m-iop-owned-single-request-agent-execution/03+02_single_ingress plan=1 tag=API milestone-task=single-ingress -->

# Surface-neutral Single-request Coordinator and Ingress

## For the Implementing Agent

Do not start until packet 02 has `complete.log`. Implement this plan exactly within the listed write boundary, run every verification command, fill all implementation-owned sections of `CODE_REVIEW-cloud-G10.md` with actual notes and stdout/stderr, keep the active pair in place, and report ready for review. Finalization belongs only to the code-review skill. If blocked, record exact blocker evidence, attempted commands/output, and the resume condition; do not ask the user, call user-input tools, create control-plane stop files, classify the next state, archive logs, or write `complete.log`.

## Archive Evidence Snapshot

- Superseded pair: `plan_cloud_G09_0.log`, `code_review_cloud_G10_0.log`.
- The superseded pair contained no implementation evidence or review verdict; implementation has not started.
- Self-review correction: coordinator/state ownership moves from `openai.Server` to the surface-neutral `service` package, `repairing` is restored to the approved state machine, and endpoint integration uses a separate optional interface instead of widening the legacy `runService` contract. Edge vet coverage is restored.

## Background

The current Anthropic path may expose caller-mediated preset/tool continuations across turns. The marked path needs exactly one accepted `/v1/messages` request whose immutable binding drives a request-local coordinator through all internal stages and yields one sanitized result or failure. The endpoint package owns translation only; coordinator semantics must remain reusable by other surfaces.

## Analysis

### Files Read

- `AGENTS.md`
- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/common/rules-agent-spec.md`
- `agent-ops/rules/project/domain/edge/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.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`
- `apps/edge/internal/service/service.go`
- `apps/edge/internal/service/run_types.go`
- `apps/edge/internal/service/provider_pool.go`
- `apps/edge/internal/openai/server.go`
- `apps/edge/internal/openai/route_resolution.go`
- `apps/edge/internal/openai/anthropic_handler.go`
- `apps/edge/internal/openai/request_identity_ingress.go`
- `apps/edge/internal/openai/hot_path_direct.go`
- `apps/edge/internal/openai/anthropic_surface_test.go`
- `apps/edge/internal/openai/request_identity_handler_test.go`
- `apps/edge/internal/openai/provider_test_support_test.go`
- `agent-contract/outer/anthropic-compatible-api.md`
- `agent-spec/input/openai-compatible-surface.md`
- `agent-spec/runtime/edge-node-execution.md`

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-owned-single-request-agent-execution/SDD.md`; status approved and implementation lock released.
- First-line Milestone task: `single-ingress`; targeted Acceptance Scenario: S01.
- Evidence Map row S01 requires one actual `/v1/messages` POST, immutable identity, complete internal multi-stage execution via the coordinator/API boundary, and one final/error. Those facts directly produce API-1/API-2 and the POST-count/race commands in Final Verification.

### Verification Context

- No separate verification handoff was supplied. Repository-native fallback came from the service lifecycle code, Anthropic handler/identity regressions, test fake interface shape, Edge test profile, and approved SDD.
- Precondition: packet 02 completion. Constraints: current checkout only; no external runner/provider; concrete Node/workspace executor stays deferred. Gap: streamed SSE projection is packet 04 and actual Claude smoke is later Milestone evidence.
- Commands use service race tests, endpoint POST/compatibility tests, deterministic doc search, `go vet`, full Edge regression, and `git diff --check`. Confidence is high for coordinator/ingress behavior with an injected multi-stage fake.

### State and Concurrency Findings

- Approved states: `accepted`, `planning`, `working`, `reviewing`, `repairing`, `internal_tool`, `finalizing`, `completed`, `failed`, `cancelled`.
- `internal_tool` must return only to its saved active stage. Stage sequence and retries are validated from internal envelopes; stale, duplicate, or illegal transitions fail closed.
- One terminal wins under completion, failure, cancellation, and duplicate/racing internal events. No goroutine or stage survives request termination.

### Test Coverage Gaps

- No service test exercises the full state graph, repair path, temporary internal-tool state, immutable admission, cancellation, or terminal races.
- Existing endpoint tests do not count one marked HTTP handler POST across a multi-stage executor or prove that the marked branch bypasses legacy caller continuation.

### Symbol References

- No existing symbol is renamed or removed.
- `runService` is implemented by `*service.Service` and multiple OpenAI test fakes. It must not gain the new method; the marked handler uses a separate narrow optional interface.
- `routeDispatch` is the call-site carrier for packet 02's binding; `handleAnthropicMessages` is the endpoint branch point.

### Split Judgment

- Stable child contract: the service coordinator plus marked buffered ingress independently prove S01 with an injected executor and one POST, without depending on SSE projection.
- Predecessor index 02 resolves to `agent-task/m-iop-owned-single-request-agent-execution/02+01_preset_binding/`; its `complete.log` is currently missing, so implementation remains pending and unambiguous.

### Scope Rationale

- Exclude generic Anthropic relay, Chat bridge, count-tokens, unmarked preset continuation, and streaming projection because they have separate compatibility/packet ownership.
- Exclude concrete provider/Node/workspace protocol and actual Claude smoke. Do not expose reasoning, tool protocol, route/provider/credential/workspace data, or internal terminals.

### Final Routing

- `evaluation_mode=isolated-reassessment`; finalizer `finalize-task-policy.sh` in `pair` mode.
- Build closures are true; scores 2/2/2/1/2 = G09; base/final route `grade-boundary`; lane `cloud`; canonical filename `PLAN-cloud-G09.md`.
- Build signals: `large_indivisible_context=false`; positive loop risks `temporal_state`, `concurrent_consistency`, `boundary_contract`, `structured_interpretation`, `variant_product` (5); `review_rework_count=0`; `evidence_integrity_failure=false`; no capability gap.
- Review closures are true; scores 2/2/2/2/2 = G10; route `official-review`; lane `cloud`; canonical filename `CODE_REVIEW-cloud-G10.md`.

## Dependencies and Execution Order

1. Verify packet 02 completion evidence.
2. Implement and race-test the service coordinator before endpoint integration.
3. Add the marked handler branch before legacy pool/continuation admission.
4. Prove one HTTP POST and generic path compatibility, then synchronize contracts/specs.

## Implementation Checklist

- [ ] Implement the surface-neutral request-local coordinator, executor port, complete approved state graph including repair/internal-tool resume, immutable admission, cancellation, and one-shot endpoint terminal acknowledgement before `completed`.
- [ ] Route marked Anthropic Messages requests through a separate optional service capability before legacy admission, keep one HTTP lifetime, and prove one actual POST with a multi-stage fake.
- [ ] Preserve unmarked Anthropic, Chat, and count-tokens behavior; expose only sanitized progress/final/error values and synchronize the boundary documents.
- [ ] Run dependency, targeted race, package, vet, full Edge regression, and `git diff --check` verification.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

## Implementation Plan

### [API-1] Implement the coordinator in service

**Problem**

- `apps/edge/internal/service/service.go:28` owns Edge request/runtime state but exposes no fixed single-request executor/coordinator API.
- The superseded plan placed state in the endpoint server and omitted approved `repairing`, which would violate the surface-neutral domain boundary and reject a valid SDD transition.

**Solution**

Before (`apps/edge/internal/service/service.go:28`):

```go
type Service struct {
    mu                   sync.RWMutex
    registry             *edgenode.Registry
    events               *edgeevents.Bus
    nodeStore            *edgenode.NodeStore
}
```

After:

```go
type Service struct {
    // Existing fields remain.
    singleRequestExecutor SingleRequestExecutor
}

func (s *Service) StartSingleRequest(ctx context.Context, req SingleRequestRequest) (SingleRequestExecution, error)
```

Define a service-owned executor that accepts a frozen binding/input and emits typed internal envelopes. Validate request/stage identity and the full state graph, including the repair loop and saved-stage `internal_tool` detour. Copy mutable inputs and expose only closed progress/result enums. Return a request-scoped execution handle that holds a successful terminal candidate in `finalizing`; it may enter `completed` only after the endpoint calls a one-shot success acknowledgement after its terminal write. Duplicate/stale acknowledgement fails closed; write failure or caller cancellation selects `failed`/`cancelled`. Serialize outcome/ack selection, cancel the executor on exit, and fail within-request if unavailable. Do not import endpoint wire types or implement Node/tool wire.

**Modified Files and Checklist**

- [ ] `apps/edge/internal/service/service.go` — configure the optional executor and expose the surface-neutral request API.
- [ ] `apps/edge/internal/service/single_request.go` — implement executor/envelope types, state validation, redacted progress, cancellation, and terminal ownership.
- [ ] `apps/edge/internal/service/single_request_test.go` — cover success held in finalizing until ack, duplicate/write-failure ack, repair, internal-tool resume, illegal/stale/duplicate events, immutable admission, unavailable executor, cancel, and terminal races under `-race`.

**Test Strategy**

- Add `TestSingleRequestSuccessWaitsForTerminalAck`, duplicate/write-failure acknowledgement cases, `...RepairFlow`, `...InternalToolResumesSavedStage`, invalid envelope/transition tables, `...ImmutableAdmission`, `...ExecutorUnavailable`, `...Cancel`, and terminal race cases.
- Use an injected channel-driven fake executor and run all `TestSingleRequest` cases under the race detector.

**Verification**

- `go test -race ./apps/edge/internal/service -run 'TestSingleRequest' -count=1`
- Expected: all approved paths including repair pass, success cannot reach completed before endpoint acknowledgement, invalid/stale events fail closed, and exactly one outcome/ack wins without races.

### [API-2] Admit marked Anthropic requests exactly once

**Problem**

- `apps/edge/internal/openai/anthropic_handler.go:66` reaches `anthropicPoolRequest`/legacy continuation after dispatch resolution and has no marked one-request branch.
- `apps/edge/internal/openai/server.go:23` defines a widely faked `runService`; widening it would break unrelated test implementations and couple the new capability to generic endpoints.

**Solution**

Before (`apps/edge/internal/openai/server.go:23`):

```go
type runService interface {
    SubmitRun(context.Context, edgeservice.SubmitRunRequest) (edgeservice.RunResult, error)
    SubmitProviderTunnel(context.Context, edgeservice.SubmitProviderTunnelRequest) (edgeservice.ProviderTunnelResult, error)
    SubmitProviderPool(context.Context, edgeservice.ProviderPoolDispatchRequest) (*edgeservice.ProviderPoolDispatchResult, error)
    OllamaAPI(context.Context, edgeservice.OllamaAPIRequest) (edgeservice.OllamaAPIView, error)
    CancelRun(context.Context, edgeservice.CancelRunRequest) (edgeservice.CommandResult, error)
}
```

After, without changing that interface:

```go
type singleRequestService interface {
    StartSingleRequest(context.Context, service.SingleRequestRequest) (service.SingleRequestExecution, error)
}
```

Assert the separate capability only for a marked dispatch. Branch after request validation/authorization but before pool/legacy continuation, copy request input, preserve the public model, and translate one buffered sanitized final/error. Acknowledge success only after the endpoint terminal is written; propagate write failure/cancellation to the handle. Never return caller `tool_use` or re-enter the generic branch.

**Modified Files and Checklist**

- [ ] `apps/edge/internal/openai/server.go` — declare/wire the separate optional single-request capability without expanding `runService`.
- [ ] `apps/edge/internal/openai/anthropic_handler.go` — branch marked admission before legacy execution and translate buffered final/error output.
- [ ] `apps/edge/internal/openai/single_request_handler_test.go` — count real handler POST entry, drive multi-stage/repair fake events, assert one response terminal and private-value absence, and cover missing capability/failure/cancellation.

**Test Strategy**

- Add `TestAnthropicSingleRequestUsesOnePost`, multi-stage/repair success, terminal-write acknowledgement/failure, unavailable capability/failure/cancel, public-model, and private-sentinel assertions in the dedicated test file.
- Rerun `TestPresetRequestIdentityAcrossAnthropicTurns` and `TestPresetRequestIdentityAnthropicCountTokensBypassesCoordinator` unchanged from their existing test file.

**Verification**

- `go test ./apps/edge/internal/openai -run 'Test(AnthropicSingleRequest|PresetRequestIdentityAcrossAnthropicTurns|PresetRequestIdentityAnthropicCountTokensBypassesCoordinator)' -count=1`
- Expected: a marked multi-stage fake enters the HTTP handler once and returns one sanitized terminal; generic continuation/count-tokens behavior is unchanged.

### [API-3] Synchronize the coordinator boundary

**Problem**

- The current outer contract describes caller replay/tool continuation for generic compatibility, and the specs do not distinguish the marked service coordinator boundary.

**Solution**

Add a marked-path exception to the existing virtual-preset Hot Path contract and corresponding specs. Document immutable service admission, one Messages POST, no caller continuation tool wire, public model retention, same-request sanitized failure, and unchanged generic/Chat/count-tokens behavior. Describe the executor as an internal port without claiming concrete workspace/Node implementation or real-provider smoke.

**Modified Files and Checklist**

- [ ] `agent-contract/outer/anthropic-compatible-api.md` — define one-ingress semantics, compatibility, and private/public boundaries.
- [ ] `agent-spec/input/openai-compatible-surface.md` — synchronize marked handler behavior and executable evidence.
- [ ] `agent-spec/runtime/edge-node-execution.md` — record the surface-neutral coordinator port and explicit implementation deferral.

**Test Strategy**

- No standalone documentation test. API-2's named one-POST/privacy/compatibility tests are the executable contract oracle.

**Verification**

- `rg --sort path -n 'single-request|one POST|repairing|tool_use|count_tokens' agent-contract/outer/anthropic-compatible-api.md agent-spec/input/openai-compatible-surface.md agent-spec/runtime/edge-node-execution.md`
- Expected: marked behavior and deferrals are explicit, while generic compatibility remains documented.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/edge/internal/service/service.go` | API-1 |
| `apps/edge/internal/service/single_request.go` | API-1 |
| `apps/edge/internal/service/single_request_test.go` | API-1 |
| `apps/edge/internal/openai/server.go` | API-2 |
| `apps/edge/internal/openai/anthropic_handler.go` | API-2 |
| `apps/edge/internal/openai/single_request_handler_test.go` | API-2 |
| `agent-contract/outer/anthropic-compatible-api.md` | API-3 |
| `agent-spec/input/openai-compatible-surface.md` | API-3 |
| `agent-spec/runtime/edge-node-execution.md` | API-3 |
| `agent-task/m-iop-owned-single-request-agent-execution/03+02_single_ingress/CODE_REVIEW-cloud-G10.md` | API-1, API-2, API-3 |

## Final Verification

1. `test -f agent-task/m-iop-owned-single-request-agent-execution/02+01_preset_binding/complete.log || find agent-task/archive -type f -path '*/m-iop-owned-single-request-agent-execution/02+01_preset_binding/complete.log' -print | sort | grep -q .`
2. `go test -race ./apps/edge/internal/service -run 'TestSingleRequest' -count=1`
3. `go test ./apps/edge/internal/openai -run 'Test(AnthropicSingleRequest|PresetRequestIdentityAcrossAnthropicTurns|PresetRequestIdentityAnthropicCountTokensBypassesCoordinator)' -count=1`
4. `rg --sort path -n 'single-request|one POST|repairing|tool_use|count_tokens' agent-contract/outer/anthropic-compatible-api.md agent-spec/input/openai-compatible-surface.md agent-spec/runtime/edge-node-execution.md`
5. `go test ./apps/edge/internal/service ./apps/edge/internal/openai -count=1`
6. `go vet ./apps/edge/...`
7. `go test ./apps/edge/... -count=1`
8. `git diff --check`

Expected: predecessor evidence exists; service race/state tests pass; one marked handler POST yields one sanitized final/error without caller continuation; generic regressions pass. Concrete workspace execution and actual Claude smoke remain unclaimed.

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