일반 API와 구독 endpoint가 동일 모델명으로 섞이지 않도록 profile, credential route, Edge 모델 매핑 및 검증 경계를 구현 전에 확정한다.
16 KiB
Code Review Reference - API
[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. 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.
Overview
date=2026-08-02 task=glm_coding_plan, plan=0, tag=API
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:
- Append verdict and
review_rework_count/evidence_integrity_failurerouting signals. - Archive
CODE_REVIEW-cloud-G06.md→code_review_cloud_G06_0.logandPLAN-local-G06.md→plan_local_G06_0.log. - If PASS, write
complete.logand move active task directory toagent-task/archive/YYYY/MM/glm_coding_plan/. If WARN/FAIL, fully write the next filesystem state required by the code-review skill. - If PASS and task group is
m-<milestone-slug>, preserve the first-linemilestone-taskmetadata incomplete.logand report it for the runtime aggregation event. Roadmap state evaluation belongs tosync-milestone-workstate. - Check applicable
Review-Only Checklistitems at the final.loglocation before reporting.
Implementation Item Completion
| Item | Status |
|---|---|
| API-1 - GLM General/Coding profile catalog and transport regression | [ ] |
| API-2 - Managed GLM credential dual-profile route isolation | [ ] |
| API-3 - Edge model-driven configuration and current spec | [ ] |
| API-4 - SOPS-backed Coding Plan smoke and verification | [ ] |
Implementation Checklist
- [API-1] Register distinct
glmGeneral API andglm_codingCoding Plan profiles, including tool-calling capability, and add literal config plus Node transport regressions. - [API-2] Permit one
glm/bearermanaged credential slot to bind independently to both GLM profiles and test exact route alias/resource-selector isolation. - [API-3] Document the model-driven two-provider Edge configuration and synchronize the current provider-pool spec without enabling Coding Plan or adding fallback.
- [API-4] Extend the local Edge smoke profile with the existing SOPS-backed Coding Plan checks and run fresh focused, build, repository E2E, and redacted upstream verification.
- Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.
Review-Only Checklist
[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, orFAILand verifiedreview_rework_count,evidence_integrity_failuretoCode Review Result. - Verify that verdict,
Dimension Assessment, and Required/Suggested/Nit classifications match. - Archive active
CODE_REVIEW-*-G??.mdtocode_review_cloud_G06_0.log. - Archive active
PLAN-*-G??.mdtoplan_local_G06_0.log. - Verify that the Agent-Ops managed block in
.gitignoreunignoresagent-task/**/*.mdandagent-task/**/*.logand ignoresagent-roadmap/current.md. - If PASS, write
complete.logbased onagent-ops/skills/common/code-review/templates/complete-log-template.mdand leave no active.mdfiles. - If PASS, move active task directory
agent-task/glm_coding_plan/toagent-task/archive/YYYY/MM/glm_coding_plan/and update this checklist at the final archive path. - If PASS and task group is
m-<milestone-slug>, preserve and reportmilestone-taskmetadata for runtime aggregation, without modifying roadmap or directly callingupdate-roadmap. - If PASS for split work, remove empty active parent
agent-task/glm_coding_plan/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
Record any deviations from the plan and the rationale here.
Key Design Decisions
Record key design decisions here.
Reviewer Checkpoints
- Verify
glmremains bound tohttps://api.z.ai/api/paas/v4andglm_codingtohttps://api.z.ai/api/coding/paas/v4, with Bearer auth, models/chat/streaming/tool_calling, and no Responses operation/capability. - Verify the literal catalog/auth count tests and Node loopback fixture include
glm_codingand do not derive expected values from production catalog data. - Verify one
glm/bearerslot can store distinctglm/glm_codingroutes with aliasesglm-5.1-api/glm-5.1-codingand selectorsglm-api/glm-coding, while another vendor is rejected. - Verify the Edge example never maps both providers under one external model ID, never enables a provider by default, never adds fallback, and records the Z.AI supported-use/proxy restriction without a credential.
- Verify no config schema, proto, driver, Edge handler, contract, roadmap, SOPS file, or token source was changed outside the plan.
- Verify the local smoke uses the SOPS scalar only through a mode-0600 temporary curl config, calls the Coding base URL only, removes temporary files, and records actual models/chat/SSE/tool evidence without response or credential leakage.
- Verify focused tests use
-count=1,make build-edgeandmake test-e2eactually ran, and every command's stdout/stderr is pasted below.
Verification Results
[IMPLEMENTING AGENT] Run every command exactly as written. Paste actual stdout/stderr under the matching
Actual Outputheading. If a command changes, record the replacement and reason inDeviations from Planbefore pasting its output.
API-1 Verification
Run:
gofmt -w packages/go/config/protocol_profile.go packages/go/config/protocol_profile_test.go apps/node/internal/adapters/openai_compat/protocol_profile_test.go
go test -count=1 ./packages/go/config ./apps/node/internal/adapters/openai_compat
Expected: both packages pass fresh; the loopback fixture records /api/coding/paas/v4/chat/completions and no live provider is called.
Actual Output
Paste actual stdout/stderr here.
API-2 Verification
Run:
gofmt -w apps/control-plane/internal/credentialstore/route.go apps/control-plane/internal/credentialstore/route_test.go
go test -count=1 ./apps/control-plane/internal/credentialstore
Expected: the GLM dual-profile route test passes and the existing incompatible-profile tests remain green.
Actual Output
Paste actual stdout/stderr here.
API-3 Verification
Run:
rg --sort path -n 'glm_coding|glm-5\.1-api|glm-5\.1-coding|glm-api|glm-coding' configs/edge.yaml agent-spec/runtime/provider-pool-config-refresh.md
git diff --check -- configs/edge.yaml agent-spec/runtime/provider-pool-config-refresh.md
Expected: both IDs/profiles appear with distinct provider mappings, and no whitespace error or secret value is present.
Actual Output
Paste actual stdout/stderr here.
API-4 Verification
Run the exact redacted command in Final Verification step 4 and copy the same command/criteria into the GLM Coding Plan section of agent-test/local/edge-smoke.md.
Expected: preflight passes without revealing the token; models, non-stream, stream, and function-call assertions pass against only https://api.z.ai/api/coding/paas/v4; the command prints glm coding smoke: PASS and removes temporary files.
Actual Output
Paste actual stdout/stderr here.
Final Verification
- Confirm the checkout and external secret preflight. These commands must not print decrypted data:
test "$(git branch --show-current)" = "feature/glm-coding-plan"
test "$(git merge-base HEAD origin/dev)" = "32c0754f91b05ee95ab25b1062016d44fba18bf2"
test "$(stat -c '%a' /config/.config/iop/secrets/dev-openai-toki.sops.yaml)" = "600"
test "$(stat -c '%a' /config/.config/sops/age/keys.txt)" = "600"
SOPS_AGE_KEY_FILE=/config/.config/sops/age/keys.txt sops filestatus /config/.config/iop/secrets/dev-openai-toki.sops.yaml | jq -e '.encrypted == true'
test "$(SOPS_AGE_KEY_FILE=/config/.config/sops/age/keys.txt sops decrypt --extract '["tokens"]["glm-coding-plan"]' /config/.config/iop/secrets/dev-openai-toki.sops.yaml | wc -c)" -gt 1
Expected: every command exits 0 and only the non-secret filestatus JSON is emitted.
- Confirm formatting and run fresh focused tests:
test -z "$(gofmt -d packages/go/config/protocol_profile.go packages/go/config/protocol_profile_test.go apps/control-plane/internal/credentialstore/route.go apps/control-plane/internal/credentialstore/route_test.go apps/node/internal/adapters/openai_compat/protocol_profile_test.go)"
go test -count=1 ./packages/go/config ./apps/control-plane/internal/credentialstore ./apps/node/internal/adapters/openai_compat
Expected: no gofmt diff and all three packages pass.
- Run the Edge/config user-path build and repository-native full cycle:
make build-edge
make test-e2e
Expected: Edge builds and the repository Edge-Node E2E exits 0. Record actual stdout/stderr; this verifies the existing user pipeline but does not claim a live Coding Plan proxy deployment.
- Execute the redacted Coding Plan smoke. This command uses only the Coding endpoint and prints no response body or credential:
bash <<'BASH'
set -euo pipefail
set +x
sops_file=/config/.config/iop/secrets/dev-openai-toki.sops.yaml
age_file=/config/.config/sops/age/keys.txt
base_url=https://api.z.ai/api/coding/paas/v4
smoke_dir="$(mktemp -d /tmp/iop-glm-coding-smoke.XXXXXX)"
cleanup() {
rm -rf -- "$smoke_dir"
}
trap cleanup EXIT
test "$(stat -c '%a' "$sops_file")" = "600"
test "$(stat -c '%a' "$age_file")" = "600"
SOPS_AGE_KEY_FILE="$age_file" sops filestatus "$sops_file" | jq -e '.encrypted == true' >/dev/null
token="$(SOPS_AGE_KEY_FILE="$age_file" sops decrypt --extract '["tokens"]["glm-coding-plan"]' "$sops_file")"
test -n "$token"
umask 077
auth_config="$smoke_dir/curl-auth.conf"
printf 'header = "Authorization: Bearer %s"\nheader = "Content-Type: application/json"\n' "$token" >"$auth_config"
unset token
curl --fail --silent --show-error --config "$auth_config" \
--output "$smoke_dir/models.json" "$base_url/models"
jq -e '(.data | type == "array") and any(.data[]; (.id | ascii_downcase) == "glm-5.1")' \
"$smoke_dir/models.json" >/dev/null
jq -n '{
model: "glm-5.1",
messages: [{role: "user", content: "Reply exactly GLM_CODING_PLAN_OK"}],
stream: false,
max_tokens: 32
}' >"$smoke_dir/chat.json"
curl --fail --silent --show-error --config "$auth_config" \
--request POST --data-binary "@$smoke_dir/chat.json" \
--output "$smoke_dir/chat-response.json" "$base_url/chat/completions"
jq -e '(.choices[0].message.content | type == "string" and length > 0) and (.usage.total_tokens | type == "number")' \
"$smoke_dir/chat-response.json" >/dev/null
jq -n '{
model: "glm-5.1",
messages: [{role: "user", content: "Reply exactly GLM_CODING_PLAN_STREAM_OK"}],
stream: true,
max_tokens: 32
}' >"$smoke_dir/stream.json"
curl --fail --silent --show-error --no-buffer --config "$auth_config" \
--request POST --data-binary "@$smoke_dir/stream.json" \
--output "$smoke_dir/stream-response.txt" "$base_url/chat/completions"
grep -Eq '^data: .+' "$smoke_dir/stream-response.txt"
grep -Fq 'data: [DONE]' "$smoke_dir/stream-response.txt"
jq -n '{
model: "glm-5.1",
messages: [{role: "user", content: "Call emit_marker with marker GLM_CODING_PLAN_TOOL_OK. Do not answer directly."}],
tools: [{
type: "function",
function: {
name: "emit_marker",
description: "Emit the requested verification marker",
parameters: {
type: "object",
properties: {marker: {type: "string"}},
required: ["marker"]
}
}
}],
tool_choice: "auto",
stream: false,
max_tokens: 64
}' >"$smoke_dir/tool.json"
curl --fail --silent --show-error --config "$auth_config" \
--request POST --data-binary "@$smoke_dir/tool.json" \
--output "$smoke_dir/tool-response.json" "$base_url/chat/completions"
jq -e 'any(.choices[0].message.tool_calls[]?; .function.name == "emit_marker")' \
"$smoke_dir/tool-response.json" >/dev/null
printf 'glm coding smoke: PASS\n'
BASH
Expected: /models, non-stream Chat, SSE [DONE], and one tool call pass at https://api.z.ai/api/coding/paas/v4 only; the command prints glm coding smoke: PASS and removes all temporary files.
- Inspect scope and secret safety:
git diff --check
git diff --name-only -- packages/go/config/protocol_profile.go packages/go/config/protocol_profile_test.go apps/control-plane/internal/credentialstore/route.go apps/control-plane/internal/credentialstore/route_test.go apps/node/internal/adapters/openai_compat/protocol_profile_test.go configs/edge.yaml agent-spec/runtime/provider-pool-config-refresh.md
rg --sort path -n 'glm_coding|glm-5\.1-api|glm-5\.1-coding' packages/go/config/protocol_profile.go packages/go/config/protocol_profile_test.go apps/control-plane/internal/credentialstore/route.go apps/control-plane/internal/credentialstore/route_test.go apps/node/internal/adapters/openai_compat/protocol_profile_test.go configs/edge.yaml agent-spec/runtime/provider-pool-config-refresh.md agent-test/local/edge-smoke.md
Expected: only the claimed implementation files plus active review evidence are modified; GLM split identifiers are present; no token/API key value appears in the diff or command output.
After completing all code changes, fill implementation-owned sections in CODE_REVIEW-*-G??.md.
Actual Output
Paste actual stdout/stderr for each numbered command here.
[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 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 placeholder text 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 |