<!-- task=m-iop-hot-path-one-shot-execution/11+09,10_cleanup plan=4 tag=REVIEW_REVIEW_REVIEW_REVIEW_API milestone-task=cleanup -->

# Review Follow-up: Preserve Empty Receipt Fail-Closed Semantics

## For the Implementing Agent

Implement every checklist item, run every verification command with fresh output, and fill the implementation-owned sections in `CODE_REVIEW-cloud-G06.md`. Keep the active PLAN/review pair 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, write `complete.log`, or modify roadmap state; finalization belongs to the code-review skill.

## Background

The correlation-valid `{"written":false}` receipt now enters primary-error cleanup, but the new exactness predicate also admits an empty success-status result. Empty results are already defined as opaque by the workspace receipt contract and must not authorize a caller-executed delete frontier. This follow-up restores that boundary without regressing explicit status errors or non-empty parseable matcher failures.

## Dependencies and Execution Order

- `09+06,08_artifact_pair` is complete at `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/09+06,08_artifact_pair/complete.log`.
- `10+07,09_light_flow` is complete at `agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/10+07,09_light_flow/complete.log`.
- Both archived PASS records satisfy the dependencies encoded by `11+09,10_cleanup`; no new predecessor is introduced.

## Archive Evidence Snapshot

- Current review archive after finalization: `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/code_review_cloud_G08_3.log`.
- Earlier reviews: `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/code_review_cloud_G10_0.log`, `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/code_review_cloud_G10_1.log`, and `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/code_review_cloud_G09_2.log`.
- Current verdict: FAIL; findings: Required 1, Suggested 0, Nit 0.
- Required gap: `workspaceResultIsExact` treats the empty-body success branch of `normalizeResultEnvelope` as an exact caller operation report and authorizes cleanup.
- Reviewer reproduction: a successful Plan receipt plus an empty Review receipt issued HTTP 200 with a canonical `delete_file` frontier on both OpenAI and Anthropic; the temporary reproducer was removed.
- Trusted passing evidence: the focused primary-error races, cleanup/TTL races, common race suites, full Edge suite, vet, formatting, and diff checks all passed; they omit the empty receipt variant.
- Affected implementation area: `workspace_tool_codec.go` exactness classification plus focused classifier and public-handler tests.
- Roadmap carryover: milestone task `cleanup`, approved and unlocked SDD Acceptance Scenario/Evidence Map row S09, with the existing S06/S14 opaque-result trust boundary preserved.

## Analysis

### Files Read

- `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/PLAN-cloud-G07.md`
- `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/CODE_REVIEW-cloud-G08.md`
- `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/code_review_cloud_G09_2.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-contract/outer/openai-compatible-api.md`
- `agent-contract/outer/anthropic-compatible-api.md`
- `agent-spec/runtime/stream-evidence-gate.md`
- `agent-spec/input/openai-compatible-surface.md`
- `apps/edge/internal/openai/artifact_pair.go`
- `apps/edge/internal/openai/workspace_tool_codec.go`
- `apps/edge/internal/openai/artifact_pair_test.go`
- `apps/edge/internal/openai/workspace_tool_binding_test.go`
- `apps/edge/internal/openai/hot_path_cleanup_test.go`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`

### SDD Criteria

- SDD: `agent-roadmap/sdd/knowledge-tool-optimization-extension/iop-hot-path-one-shot-execution/SDD.md`; status `[승인됨]`; SDD lock released; no SDD user review.
- First-line milestone task: `cleanup`.
- Targeted Acceptance Scenario/Evidence Map row: S09. S09 requires artifact-bearing errors to attempt caller-executed cleanup while preserving terminal/TTL ownership boundaries.
- The S06/S14 interface and evidence rows define opaque results as fail-closed input. The checklist therefore separates explicit status errors and non-empty parseable matcher failures from empty or malformed success-status results, then verifies both public protocols and the retained `{"written":false}` cleanup path.

### Verification Context

- No neutral verification-context handoff was supplied. The active pair, approved SDD, Edge local test profile, relevant source/tests, and fresh reviewer commands are repository-native evidence.
- Environment: `/config/workspace/iop-s0`, Go 1.26.2 linux/arm64, dirty shared checkout. Deterministic tests require no external service or credential.
- Fresh reviewer evidence: the exact focused/race/full Edge commands in the current review exited 0; `go vet`, `gofmt -d`, and `git diff --check` produced no output. A temporary both-endpoint handler test failed because each empty receipt returned HTTP 200 with `delete_file`; the file was removed.
- Preconditions: the two dependency `complete.log` files exist. Constraints exclude live provider smoke, real workspace deletion, credentialed calls, and external runners.
- Gap: no retained test distinguishes empty success-status input from an explicit status error with an empty body at `workspaceResultIsExact`, and no public-handler test covers the empty pair receipt.
- Confidence: high. The failing case exercised the same scripted Plan/Review frontier used by the passing primary-error matrix on both protocols.

### Test Coverage Gaps

- Non-empty parseable matcher failure `{"written":false}`: covered by `TestHotPathCleanupPrimaryErrorPrecedence` and must continue to issue cleanup.
- Empty success-status result: not covered; freshly reproduced as an unauthorized cleanup frontier on OpenAI and Anthropic.
- Explicit status error with an empty body: not covered at the classifier boundary; it must remain an exact failure eligible for best-effort cleanup.
- Malformed non-JSON result: covered by `TestArtifactPairFailureCleanupKeepsMalformedFailClosed` and must remain no-cleanup HTTP 400.
- Wrong call identity, mutated payload correlation, lineage, owner, and principal: covered by existing artifact/coordinator tests and unchanged.

### Symbol References

- No symbol is renamed or removed.
- `workspaceResultIsExact` is defined in `workspace_tool_codec.go` and called only by `artifactFrontierStore.consume` in `artifact_pair.go`.
- `matchResultReceipt`, `matchResultCorrelation`, `normalizeResultEnvelope`, and `hasExplicitErrorSignal` remain unchanged boundaries.

### Split Judgment

Keep one plan. The exactness predicate, its classifier table, and both-endpoint frontier behavior form one compact trust invariant; splitting tests from the predicate would leave an independently unverified cleanup authorization boundary. Predecessor indices 09 and 10 are satisfied by the exact archived `complete.log` paths listed above.

### Scope Rationale

Exclude receipt matcher semantics, issue-correlation digests, lineage/owner/principal validation, cleanup transaction state, endpoint error envelopes, local/review dispatch, TTL/cancellation behavior, and live workspace/provider smoke. Only empty-body exactness classification and deterministic evidence are in scope.

### Final Routing

- `evaluation_mode=isolated-reassessment`; `finalizer=finalize-task-policy.sh`; `finalizer_mode=pair`; capability gap: none.
- Build closures are all true. Scores `(scope=1,state=1,blast=1,evidence=1,verification=1)` produce G05 with base `local-fit`; recovery signals select `recovery-boundary`, lane `cloud`, filename `PLAN-cloud-G05.md`.
- Review closures are all true. Scores `(scope=1,state=1,blast=1,evidence=2,verification=1)` produce G06 with `official-review`, lane `cloud`, adapter `codex`, model `gpt-5.6-sol`, reasoning effort `xhigh`, filename `CODE_REVIEW-cloud-G06.md`.
- `large_indivisible_context=false`; positive loop-risk signatures are `temporal_state`, `boundary_contract`, and `variant_product` (`loop_risk_count=3`).
- Recovery signals: `review_rework_count=4`, `evidence_integrity_failure=true`; recovery boundary matched and risk boundary did not match.

## Implementation Checklist

- [x] Reject empty success-status workspace results as opaque while preserving explicit status failures and non-empty parseable matcher failures as exact.
- [x] Add classifier and both-endpoint public-handler regressions for empty receipt rejection without regressing `{"written":false}` primary cleanup.
- [x] Run all focused and final verification commands with fresh output.
- [x] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REVIEW_REVIEW_API-1] Separate empty opaque receipts from exact failures

#### Problem

`workspaceResultIsExact` (`workspace_tool_codec.go:420-428`) returns true whenever `normalizeResultEnvelope` returns nil. That normalizer deliberately accepts an empty body as `{status, result:nil}` for receipt matching, so a success-status empty result becomes trusted enough to authorize best-effort deletion even though `TestWorkspaceBindingReceipts` defines it as opaque.

#### Solution

Keep `normalizeResultEnvelope` unchanged for matcher evaluation. In `workspaceResultIsExact`, recognize an explicit status error independently, reject a whitespace-only body when the status does not report failure, and only then accept a non-empty body that parses as exactly one JSON value.

Before (`workspace_tool_codec.go:420-428`):

```go
func workspaceResultIsExact(result workspaceResult) bool {
	_, err := normalizeResultEnvelope(result)
	return err == nil
}
```

After:

```go
func workspaceResultIsExact(result workspaceResult) bool {
	if hasExplicitErrorSignal(map[string]any{"status": result.status}) {
		return true
	}
	if len(bytes.TrimSpace(result.body)) == 0 {
		return false
	}
	_, err := normalizeResultEnvelope(result)
	return err == nil
}
```

#### Modified Files and Checklist

- [x] `apps/edge/internal/openai/workspace_tool_codec.go` — distinguish explicit status failure from an empty success-status body.
- [x] `apps/edge/internal/openai/workspace_tool_binding_test.go` — add `TestWorkspaceResultExactness` for empty success, empty explicit error, `{"written":false}`, malformed, and valid success bodies.

#### Test Strategy

Add a focused table because `matchResultReceipt` and exactness serve different trust decisions. The table must prove empty success is false, status `error` with no body is true, non-empty `{"written":false}` is true, malformed/trailing JSON is false, and a normal success receipt is true.

#### Verification

```bash
go test -count=1 ./apps/edge/internal/openai -run '^TestWorkspace(ResultExactness|BindingReceipts)$'
```

Expected: exit 0; classifier cases and the unchanged receipt matcher contract both pass freshly.

### [REVIEW_REVIEW_REVIEW_REVIEW_API-2] Lock the public empty-receipt boundary on both protocols

#### Problem

`TestArtifactPairFailureCleanupKeepsMalformedFailClosed` (`artifact_pair_test.go:548-577`) proves malformed non-JSON input does not issue cleanup, while `TestHotPathCleanupPrimaryErrorPrecedence` proves non-empty `{"written":false}` does. No public-handler case covers the empty-body boundary between them.

#### Solution

Extend the existing fail-closed handler test with a successful Plan receipt and empty Review receipt for OpenAI and Anthropic. Assert HTTP 400, no `delete_file` frontier, and exactly two selector calls. Retain the existing primary-error matcher-failure case as the positive control that a non-empty exact failure still issues cleanup and preserves the original error.

#### Modified Files and Checklist

- [x] `apps/edge/internal/openai/artifact_pair_test.go` — add the both-protocol empty pair receipt regression.
- [x] `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/CODE_REVIEW-cloud-G06.md` — record actual implementation notes, deviations, decisions, and raw command output.

#### Test Strategy

Extend the existing scripted public-handler fixture rather than add another helper. The regression uses no external workspace, provider, credential, or real deletion and directly observes the endpoint response plus provider-call count.

#### Verification

```bash
go test -count=1 ./apps/edge/internal/openai -run '^Test(ArtifactPairFailureCleanupKeepsMalformedFailClosed|HotPathCleanupPrimaryErrorPrecedence)$'
```

Expected: exit 0; empty and malformed results fail closed on both protocols while `{"written":false}` still enters primary cleanup.

## 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 |
| `apps/edge/internal/openai/artifact_pair_test.go` | REVIEW_REVIEW_REVIEW_REVIEW_API-2 |
| `agent-task/m-iop-hot-path-one-shot-execution/11+09,10_cleanup/CODE_REVIEW-cloud-G06.md` | REVIEW_REVIEW_REVIEW_REVIEW_API-2 |

## Final Verification

```bash
test -f agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/09+06,08_artifact_pair/complete.log
test -f agent-task/archive/2026/08/m-iop-hot-path-one-shot-execution/10+07,09_light_flow/complete.log
go test -count=1 ./apps/edge/internal/openai -run '^TestWorkspace(ResultExactness|BindingReceipts)$'
go test -count=1 ./apps/edge/internal/openai -run '^Test(ArtifactPairFailureCleanupKeepsMalformedFailClosed|HotPathCleanupPrimaryErrorPrecedence)$'
go test -race -count=1 ./apps/edge/internal/openai -run '^Test(ArtifactPairFailureCleanupKeepsMalformedFailClosed|HotPathCleanupPrimaryError|LogicalRequestTTL)$'
go test -race -count=1 ./packages/go/streamgate ./packages/go/config ./apps/edge/internal/openai ./apps/edge/internal/service
edge_test_tmpdir="$(mktemp -d /config/workspace/iop-edge-test.XXXXXX)"
chmod 700 "$edge_test_tmpdir"
TMPDIR="$edge_test_tmpdir" go test -count=1 ./apps/edge/...
edge_test_status=$?
rmdir "$edge_test_tmpdir"
exit "$edge_test_status"
```

Run the remaining static checks in a new shell after the full Edge command:

```bash
go vet ./apps/edge/...
gofmt -d apps/edge/internal/openai/workspace_tool_codec.go apps/edge/internal/openai/workspace_tool_binding_test.go apps/edge/internal/openai/artifact_pair_test.go
git diff --check
```

Expected: every command exits 0; focused exactness and public-handler cases pass freshly; race and full Edge suites pass; the executable temporary directory is removed; vet, formatting, and diff checks print nothing. No external credential, real workspace mutation, or live provider is required.

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