<!-- task=m-iop-hot-path-one-shot-execution/01_preset_catalog plan=0 tag=API milestone-task=preset-schema,hot-preset -->

# Execution Preset Catalog and Hot-Mode Registry

## For the Implementing Agent

Implement this plan, run every verification command, and fill every implementation-owned section of `CODE_REVIEW-cloud-G07.md` with actual notes and stdout/stderr. Keep the active files in place and report ready for review. If blocked, record only the exact blocker, attempted commands/output, and resume condition in implementation-owned evidence fields; do not ask the user, call user-input tools, create stop files, classify the next state, archive logs, or write `complete.log`. Finalization belongs to the code-review skill.

## Background

The Edge config has model/provider catalogs but no execution policy that can freeze selector, allowed modes, downstream stages, and workspace bindings as one generation. This packet adds that compatible foundation and the registered `direct`/`light` handler vocabulary; no model is routed through a preset yet.

## 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/config.go`
- `packages/go/config/edge_types.go`
- `packages/go/config/provider_types.go`
- `packages/go/config/load.go`
- `packages/go/config/validate.go`
- `packages/go/config/provider_catalog_config_test.go`
- `packages/go/config/provider_catalog_validation_config_test.go`
- `apps/edge/internal/configrefresh/classify.go`
- `apps/edge/internal/configrefresh/node_runtime_classify_test.go`
- `apps/edge/internal/openai/server.go`
- `apps/edge/internal/input/manager.go`
- `apps/edge/internal/bootstrap/runtime.go`

### SDD Criteria

The approved/unlocked SDD is `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`. Header metadata covers `preset-schema,hot-preset`; target scenarios are S02 and S04, and Evidence Map rows S02/S04 require decode/normalize/refresh generation isolation plus `direct`/`light` success and `heavy`/custom startup rejection. Those requirements are represented directly in API-1/API-2 and the test matrix below.

### Verification Context

No external handoff was supplied. Repository-native evidence is the local test rule, `agent-test/local/edge-smoke.md`, `agent-test/local/platform-common-smoke.md`, Go 1.26.2 at `/config/.local/bin/go`, and a clean starting worktree. Fresh (`-count=1`) and race-enabled tests are required; no external provider, credential, port, or workspace runner is needed for S02/S04. Confidence: high.

### Test Coverage Gaps

Existing config tests cover provider/model catalogs but not preset shape, mode registry, deep cloning, or refresh isolation. Add focused config, refresh, and runtime propagation tests. Existing provider-only configurations must remain covered by the full package suite.

### Symbol References

No symbol is renamed or removed. New setters extend `input.Manager` and `openai.Server`; runtime assembly is their only production caller.

### Split Judgment

This is split child 01 with no runtime predecessor. Its stable contract is: valid preset catalogs load and live-apply as immutable snapshots while provider-only models behave unchanged. Child 02 may consume that contract only after this directory has `complete.log`; the remaining children and dependencies are encoded in their directory names. No active or archived sibling index for this task group existed when indices were assigned.

### Scope Rationale

Do not add `models[].execution_preset`, principal authorization, selector execution, request state, or protocol streaming here. Do not add `heavy`, future modes, manifests, revision trees, or defaults that activate a preset. `configs/edge.yaml` remains unchanged unless a test fixture proves an existing checked-in example must compile.

### Final Routing

`evaluation_mode=first-pass`; `finalizer=finalize-task-policy.sh` (`pair`). Build closures are all true; scores `(scope=2,state=1,blast=2,evidence=1,verification=1)` yield G07, base/final route `local-fit`, `large_indivisible_context=false`, matched risks `boundary_contract,variant_product` (2), rework 0, evidence-integrity failure false, no capability gap; canonical file `PLAN-local-G07.md`. Review closures are all true; scores `(2,1,2,1,1)` yield official cloud G07 with `CODE_REVIEW-cloud-G07.md` (`gpt-5.6-sol`, xhigh).

## Implementation Checklist

- [ ] Define and fail-closed validate the execution preset catalog and registered direct/light mode shapes.
- [ ] Propagate a deeply cloned preset generation through startup and live config refresh without changing active snapshots.
- [ ] 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] Define the preset schema and hot-mode registry

#### Problem

`EdgeConfig` exposes only `Models` and `ProtocolProfiles` (`packages/go/config/edge_types.go:50-60`), so the SDD fields at lines 87-95 cannot be decoded or validated. Unknown/unsupported mode handlers also have no startup rejection boundary.

#### Solution

Add a cohesive preset type file containing selector stage, ordered route stages/options, allowed modes, and declarative workspace binding alternatives. Validate unique ids, canonical model references, exact current route shapes (`direct` has no downstream stages; `light` is `local,review`), bounded options, and only registered mode descriptors. The config package owns pure shape descriptors, not executable handlers; the Edge runtime must use the same descriptor keys when it installs/looks up handlers so unsupported modes fail before dispatch.

```go
// Before: edge_types.go:50-60
Models []ModelCatalogEntry
ProtocolProfiles map[string]ProtocolProfileConf

// After
Models           []ModelCatalogEntry
ExecutionPresets []ExecutionPresetConf
ProtocolProfiles map[string]ProtocolProfileConf
```

#### Modified Files and Checklist

- [ ] `packages/go/config/config.go` — document the new responsibility file.
- [ ] `packages/go/config/edge_types.go` — add the top-level catalog.
- [ ] `packages/go/config/execution_preset_types.go` — define types, clone helpers, pure mode-shape descriptors, and validation without executable runtime handlers.
- [ ] `packages/go/config/load.go` — validate/normalize presets before model admission.
- [ ] `packages/go/config/execution_preset_config_test.go` — cover valid direct/light and invalid ids, stages, options, heavy/custom modes, and binding shapes.

#### Test Strategy

Write `TestLoadEdgeExecutionPresetCatalog` and `TestLoadEdgeExecutionPresetRejectsInvalidShape` with table fixtures. Assert ordered stages/options survive decode, `direct`/`light` pass, unsupported descriptor keys and malformed/dangling stage references fail deterministically, and existing provider-only fixtures still load. Assert the descriptor layer contains no executable callback or provider dependency.

#### Verification

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

### [API-2] Publish immutable preset generations at startup and refresh

#### Problem

Startup and refresh only call `SetModelCatalog` (`apps/edge/internal/input/manager.go:24-55`, `apps/edge/internal/bootstrap/runtime.go:273-296`), and refresh diffing only indexes `models` (`apps/edge/internal/configrefresh/classify.go:184,349-421`). An active tool round-trip could otherwise observe partially replaced policy.

#### Solution

Add a deep-cloned server snapshot containing a monotonically replaced preset catalog generation, wire it through `NewManager`/refresh, and classify preset changes as mutable for new requests. The setter must replace one immutable aggregate under the existing server lock; consumers retain the prior copied generation. At startup/refresh admission, runtime mode lookup must agree with the config descriptor keys and reject an unavailable handler before any provider dispatch.

```go
// Before: bootstrap/runtime.go:292-296
r.Service.SetRuntimeConfig(nextStore, candidate.Models, poolPolicy)
r.Input.SetModelCatalog(candidate.Models)

// After
r.Service.SetRuntimeConfig(nextStore, candidate.Models, poolPolicy)
r.Input.SetExecutionCatalog(candidate.Models, candidate.ExecutionPresets)
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/configrefresh/classify.go` — diff preset ids and classify live changes.
- [ ] `apps/edge/internal/configrefresh/execution_preset_classify_test.go` — verify applied paths and stable ordering.
- [ ] `apps/edge/internal/openai/server.go` — own atomic/deep-cloned execution catalog snapshots.
- [ ] `apps/edge/internal/input/manager.go` — provide one catalog replacement entry point.
- [ ] `apps/edge/internal/bootstrap/runtime.go` — wire startup and refresh replacement.
- [ ] `apps/edge/internal/bootstrap/runtime_execution_preset_test.go` — prove refresh affects new snapshots and not retained ones.

#### Test Strategy

Write `TestClassifyExecutionPresetLiveApply` and `TestRuntimeRefreshReplacesExecutionPresetGeneration`. Mutate caller-owned maps/slices after setting and assert snapshots do not change; retain a pre-refresh snapshot and assert only a post-refresh read sees the new generation.

#### Verification

Run `go test -count=1 ./apps/edge/internal/configrefresh ./apps/edge/internal/bootstrap ./apps/edge/internal/openai`; expect PASS.

## Modified Files Summary

| File | Items |
|------|-------|
| `packages/go/config/config.go` | API-1 |
| `packages/go/config/edge_types.go` | API-1 |
| `packages/go/config/execution_preset_types.go` | API-1 |
| `packages/go/config/load.go` | API-1 |
| `packages/go/config/execution_preset_config_test.go` | API-1 |
| `apps/edge/internal/configrefresh/classify.go` | API-2 |
| `apps/edge/internal/configrefresh/execution_preset_classify_test.go` | API-2 |
| `apps/edge/internal/openai/server.go` | API-2 |
| `apps/edge/internal/input/manager.go` | API-2 |
| `apps/edge/internal/bootstrap/runtime.go` | API-2 |
| `apps/edge/internal/bootstrap/runtime_execution_preset_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/01_preset_catalog/CODE_REVIEW-cloud-G07.md` | API-1, API-2 |

## Final Verification

Run from `/config/workspace/iop-s0`; cached test output is not acceptable.

```bash
go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh ./apps/edge/internal/bootstrap ./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/configrefresh ./apps/edge/internal/bootstrap ./apps/edge/internal/openai
git diff --check
```

Expected: every command exits 0; preset fixtures reject unsupported modes before runtime dispatch; retained snapshots remain immutable. External Claude/Pi smoke remains the later `hot-smoke` task, not a closure condition for S02/S04. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
