23 KiB
Plan - Run and Score the Thin-Agent Matrix Once
For the Implementing Agent
Execute the pre-attempt gate and the nine rows exactly as specified. A started producer command consumes that row even on timeout, failure, or malformed output; never retry, resume, recover, or replace it. Fill implementation-owned sections in CODE_REVIEW-cloud-G08.md, then leave the active pair for official review.
Background
The checkpoint pair established the intended atomic benchmark and the first refinement added explicit evidence paths. That refinement remained non-executable: it could form /v1/v1/models, unset the token before producer work, and ran Claude outside the row workspace. This replacement preserves the original nine-route, single-attempt, blind-score intent while closing those command and evidence defects.
Archive Evidence Snapshot
- Pre-refine intent: checkpoint
e09aa66c3cdb829366463c10f8bc5f5801e3136e, with one atomic pair covering all four Milestone Task ids. - Replaced unstarted refinement:
plan_local_G08_1.log,code_review_cloud_G08_1.log; no verdict or implementation evidence. - Earlier unstarted pair:
plan_local_G08_0.log,code_review_cloud_G08_0.log; no verdict. - Preserved invariants: fixed prompt and nine tuples, empty row workspaces, one producer invocation per tuple, no benchmark runner/state machine, opaque single-pass scoring, failures and missing usage are not zero.
Analysis
Files Read
AGENTS.mdagent-ops/rules/project/rules.mdagent-ops/rules/common/rules-roadmap.mdagent-ops/rules/common/rules-agent-spec.mdagent-ops/rules/project/domain/testing/rules.mdagent-ops/skills/common/router.mdagent-ops/skills/common/plan/SKILL.mdagent-ops/skills/common/refine-plans/SKILL.mdagent-ops/skills/common/finalize-task-routing/SKILL.mdagent-test/local/rules.mdagent-test/dev/rules.mdagent-test/dev/iop-thin-agent-model-comparison.mdagent-test/dev/iop-benchmark-route-minimal-html-smoke.mdagent-roadmap/current.mdagent-roadmap/phase/knowledge-tool-optimization-extension/milestones/thin-agent-model-comparison-benchmark.mdagent-spec/index.mdagent-contract/index.mddocs/dev-opencode-settings-guide.mdscripts/e2e-hot-path-agents.shscripts/e2e-single-request-claude.sh- the four task-local logs named above
SDD Criteria
SDD is not required. The Milestone records a test-only observation of existing caller/product paths with no API, state-machine, retry, or schema change. This pair contributes exactly single-attempt-matrix, minimal-result-table, single-pass-scorecard, and bounded-conclusion.
Verification Context
No handoff was supplied. Repository-native dev rules select toki@toki-labs.com, /Users/toki/agent-work/iop-dev, Edge port 18083, the existing SOPS principal token, and the managed CA. Before creating run_root, normalize the decrypted URL once to api_root by removing one trailing slash and one trailing /v1; use ${api_root}/v1/models, ANTHROPIC_BASE_URL=$api_root, and OpenCode baseURL=${api_root}/v1. Keep the shell-local token through row 09 and unset it immediately afterward.
External preflight must prove the smoke-qualified clean dev runtime identity, required caller versions/flags, ports, credential inputs, timeout tool, and authenticated five-model catalog. It does not deploy or mutate tracked runtime config. Local /config/.local/bin/chromium renders each scorable source once at each fixed viewport. Secrets and raw caller streams remain ignored evidence.
Test Coverage Gaps
- Live availability has no unit substitute; the authenticated catalog gate and immutable row ledgers are the evidence.
- Caller usage schemas differ; use an explicit caller field from the sole stream or
미제공. - Visual judgment is manual by design; opaque input, fixed renders, locked anchors, arithmetic, and direct evidence bound it.
Symbol References
None; no product symbol changes.
Split Judgment
Keep one atomic pair. The result table, post-attempt opaque bijection, scorecard, and conclusion must bind to the same immutable nine-attempt set; independent children could expose route identity early or weaken the no-retry boundary. The explicit row protocol keeps large_indivisible_context=false.
Scope Rationale
Writable tracked output is only the comparison document and active review evidence. Writable ignored evidence is the enumerated agent-test/runs/bench-lite-01 files below. Product source/config, caller installation or user config, roadmap/spec/contract, scripts, runner/manifest/state-store, and prior smoke evidence are excluded.
Final Routing
- evaluation_mode:
first-passfor this semantic replacement - finalizer:
finalize-task-policy.sh, modepair - closures: scope/context/verification/evidence/ownership/decision are true for build and review
- build scores: scope 1, state 2, blast 1, evidence 2, verification 2 = G08;
local-fit;PLAN-local-G08.md - review scores: scope 1, state 2, blast 1, evidence 2, verification 2 = G08;
official-review;CODE_REVIEW-cloud-G08.md - positive loop risk:
variant_product(1);large_indivisible_context=false; rework 0; integrity failure false
Implementation Checklist
- Pass the authenticated catalog/runtime gate without creating a producer workspace.
- Create nine empty row workspaces and execute each fixed caller/model tuple exactly once in its row workspace, with no retry/resume/recovery.
- Fill the nine-row result table from immutable evidence, using caller-provided usage or
미제공. - After all attempts, create one shuffled opaque bijection and copy/extract each scorable exact source without route facts.
- Render each scorable opaque source once at desktop and once at mobile, then score it once with locked anchors and direct evidence.
- Write a bounded conclusion comparing only successful scorable results and separating operational facts from quality.
- Run the final count, isolation, placeholder, retry, secret, arithmetic, and scope checks.
- Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.
[TEST-1] Consume the Immutable Nine-Row Matrix
Problem: agent-test/dev/iop-thin-agent-model-comparison.md:28-41 requires nine empty-workspace single attempts. The prior refinement appended /v1/models to an unnormalized URL, released the token before attempts, and invoked Claude from the repository root rather than the row workspace; those defects can fail the gate or invalidate that comparison.
Solution: Run one remote zsh session. Complete the gate in Final Verification, keeping api_root, iop_token, ca, run_root, and the prompt alive. Create all row workspaces before row 01. Execute these tuples in order: row 01 Claude/claude-sonnet-5; 02 Claude/gemini-3.6-flash; 03 OpenCode/gemini-3.6-flash; 04 Claude/gpt-5.6-luna; 05 Codex/gpt-5.6-luna; 06 Claude/gemini-hybrid; 07 OpenCode/gemini-hybrid; 08 Claude/gpt-hybrid; 09 Codex/gpt-hybrid.
Before each command, require missing attempt.txt and producer.jsonl, require an empty workspace, and write caller/model/version/start plus attempt_count=1, retry=0, resume=0. Wrap the sole invocation with /opt/homebrew/bin/gtimeout 900, redirect its only stream to producer.jsonl, and append end/elapsed/exit. Use the following exact caller forms, substituting only the tuple values:
# Claude rows: invoke from the row workspace.
( cd "$workspace" && ANTHROPIC_BASE_URL="$api_root" ANTHROPIC_AUTH_TOKEN="$iop_token" NODE_EXTRA_CA_CERTS="$ca" CLAUDE_CODE_MAX_RETRIES=0 /opt/homebrew/bin/gtimeout 900 claude --print --output-format stream-json --verbose --bare --no-session-persistence --dangerously-skip-permissions --model "$model" "$(cat "$run_root/prompt.txt")" ) > "$run_root/$row/producer.jsonl" 2>&1
# OpenCode rows: --dir and command-scoped config bind the row workspace.
IOP_BENCH_TOKEN="$iop_token" OPENCODE_CONFIG_CONTENT="$(jq -cn --arg base "$api_root/v1" --arg model "$model" '{permission:{read:"allow",write:"allow",edit:"allow",glob:"allow",bash:"allow"},provider:{iop:{npm:"@ai-sdk/openai-compatible",options:{baseURL:$base,apiKey:"{env:IOP_BENCH_TOKEN}"},models:{($model):{name:$model}}}}}')" NODE_EXTRA_CA_CERTS="$ca" /opt/homebrew/bin/gtimeout 900 opencode run --pure --auto --model "iop/$model" --agent build --format json --dir "$workspace" "$(cat "$run_root/prompt.txt")" > "$run_root/$row/producer.jsonl" 2>&1
# Codex rows: isolated auth/config home and explicit row cwd.
codex_home="$(mktemp -d)"
cp /Users/toki/.codex/auth.json "$codex_home/auth.json"
cp /Users/toki/.codex/iop-direct.config.toml "$codex_home/iop-direct.config.toml"
CODEX_HOME="$codex_home" IOP_CODEX_API_KEY="$iop_token" CODEX_CA_CERTIFICATE="$ca" /opt/homebrew/bin/gtimeout 900 codex exec --ephemeral --json --sandbox workspace-write --skip-git-repo-check --cd "$workspace" --profile iop-direct --model "$model" --output-last-message "$run_root/$row/terminal.txt" "$(cat "$run_root/prompt.txt")" > "$run_root/$row/producer.jsonl" 2>&1
rm -rf "$codex_home"
Capture status with set +e/status=$?/set -e around each exact invocation; cleanup is not a retry. For direct rows 01-05, accept workspace/index.html only with exactly one terminal BENCH_LITE_01_DONE. For preset rows 06-09, extract terminal text once from that row's sole stream; if its caller-native terminal event is absent or ambiguous, mark 채점 불가. A terminal is scorable only when this strict one-shot extractor finds exactly one html fence: ruby -e 's=File.binread(ARGV[0]);m=s.scan(/```html\r?\n(.*?)\r?\n```/m);abort("expected exactly one html fence") unless m.length==1;File.binwrite(ARGV[1],m[0][0])' terminal.txt index.html.
After row 09, unset iop_token, transfer the ignored run directory once to this checkout, then create opaque-map.txt exactly once with a shuffled row/E01-E09 bijection. Copy only scorable exact HTML into the mapped E*/index.html; write only its SHA-256 to source.txt. Do not place route, caller, model, time, usage, or row id in any E* directory. Freeze all scores before joining the mapping.
Modified Files and Checklist:
agent-test/dev/iop-thin-agent-model-comparison.md: immutable result rows and observations.agent-test/runs/bench-lite-01/prompt.txt: exact fixed prompt.agent-test/runs/bench-lite-01/catalog.json: credential-free catalog body.agent-test/runs/bench-lite-01/runtime.txt: redacted preflight identity.agent-test/runs/bench-lite-01/opaque-map.txt: one post-attempt bijection.- Row and opaque evidence files enumerated in Modified Files Summary.
Test Strategy: No new test code or common runner. The measured behavior is the nine live caller invocations; immutable ledgers and sole streams are the regression evidence.
Verification: Run Final Verification. Expect gate success before run_root, nine ledgers/streams, one attempt marker per row, exact empty-workspace binding, and no retry/resume/recovery.
[TEST-2] Render, Score Once, and Conclude
Problem: agent-test/dev/iop-thin-agent-model-comparison.md:43-91 requires source plus desktop/mobile evidence under a single blind evaluation pass, while its conclusion must not turn missing or failed data into zero.
Solution: For each scorable E*/index.html, create fresh temporary Chromium profiles outside the repository and invoke Chromium once with --window-size=1440,900 --screenshot=desktop.png, then once with --window-size=390,844 --screenshot=mobile.png. Record viewport and sole exit status in render.txt; a failed render is not repeated. Score only the opaque source/renders, use the fixed A selectors and B-D anchors 0/1/3/5, record direct evidence and each deduction, and verify A+B+C+D. Join route facts only after all score blocks are frozen. Compare only successful scorable results; keep failure, unscorable output, and 미제공 separate.
Modified Files and Checklist:
agent-test/dev/iop-thin-agent-model-comparison.md: score rows, evidence blocks, allowed correction notes, bounded conclusion.- Opaque render evidence enumerated in Modified Files Summary.
Test Strategy: No automated judge/browser gate. Fixed source, two one-shot renders, locked anchors, reviewer inspection, and arithmetic are the required evidence.
Verification: Expect every scorable ID to have exactly one source, SHA record, two images, and one two-entry render ledger; every score has anchor/evidence and correct arithmetic.
Modified Files Summary
| File | Items |
|---|---|
agent-test/dev/iop-thin-agent-model-comparison.md |
TEST-1, TEST-2 |
agent-test/runs/bench-lite-01/prompt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/catalog.json |
TEST-1 |
agent-test/runs/bench-lite-01/runtime.txt |
TEST-1 |
agent-test/runs/bench-lite-01/opaque-map.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-01/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-01/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-01/workspace/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/row-02/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-02/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-02/workspace/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/row-03/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-03/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-03/workspace/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/row-04/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-04/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-04/workspace/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/row-05/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-05/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-05/terminal.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-05/workspace/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/row-06/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-06/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-06/terminal.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-07/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-07/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-07/terminal.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-08/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-08/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-08/terminal.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-09/attempt.txt |
TEST-1 |
agent-test/runs/bench-lite-01/row-09/producer.jsonl |
TEST-1 |
agent-test/runs/bench-lite-01/row-09/terminal.txt |
TEST-1 |
agent-task/m-thin-agent-model-comparison-benchmark/CODE_REVIEW-cloud-G08.md |
TEST-1, TEST-2 |
agent-test/runs/bench-lite-01/E01/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E01/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E01/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E01/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E01/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E02/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E02/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E02/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E02/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E02/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E03/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E03/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E03/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E03/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E03/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E04/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E04/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E04/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E04/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E04/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E05/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E05/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E05/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E05/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E05/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E06/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E06/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E06/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E06/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E06/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E07/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E07/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E07/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E07/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E07/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E08/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E08/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E08/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E08/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E08/render.txt |
TEST-2 |
agent-test/runs/bench-lite-01/E09/index.html |
TEST-1 |
agent-test/runs/bench-lite-01/E09/source.txt |
TEST-1 |
agent-test/runs/bench-lite-01/E09/desktop.png |
TEST-2 |
agent-test/runs/bench-lite-01/E09/mobile.png |
TEST-2 |
agent-test/runs/bench-lite-01/E09/render.txt |
TEST-2 |
Final Verification
Before creating run_root, run in one remote zsh shell:
set -euo pipefail
cd /Users/toki/agent-work/iop-dev
run_root="$PWD/agent-test/runs/bench-lite-01"
test ! -e "$run_root"
ca="$PWD/build/dev-runtime/.secrets/credential-plane/ca.pem"
secret=/Users/toki/.config/iop/secrets/dev-openai-toki.sops.yaml
export SOPS_AGE_KEY_FILE=/Users/toki/.config/sops/age/keys.txt
base_url="$(/opt/homebrew/bin/sops -d --extract '["base_url"]' "$secret")"
api_root="${base_url%/}"; api_root="${api_root%/v1}"
iop_token="$(/opt/homebrew/bin/sops -d --extract '["tokens"]["toki-dev-cline"]' "$secret")"
test -n "$api_root"; test -n "$iop_token"; test -f "$ca"
test -z "$(git status --short)"; test "$(git branch --show-current)" = dev
test "$(git rev-parse HEAD)" = 16b7aba95a282b6c5d1e88d3b1849eaa1208b28a
command -v /opt/homebrew/bin/gtimeout jq ruby claude opencode codex
claude --help | rg -- '--print|--output-format|--verbose|--no-session-persistence|--bare'
opencode run --help | rg -- '--pure|--model|--agent|--format|--dir'
codex exec --help | rg -- '--ephemeral|--json|--sandbox|--cd|--profile|--model|--output-last-message'
nc -z 127.0.0.1 18083; nc -z 127.0.0.1 19093
tmp_catalog="$(mktemp)"
http_code="$(curl --cacert "$ca" -sS -o "$tmp_catalog" -w '%{http_code}' -H "Authorization: Bearer $iop_token" "$api_root/v1/models")"
test "$http_code" = 200
for model in claude-sonnet-5 gemini-3.6-flash gpt-5.6-luna gemini-hybrid gpt-hybrid; do jq -e --arg model "$model" '.data[] | select(.id == $model)' "$tmp_catalog" >/dev/null; done
mkdir "$run_root"; mv "$tmp_catalog" "$run_root/catalog.json"
printf 'branch=dev\nhead=%s\nports=18083,19093\ncatalog_http=200\n' "$(git rev-parse HEAD)" > "$run_root/runtime.txt"
Copy the exact fixed prompt into prompt.txt, create all nine row workspaces, and execute the expanded caller forms in TEST-1. Preserve redacted expanded commands, exit statuses, and ledgers in the active review. Unset iop_token only after row 09.
For each scorable opaque ID, run once with a fresh profile per viewport and record both statuses:
opaque_id=E01; opaque_dir="$PWD/agent-test/runs/bench-lite-01/$opaque_id"; render_log="$opaque_dir/render.txt"
test ! -e "$render_log"; : > "$render_log"
profile="$(mktemp -d)"; printf 'viewport=1440x900\n' >> "$render_log"
set +e; /config/.local/bin/chromium --headless --disable-gpu --hide-scrollbars --run-all-compositor-stages-before-draw --user-data-dir="$profile" --window-size=1440,900 --screenshot="$opaque_dir/desktop.png" "file://$opaque_dir/index.html"; status=$?; set -e
printf 'exit_status=%s\n' "$status" >> "$render_log"
profile="$(mktemp -d)"; printf 'viewport=390x844\n' >> "$render_log"
set +e; /config/.local/bin/chromium --headless --disable-gpu --hide-scrollbars --run-all-compositor-stages-before-draw --user-data-dir="$profile" --window-size=390,844 --screenshot="$opaque_dir/mobile.png" "file://$opaque_dir/index.html"; status=$?; set -e
printf 'exit_status=%s\n' "$status" >> "$render_log"
Run fresh local checks; cached output is not applicable:
test "$(find agent-test/runs/bench-lite-01 -mindepth 2 -maxdepth 2 -name attempt.txt -type f | wc -l)" -eq 9
test "$(find agent-test/runs/bench-lite-01 -mindepth 2 -maxdepth 2 -name producer.jsonl -type f | wc -l)" -eq 9
test "$(rg -l '^attempt_count=1$' agent-test/runs/bench-lite-01/row-*/attempt.txt | wc -l)" -eq 9
test "$(rg -l '^workspace_initial_entries=0$' agent-test/runs/bench-lite-01/row-*/attempt.txt | wc -l)" -eq 9
test "$(cut -d' ' -f1 agent-test/runs/bench-lite-01/opaque-map.txt | LC_ALL=C sort -u | wc -l)" -eq 9
test "$(cut -d' ' -f2 agent-test/runs/bench-lite-01/opaque-map.txt | LC_ALL=C sort -u | wc -l)" -eq 9
scorable="$(find agent-test/runs/bench-lite-01 -mindepth 2 -maxdepth 2 -path '*/E*/index.html' -type f | wc -l)"
for name in desktop.png mobile.png render.txt source.txt; do test "$(find agent-test/runs/bench-lite-01 -mindepth 2 -maxdepth 2 -path "*/E*/$name" -type f | wc -l)" -eq "$scorable"; done
! rg -n '미실행|미측정|미확인|미부여-[0-9]|미채점' agent-test/dev/iop-thin-agent-model-comparison.md
! rg -n '(retry|resume|recovery)[[:space:]]*[:=][[:space:]]*(true|yes|[1-9])' agent-test/runs/bench-lite-01
! rg -n --hidden '(sk-|Bearer [A-Za-z0-9._-]{16,}|api[_-]?key[[:space:]]*[:=][[:space:]]*[A-Za-z0-9._-]{16,})' agent-test/dev/iop-thin-agent-model-comparison.md agent-test/runs/bench-lite-01
! rg -n 'Claude|OpenCode|Codex|claude-sonnet|gemini|gpt|hybrid|경과|usage|row-[0-9]' agent-test/runs/bench-lite-01/E*/source.txt agent-test/runs/bench-lite-01/E*/render.txt
git diff --check -- agent-test/dev/iop-thin-agent-model-comparison.md agent-task/m-thin-agent-model-comparison-benchmark
git diff --name-only -- . ':(exclude)agent-test/dev/iop-thin-agent-model-comparison.md' ':(exclude)agent-task/m-thin-agent-model-comparison-benchmark/**'
The last command must print nothing. Reviewer inspection must confirm gate-before-workspace ordering, exact tuple/workspace binding, one producer invocation per row, explicit usage or 미제공, opaque isolation through score freeze, fixed-anchor arithmetic, and a conclusion that excludes failed/unscorable rows from quality comparison.
After completing all code changes, fill implementation-owned sections in CODE_REVIEW-cloud-G08.md.