# Milestone: Webhook Revision Reconcile

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/provider-change-request-integration/PHASE.md`

## 목표

NomadCode가 generic `branch.updated` HTTP webhook delivery를 wakeup으로 받을 수 있게 하는 대응을 최우선으로 진행한다. 이후 provider webhook, outbound consumer webhook, provider polling, Git revision scan을 같은 변경 입력으로 정규화한다. Webhook은 빠른 wakeup signal이지만 최종 판정은 Git revision/diff 또는 provider read API로 재검증해 중복 적용과 누락을 줄인다. 외부 event delivery는 GitHub webhook과 유사한 HTTP callback 방식으로 제공하고, proto-socket은 외부 연결 규약에서 제외한다.

## 상태

[완료]

## 승격 조건

- 없음

## 구현 잠금

- 상태: 해제
- SDD: 필요
- SDD 문서: `agent-roadmap/archive/sdd/provider-change-request-integration/webhook-revision-reconcile/SDD.md`
- 잠금 해제 조건:
  - [x] SDD 잠금이 해제되어 있다.
  - [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
  - [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
  - [x] Evidence Map이 plan의 `Spec Targets`와 완료 시 `Spec Completion`으로 검증 가능하게 연결되어 있다.
- 결정 필요: 없음
- 해소 근거:
  - SDD 상태는 `[승인됨]`이고 SDD 잠금은 해제되어 있다.
  - `agent-contract/provided/gito-forgejo-branch-events-v1.md`의 NomadCode interop 확인 기준을 그대로 따른다.

## 범위

- NomadCode `branch.updated` consumer webhook wakeup interop
- consumer webhook subscription과 HTTP delivery
- delivery idempotency, signature, retry/backoff
- branch updated event
- webhook received event
- provider polling fallback
- revision mismatch conflict
- idempotency key와 expected revision
- reconcile dry-run/apply action 후보

## 기능

### Epic: [delivery] Webhook delivery

정규화된 event를 NomadCode 같은 외부 consumer가 제공한 HTTP endpoint로 전달한다.

- [x] [subscription] consumer endpoint, event type, repo/branch filter, `secret_ref`를 등록하는 형식을 정의한다.
- [x] [deliver] `branch.updated` 같은 normalized event를 signed HTTP POST로 전달한다. 검증: fake consumer endpoint가 delivery id와 payload를 수신한다.
- [x] [nomadcode-wakeup] NomadCode dev consumer가 generic `branch.updated` HTTP webhook delivery를 wakeup으로 매핑할 수 있는 interop path를 검증한다. 검증: `cd services/core && go test -run TestWebhookDeliveryBranchUpdated ./internal/controlplane/ -v -count=1`
- [x] [retry] delivery idempotency, retry/backoff, failed delivery 상태를 PostgreSQL 기준으로 기록한다.

### Epic: [sources] Change sources

여러 입력을 하나의 change event model로 정규화한다.

- [x] [webhook-source] webhook payload를 wakeup signal event로 저장한다.
- [x] [poll-source] provider polling fallback shape를 정의한다.
- [x] [git-source] Git revision scan event와 provider event를 같은 identity로 연결한다.

### Epic: [reconcile] Reconcile policy

변경 적용 전 재검증과 conflict 처리를 수행한다.

- [x] [expected-rev] expected revision이 맞지 않으면 conflict로 멈춘다.
- [x] [dry-run] reconcile dry-run 결과로 drift/conflict/proposal을 반환한다.
- [x] [apply] idempotency key로 중복 적용 없이 change를 반영한다. 검증: 같은 event 재처리 시 side effect가 한 번만 실행된다.

## 완료 리뷰

- 상태: 통과
- 요청일: 2026-06-19
- 완료 근거:
  - `agent-task/archive/2026/06/m-webhook-revision-reconcile_1/complete.log`의 `Roadmap Completion`에서 `expected-rev`, `dry-run`, `apply`가 PASS로 기록되었다.
  - 같은 `complete.log`의 `Spec Completion`에서 SDD Acceptance Scenario `S08`, `S09`, `S10`이 PASS로 기록되었다.
  - 최종 검증 `cd services/core && go test ./...`, focused reconcile tests, `git diff --check`가 PASS로 기록되었다.
  - 코드레벨 완료 감사에서 fresh `cd services/core && go test -count=1 ./...`, focused reconcile/webhook tests, Postgres webhook delivery store test가 PASS했다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 모든 기능 Task와 SDD scenario가 evidence와 함께 완료되었고, 코드레벨 재검토에서 완료 차단 이슈가 없어 Milestone을 완료/archive 처리했다.

## 범위 제외

- provider별 모든 webhook payload 지원
- real-time delivery 보장
- Redis Streams fanout
- proto-socket external consumer delivery
- UI conflict resolution 화면

## 작업 컨텍스트

- 관련 경로: `services/core/internal/controlplane/`, `services/core/internal/events/`, `services/core/internal/provider/`, `services/core/internal/gitengine/`, `services/core/internal/worker/`, `agent-contract/provided/gito-forgejo-branch-events-v1.md`
- 표준선(선택): webhook은 빠른 신호이고 확정은 Git revision/diff 또는 provider read API로 수행한다. 외부 event delivery는 HTTP webhook/callback이며 proto-socket은 내부 control/runtime 규약으로만 남긴다. NomadCode 전용 필수 필드는 base payload에 넣지 않는다.
- 선행 작업: Forgejo Branch Event MVP와 `gito.forgejo-branch-events.v1` 계약
- 후속 작업: Change Request Abstraction, Flutter Control Surface Baseline
- 작업현황 동기화(2026-06-18): `subscription`, `deliver`, `nomadcode-wakeup`, `retry`, `webhook-source`, `git-source`는 코드/테스트 근거로 완료 처리했다.
- 작업현황 동기화(2026-06-18): `poll-source`는 provider polling 입력 shape와 revision identity dedupe 테스트 근거로 완료 처리했다.
- 계획 작성(2026-06-18): `expected-rev`, `dry-run`, `apply`는 `agent-task/m-webhook-revision-reconcile/PLAN-local-G05.md`에서 reconcile policy 작업으로 묶었다.
- 작업현황 동기화(2026-06-19): `expected-rev`, `dry-run`, `apply`는 `agent-task/archive/2026/06/m-webhook-revision-reconcile_1/complete.log`의 Roadmap/Spec Completion 근거로 완료 처리했다.
- 완료 처리(2026-06-19): 코드레벨 감사에서 Required/Suggested 이슈가 없었고 fresh core 검증이 통과해 archive 이동했다.
- 남은 기능 Task: 없음.
