<!-- task=m-iop-hot-path-one-shot-execution/05+01,02,03_artifact_pair plan=0 tag=API milestone-task=artifact-pair -->

# Declarative Workspace Binding and Plan/Review Pair

## For the Implementing Agent

Start only after predecessors 01/02/03 complete. Implement, run all commands, and fill `CODE_REVIEW-cloud-G10.md` with actual evidence. Leave active files for official review. Record blockers only in implementation evidence; do not ask the user, create control files, classify state, archive, or write `complete.log`.

## Background

IOP must request workspace operations through whatever compatible tool schema the caller already supplied. It must deterministically map canonical prepare/read/write/delete calls and validate exactly the Plan/Review pair without executing tools or trusting opaque results.

## Dependencies and Execution Order

- Required predecessors: `01_preset_catalog`, `02+01_preset_model`, `03+01,02_request_identity`; their active `complete.log` files were missing at plan creation.

## Analysis

### Files Read

- `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`
- `apps/edge/internal/openai/chat_types.go`
- `apps/edge/internal/openai/chat_decode.go`
- `apps/edge/internal/openai/anthropic_types.go`
- `apps/edge/internal/openai/tool_schema.go`
- `apps/edge/internal/openai/anthropic_surface_test.go`
- `apps/edge/internal/openai/stream_gate_ingress_test.go`
- `agent-contract/outer/openai-compatible-api.md`
- `agent-contract/outer/anthropic-compatible-api.md`

### SDD Criteria

Approved/unlocked SDD; task/scenario/Evidence row S06. Required matrix: canonical↔actual mapping, parent-capable write or prepare, exact receipt vs opaque result, reversed pair results, missing/extra/duplicate tools, and traversal/containment rejection before local dispatch.

### Verification Context

No handoff. Unit/httptest fixtures model Chat and Anthropic schemas; no workspace or tool is actually executed. Fresh/race tests required. Confidence: high.

### Test Coverage Gaps

Existing tool validation checks provider output schemas, not request-local workspace role selection, argument synthesis, no-escape paths, or bidirectional public/provider id mapping. Add isolated binding and pair-frontier integration suites.

### Symbol References

No rename/removal. New binding code consumes decoded `chatCompletionRequest.Tools` and `anthropicMessageRequest.Tools` but does not change their wire structs.

### Split Judgment

Child 05 is parallel with child 04 after 01/02/03. Its stable contract is a pinned binding plus validated prepare/pair continuation result, without running local/review. Child 06 consumes both the direct selector integration and this artifact contract.

### Scope Rationale

Exclude filesystem execution, agent adapters, local/review model dispatch, cleanup, generic shell evaluation, manifests, revisions, sibling files, and server-side artifact fallback. Command mapping must be fixed-data synthesis, not arbitrary model-generated shell.

### Final Routing

`evaluation_mode=first-pass`; `finalizer=finalize-task-policy.sh` pair. Build closures true, scores `(2,2,2,2,2)` => G10/grade-boundary cloud; `large_indivisible_context=false`, risks `temporal_state,concurrent_consistency,boundary_contract,structured_interpretation,variant_product` (5), rework 0, evidence-integrity false, no gap; `PLAN-cloud-G10.md`. Review scores `(2,2,2,2,2)` => official cloud G10, `CODE_REVIEW-cloud-G10.md`, Codex `gpt-5.6-sol` xhigh.

## Implementation Checklist

- [ ] Select and pin a declarative workspace tool binding from actual Chat/Anthropic schemas with safe deterministic argument/result transforms.
- [ ] Enforce prepare and exact Plan/Review expected sets, paths, public/provider ids, and one-frontier result success before local eligibility.
- [ ] Run focused mapping/frontier, 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] Compile request-local workspace operation bindings

#### Problem

Chat tools are generic `[]any` (`chat_types.go:17-24`) and Anthropic tools only expose name/schema (`anthropic_types.go:31-47`). No code matches configured role alternatives or guarantees workspace-relative containment and deterministic receipts.

#### Solution

Compile ordered alternatives against actual tool JSON Schema into an immutable binding. Provide canonical prepare/read/write/delete call encoders and result matchers. Structured bindings encode named fields. Command bindings synthesize only fixed path/content commands with shell-safe payload encoding and a caller-executed canonical-cwd/target containment guard; Edge does not inspect or resolve the workspace itself and accepts success only from the guard's exact receipt.

```go
// Before: tools pass through as opaque provider input.

// After
binding, err := selectWorkspaceBinding(preset.WorkspaceTools, endpointTools)
actualCall, publicID, err := binding.Encode(canonicalArtifactCall)
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/workspace_tool_binding.go` — matcher/compiler/immutable selected binding.
- [ ] `apps/edge/internal/openai/workspace_tool_codec.go` — safe argument encoding, id mapping, lexical path checks, caller-executed containment guard synthesis, and exact result matching.
- [ ] `apps/edge/internal/openai/workspace_tool_binding_test.go` — structured/command schemas, alternatives, fingerprint, unsafe path/command cases.

#### Test Strategy

Write `TestWorkspaceToolBindingMatrix` and `TestWorkspaceCommandBindingSafetyGuard`. Cover parent-capable write, separate prepare, missing roles, reordered properties, schema replacement, exact/opaque receipts, quoting/newline content, `..`, absolute path, sibling path, deterministic guard/receipt synthesis, and a failed containment receipt. Do not make the Edge test inspect a real caller workspace or execute the generated tool command.

#### Verification

Run `go test -count=1 ./apps/edge/internal/openai -run 'TestWorkspace(Tool|Command)'`; expect PASS.

### [API-2] Validate directory prepare and exact pair continuation frontier

#### Problem

The SDD permits either one prepare call or exactly two Plan/Review writes, then requires both results exactly once in the immediately following frontier (`SDD.md:121-127`). Existing tool validation does not own a cross-call expected set.

#### Solution

Build issued paths only as `.iop/job/<request_id>/{plan.md,review.md}`. If needed, emit exactly one prepare call and resume the same selector stage; then accept exactly the two mapped writes and store their expected public/internal ids. Validate the next frontier order-independently, rejecting missing, unknown, duplicate, opaque, failed, mixed work calls, alternate requests, traversal, and later replay.

```go
// Before: generic tool result validation has no reserved expected pair.

// After
expected := newArtifactExpectedSet(planCall, reviewCall)
if err := expected.ConsumeExactlyOnce(continuation.Results); err != nil { return admissionError(err) }
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/artifact_pair.go` — issued paths, prepare/pair expected sets, result consumption.
- [ ] `apps/edge/internal/openai/artifact_pair_test.go` — Chat/Messages mapping and reversed/missing/extra result integration.

#### Test Strategy

Write `TestArtifactPairFrontierMatrix` with both endpoints and all S06 cases. Assert local eligibility remains false until both exact successes are consumed and no actual filesystem call occurs.

#### Verification

Run `go test -race -count=1 ./apps/edge/internal/openai -run 'Test(Workspace|ArtifactPair)'`; expect PASS.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/openai/workspace_tool_binding.go` | API-1 |
| `apps/edge/internal/openai/workspace_tool_codec.go` | API-1 |
| `apps/edge/internal/openai/workspace_tool_binding_test.go` | API-1 |
| `apps/edge/internal/openai/artifact_pair.go` | API-2 |
| `apps/edge/internal/openai/artifact_pair_test.go` | API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/05+01,02,03_artifact_pair/CODE_REVIEW-cloud-G10.md` | API-1, API-2 |

## Final Verification

```bash
test -f agent-task/m-iop-hot-path-one-shot-execution/01_preset_catalog/complete.log
test -f agent-task/m-iop-hot-path-one-shot-execution/02+01_preset_model/complete.log
test -f agent-task/m-iop-hot-path-one-shot-execution/03+01,02_request_identity/complete.log
go test -race -count=1 ./apps/edge/internal/openai -run 'Test(Workspace|ArtifactPair)'
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; unsafe/malformed/opaque paths dispatch no local stage; reversed exact pair success becomes eligible once. Cache is not acceptable. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
