<!-- task=m-multi-provider-protocol-profile-native-messages/06+01,02_fixture_suite plan=0 tag=TEST -->

# Plan - TEST

## For the Implementing Agent

Filling implementation-owned sections in `CODE_REVIEW-cloud-G03.md` is mandatory. Run every verification command exactly, paste actual output, keep both active files in place, and report ready for review. If blocked, record only the exact blocker, attempted commands/output, and resume condition in implementation-owned evidence. Do not ask the user, create control-plane files, classify next state, archive logs, or write `complete.log`; those are review-agent-only actions.

## Background

The existing profile table proves URL, selected auth header, and request model rewriting for one JSON success response. It does not prove that every concrete Chat and Messages profile retains non-stream, SSE, and provider-error tunnel behavior. This task makes that qualification deterministic and credential-free without changing runtime behavior.

## Archive Evidence Snapshot

- `agent-task/archive/2026/08/m-multi-provider-protocol-profile-native-messages/01_protocol_core/complete.log`: PASS for `profile-contract`, `path-resolution`, and `profile-catalog`; the concrete profile catalog and URL-resolution contract are available to consume.
- `agent-task/archive/2026/08/m-multi-provider-protocol-profile-native-messages/02+01_messages_ingress/complete.log`: PASS for the Messages ingress/native/bridge work; the Messages operation and raw tunnel semantics are available to consume.

## 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:
  - `fixture-suite`: deterministic, credential-free provider profile qualification
- Completion mode: check-on-pass

## Analysis

### Files Read

- `apps/node/internal/adapters/openai_compat/protocol_profile_test.go`
- `apps/node/internal/adapters/openai_compat/openai_compat_test_support_test.go`
- `apps/node/internal/adapters/openai_compat/provider_tunnel_test.go`
- `apps/node/internal/adapters/openai_compat/execute_test.go`
- `apps/node/internal/adapters/openai_compat/provider_tunnel.go`
- `apps/node/internal/adapters/openai_compat/request.go`
- `apps/node/internal/adapters/openai_compat/execute.go`
- `apps/edge/internal/openai/anthropic_native_test.go`
- `apps/edge/internal/openai/anthropic_bridge_test.go`

### SDD Criteria

`agent-roadmap/sdd/operational-observability-provider-management/multi-provider-protocol-profile-native-messages/SDD.md` is approved and unlocked. S09 maps `fixture-suite` to a credential-free full provider fixture suite; Evidence Map S09 requires network-disabled test output. The checklist therefore extends the profile matrix over the three response modes and the final verification runs only deterministic Go packages.

### Verification Context

No handoff was supplied. The local Node and testing rules require Go tests from the repository root and no provider credentials for fixture coverage. `TestProtocolProfileOperationURLFixtures` currently runs each concrete profile against `httptest`; `fakeTunnelSink` exposes emitted tunnel frames and `assertOrderedTunnelFrames` verifies ordered, single-terminal framing. Existing driver-level fixtures already cover OpenAI Chat SSE parsing plus native/bridged Anthropic non-stream, fragmented stream, terminal, and provider-error behavior. No external runner, config, credential, or network is required; confidence is high because every upstream is loopback or an in-memory tunnel.

### Test Coverage Gaps

- URL, selected auth header, and model rewrite are covered by `protocol_profile_test.go:23-93` only for `200 application/json`.
- Per-profile SSE content type/body forwarding, non-2xx status/body forwarding, and frame assertions are absent.
- `provider_tunnel_test.go` covers generic tunnel mechanics and `execute_test.go` covers OpenAI Chat SSE parsing, but neither crosses those behaviors with the complete profile URL/auth/model matrix.
- `anthropic_native_test.go` and `anthropic_bridge_test.go` already cover Messages non-stream, fragmented stream, exactly-once terminal, and provider-error mapping. They need verification evidence, not duplicate source changes.

### Symbol References

None. The existing test function remains named `TestProtocolProfileOperationURLFixtures`.

### Split Judgment

This child has one stable contract: loopback profile fixtures emit the declared URL/auth/model request and preserve start/body/end frames for three upstream outcomes. It depends on archived `01_protocol_core/complete.log` and `02+01_messages_ingress/complete.log`, both satisfied. It can PASS independently with network-disabled Go tests; live evidence is intentionally isolated in sibling `07+05,06_live_smoke`.

### Scope Rationale

Only the Node adapter fixture test changes. Production profile/config code, Edge ingress tests, contracts/specs, Responses coverage, CI configuration, credentials, and external provider calls are excluded: they are either already owned by predecessor tasks or outside S09's deterministic test boundary.

### Final Routing

`evaluation_mode=pair`; finalizer `finalize-task-policy.sh` routed the build and review targets with closure satisfied. `large_indivisible_context=false`; positive loop risk is `variant_product` (12 concrete profiles × JSON/SSE/error outcomes), count 1; recovery signals and capability-gap evidence are false. Canonical files are `PLAN-local-G03.md` and `CODE_REVIEW-cloud-G03.md`.

## Dependencies and Execution Order

1. Confirm `01_protocol_core` and `02+01_messages_ingress` remain satisfied by the archive `complete.log` files cited above.
2. Extend the loopback fixture matrix, then run the deterministic Node/config/Edge verification sequence.

## Implementation Checklist

- [ ] [TEST-1] Extend the concrete profile loopback fixture matrix to assert non-stream, SSE, and provider-error tunnel frames without a network or credential.
- [ ] [TEST-2] Run the full deterministic qualification command set and record that no external provider call occurred.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [TEST-1] Qualify every concrete profile across tunnel outcomes

**Problem**

`apps/node/internal/adapters/openai_compat/protocol_profile_test.go:23-93` writes only a successful JSON response, so the 12-profile matrix does not prove that its resolved route survives streaming or provider errors.

**Solution**

Keep the existing fixture identifiers, base prefixes, expected URI, auth-header checks, and model-map assertion. Add the standard-library `bytes` import, nest a deterministic outcome table beneath each profile, and make its `httptest` response and sink assertions explicit: `200 application/json` non-stream body, driver-appropriate `200 text/event-stream` fixed SSE bytes, and `422 application/json` provider error bytes. For every outcome, assert one upstream request; `ResponseStart` status/content type, concatenated body bytes, and `assertOrderedTunnelFrames`' single terminal frame. A provider HTTP error must end with `END` after preserving its 422 status/body; reserve terminal `ERROR` for transport/relay failures.

Before (`apps/node/internal/adapters/openai_compat/protocol_profile_test.go:67-68`):

```go
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"ok":true}`))
```

After:

```go
import "bytes"

for _, fx := range fixtures {
    outcomes := []struct {
        name        string
        status      int
        contentType string
        body        []byte
    }{
        {name: "json", status: http.StatusOK, contentType: "application/json", body: []byte(`{"ok":true}`)},
        {name: "sse", status: http.StatusOK, contentType: "text/event-stream", body: fixtureSSEBody(fx.operation)},
        {name: "provider_error", status: http.StatusUnprocessableEntity, contentType: "application/json", body: []byte(`{"error":{"message":"fixture"}}`)},
    }
    for _, outcome := range outcomes {
        // Run fx.id/outcome.name, collect fakeTunnelSink frames, and compare bytes.
    }
}

func fixtureSSEBody(operation config.ProtocolOperation) []byte {
    if operation == config.OperationMessages {
        return []byte("event: message_start\\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_fixture\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"model\":\"upstream-model\",\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":1,\"output_tokens\":0}}}\\n\\nevent: message_stop\\ndata: {\"type\":\"message_stop\"}\\n\\n")
    }
    return []byte("data: {\"choices\":[{\"delta\":{\"content\":\"fixture\"}}]}\\n\\ndata: [DONE]\\n\\n")
}
```

**Modified Files and Checklist**

- [ ] `apps/node/internal/adapters/openai_compat/protocol_profile_test.go`: add `bytes`, a test-local driver-appropriate SSE fixture helper, and the nested outcome assertions; do not add external fixtures or production behavior.

**Test Strategy**

Write the three outcome subtests inside `TestProtocolProfileOperationURLFixtures`. Each subtest uses only `httptest`, test-secret headers, the existing concrete profile resolver, and `fakeTunnelSink`; it asserts exact request routing plus raw tunnel frame semantics for all 12 profile ids. The SSE helper returns valid OpenAI Chat or Anthropic Messages fixture bytes according to `fx.operation`.

**Verification**

```bash
go test -count=1 -v ./apps/node/internal/adapters/openai_compat -run '^TestProtocolProfileOperationURLFixtures$'
```

Expected: every profile/outcome subtest passes without a network request.

### [TEST-2] Prove the deterministic qualification boundary

**Problem**

S09 requires the full provider fixture suite to be repeatable without credentials or subscriptions, not merely a focused unit-test result.

**Solution**

Run the focused matrix and then the affected adapter, config, and Edge OpenAI package tests with cache disabled. The full package runs must retain the existing OpenAI Chat parser and Anthropic native/bridge non-stream, stream, terminal, and error-mapping coverage. Record the actual output and explicitly state that no SOPS, curl, or provider endpoint command was executed.

**Modified Files and Checklist**

- [ ] `agent-task/m-multi-provider-protocol-profile-native-messages/06+01,02_fixture_suite/CODE_REVIEW-cloud-G03.md`: record command output and the no-network evidence.

**Test Strategy**

No additional test source is needed beyond TEST-1. The package sequence verifies the fixture matrix against the concrete profile catalog and existing Edge contract behavior.

**Verification**

```bash
go test -count=1 -v ./apps/node/internal/adapters/openai_compat -run '^TestProtocolProfileOperationURLFixtures$'
go test -count=1 ./apps/node/internal/adapters/openai_compat
go test -count=1 ./packages/go/config/...
go test -count=1 ./apps/edge/internal/openai/...
```

Expected: all commands exit 0; cache output is not accepted; no external credential or network dependency appears.

## Modified Files Summary

| File | Items |
|---|---|
| `apps/node/internal/adapters/openai_compat/protocol_profile_test.go` | TEST-1 |
| `agent-task/m-multi-provider-protocol-profile-native-messages/06+01,02_fixture_suite/CODE_REVIEW-cloud-G03.md` | TEST-1, TEST-2 |

## Final Verification

```bash
go test -count=1 -v ./apps/node/internal/adapters/openai_compat -run '^TestProtocolProfileOperationURLFixtures$'
go test -count=1 ./apps/node/internal/adapters/openai_compat
go test -count=1 ./packages/go/config/...
go test -count=1 ./apps/edge/internal/openai/...
```

All commands must exit 0 with fresh output. The review evidence must state that verification used only loopback fixtures and did not invoke SOPS, curl, or a provider endpoint. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
