<!-- task=m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding plan=5 tag=REVIEW_REVIEW_REVIEW_REVIEW_API milestone-task=artifact-pair -->

# Fix Root-Workspace Containment Guard

## For the Implementing Agent

Implement every checklist item, run every verification command, and fill the implementation-owned sections of `CODE_REVIEW-cloud-G03.md` with actual notes and verbatim output. Keep the active PLAN and CODE_REVIEW files in place and report ready for review; finalization is code-review-skill-only. 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`.

## Background

The native decoder, command-content, fresh-parent, and symlink-escape repairs pass their full verification. The generated shell guard still rejects valid existing and non-parent-capable targets when the API-admitted absolute workspace is `/`, because canonical target strings use one leading slash while the prefix pattern expects two. This follow-up fixes that root-aware containment comparison without changing the workspace binding contract or integrating the compiler into the later artifact-pair coordinator.

## Archive Evidence Snapshot

- Prior plan: `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/plan_cloud_G07_4.log`.
- Prior review: `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/code_review_cloud_G07_4.log`.
- Verdict: FAIL with 1 Required, 0 Suggested, and 0 Nit findings; `review_rework_count=4`, `evidence_integrity_failure=false`.
- Required scope: make containment comparison correct when the canonical workspace root is `/`, and add permanent existing-target plus non-parent-capable root-workspace regressions while retaining fresh-parent and symlink-escape coverage.
- Affected files: `apps/edge/internal/openai/workspace_tool_codec.go` and `apps/edge/internal/openai/workspace_tool_binding_test.go`.
- Fresh evidence: dependency, focused, SDD-expanded race, Edge-wide, vet, formatting, and diff checks pass on unchanged owned sources; the exact generated-guard probe with `IOP_WORKSPACE_CWD=/` and existing relative target `tmp` prints `iop: path escapes workspace root` and exits 1.
- Roadmap carryover: Milestone task `artifact-pair` and approved SDD scenario S06 remain unsatisfied for canonical containment across every API-admitted absolute workspace.

## Dependencies and Execution Order

- Predecessor 02 is satisfied by `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/02+01_preset_generation/complete.log`.
- Predecessor 04 is satisfied by `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/04+02,03_preset_model_authorization/complete.log`.
- Predecessor 06 is satisfied by `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/06+04,05_request_identity_ingress/complete.log`.

## Analysis

### Files Read

- `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/PLAN-cloud-G07.md`
- `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/CODE_REVIEW-cloud-G07.md`
- `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/code_review_cloud_G07_3.log`
- `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-spec/input/openai-compatible-surface.md`
- `agent-contract/outer/openai-compatible-api.md`
- `agent-contract/outer/anthropic-compatible-api.md`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`
- `apps/edge/internal/openai/workspace_tool_binding.go`
- `apps/edge/internal/openai/workspace_tool_codec.go`
- `apps/edge/internal/openai/workspace_tool_binding_test.go`
- `apps/edge/internal/openai/route_resolution.go`
- `apps/edge/internal/openai/anthropic_types.go`
- `apps/edge/internal/openai/hot_path_selector.go`
- `packages/go/config/execution_preset_types.go`

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`; status approved and implementation lock released.
- Milestone task id: `artifact-pair`.
- Target acceptance scenario: S06.
- S06 requires canonical-to-actual mapping, parent-capable write or separate prepare behavior, exact receipts, and workspace-relative no-escape containment before local-stage admission.
- The Evidence Map therefore requires the permanent root-workspace variants to remain in the same compiler/codec regression packet and requires focused, race, full Edge, static, formatting, and diff evidence.

### Verification Context

- No external handoff was supplied. Repository-native evidence came from the active pair, the exact prior review log, the approved SDD, the API contracts, the guard source/tests, and `agent-test/local/edge-smoke.md`.
- Current host: `/config/workspace/iop-s0`, Go `go1.26.2 linux/arm64`; deterministic package verification requires no credential, provider, remote runner, or caller workspace command execution.
- Passing evidence: exact predecessor probes, focused workspace tests, SDD-expanded race, executable-`TMPDIR` all-Edge, vet, formatting, and diff checks exit zero on unchanged owned sources.
- Failing evidence: the exact generated guard rejects existing relative target `tmp` under canonical workspace `/` with `iop: path escapes workspace root` and status 1. `validateWorkspaceForRoute` admits `/` because it requires only a non-empty absolute path.
- Constraints: retain symlink escape rejection and fresh nested parent admission; tests execute only the generated guard against hermetic fixtures and never invoke a caller workspace command. Fresh `-count=1` Go evidence is required.
- External verification is not required because production coordinator integration and actual agent tool execution remain later subtasks.
- Confidence: high; the failing branch and expected root containment behavior are deterministic.

### Test Coverage Gaps

- Existing non-root fresh-parent, missing-immediate-parent, final-symlink, and ancestor-symlink cases pass.
- No permanent case exercises an existing target with canonical workspace `/`.
- No permanent case exercises a non-parent-capable target with an existing immediate parent under canonical workspace `/`.

### Symbol References

No symbol is renamed or removed. `synthesizeContainmentGuard` remains private to the codec and workspace binding tests.

### Split Judgment

This is one compact containment invariant: root-aware path joining/prefix comparison and its two regression variants must change together. The dependency indices 02, 04, and 06 are satisfied by the exact archived `complete.log` files listed above.

### Scope Rationale

Exclude compiler normalization, command payload mapping, receipt matching, endpoint coordinator integration, actual caller tool execution, contracts/config schema changes, sibling Hot Path handlers, and roadmap edits. Those areas either already pass or belong to later dependent subtasks; this repair changes only guard synthesis, its hermetic tests, and implementation evidence.

### Final Routing

- `evaluation_mode=isolated-reassessment`; finalizer `finalize-task-policy.sh` in pair mode.
- Build closures for scope, context, verification, evidence, ownership, and decision are true. Scores `(1,0,1,0,1)` produce G03 with base `local-fit`; `review_rework_count=4` and `evidence_integrity_failure=false` select `recovery-boundary`, yielding `PLAN-cloud-G03.md`.
- Review closures are true. Scores `(1,0,1,0,1)` produce official cloud G03 `CODE_REVIEW-cloud-G03.md` with adapter `codex`, model `gpt-5.6-sol`, and reasoning effort `xhigh`.
- `large_indivisible_context=false`; positive loop-risk signatures are `boundary_contract`, `structured_interpretation`, and `variant_product` (3); risk boundary is not matched and recovery boundary is matched.
- Capability gap: none. The local Go and shell toolchain can implement and verify the repair without external authority.

## Implementation Checklist

- [ ] Make containment guard path joining and prefix comparison correct for canonical workspace `/`, add existing-target and non-parent-capable root-workspace regressions, and obtain clean dependency, focused, SDD-expanded race, all-Edge, vet, formatting, and diff evidence.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REVIEW_REVIEW_API-1] Make Root-Workspace Containment Correct

#### Problem

`apps/edge/internal/openai/workspace_tool_codec.go:339` compares `"$IOP_WS_TARGET/"` with `"$IOP_WS_ROOT"/*`. When `IOP_WS_ROOT=/`, canonical existing targets and resolved parents such as `/tmp` have one leading slash while the pattern is built with a double-slash prefix, so valid contained paths are rejected.

#### Solution

Normalize the root-aware candidate join and containment comparison so `/` admits its descendants while every non-root workspace retains an exact root-plus-slash boundary. Keep canonical resolution of existing targets, nearest-existing-ancestor behavior for parent-capable operations, immediate-parent requirements for other operations, and symlink escape rejection.

Before (`workspace_tool_codec.go:339`):

```go
b.WriteString(`case "$IOP_WS_TARGET/" in "$IOP_WS_ROOT"/*) : ;; *) echo 'iop: path escapes workspace root' >&2; exit 1 ;; esac; }`)
```

After:

```go
// Emit a root-aware containment comparison: canonical `/` accepts `/x`,
// while non-root workspaces accept only the exact root boundary and descendants.
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/workspace_tool_codec.go` — root-aware guard join/comparison without weakening non-root containment or symlink fencing.
- [ ] `apps/edge/internal/openai/workspace_tool_binding_test.go` — hermetic root-workspace existing-target and non-parent-capable regressions, retaining fresh-parent and symlink-escape cases.
- [ ] `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/CODE_REVIEW-cloud-G03.md` — actual implementation decisions and verbatim final command output only.

#### Test Strategy

Extend `TestWorkspaceContainmentGuard`. Evaluate only the generated guard: an existing relative target under canonical workspace `/` must pass; a non-parent-capable missing target whose immediate parent exists under `/` must pass; the existing non-root fresh-parent and symlink-escape cases must remain unchanged. Do not invoke the mapped caller workspace command.

#### Verification

Run `go test -count=1 ./apps/edge/internal/openai -run 'TestWorkspace(Tool|Command|Binding|Operation|Containment)'`; expect every compiler, codec, receipt, root/non-root containment, and symlink case to pass.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/openai/workspace_tool_codec.go` | REVIEW_REVIEW_REVIEW_REVIEW_API-1 |
| `apps/edge/internal/openai/workspace_tool_binding_test.go` | REVIEW_REVIEW_REVIEW_REVIEW_API-1 |
| `agent-task/m-iop-hot-path-one-shot-execution/08+02,04,06_workspace_binding/CODE_REVIEW-cloud-G03.md` | REVIEW_REVIEW_REVIEW_REVIEW_API-1 |

## Final Verification

```bash
test -f agent-task/m-iop-hot-path-one-shot-execution/02+01_preset_generation/complete.log || test -f agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/02+01_preset_generation/complete.log
test -f agent-task/m-iop-hot-path-one-shot-execution/04+02,03_preset_model_authorization/complete.log || test -f agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/04+02,03_preset_model_authorization/complete.log
test -f agent-task/m-iop-hot-path-one-shot-execution/06+04,05_request_identity_ingress/complete.log || test -f agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/06+04,05_request_identity_ingress/complete.log
go test -count=1 ./apps/edge/internal/openai -run 'TestWorkspace(Tool|Command|Binding|Operation|Containment)'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
review_tmp_dir=$(mktemp -d /config/.tmp-iop-workspace-binding.XXXXXX)
TMPDIR="$review_tmp_dir" go test -count=1 ./apps/edge/...
review_status=$?
rmdir "$review_tmp_dir"
test "$review_status" -eq 0
go vet ./apps/edge/...
gofmt -d apps/edge/internal/openai/workspace_tool_codec.go apps/edge/internal/openai/workspace_tool_binding_test.go
git diff --check
```

Expected: every command exits 0; canonical workspace `/` admits valid existing and non-parent-capable descendants; non-root fresh parents remain admitted only for parent-capable operations; existing final/ancestor symlink escapes still fail; no test executes a caller workspace command.

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