<!-- task=m-iop-hot-path-one-shot-execution/01_preset_schema plan=3 tag=REVIEW_API milestone-task=preset-schema,hot-preset -->

# Close Remaining Execution Preset Validation Gaps

## For the Implementing Agent

Implement this follow-up, run every verification command, and fill every implementation-owned section of `CODE_REVIEW-cloud-G06.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 control-plane stop files, classify the next state, archive logs, or write `complete.log`; finalization belongs to the code-review skill.

## Background

The corrected execution preset shape and the original multi-mode/option regressions now pass, but two remaining validator branches still accept configs that cannot satisfy the approved canonical-model and workspace-binding contract. This follow-up closes those fail-open paths without expanding into preset generations, model-to-preset mapping, authorization, or runtime workspace binding compilation.

## Archive Evidence Snapshot

- The current pair will be archived as `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/plan_cloud_G06_2.log` and `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/code_review_cloud_G06_2.log`.
- Verdict: FAIL. Required 2, Suggested 0, Nit 0.
- Required: reject canonical selector/stage references when `models[]` is empty; reject `light` presets without complete workspace alternatives, normalize operation keys, and validate matcher/mapping/result descriptor payloads.
- Reviewer evidence: focused, full config, race, config vet, package-wide vet, and `git diff --check` passed. A temporary focused reproducer failed because both a missing-model selector with no model catalog and a `light` route with zero workspace alternatives loaded successfully. Package-wide tests remain non-closure evidence because unrelated `agentprovider/catalog` fake-CLI tests fail on this host's PATH/executable-temp restrictions.
- Roadmap carryover: `milestone-task=preset-schema,hot-preset`; approved SDD S02/S04 remain the acceptance boundary. Immutable generation publication, model-to-preset one-of, authorization, request coordination, and workspace binding compilation remain in later children.

## Analysis

### Files Read

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/project/domain/platform-common/rules.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-test/local/rules.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-roadmap/current.md`
- `agent-roadmap/phase/knowledge-tool-optimization-extension/PHASE.md`
- `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`
- `agent-contract/index.md`
- `agent-contract/inner/edge-config-runtime-refresh.md`
- `agent-spec/index.md`
- `agent-spec/runtime/provider-pool-config-refresh.md`
- `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/PLAN-cloud-G06.md`
- `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/CODE_REVIEW-cloud-G06.md`
- `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/code_review_cloud_G03_1.log`
- `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/code_review_cloud_G07_0.log`
- `go.mod`
- `packages/go/config/config.go`
- `packages/go/config/edge_types.go`
- `packages/go/config/execution_preset_types.go`
- `packages/go/config/load.go`
- `packages/go/config/execution_preset_config_test.go`

### SDD Criteria

The selected SDD at `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md` is approved and unlocked. The first-line scope remains `milestone-task=preset-schema,hot-preset`. S02 requires preset decode/normalization against canonical model resources for later generation isolation; S04 requires only registered `direct`/`light` startup shapes and fail-closed rejection of unusable bindings. Evidence Map rows S02/S04 require the config fixture and handler-registry evidence, so the implementation checklist closes every currently observed canonical-reference and workspace-descriptor fail-open variant while preserving the existing shape/handler tests.

### Verification Context

No external verification handoff was supplied. Repository-native evidence came from the platform-common/testing rules, local platform-common profile, approved SDD, current config source/tests, active review evidence, and fresh reviewer commands. Go resolves to `/config/.local/bin/go` (`go1.26.2 linux/arm64`, GOROOT `/config/opt/go`). The focused preset tests, full config package, config race test, config vet, package-wide vet, and `git diff --check` exit 0. The package-wide test command reaches unrelated `packages/go/agentprovider/catalog` failures caused by isolated PATH lookup and non-executable temporary fake CLI files on this host, so it is recorded as a profile limitation rather than this packet's success oracle. No external provider, credential, port, or runner is required. Confidence: high.

### Test Coverage Gaps

- Selector/stage canonical references with an empty `models[]` catalog: missing and currently fail-open.
- `light` with zero workspace alternatives: missing and currently fail-open.
- Required workspace operations with omitted `schema_matcher`, `argument_map`, or `result_matcher`: missing; current valid fixtures omit them.
- Whitespace-normalized operation keys and normalized duplicate rejection: missing; current code validates a trimmed temporary name but retains the raw map key.
- Approved list shape, direct/light route correspondence, required-stage option bounds, unsupported modes, missing read/write/delete/prepare, and provider-only compatibility: covered and must remain passing.

### Symbol References

None. This follow-up changes validator behavior and tests without renaming or removing a symbol.

### Split Judgment

Keep one compact follow-up. Canonical model membership and complete workspace descriptor admission are the remaining halves of one fail-closed preset-load invariant, and the same focused config test is the deterministic PASS boundary.

### Scope Rationale

Modify only `execution_preset_types.go` and its config regression test. Do not change strict subtree decoding, the top-level config shape, runtime cloning/refresh, `models[].execution_preset`, principal authorization, selector execution, request state, workspace binding compilation, protocol streaming, or `configs/edge.yaml`; those remain assigned to later children.

### Final Routing

`evaluation_mode=isolated-reassessment`; `finalizer=finalize-task-policy.sh` (`pair`). Build and review closures are all true, with no capability gap. Build scores `(scope=1,state=0,blast=2,evidence=2,verification=0)` produce G05; review scores `(1,0,2,2,1)` produce G06. `large_indivisible_context=false`; positive risks are `boundary_contract`, `structured_interpretation`, and `variant_product` (3). Recovery signals are `review_rework_count=2` and `evidence_integrity_failure=true`, so build route basis is `recovery-boundary`, lane cloud, filename `PLAN-cloud-G05.md`. Official review is cloud G06 in `CODE_REVIEW-cloud-G06.md`.

## Implementation Checklist

- [ ] Reject every selector/stage model absent from the canonical model catalog and require complete, normalized workspace binding alternatives for every `light` preset.
- [ ] Add regression coverage for empty-catalog references, zero `light` alternatives, incomplete operation descriptors, and normalized operation keys while preserving all existing preset/provider compatibility cases.
- [ ] Run focused, fresh, race, vet, and diff verification exactly as written.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_API-1] Close canonical-reference and workspace-binding fail-open paths

#### Problem

`packages/go/config/execution_preset_types.go:117` and line 214 skip canonical membership whenever the supplied model-id map is empty, even though `LoadEdge` always supplies the complete `seenModelIDs` map. `packages/go/config/execution_preset_types.go:239` returns success for zero workspace alternatives and validates each declared operation using only a non-empty tool name; lines 265-277 trim an operation key only for comparison and retain the raw key. These paths violate the active plan's canonical-resolution and complete declarative-binding requirements.

#### Solution

Apply catalog membership unconditionally for every non-empty selector/stage model. Before iterating workspace alternatives, require at least one when `light` is allowed. Rebuild every operation map under normalized keys, reject collisions after normalization, and validate the non-empty schema matcher, canonical argument locations, and result success/error matcher required by the SDD descriptor contract.

```go
// Before: execution_preset_types.go:117
if canonicalModelIDs != nil && len(canonicalModelIDs) > 0 {
	if _, ok := canonicalModelIDs[p.Selector.Model]; !ok {
		return fmt.Errorf("... not found in models catalog")
	}
}

// After
if _, ok := canonicalModelIDs[p.Selector.Model]; !ok {
	return fmt.Errorf("... not found in models catalog")
}
```

```go
// Before: execution_preset_types.go:239
func validateWorkspaceTools(..., tools []ExecutionWorkspaceToolAlternative, allowedModes map[string]struct{}) error {
	for j := range tools {
		// A tool name alone is currently sufficient.
	}
}

// After
func validateWorkspaceTools(..., tools []ExecutionWorkspaceToolAlternative, allowedModes map[string]struct{}) error {
	if _, light := allowedModes[ModeLight]; light && len(tools) == 0 {
		return fmt.Errorf("... mode %q requires at least one workspace_tools alternative", ModeLight)
	}
	// Normalize keys into a new map, reject normalized duplicates, and require
	// schema_matcher, argument_map, and result_matcher for every operation.
}
```

#### Modified Files and Checklist

- [ ] `packages/go/config/execution_preset_types.go` — remove empty-catalog bypasses and enforce complete normalized `light` workspace alternatives.
- [ ] `packages/go/config/execution_preset_config_test.go` — add the focused fail-open and normalization regression matrix; update valid fixtures with complete descriptor fields.

#### Test Strategy

Extend `TestLoadEdgeExecutionPresetRejectsInvalidShape` with selector and stage references against an empty model catalog, a `light` route with no `workspace_tools`, each omitted required descriptor map, a whitespace-normalized operation key, and a normalized duplicate. Update `TestLoadEdgeExecutionPresetCatalog` fixtures to carry the approved matcher/mapping/result data and assert retained normalized keys. Preserve the existing multi-mode, option-overflow, unsupported-mode, missing-operation, strict-decode, and provider-only cases.

#### Verification

Run `go test -count=1 ./packages/go/config -run 'TestLoadEdgeExecutionPreset(Catalog|RejectsInvalidShape)$'`; expect every valid SDD-shaped fixture to load and every fail-open regression to reject deterministically.

## Modified Files Summary

| File | Items |
|------|-------|
| `packages/go/config/execution_preset_types.go` | REVIEW_API-1 |
| `packages/go/config/execution_preset_config_test.go` | REVIEW_API-1 |
| `agent-task/m-iop-hot-path-one-shot-execution/01_preset_schema/CODE_REVIEW-cloud-G06.md` | REVIEW_API-1 |

## Final Verification

Cached test output is not acceptable.

```bash
go test -count=1 ./packages/go/config -run 'TestLoadEdgeExecutionPreset(Catalog|RejectsInvalidShape)$'
go test -count=1 ./packages/go/config
go test -race -count=1 ./packages/go/config
go vet ./packages/go/config
go vet ./packages/go/...
git diff --check
```

Expected: every command exits 0; missing canonical models, incomplete or absent `light` workspace alternatives, incomplete descriptors, and normalized duplicate operation keys fail closed, while approved direct/light fixtures and provider-only configs remain compatible.

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