diff --git a/.gitignore b/.gitignore index 72c9ff6..8c574cb 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ .env.* !.env.example +# Plane local secrets +.env.plane.local + # Logs *.log diff --git a/agent-ops/roadmap/ROADMAP.md b/agent-ops/roadmap/ROADMAP.md index ccbcb0f..bbe66c1 100644 --- a/agent-ops/roadmap/ROADMAP.md +++ b/agent-ops/roadmap/ROADMAP.md @@ -26,7 +26,7 @@ NomadCode는 모바일 앱, 웹 콘솔, core 서비스, 공유 계약, agent-ope ### Work Item Provider Pipeline Design -- [Work Item Provider Pipeline Design](milestones/plane-task-pipeline-design.md) - 상태: 계획; 목표: Plane/Jira 등 work item provider와 core task 사이의 생성, enqueue, 상태 투영, 결과 발행 계약을 provider-neutral하게 정리한다. +- [Work Item Provider Pipeline Design](milestones/plane-task-pipeline-design.md) - 상태: 진행 중; 목표: Plane/Jira 등 work item provider와 core task 사이의 생성, enqueue, 상태 투영, 결과 발행 계약을 provider-neutral하게 정리한다. ### Workflow Core diff --git a/agent-ops/roadmap/current.md b/agent-ops/roadmap/current.md index 8c64f00..728e060 100644 --- a/agent-ops/roadmap/current.md +++ b/agent-ops/roadmap/current.md @@ -2,7 +2,7 @@ ## 활성 Milestone -- Work Item Provider Pipeline Design (상태: 계획, 구현 착수 전): agent-ops/roadmap/milestones/plane-task-pipeline-design.md +- Work Item Provider Pipeline Design (상태: 진행 중, 현재 항목: 자동 enqueue/trigger 경계 결정): agent-ops/roadmap/milestones/plane-task-pipeline-design.md ## 선택 규칙 diff --git a/agent-ops/roadmap/milestones/plane-task-pipeline-design.md b/agent-ops/roadmap/milestones/plane-task-pipeline-design.md index d3a2015..021da01 100644 --- a/agent-ops/roadmap/milestones/plane-task-pipeline-design.md +++ b/agent-ops/roadmap/milestones/plane-task-pipeline-design.md @@ -10,7 +10,7 @@ Work Item Provider Pipeline Design ## 상태 -계획 +진행 중 ## 범위 @@ -32,6 +32,13 @@ Work Item Provider Pipeline Design - [x] 생성된 task는 `pending` 상태로 남기고 enqueue는 별도 단계에서 처리한다. - [x] Plane 연결 정보는 provider-neutral external ref와 Plane metadata에 함께 저장한다. - [ ] 자동 enqueue 여부와 사용자/운영 트리거 경계를 결정한다. + - [x] `backlog`에서 `todo`로 옮기는 주체는 사용자로 둔다. + - [x] `todo` 상태여도 agent 작업자가 지정된 work item만 자동 실행 후보로 본다. + - [x] provider API 인증은 일반 사용자형 service account token을 기본으로 둔다. + - [x] Plane dev service account token은 ignored local file `.env.plane.local`에 저장하고, NomadCode project Admin 권한으로 검증한다. + - [x] worker identity는 provider assignee만으로 고정하지 않고 core metadata와 label/comment prefix로 표현한다. + - [ ] webhook-first trigger와 polling fallback의 세부 조건을 확정한다. + - [ ] agent 작업자 지정 신호를 assignee, label, 또는 둘의 조합 중 무엇으로 볼지 확정한다. - [ ] work item provider adapter interface를 설계한다. - [ ] core pipeline이 사용할 provider-neutral DTO를 정의한다. - [ ] work item 조회, comment 작성, status/state 변경, label projection 경계를 interface로 분리한다. @@ -107,6 +114,14 @@ Work Item Provider Pipeline Design - provider 본문(description)은 작업 요구사항과 맥락의 원본으로 보고, agent 실행 상태를 매번 갱신하는 저장소로 쓰지 않는다. - Plane custom property는 현재 NomadCode dev project에서 `is_issue_type_enabled=False`라 기본 경로로 전제하지 않는다. - Plane 샘플 work item `NOMAD-13`은 `In Progress` state와 `agent:waiting-user`, `phase:planning` 라벨로 board state와 agent 내부 실행 상태 분리 방식을 보여준다. +- trigger/auth 결정: + - 사용자가 `backlog`에서 `todo`로 이동시키는 행위가 AI 작업 위임 의사로 간주될 수 있는 첫 관문이다. + - core는 `todo` 상태와 agent 작업자 지정 신호가 함께 있을 때만 자동 실행 후보로 본다. + - provider webhook을 우선 trigger로 사용하고, polling은 webhook 누락 또는 장애 복구용 fallback으로 둔다. + - provider API 호출과 댓글 작성은 일반 사용자형 service account token으로 수행한다. + - Plane dev token은 repo root의 ignored `.env.plane.local`에서 로드하며, 해당 token 계정은 NomadCode project Admin 권한으로 API 조회/댓글 작성 smoke가 성공했다. + - worker identity는 service account 인증 주체와 분리한다. 실제 agent 종류는 core metadata, provider label, comment prefix에 남긴다. + - Plane bot user는 UI 필터와 내장 agent trigger 경로가 있어 1차 작업자 모델로 전제하지 않는다. - provider abstraction 결정: - Plane은 첫 구현 provider일 뿐이며 core pipeline의 도메인 모델이 되어서는 안 된다. - Jira도 같은 workflow state, label/comment projection, idempotency 계약을 공유할 수 있어야 한다. @@ -119,8 +134,10 @@ Work Item Provider Pipeline Design - `✅ VERIFY | <요약>`: 테스트/검증 완료 기록 - 각 comment 본문은 1~2줄 요약을 기본으로 하며, 자세한 실행 로그나 상태 metadata는 core에 남긴다. - 현재 지점 / 착수 상태: - - 현재 상태는 `계획`이며, 구현 착수 전 설계 정리 지점이다. + - 현재 상태는 `진행 중`이며, 구현 착수 전 설계 정리 지점이다. + - 현재 진행작업은 `자동 enqueue 여부와 사용자/운영 트리거 경계를 결정한다` 항목이다. - 정리된 내용은 provider-neutral 방향성, Plane/Jira adapter 추상화 필요성, label/comment 기반 상태 투영 샘플이다. - - 아직 확정되지 않은 다음 결정은 provider adapter interface, trigger 경계, core metadata schema, provider label mapping이다. + - 현재 항목에서 아직 확정되지 않은 결정은 webhook-first trigger와 polling fallback의 세부 조건, agent 작업자 지정 신호를 assignee/label/조합 중 무엇으로 볼지다. + - 이후 남은 큰 결정은 provider adapter interface, core metadata schema, provider label mapping이다. - 다음에 이 마일스톤을 착수하면 Plane 고정 진입부 리팩토링 전에 위 결정 항목을 먼저 닫는다. - 확인 필요: trigger 방식은 현재 구현 상태와 운영 기대치를 보고 수동 endpoint 유지, webhook, polling 중 하나를 선택한다. diff --git a/agent-ops/rules/project/domain/core/rules.md b/agent-ops/rules/project/domain/core/rules.md index 0534eb4..10c28df 100644 --- a/agent-ops/rules/project/domain/core/rules.md +++ b/agent-ops/rules/project/domain/core/rules.md @@ -56,7 +56,9 @@ NomadCode의 백엔드 오케스트레이션 도메인이다. workflow, scheduli - compose service 이름은 `plane-api`, `plane-worker`, `plane-beat`, `plane-frontend`, `postgres`, `redis`, `rabbitmq`, `minio`다. 실제 컨테이너 이름은 `plane-api`, `plane-worker`, `plane-beat`, `plane-frontend`, `plane-postgres`, `plane-redis`, `plane-rabbitmq`, `plane-minio`다. - NomadCode dev Plane workspace slug는 `general`, workspace id는 `dadf050e-cd1e-4590-bc33-672511630841`, project id는 `a6beb42f-7a8a-410c-b50f-ea3ca94828f3`, project identifier는 `NOMAD`다. - NomadCode project state id: Backlog `62d4c50c-0cea-4a76-a0ed-ec97498b2d5f`, Todo `45ba7449-f684-4381-af6d-5854747c5e8d`, In Progress `c6ac1a6b-74d5-47fb-8b36-646d2bf0284d`, Done `ea2e5b48-8bf1-4723-b749-de7723be41e9`, Cancelled `f29c06c2-d70c-4b56-a83c-fccc4db60ae4`. -- Plane API token이나 서버 `.env`의 secret 값은 domain rule에 기록하지 않는다. API 호출은 가능하면 `PLANE_TOKEN` 환경 변수로 수행하고, 토큰이 없을 때 서버 내부 조작이 명시적으로 요청되면 `plane-api`의 Django shell/ORM을 우선 사용한다. +- Plane API 호출은 repo root의 ignored local secret file `.env.plane.local`을 우선 사용한다. 이 파일은 `PLANE_BASE_URL`, `PLANE_TOKEN`, `PLANE_WORKSPACE_SLUG`, `PLANE_PROJECT_ID`를 담고 있으며 `.gitignore`로 제외된다. shell 작업에서는 `set -a; source .env.plane.local; set +a`로 로드한다. +- `.env.plane.local`의 현재 Plane token 계정은 NomadCode project에서 Admin role로 설정되어 있다. +- Plane API token이나 서버 `.env`의 secret 값은 domain rule에 직접 기록하지 않는다. 토큰 파일이 없거나 API 권한이 부족할 때만 서버 내부 조작이 명시적으로 요청되면 `plane-api`의 Django shell/ORM을 사용한다. - Plane custom property는 work item types 기반 기능이며, 현재 NomadCode dev project의 `is_issue_type_enabled`는 `False`다. 무료 self-hosted/free tier에서는 이 기능을 전제로 설계하지 않는다. - Plane work item 샘플 `NOMAD-13`은 `In Progress` state에 있으며, board state와 agent 내부 실행 상태를 분리하는 예시다. external source/id는 `nomadcode` / `sample-agent-in-progress-state`이고, 라벨 `agent:waiting-user`, `phase:planning`으로 내부 상태를 보드에서 보이게 한다. - provider-neutral 상태 설계는 board state를 `backlog`, `todo`, `in_progress`, `testing`, `complete`, `cancel`로 두고, canonical agent 실행 상태는 core task metadata에 저장한다. provider에는 labels를 우선 투영하고, 자세한 사유는 comment로 남긴다. diff --git a/agent-ops/rules/project/rules.md b/agent-ops/rules/project/rules.md index ea91b76..c6176b9 100644 --- a/agent-ops/rules/project/rules.md +++ b/agent-ops/rules/project/rules.md @@ -35,6 +35,7 @@ NomadCode는 AI 병렬 작업 운용을 위한 원레포다. 백엔드 오케스 - `apps/mobile` 변경은 `flutter test`와 필요 시 `flutter analyze --no-fatal-infos`로 확인한다. - `packages/contracts`가 실제 계약을 갖기 전에는 API 형태를 서비스/클라이언트에 중복 고정하지 말고 계약 후보를 문서화한다. - 하위 앱/서비스에 별도 `agent-ops`나 AI entry 파일을 만들지 않는다. 루트 `agent-ops`와 루트 entry 파일만 사용한다. +- Plane 관련 core 작업은 `agent-ops/rules/project/domain/core/rules.md`의 `Plane dev 작업 메모`를 먼저 확인한다. Plane API 토큰은 ignored local secret file `.env.plane.local`에서 로드하며, 토큰 값은 규칙/로드맵/문서에 직접 기록하지 않는다. ## 도메인 매핑