gito/agent-roadmap/archive/sdd/provider-change-request-integration/webhook-revision-reconcile/SDD.md

9.9 KiB

SDD: Webhook Revision Reconcile

위치

  • Milestone: agent-roadmap/archive/phase/provider-change-request-integration/milestones/webhook-revision-reconcile.md
  • Phase: agent-roadmap/phase/provider-change-request-integration/PHASE.md

상태

[승인됨]

SDD 잠금

  • 상태: 해제
  • 사용자 리뷰: 없음
  • 잠금 항목:
    • 없음

문제 / 비목표

  • 문제: NomadCode가 Gito의 branch.updated event를 generic HTTP webhook wakeup으로 받을 수 있어야 한다. 동시에 webhook delivery는 최종 source of truth가 아니며, delivery idempotency, retry, signature, revision 재검증 경계를 구현 전에 고정해야 한다.
  • 비목표:
    • NomadCode 전용 필수 payload field를 base schema에 추가하지 않는다.
    • provider별 모든 webhook payload를 이 Milestone에서 지원하지 않는다.
    • webhook delivery 성공을 NomadCode 또는 다른 consumer의 상태 적용 완료 증거로 취급하지 않는다.
    • proto-socket, gRPC, Redis Streams fanout을 external consumer delivery 경로로 추가하지 않는다.
    • UI conflict resolution 화면은 이 Milestone에서 다루지 않는다.

Source of Truth

영역 기준 메모
Roadmap agent-roadmap/phase/provider-change-request-integration/milestones/webhook-revision-reconcile.md Milestone 목표, 범위, 기능 Task 완료 기준
Code services/core/internal/controlplane/, services/core/internal/events/, services/core/internal/worker/ REST subscription/delivery surface, normalized event, durable delivery/outbox 구현 기준
External Provider Forgejo push webhook, Gito outbound HTTP webhook consumer Forgejo push는 wakeup source, consumer delivery는 branch.updated wakeup signal
User Decision 없음 기존 gito.forgejo-branch-events.v1 계약을 따른다

State Machine

상태 진입 조건 다음 상태 근거
webhook-received Forgejo push callback이 유효 payload로 수신된다 event-recorded 또는 ignored POST /callbacks/forgejo/push, watch match 여부
ignored event가 unsupported 또는 unwatched branch에 해당한다 없음 response accepted=true, matched=false
event-recorded watched branch의 before/after revision이 normalized branch.updated로 기록된다 delivery-pending durable event/outbox record
delivery-pending matching webhook subscription이 존재한다 delivery-sending subscription event/repo/branch filter
delivery-sending worker가 pending delivery를 HTTP POST로 전송한다 delivery-succeeded 또는 delivery-retryable 또는 delivery-failed target HTTP response, timeout, signature config
delivery-succeeded consumer endpoint가 2xx를 반환한다 없음 delivery attempt record
delivery-retryable consumer endpoint가 429 또는 5xx를 반환하거나 transient network failure가 발생한다 delivery-pending 또는 delivery-failed retry/backoff policy
delivery-failed consumer endpoint가 non-retryable response를 반환하거나 retry budget이 소진된다 없음 delivery attempt state
reconcile-conflict expected revision이 현재 source of truth와 맞지 않는다 dry-run-result 또는 없음 Git revision scan 또는 provider read API
applied idempotency key로 중복 적용이 차단되고 change apply가 성공한다 없음 apply result and idempotency record

Interface Contract

  • 계약 원문: agent-contract/provided/gito-forgejo-branch-events-v1.md
  • 입력:
    • Forgejo callback: POST /callbacks/forgejo/push
    • branch watch: POST /api/listeners/branches
    • webhook subscription: POST /api/webhook-subscriptions
    • subscription filter: events, repo_id, branch
    • signing reference: secret_ref
    • revision identity: repo_id, branch, before, after
  • 출력:
    • normalized event: branch.updated
    • webhook headers: X-Gito-Event, X-Gito-Delivery, optional X-Gito-Signature
    • consumer payload: id, type, provider, delivery_id, repo_id, branch, before, after, changed_files, observed_at, created_at
    • delivery attempt state: pending, sending, succeeded, retryable, failed
  • 금지:
    • raw secret, token, password, credential 값을 tracked docs, event payload, log에 남기지 않는다.
    • NomadCode 전용 필수 field를 base branch.updated payload에 추가하지 않는다.
    • provider callback이 NomadCode, Plane, roadmap source of truth를 직접 변경하지 않는다.
    • consumer webhook delivery를 최종 상태 증거로 취급하지 않는다.
    • external consumer delivery에 proto-socket을 요구하지 않는다.

Acceptance Scenarios

ID Milestone Task Given When Then
S01 subscription consumer endpoint, event type, repo/branch filter, secret_ref가 입력된다 webhook subscription을 등록한다 subscription id와 filter가 저장되고 raw secret은 저장되지 않는다
S02 deliver watched nomadcode/develop branch에서 branch.updated event가 기록되고 matching subscription이 있다 delivery worker가 event를 처리한다 fake consumer가 signed HTTP POST, delivery id, base payload를 수신한다
S03 nomadcode-wakeup NomadCode dev consumer가 generic branch.updated endpoint를 제공한다 Gito가 matching delivery를 전송한다 consumer가 NomadCode 전용 필수 field 없이 wakeup으로 매핑할 수 있다
S04 retry consumer가 429 또는 5xx를 반환한다 delivery attempt가 기록된다 retry/backoff 상태가 PostgreSQL 기준으로 남고 delivery idempotency가 유지된다
S05 webhook-source Forgejo push callback이 들어온다 payload가 watch와 match된다 provider.webhook.received 또는 equivalent wakeup source event와 normalized branch event가 추적 가능하다
S06 poll-source provider webhook이 누락되거나 지연된다 polling fallback shape를 사용한다 같은 revision identity로 change source를 표현할 수 있다
S07 git-source Git revision scan이 before/after revision을 알고 있다 provider event와 scan result를 reconcile한다 동일 repo/branch/revision identity로 중복 이벤트를 피한다
S08 expected-rev expected revision과 현재 branch revision이 다르다 reconcile을 시도한다 apply 없이 conflict로 멈춘다
S09 dry-run event와 현재 Git/provider 상태가 주어진다 dry-run을 실행한다 drift, conflict, proposal이 관찰 가능한 결과로 반환된다
S10 apply 같은 event 또는 idempotency key가 반복 처리된다 apply를 두 번 요청한다 side effect는 한 번만 실행되고 중복은 idempotent 결과로 수렴한다

Evidence Map

Scenario Required Evidence agent-task 연결 Spec Completion 기대
S01 subscription create/list test, secret value grep agent-task/m-webhook-revision-reconcile/... subscription task가 contract filter와 secret_ref storage boundary를 만족했다
S02 cd services/core && go test -run TestWebhookDeliveryBranchUpdated ./internal/controlplane/ -v -count=1 agent-task/m-webhook-revision-reconcile/... deliver task가 fake consumer delivery id, headers, payload 수신을 증명했다
S03 NomadCode interop smoke 또는 fake NomadCode consumer test agent-task/m-webhook-revision-reconcile/... nomadcode-wakeup task가 generic branch.updated만으로 wakeup mapping을 증명했다
S04 delivery retry/backoff unit or integration test with PostgreSQL store agent-task/m-webhook-revision-reconcile/... retry task가 retryable/non-retryable status와 delivery idempotency를 증명했다
S05 Forgejo callback test and event inspection evidence agent-task/m-webhook-revision-reconcile/... webhook-source task가 provider callback을 wakeup source로 저장/추적함을 증명했다
S06 polling fallback shape contract or unit test agent-task/m-webhook-revision-reconcile/... poll-source task가 polling source를 동일 change model로 표현함을 증명했다
S07 revision identity dedupe/reconcile test agent-task/m-webhook-revision-reconcile/... git-source task가 Git revision scan과 provider event identity 연결을 증명했다
S08 expected revision mismatch test agent-task/m-webhook-revision-reconcile/... expected-rev task가 mismatch conflict stop을 증명했다
S09 reconcile dry-run test with drift/conflict/proposal output agent-task/m-webhook-revision-reconcile/... dry-run task가 apply 없이 observable proposal 결과를 증명했다
S10 idempotent apply test with repeated event/key agent-task/m-webhook-revision-reconcile/... apply task가 repeated processing side effect once를 증명했다

Cross-repo Dependencies

  • NomadCode는 external consumer로 branch.updated delivery를 수신한다. 현재 SDD는 .agent-roadmap-sync/locks.yaml entry를 요구하지 않는다.
  • 계약 기준은 agent-contract/provided/gito-forgejo-branch-events-v1.md이다.

Drift Check

  • Milestone 기능 Task와 Acceptance Scenario가 일치한다.
  • Evidence Map이 plan/code-review/complete.log에서 검증 가능하다.
  • agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
  • 사용자 리뷰가 필요한 항목은 USER_REVIEW.md에만 남겼다.

사용자 리뷰 이력

  • 없음

작업 컨텍스트

  • 표준선: webhook은 빠른 wakeup signal이며 최종 판정은 Git revision/diff 또는 provider read API로 수행한다. 외부 event delivery는 HTTP webhook/callback이고, proto-socket은 내부 control/runtime 규약으로만 남긴다.
  • 후속 SDD: 없음