<!-- task=m-iop-owned-single-request-agent-execution/01_preset_config plan=0 tag=API milestone-task=preset-binding -->

# Fixed Single-request Preset Config

## For the Implementing Agent

Implement this plan exactly within the listed write boundary. Run every verification command, fill all implementation-owned sections of `CODE_REVIEW-cloud-G07.md` with actual notes and stdout/stderr, keep both active files in place, and report ready for review. Finalization belongs only to the code-review skill. If blocked, record 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`.

## Background

The existing execution preset schema distinguishes generic `direct` and caller-continuation `light` shapes but has no marker for the approved fixed single-request path. SDD S02 requires an operator-owned workspace capability and immutable request/stage limits while preserving existing generic preset compatibility and live-refresh generation isolation.

## 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.md`
- `agent-ops/rules/project/domain/platform-common.md`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`
- `agent-test/local/platform-common-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`
- `packages/go/config/execution_preset_types.go`
- `packages/go/config/execution_preset_config_test.go`
- `packages/go/config/model_execution_preset_config_test.go`
- `apps/edge/internal/configrefresh/classify.go`
- `apps/edge/internal/configrefresh/execution_preset_classify_test.go`
- `configs/edge.yaml`
- `agent-contract/inner/edge-config-runtime-refresh.md`
- `agent-spec/runtime/provider-pool-config-refresh.md`

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-owned-single-request-agent-execution/SDD.md`, status approved and lock released.
- Milestone task: `preset-binding`.
- Acceptance Scenario: S02.
- Evidence Map: fixed-light decode/authorization/model echo/workspace snapshot tests and config contract sync under the `preset-binding` evidence aggregate.
- This packet supplies the decode, validation, cloning, refresh classification, and documented schema portion of S02. Runtime route authorization and public-model echo remain in `02+01_preset_binding`.

### Verification Context

- No separate verification handoff was supplied. Repository-native evidence came from the local test rules, the existing preset config tests, the config-refresh classifier tests, and the approved SDD.
- Baseline command `go test ./packages/go/config ./apps/edge/internal/configrefresh ./apps/edge/internal/openai -count=1` passed at starting HEAD `3331e5f8d20e2137d1cd1ae5600efedb42be291e`.
- Preconditions: implement after no predecessor; keep ordinary direct/light presets backward compatible; use no external runner.
- Constraint: actual Claude/provider execution is not evidence for this packet and belongs to `claude-smoke`.
- Confidence: high for local schema and refresh behavior. Absolute runtime exhaustion behavior is intentionally left to `error-cancel`; this packet only validates positive typed values and immutable snapshots.

### Test Coverage Gaps

- Existing tests cover generic direct/light normalization, mode ordering, workspace-tool validation, virtual-model one-of rules, and preset live-refresh classification.
- No existing test covers an optional single-request marker, opaque `workspace_ref`, typed per-request/per-stage limits, legacy workspace-tool exclusion, or dynamic-mode rejection. Add focused config tests.
- Existing refresh tests do not identify the new field as its own live-applied path. Extend the classifier test.

### Symbol References

- No symbol is renamed or removed.
- `ExecutionPreset` is cloned by `CloneExecutionPresetCatalog` and read by Edge routing; the new optional field must participate in deep cloning without changing existing callers.
- `appendExecutionPresetChanges` currently compares selector, modes, routes, and workspace tools only.

### Split Judgment

- `01_preset_config` owns the stable YAML/Go config contract and passes config plus refresh tests independently.
- `02+01_preset_binding` consumes the typed schema to compile an authorized immutable request binding.
- `03+02_single_ingress` consumes that binding in the coordinator.
- `04+03_stream_terminal` consumes coordinator public events for SSE.
- This first packet has no predecessor. The numbered split is topological and each child has an independent PASS oracle.

### Scope Rationale

- Do not modify Edge route resolution, Anthropic handlers, Node runtime, protobuf, workspace containment, tool execution, or SSE code here.
- Do not hardcode provider endpoints, credentials, Node ids, raw paths, or private config. `workspace_ref` remains an opaque operator capability reference.
- Do not introduce dynamic mode selection. The marker is valid only with exactly one allowed `light` route.

### Final Routing

- evaluation_mode: `first-pass`; finalizer: `finalize-task-policy.sh` in `pair` mode.
- Build closures: scope/context/verification/evidence/ownership/decision all true. Scores 2/1/2/1/1 = G07; base/final route `local-fit`; lane `local`; filename `PLAN-local-G07.md`.
- Build signals: `large_indivisible_context=false`; positive loop risks `boundary_contract`, `structured_interpretation`, `variant_product` (3); `review_rework_count=0`; `evidence_integrity_failure=false`; no capability gap.
- Review closures all true. Scores 2/1/2/1/1 = G07; route `official-review`; lane `cloud` with Codex `gpt-5.6-sol` xhigh; filename `CODE_REVIEW-cloud-G07.md`.

## Implementation Checklist

- [ ] Add and validate the optional fixed single-request preset policy, deep-clone it, and prove valid/boundary/legacy cases with focused config tests.
- [ ] Classify single-request policy changes as live-applied, add a secret-free commented config example, and synchronize the config contract and implementation spec.
- [ ] Run the targeted and package-level fresh Go tests plus `git diff --check`.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

## Implementation Plan

### [API-1] Add the typed fixed single-request policy

**Problem**

- `packages/go/config/execution_preset_types.go:13`-`23` has no field that distinguishes a fixed single-request preset from the generic caller-tool `light` shape.
- `packages/go/config/execution_preset_types.go:281`-`365` validates modes/routes, while `packages/go/config/execution_preset_types.go:421`-`507` always requires legacy caller workspace tools for every light preset.

**Solution**

Before (`packages/go/config/execution_preset_types.go:13`):

    type ExecutionPreset struct {
        ID             string
        Selector       ExecutionModelBinding
        AllowedModes   []string
        Routes         map[string]ExecutionRoute
        WorkspaceTools []ExecutionWorkspaceToolAlternative
    }

After:

    type ExecutionPreset struct {
        // existing fields remain source-compatible
        SingleRequest *ExecutionSingleRequestPolicy `mapstructure:"single_request" yaml:"single_request,omitempty"`
    }

    type ExecutionSingleRequestPolicy struct {
        WorkspaceRef string                       `mapstructure:"workspace_ref" yaml:"workspace_ref"`
        Limits       ExecutionSingleRequestLimits `mapstructure:"limits" yaml:"limits"`
    }

    type ExecutionSingleRequestLimits struct {
        WallClockMS int                                          `mapstructure:"wall_clock_ms" yaml:"wall_clock_ms"`
        Stages      map[string]ExecutionSingleRequestStageLimits `mapstructure:"stages" yaml:"stages"`
    }

    type ExecutionSingleRequestStageLimits struct {
        TimeoutMS         int `mapstructure:"timeout_ms" yaml:"timeout_ms"`
        MaxToolIterations int `mapstructure:"max_tool_iterations" yaml:"max_tool_iterations"`
        MaxOutputBytes    int `mapstructure:"max_output_bytes" yaml:"max_output_bytes"`
    }

- Deep-clone the pointer and stage-limit map.
- When `single_request` is present, normalize a non-empty `workspace_ref`, require `allowed_modes == ["light"]`, require exactly `plan`/`work`/`review` positive limit entries, require selector/review `reasoning_effort=high`, reject that option on work, and reject legacy `workspace_tools` so caller tool binding cannot compete with the internal workspace runtime.
- Keep unmarked direct/light validation byte-for-byte compatible. Do not add silent defaults.

**Modified Files and Checklist**

- [ ] `packages/go/config/execution_preset_types.go` — add types, cloning, normalization, and fail-closed validation.
- [ ] `packages/go/config/single_request_execution_preset_config_test.go` — add valid, boundary, unknown-field, dynamic-mode, missing-limit, option-leak, legacy-tool, and deep-clone cases.

**Test Strategy**

- Write `TestLoadEdgeSingleRequestExecutionPreset` with canonical fixtures `gemini-3.6-flash` for selector/review, `ornith-fast` for work, an opaque Mac workspace ref, positive limits, and no legacy caller tools.
- Write `TestLoadEdgeSingleRequestExecutionPresetRejectsInvalidShape` as a table for missing workspace, direct/hybrid/dynamic modes, missing/extra stage keys, non-positive limits, absent review high, and work high leakage.
- Write `TestCloneExecutionPresetSingleRequestIsolation` to mutate nested cloned limits and prove the source remains unchanged.
- Rerun existing `TestLoadEdgeExecutionPresetCatalog` and `TestLoadEdgeExecutionPresetRejectsInvalidShape` for compatibility.

**Verification**

- `go test ./packages/go/config -run 'Test(LoadEdgeSingleRequestExecutionPreset|CloneExecutionPresetSingleRequestIsolation|LoadEdgeExecutionPresetCatalog|LoadEdgeExecutionPresetRejectsInvalidShape)$' -count=1`
- Expected: all fixed and legacy preset cases pass with fresh execution.

### [API-2] Preserve refresh semantics and publish the schema

**Problem**

- `apps/edge/internal/configrefresh/classify.go:371`-`388` does not report the new policy independently.
- `configs/edge.yaml:331` onward documents provider models but no secret-free fixed single-request virtual model/preset example.
- The current config contract/spec describe generic frozen presets but not the fixed-light workspace/limit snapshot.

**Solution**

Before (`apps/edge/internal/configrefresh/classify.go:383`):

    appendDeepIfChanged(changes, ..., cur.Routes, next.Routes)
    appendDeepIfChanged(changes, ..., cur.WorkspaceTools, next.WorkspaceTools)

After:

    appendDeepIfChanged(changes, ..., cur.Routes, next.Routes)
    appendDeepIfChanged(changes, ..., cur.SingleRequest, next.SingleRequest)
    appendDeepIfChanged(changes, ..., cur.WorkspaceTools, next.WorkspaceTools)

- Classify `execution_presets["id"].single_request` as `applied`. Runtime request pinning remains a consumer responsibility, but the contract must state that refreshed values affect only new requests.
- Add only a commented, secret-free example showing public virtual model → preset, Gemini plan/review high, ornith-fast work without high, opaque `workspace_ref`, and explicit positive limits. Do not add non-resolving active config entries.
- Synchronize the inner contract and current implementation spec with schema, compatibility, and generation semantics.

**Modified Files and Checklist**

- [ ] `apps/edge/internal/configrefresh/classify.go` — add the exact live-applied diff path.
- [ ] `apps/edge/internal/configrefresh/execution_preset_classify_test.go` — assert the new sorted change path and previous/next values.
- [ ] `configs/edge.yaml` — add the commented public example only.
- [ ] `agent-contract/inner/edge-config-runtime-refresh.md` — define validation, refresh, and no-secret rules.
- [ ] `agent-spec/runtime/provider-pool-config-refresh.md` — synchronize current schema and tests.

**Test Strategy**

- Extend `TestClassifyExecutionPresetLiveApply` with differing policy snapshots and expect `execution_presets["preset-m-mod"].single_request` in deterministic lexical order.
- Do not add an external config smoke; `LoadEdge` temp-file tests provide the exact decoder/validator path.

**Verification**

- `go test ./apps/edge/internal/configrefresh -run 'TestClassifyExecutionPresetLiveApply$' -count=1`
- Expected: the classifier reports the new path as applied with stable ordering.

## Modified Files Summary

| File | Item |
|------|------|
| `packages/go/config/execution_preset_types.go` | API-1 |
| `packages/go/config/single_request_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 |
| `configs/edge.yaml` | API-2 |
| `agent-contract/inner/edge-config-runtime-refresh.md` | API-2 |
| `agent-spec/runtime/provider-pool-config-refresh.md` | API-2 |
| `agent-task/m-iop-owned-single-request-agent-execution/01_preset_config/CODE_REVIEW-cloud-G07.md` | API-1, API-2 |

## Final Verification

Run with the Go test cache disabled:

1. `go test ./packages/go/config -run 'Test(LoadEdgeSingleRequestExecutionPreset|CloneExecutionPresetSingleRequestIsolation|LoadEdgeExecutionPresetCatalog|LoadEdgeExecutionPresetRejectsInvalidShape)$' -count=1`
2. `go test ./apps/edge/internal/configrefresh -run 'TestClassifyExecutionPresetLiveApply$' -count=1`
3. `go test ./packages/go/config ./apps/edge/internal/configrefresh -count=1`
4. `go test ./packages/go/... ./apps/edge/... -count=1`
5. `git diff --check`

Expected: all commands exit 0; generic presets remain compatible; invalid fixed shapes fail closed; refresh identifies the single-request policy as live-applied. Cached output is not acceptable because every Go command uses `-count=1`.

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