nomadcode/agent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.md
toki 528e9d6966 feat(roadmapsync): plane origin authoring roundtrip 기능 및 마일스톤 ID 지원
- roadmapsync pipeline에 retry 로직 및 개발 일치 검증 로직 추가
- gitosync scanner에 slug 재조정 및 plane 매칭 로직 강화
- roadmap sync identity 관리를 위한 migration(00009) 및 SQL 쿼리 추가
- milestone parser 테스트 및 retry 테스트 보강
- agent-ops 문서(PHASE, SDD, milestones) 갱신
- agent-task archive 및 작업 디렉터리 추가
2026-06-21 07:59:56 +09:00

19 KiB

SDD: Plane-Origin Authoring Roundtrip Sync

위치

  • Milestone: agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.md
  • Phase: agent-roadmap/phase/agent-ops-mcp-control-plane/PHASE.md

상태

[승인됨]

SDD 잠금

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

문제 / 비목표

  • 문제: Plane Backlog + AGENT assignee에서 시작한 Milestone authoring은 사용자 prompt, IOP workspace 실행, git push, Gito webhook, provider identity, Plane projection을 한 사이클로 묶기 때문에 source of truth와 terminal 조건이 분산될 수 있다. 또한 Git/Plane 동기화 identity가 path와 provider work item id에 나뉘면 phase/archive 이동 또는 Plane item 생성 전 상태에서 같은 Milestone 판별이 깨질 수 있으므로, Milestone 파일명 slug 하나를 canonical id로 삼아 active roadmap 전체를 reconcile해야 한다.
  • 비목표:
    • Plane Todo -> In Progress 이후 실행 lifecycle은 다루지 않는다.
    • Milestone Task를 Plane 하위 티켓으로 생성하거나 plan/code-review 루프와 연결하지 않는다.
    • Plane 외 provider(Jira 등)에 active Milestone missing-create를 적용하지 않는다.
    • archive Milestone을 Plane과 계속 실시간 동기화하는 작업은 다루지 않는다.
    • Milestone 파일명 slug rename/reuse를 자동 추론해 병합하는 작업은 다루지 않는다.
    • IOP 내부 모델 라우팅, queue 구현, RAG, output validation은 다루지 않는다.
    • 외부 agent 제어 표면 또는 MCP tool policy는 확정하지 않는다.

Source of Truth

영역 기준 메모
Roadmap agent-roadmap/phase/*/milestones/<milestone-id>.md 파일명 slug <milestone-id>가 Git/Plane 동기화의 단일 canonical Milestone id다. path는 active/archive 위치 속성이다.
Code services/core/internal/authoring/, services/core/internal/scheduler/, services/core/internal/gitosync/, services/core/internal/roadmapsync/, services/core/internal/roadmapsyncpipeline/, services/core/internal/projectsync/, services/core/internal/workitempipeline/ authoring input, state metadata, Gito scan, active Milestone index, slug identity match, Plane creation/projection, slot finalization의 구현 기준이다.
Ledger roadmap_sync_identities, roadmap_sync_steps milestone_id를 1차 키로 두고 path, provider work item id, revision, step completion은 속성/foreign key로 기록한다.
External Provider Plane, IOP OpenAI-compatible Responses, Forgejo, Gito Plane work item id/state, IOP response lifecycle, remote develop revision, signed Gito delivery가 외부 관찰 기준이다. Plane work item id는 canonical id가 아니라 provider foreign key다.
User Decision 없음 현재 Milestone 범위와 실패 처리 기준은 기존 roadmap/domain rule 표준선으로 확정 가능하다.

State Machine

상태 진입 조건 다음 상태 근거
plane_backlog_assigned Plane work item이 Backlog + AGENT assignee 조건을 만족한다. core_task_created, ignored Plane webhook 또는 intake scan, work item payload
core_task_created Core task와 checkout metadata가 생성된다. authoring_in_progress, authoring_blocked workitempipeline, task metadata checkout
authoring_in_progress IOP Responses authoring 요청을 시작한다. authoring_generated, authoring_waiting, authoring_failed authoring_run_state, authoring_run_updated_at, IOP response result
authoring_generated authoring 결과가 workspace checkout에 반영된다. push_requested, authoring_failed model response, workspace dirty state
push_requested Core/runtime이 push-only workspace agent 요청을 보낸다. develop_pushed, push_failed, authoring_waiting push-only task metadata, remote develop verification
develop_pushed remote develop revision이 변경된다. gito_delivered, scan_waiting Forgejo revision, Gito delivery
gito_delivered Gito signed HTTP webhook이 Core에 도착한다. active_reconcile_requested, delivery_duplicate, delivery_failed signed delivery 202, Core gito webhook log
active_reconcile_requested Core가 local develop checkout을 fetch한다. active_milestone_indexed, scan_waiting, scan_failed gitosync fetch/revision verification
active_milestone_indexed Core가 agent-roadmap/phase/*/milestones/*.md를 스캔하고 archive를 제외한다. milestone_id_matched, plane_missing_detected, slug_conflict active Milestone index, filename slug
plane_missing_detected active Milestone slug가 ledger와 Plane에서 발견되지 않는다. plane_item_created, creation_failed roadmap_sync_identities, Plane create API
plane_item_created Plane work item 생성이 성공한다. milestone_id_matched Plane work item id, slug ledger
milestone_id_matched active Milestone slug가 ledger 또는 생성된 Plane item과 연결된다. plane_projected, projection_failed roadmap_sync_steps, slug identity ledger
plane_projected Plane 본문/제목/comment/status projection이 완료된다. slot_available, reconcile_complete Plane API/UI, roadmap_sync_steps
slot_available Plane-origin authoring task의 성공 terminal 상태를 기록한다. 없음 workspace slot state available, task metadata
authoring_failed timeout, queue timeout, bridge failure, identity failure 등 terminal failure가 확정된다. slot_error, slot_dirty failure category, slot finalizer
slot_dirty 수동 복구가 필요한 git dirty 또는 push failure 상태다. 없음 slot state dirty, task metadata
slot_error bridge/provider 오류 또는 복구 불가 failure 상태다. 없음 slot state error, task metadata

Interface Contract

  • 계약 원문: 없음
  • 입력:
    • Active roadmap Milestone: repo-relative path, filename slug milestone_id, Markdown body, status, archive 여부.
    • Plane work item: title, description/comment body, assignee, state, provider work item id, external URL.
    • Core task external ref: provider, external id, external metadata, payload work_item.
    • checkout metadata: slot id, slot path, source branch, project sync context.
    • IOP Responses request: thin authoring instruction, user-origin message, workspace metadata, optional push-only request.
    • Gito webhook: signed push delivery, repository/ref/revision metadata.
  • 출력:
    • workspace changes on local checkout and remote develop commit.
    • roadmap_sync_identities and roadmap_sync_steps records keyed by milestone_id, with path, provider work item id, revision, projection, retry/idempotency state as attributes.
    • Plane work item creation for active Milestones that do not have a mapped Plane item.
    • Plane original comment preservation, body/title projection, Todo state move.
    • task metadata and workspace slot terminal state.
  • 금지:
    • roadmap_milestone_path나 Plane work item id를 canonical Milestone identity로 사용하지 않는다.
    • agent-roadmap/archive/** 문서를 active sync 생성/갱신 대상으로 삼지 않는다.
    • 같은 filename slug를 자동으로 두 Milestone에 병합하거나, rename/reuse를 추정하지 않는다.
    • Plane/provider identity나 sync 계약 문구를 기본 authoring 사용자 prompt에 섞지 않는다.
    • 첫 authoring 응답 성공만으로 Plane projection 또는 task completion을 단정하지 않는다.
    • Gito webhook 202 또는 remote commit만으로 full-cycle 완료를 단정하지 않는다.
    • identity missing, identity mismatch, milestone id conflict, push failure를 Plane Todo projection으로 넘기지 않는다.
    • tracked docs, roadmap, task logs, 최종 응답에 secret 원문을 기록하지 않는다.

Acceptance Scenarios

ID Milestone Task Given When Then
S01 thin-prompt Plane-origin authoring task에 explicit instruction override가 없다. BuildAuthoringGenerateInput이 기본 instruction을 만든다. instruction은 다음 메시지를 바탕으로 마일스톤을 작성해. 수준으로 얇고 Plane/provider 계약 문구를 포함하지 않는다.
S02 iop-long-run IOP Responses authoring이 10분 이상 걸리거나 queue 대기 중이다. scheduler가 timeout, retry, stale 판단을 수행한다. 작업은 조기 failed로 확정되지 않고 관찰 가능한 in-progress/stale metadata를 남긴다.
S03 iop-progress dev IOP가 streaming을 지원하거나 지원하지 않는다. Core가 /v1/responses 진행 상태를 기록한다. stream 미지원은 명시 사유로 기록되고, stream 지원 시 진행 갱신 중단을 감지할 수 있다.
S04 push-command authoring 결과 작성은 성공했지만 remote develop 확인은 아직 없다. Core/runtime이 push-only workspace agent 요청을 보낸다. push-only 단계와 remote develop 확인 전에는 다음 projection 단계로 넘어가지 않는다.
S05 identity-source Plane work item identity가 task external ref, payload, checkout metadata, project sync 설정에 있다. authoring input과 projection input을 만든다. 사용자 작성 문구에 의존하지 않고 identity를 유지하며, 누락 시 명시 오류로 멈춘다.
S06 identity-write generated Milestone에 provider identity block이 없다. Gito callback 이후 scan/match가 실행된다. Core/runtime 주입 또는 sync ledger로 match 가능 상태가 되거나 명시 failure로 수렴한다.
S07 develop-match remote develop revision에 Milestone path 변경 후보가 있다. Core가 provider identity와 원래 Plane 티켓을 비교한다. path와 identity가 모두 일치할 때만 Plane projection을 실행한다.
S08 idempotency-retry 같은 Plane 티켓, Milestone path, Gito revision이 재처리된다. creation sync가 재실행된다. 중복 Milestone/Plane mutation 없이 남은 단계만 재시도하고 충돌은 중단한다.
S09 canonical-id active Milestone 파일 경로가 agent-roadmap/phase/<phase>/milestones/<milestone-id>.md다. Core가 roadmap sync identity를 만든다. <milestone-id> filename slug 하나가 canonical id가 되고 path/provider work item id는 속성으로 기록된다.
S10 active-index remote develop에 active와 archive Milestone이 함께 있다. Gito wakeup 후 Core가 Milestone index를 스캔한다. agent-roadmap/phase/*/milestones/*.md만 sync 후보가 되고 agent-roadmap/archive/**는 제외되며, archive 문서는 slug lookup 후보로만 남는다.
S11 plane-missing-create active Milestone slug가 ledger와 Plane에서 발견되지 않는다. reconcile job이 실행된다. Plane work item을 생성하고 slug ledger 및 provider identity marker를 기록하며 중복 생성하지 않는다.
S12 slug-reconcile 같은 Milestone slug가 같은 revision 또는 재시도에서 다시 처리된다. reconcile이 identity ledger와 completed step을 확인한다. 중복 Plane item 없이 남은 단계만 재개하고, slug 충돌/재사용/rename 의심은 명시 failure로 멈춘다.
S13 gito-delivery Forgejo push가 Gito subscription 대상 branch에 발생한다. Gito가 Core signed HTTP webhook을 보낸다. Core는 delivery를 202로 받고 duplicate 처리를 secret 없이 확인할 수 있다.
S14 scan-enqueue Gito wakeup 후 local develop checkout이 fetch된다. Core가 active Milestone index를 만들고 slug 단위 reconcile job을 enqueue한다. 변경 파일 힌트와 무관하게 active Milestone 전체가 reconcile 후보가 되고 archive Milestone은 제외된다.
S15 plane-todo slug match 또는 Plane 생성이 완료된 reconcile job이 있다. Plane projection을 실행한다. 원문 댓글 보존, 본문 projection, [milestone-id] 제목 갱신, Todo 이동이 기록된다.
S16 slot-finalize success/failure/timeout/push failed/identity missing 결과가 확정된다. slot finalizer가 task metadata와 slot state를 갱신한다. 성공은 available, 수동 git 복구는 dirty, bridge/provider 오류는 error로 수렴한다.
S17 remote-baseline standard remote runner와 dev services 상태가 stale/dirty일 수 있다. reset/clean/reclone 또는 rebuild로 테스트 기준을 맞춘다. dirty runner 상태가 차단 사유가 되지 않고 현재 요청 범위와 같은 검증 환경이 된다.
S18 full-cycle 새 Plane Backlog 티켓과 Git에만 존재하는 active Milestone이 있다. Core task, IOP authoring, push-only, Gito callback, active reconcile, Plane projection까지 실행한다. Plane Todo projection과 active Milestone missing-create evidence가 함께 남는다.
S19 regression-doc 회귀 원인과 완료 오인 조건이 확인된다. 운영/테스트 문서를 갱신한다. filename slug canonical id, archive 제외, identity 누락, IOP queue timeout, push-only 누락, delivery-only 성공을 완료로 오인하지 않는 기준이 문서화된다.

Evidence Map

Scenario Required Evidence agent-task 연결 Spec Completion 기대
S01 services/core/internal/authoring unit test showing thin default instruction and forbidden provider terms absent agent-task/m-plane-origin-authoring-roundtrip-sync/... thin-prompt: authoring request test passed and default instruction text/provider-term absence recorded
S02 core config/scheduler test or smoke evidence for long-running timeout/retry/stale metadata behavior agent-task/m-plane-origin-authoring-roundtrip-sync/... iop-long-run: timeout/retry/stale thresholds and non-premature failure evidence recorded
S03 IOP streaming capability check and fallback stale-monitor evidence agent-task/m-plane-origin-authoring-roundtrip-sync/... iop-progress: stream supported path or stream unsupported explicit reason plus stale monitor evidence recorded
S04 scheduler/runtime test or smoke showing push-only request and remote develop verification gate agent-task/m-plane-origin-authoring-roundtrip-sync/... push-command: authoring success does not complete without push-only and remote develop check
S05 authoring/workitempipeline test showing workspace metadata identity retention and missing identity failure agent-task/m-plane-origin-authoring-roundtrip-sync/... identity-source: external ref/payload/checkout/project sync identity source evidence recorded
S06 gitosync/roadmapsync test or smoke showing identity block absence handled by deterministic injection/ledger or explicit failure agent-task/m-plane-origin-authoring-roundtrip-sync/... identity-write: identity-less generated Milestone does not silently drop
S07 develop match test covering dirty slot, push failure, mismatch, missing path, and successful match agent-task/m-plane-origin-authoring-roundtrip-sync/... develop-match: only path+identity match triggers Plane projection
S08 retry/idempotency tests for repeated Plane ticket, Milestone path, Gito revision, and partial failure recovery agent-task/m-plane-origin-authoring-roundtrip-sync/... idempotency-retry: duplicate mutation prevention and retry/abort distinction recorded
S09 storage/parser/matcher tests showing filename slug is canonical and path/provider ids are attributes agent-task/m-plane-origin-authoring-roundtrip-sync/... canonical-id: filename slug identity and path/provider attribute evidence recorded
S10 active index scan tests covering active Phase Milestones, archive exclusion, and slug lookup candidate behavior agent-task/m-plane-origin-authoring-roundtrip-sync/... active-index: active-only sync candidate evidence recorded
S11 Plane adapter/reconcile tests or smoke proving missing active Milestone creates one Plane item and records ledger/marker agent-task/m-plane-origin-authoring-roundtrip-sync/... plane-missing-create: missing active Milestone creation evidence recorded
S12 retry/idempotency tests for same slug reprocess, partial failure resume, and slug conflict/reuse failure agent-task/m-plane-origin-authoring-roundtrip-sync/... slug-reconcile: duplicate prevention and conflict failure evidence recorded
S13 secret-redacted live evidence for Forgejo -> Gito -> Core signed delivery and duplicate handling agent-task/m-plane-origin-authoring-roundtrip-sync/... gito-delivery: signed delivery 202, Core log, duplicate result recorded without secret
S14 gitosync/roadmapsyncpipeline test or smoke proving active index scan-to-reconcile enqueue and archive exclusion agent-task/m-plane-origin-authoring-roundtrip-sync/... scan-enqueue: active reconcile enqueue evidence recorded
S15 Plane UI/API plus roadmap_sync_steps evidence for comment/body/title/Todo projection keyed by milestone id agent-task/m-plane-origin-authoring-roundtrip-sync/... plane-todo: original comment, body update, title update, Todo move recorded
S16 scheduler/projectsync finalizer tests or smoke for available, dirty, error terminal mapping agent-task/m-plane-origin-authoring-roundtrip-sync/... slot-finalize: terminal task metadata and slot state evidence recorded
S17 standard remote runner setup log with branch/revision and clean/reclone/rebuild actions as needed agent-task/m-plane-origin-authoring-roundtrip-sync/... remote-baseline: runner baseline evidence recorded
S18 agent-test/live-cycle-smoke.md run evidence with secret redaction from Plane Backlog to Plane Todo and active missing-create agent-task/m-plane-origin-authoring-roundtrip-sync/... full-cycle: authoring roundtrip and active reconcile evidence recorded
S19 doc diff in agent-test/live-cycle-smoke.md or core README covering regression prevention criteria agent-task/m-plane-origin-authoring-roundtrip-sync/... regression-doc: regression criteria documented

Cross-repo Dependencies

  • 없음

Drift Check

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

사용자 리뷰 이력

  • 없음

작업 컨텍스트

  • 표준선: Plane 티켓 본문과 authoring prompt는 사용자 요청 원문 중심으로 유지하고, Git/Plane 동기화의 canonical Milestone id는 파일명 slug 하나로 둔다. path와 Plane work item id는 각각 현재 위치와 provider foreign key이며, provider identity, project sync 설정, push 검증, Gito delivery, Plane creation/projection은 Core/runtime의 결정적 책임으로 둔다.
  • 후속 SDD: 없음