From 8d0baac5739128a40db588f983bc2970bd1c2bac Mon Sep 17 00:00:00 2001 From: toki Date: Sun, 9 Aug 2026 10:11:32 +0900 Subject: [PATCH] =?UTF-8?q?docs(single=5Frequest):=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?presence=20=EC=88=98=EB=A6=AC=EC=9D=98=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EA=B7=BC=EA=B1=B0=EB=A5=BC=20=EA=B8=B0=EB=A1=9D=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 원격 evidence는 push된 commit이 있어야 만들 수 있으므로 구현 commit을 먼저 올린 뒤 그 commit으로 원격을 검증했다. 검증 대상 commit, 로컬 전체 suite와 race/full/self-test 결과, Darwin/arm64 재빌드 결과를 남긴다. 승인된 operator 설정 파일 두 개가 여전히 없어 live API 검증은 외부 차단 상태이며, 이를 통과로 기록하지 않고 정확한 복구 조건과 열두 개 입력 목록을 함께 남긴다. 직전 루프의 plan/review 로그와 이번 루프 pair도 함께 보존한다. Refs: agent-task/single_request_plan_review_templates/PLAN-cloud-G08.md Co-Authored-By: Claude Opus 5 --- .../CODE_REVIEW-cloud-G08.md | 481 ++++++++---------- .../PLAN-cloud-G08.md | 364 ++++++------- .../WORK_LOG.md | 6 + .../code_review_cloud_G08_1.log | 423 +++++++++++++++ .../plan_cloud_G08_1.log | 309 +++++++++++ 5 files changed, 1125 insertions(+), 458 deletions(-) create mode 100644 agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log create mode 100644 agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log diff --git a/agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md b/agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md index 132c0442..94390e12 100644 --- a/agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md +++ b/agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md @@ -1,388 +1,313 @@ - + # Code Review Reference - REVIEW_API -**Date:** 2026-08-09 KST -**Task:** Repair the single-request template admission contract, missing regression evidence, and current documentation after official review failure. +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `Implementation Checklist`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> Execute the plan's selected root cause, scope, files, and dependency decisions as written. Do not choose another owner, narrow/expand the write boundary, or replace a fix with another verification attempt. +> If implementation is blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence fields. +> Do not ask the user directly, present choices, call user-input tools, create control-plane stop files, or classify the next state. +> Finalization (`Code Review Result`, log rename, `complete.log`, archive moves, `Review-Only Checklist`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. -## Review Agent Instructions +## Overview -- Review only the paired `PLAN-cloud-G08.md` scope and repository changes implementing it. -- Re-run verification independently; implementation-supplied output is evidence input, not the verdict. -- Only the review agent may append `Code Review Result`, archive the active pair, write `complete.log`, or move the task directory. -- On `WARN` or `FAIL`, follow the review routing policy and do not write `complete.log`. +date=2026-08-09 KST +task=single_request_plan_review_templates, plan=2, tag=REVIEW_API ## Archive Evidence Snapshot -- Prior task: `single_request_plan_review_templates`, plan `0`, tag `API` (active origin). -- Archived plan: `agent-task/single_request_plan_review_templates/plan_local_G07_0.log`. -- Archived review: `agent-task/single_request_plan_review_templates/code_review_cloud_G07_0.log`. -- Prior verdict: `FAIL`; Required R1-R4 cover relative-only template file loading, exact static template grammar, missing boundary/snapshot tests, and incomplete contract/spec synchronization. -- Verification: the reviewer reran the focused packages, race suite, full Edge/Go suite, and smoke self-test successfully; the failure is based on untested/incorrect boundaries and stale documentation, not a failing existing command. +- Prior task: `single_request_plan_review_templates`, plan `1`, tag `REVIEW_API`. +- Archived plan: `agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log`. +- Archived review: `agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log`. +- Prior verdict: `FAIL`; Required R1 identifies that plain string fields erase the distinction between omission and explicit empty/whitespace values before `loadTemplateFile` runs. +- Fresh reviewer regression: `go test -count=1 ./packages/go/config -run TestReviewConfiguredWhitespaceTemplatePathFailsClosed` failed because configured whitespace `plan_file` was admitted as omission. The temporary reviewer-only test was removed after reproduction. +- Existing focused, race, full Edge/Go, smoke self-test, and Darwin/arm64 changed-package suites passed. Live API qualification remains externally blocked because the approved remote operator config files and complete `IOP_SINGLE_REQUEST_SMOKE_*` inputs are absent. - Roadmap carryover: none; this is a non-milestone task. +## For the Review Agent + +> **[REVIEW AGENT ONLY]** The finalization steps below are review-agent only. Implementing agents must not execute this section. + +Compare implementation of each item against source files and verify that output in `Verification Results` matches code. +Review completion means the following steps are finished: + +1. Append verdict and `review_rework_count` / `evidence_integrity_failure` routing signals. +2. Archive `CODE_REVIEW-cloud-G08.md` → `code_review_cloud_G08_2.log` and `PLAN-cloud-G08.md` → `plan_cloud_G08_2.log`. +3. If PASS, write `complete.log` and move active task directory to `agent-task/archive/YYYY/MM/single_request_plan_review_templates/`. If WARN/FAIL, fully write the next filesystem state required by the code-review skill. +4. If PASS and task group is `m-`, preserve the first-line `milestone-task` metadata in `complete.log` and report it for the runtime aggregation event. Roadmap state evaluation belongs to `sync-milestone-workstate`. +5. Check applicable `Review-Only Checklist` items at the final `.log` location before reporting. + +--- + ## Implementation Item Completion -- [x] REVIEW_API-1 — Close Template Admission Boundaries -- [x] REVIEW_API-2 — Prove Freeze, Refresh, and Render Semantics -- [x] REVIEW_API-3 — Synchronize Current Contracts and Specs -- [x] REVIEW_API-4 — Produce Trustworthy Verification Evidence +| Item | Status | +|------|---------| +| REVIEW_API-1 — Preserve Configured Template Path Presence | [x] | +| REVIEW_API-2 — Close Presence and Refresh Regression Gaps | [x] | +| REVIEW_API-3 — Produce Trustworthy Local and Remote Evidence | [x] | ## Implementation Checklist -- [x] [REVIEW_API-1] Enforce relative-only template loading and exact Plan/Review grammar with boundary regressions. -- [x] [REVIEW_API-2] Add admission, clone/workspace revalidation, preset refresh, and custom Review artifact snapshot tests. -- [x] [REVIEW_API-3] Synchronize current contracts/specs with direct PlanMD, frozen templates, templated internal Review, and unchanged caller output. -- [x] [REVIEW_API-4] Run fresh focused/full/local and remote-profile verification, recording the exact external blocker if the approved SOPS identity remains unavailable. -- [x] Fill implementation-owned sections in `CODE_REVIEW-cloud-G08.md` with actual implementation notes and verification output. +- [x] [REVIEW_API-1] Preserve omission separately from configured template path values, reject configured empty/whitespace values before filesystem access, and deep-clone the optional state. +- [x] [REVIEW_API-2] Add Plan/Review presence-boundary and clone regressions, update refresh fixtures, and retain omitted fallback, relative success, and digest-only refresh evidence. +- [x] [REVIEW_API-3] Run fresh focused, race, full, smoke-self-test, documentation, and approved remote-profile verification; record the exact live-profile blocker if operator assets remain absent. +- [x] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output. ## Review-Only Checklist -- [ ] Review verdict and routing signals are appended. -- [ ] Finding severities, verdict, and routing are mutually consistent. -- [ ] On PASS only: `complete.log` is written with exact header, verdict, review path, and summary. -- [ ] On PASS only: task directory is moved under `agent-task/archive/`. -- [ ] Active review is archived as `agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log`. -- [ ] Active plan is archived as `agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log` when closure policy requires it. -- [ ] `.gitignore` admits generated task Markdown/log artifacts. -- [ ] On WARN/FAIL: the required next active state is materialized and `complete.log` is absent. +> **[REVIEW AGENT ONLY]** This checklist is used only by the review agent. +> Implementing agents must not modify or check this section. + +- [ ] Append one verdict of `PASS`, `WARN`, or `FAIL` and verified `review_rework_count`, `evidence_integrity_failure` to `Code Review Result`. +- [ ] Verify that verdict, `Dimension Assessment`, and Required/Suggested/Nit classifications match. +- [ ] Archive active `CODE_REVIEW-*-G??.md` to `code_review_cloud_G08_2.log`. +- [ ] Archive active `PLAN-*-G??.md` to `plan_cloud_G08_2.log`. +- [ ] Verify that the Agent-Ops managed block in `.gitignore` unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores `agent-roadmap/current.md`. +- [ ] If PASS, write `complete.log` based on `agent-ops/skills/common/code-review/templates/complete-log-template.md` and leave no active `.md` files. +- [ ] If PASS, move active task directory `agent-task/single_request_plan_review_templates/` to `agent-task/archive/YYYY/MM/single_request_plan_review_templates/` and update this checklist at the final archive path. +- [ ] If PASS and task group is `m-`, preserve and report `milestone-task` metadata for runtime aggregation, without modifying roadmap or directly calling `update-roadmap`. +- [ ] If PASS for split work, remove empty active parent `agent-task/single_request_plan_review_templates/` or verify it was kept due to remaining siblings/files. +- [ ] If WARN/FAIL, write the next filesystem state matching code-review verdict and do not write `complete.log`. ## Deviations from Plan -1. **Branch name.** The plan's Final Verification asserts `feature/single_request_plan_review_templates` (underscores). The actual branch — local and on the approved remote checkout — is `feature/single-request-plan-review-templates` (hyphens). Every branch-scoped command was run against the real hyphenated branch. No branch was created or renamed. -2. **`utf8` validation was added, not retained.** REVIEW_API-1 says to "retain existing regular-file, size, UTF-8, and fallback behavior". `loadTemplateFile` had no UTF-8 check; there was nothing to retain. A `utf8.Valid` rejection was added so the loader boundary the plan describes is real, and it is covered by `TestLoadEdgeSingleRequestTemplates/non-UTF-8_template_file_fails_closed`. -3. **Grammar errors no longer echo template text.** The old validator returned `unknown placeholder %q` with the offending token from the template body. The plan's REVIEW_API-1 Verification requires rejection "without exposing file content in errors", so unknown-placeholder and delimiter-residue errors now name the violation category only. Documented required lines and documented placeholder names (compile-time constants, not file content) are still echoed. -4. **`..` traversal was not added to the loader.** The plan scopes R1 to rejecting empty and absolute values. A relative path containing `..` still resolves through `filepath.Join`. This is unchanged behavior, in scope for a follow-up if the operator-config threat model warrants path containment; it was not silently broadened here. -5. **Remote `make` variables in the plan do not exist.** The plan's remote command passes `EDGE_CONFIG=` / `SOPS_CONFIG=`. The smoke targets in `Makefile:206-236` read `IOP_SINGLE_REQUEST_SMOKE_*` variables only, so those two assignments are inert and the preflight runs with empty arguments regardless of the config files. Recorded here because it changes how the remote blocker below must be resolved. -6. **Remote evidence required two commits.** The plan asks for a clean tree and a pushed commit before the remote rebuild, and for the remote output to be pasted into this file. Those cannot both hold in one commit. The implementation commit was pushed first, the remote profile was exercised against exactly that commit, and this file's remote section was then updated and committed. Both hashes are recorded below. -7. **`WORK_LOG.md` is dispatcher-owned.** It is admitted by `.gitignore` (`agent-task/**/*.md`) and was committed with the task directory, but the dispatcher appends its `FINISH` row after this agent exits, so `git status --short` cannot stay empty past that point. The clean-tree assertion below is true as of the recorded implementation commit. +- The config-refresh test pointer helper is named `templatePath` instead of the `stringPointer` name used in the plan's illustrative code block. The plan required "a local test pointer helper" without fixing the identifier; `templatePath` states what the pointer means at the two fixture call sites. Behavior, scope, and file set are unchanged. +- No verification command was added, removed, or altered. Every command in `Final Verification` was executed as written. ## Key Design Decisions -**Relative-only template loading (`packages/go/config/load.go:721-762`).** The parameter was renamed from `relOrAbsPath` to `relativePath`, and empty and absolute values are rejected before `os.Lstat`/`os.Open`, so an absolute path never reaches the filesystem at all. `filepath.Join(baseDir, target)` is now the only resolution path, which is what `agent-contract/inner/edge-config-runtime-refresh.md` already specified. Existing `Lstat`-based non-regular-file rejection (which also rejects symlinks), the `io.LimitReader(f, 8193)` size boundary, and independent per-file default fallback in `resolveSingleRequestTemplates` are unchanged. - -**Exact standalone-line grammar (`packages/go/singlerequesttemplate/template.go:63-104`).** `exactLineOffsets` compares maximal `\n`-delimited segments byte for byte and reports both the first offset and the occurrence count; `requireExactLines` demands exactly one occurrence of each required line. This is what closes the reported defect: `### Plan`, `# Plan Mismatch`, `Result: PASS`, and `NOTPASS` all previously satisfied the substring checks and are now rejected. Offsets feed the same structural ordering assertions as before, so no ordering semantics changed. - -**Closed placeholder inventory (`packages/go/singlerequesttemplate/template.go:106-128`).** `requirePlaceholderInventory` removes exactly one occurrence of each documented placeholder and then rejects any surviving `{{` or `}}`. Removing first is what makes the check closed rather than a denylist: it catches unknown placeholders (`{{severity}}`), unbalanced delimiters (`{{goal}}}}`), and nesting (`{{{{goal}}}}`), which the old `\{\{[^}]*\}\}` scan could not. - -**Templates are strings, so freezing is structural.** `SingleRequestTemplateBinding` holds two immutable Go strings, so the "frozen" property follows from the type rather than from a defensive copy. That is exactly why the plan's R3 gap mattered: the invariant was true but unproven and unprotected. The new tests assert it explicitly at admission, through `Clone`, through `cloneValidatedSingleRequestBinding`, and across a simulated refresh, so a future change to a mutable representation fails loudly. - -**Validation is re-run at revalidation, not just admission.** `cloneValidatedSingleRequestBinding` routes back through `NewSingleRequestBindingWithTemplates`, so a template tampered with after admission fails workspace revalidation instead of being cloned forward. `TestSingleRequestBindingTemplateSnapshot/an_invalid_template_cannot_survive_workspace_revalidation` pins that. - -**Review template selects the artifact, never the caller response.** `renderSingleRequestReview` builds the internal artifact from `binding.Templates.Review` while `singleRequestReviewResult.Output` stays the trimmed `decision.output`. `TestSingleRequestReviewStageCustomTemplateSnapshot` renders the same decision through both the custom and the built-in template, asserts two different exact artifacts, and asserts one identical caller-visible output — which is the property the outer contract now states. - -**No production behavior was changed for REVIEW_API-2.** Every file under that item is a `_test.go` file. The three regressions were mutation-checked against the pre-fix behavior (see Verification Results) rather than assumed to be meaningful. - -**Documentation scope.** The inner contract `agent-contract/inner/edge-config-runtime-refresh.md` already described relative-only loading, the 8192-byte cap, digest-only refresh evidence, and frozen effective templates; the implementation converged to it and it was left unmodified, per the plan's instruction not to broaden it. The outer contract, the two runtime specs, and the input spec were the surfaces that contradicted the shipped behavior. +- `PlanFile` and `ReviewFile` became `*string` with the existing `mapstructure:"plan_file"` / `yaml:"plan_file,omitempty"` names. `execution_presets` decodes through the strict `ErrorUnused` mapstructure decoder in `LoadEdge`, which maps an absent key to a nil pointer and a present key — including `""` and `" "` — to a non-nil cell. `omitempty` on a pointer still omits an unset path on marshal, so no config file, example, or contract text needed to change. +- `resolveSingleRequestTemplates` now branches on `sr.Templates.PlanFile == nil` / `.ReviewFile == nil` instead of `strings.TrimSpace(...) == ""`. Omission is the only default-fallback signal; every configured value is dereferenced into `loadTemplateFile`, which trims and rejects empty/whitespace before `filepath.IsAbs`, `os.Lstat`, or `os.Open`. The previously dead empty check at `packages/go/config/load.go:732-734` is now the live rejection path for decoded configuration, and the new regressions assert the error carries the `single_request.templates.plan_file` / `.review_file` context and never the resolved directory. +- `ExecutionSingleRequestTemplates` gained its own `Clone` plus a `cloneStringPointer` helper, and `ExecutionSingleRequestPolicy.Clone` now calls `p.Templates.Clone()` instead of copying the struct by value. Without this, introducing pointers would have silently turned the existing snapshot copy into an alias. `EffectivePlan` / `EffectiveReview` stay plain value copies, so the frozen effective pair is unchanged. +- The four presence-boundary cases reuse the existing `validPresetYAML(planFile, reviewFile)` helper by passing quoted YAML scalars (`""` and `" "`) rather than changing the helper's omission contract. The helper keeps treating a Go empty string as "omit the key", which is exactly the distinction under test, so the omitted-fallback, relative-success, absolute-rejection, size, file-kind, UTF-8, and grammar cases stay byte-identical. +- Existing fallback and relative-success subtests were strengthened with `nil` versus non-nil path assertions so a future regression that re-collapses presence into a plain string fails on the successful paths too, not only on the new rejection paths. +- `reflect.DeepEqual` in `configrefresh.appendSingleRequestChanged` follows pointers, so two independently allocated cells holding the same path stay equal. The refresh classifier therefore still reports exactly one change for a content-only template edit, and `TestClassifySingleRequestTemplateContentChange` keeps proving that neither configured paths nor raw template bodies enter the change summary. +- Contracts and specs were left untouched: `agent-spec/runtime/provider-pool-config-refresh.md` already requires non-empty relative paths rejected before filesystem access, so the code converged to the documents rather than the reverse. ## Reviewer Checkpoints -- Confirm absolute `plan_file` and `review_file` values are rejected before filesystem access, while independent fallback and exact size/file-kind boundaries remain correct. -- Confirm required Plan/Review headings and Review `PASS` are exact lines and the admitted placeholder inventory is closed. -- Confirm binding snapshot, clone/workspace revalidation, preset refresh isolation, and custom Review artifact tests exist and assert caller-output invariance. -- Confirm the outer contract and current specs consistently describe direct PlanMD, frozen effective templates, templated internal Review artifacts, and unchanged caller-visible I/O. +- Confirm omission and explicit empty/whitespace values remain distinguishable after Viper/mapstructure decode for both `plan_file` and `review_file`. +- Confirm nil alone selects the built-in default and every non-nil path reaches trimmed empty/absolute rejection before `Lstat` or `Open`. +- Confirm optional path cells are deep-cloned while effective template strings remain unchanged. +- Confirm refresh classification still observes effective-content changes while exposing neither configured paths nor raw template bodies. +- Confirm current contracts/specs remain unchanged and accurately match the repaired code. +- Confirm all local evidence is fresh and the approved remote checkout is synchronized to the exact tested source commit before Darwin/arm64 evidence is accepted. +- Confirm missing remote operator assets are recorded as an external block, never as a live-smoke pass. ## Verification Results -### REVIEW_API-1 — Template and Config Boundaries +### REVIEW_API-1 — Presence-aware loader and clone boundary ```bash -test -z "$(gofmt -l packages/go/singlerequesttemplate/template.go packages/go/singlerequesttemplate/template_test.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/service/single_request_types_test.go apps/edge/internal/openai/single_request_preset_binding_test.go apps/edge/internal/openai/single_request_review_stage_test.go)" -go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config +go test -count=1 ./packages/go/config -run 'TestLoadEdgeSingleRequestTemplates|TestExecutionSingleRequestTemplatePathPresenceClone' ``` -```text -$ test -z "$(gofmt -l packages/go/singlerequesttemplate/template.go packages/go/singlerequesttemplate/template_test.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/service/single_request_types_test.go apps/edge/internal/openai/single_request_preset_binding_test.go apps/edge/internal/openai/single_request_review_stage_test.go)" -exit=0 +Tested source commit: `6f141b9121af505e01730fe2a13244d986060b27` (branch `feature/single-request-plan-review-templates`). -$ go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config -ok iop/packages/go/singlerequesttemplate 0.005s -ok iop/packages/go/config 0.144s +```text +$ go test -count=1 ./packages/go/config -run 'TestLoadEdgeSingleRequestTemplates|TestExecutionSingleRequestTemplatePathPresenceClone' +ok iop/packages/go/config 0.030s exit=0 ``` -New boundary subtests actually executed (`-v`, abridged to the added cases): +Executed new/changed subtest names, from the `-v` run of the same selector: ```text -=== RUN TestLoadEdgeSingleRequestTemplates/absolute_plan_file_rejected_before_filesystem_access -=== RUN TestLoadEdgeSingleRequestTemplates/absolute_review_file_rejected_before_filesystem_access -=== RUN TestLoadEdgeSingleRequestTemplates/plan_file_configured_and_review_file_falls_back -=== RUN TestLoadEdgeSingleRequestTemplates/review_file_configured_and_plan_file_falls_back -=== RUN TestLoadEdgeSingleRequestTemplates/exact_8192_byte_template_file_accepted -=== RUN TestLoadEdgeSingleRequestTemplates/symlinked_template_file_fails_closed -=== RUN TestLoadEdgeSingleRequestTemplates/directory_template_path_fails_closed -=== RUN TestLoadEdgeSingleRequestTemplates/unreadable_template_file_fails_closed -=== RUN TestLoadEdgeSingleRequestTemplates/non-UTF-8_template_file_fails_closed -=== RUN TestLoadEdgeSingleRequestTemplates/invalid_grammar_matrix_fails_closed - (11 subcases: plan missing/decorated heading, unknown placeholder, delimiter residue, - duplicate placeholder; review missing PASS, NOTPASS, decorated heading, - missing placeholder, unknown placeholder, wrong order) ---- PASS: TestLoadEdgeSingleRequestTemplates (0.02s) +=== RUN TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed +=== RUN TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/empty_plan_file +=== RUN TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/whitespace_plan_file +=== RUN TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/empty_review_file +=== RUN TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/whitespace_review_file + --- PASS: TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed (0.00s) + --- PASS: TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/empty_plan_file (0.00s) + --- PASS: TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/whitespace_plan_file (0.00s) + --- PASS: TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/empty_review_file (0.00s) + --- PASS: TestLoadEdgeSingleRequestTemplates/explicitly_configured_empty_template_path_fails_closed/whitespace_review_file (0.00s) +=== RUN TestExecutionSingleRequestTemplatePathPresenceClone +--- PASS: TestExecutionSingleRequestTemplatePathPresenceClone (0.00s) ``` -Mutation check — the three grammar/path fixes were temporarily reverted in place (`filepath.IsAbs` fallthrough restored in `loadTemplateFile`; `requireExactLines` reverted to `strings.Index`/`strings.Count`) and the same suites re-run, proving the new cases fail against the pre-fix behavior rather than passing vacuously. The files were restored byte-for-byte afterwards and re-verified green: +The unchanged boundary cases in the same test ran and passed in the same execution: omitted fallback, config-relative resolution, missing file, oversized 8193 bytes, invalid content, absolute `plan_file`/`review_file` rejection, both independent-fallback cases, the exact 8192-byte acceptance, symlink, directory, unreadable, non-UTF-8, and all eleven invalid-grammar cases. -```text ---- FAIL: TestLoadEdgeSingleRequestTemplates/absolute_plan_file_rejected_before_filesystem_access - expected error for absolute plan_file "/tmp/.../plan.md" ---- FAIL: TestLoadEdgeSingleRequestTemplates/absolute_review_file_rejected_before_filesystem_access - expected error for absolute review_file "/tmp/.../review.md" ---- FAIL: TestValidatePlanTemplate/decorated_heading_###_Plan err = , wantErr true ---- FAIL: TestValidatePlanTemplate/heading_line_carries_trailing_text err = , wantErr true ---- FAIL: TestValidatePlanTemplate/heading_embedded_inside_a_prose_line err = , wantErr true ---- FAIL: TestValidatePlanTemplate/duplicate_required_heading err = , wantErr true ---- FAIL: TestValidateReviewTemplate/NOTPASS_does_not_satisfy_the_PASS_result_line err = , wantErr true ---- FAIL: TestValidateReviewTemplate/PASS_embedded_in_a_prose_line err = , wantErr true ---- FAIL: TestValidateReviewTemplate/decorated_heading_###_Review err = , wantErr true ---- FAIL: TestValidateReviewTemplate/duplicate_PASS_result_line err = , wantErr true -FAIL iop/packages/go/config 0.014s -FAIL iop/packages/go/singlerequesttemplate 0.010s -``` +Each of the four new cases asserts three things and all three held: the error carries its own `single_request.templates.plan_file` or `single_request.templates.review_file` context, the message is `template path must not be empty`, and the message never contains the config directory — proving the rejection happened before `os.Lstat`/`os.Open`. The clone regression proves the cloned `PlanFile`/`ReviewFile` cells are distinct pointers, that mutating them leaves the original paths and both effective templates untouched, and that an omitted (nil) path clones as omission rather than as a configured empty value. -### REVIEW_API-2 — Binding, Refresh, Review Rendering, and Race Coverage +### REVIEW_API-2 — Focused and race regressions ```bash -go test -count=1 ./apps/edge/internal/service -run 'TestSingleRequestBinding' -go test -count=1 ./apps/edge/internal/openai -run 'TestSingleRequest(PresetBinding|ReviewStage)' -go test -race -count=1 ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/configrefresh ./packages/go/config ./packages/go/singlerequesttemplate +go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +go test -race -count=1 ./packages/go/config ./apps/edge/internal/configrefresh ``` ```text -$ go test -count=1 ./apps/edge/internal/service -run 'TestSingleRequestBinding' -ok iop/apps/edge/internal/service 0.026s +$ go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +ok iop/packages/go/config 0.165s +ok iop/apps/edge/internal/configrefresh 0.044s exit=0 -$ go test -count=1 ./apps/edge/internal/openai -run 'TestSingleRequest(PresetBinding|ReviewStage)' -ok iop/apps/edge/internal/openai 0.044s -exit=0 - -$ go test -race -count=1 ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/configrefresh ./packages/go/config ./packages/go/singlerequesttemplate -ok iop/apps/edge/internal/openai 12.349s -ok iop/apps/edge/internal/service 9.384s -ok iop/apps/edge/internal/configrefresh 1.210s -ok iop/packages/go/config 1.893s -ok iop/packages/go/singlerequesttemplate 1.037s +$ go test -race -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +ok iop/packages/go/config 1.855s +ok iop/apps/edge/internal/configrefresh 1.151s exit=0 ``` -The three prescribed regressions exist and executed (`-v`, added cases only): +Refresh redaction result, from the `-v` run of the adapted fixtures: ```text -=== RUN TestSingleRequestBindingTemplateSnapshot -=== RUN TestSingleRequestBindingTemplateSnapshot/admitted_binding_carries_the_exact_effective_pair -=== RUN TestSingleRequestBindingTemplateSnapshot/template-less_admission_falls_back_to_the_built-in_defaults -=== RUN TestSingleRequestBindingTemplateSnapshot/clone_preserves_the_frozen_pair -=== RUN TestSingleRequestBindingTemplateSnapshot/workspace_revalidation_preserves_the_frozen_pair -=== RUN TestSingleRequestBindingTemplateSnapshot/invalid_effective_templates_are_rejected_at_admission -=== RUN TestSingleRequestBindingTemplateSnapshot/an_invalid_template_cannot_survive_workspace_revalidation ---- PASS: TestSingleRequestBindingTemplateSnapshot (0.00s) - -=== RUN TestSingleRequestPresetBindingTemplateRefreshIsolation ---- PASS: TestSingleRequestPresetBindingTemplateRefreshIsolation (0.00s) -=== RUN TestSingleRequestPresetBindingTemplateFallback -=== RUN TestSingleRequestPresetBindingTemplateFallback/both_templates_fall_back -=== RUN TestSingleRequestPresetBindingTemplateFallback/plan_configured_and_review_falls_back -=== RUN TestSingleRequestPresetBindingTemplateFallback/review_configured_and_plan_falls_back -=== RUN TestSingleRequestPresetBindingTemplateFallback/invalid_effective_template_fails_admission_closed ---- PASS: TestSingleRequestPresetBindingTemplateFallback (0.00s) -=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot -=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/custom_template_renders_the_exact_internal_artifact -=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/default_template_renders_the_exact_internal_artifact -=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/stage_run_writes_the_custom_artifact_and_preserves_caller_output -=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/an_invalid_effective_template_fails_the_render_closed ---- PASS: TestSingleRequestReviewStageCustomTemplateSnapshot (0.00s) -ok iop/apps/edge/internal/openai 0.038s +=== RUN TestClassifySingleRequestTemplateContentChange +--- PASS: TestClassifySingleRequestTemplateContentChange (0.00s) ``` -Assertions are exact rather than substring: the refresh test compares the whole admitted template pair before and after mutating `preset.SingleRequest.Templates.*` and compiles a second binding to show the refreshed pair reaches only the new admission; the Review test compares the full rendered artifact byte string for both the custom and the built-in template while asserting one identical caller-visible `result.Output`. +The two fixtures now build `PlanFile`/`ReviewFile` through the local `templatePath` helper, so `current` and `candidate` hold the same paths in separately allocated cells. `reflect.DeepEqual` still reports equality for those fields, the classifier still emits exactly one `execution_presets["preset-templates"].single_request` change of class `applied` driven by the effective-content edit, and the assertions that `Previous`/`Next` contain neither `templates/plan.md` nor the raw `Plan template v1`/`v2` bodies still hold. -### REVIEW_API-3 — Full Suite and Documentation Guard +### REVIEW_API-3 — Full local verification ```bash +test -z "$(gofmt -l packages/go/config/execution_preset_types.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/configrefresh/execution_preset_classify_test.go)" +git diff --check +go test -count=1 ./packages/go/config -run 'TestLoadEdgeSingleRequestTemplates|TestExecutionSingleRequestTemplatePathPresenceClone' +go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +go test -race -count=1 ./packages/go/config ./apps/edge/internal/configrefresh go test -count=1 ./apps/edge/... ./packages/go/... make test-single-request-claude-smoke-self-test -if rg --sort path -n 'Edge-owned OpenAI `json_schema` response format|strict small plan/verification JSON|stage-owned JSON Schema override protection' agent-spec/runtime/edge-node-execution.md; then exit 1; fi +rg --sort path -n 'Absolute and empty paths are rejected before any filesystem access|plan_file.*review_file.*non-empty paths' agent-spec/runtime/provider-pool-config-refresh.md ``` +All commands below were run fresh from the repository root at tested source commit `6f141b9121af505e01730fe2a13244d986060b27`. Later edits to this review file are evidence-only and did not touch source or tests. + ```text +=== tested commit: 6f141b9121af505e01730fe2a13244d986060b27 === +$ test -z "$(gofmt -l packages/go/config/execution_preset_types.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/configrefresh/execution_preset_classify_test.go)" +exit=0 +$ git diff --check +exit=0 +$ go test -count=1 ./packages/go/config -run 'TestLoadEdgeSingleRequestTemplates|TestExecutionSingleRequestTemplatePathPresenceClone' +ok iop/packages/go/config 0.030s +exit=0 +$ go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +ok iop/packages/go/config 0.165s +ok iop/apps/edge/internal/configrefresh 0.044s +exit=0 +$ go test -race -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +ok iop/packages/go/config 1.855s +ok iop/apps/edge/internal/configrefresh 1.151s +exit=0 $ go test -count=1 ./apps/edge/... ./packages/go/... -ok iop/apps/edge/cmd/edge 0.237s -ok iop/apps/edge/internal/authprojection 0.055s -ok iop/apps/edge/internal/bootstrap 0.493s -ok iop/apps/edge/internal/configrefresh 0.117s -ok iop/apps/edge/internal/controlplane 6.676s -ok iop/apps/edge/internal/edgecmd 0.135s -ok iop/apps/edge/internal/edgevalidate 0.104s -ok iop/apps/edge/internal/events 0.043s -ok iop/apps/edge/internal/input 0.067s -ok iop/apps/edge/internal/input/a2a 0.058s -ok iop/apps/edge/internal/node 0.046s -ok iop/apps/edge/internal/openai 8.361s -ok iop/apps/edge/internal/opsconsole 0.062s -ok iop/apps/edge/internal/service 8.221s -ok iop/apps/edge/internal/transport 4.810s -ok iop/packages/go/audit 0.010s -ok iop/packages/go/auth 10.035s -ok iop/packages/go/config 0.161s -ok iop/packages/go/credentiallease 0.038s +ok iop/apps/edge/cmd/edge 0.211s +ok iop/apps/edge/internal/authprojection 0.063s +ok iop/apps/edge/internal/bootstrap 0.497s +ok iop/apps/edge/internal/configrefresh 0.108s +ok iop/apps/edge/internal/controlplane 6.615s +ok iop/apps/edge/internal/edgecmd 0.076s +ok iop/apps/edge/internal/edgevalidate 0.107s +ok iop/apps/edge/internal/events 0.092s +ok iop/apps/edge/internal/input 0.123s +ok iop/apps/edge/internal/input/a2a 0.052s +ok iop/apps/edge/internal/node 0.042s +ok iop/apps/edge/internal/openai 8.405s +ok iop/apps/edge/internal/opsconsole 0.063s +ok iop/apps/edge/internal/service 8.194s +ok iop/apps/edge/internal/transport 4.806s +ok iop/packages/go/audit 0.012s +ok iop/packages/go/auth 10.038s +ok iop/packages/go/config 0.164s +ok iop/packages/go/credentiallease 0.046s ? iop/packages/go/events [no test files] -ok iop/packages/go/execution 0.017s +ok iop/packages/go/execution 0.013s ok iop/packages/go/hostsetup 0.011s ? iop/packages/go/jobs [no test files] ? iop/packages/go/metadata [no test files] -ok iop/packages/go/observability 0.024s +ok iop/packages/go/observability 0.037s ? iop/packages/go/policy [no test files] -ok iop/packages/go/singlerequesttemplate 0.007s -ok iop/packages/go/streamgate 0.884s +ok iop/packages/go/singlerequesttemplate 0.013s +ok iop/packages/go/streamgate 0.886s ? iop/packages/go/version [no test files] -ok iop/packages/go/workspaceprotocol 0.016s +ok iop/packages/go/workspaceprotocol 0.025s exit=0 - $ make test-single-request-claude-smoke-self-test ./scripts/e2e-single-request-claude.sh --self-test [single-request-claude-smoke] self-test passed: exact Claude base-route coverage, structured observation admission, child-only zero retry, authenticated model admission, closed failure classification, model/Edge/Node/runtime binding, zero-child preflight, derived verification, redaction, cleanup, signal handling, and atomic publication exit=0 - -$ if rg --sort path -n 'Edge-owned OpenAI `json_schema` response format|strict small plan/verification JSON|stage-owned JSON Schema override protection' agent-spec/runtime/edge-node-execution.md; then exit 1; fi -(rg produced no matches; the guard did not trip) +$ rg --sort path -n 'Absolute and empty paths are rejected before any filesystem access|plan_file.*review_file.*non-empty paths' agent-spec/runtime/provider-pool-config-refresh.md +134:| single-request effective templates | Optional `templates` (`plan_file`/`review_file`) load bounded Markdown relative to the directory containing `edge.yaml` only. Absolute and empty paths are rejected before any filesystem access; non-regular files, sizes over 8192 bytes, non-UTF-8 content, and invalid template grammar fail closed at load. Each file falls back to its built-in default independently, and refresh diff evidence reports SHA-256 digests only, never template paths or contents. | +182:- `execution_presets[].single_request.templates` is optional. `plan_file` and `review_file` must be non-empty paths relative to the directory containing `edge.yaml`; absolute and empty values are rejected before the loader opens anything. Each file is loaded as a regular file of at most 8192 valid UTF-8 bytes and must satisfy the documented template grammar; an omitted file falls back to its built-in default independently of the other. Refresh diff evidence reports only SHA-256 digests of the effective templates. Admission freezes the effective pair into the request binding, so a refreshed template reaches only requests admitted after the refresh. exit=0 ``` -Documentation surfaces updated for REVIEW_API-3: +The documentation guard printed both current contract statements unchanged; the repaired loader now matches them instead of contradicting them. -| File | Change | -|---|---| -| `agent-contract/outer/anthropic-compatible-api.md` | Added the effective-template subsection to `Marked preset: single-request admission` (Edge-owned internal stage input, unchanged caller request/response schema, no caller selection, no path/content/digest exposure, admission freeze); added the five single-request/template source paths to 계약 메타; added the caller-boundary 금지 사항 entry. | -| `agent-contract/index.md` | `iop.anthropic-compatible-api` 읽는 조건 and 원본 경로 now name the marked-preset template boundary and its source files. | -| `agent-spec/runtime/edge-node-execution.md` | Rewrote the stale Plan `json_schema` passage to frozen-template prompting and direct PlanMD parsing; added the Review artifact-rendering boundary; added the `single-request effective templates` feature row; rewrote the two superseded 변경 기록 entries and added the 2026-08-09 entry; added the template/config source_evidence and the three new verification commands. | -| `agent-spec/runtime/provider-pool-config-refresh.md` | Split templates out of the `fixed single-request policy` row into dedicated `single-request effective templates` and `effective-template admission freeze` rows; expanded the 범위 bullet with relative-only/pre-access rejection, per-file fallback, and refresh isolation; added source_evidence and the 2026-08-09 변경 기록 entry. | -| `agent-spec/input/openai-compatible-surface.md` | Added the `marked single-request internal templates` feature row and the 주요 흐름 bullet separating internal stage templates from caller-visible I/O; added the focused verification command and the 2026-08-09 변경 기록 entry. | -| `agent-spec/index.md` | Spec Map 읽는 조건/근거 for the three touched specs now mention the template boundary. | - -`agent-contract/inner/edge-config-runtime-refresh.md` was deliberately not modified: it already specifies `edge.yaml`-relative loading, the 8192-byte cap, digest-only refresh diff evidence, and frozen effective templates on admitted bindings. The implementation converged to it. - -### REVIEW_API-4 — Approved Remote Profile +### REVIEW_API-3 — Approved Darwin/arm64 profile and external gate ```bash -test "$(git branch --show-current)" = "feature/single_request_plan_review_templates" -test -z "$(git status --short)" -git push origin feature/single_request_plan_review_templates -ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git fetch origin feature/single_request_plan_review_templates && git switch feature/single_request_plan_review_templates && git reset --hard origin/feature/single_request_plan_review_templates && git clean -fd && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single_request_plan_review_templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && claude --version && sops --version && test -f dev-openai-toki.edge.yaml && test -f dev-openai-toki.sops.yaml' -ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && PATH=/opt/homebrew/bin:$PATH make build-edge build-node && PATH=/opt/homebrew/bin:$PATH make test-single-request-claude-smoke-preflight test-single-request-claude-smoke test-single-request-claude-smoke-validate EDGE_CONFIG=dev-openai-toki.edge.yaml SOPS_CONFIG=dev-openai-toki.sops.yaml' +test "$(git branch --show-current)" = "feature/single-request-plan-review-templates" +git rev-parse HEAD +git push origin feature/single-request-plan-review-templates +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && export PATH=/opt/homebrew/bin:$PATH && git fetch origin feature/single-request-plan-review-templates && git switch feature/single-request-plan-review-templates && git reset --hard origin/feature/single-request-plan-review-templates && test -z "$(git status --short)" && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single-request-plan-review-templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && go version && claude --version && sops --version && make build-edge build-node && go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh && make test-single-request-claude-smoke-self-test' +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && for file in dev-openai-toki.edge.yaml dev-openai-toki.sops.yaml; do if test -f "$file"; then echo "PRESENT $file"; else echo "MISSING $file"; fi; done && test -r /Users/toki/.config/sops/age/keys.txt && echo "PRESENT age identity"' ``` -**Tested commit: `31fada5d08d6d93076bd0d4a7522074fb8b8d960`** — identical locally, on `origin`, and in the remote checkout. Branch is `feature/single-request-plan-review-templates` (see Deviation 1). `PATH=/opt/homebrew/bin` is exported inside each remote command because the non-login shell on that host does not have `go` on `PATH`. - -**Local push preconditions** +Source identity — local, origin, and remote all resolve to the same commit: ```text $ test "$(git branch --show-current)" = "feature/single-request-plan-review-templates" -exit=0 -$ test -z "$(git status --short)" -exit=0 +branch ok +$ git rev-parse HEAD +6f141b9121af505e01730fe2a13244d986060b27 $ git push origin feature/single-request-plan-review-templates To https://git.toki-labs.com/toki/iop.git - ee9204a5..31fada5d feature/single-request-plan-review-templates -> feature/single-request-plan-review-templates + 702e62aa..6f141b91 feature/single-request-plan-review-templates -> feature/single-request-plan-review-templates exit=0 -local HEAD = 31fada5d08d6d93076bd0d4a7522074fb8b8d960 -origin HEAD = 31fada5d08d6d93076bd0d4a7522074fb8b8d960 ``` -**Remote checkout sync and profile identity — PASS** +Approved Darwin/arm64 checkout, synchronized to that exact commit and rebuilt: ```text -$ ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git fetch ... && git switch ... && git reset --hard ... && git clean -fd && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/...)" && ...' +$ ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && export PATH=/opt/homebrew/bin:$PATH && git fetch origin feature/single-request-plan-review-templates && git switch feature/single-request-plan-review-templates && git reset --hard origin/feature/single-request-plan-review-templates && test -z "$(git status --short)" && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single-request-plan-review-templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && go version && claude --version && sops --version && make build-edge build-node && go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh && make test-single-request-claude-smoke-self-test' From https://git.toki-labs.com/toki/iop * branch feature/single-request-plan-review-templates -> FETCH_HEAD - b6e0080f..31fada5d feature/single-request-plan-review-templates -> origin/feature/single-request-plan-review-templates + 31fada5d..6f141b91 feature/single-request-plan-review-templates -> origin/feature/single-request-plan-review-templates Already on 'feature/single-request-plan-review-templates' -HEAD is now at 31fada5d fix(single_request): 템플릿 승인 경계를 닫고 회귀 근거를 채운다 -HEAD=31fada5d08d6d93076bd0d4a7522074fb8b8d960 -goenv=darwin/arm64 +Your branch is behind 'origin/feature/single-request-plan-review-templates' by 2 commits, and can be fast-forwarded. + (use "git pull" to update your local branch) +HEAD is now at 6f141b91 fix(single_request): 템플릿 경로 생략과 명시 빈 값을 구분한다 +go version go1.26.3 darwin/arm64 2.1.177 (Claude Code) sops 3.13.1 -MISSING dev-openai-toki.edge.yaml -MISSING dev-openai-toki.sops.yaml -ssh exit=0 -``` +[info] a new version of sops (v3.13.3) is available, you can update by visiting: https://github.com/getsops/sops/releases/tag/v3.13.3 -Host, arch, and tool versions match the archived profile exactly (`toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev`, `darwin/arm64`, Claude CLI `2.1.177`, SOPS `3.13.1`). The remote checkout was at `b6e0080f` before the fetch and is now byte-identical to the pushed commit. - -**Remote rebuild and changed-package tests on darwin/arm64 — PASS** - -```text -$ make build-edge build-node -build exit=0 +[warning] Note that in a future version, sops will no longer check whether the current version is the latest when asking for sops' version. If you want to explicitly check for the latest version, add the `--check-for-updates` option to `sops --version`. This will hide this deprecation warning and will always check, even if the default behavior changes in the future. mkdir -p build/bin GOOS=darwin GOARCH=arm64 go build -trimpath -o build/bin/iop-edge ./apps/edge/cmd/edge mkdir -p build/bin go build -trimpath -o build/bin/iop-node ./apps/node/cmd/node --rwxr-xr-x 1 toki staff 27568466 Aug 9 09:26 build/bin/iop-edge --rwxr-xr-x 1 toki staff 27756002 Aug 9 09:26 build/bin/iop-node - -$ go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config ./apps/edge/internal/service ./apps/edge/internal/openai -test exit=0 -ok iop/packages/go/singlerequesttemplate 0.260s -ok iop/packages/go/config 0.633s -ok iop/apps/edge/internal/service 8.709s -ok iop/apps/edge/internal/openai 9.074s - -$ make test-single-request-claude-smoke-self-test -self-test exit=0 +ok iop/packages/go/config 0.655s +ok iop/apps/edge/internal/configrefresh 0.847s +./scripts/e2e-single-request-claude.sh --self-test [single-request-claude-smoke] self-test passed: exact Claude base-route coverage, structured observation admission, child-only zero retry, authenticated model admission, closed failure classification, model/Edge/Node/runtime binding, zero-child preflight, derived verification, redaction, cleanup, signal handling, and atomic publication +exit=0 ``` -Remote `go version go1.26.3 darwin/arm64` at `/opt/homebrew/bin/go`. +The remote checkout was one commit behind at planning time (`31fada5d`) and was reset onto `origin/feature/single-request-plan-review-templates`; the clean-tree and HEAD-equality guards in the same command both passed before any build or test ran, so the Darwin/arm64 evidence belongs to `6f141b91` and no other tree. -**Live API qualification — BLOCKED (external). Not a pass.** - -Raw failure, exactly as the plan's command produces it: +Operator-asset probe — externally blocked, no live request was made: ```text -$ make test-single-request-claude-smoke-preflight EDGE_CONFIG=dev-openai-toki.edge.yaml SOPS_CONFIG=dev-openai-toki.sops.yaml -./scripts/e2e-single-request-claude.sh --preflight-only \ - --claude "" \ - --runtime-evidence "" \ - --base-url "" \ - --model "" \ - --edge-bin "" \ - --node-bin "" \ - --edge-config "" \ - --observation-file "" \ - --metrics-url "" \ - --workspace "" \ - --output "" \ - --secret-env "" -[single-request-claude-smoke] validation failed: caller input absent -make: *** [test-single-request-claude-smoke-preflight] Error 69 -preflight exit=2 +$ ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && for file in dev-openai-toki.edge.yaml dev-openai-toki.sops.yaml; do if test -f "$file"; then echo "PRESENT $file"; else echo "MISSING $file"; fi; done && test -r /Users/toki/.config/sops/age/keys.txt && echo "PRESENT age identity"' +MISSING dev-openai-toki.edge.yaml +MISSING dev-openai-toki.sops.yaml +PRESENT age identity +exit=0 ``` -`test-single-request-claude-smoke` and `test-single-request-claude-smoke-validate` were not run: the preflight is their gate and it failed closed. No live Messages request was issued and no smoke manifest was produced. +Both approved operator config files are still absent, so live API qualification was **not run** and is **not claimed as a pass**. This is an unchanged pre-existing external block, not a result of this change. No file was created, substituted, or approximated, and the inert `EDGE_CONFIG`/`SOPS_CONFIG` names were not used. -Two independent causes, both external to this change: +Resume condition — live qualification can run only after the operator does both of the following: -1. **The approved smoke inputs no longer exist on the host.** `dev-openai-toki.edge.yaml` and `dev-openai-toki.sops.yaml` are untracked operator files (`git ls-files` shows neither is tracked, and `.gitignore` does not mention them). `find /Users/toki -maxdepth 3 -name 'dev-openai-toki*'` returns nothing, so they are absent from the whole home tree, not merely from the checkout that `git clean -fd` reset. -2. **The plan's Make variables are inert.** `EDGE_CONFIG` and `SOPS_CONFIG` are not read by these targets. `Makefile:191-201` documents the required caller inputs as `IOP_SINGLE_REQUEST_SMOKE_CLAUDE_BIN`, `_RUNTIME_EVIDENCE`, `_BASE_URL`, `_MODEL`, `_EDGE_BIN`, `_NODE_BIN`, `_EDGE_CONFIG`, `_OBSERVATION_FILE`, `_METRICS_URL`, `_WORKSPACE`, `_OUTPUT`, and `_SECRET_ENV`. All twelve expanded empty, which is what `caller input absent` reports. - -**Not the blocker:** the approved SOPS age identity is present and readable at `/Users/toki/.config/sops/age/keys.txt` (`-rw------- 189 bytes`, mtime `Jun 2 14:29`). `sops --version` succeeds. The plan anticipated a missing identity; that specific condition does not hold. Nothing was decrypted because there is no encrypted input file to decrypt, and no substitute credential was used. - -**Exact resume condition.** Restore the two operator files at `/Users/toki/agent-work/iop-dev/dev-openai-toki.edge.yaml` and `dev-openai-toki.sops.yaml` (they must be re-provisioned from the operator's secret store; they are not recoverable from this repository), then re-run against the same commit with the real variable names: - -```bash -ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && export PATH=/opt/homebrew/bin:$PATH && \ - test "$(git rev-parse HEAD)" = "31fada5d08d6d93076bd0d4a7522074fb8b8d960" && \ - make test-single-request-claude-smoke-preflight test-single-request-claude-smoke test-single-request-claude-smoke-validate \ - IOP_SINGLE_REQUEST_SMOKE_EDGE_CONFIG=dev-openai-toki.edge.yaml \ - IOP_SINGLE_REQUEST_SMOKE_SECRET_ENV= \ - IOP_SINGLE_REQUEST_SMOKE_CLAUDE_BIN=<...> IOP_SINGLE_REQUEST_SMOKE_RUNTIME_EVIDENCE=<...> \ - IOP_SINGLE_REQUEST_SMOKE_BASE_URL=<...> IOP_SINGLE_REQUEST_SMOKE_MODEL=<...> \ - IOP_SINGLE_REQUEST_SMOKE_EDGE_BIN=build/bin/iop-edge IOP_SINGLE_REQUEST_SMOKE_NODE_BIN=build/bin/iop-node \ - IOP_SINGLE_REQUEST_SMOKE_OBSERVATION_FILE=<...> IOP_SINGLE_REQUEST_SMOKE_METRICS_URL=<...> \ - IOP_SINGLE_REQUEST_SMOKE_WORKSPACE=<...> IOP_SINGLE_REQUEST_SMOKE_OUTPUT=<...>' -``` - -**Scope of the block.** This change does not touch the smoke harness, the Messages wire, provider routing, or credential handling. The behavior it repairs — template loading, template grammar, admission freezing, and artifact rendering — is fully covered by the deterministic suites above, which pass identically on this container (linux) and on the approved darwin/arm64 host. What remains unqualified is the pre-existing external live-API path, which was already qualified at S12 and is unaffected by this diff. No prior output was reused and no local result is being presented as a live pass. +1. Restores `dev-openai-toki.edge.yaml` and `dev-openai-toki.sops.yaml` under `/Users/toki/agent-work/iop-dev` (the SOPS age identity at `/Users/toki/.config/sops/age/keys.txt` is already readable). +2. Supplies all twelve Makefile-defined smoke inputs: `IOP_SINGLE_REQUEST_SMOKE_CLAUDE_BIN`, `IOP_SINGLE_REQUEST_SMOKE_RUNTIME_EVIDENCE`, `IOP_SINGLE_REQUEST_SMOKE_BASE_URL`, `IOP_SINGLE_REQUEST_SMOKE_MODEL`, `IOP_SINGLE_REQUEST_SMOKE_EDGE_BIN`, `IOP_SINGLE_REQUEST_SMOKE_NODE_BIN`, `IOP_SINGLE_REQUEST_SMOKE_EDGE_CONFIG`, `IOP_SINGLE_REQUEST_SMOKE_OBSERVATION_FILE`, `IOP_SINGLE_REQUEST_SMOKE_METRICS_URL`, `IOP_SINGLE_REQUEST_SMOKE_WORKSPACE`, `IOP_SINGLE_REQUEST_SMOKE_OUTPUT`, `IOP_SINGLE_REQUEST_SMOKE_SECRET_ENV`. --- @@ -394,12 +319,12 @@ ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && export PATH=/opt/ho | Section | Owner | Note | |---------|-------|------| -| Header comment, Overview, Review Agent Instructions | Fixed at stub creation | Implementing agent must not modify or execute archive, `complete.log`, or task-directory moves. | -| Archive Evidence Snapshot | Fixed at stub creation from plan | Implementing agent reads only the cited evidence needed for this follow-up. | -| Implementation Item Completion | Fixed item names | Implementing agent checks `[ ]` to `[x]` only after actual completion. | -| Implementation Checklist | Fixed text/order from plan | Implementing agent checks `[ ]` to `[x]` only after actual completion. | -| Review-Only Checklist | Review agent only | Implementing agent must not modify or check this section. | -| Deviations from Plan, Key Design Decisions | Implementing agent | Replace placeholders with actual content. | -| Reviewer Checkpoints | Fixed at stub creation | Review agent verifies independently. | -| Verification Results | Fixed headings and commands | Implementing agent fills actual output only; command changes require a deviation entry. | -| Code Review Result | Review agent appends | Not included in this stub. | +| Header comment, Overview, Review Agent Instructions | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) | +| Archive Evidence Snapshot | Fixed at stub creation from plan when present | Implementing agent uses it as default prior-loop context; read only the specific archive files cited there when more detail is required | +| Implementation Item Completion (item names) | Fixed at stub creation | Implementing agent checks `[ ]` → `[x]` only | +| Implementation Checklist (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` → `[x]` only | +| Review-Only Checklist | Review agent only | Implementing agent must not modify or check this section | +| Deviations from Plan, Key Design Decisions | Implementing agent | Replace placeholders with actual content | +| Reviewer Checkpoints | Fixed at stub creation | Pre-filled from plan | +| Verification Results (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `Deviations from Plan` entry | +| Code Review Result | Review agent appends | Not included in stub | diff --git a/agent-task/single_request_plan_review_templates/PLAN-cloud-G08.md b/agent-task/single_request_plan_review_templates/PLAN-cloud-G08.md index 5816d376..128d0b09 100644 --- a/agent-task/single_request_plan_review_templates/PLAN-cloud-G08.md +++ b/agent-task/single_request_plan_review_templates/PLAN-cloud-G08.md @@ -1,30 +1,28 @@ - + -# Single-request Template Contract Repair - REVIEW_API +# Single-request Template Path Presence Repair - REVIEW_API -> **For Implementing Agent:** Implement only the checked-in scope below. Do not archive task files, create `complete.log`, or start/monitor orchestration. Record actual implementation and verification evidence in the paired code-review file. +> **For the Implementing Agent:** Implement only the checked-in scope below. Run every verification command, fill the implementation-owned sections of `CODE_REVIEW-cloud-G08.md` with actual notes and raw output, keep the active pair in place, and report ready for review. Finalization belongs to the code-review skill. 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 preceding implementation introduced configurable single-request Plan and Review templates, but official review found two admission-boundary defects, material gaps in the prescribed regression suite, and stale public/current documentation. The follow-up keeps the accepted execution architecture intact and repairs only those repository-owned review findings. Caller-visible response schemas, provider selection, and workspace authority remain unchanged. +The preceding repair made `loadTemplateFile` reject empty paths, but the caller converts every trimmed-empty configured value into omission before that rejection is reachable. As a result, explicit empty and whitespace-only `plan_file`/`review_file` values silently select defaults despite the current plan and spec requiring fail-closed rejection. This follow-up changes only the configuration presence boundary and its deterministic evidence. ## Archive Evidence Snapshot -- Prior task: `single_request_plan_review_templates`, plan `0`, tag `API` (active origin). -- Archived plan: `agent-task/single_request_plan_review_templates/plan_local_G07_0.log`. -- Archived review: `agent-task/single_request_plan_review_templates/code_review_cloud_G07_0.log`. -- Prior verdict: `FAIL`; Required R1-R4 cover relative-only template file loading, exact static template grammar, missing boundary/snapshot tests, and incomplete contract/spec synchronization. -- Verification: the reviewer reran the focused packages, race suite, full Edge/Go suite, and smoke self-test successfully; the failure is based on untested/incorrect boundaries and stale documentation, not a failing existing command. +- Prior task: `single_request_plan_review_templates`, plan `1`, tag `REVIEW_API`. +- Archived plan: `agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log`. +- Archived review: `agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log`. +- Prior verdict: `FAIL`; Required R1 identifies that plain string fields erase the distinction between omission and explicit empty/whitespace values before `loadTemplateFile` runs. +- Fresh reviewer regression: `go test -count=1 ./packages/go/config -run TestReviewConfiguredWhitespaceTemplatePathFailsClosed` failed because configured whitespace `plan_file` was admitted as omission. The temporary reviewer-only test was removed after reproduction. +- Existing focused, race, full Edge/Go, smoke self-test, and Darwin/arm64 changed-package suites passed. Live API qualification remains externally blocked because the approved remote operator config files and complete `IOP_SINGLE_REQUEST_SMOKE_*` inputs are absent. - Roadmap carryover: none; this is a non-milestone task. ## Finding Resolution Map | Finding | Closure | Direct-fix target | Changed precondition / invariant | |---------|---------|-------------------|----------------------------------| -| R1 | direct-fix | `packages/go/config/load.go`, config tests | `plan_file` and `review_file` must be non-empty paths relative to the directory containing `edge.yaml`; absolute paths are rejected before filesystem access. | -| R2 | direct-fix | `packages/go/singlerequesttemplate/template.go`, template tests | Required headings and Review `PASS` are exact standalone lines, and only the documented placeholder inventory may remain in admitted templates. | -| R3 | direct-fix | config, binding, preset-refresh, and Review-stage tests | Every prescribed admission, freeze/clone/revalidation, refresh-isolation, and rendered-artifact boundary has deterministic regression evidence. | -| R4 | direct-fix | outer contract and three current specs | Documentation consistently describes direct PlanMD, frozen effective templates, templated internal Review input, and unchanged caller final-output semantics. | +| R1 | direct-fix | `packages/go/config/execution_preset_types.go`, `packages/go/config/load.go`, `packages/go/config/model_execution_preset_config_test.go`, `apps/edge/internal/configrefresh/execution_preset_classify_test.go` | Field omission remains the only default-fallback signal; every explicitly configured value, including empty and whitespace-only values, reaches trimmed non-empty validation before filesystem access, and the presence state survives deep clone and refresh comparison fixtures. | ## Analysis @@ -37,6 +35,7 @@ The preceding implementation introduced configurable single-request Plan and Rev - `agent-ops/skills/common/code-review/SKILL.md` - `agent-ops/skills/common/plan/SKILL.md` - `agent-ops/skills/common/finalize-task-routing/SKILL.md` +- `agent-ops/skills/common/plan/templates/review-stub-template.md` - `agent-ops/rules/common/rules-agent-spec.md` - `agent-ops/rules/project/domain-edge.md` - `agent-ops/rules/project/domain-platform-common.md` @@ -46,264 +45,269 @@ The preceding implementation introduced configurable single-request Plan and Rev - `agent-test/local/smoke/platform-common.md` - `agent-test/local/smoke/testing.md` - `agent-contract/index.md` -- `agent-contract/inner/edge-config.md` +- `agent-contract/inner/edge-config-runtime-refresh.md` - `agent-contract/outer/anthropic-compatible-api.md` - `agent-spec/index.md` - `agent-spec/runtime/provider-pool-config-refresh.md` - `agent-spec/runtime/edge-node-execution.md` - `agent-spec/input/openai-compatible-surface.md` -- `packages/go/singlerequesttemplate/template.go` -- `packages/go/singlerequesttemplate/template_test.go` - `packages/go/config/load.go` +- `packages/go/config/execution_preset_types.go` - `packages/go/config/model_execution_preset_config_test.go` -- `apps/edge/internal/service/single_request_types.go` -- `apps/edge/internal/service/single_request_types_test.go` -- `apps/edge/internal/openai/single_request_preset_binding.go` -- `apps/edge/internal/openai/single_request_preset_binding_test.go` -- `apps/edge/internal/openai/single_request_plan_stage.go` -- `apps/edge/internal/openai/single_request_plan_stage_test.go` -- `apps/edge/internal/openai/single_request_review_stage.go` -- `apps/edge/internal/openai/single_request_review_stage_test.go` +- `apps/edge/internal/configrefresh/execution_preset_classify_test.go` - `agent-task/single_request_plan_review_templates/plan_local_G07_0.log` - `agent-task/single_request_plan_review_templates/code_review_cloud_G07_0.log` +- `agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log` +- `agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log` -### SDD / Contract Context +### SDD Criteria -- SDD is not applicable: the accepted architecture is unchanged and this plan repairs review findings within existing contracts. -- `agent-contract/inner/edge-config.md` already establishes `edge.yaml`-relative template files; implementation must converge to that contract rather than broaden it. -- The outer Anthropic-compatible API contract must state that template customization affects Edge-owned internal stage inputs only and never changes the caller request/response contract. +Not applicable. This task is not Milestone-linked and repairs an existing configuration contract without changing the accepted architecture. ### Verification Context -- There is no separate handoff. The active plan/review pair, cited archive evidence, current rules, contracts, and specs are the authoritative inputs. -- Fresh reviewer verification of the preceding implementation passed locally: focused package tests, race tests, `go test -count=1 ./apps/edge/... ./packages/go/...`, and `make test-single-request-claude-smoke-self-test` all exited `0`. -- Archived remote-profile evidence identifies `toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev`, Darwin/arm64, Claude CLI `2.1.177`, SOPS `3.13.1`, and implementation commit `b6e0080f`. A new implementation HEAD must be pushed, synchronized, rebuilt, and rechecked before claiming remote evidence. -- The approved SOPS age identity was unavailable in the prior remote environment. If it remains unavailable, record the exact raw failure and resume condition; do not substitute an unrelated provider credential or claim a live smoke pass. +- No separate handoff was supplied. Repository-native rules, source, current contracts/specs, the active pair, and the two specifically cited prior review pairs supplied the verification context. +- The local reviewer ran fresh focused config/template/service/OpenAI tests, the relevant race suite, `go test -count=1 ./apps/edge/... ./packages/go/...`, `make test-single-request-claude-smoke-self-test`, and the stale-document guard. All passed except the temporary explicit-whitespace regression, which failed for the expected defect. +- The regression precondition is exact: `ExecutionSingleRequestTemplates.PlanFile` and `.ReviewFile` are plain strings at `packages/go/config/execution_preset_types.go:286-290`; `resolveSingleRequestTemplates` treats trimmed-empty strings as omission at `packages/go/config/load.go:693-709`; the empty check in `loadTemplateFile` at `packages/go/config/load.go:727-730` is therefore unreachable for decoded configuration. +- Fresh test execution is required. Every Go command uses `-count=1`; cached output is not acceptable. -### Test Gaps to Close +#### External Verification Preflight -- Config loading lacks per-file fallback, absolute-path rejection, exact 8192-byte acceptance, symlink/non-regular/unreadable rejection, and a complete invalid-grammar matrix. -- Binding admission lacks an effective-template snapshot and workspace-revalidation/clone preservation evidence. -- Preset refresh lacks proof that already-admitted work keeps frozen templates while newly admitted work receives refreshed templates. -- Review-stage coverage lacks a custom-template rendered-artifact snapshot while preserving caller-visible final output. +- Runner: `toki@toki-labs.com`; repository/workdir: `/Users/toki/agent-work/iop-dev`; OS/arch: `darwin/arm64`. +- Local branch and origin HEAD at planning time: `feature/single-request-plan-review-templates`, `702e62aa`; local dirty state contains only dispatcher-owned `agent-task/single_request_plan_review_templates/WORK_LOG.md`. +- Remote checkout is clean but stale at `31fada5d`; implementation must push its source commit, fetch the hyphenated branch, switch, and reset that dedicated checkout to `origin/feature/single-request-plan-review-templates` before rebuilding. +- Remote tools: Go `1.26.3` at `/opt/homebrew/bin/go`, Claude CLI `2.1.177`, SOPS `3.13.1`; the SOPS age identity is readable at `/Users/toki/.config/sops/age/keys.txt`. +- Binary targets remain `build/bin/iop-edge` and `build/bin/iop-node`. No listener, port, or running process is assumed or required for changed-package verification. +- `dev-openai-toki.edge.yaml` and `dev-openai-toki.sops.yaml` are absent. The live smoke targets also require twelve `IOP_SINGLE_REQUEST_SMOKE_*` values; `EDGE_CONFIG` and `SOPS_CONFIG` are inert. Do not claim or retry live qualification unless the operator restores the files and supplies the complete input set. Record the exact missing assets and resume condition instead. -### Symbol / Text Reference Audit +### Test Coverage Gaps -- No production symbol rename is planned. -- Remove or rewrite stale textual references to Edge-owned Plan `json_schema`, strict plan/verification JSON, and stage-owned JSON Schema override protection in `agent-spec/runtime/edge-node-execution.md`. +- Existing config tests cover omitted per-file fallback, relative success, absolute rejection, size/file-kind/UTF-8 limits, and invalid grammar, but do not distinguish explicit empty/whitespace values from omission. +- No current regression proves that any new optional presence state is deep-cloned independently rather than aliased. +- The refresh classifier test uses direct string literals for both configured paths; changing the representation will break compilation unless those fixtures are updated, and the existing digest-only/path-redaction assertion must remain green. +- Full and race suites cover downstream compatibility but cannot replace the missing four Plan/Review empty/whitespace boundary cases. -### Split Decision +### Symbol References -- Use one plan. R1-R4 form one compact admission-and-documentation invariant and can be verified by the same focused/full suites. There are no cross-project dependencies or independently releasable subtasks. +- No symbol is renamed or removed. +- The type of `ExecutionSingleRequestTemplates.PlanFile` and `.ReviewFile` changes. All Go references are in `packages/go/config/load.go`, `packages/go/config/execution_preset_types.go`, and the two template literals in `apps/edge/internal/configrefresh/execution_preset_classify_test.go`; config YAML test fixtures exercise decode indirectly. +- No dependency or manifest change is required. -### Scope Exclusions +### Split Judgment -- Do not change caller request/response schemas, provider routing, workspace authorization, the Review loop decision model, protobufs, Node packages, UI surfaces, or centrally managed `agent-ops/rules/common/**` and `agent-ops/skills/common/**`. -- Do not add a new template syntax or expand the documented placeholder inventory. -- Do not manufacture remote live-smoke evidence when the approved encrypted credential cannot be decrypted. +Use one plan. Decode-time presence, default fallback, empty rejection, deep clone, and refresh fixture compatibility are one compact configuration invariant; splitting them would leave an uncompilable or falsely passing intermediate state. + +### Scope Rationale + +- Do not change template grammar, service/OpenAI stage behavior, caller-visible APIs, provider routing, workspace authority, protobufs, Node packages, smoke scripts, or centrally managed Agent-Ops files. +- Do not edit contracts/specs: their current non-empty/relative-only requirement is the target behavior, so source and tests must converge to those documents. +- Do not broaden path policy to reject relative `..` traversal; that was explicitly excluded from the prior repair and is not part of R1. +- Do not mutate or replace dispatcher-owned `WORK_LOG.md`. ### Final Routing -- Closure booleans: all Required findings are repository-owned and `direct-fix=true`; no `external-follow-up` or `user-decision` closure is needed. -- Build scoring: scope `2`, state `1`, blast radius `1`, evidence `2`, verification `2`. -- Review scoring: scope `2`, state `1`, blast radius `1`, evidence `2`, verification `2`. -- Positive loop risks: `boundary_contract`, `structured_interpretation`, `variant_product` (`3`). -- `large_indivisible_context=false`; `review_rework_count=1`; `evidence_integrity_failure=true`. -- Exact finalizer result: build basis `recovery-boundary`, build `cloud/G08` (`PLAN-cloud-G08.md`), review basis `official-review`, review `cloud/G08` (`CODE_REVIEW-cloud-G08.md`). No route-cap gap applies. +- Evaluation mode: `isolated-reassessment`; finalizer: `finalize-task-policy.sh pair`. +- Closure: `scope_closed=true`, `context_closed=true`, `ownership_closed=true`, `decision_closed=true`, `verification_closed=true`. R1 is fully repository-owned; the pre-existing live-profile absence is bounded external evidence, not an alternative owner for this fix. +- Build scoring: scope `2`, state `1`, blast radius `1`, evidence `2`, verification `2`; base basis `local-fit`, recovery basis `recovery-boundary`; route `cloud/G08`, catalog `worker/cloud/G08`, filename `PLAN-cloud-G08.md`. +- Review scoring: scope `2`, state `1`, blast radius `1`, evidence `2`, verification `2`; basis `official-review`; route `cloud/G08`, catalog `review/cloud/G08`, filename `CODE_REVIEW-cloud-G08.md`. +- `large_indivisible_context=false`; positive loop risks: `boundary_contract`, `structured_interpretation`, `variant_product` (`3`). +- Recovery signals: `review_rework_count=2`, `evidence_integrity_failure=true`. +- Capability gap: none; both routed targets exist in the catalog. ## Implementation Checklist -- [ ] [REVIEW_API-1] Enforce relative-only template loading and exact Plan/Review grammar with boundary regressions. -- [ ] [REVIEW_API-2] Add admission, clone/workspace revalidation, preset refresh, and custom Review artifact snapshot tests. -- [ ] [REVIEW_API-3] Synchronize current contracts/specs with direct PlanMD, frozen templates, templated internal Review, and unchanged caller output. -- [ ] [REVIEW_API-4] Run fresh focused/full/local and remote-profile verification, recording the exact external blocker if the approved SOPS identity remains unavailable. -- [ ] Fill implementation-owned sections in `CODE_REVIEW-cloud-G08.md` with actual implementation notes and verification output. +- [ ] [REVIEW_API-1] Preserve omission separately from configured template path values, reject configured empty/whitespace values before filesystem access, and deep-clone the optional state. +- [ ] [REVIEW_API-2] Add Plan/Review presence-boundary and clone regressions, update refresh fixtures, and retain omitted fallback, relative success, and digest-only refresh evidence. +- [ ] [REVIEW_API-3] Run fresh focused, race, full, smoke-self-test, documentation, and approved remote-profile verification; record the exact live-profile blocker if operator assets remain absent. +- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output. -## Implementation Items - -### REVIEW_API-1 — Close Template Admission Boundaries +### [REVIEW_API-1] Preserve Configured Template Path Presence **Problem** -`loadTemplateFile` accepts absolute paths even though the config contract is relative-only. Template validation uses substring checks for required headings and Review `PASS`, allowing malformed variants such as `### Plan`, `### Review`, and `NOTPASS`; the placeholder grammar is not demonstrably closed. +`packages/go/config/execution_preset_types.go:286-290` stores optional paths as strings, while `packages/go/config/load.go:693-709` uses trimmed emptiness as omission. The explicit empty rejection at `packages/go/config/load.go:727-730` is consequently dead for decoded values, and `ExecutionSingleRequestPolicy.Clone` at `packages/go/config/execution_preset_types.go:327-340` would shallow-copy any pointer introduced without a dedicated clone. **Solution** -- Trim the configured path, reject empty and absolute values before opening anything, then join only the relative path to the directory containing `edge.yaml`. -- Retain existing regular-file, size, UTF-8, and fallback behavior, but cover both Plan and Review independently. -- Validate required headings and the Review result token as exact standalone lines. -- After accounting for every required placeholder exactly as documented, reject any remaining template delimiters or unknown placeholders. +- Represent `PlanFile` and `ReviewFile` with presence-aware optional values, using `*string` with the existing mapstructure/YAML names unless a strictly equivalent repository-native representation proves necessary. +- Treat `nil` only as omission/default fallback. Dereference every non-nil value into `loadTemplateFile`, which trims and rejects empty/whitespace before `Lstat` or `Open`. +- Deep-clone both optional strings so snapshots cannot alias mutable pointer cells. Preserve `EffectivePlan` and `EffectiveReview` value copying. -Before: +Before (`packages/go/config/execution_preset_types.go:286-290`, `packages/go/config/load.go:693-709`): ```go -target := strings.TrimSpace(relOrAbsPath) -if !filepath.IsAbs(target) { - target = filepath.Join(baseDir, target) +type ExecutionSingleRequestTemplates struct { + PlanFile string `mapstructure:"plan_file" yaml:"plan_file,omitempty"` + ReviewFile string `mapstructure:"review_file" yaml:"review_file,omitempty"` +} + +if strings.TrimSpace(sr.Templates.PlanFile) == "" { + sr.Templates.EffectivePlan = singlerequesttemplate.DefaultPlanTemplate } ``` After: ```go -target := strings.TrimSpace(relativePath) -if filepath.IsAbs(target) { - return "", fmt.Errorf("template path must be relative to edge.yaml") +type ExecutionSingleRequestTemplates struct { + PlanFile *string `mapstructure:"plan_file" yaml:"plan_file,omitempty"` + ReviewFile *string `mapstructure:"review_file" yaml:"review_file,omitempty"` +} + +if sr.Templates.PlanFile == nil { + sr.Templates.EffectivePlan = singlerequesttemplate.DefaultPlanTemplate +} else { + content, err := loadTemplateFile(baseDir, *sr.Templates.PlanFile) + // validate and freeze content } -target = filepath.Join(baseDir, target) ``` -Replace substring grammar checks such as: +Clone the optional fields through a dedicated `ExecutionSingleRequestTemplates.Clone` or equivalent explicit value-copy helper; do not retain `Templates: p.Templates` after pointers are introduced. + +**Modified Files and Checklist** + +- [ ] `packages/go/config/execution_preset_types.go` — add presence-aware path fields and deep-clone them. +- [ ] `packages/go/config/load.go` — use nil only for fallback and route non-nil values through the existing loader rejection. + +**Test Strategy** + +- Tests are required because this is a bug fix and a configuration type-boundary change. REVIEW_API-2 adds the load and clone regressions in the already established template config test file. +- Preserve existing regular-file, 8192-byte, UTF-8, exact grammar, and independent fallback tests unchanged unless pointer-aware assertions are needed. + +**Verification** + +```bash +go test -count=1 ./packages/go/config -run 'TestLoadEdgeSingleRequestTemplates|TestExecutionSingleRequestTemplatePathPresenceClone' +``` + +Expected: explicit Plan/Review empty and whitespace values fail, omitted fields still use defaults, relative paths still load, and cloned pointer cells are independent. + +### [REVIEW_API-2] Close Presence and Refresh Regression Gaps + +**Problem** + +`packages/go/config/model_execution_preset_config_test.go:527` has extensive template boundary coverage but no explicit empty/whitespace matrix and no optional-state clone assertion. `apps/edge/internal/configrefresh/execution_preset_classify_test.go:247-249` and `:286-288` construct string path fields directly and must remain compatible while preserving the existing digest-only, no-path/no-body refresh evidence. + +**Solution** + +- Extend `TestLoadEdgeSingleRequestTemplates` with four cases: explicit empty and whitespace-only `plan_file`, and explicit empty and whitespace-only `review_file`. Require the correct field context plus `template path must not be empty` and no filesystem-dependent error. +- Strengthen existing omission/fallback and relative-success cases to assert path presence (`nil` versus non-nil) where stable. +- Add `TestExecutionSingleRequestTemplatePathPresenceClone` that clones a policy, mutates each cloned path cell, and proves the original values and effective template strings are unchanged. +- Update the two config-refresh template literals through a local test pointer helper. Keep `TestClassifySingleRequestTemplateContentChange` assertions that raw paths and template bodies never enter change summaries. + +Before (`apps/edge/internal/configrefresh/execution_preset_classify_test.go:247-249`): ```go -if strings.Index(tmpl, "# Plan") < 0 { /* ... */ } +Templates: config.ExecutionSingleRequestTemplates{ + PlanFile: "templates/plan.md", + ReviewFile: "templates/review.md", +}, ``` -with a line-aware exact matcher and closed-token validation shared by both variants. +After: -**Modified Files Checklist** +```go +Templates: config.ExecutionSingleRequestTemplates{ + PlanFile: stringPointer("templates/plan.md"), + ReviewFile: stringPointer("templates/review.md"), +}, +``` -- [ ] `packages/go/singlerequesttemplate/template.go` -- [ ] `packages/go/singlerequesttemplate/template_test.go` -- [ ] `packages/go/config/load.go` -- [ ] `packages/go/config/model_execution_preset_config_test.go` +**Modified Files and Checklist** + +- [ ] `packages/go/config/model_execution_preset_config_test.go` — add the four decode/load regressions, presence assertions, and clone independence test. +- [ ] `apps/edge/internal/configrefresh/execution_preset_classify_test.go` — update path fixtures with a local pointer helper and retain redaction assertions. **Test Strategy** -- Extend `TestValidatePlanTemplate` and `TestValidateReviewTemplate` for exact headings/result lines, missing/duplicate/unknown placeholders, and delimiter residue. -- Extend `TestLoadEdgeSingleRequestTemplates` for Plan/Review absolute-path rejection, relative success, per-file fallback, exact size boundary, and filesystem-kind failures. +- Extend `TestLoadEdgeSingleRequestTemplates` with table-driven YAML fixtures for both fields and both explicit empty forms. +- Add `TestExecutionSingleRequestTemplatePathPresenceClone` with distinct Plan/Review values, mutation after clone, and exact original/clone assertions. +- Re-run `TestClassifySingleRequestTemplateContentChange` to prove type adaptation does not expose configured paths or raw bodies and still classifies an effective-content change as live-applied. **Verification** -- Run the focused template/config tests and confirm every malformed variant is rejected without exposing file content in errors. +```bash +go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +go test -race -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +``` -### REVIEW_API-2 — Prove Freeze, Refresh, and Render Semantics +Expected: both fresh suites pass, including all new named regressions and the unchanged refresh redaction checks. + +### [REVIEW_API-3] Produce Trustworthy Local and Remote Evidence **Problem** -The preceding review claimed coverage that is absent from the actual test files. The admitted effective template snapshot, clone/workspace revalidation, refresh isolation, and custom Review artifact are therefore not protected against regression. +The prior evidence marked the configured-empty boundary complete even though no test reached it. The remote Darwin/arm64 checkout is also one commit behind the current branch, and live qualification cannot run while approved operator assets and the complete smoke input set are absent. **Solution** -- Add deterministic service-level assertions that admitted bindings carry the exact effective Plan/Review template pair through clone and workspace revalidation paths. -- Add preset refresh assertions that existing work retains its frozen templates and newly admitted work observes the refreshed pair. -- Add a Review-stage custom-template snapshot proving internal artifact rendering uses the frozen template while `decision.output` remains the caller-visible final response. -- Do not change production behavior unless a new regression exposes a concrete defect. +- Run every local command below with fresh test execution and paste actual stdout/stderr into the paired review file. +- Record the source commit, push the hyphenated branch, synchronize the dedicated remote checkout to that exact commit, rebuild, and rerun changed packages plus the deterministic smoke self-test on Darwin/arm64. +- Probe the two operator files without creating or substituting them. If either is absent, record `MISSING`, skip live API qualification, and retain the exact restore/input resume condition. Never describe the block as a pass. -**Modified Files Checklist** +Before (prior evidence claim): -- [ ] `apps/edge/internal/service/single_request_types_test.go` -- [ ] `apps/edge/internal/openai/single_request_preset_binding_test.go` -- [ ] `apps/edge/internal/openai/single_request_review_stage_test.go` +```text +empty and absolute values are rejected before os.Lstat/os.Open +``` + +After (required evidence): + +```text +explicit empty/whitespace Plan and Review cases execute and fail closed; +remote source identity and any external blocker are recorded separately +``` + +**Modified Files and Checklist** + +- [ ] `agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md` — fill actual implementation decisions, deviations, local/remote output, tested commit, and blocker/resume evidence. **Test Strategy** -- Add/extend `TestSingleRequestBindingTemplateSnapshot`. -- Add/extend `TestSingleRequestPresetBindingTemplateRefreshIsolation`. -- Add/extend `TestSingleRequestReviewStageCustomTemplateSnapshot`. -- Assert both the internal rendered artifact and unchanged caller output; do not rely on substring-only assertions where an exact snapshot is stable. +- No production test is added in this item; REVIEW_API-2 owns deterministic regressions. +- Local fresh suites, race execution, the full Edge/Go suite, smoke self-test, documentation guard, and remote changed-package execution jointly verify compatibility and evidence integrity. **Verification** -- Run the named focused packages, then the race suite covering OpenAI stages, service admission, refresh, config, and template validation. - -### REVIEW_API-3 — Synchronize Current Contracts and Specs - -**Problem** - -The current runtime spec still describes a Plan JSON Schema path that the implementation removed. The outer API contract and input spec do not yet document the accepted frozen-template/direct-PlanMD/internal-Review model, leaving the current documentation contradictory. - -**Solution** - -- Update the outer Anthropic-compatible contract to describe unchanged caller I/O and Edge-owned internal template customization. -- Update the provider-pool refresh spec with admission-time effective-template freezing and refresh isolation. -- Rewrite stale Plan JSON Schema passages in the Edge execution spec to direct PlanMD validation and templated Review artifact semantics. -- Update the OpenAI-compatible input surface to distinguish internal stage templates from caller-visible input/output. -- Preserve existing terminology and add the required current-spec change records where that spec format requires them. - -**Modified Files Checklist** - -- [ ] `agent-contract/outer/anthropic-compatible-api.md` -- [ ] `agent-spec/runtime/provider-pool-config-refresh.md` -- [ ] `agent-spec/runtime/edge-node-execution.md` -- [ ] `agent-spec/input/openai-compatible-surface.md` - -**Test Strategy** - -- Search the current spec for the known stale Plan JSON Schema phrases and require no matches. -- Cross-check every new statement against the implementation and the inner Edge config contract. - -**Verification** - -- Run the documented `rg` guard and manually confirm the four surfaces agree on admission, execution, refresh, and caller-output boundaries. - -### REVIEW_API-4 — Produce Trustworthy Verification Evidence - -**Problem** - -The earlier implementation evidence checked off work and named tests/docs that were absent. Local behavior passed, but the recorded completeness and remote live-smoke claims cannot be trusted without fresh evidence. - -**Solution** - -- Run every command in Final Verification against the completed working tree and paste actual output into the paired review file. -- Confirm the pushed commit and the remote checkout are identical before a remote rebuild or live smoke. -- If approved SOPS decryption remains unavailable, record the exact failing command, raw error, exit code, and resume condition. Treat that as an allowed external-profile blocker only; never convert it into a local pass. - -**Modified Files Checklist** - -- [ ] `agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md` - -**Test Strategy** - -- Verify formatting, focused tests, race tests, the full Edge/Go suite, the deterministic smoke self-test, the documentation guard, and the approved remote profile. - -**Verification** - -- Evidence must identify the tested commit and clearly separate local success from any externally blocked live qualification. +Run the complete `Final Verification` sequence below. Expected: all repository-owned commands pass; remote live qualification is attempted only when every operator precondition is present, otherwise the paired review records the exact external blocker and resume condition. ## Modified Files Summary | File | Item | |---|---| -| `packages/go/singlerequesttemplate/template.go` | REVIEW_API-1 | -| `packages/go/singlerequesttemplate/template_test.go` | REVIEW_API-1 | +| `packages/go/config/execution_preset_types.go` | REVIEW_API-1 | | `packages/go/config/load.go` | REVIEW_API-1 | -| `packages/go/config/model_execution_preset_config_test.go` | REVIEW_API-1 | -| `apps/edge/internal/service/single_request_types_test.go` | REVIEW_API-2 | -| `apps/edge/internal/openai/single_request_preset_binding_test.go` | REVIEW_API-2 | -| `apps/edge/internal/openai/single_request_review_stage_test.go` | REVIEW_API-2 | -| `agent-contract/outer/anthropic-compatible-api.md` | REVIEW_API-3 | -| `agent-spec/runtime/provider-pool-config-refresh.md` | REVIEW_API-3 | -| `agent-spec/runtime/edge-node-execution.md` | REVIEW_API-3 | -| `agent-spec/input/openai-compatible-surface.md` | REVIEW_API-3 | -| `agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md` | REVIEW_API-4 | +| `packages/go/config/model_execution_preset_config_test.go` | REVIEW_API-2 | +| `apps/edge/internal/configrefresh/execution_preset_classify_test.go` | REVIEW_API-2 | +| `agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md` | REVIEW_API-3 | ## Final Verification -Run locally from the repository root: +Run locally from the repository root after all source and test changes: ```bash -test -z "$(gofmt -l packages/go/singlerequesttemplate/template.go packages/go/singlerequesttemplate/template_test.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/service/single_request_types_test.go apps/edge/internal/openai/single_request_preset_binding_test.go apps/edge/internal/openai/single_request_review_stage_test.go)" -go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config -go test -count=1 ./apps/edge/internal/service -run 'TestSingleRequestBinding' -go test -count=1 ./apps/edge/internal/openai -run 'TestSingleRequest(PresetBinding|ReviewStage)' -go test -race -count=1 ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/configrefresh ./packages/go/config ./packages/go/singlerequesttemplate +test -z "$(gofmt -l packages/go/config/execution_preset_types.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/configrefresh/execution_preset_classify_test.go)" +git diff --check +go test -count=1 ./packages/go/config -run 'TestLoadEdgeSingleRequestTemplates|TestExecutionSingleRequestTemplatePathPresenceClone' +go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh +go test -race -count=1 ./packages/go/config ./apps/edge/internal/configrefresh go test -count=1 ./apps/edge/... ./packages/go/... make test-single-request-claude-smoke-self-test -if rg --sort path -n 'Edge-owned OpenAI `json_schema` response format|strict small plan/verification JSON|stage-owned JSON Schema override protection' agent-spec/runtime/edge-node-execution.md; then exit 1; fi +rg --sort path -n 'Absolute and empty paths are rejected before any filesystem access|plan_file.*review_file.*non-empty paths' agent-spec/runtime/provider-pool-config-refresh.md ``` -Then verify the approved remote profile against the exact pushed implementation commit: +Expected: formatting and diff checks are silent; every fresh Go suite and smoke self-test passes; the documentation guard prints the two current contract statements. + +After the source/test commit is pushed, synchronize and verify the approved Darwin/arm64 checkout against the exact pushed HEAD: ```bash -test "$(git branch --show-current)" = "feature/single_request_plan_review_templates" -test -z "$(git status --short)" -git push origin feature/single_request_plan_review_templates - -ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git fetch origin feature/single_request_plan_review_templates && git switch feature/single_request_plan_review_templates && git reset --hard origin/feature/single_request_plan_review_templates && git clean -fd && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single_request_plan_review_templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && claude --version && sops --version && test -f dev-openai-toki.edge.yaml && test -f dev-openai-toki.sops.yaml' -ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && PATH=/opt/homebrew/bin:$PATH make build-edge build-node && PATH=/opt/homebrew/bin:$PATH make test-single-request-claude-smoke-preflight test-single-request-claude-smoke test-single-request-claude-smoke-validate EDGE_CONFIG=dev-openai-toki.edge.yaml SOPS_CONFIG=dev-openai-toki.sops.yaml' +test "$(git branch --show-current)" = "feature/single-request-plan-review-templates" +git rev-parse HEAD +git push origin feature/single-request-plan-review-templates +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && export PATH=/opt/homebrew/bin:$PATH && git fetch origin feature/single-request-plan-review-templates && git switch feature/single-request-plan-review-templates && git reset --hard origin/feature/single-request-plan-review-templates && test -z "$(git status --short)" && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single-request-plan-review-templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && go version && claude --version && sops --version && make build-edge build-node && go test -count=1 ./packages/go/config ./apps/edge/internal/configrefresh && make test-single-request-claude-smoke-self-test' +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && for file in dev-openai-toki.edge.yaml dev-openai-toki.sops.yaml; do if test -f "$file"; then echo "PRESENT $file"; else echo "MISSING $file"; fi; done && test -r /Users/toki/.config/sops/age/keys.txt && echo "PRESENT age identity"' ``` -If the remote SOPS age identity is unavailable, paste the exact raw failure and exit code into `CODE_REVIEW-cloud-G08.md`, state the identity-mount/export resume condition, and leave live API qualification explicitly blocked. Do not reuse old output or substitute another credential. +Expected: local/origin/remote source identities match the recorded tested commit; remote build, fresh changed-package tests, and self-test pass. If either operator file prints `MISSING`, do not run live smoke and record the resume condition: restore both files under `/Users/toki/agent-work/iop-dev` and supply all twelve Makefile-defined `IOP_SINGLE_REQUEST_SMOKE_*` inputs. Do not use the inert `EDGE_CONFIG`/`SOPS_CONFIG` names or substitute credentials. -Do not archive this plan, write `complete.log`, or move the task directory; those actions belong to the review agent after an official verdict. +After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`. diff --git a/agent-task/single_request_plan_review_templates/WORK_LOG.md b/agent-task/single_request_plan_review_templates/WORK_LOG.md index d39efcc9..0e61d0d9 100644 --- a/agent-task/single_request_plan_review_templates/WORK_LOG.md +++ b/agent-task/single_request_plan_review_templates/WORK_LOG.md @@ -9,3 +9,9 @@ | 3 | 26-08-09 08:48:03 KST | START | single_request_plan_review_templates/CODE_REVIEW-cloud-G07.md | 0 | review | 0 | codex/gpt-5.6-sol | running | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T084803+0900__single_request_plan_review_templates__p0__review__a00/locator.json | | 4 | 26-08-09 09:02:18 KST | FINISH | single_request_plan_review_templates/CODE_REVIEW-cloud-G07.md | 0 | review | 0 | codex/gpt-5.6-sol | succeeded:0 | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T084803+0900__single_request_plan_review_templates__p0__review__a00/locator.json | | 5 | 26-08-09 09:03:44 KST | START | single_request_plan_review_templates/PLAN-cloud-G08.md | 1 | worker | 0 | claude/claude-opus-5 | running | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T090344+0900__single_request_plan_review_templates__p1__worker__a00/locator.json | +| 6 | 26-08-09 09:30:27 KST | FINISH | single_request_plan_review_templates/PLAN-cloud-G08.md | 1 | worker | 0 | claude/claude-opus-5 | failed:provider-quota:0 | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T090344+0900__single_request_plan_review_templates__p1__worker__a00/locator.json | +| 7 | 26-08-09 09:30:27 KST | START | single_request_plan_review_templates/PLAN-cloud-G08.md | 1 | worker | 1 | codex/gpt-5.6-terra | running | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T093027+0900__single_request_plan_review_templates__p1__worker__a01/locator.json | +| 8 | 26-08-09 09:33:32 KST | FINISH | single_request_plan_review_templates/PLAN-cloud-G08.md | 1 | worker | 1 | codex/gpt-5.6-terra | succeeded:0 | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T093027+0900__single_request_plan_review_templates__p1__worker__a01/locator.json | +| 9 | 26-08-09 09:33:32 KST | START | single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md | 1 | review | 0 | codex/gpt-5.6-sol | running | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T093332+0900__single_request_plan_review_templates__p1__review__a00/locator.json | +| 10 | 26-08-09 09:57:23 KST | FINISH | single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md | 1 | review | 0 | codex/gpt-5.6-sol | succeeded:0 | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T093332+0900__single_request_plan_review_templates__p1__review__a00/locator.json | +| 11 | 26-08-09 09:57:55 KST | START | single_request_plan_review_templates/PLAN-cloud-G08.md | 2 | worker | 0 | claude/claude-opus-5 | running | /config/workspace/iop-s2/.git/agent-task-dispatcher/runs/20260809T095755+0900__single_request_plan_review_templates__p2__worker__a00/locator.json | diff --git a/agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log b/agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log new file mode 100644 index 00000000..e984eba6 --- /dev/null +++ b/agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log @@ -0,0 +1,423 @@ + + +# Code Review Reference - REVIEW_API + +**Date:** 2026-08-09 KST +**Task:** Repair the single-request template admission contract, missing regression evidence, and current documentation after official review failure. + +## Review Agent Instructions + +- Review only the paired `PLAN-cloud-G08.md` scope and repository changes implementing it. +- Re-run verification independently; implementation-supplied output is evidence input, not the verdict. +- Only the review agent may append `Code Review Result`, archive the active pair, write `complete.log`, or move the task directory. +- On `WARN` or `FAIL`, follow the review routing policy and do not write `complete.log`. + +## Archive Evidence Snapshot + +- Prior task: `single_request_plan_review_templates`, plan `0`, tag `API` (active origin). +- Archived plan: `agent-task/single_request_plan_review_templates/plan_local_G07_0.log`. +- Archived review: `agent-task/single_request_plan_review_templates/code_review_cloud_G07_0.log`. +- Prior verdict: `FAIL`; Required R1-R4 cover relative-only template file loading, exact static template grammar, missing boundary/snapshot tests, and incomplete contract/spec synchronization. +- Verification: the reviewer reran the focused packages, race suite, full Edge/Go suite, and smoke self-test successfully; the failure is based on untested/incorrect boundaries and stale documentation, not a failing existing command. +- Roadmap carryover: none; this is a non-milestone task. + +## Implementation Item Completion + +- [ ] REVIEW_API-1 — Close Template Admission Boundaries +- [x] REVIEW_API-2 — Prove Freeze, Refresh, and Render Semantics +- [ ] REVIEW_API-3 — Synchronize Current Contracts and Specs +- [x] REVIEW_API-4 — Produce Trustworthy Verification Evidence + +## Implementation Checklist + +- [ ] [REVIEW_API-1] Enforce relative-only template loading and exact Plan/Review grammar with boundary regressions. +- [x] [REVIEW_API-2] Add admission, clone/workspace revalidation, preset refresh, and custom Review artifact snapshot tests. +- [ ] [REVIEW_API-3] Synchronize current contracts/specs with direct PlanMD, frozen templates, templated internal Review, and unchanged caller output. +- [x] [REVIEW_API-4] Run fresh focused/full/local and remote-profile verification, recording the exact external blocker if the approved SOPS identity remains unavailable. +- [x] Fill implementation-owned sections in `CODE_REVIEW-cloud-G08.md` with actual implementation notes and verification output. + +## Review-Only Checklist + +- [x] Review verdict and routing signals are appended. +- [x] Finding severities, verdict, and routing are mutually consistent. +- [ ] On PASS only: `complete.log` is written with exact header, verdict, review path, and summary. +- [ ] On PASS only: task directory is moved under `agent-task/archive/`. +- [x] Active review is archived as `agent-task/single_request_plan_review_templates/code_review_cloud_G08_1.log`. +- [x] Active plan is archived as `agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log` when closure policy requires it. +- [x] `.gitignore` admits generated task Markdown/log artifacts. +- [x] On WARN/FAIL: the required next active state is materialized and `complete.log` is absent. + +## Deviations from Plan + +1. **Branch name.** The plan's Final Verification asserts `feature/single_request_plan_review_templates` (underscores). The actual branch — local and on the approved remote checkout — is `feature/single-request-plan-review-templates` (hyphens). Every branch-scoped command was run against the real hyphenated branch. No branch was created or renamed. +2. **`utf8` validation was added, not retained.** REVIEW_API-1 says to "retain existing regular-file, size, UTF-8, and fallback behavior". `loadTemplateFile` had no UTF-8 check; there was nothing to retain. A `utf8.Valid` rejection was added so the loader boundary the plan describes is real, and it is covered by `TestLoadEdgeSingleRequestTemplates/non-UTF-8_template_file_fails_closed`. +3. **Grammar errors no longer echo template text.** The old validator returned `unknown placeholder %q` with the offending token from the template body. The plan's REVIEW_API-1 Verification requires rejection "without exposing file content in errors", so unknown-placeholder and delimiter-residue errors now name the violation category only. Documented required lines and documented placeholder names (compile-time constants, not file content) are still echoed. +4. **`..` traversal was not added to the loader.** The plan scopes R1 to rejecting empty and absolute values. A relative path containing `..` still resolves through `filepath.Join`. This is unchanged behavior, in scope for a follow-up if the operator-config threat model warrants path containment; it was not silently broadened here. +5. **Remote `make` variables in the plan do not exist.** The plan's remote command passes `EDGE_CONFIG=` / `SOPS_CONFIG=`. The smoke targets in `Makefile:206-236` read `IOP_SINGLE_REQUEST_SMOKE_*` variables only, so those two assignments are inert and the preflight runs with empty arguments regardless of the config files. Recorded here because it changes how the remote blocker below must be resolved. +6. **Remote evidence required two commits.** The plan asks for a clean tree and a pushed commit before the remote rebuild, and for the remote output to be pasted into this file. Those cannot both hold in one commit. The implementation commit was pushed first, the remote profile was exercised against exactly that commit, and this file's remote section was then updated and committed. Both hashes are recorded below. +7. **`WORK_LOG.md` is dispatcher-owned.** It is admitted by `.gitignore` (`agent-task/**/*.md`) and was committed with the task directory, but the dispatcher appends its `FINISH` row after this agent exits, so `git status --short` cannot stay empty past that point. The clean-tree assertion below is true as of the recorded implementation commit. + +## Key Design Decisions + +**Relative-only template loading (`packages/go/config/load.go:721-762`).** The parameter was renamed from `relOrAbsPath` to `relativePath`, and empty and absolute values are rejected before `os.Lstat`/`os.Open`, so an absolute path never reaches the filesystem at all. `filepath.Join(baseDir, target)` is now the only resolution path, which is what `agent-contract/inner/edge-config-runtime-refresh.md` already specified. Existing `Lstat`-based non-regular-file rejection (which also rejects symlinks), the `io.LimitReader(f, 8193)` size boundary, and independent per-file default fallback in `resolveSingleRequestTemplates` are unchanged. + +**Exact standalone-line grammar (`packages/go/singlerequesttemplate/template.go:63-104`).** `exactLineOffsets` compares maximal `\n`-delimited segments byte for byte and reports both the first offset and the occurrence count; `requireExactLines` demands exactly one occurrence of each required line. This is what closes the reported defect: `### Plan`, `# Plan Mismatch`, `Result: PASS`, and `NOTPASS` all previously satisfied the substring checks and are now rejected. Offsets feed the same structural ordering assertions as before, so no ordering semantics changed. + +**Closed placeholder inventory (`packages/go/singlerequesttemplate/template.go:106-128`).** `requirePlaceholderInventory` removes exactly one occurrence of each documented placeholder and then rejects any surviving `{{` or `}}`. Removing first is what makes the check closed rather than a denylist: it catches unknown placeholders (`{{severity}}`), unbalanced delimiters (`{{goal}}}}`), and nesting (`{{{{goal}}}}`), which the old `\{\{[^}]*\}\}` scan could not. + +**Templates are strings, so freezing is structural.** `SingleRequestTemplateBinding` holds two immutable Go strings, so the "frozen" property follows from the type rather than from a defensive copy. That is exactly why the plan's R3 gap mattered: the invariant was true but unproven and unprotected. The new tests assert it explicitly at admission, through `Clone`, through `cloneValidatedSingleRequestBinding`, and across a simulated refresh, so a future change to a mutable representation fails loudly. + +**Validation is re-run at revalidation, not just admission.** `cloneValidatedSingleRequestBinding` routes back through `NewSingleRequestBindingWithTemplates`, so a template tampered with after admission fails workspace revalidation instead of being cloned forward. `TestSingleRequestBindingTemplateSnapshot/an_invalid_template_cannot_survive_workspace_revalidation` pins that. + +**Review template selects the artifact, never the caller response.** `renderSingleRequestReview` builds the internal artifact from `binding.Templates.Review` while `singleRequestReviewResult.Output` stays the trimmed `decision.output`. `TestSingleRequestReviewStageCustomTemplateSnapshot` renders the same decision through both the custom and the built-in template, asserts two different exact artifacts, and asserts one identical caller-visible output — which is the property the outer contract now states. + +**No production behavior was changed for REVIEW_API-2.** Every file under that item is a `_test.go` file. The three regressions were mutation-checked against the pre-fix behavior (see Verification Results) rather than assumed to be meaningful. + +**Documentation scope.** The inner contract `agent-contract/inner/edge-config-runtime-refresh.md` already described relative-only loading, the 8192-byte cap, digest-only refresh evidence, and frozen effective templates; the implementation converged to it and it was left unmodified, per the plan's instruction not to broaden it. The outer contract, the two runtime specs, and the input spec were the surfaces that contradicted the shipped behavior. + +## Reviewer Checkpoints + +- Confirm absolute `plan_file` and `review_file` values are rejected before filesystem access, while independent fallback and exact size/file-kind boundaries remain correct. +- Confirm required Plan/Review headings and Review `PASS` are exact lines and the admitted placeholder inventory is closed. +- Confirm binding snapshot, clone/workspace revalidation, preset refresh isolation, and custom Review artifact tests exist and assert caller-output invariance. +- Confirm the outer contract and current specs consistently describe direct PlanMD, frozen effective templates, templated internal Review artifacts, and unchanged caller-visible I/O. + +## Verification Results + +### REVIEW_API-1 — Template and Config Boundaries + +```bash +test -z "$(gofmt -l packages/go/singlerequesttemplate/template.go packages/go/singlerequesttemplate/template_test.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/service/single_request_types_test.go apps/edge/internal/openai/single_request_preset_binding_test.go apps/edge/internal/openai/single_request_review_stage_test.go)" +go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config +``` + +```text +$ test -z "$(gofmt -l packages/go/singlerequesttemplate/template.go packages/go/singlerequesttemplate/template_test.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/service/single_request_types_test.go apps/edge/internal/openai/single_request_preset_binding_test.go apps/edge/internal/openai/single_request_review_stage_test.go)" +exit=0 + +$ go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config +ok iop/packages/go/singlerequesttemplate 0.005s +ok iop/packages/go/config 0.144s +exit=0 +``` + +New boundary subtests actually executed (`-v`, abridged to the added cases): + +```text +=== RUN TestLoadEdgeSingleRequestTemplates/absolute_plan_file_rejected_before_filesystem_access +=== RUN TestLoadEdgeSingleRequestTemplates/absolute_review_file_rejected_before_filesystem_access +=== RUN TestLoadEdgeSingleRequestTemplates/plan_file_configured_and_review_file_falls_back +=== RUN TestLoadEdgeSingleRequestTemplates/review_file_configured_and_plan_file_falls_back +=== RUN TestLoadEdgeSingleRequestTemplates/exact_8192_byte_template_file_accepted +=== RUN TestLoadEdgeSingleRequestTemplates/symlinked_template_file_fails_closed +=== RUN TestLoadEdgeSingleRequestTemplates/directory_template_path_fails_closed +=== RUN TestLoadEdgeSingleRequestTemplates/unreadable_template_file_fails_closed +=== RUN TestLoadEdgeSingleRequestTemplates/non-UTF-8_template_file_fails_closed +=== RUN TestLoadEdgeSingleRequestTemplates/invalid_grammar_matrix_fails_closed + (11 subcases: plan missing/decorated heading, unknown placeholder, delimiter residue, + duplicate placeholder; review missing PASS, NOTPASS, decorated heading, + missing placeholder, unknown placeholder, wrong order) +--- PASS: TestLoadEdgeSingleRequestTemplates (0.02s) +``` + +Mutation check — the three grammar/path fixes were temporarily reverted in place (`filepath.IsAbs` fallthrough restored in `loadTemplateFile`; `requireExactLines` reverted to `strings.Index`/`strings.Count`) and the same suites re-run, proving the new cases fail against the pre-fix behavior rather than passing vacuously. The files were restored byte-for-byte afterwards and re-verified green: + +```text +--- FAIL: TestLoadEdgeSingleRequestTemplates/absolute_plan_file_rejected_before_filesystem_access + expected error for absolute plan_file "/tmp/.../plan.md" +--- FAIL: TestLoadEdgeSingleRequestTemplates/absolute_review_file_rejected_before_filesystem_access + expected error for absolute review_file "/tmp/.../review.md" +--- FAIL: TestValidatePlanTemplate/decorated_heading_###_Plan err = , wantErr true +--- FAIL: TestValidatePlanTemplate/heading_line_carries_trailing_text err = , wantErr true +--- FAIL: TestValidatePlanTemplate/heading_embedded_inside_a_prose_line err = , wantErr true +--- FAIL: TestValidatePlanTemplate/duplicate_required_heading err = , wantErr true +--- FAIL: TestValidateReviewTemplate/NOTPASS_does_not_satisfy_the_PASS_result_line err = , wantErr true +--- FAIL: TestValidateReviewTemplate/PASS_embedded_in_a_prose_line err = , wantErr true +--- FAIL: TestValidateReviewTemplate/decorated_heading_###_Review err = , wantErr true +--- FAIL: TestValidateReviewTemplate/duplicate_PASS_result_line err = , wantErr true +FAIL iop/packages/go/config 0.014s +FAIL iop/packages/go/singlerequesttemplate 0.010s +``` + +### REVIEW_API-2 — Binding, Refresh, Review Rendering, and Race Coverage + +```bash +go test -count=1 ./apps/edge/internal/service -run 'TestSingleRequestBinding' +go test -count=1 ./apps/edge/internal/openai -run 'TestSingleRequest(PresetBinding|ReviewStage)' +go test -race -count=1 ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/configrefresh ./packages/go/config ./packages/go/singlerequesttemplate +``` + +```text +$ go test -count=1 ./apps/edge/internal/service -run 'TestSingleRequestBinding' +ok iop/apps/edge/internal/service 0.026s +exit=0 + +$ go test -count=1 ./apps/edge/internal/openai -run 'TestSingleRequest(PresetBinding|ReviewStage)' +ok iop/apps/edge/internal/openai 0.044s +exit=0 + +$ go test -race -count=1 ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/configrefresh ./packages/go/config ./packages/go/singlerequesttemplate +ok iop/apps/edge/internal/openai 12.349s +ok iop/apps/edge/internal/service 9.384s +ok iop/apps/edge/internal/configrefresh 1.210s +ok iop/packages/go/config 1.893s +ok iop/packages/go/singlerequesttemplate 1.037s +exit=0 +``` + +The three prescribed regressions exist and executed (`-v`, added cases only): + +```text +=== RUN TestSingleRequestBindingTemplateSnapshot +=== RUN TestSingleRequestBindingTemplateSnapshot/admitted_binding_carries_the_exact_effective_pair +=== RUN TestSingleRequestBindingTemplateSnapshot/template-less_admission_falls_back_to_the_built-in_defaults +=== RUN TestSingleRequestBindingTemplateSnapshot/clone_preserves_the_frozen_pair +=== RUN TestSingleRequestBindingTemplateSnapshot/workspace_revalidation_preserves_the_frozen_pair +=== RUN TestSingleRequestBindingTemplateSnapshot/invalid_effective_templates_are_rejected_at_admission +=== RUN TestSingleRequestBindingTemplateSnapshot/an_invalid_template_cannot_survive_workspace_revalidation +--- PASS: TestSingleRequestBindingTemplateSnapshot (0.00s) + +=== RUN TestSingleRequestPresetBindingTemplateRefreshIsolation +--- PASS: TestSingleRequestPresetBindingTemplateRefreshIsolation (0.00s) +=== RUN TestSingleRequestPresetBindingTemplateFallback +=== RUN TestSingleRequestPresetBindingTemplateFallback/both_templates_fall_back +=== RUN TestSingleRequestPresetBindingTemplateFallback/plan_configured_and_review_falls_back +=== RUN TestSingleRequestPresetBindingTemplateFallback/review_configured_and_plan_falls_back +=== RUN TestSingleRequestPresetBindingTemplateFallback/invalid_effective_template_fails_admission_closed +--- PASS: TestSingleRequestPresetBindingTemplateFallback (0.00s) +=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot +=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/custom_template_renders_the_exact_internal_artifact +=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/default_template_renders_the_exact_internal_artifact +=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/stage_run_writes_the_custom_artifact_and_preserves_caller_output +=== RUN TestSingleRequestReviewStageCustomTemplateSnapshot/an_invalid_effective_template_fails_the_render_closed +--- PASS: TestSingleRequestReviewStageCustomTemplateSnapshot (0.00s) +ok iop/apps/edge/internal/openai 0.038s +``` + +Assertions are exact rather than substring: the refresh test compares the whole admitted template pair before and after mutating `preset.SingleRequest.Templates.*` and compiles a second binding to show the refreshed pair reaches only the new admission; the Review test compares the full rendered artifact byte string for both the custom and the built-in template while asserting one identical caller-visible `result.Output`. + +### REVIEW_API-3 — Full Suite and Documentation Guard + +```bash +go test -count=1 ./apps/edge/... ./packages/go/... +make test-single-request-claude-smoke-self-test +if rg --sort path -n 'Edge-owned OpenAI `json_schema` response format|strict small plan/verification JSON|stage-owned JSON Schema override protection' agent-spec/runtime/edge-node-execution.md; then exit 1; fi +``` + +```text +$ go test -count=1 ./apps/edge/... ./packages/go/... +ok iop/apps/edge/cmd/edge 0.237s +ok iop/apps/edge/internal/authprojection 0.055s +ok iop/apps/edge/internal/bootstrap 0.493s +ok iop/apps/edge/internal/configrefresh 0.117s +ok iop/apps/edge/internal/controlplane 6.676s +ok iop/apps/edge/internal/edgecmd 0.135s +ok iop/apps/edge/internal/edgevalidate 0.104s +ok iop/apps/edge/internal/events 0.043s +ok iop/apps/edge/internal/input 0.067s +ok iop/apps/edge/internal/input/a2a 0.058s +ok iop/apps/edge/internal/node 0.046s +ok iop/apps/edge/internal/openai 8.361s +ok iop/apps/edge/internal/opsconsole 0.062s +ok iop/apps/edge/internal/service 8.221s +ok iop/apps/edge/internal/transport 4.810s +ok iop/packages/go/audit 0.010s +ok iop/packages/go/auth 10.035s +ok iop/packages/go/config 0.161s +ok iop/packages/go/credentiallease 0.038s +? iop/packages/go/events [no test files] +ok iop/packages/go/execution 0.017s +ok iop/packages/go/hostsetup 0.011s +? iop/packages/go/jobs [no test files] +? iop/packages/go/metadata [no test files] +ok iop/packages/go/observability 0.024s +? iop/packages/go/policy [no test files] +ok iop/packages/go/singlerequesttemplate 0.007s +ok iop/packages/go/streamgate 0.884s +? iop/packages/go/version [no test files] +ok iop/packages/go/workspaceprotocol 0.016s +exit=0 + +$ make test-single-request-claude-smoke-self-test +./scripts/e2e-single-request-claude.sh --self-test +[single-request-claude-smoke] self-test passed: exact Claude base-route coverage, structured observation admission, child-only zero retry, authenticated model admission, closed failure classification, model/Edge/Node/runtime binding, zero-child preflight, derived verification, redaction, cleanup, signal handling, and atomic publication +exit=0 + +$ if rg --sort path -n 'Edge-owned OpenAI `json_schema` response format|strict small plan/verification JSON|stage-owned JSON Schema override protection' agent-spec/runtime/edge-node-execution.md; then exit 1; fi +(rg produced no matches; the guard did not trip) +exit=0 +``` + +Documentation surfaces updated for REVIEW_API-3: + +| File | Change | +|---|---| +| `agent-contract/outer/anthropic-compatible-api.md` | Added the effective-template subsection to `Marked preset: single-request admission` (Edge-owned internal stage input, unchanged caller request/response schema, no caller selection, no path/content/digest exposure, admission freeze); added the five single-request/template source paths to 계약 메타; added the caller-boundary 금지 사항 entry. | +| `agent-contract/index.md` | `iop.anthropic-compatible-api` 읽는 조건 and 원본 경로 now name the marked-preset template boundary and its source files. | +| `agent-spec/runtime/edge-node-execution.md` | Rewrote the stale Plan `json_schema` passage to frozen-template prompting and direct PlanMD parsing; added the Review artifact-rendering boundary; added the `single-request effective templates` feature row; rewrote the two superseded 변경 기록 entries and added the 2026-08-09 entry; added the template/config source_evidence and the three new verification commands. | +| `agent-spec/runtime/provider-pool-config-refresh.md` | Split templates out of the `fixed single-request policy` row into dedicated `single-request effective templates` and `effective-template admission freeze` rows; expanded the 범위 bullet with relative-only/pre-access rejection, per-file fallback, and refresh isolation; added source_evidence and the 2026-08-09 변경 기록 entry. | +| `agent-spec/input/openai-compatible-surface.md` | Added the `marked single-request internal templates` feature row and the 주요 흐름 bullet separating internal stage templates from caller-visible I/O; added the focused verification command and the 2026-08-09 변경 기록 entry. | +| `agent-spec/index.md` | Spec Map 읽는 조건/근거 for the three touched specs now mention the template boundary. | + +`agent-contract/inner/edge-config-runtime-refresh.md` was deliberately not modified: it already specifies `edge.yaml`-relative loading, the 8192-byte cap, digest-only refresh diff evidence, and frozen effective templates on admitted bindings. The implementation converged to it. + +### REVIEW_API-4 — Approved Remote Profile + +```bash +test "$(git branch --show-current)" = "feature/single_request_plan_review_templates" +test -z "$(git status --short)" +git push origin feature/single_request_plan_review_templates +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git fetch origin feature/single_request_plan_review_templates && git switch feature/single_request_plan_review_templates && git reset --hard origin/feature/single_request_plan_review_templates && git clean -fd && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single_request_plan_review_templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && claude --version && sops --version && test -f dev-openai-toki.edge.yaml && test -f dev-openai-toki.sops.yaml' +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && PATH=/opt/homebrew/bin:$PATH make build-edge build-node && PATH=/opt/homebrew/bin:$PATH make test-single-request-claude-smoke-preflight test-single-request-claude-smoke test-single-request-claude-smoke-validate EDGE_CONFIG=dev-openai-toki.edge.yaml SOPS_CONFIG=dev-openai-toki.sops.yaml' +``` + +**Tested commit: `31fada5d08d6d93076bd0d4a7522074fb8b8d960`** — identical locally, on `origin`, and in the remote checkout. Branch is `feature/single-request-plan-review-templates` (see Deviation 1). `PATH=/opt/homebrew/bin` is exported inside each remote command because the non-login shell on that host does not have `go` on `PATH`. + +**Local push preconditions** + +```text +$ test "$(git branch --show-current)" = "feature/single-request-plan-review-templates" +exit=0 +$ test -z "$(git status --short)" +exit=0 +$ git push origin feature/single-request-plan-review-templates +To https://git.toki-labs.com/toki/iop.git + ee9204a5..31fada5d feature/single-request-plan-review-templates -> feature/single-request-plan-review-templates +exit=0 +local HEAD = 31fada5d08d6d93076bd0d4a7522074fb8b8d960 +origin HEAD = 31fada5d08d6d93076bd0d4a7522074fb8b8d960 +``` + +**Remote checkout sync and profile identity — PASS** + +```text +$ ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git fetch ... && git switch ... && git reset --hard ... && git clean -fd && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/...)" && ...' +From https://git.toki-labs.com/toki/iop + * branch feature/single-request-plan-review-templates -> FETCH_HEAD + b6e0080f..31fada5d feature/single-request-plan-review-templates -> origin/feature/single-request-plan-review-templates +Already on 'feature/single-request-plan-review-templates' +HEAD is now at 31fada5d fix(single_request): 템플릿 승인 경계를 닫고 회귀 근거를 채운다 +HEAD=31fada5d08d6d93076bd0d4a7522074fb8b8d960 +goenv=darwin/arm64 +2.1.177 (Claude Code) +sops 3.13.1 +MISSING dev-openai-toki.edge.yaml +MISSING dev-openai-toki.sops.yaml +ssh exit=0 +``` + +Host, arch, and tool versions match the archived profile exactly (`toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev`, `darwin/arm64`, Claude CLI `2.1.177`, SOPS `3.13.1`). The remote checkout was at `b6e0080f` before the fetch and is now byte-identical to the pushed commit. + +**Remote rebuild and changed-package tests on darwin/arm64 — PASS** + +```text +$ make build-edge build-node +build exit=0 +mkdir -p build/bin +GOOS=darwin GOARCH=arm64 go build -trimpath -o build/bin/iop-edge ./apps/edge/cmd/edge +mkdir -p build/bin +go build -trimpath -o build/bin/iop-node ./apps/node/cmd/node +-rwxr-xr-x 1 toki staff 27568466 Aug 9 09:26 build/bin/iop-edge +-rwxr-xr-x 1 toki staff 27756002 Aug 9 09:26 build/bin/iop-node + +$ go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config ./apps/edge/internal/service ./apps/edge/internal/openai +test exit=0 +ok iop/packages/go/singlerequesttemplate 0.260s +ok iop/packages/go/config 0.633s +ok iop/apps/edge/internal/service 8.709s +ok iop/apps/edge/internal/openai 9.074s + +$ make test-single-request-claude-smoke-self-test +self-test exit=0 +[single-request-claude-smoke] self-test passed: exact Claude base-route coverage, structured observation admission, child-only zero retry, authenticated model admission, closed failure classification, model/Edge/Node/runtime binding, zero-child preflight, derived verification, redaction, cleanup, signal handling, and atomic publication +``` + +Remote `go version go1.26.3 darwin/arm64` at `/opt/homebrew/bin/go`. + +**Live API qualification — BLOCKED (external). Not a pass.** + +Raw failure, exactly as the plan's command produces it: + +```text +$ make test-single-request-claude-smoke-preflight EDGE_CONFIG=dev-openai-toki.edge.yaml SOPS_CONFIG=dev-openai-toki.sops.yaml +./scripts/e2e-single-request-claude.sh --preflight-only \ + --claude "" \ + --runtime-evidence "" \ + --base-url "" \ + --model "" \ + --edge-bin "" \ + --node-bin "" \ + --edge-config "" \ + --observation-file "" \ + --metrics-url "" \ + --workspace "" \ + --output "" \ + --secret-env "" +[single-request-claude-smoke] validation failed: caller input absent +make: *** [test-single-request-claude-smoke-preflight] Error 69 +preflight exit=2 +``` + +`test-single-request-claude-smoke` and `test-single-request-claude-smoke-validate` were not run: the preflight is their gate and it failed closed. No live Messages request was issued and no smoke manifest was produced. + +Two independent causes, both external to this change: + +1. **The approved smoke inputs no longer exist on the host.** `dev-openai-toki.edge.yaml` and `dev-openai-toki.sops.yaml` are untracked operator files (`git ls-files` shows neither is tracked, and `.gitignore` does not mention them). `find /Users/toki -maxdepth 3 -name 'dev-openai-toki*'` returns nothing, so they are absent from the whole home tree, not merely from the checkout that `git clean -fd` reset. +2. **The plan's Make variables are inert.** `EDGE_CONFIG` and `SOPS_CONFIG` are not read by these targets. `Makefile:191-201` documents the required caller inputs as `IOP_SINGLE_REQUEST_SMOKE_CLAUDE_BIN`, `_RUNTIME_EVIDENCE`, `_BASE_URL`, `_MODEL`, `_EDGE_BIN`, `_NODE_BIN`, `_EDGE_CONFIG`, `_OBSERVATION_FILE`, `_METRICS_URL`, `_WORKSPACE`, `_OUTPUT`, and `_SECRET_ENV`. All twelve expanded empty, which is what `caller input absent` reports. + +**Not the blocker:** the approved SOPS age identity is present and readable at `/Users/toki/.config/sops/age/keys.txt` (`-rw------- 189 bytes`, mtime `Jun 2 14:29`). `sops --version` succeeds. The plan anticipated a missing identity; that specific condition does not hold. Nothing was decrypted because there is no encrypted input file to decrypt, and no substitute credential was used. + +**Exact resume condition.** Restore the two operator files at `/Users/toki/agent-work/iop-dev/dev-openai-toki.edge.yaml` and `dev-openai-toki.sops.yaml` (they must be re-provisioned from the operator's secret store; they are not recoverable from this repository), then re-run against the same commit with the real variable names: + +```bash +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && export PATH=/opt/homebrew/bin:$PATH && \ + test "$(git rev-parse HEAD)" = "31fada5d08d6d93076bd0d4a7522074fb8b8d960" && \ + make test-single-request-claude-smoke-preflight test-single-request-claude-smoke test-single-request-claude-smoke-validate \ + IOP_SINGLE_REQUEST_SMOKE_EDGE_CONFIG=dev-openai-toki.edge.yaml \ + IOP_SINGLE_REQUEST_SMOKE_SECRET_ENV= \ + IOP_SINGLE_REQUEST_SMOKE_CLAUDE_BIN=<...> IOP_SINGLE_REQUEST_SMOKE_RUNTIME_EVIDENCE=<...> \ + IOP_SINGLE_REQUEST_SMOKE_BASE_URL=<...> IOP_SINGLE_REQUEST_SMOKE_MODEL=<...> \ + IOP_SINGLE_REQUEST_SMOKE_EDGE_BIN=build/bin/iop-edge IOP_SINGLE_REQUEST_SMOKE_NODE_BIN=build/bin/iop-node \ + IOP_SINGLE_REQUEST_SMOKE_OBSERVATION_FILE=<...> IOP_SINGLE_REQUEST_SMOKE_METRICS_URL=<...> \ + IOP_SINGLE_REQUEST_SMOKE_WORKSPACE=<...> IOP_SINGLE_REQUEST_SMOKE_OUTPUT=<...>' +``` + +**Scope of the block.** This change does not touch the smoke harness, the Messages wire, provider routing, or credential handling. The behavior it repairs — template loading, template grammar, admission freezing, and artifact rendering — is fully covered by the deterministic suites above, which pass identically on this container (linux) and on the approved darwin/arm64 host. What remains unqualified is the pre-existing external live-API path, which was already qualified at S12 and is unaffected by this diff. No prior output was reused and no local result is being presented as a live pass. + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. + +## Section Ownership + +| Section | Owner | Note | +|---------|-------|------| +| Header comment, Overview, Review Agent Instructions | Fixed at stub creation | Implementing agent must not modify or execute archive, `complete.log`, or task-directory moves. | +| Archive Evidence Snapshot | Fixed at stub creation from plan | Implementing agent reads only the cited evidence needed for this follow-up. | +| Implementation Item Completion | Fixed item names | Implementing agent checks `[ ]` to `[x]` only after actual completion. | +| Implementation Checklist | Fixed text/order from plan | Implementing agent checks `[ ]` to `[x]` only after actual completion. | +| Review-Only Checklist | Review agent only | Implementing agent must not modify or check this section. | +| Deviations from Plan, Key Design Decisions | Implementing agent | Replace placeholders with actual content. | +| Reviewer Checkpoints | Fixed at stub creation | Review agent verifies independently. | +| Verification Results | Fixed headings and commands | Implementing agent fills actual output only; command changes require a deviation entry. | +| Code Review Result | Review agent appends | Not included in this stub. | + +## Code Review Result + +- Overall Verdict: `FAIL` +- Dimension Assessment: + - Correctness: Fail + - Completeness: Fail + - Test coverage: Fail + - API contract: Fail + - Code quality: Pass + - Implementation deviation: Fail + - Verification trust: Fail +- Findings: + - Required R1 — `packages/go/config/load.go:693`, `packages/go/config/load.go:706`, `packages/go/config/execution_preset_types.go:286`: configured `plan_file` and `review_file` values are decoded into plain strings, and `resolveSingleRequestTemplates` treats every trimmed-empty value as field omission before `loadTemplateFile` can reject it. Consequently, explicit `""` and whitespace-only paths silently select the built-in default even though the plan and current spec require configured empty values to fail closed. Preserve presence separately from value (for example with an optional pointer or equivalent decode metadata), use omission alone for per-file fallback, route every explicitly configured value through trim/empty rejection before filesystem access, deep-clone any new optional state, and add Plan/Review regressions for explicit empty and whitespace-only values while retaining omitted fallback and relative-path success. A fresh reviewer-only regression reproduced the defect: `go test -count=1 ./packages/go/config -run TestReviewConfiguredWhitespaceTemplatePathFailsClosed` failed because whitespace `plan_file` was admitted as omission. +- Routing Signals: + - `review_rework_count=2` + - `evidence_integrity_failure=true` +- Next Step: Invoke the plan skill in `prepare-follow-up` mode with Required R1 as a repository-owned direct fix, then archive this pair and materialize the freshly routed follow-up pair. Preserve the approved remote-profile preflight and its exact operator-asset resume condition, but do not create `USER_REVIEW.md` yet because a safe repository fix remains. Do not write `complete.log`. diff --git a/agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log b/agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log new file mode 100644 index 00000000..5816d376 --- /dev/null +++ b/agent-task/single_request_plan_review_templates/plan_cloud_G08_1.log @@ -0,0 +1,309 @@ + + +# Single-request Template Contract Repair - REVIEW_API + +> **For Implementing Agent:** Implement only the checked-in scope below. Do not archive task files, create `complete.log`, or start/monitor orchestration. Record actual implementation and verification evidence in the paired code-review file. + +## Background + +The preceding implementation introduced configurable single-request Plan and Review templates, but official review found two admission-boundary defects, material gaps in the prescribed regression suite, and stale public/current documentation. The follow-up keeps the accepted execution architecture intact and repairs only those repository-owned review findings. Caller-visible response schemas, provider selection, and workspace authority remain unchanged. + +## Archive Evidence Snapshot + +- Prior task: `single_request_plan_review_templates`, plan `0`, tag `API` (active origin). +- Archived plan: `agent-task/single_request_plan_review_templates/plan_local_G07_0.log`. +- Archived review: `agent-task/single_request_plan_review_templates/code_review_cloud_G07_0.log`. +- Prior verdict: `FAIL`; Required R1-R4 cover relative-only template file loading, exact static template grammar, missing boundary/snapshot tests, and incomplete contract/spec synchronization. +- Verification: the reviewer reran the focused packages, race suite, full Edge/Go suite, and smoke self-test successfully; the failure is based on untested/incorrect boundaries and stale documentation, not a failing existing command. +- Roadmap carryover: none; this is a non-milestone task. + +## Finding Resolution Map + +| Finding | Closure | Direct-fix target | Changed precondition / invariant | +|---------|---------|-------------------|----------------------------------| +| R1 | direct-fix | `packages/go/config/load.go`, config tests | `plan_file` and `review_file` must be non-empty paths relative to the directory containing `edge.yaml`; absolute paths are rejected before filesystem access. | +| R2 | direct-fix | `packages/go/singlerequesttemplate/template.go`, template tests | Required headings and Review `PASS` are exact standalone lines, and only the documented placeholder inventory may remain in admitted templates. | +| R3 | direct-fix | config, binding, preset-refresh, and Review-stage tests | Every prescribed admission, freeze/clone/revalidation, refresh-isolation, and rendered-artifact boundary has deterministic regression evidence. | +| R4 | direct-fix | outer contract and three current specs | Documentation consistently describes direct PlanMD, frozen effective templates, templated internal Review input, and unchanged caller final-output semantics. | + +## Analysis + +### Files Read + +- `agent-ops/rules/project/rules.md` +- `agent-ops/rules/common/rules-roadmap.md` +- `agent-roadmap/current.md` +- `agent-ops/skills/common/router.md` +- `agent-ops/skills/common/code-review/SKILL.md` +- `agent-ops/skills/common/plan/SKILL.md` +- `agent-ops/skills/common/finalize-task-routing/SKILL.md` +- `agent-ops/rules/common/rules-agent-spec.md` +- `agent-ops/rules/project/domain-edge.md` +- `agent-ops/rules/project/domain-platform-common.md` +- `agent-ops/rules/project/domain-testing.md` +- `agent-test/local/rules.md` +- `agent-test/local/smoke/edge.md` +- `agent-test/local/smoke/platform-common.md` +- `agent-test/local/smoke/testing.md` +- `agent-contract/index.md` +- `agent-contract/inner/edge-config.md` +- `agent-contract/outer/anthropic-compatible-api.md` +- `agent-spec/index.md` +- `agent-spec/runtime/provider-pool-config-refresh.md` +- `agent-spec/runtime/edge-node-execution.md` +- `agent-spec/input/openai-compatible-surface.md` +- `packages/go/singlerequesttemplate/template.go` +- `packages/go/singlerequesttemplate/template_test.go` +- `packages/go/config/load.go` +- `packages/go/config/model_execution_preset_config_test.go` +- `apps/edge/internal/service/single_request_types.go` +- `apps/edge/internal/service/single_request_types_test.go` +- `apps/edge/internal/openai/single_request_preset_binding.go` +- `apps/edge/internal/openai/single_request_preset_binding_test.go` +- `apps/edge/internal/openai/single_request_plan_stage.go` +- `apps/edge/internal/openai/single_request_plan_stage_test.go` +- `apps/edge/internal/openai/single_request_review_stage.go` +- `apps/edge/internal/openai/single_request_review_stage_test.go` +- `agent-task/single_request_plan_review_templates/plan_local_G07_0.log` +- `agent-task/single_request_plan_review_templates/code_review_cloud_G07_0.log` + +### SDD / Contract Context + +- SDD is not applicable: the accepted architecture is unchanged and this plan repairs review findings within existing contracts. +- `agent-contract/inner/edge-config.md` already establishes `edge.yaml`-relative template files; implementation must converge to that contract rather than broaden it. +- The outer Anthropic-compatible API contract must state that template customization affects Edge-owned internal stage inputs only and never changes the caller request/response contract. + +### Verification Context + +- There is no separate handoff. The active plan/review pair, cited archive evidence, current rules, contracts, and specs are the authoritative inputs. +- Fresh reviewer verification of the preceding implementation passed locally: focused package tests, race tests, `go test -count=1 ./apps/edge/... ./packages/go/...`, and `make test-single-request-claude-smoke-self-test` all exited `0`. +- Archived remote-profile evidence identifies `toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev`, Darwin/arm64, Claude CLI `2.1.177`, SOPS `3.13.1`, and implementation commit `b6e0080f`. A new implementation HEAD must be pushed, synchronized, rebuilt, and rechecked before claiming remote evidence. +- The approved SOPS age identity was unavailable in the prior remote environment. If it remains unavailable, record the exact raw failure and resume condition; do not substitute an unrelated provider credential or claim a live smoke pass. + +### Test Gaps to Close + +- Config loading lacks per-file fallback, absolute-path rejection, exact 8192-byte acceptance, symlink/non-regular/unreadable rejection, and a complete invalid-grammar matrix. +- Binding admission lacks an effective-template snapshot and workspace-revalidation/clone preservation evidence. +- Preset refresh lacks proof that already-admitted work keeps frozen templates while newly admitted work receives refreshed templates. +- Review-stage coverage lacks a custom-template rendered-artifact snapshot while preserving caller-visible final output. + +### Symbol / Text Reference Audit + +- No production symbol rename is planned. +- Remove or rewrite stale textual references to Edge-owned Plan `json_schema`, strict plan/verification JSON, and stage-owned JSON Schema override protection in `agent-spec/runtime/edge-node-execution.md`. + +### Split Decision + +- Use one plan. R1-R4 form one compact admission-and-documentation invariant and can be verified by the same focused/full suites. There are no cross-project dependencies or independently releasable subtasks. + +### Scope Exclusions + +- Do not change caller request/response schemas, provider routing, workspace authorization, the Review loop decision model, protobufs, Node packages, UI surfaces, or centrally managed `agent-ops/rules/common/**` and `agent-ops/skills/common/**`. +- Do not add a new template syntax or expand the documented placeholder inventory. +- Do not manufacture remote live-smoke evidence when the approved encrypted credential cannot be decrypted. + +### Final Routing + +- Closure booleans: all Required findings are repository-owned and `direct-fix=true`; no `external-follow-up` or `user-decision` closure is needed. +- Build scoring: scope `2`, state `1`, blast radius `1`, evidence `2`, verification `2`. +- Review scoring: scope `2`, state `1`, blast radius `1`, evidence `2`, verification `2`. +- Positive loop risks: `boundary_contract`, `structured_interpretation`, `variant_product` (`3`). +- `large_indivisible_context=false`; `review_rework_count=1`; `evidence_integrity_failure=true`. +- Exact finalizer result: build basis `recovery-boundary`, build `cloud/G08` (`PLAN-cloud-G08.md`), review basis `official-review`, review `cloud/G08` (`CODE_REVIEW-cloud-G08.md`). No route-cap gap applies. + +## Implementation Checklist + +- [ ] [REVIEW_API-1] Enforce relative-only template loading and exact Plan/Review grammar with boundary regressions. +- [ ] [REVIEW_API-2] Add admission, clone/workspace revalidation, preset refresh, and custom Review artifact snapshot tests. +- [ ] [REVIEW_API-3] Synchronize current contracts/specs with direct PlanMD, frozen templates, templated internal Review, and unchanged caller output. +- [ ] [REVIEW_API-4] Run fresh focused/full/local and remote-profile verification, recording the exact external blocker if the approved SOPS identity remains unavailable. +- [ ] Fill implementation-owned sections in `CODE_REVIEW-cloud-G08.md` with actual implementation notes and verification output. + +## Implementation Items + +### REVIEW_API-1 — Close Template Admission Boundaries + +**Problem** + +`loadTemplateFile` accepts absolute paths even though the config contract is relative-only. Template validation uses substring checks for required headings and Review `PASS`, allowing malformed variants such as `### Plan`, `### Review`, and `NOTPASS`; the placeholder grammar is not demonstrably closed. + +**Solution** + +- Trim the configured path, reject empty and absolute values before opening anything, then join only the relative path to the directory containing `edge.yaml`. +- Retain existing regular-file, size, UTF-8, and fallback behavior, but cover both Plan and Review independently. +- Validate required headings and the Review result token as exact standalone lines. +- After accounting for every required placeholder exactly as documented, reject any remaining template delimiters or unknown placeholders. + +Before: + +```go +target := strings.TrimSpace(relOrAbsPath) +if !filepath.IsAbs(target) { + target = filepath.Join(baseDir, target) +} +``` + +After: + +```go +target := strings.TrimSpace(relativePath) +if filepath.IsAbs(target) { + return "", fmt.Errorf("template path must be relative to edge.yaml") +} +target = filepath.Join(baseDir, target) +``` + +Replace substring grammar checks such as: + +```go +if strings.Index(tmpl, "# Plan") < 0 { /* ... */ } +``` + +with a line-aware exact matcher and closed-token validation shared by both variants. + +**Modified Files Checklist** + +- [ ] `packages/go/singlerequesttemplate/template.go` +- [ ] `packages/go/singlerequesttemplate/template_test.go` +- [ ] `packages/go/config/load.go` +- [ ] `packages/go/config/model_execution_preset_config_test.go` + +**Test Strategy** + +- Extend `TestValidatePlanTemplate` and `TestValidateReviewTemplate` for exact headings/result lines, missing/duplicate/unknown placeholders, and delimiter residue. +- Extend `TestLoadEdgeSingleRequestTemplates` for Plan/Review absolute-path rejection, relative success, per-file fallback, exact size boundary, and filesystem-kind failures. + +**Verification** + +- Run the focused template/config tests and confirm every malformed variant is rejected without exposing file content in errors. + +### REVIEW_API-2 — Prove Freeze, Refresh, and Render Semantics + +**Problem** + +The preceding review claimed coverage that is absent from the actual test files. The admitted effective template snapshot, clone/workspace revalidation, refresh isolation, and custom Review artifact are therefore not protected against regression. + +**Solution** + +- Add deterministic service-level assertions that admitted bindings carry the exact effective Plan/Review template pair through clone and workspace revalidation paths. +- Add preset refresh assertions that existing work retains its frozen templates and newly admitted work observes the refreshed pair. +- Add a Review-stage custom-template snapshot proving internal artifact rendering uses the frozen template while `decision.output` remains the caller-visible final response. +- Do not change production behavior unless a new regression exposes a concrete defect. + +**Modified Files Checklist** + +- [ ] `apps/edge/internal/service/single_request_types_test.go` +- [ ] `apps/edge/internal/openai/single_request_preset_binding_test.go` +- [ ] `apps/edge/internal/openai/single_request_review_stage_test.go` + +**Test Strategy** + +- Add/extend `TestSingleRequestBindingTemplateSnapshot`. +- Add/extend `TestSingleRequestPresetBindingTemplateRefreshIsolation`. +- Add/extend `TestSingleRequestReviewStageCustomTemplateSnapshot`. +- Assert both the internal rendered artifact and unchanged caller output; do not rely on substring-only assertions where an exact snapshot is stable. + +**Verification** + +- Run the named focused packages, then the race suite covering OpenAI stages, service admission, refresh, config, and template validation. + +### REVIEW_API-3 — Synchronize Current Contracts and Specs + +**Problem** + +The current runtime spec still describes a Plan JSON Schema path that the implementation removed. The outer API contract and input spec do not yet document the accepted frozen-template/direct-PlanMD/internal-Review model, leaving the current documentation contradictory. + +**Solution** + +- Update the outer Anthropic-compatible contract to describe unchanged caller I/O and Edge-owned internal template customization. +- Update the provider-pool refresh spec with admission-time effective-template freezing and refresh isolation. +- Rewrite stale Plan JSON Schema passages in the Edge execution spec to direct PlanMD validation and templated Review artifact semantics. +- Update the OpenAI-compatible input surface to distinguish internal stage templates from caller-visible input/output. +- Preserve existing terminology and add the required current-spec change records where that spec format requires them. + +**Modified Files Checklist** + +- [ ] `agent-contract/outer/anthropic-compatible-api.md` +- [ ] `agent-spec/runtime/provider-pool-config-refresh.md` +- [ ] `agent-spec/runtime/edge-node-execution.md` +- [ ] `agent-spec/input/openai-compatible-surface.md` + +**Test Strategy** + +- Search the current spec for the known stale Plan JSON Schema phrases and require no matches. +- Cross-check every new statement against the implementation and the inner Edge config contract. + +**Verification** + +- Run the documented `rg` guard and manually confirm the four surfaces agree on admission, execution, refresh, and caller-output boundaries. + +### REVIEW_API-4 — Produce Trustworthy Verification Evidence + +**Problem** + +The earlier implementation evidence checked off work and named tests/docs that were absent. Local behavior passed, but the recorded completeness and remote live-smoke claims cannot be trusted without fresh evidence. + +**Solution** + +- Run every command in Final Verification against the completed working tree and paste actual output into the paired review file. +- Confirm the pushed commit and the remote checkout are identical before a remote rebuild or live smoke. +- If approved SOPS decryption remains unavailable, record the exact failing command, raw error, exit code, and resume condition. Treat that as an allowed external-profile blocker only; never convert it into a local pass. + +**Modified Files Checklist** + +- [ ] `agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md` + +**Test Strategy** + +- Verify formatting, focused tests, race tests, the full Edge/Go suite, the deterministic smoke self-test, the documentation guard, and the approved remote profile. + +**Verification** + +- Evidence must identify the tested commit and clearly separate local success from any externally blocked live qualification. + +## Modified Files Summary + +| File | Item | +|---|---| +| `packages/go/singlerequesttemplate/template.go` | REVIEW_API-1 | +| `packages/go/singlerequesttemplate/template_test.go` | REVIEW_API-1 | +| `packages/go/config/load.go` | REVIEW_API-1 | +| `packages/go/config/model_execution_preset_config_test.go` | REVIEW_API-1 | +| `apps/edge/internal/service/single_request_types_test.go` | REVIEW_API-2 | +| `apps/edge/internal/openai/single_request_preset_binding_test.go` | REVIEW_API-2 | +| `apps/edge/internal/openai/single_request_review_stage_test.go` | REVIEW_API-2 | +| `agent-contract/outer/anthropic-compatible-api.md` | REVIEW_API-3 | +| `agent-spec/runtime/provider-pool-config-refresh.md` | REVIEW_API-3 | +| `agent-spec/runtime/edge-node-execution.md` | REVIEW_API-3 | +| `agent-spec/input/openai-compatible-surface.md` | REVIEW_API-3 | +| `agent-task/single_request_plan_review_templates/CODE_REVIEW-cloud-G08.md` | REVIEW_API-4 | + +## Final Verification + +Run locally from the repository root: + +```bash +test -z "$(gofmt -l packages/go/singlerequesttemplate/template.go packages/go/singlerequesttemplate/template_test.go packages/go/config/load.go packages/go/config/model_execution_preset_config_test.go apps/edge/internal/service/single_request_types_test.go apps/edge/internal/openai/single_request_preset_binding_test.go apps/edge/internal/openai/single_request_review_stage_test.go)" +go test -count=1 ./packages/go/singlerequesttemplate ./packages/go/config +go test -count=1 ./apps/edge/internal/service -run 'TestSingleRequestBinding' +go test -count=1 ./apps/edge/internal/openai -run 'TestSingleRequest(PresetBinding|ReviewStage)' +go test -race -count=1 ./apps/edge/internal/openai ./apps/edge/internal/service ./apps/edge/internal/configrefresh ./packages/go/config ./packages/go/singlerequesttemplate +go test -count=1 ./apps/edge/... ./packages/go/... +make test-single-request-claude-smoke-self-test +if rg --sort path -n 'Edge-owned OpenAI `json_schema` response format|strict small plan/verification JSON|stage-owned JSON Schema override protection' agent-spec/runtime/edge-node-execution.md; then exit 1; fi +``` + +Then verify the approved remote profile against the exact pushed implementation commit: + +```bash +test "$(git branch --show-current)" = "feature/single_request_plan_review_templates" +test -z "$(git status --short)" +git push origin feature/single_request_plan_review_templates + +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && git fetch origin feature/single_request_plan_review_templates && git switch feature/single_request_plan_review_templates && git reset --hard origin/feature/single_request_plan_review_templates && git clean -fd && test "$(git rev-parse HEAD)" = "$(git rev-parse origin/feature/single_request_plan_review_templates)" && test "$(go env GOOS)/$(go env GOARCH)" = "darwin/arm64" && claude --version && sops --version && test -f dev-openai-toki.edge.yaml && test -f dev-openai-toki.sops.yaml' +ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && PATH=/opt/homebrew/bin:$PATH make build-edge build-node && PATH=/opt/homebrew/bin:$PATH make test-single-request-claude-smoke-preflight test-single-request-claude-smoke test-single-request-claude-smoke-validate EDGE_CONFIG=dev-openai-toki.edge.yaml SOPS_CONFIG=dev-openai-toki.sops.yaml' +``` + +If the remote SOPS age identity is unavailable, paste the exact raw failure and exit code into `CODE_REVIEW-cloud-G08.md`, state the identity-mount/export resume condition, and leave live API qualification explicitly blocked. Do not reuse old output or substitute another credential. + +Do not archive this plan, write `complete.log`, or move the task directory; those actions belong to the review agent after an official verdict.