<!-- task=m-provider-adapter-foundation/01_webhook_adapter_contract plan=1 tag=REVIEW_API -->

# Provider Webhook Adapter Contract Follow-up Plan

## 이 파일을 읽는 구현 에이전트에게

이 계획의 구현 완료는 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용, 검증 출력, 계획 대비 변경 사항으로 채운 뒤에만 성립한다. 구현 중 선택된 SDD 결정 또는 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 막으면 review stub의 `사용자 리뷰 요청` 섹션을 채우고 멈춘다. 직접 사용자에게 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 환경, secret, 서비스 준비, 검증 증거 공백은 사용자 리뷰 요청이 아니라 검증 결과나 후속 plan 사유로 기록한다.

## Archive Evidence Snapshot

- 이전 plan log: `agent-task/m-provider-adapter-foundation/01_webhook_adapter_contract/plan_local_G05_0.log`
- 이전 review log: `agent-task/m-provider-adapter-foundation/01_webhook_adapter_contract/code_review_local_G05_0.log`
- 이전 판정: FAIL
- Required 요약:
  - `services/core/internal/provider/provider_test.go:79`의 fake adapter가 `WebhookRequest`를 기록하지 않아 `TestWebhookAdapterContractRequestDelivery`가 provider/event/delivery/payload/header/query가 verifier와 normalizer에 실제 전달됐는지 검증하지 못한다.
- Suggested 요약: 없음
- Nit 요약: 없음
- 영향 파일: `services/core/internal/provider/provider_test.go`
- 검증 근거:
  - `cd services/core && go test -count=1 ./internal/provider` 통과
  - `cd services/core && go test -count=1 ./internal/provider ./internal/controlplane` 통과
  - `cd services/core && go test ./...` 통과
- 허용된 archive 재확인 경로: 위의 이전 plan/review log 두 파일만 필요 시 좁게 읽는다.

## 범위 결정 근거

- 이 follow-up은 이전 리뷰의 Required 하나만 닫는다.
- provider API 타입, router/runtime 동작, Forgejo webhook wiring은 변경하지 않는다.
- Roadmap Targets와 Spec Targets는 이전 plan에 없었으므로 이 follow-up에서도 주장하지 않는다.

## 구현 체크리스트

- [x] fake webhook adapter가 verifier와 normalizer 각각에서 받은 `WebhookRequest`를 기록하도록 `services/core/internal/provider/provider_test.go`를 보강한다.
- [x] `TestWebhookAdapterContractRequestDelivery`에서 provider, event type, delivery id, payload, header, query, receivedAt이 verifier와 normalizer 양쪽에 보존되어 전달됐는지 assert한다.
- [x] `cd services/core && go test -count=1 ./internal/provider`를 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [REVIEW_API-1] Provider Webhook Request Delivery Test

### 문제

`fakeWebhookAdapter.VerifyWebhook`와 `fakeWebhookAdapter.NormalizeWebhook`는 `WebhookRequest` 인자를 받지만 기록하지 않는다. 그래서 현재 테스트는 request literal을 메서드에 넘겨도 verifier/normalizer hook이 그 request metadata를 실제로 받았는지 확인하지 못한다.

### 해결 방법

- fake adapter에 `verifyReq WebhookRequest`와 `normalizeReq WebhookRequest` 필드를 추가한다.
- 각 메서드에서 받은 request를 해당 필드에 저장한다.
- 테스트에서 두 저장값 모두에 대해 `Provider`, `EventType`, `ExternalID`, `Payload`, `Headers`, `Query`, `ReceivedAt`을 assert한다.
- 기존 candidate type/revision 검증은 유지한다.

### 테스트 작성

- 기존 `TestWebhookAdapterContractRequestDelivery`를 보강한다.
- 새 테스트 파일은 만들지 않는다.

### 중간 검증

```bash
cd services/core && go test -count=1 ./internal/provider
```

기대 결과: exit 0.

## 수정 파일 요약

| 파일 | 항목 |
| --- | --- |
| `services/core/internal/provider/provider_test.go` | REVIEW_API-1 |

## 최종 검증

```bash
cd services/core && go test -count=1 ./internal/provider
```

기대 결과: exit 0.
