<!-- task=m-iop-hot-path-one-shot-execution/02+01_preset_model plan=0 tag=API milestone-task=preset-model -->

# Virtual Preset Model Admission and Authorization

## For the Implementing Agent

Implement this plan only after predecessor 01 has `complete.log`, run every verification command, and fill every implementation-owned section of `CODE_REVIEW-cloud-G07.md` with actual notes/output. Keep active files for official review. If blocked, record the exact blocker, attempts, and resume condition only; do not ask the user, create stop files, classify state, archive logs, or write `complete.log`.

## Background

A public model currently always means a provider pool group. This packet makes a model point to exactly one of a provider mapping or an execution preset, while preserving the public model identity and requiring every preset stage to resolve uniquely for the authenticated principal.

## Dependencies and Execution Order

- Runtime predecessor: `01_preset_catalog`. Start only after `agent-task/m-iop-hot-path-one-shot-execution/01_preset_catalog/complete.log` exists. It was missing at plan creation because predecessor implementation had not started.

## Analysis

### Files Read

- `agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/iop-hot-path-one-shot-execution.md`
- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`
- `packages/go/config/provider_types.go`
- `packages/go/config/load.go`
- `packages/go/config/provider_catalog_validation_config_test.go`
- `apps/edge/internal/openai/server.go`
- `apps/edge/internal/openai/route_resolution.go`
- `apps/edge/internal/openai/principal_routes.go`
- `apps/edge/internal/openai/routes.go`
- `apps/edge/internal/openai/openai_auth_routes_models_test.go`
- `apps/edge/internal/openai/principal_routes_test.go`
- `agent-contract/outer/openai-compatible-api.md`
- `agent-contract/outer/anthropic-compatible-api.md`

### SDD Criteria

The approved/unlocked SDD targets `preset-model`, scenario S01, Evidence Map S01. Tests must cover provider vs preset one-of, managed zero/one/multiple matches across selector and all stages, list/admission, response model echo, and no synthetic credential projection.

### Verification Context

No handoff was supplied. Local Go 1.26.2 and repository test rules are available; fresh and race runs are required. No external credential is needed because projection fixtures provide deterministic managed-route evidence. Confidence: high.

### Test Coverage Gaps

Existing tests cover provider catalog validation and one managed route, not a virtual model whose selector/local/review references must all match uniquely. Add explicit one-of/load tests and principal list/admission tables. Existing public model echo tests remain regression coverage.

### Symbol References

No rename/removal. `resolveManagedCatalogBinding` is called only by `resolveProjectedRoute` (`principal_routes.go:106,136`) and will gain a preset-aware sibling rather than change provider semantics.

### Split Judgment

Child 02 depends only on 01. Its stable contract is that only fully authorized virtual preset ids enter model listing/dispatch and provider-backed ids retain existing behavior. It does not execute a preset stage; children 03-07 consume the resolved immutable binding.

### Scope Rationale

Exclude mode selection, coordinator state, workspace tools, and downstream execution. Do not add projection messages, credential slots, raw provider ids, or principal route ids to static preset config.

### Final Routing

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

## Implementation Checklist

- [ ] Enforce the provider-map versus execution-preset one-of and reference validation at config load.
- [ ] List and admit a virtual model only when selector and every allowed stage route resolve uniquely for the principal, preserving public identity.
- [ ] Run the focused, race, vet, and diff verification commands exactly as written.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Add model-to-preset one-of validation

#### Problem

`ModelCatalogEntry` has only `Providers` and rejects an empty map (`packages/go/config/provider_types.go:167-198,229-283`). `LoadEdge` validates only provider references (`packages/go/config/load.go:153-176`).

#### Solution

Add `ExecutionPreset string` and enforce exactly one of a non-empty provider map or a non-empty preset id. Resolve the preset id against the predecessor catalog after all ids are normalized; provider-only token/budget checks must not run against a virtual entry.

```go
// Before: provider_types.go:192-198
Providers map[string]string `mapstructure:"providers" yaml:"providers"`
TokenCounter *TokenCounterConf

// After
Providers       map[string]string `mapstructure:"providers" yaml:"providers,omitempty"`
ExecutionPreset string            `mapstructure:"execution_preset" yaml:"execution_preset,omitempty"`
TokenCounter    *TokenCounterConf
```

#### Modified Files and Checklist

- [ ] `packages/go/config/provider_types.go` — add the field and one-of validation.
- [ ] `packages/go/config/load.go` — resolve preset references and skip provider-only checks for virtual entries.
- [ ] `packages/go/config/model_execution_preset_config_test.go` — cover one-of, dangling ids, duplicates, and compatibility.

#### Test Strategy

Write `TestLoadEdgeModelExecutionPresetOneOf` as a table with provider-only, preset-only, neither, both, and dangling cases. Assert stable error paths and unchanged provider fixtures.

#### Verification

Run `go test -count=1 ./packages/go/config`; expect PASS.

### [API-2] Resolve virtual model authorization and public identity

#### Problem

Managed listing blindly publishes projected route ids (`principal_routes.go:35-55`), while admission resolves one projected route to one provider model group (`principal_routes.go:76-167`). It cannot prove unique authorization for the selector plus every preset stage or echo the virtual id independently from internal targets.

#### Solution

Represent a preset dispatch with the external model id, preset id/generation, and immutable per-role canonical references. In managed mode match each reference against the authenticated projection and require exactly one active route; in legacy mode require an existing canonical model entry. Filter virtual ids from model listing when any reference is zero/ambiguous and re-resolve the chosen stage route/credential at dispatch time.

```go
// Before: route_resolution.go:53-82
type routeDispatch struct {
    ProviderPool bool
    ModelGroupKey string
}

// After
type routeDispatch struct {
    ProviderPool bool
    Preset       *resolvedExecutionPreset
    ExternalModel string
}
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/route_resolution.go` — distinguish provider and preset dispatch.
- [ ] `apps/edge/internal/openai/principal_routes.go` — authorize all canonical references and filter listings.
- [ ] `apps/edge/internal/openai/routes.go` — preserve external model ids on both model list protocols.
- [ ] `apps/edge/internal/openai/openai_auth_routes_models_test.go` — cover legacy listing/admission/echo.
- [ ] `apps/edge/internal/openai/principal_routes_test.go` — cover zero/one/ambiguous managed stage matches and revoke/revision recheck.

#### Test Strategy

Add `TestVirtualPresetModelAuthorizationMatrix` and extend managed model-list tests. Fixtures must include selector/local/review matches, alias collisions, missing route, cross-principal route, and internal target mismatch. Assert public response `model` remains the requested virtual id.

#### Verification

Run `go test -count=1 ./apps/edge/internal/openai -run 'Test(VirtualPreset|Managed.*Model|ModelCatalog)'`; expect PASS.

## Modified Files Summary

| File | Items |
|------|-------|
| `packages/go/config/provider_types.go` | API-1 |
| `packages/go/config/load.go` | API-1 |
| `packages/go/config/model_execution_preset_config_test.go` | API-1 |
| `apps/edge/internal/openai/route_resolution.go` | API-2 |
| `apps/edge/internal/openai/principal_routes.go` | API-2 |
| `apps/edge/internal/openai/routes.go` | API-2 |
| `apps/edge/internal/openai/openai_auth_routes_models_test.go` | API-2 |
| `apps/edge/internal/openai/principal_routes_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/02+01_preset_model/CODE_REVIEW-cloud-G07.md` | API-1, API-2 |

## Final Verification

```bash
test -f agent-task/m-iop-hot-path-one-shot-execution/01_preset_catalog/complete.log
go test -count=1 ./packages/go/config ./apps/edge/internal/openai
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
go vet ./packages/go/config ./apps/edge/internal/openai
git diff --check
```

Expected: predecessor check and all commands exit 0; virtual ids are exposed only for unique all-stage authorization and provider-only behavior is unchanged. Cache is not acceptable. External agent smoke remains later `hot-smoke`. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
