<!-- task=m-iop-hot-path-one-shot-execution/07+02,04,06_route_selector_direct plan=0 tag=API milestone-task=route-selector,direct-flow -->

# Structural Mode Selection and Direct Flow

## For the Implementing Agent

Start only after predecessors 02/04/06 complete. Implement, run every command, and fill `CODE_REVIEW-cloud-G08.md` with actual notes/output; leave active files for official review. If blocked, record exact evidence and resume condition only. Do not ask the user, create control files, classify next state, archive, or write `complete.log`.

## Background

The fused selector/planner must choose from emitted structure, not prose or hidden markers. This packet establishes the fail-closed decision boundary and completes `direct`, including high-thinking and ordinary agent tool round-trips, without creating the reserved artifact namespace.

## Dependencies and Execution Order

- Required predecessors are `02+01_preset_generation`, `04+02,03_preset_model_authorization`, and `06+04,05_request_identity_ingress`.

## Analysis

### Files Read

- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`
- `apps/edge/internal/openai/route_resolution.go`
- `apps/edge/internal/openai/chat_handler.go`
- `apps/edge/internal/openai/chat_types.go`
- `apps/edge/internal/openai/anthropic_handler.go`
- `apps/edge/internal/openai/anthropic_types.go`
- `apps/edge/internal/openai/anthropic_surface_test.go`
- `apps/edge/internal/openai/stream_gate_ingress_test.go`
- `agent-spec/runtime/stream-evidence-gate.md`

### SDD Criteria

Approved/unlocked SDD. Header tasks `route-selector,direct-flow`; S03 requires direct/general-tool versus exact reserved control shapes and deterministic rejection without prose parsing; S07 requires text/high-think/tool direct completion and artifact absence. Evidence Map S03/S07 sets both the selector table and end-to-end tests.

### Verification Context

No handoff. Local fake run/tunnel services and stream fixtures are enough; fresh/race tests required. Protocol-level multi-stage re-encoding is deferred to Epic 3, but one-stage direct must retain current endpoint-native behavior. Confidence: high.

### Test Coverage Gaps

Existing handlers cover text, thinking, native/text tool calls, and stream completion, but no preset structural classifier or reserved path absence assertion. Add classifier tables and preset direct handler integration while retaining existing suites.

### Symbol References

No rename/removal. New selector/runner is called from the preset dispatch hook introduced by child 06.

### Split Judgment

This unchanged pair consumes the refined preset/model/identity closure children and owns structural selection plus direct behavior. Workspace binding and artifact frontiers remain separate. Direct and selector stay together because the accepted non-reserved shape is itself the direct entry invariant.

### Scope Rationale

Exclude workspace binding/pair validation, local/review/repair, cleanup, cross-stage envelope composition, and output observability. Do not parse natural-language reasoning or recover direct failure as light.

### Final Routing

`evaluation_mode=first-pass`; `finalizer=finalize-task-policy.sh` pair. Build closures true, scores `(2,1,2,1,1)` => local-fit G07; `large_indivisible_context=false`, risks `boundary_contract,structured_interpretation,variant_product` (3), rework 0, evidence-integrity false, no gap; `PLAN-local-G07.md`. Review scores `(2,1,2,2,1)` => official cloud G08, `CODE_REVIEW-cloud-G08.md`, Codex `gpt-5.6-sol` xhigh.

## Implementation Checklist

- [ ] Classify direct/light candidates only from normalized emitted structure, preset allowlist, and deterministic capability/health gates.
- [ ] Execute direct text, high-thinking, and ordinary tool continuations with no Plan/Review artifact and stable public model identity.
- [ ] Run focused integration, common race, vet, and diff verification exactly as written.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Add deterministic structural decision classification

#### Problem

`routeDispatch` selects provider mechanics only (`route_resolution.go:53-82`) and handler output paths do not distinguish reserved artifact controls. The SDD forbids mode markers and reasoning parsing.

#### Solution

Normalize selector output into content/reasoning/general tool calls and canonical reserved controls. Exact prepare or exact pair is a light candidate; absence of reserved controls is direct; partial pair, mixed reserved/general calls, wrong reserved path, unsupported allowlist, or failed hard gate is a typed validation error with stable reason.

```go
// Before: provider result flows directly to endpoint encoding.

// After
decision, err := classifyHotPathOutput(preset, issuedPaths, normalizedEvents)
switch decision.Mode { case modeDirect: /* direct runner */; case modeLight: /* child 10 */ }
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/hot_path_selector.go` — normalized structural classifier and reason codes.
- [ ] `apps/edge/internal/openai/hot_path_selector_test.go` — shape/allowlist/capability/health table.

#### Test Strategy

Write `TestHotPathSelectorDecisionMatrix` covering content, thinking, general tools, exact prepare/pair, partial/mixed/duplicate/wrong path, light-disabled, heavy/custom, unhealthy route, and prose containing words “direct/light”. Assert prose never changes mode.

#### Verification

```bash
go test -count=1 ./apps/edge/internal/openai -run TestHotPathSelectorDecisionMatrix
```

Expect PASS.

### [API-2] Complete the direct state path

#### Problem

Chat and Anthropic handlers currently dispatch one route (`chat_handler.go:101-141` and corresponding Messages flow) and child 06 only joins the coordinator. A preset direct turn needs the selector stage to become the public response/tool continuation without downstream stages or artifact state.

#### Solution

Implement a direct runner that commits released content/reasoning/general tools, records expected tool results on the same logical request, resumes the same stage, and marks logical completion once. Reuse existing endpoint encoders and model echo; enforce that no reserved `.iop/job/` operation or artifact path can be emitted.

```go
// Before: preset dispatch hook has no executable mode.

// After
func (s *Server) runDirectTurn(ctx context.Context, turn *hotPathTurn, output normalizedStageOutput) error
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/hot_path_dispatch.go` — invoke selector and direct runner from preset turns.
- [ ] `apps/edge/internal/openai/hot_path_direct.go` — direct transitions/tool frontier/completion.
- [ ] `apps/edge/internal/openai/hot_path_direct_test.go` — Chat/Messages text, thinking, tool resume, and artifact-absence integration.

#### Test Strategy

Write `TestHotPathDirectChat` and `TestHotPathDirectAnthropic` with stream/non-stream text, high thinking, one ordinary tool round-trip, duplicate result rejection, public model echo, and an assertion that no emitted call/path contains `.iop/job/`.

#### Verification

Run `go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPath(Selector|Direct)'`; expect PASS.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/openai/hot_path_selector.go` | API-1 |
| `apps/edge/internal/openai/hot_path_selector_test.go` | API-1 |
| `apps/edge/internal/openai/hot_path_dispatch.go` | API-2 |
| `apps/edge/internal/openai/hot_path_direct.go` | API-2 |
| `apps/edge/internal/openai/hot_path_direct_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/07+02,04,06_route_selector_direct/CODE_REVIEW-cloud-G08.md` | API-1, API-2 |

## Final Verification

```bash
test -f agent-task/m-iop-hot-path-one-shot-execution/02+01_preset_generation/complete.log
test -f agent-task/m-iop-hot-path-one-shot-execution/04+02,03_preset_model_authorization/complete.log
test -f agent-task/m-iop-hot-path-one-shot-execution/06+04,05_request_identity_ingress/complete.log
go test -race -count=1 ./apps/edge/internal/openai -run 'TestHotPath(Selector|Direct)'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
go vet ./apps/edge/internal/openai
git diff --check
```

Expected: all exit 0; mode never depends on prose; direct has no reserved artifact calls and completes exactly once. Cache is not acceptable. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
