<!-- task=m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification plan=5 tag=REVIEW_REVIEW_REVIEW_API milestone-task=workspace-binding,claude-smoke -->

# Close tool observation before continuation and requalify preflight

## For the Implementing Agent

Filling the implementation-owned sections of `CODE_REVIEW-cloud-G09.md` is the mandatory last implementation step. Run every verification command, paste actual stdout/stderr, keep both active files in place, and report ready for review. Only the official code-review skill may append a verdict, archive files, write `complete.log`, create `USER_REVIEW.md`, or classify the next state. If blocked, record the exact blocker, attempted command/output, and resume condition only in implementation-owned evidence fields; do not ask the user, call user-input tools, create control-plane stop files, or change the selected owner. This packet permits the bounded disposable candidate refresh and `--preflight-only`, but forbids `--run` and every other live Claude/provider invocation.

## Background

The Claude origin-route repair and isolated lifecycle Prometheus registry pass focused review. The remaining failure is an ordering race: `executeInternalWorkspaceTool` publishes a successful continuation before its deferred tool observation closes, so resumed plan/work/review envelopes may overwrite the pending stage close. The implementation's first required race run observed five instead of seven lifecycle events; later green reruns do not satisfy the no-retry acceptance rule. The tool-observation boundary and its oracle must be deterministic before the disposable candidate is refreshed for zero-child preflight.

## Archive Evidence Snapshot

- Immediate prior plan/review: `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/plan_cloud_G09_4.log` and `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/code_review_cloud_G09_4.log`; verdict `FAIL`, `review_rework_count=3`, `evidence_integrity_failure=false`.
- Required R2: `apps/edge/internal/service/single_request_tool_loop.go:137` defers `onToolExit` until after `ContinueInternalTool` at line 220. The first exact race run reported five lifecycle events instead of request/tool/plan/work/review/cleanup/terminal; source inspection confirms resumed envelopes can advance first.
- Accepted prior work remains read-only in this packet: origin-form Claude base validation and exact-route zero-child fixtures in `scripts/e2e-single-request-claude.sh`, plus the dedicated lifecycle registry seam in `apps/edge/internal/service/single_request_metrics.go` and `apps/edge/internal/openai/single_request_handler_test.go`.
- Fresh review evidence: harness syntax/self-test passed; the dedicated-registry OpenAI observation test passed under `-race -count=20`; a focused service lifecycle run passed under `-race -count=100`; and three later full race suites passed. These reruns establish intermittency, not acceptance, because the code ordering remains wrong.
- Fresh read-only SSH preflight passed for `/Users/toki/agent-work/iop-s12-validation-20260808/source`: health 200, `/v1/messages` 401/405, `/v1/v1/messages` 404, ingress 0, writable workspace, and no result or manifest. Candidate Edge PID 25372 and selected Node PID 25114 were alive when reviewed.
- Live Claude authorization remains consumed. Do not run Claude. After repository repair and clean remote preflight, the official reviewer owns the separate `external-execution` gate.

## Finding Resolution Map

| Finding | Mode | Fix/evidence | Changed precondition |
|---------|------|--------------|----------------------|
| R2 | direct-fix | Change `apps/edge/internal/service/single_request_tool_loop.go` so a successful tool observation closes exactly once before continuation can submit resumed envelopes; add a synchronous-continuation regression in `apps/edge/internal/service/single_request_observation_test.go`. | The old source-level ordering race is removed and the regression deterministically exercises the formerly scheduler-dependent interleaving before repeated race and remote preflight evidence are accepted. |

## Analysis

### Files Read

- Active/prior evidence: `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/PLAN-cloud-G09.md`, `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/CODE_REVIEW-cloud-G09.md`, `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/plan_cloud_G10_3.log`, and `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/code_review_cloud_G10_3.log` before the current pair was archived to the paths above.
- Production path: `apps/edge/internal/service/single_request_tool_loop.go`, `apps/edge/internal/service/single_request.go`, and `apps/edge/internal/service/single_request_observation.go`.
- Tests and accepted seams: `apps/edge/internal/service/single_request_observation_test.go`, `apps/edge/internal/service/single_request_tool_loop_test.go`, `apps/edge/internal/service/single_request_metrics.go`, and `apps/edge/internal/openai/single_request_handler_test.go`.
- Harness/build context: `scripts/e2e-single-request-claude.sh` and `Makefile`.
- Current owners: `agent-roadmap/phase/iop-owned-single-request-agent-execution/milestones/25_claude_smoke_qualification.md`, its approved SDD, `agent-contract/outer/anthropic-compatible-api.md`, `agent-spec/input/openai-compatible-surface.md`, and `agent-spec/runtime/edge-node-execution.md`.

### SDD Criteria

- The selected Milestone has `SDD: 필요`, approved and unlocked. The header preserves `milestone-task=workspace-binding,claude-smoke`.
- Acceptance Scenario S04 requires exact workspace/Node binding evidence; this packet preserves the accepted platform-neutral binding and refreshes only the selected disposable Edge identity.
- Acceptance Scenario S12 requires one ingress, ordered `gemini -> ornith-fast -> gemini`, stage/total timing, one terminal, and verified mutation. This packet repairs the stage observation prerequisite but deliberately stops at zero-child preflight, so it must not claim S12 PASS or promote deferred contract/spec language.
- The Evidence Map requires source, Edge, Node, config, model, workspace owner, observation log, and metrics identity to agree. The candidate refresh and runtime-evidence reconciliation below are therefore part of the same verification unit as R2.

### Verification Context

- No separate handoff file was supplied. Repository evidence and the exact archived review paths above were used.
- Fresh local commands and outcomes: harness syntax/self-test PASS; OpenAI observation `-race -count=20` PASS; focused service lifecycle `-race -count=100` PASS; later three-run full race PASS. The implementation's recorded first exact race run failed with event count 5 versus 7.
- External preflight: authorized runner `ssh -o BatchMode=yes toki@toki-labs.com`; source `/Users/toki/agent-work/iop-s12-validation-20260808/source` at HEAD `70d22850d01714fdef734dafa42e82fed79e0786`; workspace `/Users/toki/agent-work/iop-s12-validation-20260808/workspace`; Darwin/arm64; Edge `/Users/toki/agent-work/iop-s12-validation-20260808/source/build/s12/bin/iop-edge`; Node `.../iop-node-darwin-arm64`; config `build/s12/runtime/edge.yaml`; runtime evidence `build/s12/runtime/runtime-evidence.json`; ports 18083/19101; canonical Claude executable `/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe`.
- Safe read-only SSH checks passed with candidate Edge PID 25372, selected Node PID 25114, health 200, exact route distinction, ingress 0, and absent output/manifest. The remote source is a detached HEAD with only the bounded prior overlays dirty.
- Exact sync is a tar overlay of the two R2 files only. Exact rebuild/restart is the selected Edge command in Final Verification 7; no selected Node, canonical dev checkout, provider process, config, or workspace is replaced. Runtime evidence is atomically reconciled from the candidate source/binary/config facts before Final Verification 8 validates it.
- `/config/workspace/iop/token/.claude` is used only as stdin for `--preflight-only`; no value may be printed or persisted. Cached Go output is not acceptable.

### Test Coverage Gaps

- The existing buffered-channel continuation permits the bad ordering but does not force it. Add a dedicated executor/test that synchronously submits resumed plan/work/review/finalizing envelopes from `ContinueInternalTool` before it returns.
- Existing failure/cancel tests cover in-flight tool terminal ordering. Retain them and add an explicit continuation-error assertion if the success-boundary change alters tool-versus-terminal classification.
- No repository test replaces a live S12 invocation. This packet stops after clean preflight with no manifest.

### Symbol References

- No symbol rename or removal is planned.
- `SingleRequestToolContinuation.ContinueInternalTool` remains unchanged. Its service caller is `executeInternalWorkspaceTool`; test implementations are in `single_request_tool_loop_test.go`, `single_request_observation_test.go`, and `single_request_artifact_test.go`.

### Split Judgment

Keep one compact plan. The production ordering boundary and the synchronous regression are one concurrency invariant; the disposable Edge must contain that exact repair before preflight can be trusted. Splitting would repeat verification against an unchanged candidate or separate the bug fix from its deterministic oracle.

### Scope Rationale

Write only the tool-loop implementation, its service observation regression, and the active review evidence file. Do not modify the accepted Claude harness, metrics registry seam, OpenAI handler test, public API, protobuf/config/schema, contract/spec, manifest, workspace, canonical dev checkout, selected Node, unrelated processes, roadmap, or live provider state. Remote writes are limited to the two reviewed source overlays, selected disposable Edge binary/process, runtime evidence, and its log.

### Final Routing

- `evaluation_mode=isolated-reassessment`; build/review closures `scope`, `context`, `verification`, `evidence`, `ownership`, and `decision` are all true; no capability gap.
- Finalizer `finalize-task-policy.sh`, mode `pair`. Build scores `2/2/1/2/2` => G09, base/final `grade-boundary`, `worker/cloud/G09`, `PLAN-cloud-G09.md`. Review scores `2/2/1/2/2` => G09, `official-review`, `review/cloud/G09`, `CODE_REVIEW-cloud-G09.md`.
- `large_indivisible_context=false`; matched risks `temporal_state`, `concurrent_consistency`, `boundary_contract`, `structured_interpretation` (4); `review_rework_count=3`; `evidence_integrity_failure=false`. Risk and recovery boundaries match, but grade-boundary remains authoritative.

## Dependencies and Execution Order

1. Implement and test the tool-observation/continuation ordering locally without changing the accepted R1 or registry files.
2. Pass the new deterministic regression, focused OpenAI test, three consecutive full race suites, harness self-test, full suite, and hygiene gates without retrying a failed required command.
3. Overlay only the two reviewed R2 files, rebuild/restart only the selected disposable Edge with rollback, atomically refresh runtime evidence, and verify identity/health/zero ingress.
4. Run `--preflight-only` once. Do not run `--run`, create/copy a manifest, or promote S12 wording.
5. Record exact outputs in `CODE_REVIEW-cloud-G09.md`; the official reviewer owns the subsequent live external-execution classification.

## Implementation Checklist

- [ ] Close the tool observation exactly once before continuation can advance resumed stages, preserving failure/cancel and continuation-error terminal classification without holding `h.mu` across external code.
- [ ] Add a deterministic synchronous-continuation lifecycle regression and pass all local no-retry race, harness, suite, protobuf-reproducibility, and hygiene gates.
- [ ] Refresh only the disposable selected Edge from the two reviewed files, reconcile runtime identity, pass origin-based remote `--preflight-only` with zero Claude children/ingress and no manifest, and retain deferred S12 state.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REVIEW_API-1] Establish the tool-observation completion boundary

**Problem**

`apps/edge/internal/service/single_request_tool_loop.go:137-141` defers `h.timing.onToolExit`, while line 220 calls external `ContinueInternalTool` first. A continuation can submit resumed stage envelopes before the deferred observation releases the paused plan stage; `single_request_observation.go` then retains only one pending close and omits work/review events.

**Solution**

Use one local exactly-once observation closer. Early validation, workspace, wire, timeout, cancellation, and budget returns retain deferred closure with their classified outcome. After the successful result has been validated and marked ready, explicitly close the successful tool observation under `h.mu`, mark it closed, release the lock, and only then call `ContinueInternalTool`. Never hold `h.mu` across continuation. If continuation fails, fail the request with the existing context-aware terminal classification; the already completed workspace tool remains a successful tool event and must not be emitted twice.

Before (`apps/edge/internal/service/single_request_tool_loop.go:137`):

```go
defer func() {
	h.mu.Lock()
	h.timing.onToolExit(outcome, errorClass)
	h.mu.Unlock()
}()
// ...
if err := continuation.ContinueInternalTool(ctx, result.Clone()); err != nil {
	outcome, errorClass = h.failInternalWorkspaceToolOutcome(ctx, singleRequestErrorClassInternalToolFailed, ErrSingleRequestInternalToolBudget)
}
```

After:

```go
toolObserved := false
observeTool := func(outcome singleRequestOutcome, errorClass singleRequestErrorClass) {
	if toolObserved {
		return
	}
	h.mu.Lock()
	h.timing.onToolExit(outcome, errorClass)
	h.mu.Unlock()
	toolObserved = true
}
defer func() { observeTool(outcome, errorClass) }()
// ... validated successful result, with h.mu released
observeTool(singleRequestOutcomeSuccess, "")
if err := continuation.ContinueInternalTool(ctx, result.Clone()); err != nil {
	outcome, errorClass = h.failInternalWorkspaceToolOutcome(ctx, singleRequestErrorClassInternalToolFailed, ErrSingleRequestInternalToolBudget)
}
```

The concrete implementation may keep the closure flag under the single tool goroutine rather than making it atomic; it must preserve the lock/external-call boundary and exactly-once semantics.

**Modified Files and Checklist**

- [ ] Update `apps/edge/internal/service/single_request_tool_loop.go` with an exactly-once tool observation closer and explicit pre-continuation success boundary.

**Test Strategy**

Use the deterministic regression in item 2 plus existing failure/cancel tool-loop tests. Do not add sleeps or retry acceptance.

**Verification**

`go test -race -count=100 ./apps/edge/internal/service -run '^TestSingleRequestObservationSynchronousContinuationOrdering$'` must pass freshly.

### [REVIEW_REVIEW_REVIEW_API-2] Make the formerly intermittent interleaving deterministic

**Problem**

`apps/edge/internal/service/single_request_observation_test.go:766-768` sends the tool result to a buffered channel and returns. The executor goroutine and deferred `onToolExit` then race, so the lifecycle test sometimes sees all seven events and sometimes loses work/review.

**Solution**

Add `TestSingleRequestObservationSynchronousContinuationOrdering` with a dedicated executor that stores its controller/request identity, submits the tool pause, and blocks. Its `ContinueInternalTool` synchronously submits resumed plan, working, reviewing, and finalizing envelopes before returning, then releases the executor. Drive the manual clock exactly as the current lifecycle fixture does. Assert the complete ordered classes request/tool/stage(plan)/stage(work)/stage(review)/cleanup/terminal; exact stage names, tool count, durations, one cleanup, one terminal, correlations/privacy, and no duplicate event. Also assert a continuation error still fails the request with the existing terminal error class while the successfully completed workspace tool is emitted once.

**Modified Files and Checklist**

- [ ] Update `apps/edge/internal/service/single_request_observation_test.go` with the synchronous executor/regression and continuation-error classification assertion.

**Test Strategy**

Add the named regression rather than changing the existing buffered integration fixture. The synchronous callback makes the old implementation fail every time and the repaired implementation pass without scheduling luck. Run it 100 times with `-race`, then retain the existing OpenAI observation integration test and full package matrix.

**Verification**

`go test -race -count=100 ./apps/edge/internal/service -run '^TestSingleRequestObservationSynchronousContinuationOrdering$'` and `go test -race -count=20 ./apps/edge/internal/openai -run '^TestAnthropicSingleRequestObservation$'` must both pass.

### [REVIEW_REVIEW_REVIEW_API-3] Refresh the selected disposable Edge and stop at preflight

**Problem**

The running disposable candidate predates the R2 ordering repair. A green local suite cannot qualify remote lifecycle behavior against that stale binary, while the consumed one-run authorization forbids another live Claude request.

**Solution**

After all local gates pass, tar-overlay exactly the two reviewed R2 files into `/Users/toki/agent-work/iop-s12-validation-20260808/source`. Build `build/s12/bin/iop-edge.next`, validate it against the existing candidate config, preserve `iop-edge.pre-r2` for rollback, stop only the one exact candidate Edge process, atomically install/start the new Edge, and roll back on failed health. Leave PID 25114's selected Node and every unrelated runtime untouched. Recompute the existing runtime-evidence source head/branch/worktree, Edge binary/version, config/check, owner, origin base, and stage-binding digests atomically using the same algorithms enforced by the harness. Verify health, route distinction, ingress 0, writable workspace, and absent result/manifest before one `--preflight-only` call with the canonical Claude executable. The harness must report preflight success without a Claude child.

**Modified Files and Checklist**

- [ ] Record the exact non-secret overlay/build/PID/rollback/runtime-evidence/health/route/metric/preflight facts and actual output in `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/CODE_REVIEW-cloud-G09.md`.
- [ ] Confirm `agent-test/evidence/iop-owned-single-request-agent-execution/claude-smoke-evidence.json` and the remote workspace result remain absent; do not change contract/spec qualification text.

**Test Strategy**

No live integration test is authorized. Use exact read-only route/metric checks followed by one harness `--preflight-only`. A setup or preflight failure stops implementation and is recorded; it never authorizes `--run` or a retry of a failed local acceptance gate.

**Verification**

Run Final Verification 6-9 in order. Commands 7-8 may mutate only the selected disposable source/Edge/runtime-evidence paths; command 9 must start zero Claude children.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/service/single_request_tool_loop.go` | REVIEW_REVIEW_REVIEW_API-1 |
| `apps/edge/internal/service/single_request_observation_test.go` | REVIEW_REVIEW_REVIEW_API-2 |
| `agent-task/m-iop-owned-single-request-agent-execution/25+23,24_claude_smoke_qualification/CODE_REVIEW-cloud-G09.md` | REVIEW_REVIEW_REVIEW_API-1, REVIEW_REVIEW_REVIEW_API-2, REVIEW_REVIEW_REVIEW_API-3 |

## Final Verification

Fresh output is required. A failure in commands 1-5 ends local acceptance; do not rerun it and substitute a later pass. Commands 6 and 8 are read-only remote checks. Command 7 refreshes only the selected disposable candidate. Command 9 is `--preflight-only`. No command may contain `--run` or make a live Claude/provider request.

1. `go test -race -count=100 ./apps/edge/internal/service -run '^TestSingleRequestObservationSynchronousContinuationOrdering$'` — the continuation deterministically advances resumed envelopes before returning, yet all seven lifecycle events remain ordered, complete, and unique across 100 fresh race iterations.
2. `go test -race -count=20 ./apps/edge/internal/openai -run '^TestAnthropicSingleRequestObservation$'` — the dedicated-registry HTTP lifecycle test passes twenty fresh race iterations.
3. `bash -c 'set -euo pipefail; for run in 1 2 3; do echo "race-suite-run=$run"; go test -race -count=1 ./packages/go/config ./packages/go/streamgate ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/node/internal/bootstrap ./apps/node/internal/node ./apps/node/internal/transport ./apps/node/internal/workspace; done'` — the required matrix passes three consecutive fresh runs in this single command.
4. `bash -n scripts/e2e-single-request-claude.sh && make test-single-request-claude-smoke-self-test && go test -count=1 ./...` — the accepted origin-route harness remains green and the full Go suite passes freshly.
5. `bash -c 'set -euo pipefail; tmp="$(mktemp -d)"; trap '\''rm -rf "$tmp"'\'' EXIT; find proto/gen/iop -type f -print0 | sort -z | xargs -0 sha256sum >"$tmp/before"; make proto; find proto/gen/iop -type f -print0 | sort -z | xargs -0 sha256sum >"$tmp/after"; cmp "$tmp/before" "$tmp/after"; test ! -e agent-test/evidence/iop-owned-single-request-agent-execution/claude-smoke-evidence.json; git diff --check'` — protobuf generation is reproducible relative to the accepted current worktree, no manifest exists, and diff hygiene passes.
6. `ssh -o BatchMode=yes toki@toki-labs.com 'set -eu; root=/Users/toki/agent-work/iop-s12-validation-20260808/source; cd "$root"; test "$(git rev-parse HEAD)" = 70d22850d01714fdef734dafa42e82fed79e0786; test -d /Users/toki/agent-work/iop-s12-validation-20260808/workspace; test -w /Users/toki/agent-work/iop-s12-validation-20260808/workspace; test ! -e /Users/toki/agent-work/iop-s12-validation-20260808/workspace/smoke-result.txt; test ! -e agent-test/evidence/iop-owned-single-request-agent-execution/claude-smoke-evidence.json; test "$(curl -sS -o /dev/null -w "%{http_code}" http://127.0.0.1:18083/healthz)" = 200; code="$(curl -sS -o /dev/null -w "%{http_code}" -X OPTIONS http://127.0.0.1:18083/v1/messages)"; test "$code" = 401 -o "$code" = 405; test "$(curl -sS -o /dev/null -w "%{http_code}" -X OPTIONS http://127.0.0.1:18083/v1/v1/messages)" = 404; curl -fsS http://127.0.0.1:19101/metrics | grep -Eq "^iop_anthropic_single_request_ingress_total 0(\\.0+)?$"'` — current candidate assumptions and zero ingress hold before mutation.
7. `bash -c 'set -euo pipefail; tar -cf - apps/edge/internal/service/single_request_tool_loop.go apps/edge/internal/service/single_request_observation_test.go | ssh -o BatchMode=yes toki@toki-labs.com '\''set -eu; root=/Users/toki/agent-work/iop-s12-validation-20260808/source; cd "$root"; tar -xf -; git diff --check -- apps/edge/internal/service/single_request_tool_loop.go apps/edge/internal/service/single_request_observation_test.go; PATH=/opt/homebrew/bin:$PATH; /opt/homebrew/bin/go build -trimpath -o build/s12/bin/iop-edge.next ./apps/edge/cmd/edge; build/s12/bin/iop-edge.next config check --config build/s12/runtime/edge.yaml; old_pid="$(pgrep -f "^$root/build/s12/bin/iop-edge --config $root/build/s12/runtime/edge.yaml serve$")"; test -n "$old_pid"; test "$(printf "%s\\n" "$old_pid" | wc -l | tr -d " ")" = 1; cp -p build/s12/bin/iop-edge build/s12/bin/iop-edge.pre-r2; kill "$old_pid"; stopped=0; for attempt in 1 2 3 4 5 6 7 8 9 10; do if ! kill -0 "$old_pid" 2>/dev/null; then stopped=1; break; fi; sleep 1; done; test "$stopped" = 1; mv build/s12/bin/iop-edge.next build/s12/bin/iop-edge; nohup "$root/build/s12/bin/iop-edge" --config "$root/build/s12/runtime/edge.yaml" serve >>"$root/build/s12/runtime/edge.log" 2>&1 </dev/null & new_pid=$!; ok=0; for attempt in 1 2 3 4 5 6 7 8 9 10; do if curl -fsS http://127.0.0.1:18083/healthz >/dev/null 2>&1; then ok=1; break; fi; sleep 1; done; if test "$ok" != 1; then kill "$new_pid" 2>/dev/null || true; for attempt in 1 2 3 4 5 6 7 8 9 10; do if ! kill -0 "$new_pid" 2>/dev/null; then break; fi; sleep 1; done; mv build/s12/bin/iop-edge.pre-r2 build/s12/bin/iop-edge; nohup "$root/build/s12/bin/iop-edge" --config "$root/build/s12/runtime/edge.yaml" serve >>"$root/build/s12/runtime/edge.log" 2>&1 </dev/null & exit 1; fi; rm build/s12/bin/iop-edge.pre-r2; printf "old_edge_pid=%s new_edge_pid=%s\\n" "$old_pid" "$new_pid"'\'''` — exactly two files are overlaid and only the selected Edge is rebuilt/restarted with rollback.
8. Run this exact atomic runtime-evidence reconciliation and identity check:

   ```sh
   ssh -o BatchMode=yes toki@toki-labs.com 'set -eu
   cd /Users/toki/agent-work/iop-s12-validation-20260808/source
   python3 - build/s12/runtime/runtime-evidence.json <<'"'"'PY'"'"'
   import hashlib, json, os, subprocess, sys, tempfile

   path = sys.argv[1]
   root = os.getcwd()

   def sha_bytes(value):
       return "sha256:" + hashlib.sha256(value).hexdigest()

   def sha_text(value):
       return sha_bytes(value.encode())

   def sha_file(path_value):
       digest = hashlib.sha256()
       with open(path_value, "rb") as stream:
           for block in iter(lambda: stream.read(1024 * 1024), b""):
               digest.update(block)
       return "sha256:" + digest.hexdigest()

   inputs = [
       "apps/edge/internal/openai",
       "apps/edge/internal/service",
       "apps/node/internal/bootstrap",
       "apps/node/internal/workspace",
       "packages/go/config",
       "scripts/e2e-single-request-claude.sh",
       "scripts/fixtures/single-request-claude-smoke-manifest.schema.json",
       "Makefile",
   ]
   files = []
   for rel in inputs:
       candidate = os.path.join(root, rel)
       if os.path.isdir(candidate):
           for current, dirs, names in os.walk(candidate):
               dirs.sort()
               for name in sorted(names):
                   item = os.path.join(current, name)
                   if os.path.isfile(item) and not os.path.islink(item):
                       files.append(item)
       elif os.path.isfile(candidate) and not os.path.islink(candidate):
           files.append(candidate)
   tree = hashlib.sha256()
   for item in sorted(files):
       rel = os.path.relpath(item, root).replace(os.sep, "/")
       tree.update(rel.encode() + b"\0" + sha_file(item)[7:].encode() + b"\0")

   with open(path, encoding="utf-8") as stream:
       data = json.load(stream)
   runtime = data["runtime"]
   data["source"]["head"] = subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip()
   data["source"]["branch_digest"] = sha_text(subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], text=True).strip())
   data["source"]["worktree_digest"] = "sha256:" + tree.hexdigest()
   runtime["edge_digest"] = sha_file("build/s12/bin/iop-edge")
   runtime["edge_version_digest"] = sha_bytes(subprocess.check_output(["build/s12/bin/iop-edge", "version"], stderr=subprocess.STDOUT))
   runtime["config_digest"] = sha_file("build/s12/runtime/edge.yaml")
   runtime["config_check_digest"] = sha_bytes(subprocess.check_output(["build/s12/bin/iop-edge", "config", "check", "--config", "build/s12/runtime/edge.yaml"], stderr=subprocess.STDOUT))
   runtime["base_url_digest"] = sha_text("http://127.0.0.1:18083")
   owner = "|".join([runtime["workspace_os"], runtime["workspace_arch"], runtime["workspace_root_digest"], runtime["config_digest"], runtime["node_digest"], runtime["node_version_digest"]])
   runtime["workspace_owner_digest"] = sha_text(owner)
   binding = "|".join([runtime["config_digest"], runtime["config_check_digest"], runtime["base_url_digest"], runtime["public_model_digest"], *runtime["stage_engines"]])
   runtime["stage_binding_digest"] = sha_text(binding)
   descriptor, temporary = tempfile.mkstemp(prefix=".runtime-evidence.", dir=os.path.dirname(path), text=True)
   try:
       os.fchmod(descriptor, 0o600)
       with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
           json.dump(data, stream, sort_keys=True, separators=(",", ":"))
           stream.write("\n")
       os.replace(temporary, path)
   except Exception:
       if os.path.exists(temporary):
           os.unlink(temporary)
       raise
   PY
   build/s12/bin/iop-edge config check --config build/s12/runtime/edge.yaml
   build/s12/bin/iop-edge version
   build/s12/bin/iop-node-darwin-arm64 version
   test "$(uname -s)" = Darwin
   test "$(uname -m)" = arm64
   curl -fsS http://127.0.0.1:18083/healthz >/dev/null
   curl -fsS http://127.0.0.1:19101/metrics | grep -Eq "^iop_anthropic_single_request_ingress_total 0(\\.0+)?$"
   test ! -e agent-test/evidence/iop-owned-single-request-agent-execution/claude-smoke-evidence.json'
   ```

   The refreshed source/binary/config/host/listener identity must be healthy with zero ingress and no manifest.
9. `ssh -o BatchMode=yes toki@toki-labs.com 'IFS= read -r ANTHROPIC_API_KEY; export ANTHROPIC_API_KEY; cd /Users/toki/agent-work/iop-s12-validation-20260808/source; exec ./scripts/e2e-single-request-claude.sh --preflight-only --claude /opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe --runtime-evidence build/s12/runtime/runtime-evidence.json --base-url http://127.0.0.1:18083 --model iop-single-request-light --edge-bin build/s12/bin/iop-edge --node-bin build/s12/bin/iop-node-darwin-arm64 --edge-config build/s12/runtime/edge.yaml --observation-file build/s12/runtime/edge.log --metrics-url http://127.0.0.1:19101/metrics --workspace /Users/toki/agent-work/iop-s12-validation-20260808/workspace --output /Users/toki/agent-work/iop-s12-validation-20260808/source/agent-test/evidence/iop-owned-single-request-agent-execution/claude-smoke-evidence.json --secret-env ANTHROPIC_API_KEY' < /config/workspace/iop/token/.claude` — exits zero with the origin base, starts no Claude child, prints no secret, leaves ingress 0, and creates no manifest.
10. `bash -c 'set -euo pipefail; test ! -e agent-test/evidence/iop-owned-single-request-agent-execution/claude-smoke-evidence.json; rg --sort path -n "actual external Claude qualification remains explicitly deferred|Actual Claude timing evidence on an approved IOP Node is explicitly deferred|actual Claude timing evidence on an approved IOP Node is explicitly deferred" agent-contract/outer/anthropic-compatible-api.md agent-spec/runtime/edge-node-execution.md agent-spec/input/openai-compatible-surface.md; git diff --check'` — qualification remains explicitly deferred and no tracked manifest or hygiene defect exists.

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