<!-- task=m-multi-provider-protocol-profile-native-messages/03+02_contract_responses_sync plan=1 tag=API -->

# Responses profile regression과 contract/spec 동기화

## For the Implementing Agent

`CODE_REVIEW-cloud-G05.md`의 구현 담당 섹션을 채우는 것이 구현의 필수 마지막 단계다. 선행 `02+01_messages_ingress/complete.log`를 확인하고, contract/spec 작업 전 router가 지시하는 update-contract/update-spec 절차를 적용한다. 검증의 실제 stdout/stderr와 문서 drift 근거를 기록한 뒤 active 파일을 유지하고 review 준비 완료를 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review skill만 수행한다. 막히면 구현 담당 evidence 필드에 정확한 blocker, 시도한 명령/출력, 재개 조건만 기록하며 사용자 질문, user-input tool, stop file, 상태 분류, archive/complete 처리를 하지 않는다.

## Background

protocol profile과 Messages 구현 뒤에는 기존 Responses tunnel이 새 operation/capability 경계를 사용하면서도 normalized/passthrough/provider-auth/Pi 소비 의미를 유지해야 한다. 또한 public Messages 계약, profile config, Edge-Node operation wire와 현재 구현 spec은 구현 source of truth를 한 번만 가리켜야 한다. 이 계획은 작은 회귀·문서 작업이지만 앞선 구현 없이는 정확한 계약 원문을 쓸 수 없어 마지막 dependent PASS unit으로 둔다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/operational-observability-provider-management/milestones/multi-provider-protocol-profile-native-messages.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/operational-observability-provider-management/milestones/multi-provider-protocol-profile-native-messages.md)
- Task ids:
  - `contract-sync`: profile config, tunnel operation, Chat/Messages public/inner 계약과 구현 spec 동기화
  - `responses-regression`: 선택적 Responses driver와 Pi 소비 동작 보존
- Completion mode: check-on-pass

## Analysis

### Files Read

- `agent-roadmap/phase/operational-observability-provider-management/milestones/multi-provider-protocol-profile-native-messages.md`
- `agent-roadmap/sdd/operational-observability-provider-management/multi-provider-protocol-profile-native-messages/SDD.md`
- `agent-contract/index.md`
- `agent-contract/outer/openai-compatible-api.md`
- `agent-contract/inner/edge-node-runtime-wire.md`
- `agent-contract/inner/edge-config-runtime-refresh.md`
- `agent-spec/index.md`
- `agent-spec/input/openai-compatible-surface.md`
- `agent-spec/runtime/edge-node-execution.md`
- `agent-spec/runtime/provider-pool-config-refresh.md`
- `agent-ops/rules/common/rules-agent-spec.md`
- `packages/go/config/edge_types.go`
- `packages/go/config/provider_types.go`
- `proto/iop/runtime.proto`
- `apps/edge/internal/openai/routes.go`
- `apps/edge/internal/openai/principal.go`
- `apps/edge/internal/openai/provider_tunnel.go`
- `apps/edge/internal/openai/responses_handler.go`
- `apps/edge/internal/openai/responses_handler_test.go`
- `apps/edge/internal/openai/openai_auth_routes_models_test.go`
- `apps/node/internal/adapters/openai_compat/provider_tunnel.go`
- `apps/node/internal/adapters/openai_compat/provider_tunnel_test.go`
- `apps/node/internal/adapters/openai_compat/capabilities_test.go`
- `agent-client/pi/README.md`
- `agent-client/pi/install.sh`

### SDD Criteria

- SDD: `agent-roadmap/sdd/operational-observability-provider-management/multi-provider-protocol-profile-native-messages/SDD.md`, `[승인됨]`, 잠금 해제.
- S04 / `contract-sync`: protocol/config/wire 구현이 끝난 뒤 public/inner contract와 spec index가 실제 source path를 가리키며 중복 계약 원문이 없어야 한다.
- S08 / `responses-regression`: normalized/passthrough/provider-auth fixture와 선택적 `openai_responses` profile/runtime test가 기존 status/body/stream 의미와 Pi 소비를 보존해야 한다. 공통 provider 완료에 Responses live smoke는 요구하지 않는다.
- Evidence Map S04의 index/path search와 S08의 기존 Responses suite를 DOC-3/API-1 final commands에 포함했다.

### Verification Context

- 별도 handoff는 없었다.
- 읽은 검증 source: `agent-test/local/rules.md`, `agent-test/local/profiles/edge-smoke.md`, `agent-test/local/profiles/node-smoke.md`, `agent-test/local/profiles/platform-common-smoke.md`, `agent-ops/rules/project/domain/edge.md`, `agent-ops/rules/project/domain/node.md`, `agent-ops/rules/project/domain/platform-common.md`, `agent-ops/rules/project/domain/testing.md`.
- preflight: `/config/.local/bin/go`, `go1.26.2 linux/arm64`, `GOROOT=/config/opt/go`; workspace `/config/workspace/iop-s0`, branch `feature/multi-provider-protocol-profile-native-messages`, HEAD `174a2a6b1375bd71c3a977aff91e6afb9c26bd58`.
- 사용자 소유 dirty roadmap 4건은 보존한다.
- Go regression은 `-count=1`; Pi installer는 temp HOME을 만드는 Python unittest로 실제 script를 실행해 user file merge 결과를 검사한다. 외부 network/credential은 사용하지 않는다.
- contract/spec drift는 index pointer와 implementation symbol/path를 deterministic `rg --sort path`로 확인한다. 문서 원문은 구현 완료 뒤에만 작성한다.
- Responses live smoke는 SDD가 명시적으로 제외한다. repository-native provider tunnel/normalized/provider-auth fixtures와 Pi temp-home test가 fallback이 아니라 required evidence다.
- confidence: 높음. Responses handler/tunnel/test, Pi installer, 모든 매칭 contract/spec/index를 읽었다.

### Test Coverage Gaps

- 기존 Responses tests는 raw `/v1/responses` path를 확인하지만 explicit `openai_responses` profile operation/capability와 profile 미지원 pre-dispatch 거부를 확인하지 않는다.
- Pi installer에는 temp-home executable regression이 없어 provider API/default/timeout merge가 깨져도 자동 검출되지 않는다.
- Anthropic-compatible outer contract 파일이 없고 contract/spec index는 profile/operation/Messages source path를 모른다.

### Symbol References

- renamed/removed symbol은 없다.
- Responses public route `/v1/responses`와 existing DTO/handler 이름은 유지한다.
- 새 operation id는 wire의 기존 `Path`를 제거하지 않고 explicit profile에서 우선 사용한다.

### Split Judgment

- 이 child의 stable contract는 완성된 protocol/Messages 구현을 기준으로 Responses compatibility와 모든 contract/spec pointer가 동시에 일치하는 것이다. PASS evidence는 S08 Go/Pi regression과 S04 drift search다.
- 직접 predecessor는 `02+01_messages_ingress`다. 현재 active/archived `complete.log`가 없어 dependency는 `missing`; 구현은 `agent-task/m-multi-provider-protocol-profile-native-messages/02+01_messages_ingress/complete.log` 전에는 시작하지 않는다.
- `02+01_messages_ingress`가 `01_protocol_core`를 직접 의존하므로 이 child는 directory 이름에 없는 추가 predecessor를 선언하지 않는다.
- 이 plan 내부는 Responses migration/test가 실제 implementation symbol을 확정하고 그 뒤 contract/spec를 쓰는 짧은 순서다. 별도 PASS unit으로 더 나누면 S04 문서가 아직 검증되지 않은 Responses 경계를 source of truth로 가리킨다.

### Scope Rationale

- profile schema와 Messages feature behavior를 다시 설계하지 않는다. 발견된 drift가 source bug라면 plan deviation에 기록하고 선행 task follow-up 대상으로 남기며 문서로 덮지 않는다.
- `agent-client/pi/install.sh`의 provider 목록/API semantics는 변경하지 않는다. temp-home regression이 실패할 때만 plan deviation 없이 원인을 수정할 수 없으므로 review blocker로 기록한다; 이 plan의 예상 source change는 test와 README clarification이다.
- live provider credentials, Responses live smoke, Claude gateway 변경, qualification record는 제외한다.
- archive evidence를 사용하지 않으며 archive를 탐색하지 않는다.

### Final Routing

- status: `routed`; evaluation_mode: `first-pass`; finalizer: `finalize-task-policy.sh` (`pair`).
- build closures: 모두 `true`; capability gap 없음.
- build grade scores: scope_coupling=2, state_concurrency=0, blast_irreversibility=1, evidence_diagnosis=1, verification_complexity=1 → G05.
- build route: base=`local-fit`, large_indivisible_context=false, matched loop risk=`boundary_contract` (1), risk/recovery boundary 미충족, review_rework_count=0, evidence_integrity_failure=false.
- review closures: 모두 `true`; grade scores 2/0/1/1/1 → G05; route=`official-review`, cloud, Codex `gpt-5.6-sol`, xhigh.
- canonical files: `PLAN-local-G05.md`, `CODE_REVIEW-cloud-G05.md`.

## Dependencies and Execution Order

1. `02+01_messages_ingress` — `agent-task/m-multi-provider-protocol-profile-native-messages/02+01_messages_ingress/complete.log`가 직접 선행 조건이다. 현재 missing이므로 구현자는 파일이 생길 때까지 시작하지 않는다.
2. API-1/TEST-2로 implementation regression을 고정한 뒤 DOC-3 contract/spec를 작성한다. 문서를 먼저 써서 구현 drift를 정당화하지 않는다.

## Implementation Checklist

- [ ] Migrate provider-pool Responses passthrough to the optional profile operation/capability boundary while preserving legacy no-profile, normalized, stream, provider-auth, and body/status semantics with S08 tests.
- [ ] Add an executable temp-home Pi installer regression and clarify the maintained `openai-responses` consumption path without changing user secrets or existing defaults.
- [ ] Using the routed contract/spec workflows, add the Anthropic outer contract and synchronize config/wire/OpenAI contracts plus current specs/indexes to implementation source paths, proving no duplicate source of truth for S04.
- [ ] Run focused Responses/Pi/drift checks and full packages/Edge/Node verification with fresh results.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Optional Responses profile operation without behavior drift

#### Problem

Provider-pool Responses currently constructs a tunnel with a literal path (`apps/edge/internal/openai/responses_handler.go:357-372`) and the shared provider tunnel helpers repeat `/v1/responses`. After protocol core, explicit profiles must admit the `responses` operation/capability; legacy no-profile routes still need the old path fallback. The SDD forbids making Responses a universal provider baseline.

Before (`responses_handler.go:357-372`):

```go
baseTunnel := edgeservice.SubmitProviderTunnelRequest{
    Method:       http.MethodPost,
    Path:         "/v1/responses",
    Stream:       env.Stream,
    ProviderPool: true,
}
```

#### Solution

Set the profile operation id for explicit profiles and filter only candidates that declare optional Responses support. Preserve `Path: "/v1/responses"` as mixed-version fallback; profile-aware Node resolution must prefer Operation. Leave normalized execution validation, passthrough bytes/SSE, provider auth and stream-gate behavior unchanged. A profile with no Responses operation is rejected before tunnel dispatch, while a legacy no-profile candidate follows existing classification.

After:

```go
baseTunnel := edgeservice.SubmitProviderTunnelRequest{
    Method:       http.MethodPost,
    Operation:    config.ProtocolOperationResponses,
    Path:         "/v1/responses", // legacy mixed-version fallback
    Stream:       env.Stream,
    ProviderPool: true,
}
```

#### Modified Files and Checklist

- [ ] `apps/edge/internal/openai/responses_handler.go`: set Responses operation and candidate capability predicate without changing normalized branch semantics.
- [ ] `apps/edge/internal/openai/provider_tunnel.go`: propagate the operation in direct/pool/recovery tunnel templates while preserving raw path fallback and auth.
- [ ] `apps/edge/internal/openai/responses_protocol_profile_test.go`: add explicit-supported, explicit-unsupported, legacy fallback, body/status/stream/provider-auth regression cases.

#### Test Strategy

Write `TestResponsesProtocolProfileOperationPassthrough`, `TestResponsesProtocolProfileUnsupportedRejectsBeforeDispatch`, `TestResponsesLegacyProfileFallback`, and table subtests covering non-stream/stream/provider-auth. Reuse fake tunnel frames; assert operation/path, exact output bytes/status, zero dispatch when unsupported, and unchanged normalized SubmitRun path.

#### Verification

```bash
go test -count=1 ./apps/edge/internal/openai -run 'TestResponses(ProtocolProfile|LegacyProfileFallback)'
go test -count=1 ./apps/edge/internal/openai -run 'TestResponses|Test.*ProviderAuth'
```

Expected: explicit capability controls only profile-aware passthrough; all existing Responses/provider-auth behavior passes unchanged.

### [TEST-2] Pi `openai-responses` consumption regression

#### Problem

`agent-client/pi/install.sh` currently writes `api: "openai-responses"`, preserves existing defaults/API keys, and removes provider timeout override, but there is no executable test. S08 requires this consumption behavior to remain while common provider qualification does not require Responses live smoke.

#### Solution

Add a Python unittest that creates a temp HOME with representative existing `settings.json`/`models.json`, runs the real shell installer, then asserts Seulgivibe Codex remains `openai-responses`, existing default/key/dev-corp data is preserved, legacy provider migration is correct, HTTP idle timeout is disabled and provider timeout removed. It must use fake keys only and assert generated repository/test output contains no real credential.

#### Modified Files and Checklist

- [ ] `agent-client/pi/install_test.py`: executable temp-home merge/idempotency regression around the real installer.
- [ ] `agent-client/pi/README.md`: state that Pi Responses consumption is retained and is validated credential-free; do not change setup semantics.

#### Test Strategy

Write `PiInstallTest.test_preserves_openai_responses_consumption_and_user_settings` and `test_is_idempotent`. Invoke `bash agent-client/pi/install.sh` with `HOME=<tempdir>`, inspect JSON, rerun, and assert stable results/backups without external network.

#### Verification

```bash
command -v python3 && python3 --version
python3 agent-client/pi/install_test.py
bash -n agent-client/pi/install.sh
```

Expected: both temp-home tests pass, shell syntax is valid, and no user home is touched.

### [DOC-3] Public/inner contracts and current specs

#### Problem

`agent-contract/index.md` has no Anthropic public contract; existing OpenAI/config/wire contracts describe literal OpenAI paths and pre-profile payloads. Matching specs likewise cannot point to concrete profile resolution, operation-aware tunnel, shared principal auth, native/bridge Messages, or optional Responses semantics. Copying SDD prose into multiple docs would create competing source of truth.

#### Solution

After source/tests pass, follow router-selected update-contract/update-spec workflows. Create the SDD-mandated `outer/anthropic-compatible-api.md` as the sole public Messages contract; update existing OpenAI, wire, config contracts with cross-links and exact implementation owners. Update current specs/index descriptions to explain runtime behavior and point to contract originals, without duplicating full request schemas. Use index/path search to prove every pointer resolves and old gateway is migration evidence only.

#### Modified Files and Checklist

- [ ] `agent-contract/index.md`: register the Anthropic outer contract and updated ownership pointers.
- [ ] `agent-contract/outer/anthropic-compatible-api.md`: define canonical/alias routes, auth/version/models/count, native/bridge request/response/SSE/error contract.
- [ ] `agent-contract/outer/openai-compatible-api.md`: retain Chat/Responses authority and cross-reference shared auth/model/profile behavior.
- [ ] `agent-contract/inner/edge-node-runtime-wire.md`: document append-only concrete profile and operation fields, legacy Path fallback, raw frame invariants.
- [ ] `agent-contract/inner/edge-config-runtime-refresh.md`: document catalog overlay validation, concrete snapshot/refresh, alias normalization and capability admission.
- [ ] `agent-spec/index.md`: update matching spec summaries/pointers only where source ownership changed.
- [ ] `agent-spec/input/openai-compatible-surface.md`: document coexistence of OpenAI and Anthropic ingress, direct Edge routing, optional Responses preservation.
- [ ] `agent-spec/runtime/edge-node-execution.md`: document selected profile driver/native/bridge operation flow and terminal ownership.
- [ ] `agent-spec/runtime/provider-pool-config-refresh.md`: document overlay resolution and immutable refresh snapshot.

#### Test Strategy

No new parser test: docs are verified by exact index/path searches plus code tests from API-1 and predecessor. The reviewer must compare field/route names against source, not SDD prose alone.

#### Verification

```bash
test -f agent-contract/outer/anthropic-compatible-api.md
rg -n --sort path 'anthropic-compatible-api|openai-compatible-api|edge-node-runtime-wire|edge-config-runtime-refresh' agent-contract/index.md agent-spec/index.md
rg -n --sort path 'ConcreteProtocolProfile|ProtocolOperation|/v1/messages|/v1/responses' agent-contract agent-spec apps/edge/internal/openai proto/iop/runtime.proto packages/go/config
rg -n --sort path 'agent-client/claude/iop-claude-gateway.py' agent-contract agent-spec
```

Expected: indexes point to real files; implementation symbols/routes are covered once by the owning contract and specs point to them; gateway references, if any, are migration-only.

### [API-4] Whole-plan verification and evidence capture

#### Problem

S04/S08 close only when focused behavior, full Go regressions, Pi execution and docs drift all agree after predecessor implementation.

#### Solution

Run the dependency check, focused tests, all package/Edge/Node vet/tests, Pi tests, deterministic drift searches and diff check. Record actual output in the review stub; do not substitute live provider evidence.

#### Modified Files and Checklist

- [ ] `agent-task/m-multi-provider-protocol-profile-native-messages/03+02_contract_responses_sync/CODE_REVIEW-cloud-G05.md`: record actual implementation, contract workflow, command output and any intentional search result.

#### Test Strategy

No additional file. Fresh full-suite output is required and cached Go results are not accepted.

#### Verification

```bash
command -v go && go version && go env GOROOT
go vet ./packages/go/...
go vet ./apps/edge/...
go vet ./apps/node/...
go test -count=1 ./packages/go/...
go test -count=1 ./apps/edge/...
go test -count=1 ./apps/node/...
python3 agent-client/pi/install_test.py
git diff --check
```

Expected: all commands pass and no external credential/live Responses call is required.

## Modified Files Summary

| File | Items |
|------|-------|
| `apps/edge/internal/openai/responses_handler.go` | API-1 |
| `apps/edge/internal/openai/provider_tunnel.go` | API-1 |
| `apps/edge/internal/openai/responses_protocol_profile_test.go` | API-1 |
| `agent-client/pi/install_test.py` | TEST-2 |
| `agent-client/pi/README.md` | TEST-2 |
| `agent-contract/index.md` | DOC-3 |
| `agent-contract/outer/anthropic-compatible-api.md` | DOC-3 |
| `agent-contract/outer/openai-compatible-api.md` | DOC-3 |
| `agent-contract/inner/edge-node-runtime-wire.md` | DOC-3 |
| `agent-contract/inner/edge-config-runtime-refresh.md` | DOC-3 |
| `agent-spec/index.md` | DOC-3 |
| `agent-spec/input/openai-compatible-surface.md` | DOC-3 |
| `agent-spec/runtime/edge-node-execution.md` | DOC-3 |
| `agent-spec/runtime/provider-pool-config-refresh.md` | DOC-3 |
| `agent-task/m-multi-provider-protocol-profile-native-messages/03+02_contract_responses_sync/CODE_REVIEW-cloud-G05.md` | API-4 |

## Final Verification

Run after predecessor PASS, in order; Go test cache is not acceptable:

```bash
test -f agent-task/m-multi-provider-protocol-profile-native-messages/02+01_messages_ingress/complete.log
command -v go && go version && go env GOROOT
command -v python3 && python3 --version
go test -count=1 ./apps/edge/internal/openai -run 'TestResponses(ProtocolProfile|LegacyProfileFallback)'
go test -count=1 ./apps/edge/internal/openai -run 'TestResponses|Test.*ProviderAuth'
python3 agent-client/pi/install_test.py
bash -n agent-client/pi/install.sh
test -f agent-contract/outer/anthropic-compatible-api.md
rg -n --sort path 'anthropic-compatible-api|openai-compatible-api|edge-node-runtime-wire|edge-config-runtime-refresh' agent-contract/index.md agent-spec/index.md
rg -n --sort path 'ConcreteProtocolProfile|ProtocolOperation|/v1/messages|/v1/responses' agent-contract agent-spec apps/edge/internal/openai proto/iop/runtime.proto packages/go/config
rg -n --sort path 'agent-client/claude/iop-claude-gateway.py' agent-contract agent-spec
go vet ./packages/go/...
go vet ./apps/edge/...
go vet ./apps/node/...
go test -count=1 ./packages/go/...
go test -count=1 ./apps/edge/...
go test -count=1 ./apps/node/...
git diff --check
```

Expected: dependency exists, S08 Responses/Pi regressions pass, S04 indexes and source paths have no unclassified drift/duplicate authority, all Go vet/tests pass, and diff check is clean.

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