- plane-origin-authoring-roundtrip-sync 마일스톤 gito-delivery, scan-enqueue, plane-todo, slot-finalize, regression-doc 완료 체크 - 완료 리뷰에 각 Task 완료 근거와 활성 plan 목록 업데이트 - live-cycle-smoke에 완료 오인 방지 기준 추가 - filename slug canonical id, archive 제외, provider identity - IOP queue timeout/stale, push-only 누락, Gito delivery-only 성공
8.1 KiB
8.1 KiB
| test_env | test_profile | domain | verification_type | last_rule_updated_at |
|---|---|---|---|---|
| local | live-cycle-smoke | core | smoke | 2026-06-21 |
live-cycle-smoke
전체 webhook → authoring → develop match → Plane projection → slot 회수 사이클을 검증한다. 이 문서는 절차 기술과 runtime-equivalent 근거를 함께 기록한다.
읽기 조건
live-webhook-task,webhook-auto-enqueue,live-creation-projection증거가 필요한 경우.agent-task/m-milestone-work-item-creation-sync/14+12,13_live_cycle_smoke구현/리뷰 시.
환경
- host: standard remote runner
toki@toki-labs.com, checkout$HOME/agent-work/nomadcode. - Core server: Docker Compose (
services/core/docker-compose.yml), host port18010->8080. - Plane dev:
https://plane.toki-labs.com, workspacegeneral, projectNOMAD. - Secrets:
.env.plane.local(ignored), SOPSsecrets/nomadcode.dev.sops.yaml(webhook secret). - runner checkout: 검증용 disposable mirror다. dirty worktree, uncommitted 변경, 임시 파일을 이유로 중단하지 않고 현재 대화 workspace의 요청 범위 상태와 같게 reset/clean/reclone 또는 파일 동기화한 뒤 테스트한다.
전제 조건
- Core server는 현재 검증 대상 상태로 빌드·배포되어 있어야 한다. 원격 checkout이나 실행 컨테이너가 낡았으면 테스트 수행자가 reset/clean/reclone, 파일 동기화, compose rebuild/recreate로 최신화한다.
PLANE_WEBHOOK_SECRET,PLANE_TOKEN등 secret은.env.plane.local또는 SOPS에서 로드한다.- Plane dev 서버가
https://plane.toki-labs.com에서 정상 동작 중이어야 한다. - workspace slot 행이 DB에
available상태로 최소 1개 이상 있어야 한다.
Fixture IDs (non-secret)
agent-test/plane-dev.md참조. webhook smoke에서는Backlog + AGENT assignee상태 티켓을 생성하거나 AGENT를 assign한다.- work item UUID는 Plane에서 새로 생성하거나 기존 NOMAD-10/NOMAD-11 같은 기존 fixture를 재사용할 수 있다.
명령 (SECRET_FREE)
# 1. 환경 로드 (secrets은 ignored local file에서)
set -a; source .env.plane.local; set +a
# 2. Core server 헬스 확인
CORE_URL="http://127.0.0.1:18010"
curl -s "$CORE_URL/api/tasks" | python3 -c \
"import sys,json; d=json.load(sys.stdin); print('task_count:', len(d.get('tasks',[])))"
# 3. DB slot 상태 확인 (slot_id=1 기준)
# - slot available이면 smoke 가능
# - slot in_use/dirty/error이면 prior run이 미완료 또는 오류임
curl -s "$CORE_URL/api/workspaces/slots" 2>/dev/null | head -200 || echo "(slot API 없음 - DB 직접 확인 필요)"
# 4. Plane: Backlog + AGENT assignee 티켓 생성 또는 AGENT 배정
# - Plane UI 또는 API로 수행; work_item_uuid만 기록
WORK_ITEM_UUID="<new-or-existing-uuid>"
# 5. Plane webhook 수동 전송 (plane-dev.md 참조)
# - Plane dev UI → Webhook Settings → Test Delivery
# - 또는 curl로 직접 (PLANE_WEBHOOK_SECRET 필요, secret 출력 금지)
# Expected: HTTP 202, Core logs show task created
# 6. Core task 생성 확인 (external_id=WORK_ITEM_UUID 로 조회)
curl -s "$CORE_URL/api/tasks?source=plane" 2>/dev/null | python3 -c "
import sys, json
d = json.load(sys.stdin)
for t in d.get('tasks', []):
if t.get('external_id') == '$WORK_ITEM_UUID':
m = t.get('metadata', {})
c = m.get('checkout', {})
print('task_id:', t['id'])
print('status:', t['status'])
print('slot_id:', c.get('slot_id'))
print('slot_path:', c.get('slot_path'))
print('authoring_run_state:', m.get('authoring_run_state'))
print('wait_type:', m.get('wait_type'))
"
# Expected: task found, checkout.slot_id > 0, authoring_run_state=in_progress
# 7. develop 브랜치에 push 발생 → gitosync scanner가 pick up (자동)
# Core log: roadmap_creation_sync job enqueued, SyncCreation 호출
# 8. projection 완료 후 task 상태 재확인
# Expected: authoring_run_state=succeeded, status=completed, slot released
# 9. slot 재사용 확인: 두 번째 smoke 티켓 생성 → 같은 slot_id 또는 새 available slot에서 reservation
검증 항목
| 항목 | 증거 유형 | 단계 |
|---|---|---|
live-webhook-task: webhook 202 + task 생성 + checkout metadata |
Live API 응답 | 5→6 |
webhook-auto-enqueue: task가 별도 API 호출 없이 authoring queue 진입 |
Core log 또는 status=running | 6 |
live-creation-projection: develop 스캔 → ledger steps → Plane Todo |
Core log + Plane UI | 7→8 |
| slot 재사용: 두 번째 smoke에서 slot available | API 응답 | 9 |
완료 오인 방지 기준
- filename slug canonical id:
roadmap_sync_identities.milestone_id또는 Core log가agent-roadmap/phase/*/milestones/<milestone-id>.md의 파일명 slug 기준으로 매칭됨을 보여야 한다.roadmap_milestone_path나 Plane work item id만 맞는 증거는 완료 근거가 아니다. - archive 제외: active reconcile 후보는
agent-roadmap/phase/*/milestones/*.md만 포함해야 한다.agent-roadmap/archive/**문서는 생성/갱신 대상이 아니라 이력 lookup 후보로만 남아야 한다. - provider identity 누락/불일치: generated Milestone에 provider identity가 없거나 원 Plane 티켓과 불일치하면 Plane
Todoprojection으로 넘기지 않는다. sync ledger 보강 또는 명시 failure evidence가 필요하다. - IOP queue timeout/stale: IOP
/v1/responses장시간 대기, queue timeout, stale monitor는 각각 task metadata에 관찰 가능한 상태로 남아야 한다. authoring 시작이나 단일 실패 로그만으로 terminal 완료/실패를 단정하지 않는다. - push-only 누락: authoring 응답 성공은 완료 근거가 아니다. push-only 요청, remote
developrevision 확인, Gito wakeup 이후 reconcile evidence가 이어져야 다음 단계 완료로 본다. - Gito delivery-only 성공: signed webhook 202 또는 duplicate 202는 delivery 증거일 뿐 full-cycle 완료 근거가 아니다. active Milestone slug reconcile enqueue,
roadmap_sync_steps, Plane body/title/comment projection,Todo이동까지 확인한다. - full-cycle 완료: 새 Plane
Backlog + AGENT assigneeauthoring roundtrip과 Git에만 있는 active Milestone missing-create/reconcile roundtrip을 모두 secret redaction 상태로 남긴다.
대체 근거 (런타임 에퀄리번트)
reviewed commit을 현재 실행 중인 서버에 배포하지 않은 경우 아래 단계로 대체 근거를 수집한다.
단계 A: unit test
cd services/core && go test -count=1 \
./cmd/plane-smoke/... \
./internal/http/... \
./internal/scheduler/... \
./internal/roadmapsyncpipeline/...
커버 범위:
TestRoadmapCreationSyncWorkerFinalizesExternalTaskOnProjected→ projection + slot available 전환TestMarkFailedWithTaskAuthoringRecordsState→ failure + slot error 전환TestMarkFailedWithTaskAuthoringMissingSlotIDSkipsSlotUpdate→ missing slot_id skipTestSyncCreationReadyRunsStepsAndMarksLedger→ ledger steps all marked- webhook HTTP handler tests → dispatch gate logic
단계 B: 기존 baseline 확인
# 2026-06-15 smoke baseline (commit 55e0139 기준 서버)
curl -s http://127.0.0.1:18010/api/tasks/e3c92411-4056-4b76-a879-66f7904125d0
# Expected: status=completed, checkout.slot_id=1, source=plane
live-webhook-task와 webhook-auto-enqueue의 일부 증거는 이 baseline이 커버한다.
live-creation-projection (Plane Todo 이동)과 slot terminal state 회수는 reviewed commit 배포 후만 검증 가능.
차단 기준
- Core server를 현재 검증 대상 상태로 재배포할 수 없으면
live-creation-projection과 slot 회수 증거를 수집할 수 없다. - 원격 runner checkout의 dirty 상태는 차단 기준이 아니다. reset/clean/reclone, 파일 동기화, Docker image 재빌드·재배포를 먼저 수행하고, 권한·secret·외부 서비스 장애처럼 에이전트가 해소할 수 없는 사유만 차단으로 보고한다.
보고 항목
- 실행한 명령:
- 성공한 검증:
- 실패/차단된 검증:
- 생략 사유:
- 남은 위험: