<!-- task=m-gito-branch-event-creation-sync-bridge/02+01_creation_enqueue_bridge plan=0 tag=GITO_CREATION_ENQUEUE -->

# Plan: Gito Creation Enqueue Bridge

## 메타
- Milestone: `gito-branch-event-creation-sync-bridge`
- Build grade: cloud-G07
- Mode: implementation
- Scope: Gito `branch.updated` 이벤트를 target branch revision 검증, milestone markdown scan, Plane work item 조회, `EnqueueRoadmapCreationSync` 호출로 연결한다.

## 분할 판단
- 선행 작업: `01_event_client`
- 선행 완료 조건: `agent-task/m-gito-branch-event-creation-sync-bridge/01_event_client/complete.log`
- 현재 상태: 선행 계획은 존재하지만 아직 구현 완료 전이다. 이 계획은 후속 구현 계획으로 남기며, 실제 구현은 선행 이벤트 클라이언트가 완료된 뒤 진행한다.

## Roadmap Targets
- `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/gito-branch-event-creation-sync-bridge.md`
- Task IDs:
  - `[revision-scan]`
  - `[creation-enqueue]`
  - `[runtime-wiring]`
- Completion mode: check-on-pass

## 문제 요약
Core에는 creation sync worker와 enqueue 함수가 있지만, Gito 이벤트에서 자동으로 job args를 구성해 enqueue하는 bridge가 없다.

확인된 코드 레벨 근거:
- [services/core/internal/scheduler/river.go](/config/workspace/nomadcode/services/core/internal/scheduler/river.go:99): `EnqueueRoadmapCreationSync`는 존재하지만 외부 이벤트 wakeup producer가 없다.
- [services/core/internal/roadmapsyncpipeline/service.go](/config/workspace/nomadcode/services/core/internal/roadmapsyncpipeline/service.go:113): `SyncCreation`은 scan result와 expected Plane todo args를 요구하므로, 이벤트에서 이 입력을 구성하는 계층이 필요하다.
- [services/core/cmd/server/main.go](/config/workspace/nomadcode/services/core/cmd/server/main.go:103): scheduler와 creation sync service는 wiring되어 있지만 Gito event runner는 없다.

## 구현 계획

### 1. Revision scan seam 추가
- 패키지 후보: `services/core/internal/gitosync`
- `BranchRevisionScanner`
  - 입력: `gitoevents.BranchUpdatedEvent`
  - 설정: develop branch checkout path, remote name, target branch
  - 출력: `roadmapsync.ScanResult` 후보 목록
- `CommandRunner` seam을 둬 git command를 테스트 가능하게 만든다.
- 권장 git 흐름:
  - `git -C <developBranchPath> fetch --prune origin develop`
  - `git -C <developBranchPath> rev-parse refs/remotes/origin/develop`
  - remote revision이 event `after`와 다르면 not-ready로 skip
  - `git -C <developBranchPath> diff --name-only <before> <after> -- agent-roadmap/phase/*/milestones/*.md`
  - `git -C <developBranchPath> show <after>:<path>`로 milestone markdown을 읽고 [services/core/internal/roadmapsync/milestone_parser.go](/config/workspace/nomadcode/services/core/internal/roadmapsync/milestone_parser.go:1)의 parser를 사용한다.
- Gito `changed_files`는 scan 시작 여부를 줄이는 hint로만 사용하고 최종 변경 파일은 target revision에서 다시 검증한다.

### 2. Creation enqueue bridge 추가
- `Bridge` 또는 `Handler`
  - Gito event target repo/branch/path 검증.
  - scanner로 milestone candidates 구성.
  - milestone identity에서 provider key/ref를 읽는다.
  - [services/core/internal/workitem/provider.go](/config/workspace/nomadcode/services/core/internal/workitem/provider.go:1)의 reader/Plane client 계층으로 기존 Plane work item을 조회한다.
  - original body는 HTML description 우선, 없으면 text description fallback을 사용한다.
  - Todo state id는 설정에서 주입한다. 예: `PLANE_TODO_STATE_ID` 또는 `ROADMAP_CREATION_TODO_STATE_ID`.
  - `scheduler.RoadmapCreationSyncJobArgs`를 구성해 [services/core/internal/scheduler/river.go](/config/workspace/nomadcode/services/core/internal/scheduler/river.go:99)의 enqueue 함수를 호출한다.
- duplicate/same revision 처리:
  - MVP에서는 bridge 내부 `ProcessedRevisionStore` seam을 둔다.
  - `(repo_id, branch, after)`가 이미 처리된 경우 enqueue하지 않는다.
  - 실제 sync step은 기존 identity/ledger idempotency를 함께 사용한다.

### 3. Runtime wiring
- [services/core/cmd/server/main.go](/config/workspace/nomadcode/services/core/cmd/server/main.go:103)
  - config에 Gito endpoint/repo/branch/todo-state-id가 모두 있을 때만 event runner를 시작한다.
  - `context.Context` 종료와 함께 runner를 stop한다.
  - endpoint 미설정이면 기존 Core server 동작은 동일해야 한다.
- public HTTP API는 추가하지 않는다.

### 4. 테스트
- `services/core/internal/gitosync/scanner_test.go`
  - fake command runner로 fetch/rev-parse/diff/show 순서 검증.
  - remote revision이 event `after`와 다르면 enqueue 후보 없음.
  - milestone markdown parser 결과가 scan result로 변환되는지 검증.
- `services/core/internal/gitosync/bridge_test.go`
  - wrong repo/branch/path는 enqueue하지 않음.
  - provider identity 없는 milestone은 skip 또는 명시 error 처리.
  - Plane work item 조회 결과로 exact `RoadmapCreationSyncJobArgs` 생성.
  - same `(repo_id, branch, after)` 이벤트는 중복 enqueue하지 않음.
- `services/core/internal/config/config_test.go`
  - Todo state id env/default/disabled 동작 검증.

## 완료 조건
- Gito `branch.updated`가 Core creation sync enqueue로 연결된다.
- target branch revision 확인 후 milestone markdown을 스캔한다.
- Plane original body/state 기반으로 creation sync job args를 구성한다.
- endpoint 또는 todo-state-id 미설정 시 기존 runtime은 disabled 상태로 유지된다.
- 아래 검증이 통과한다.
  - `cd services/core && go test -count=1 ./internal/gitoevents ./internal/gitosync ./internal/roadmapsync ./internal/roadmapsyncpipeline ./internal/scheduler ./internal/config`
  - `cd services/core && go test -count=1 ./...`
  - `cd services/core && go vet ./...`
  - `git diff --check`

## 구현 후 사용자 리뷰 요청

아래 내용을 포함해 사용자 리뷰를 요청한다.

```markdown
## 사용자 리뷰 요청

- 구현 요약:
  - Gito branch event에서 target branch revision scan 수행
  - milestone markdown을 `roadmapsync.ScanResult`로 변환
  - Plane work item 조회 후 `EnqueueRoadmapCreationSync` 연결
  - runtime 설정 기반 runner wiring
- 확인 요청:
  - Todo state id 설정명이 운영 배포 방식에 맞는지
  - 중복 이벤트 처리를 MVP in-memory revision guard로 시작해도 되는지
```
