Skip to content

Plan — infra-orchestrator v1

infra-orchestrator 개발기획서 (v1)

status: SSOT (초안 v4를 로컬·범용으로 개정)
엔진 repo: infra-orchestrator
CLI: porch (충돌 시 infra-orch)
Python 패키지: infra_orchestrator
naming SSOT: docs/NAMING_AND_TOPOLOGY.md
v4 분석: internal/infra-orchestrator-v4-review
한 줄: Python이 상태·검증·Git을 통제하고, Cursor는 Task마다 새로 만드는 로컬 일회성 Agent로만 호출한다.

플랫폼 v1의 Phase 2 “병렬 오케스트레이션”과 slug는 같고 역할은 다르다. 이 repo는 Cursor 개발 Task 자동화다. 제품 스토리보드 병렬 생성은 infra-canvas / ai-engine에 둔다.

다이어그램은 Mermaid다. GitHub, VS Code, Cursor Markdown 미리보기에서 렌더링된다.

목차

  1. 개요
  2. 범위와 설계 원칙
  3. 아키텍처
  4. 모듈과 Plan 규격
  5. 데이터 모델
  6. 상태 머신과 정책
  7. 사용량
  8. 신뢰성·보안
  9. 로드맵
  10. 테스트·지표·남은 결정

1. 개요

기획서를 입력받아 RELEASE_READY까지 로컬에서 자동 진행하되, Cursor 토큰을 구조적으로 줄이는 Python 엔진이다. 여러 제품 org·workspace가 같은 엔진을 쓰고, 프로젝트 차이는 .orchestrator/만으로 흡수한다.

문제

  • 한 Agent 세션에 구현·리뷰·수정·테스트가 쌓이면 입력이 수백만 토큰으로 커진다.
  • git status, 테스트, 린트처럼 결정론적 일까지 AI가 한다.
  • 기획서 원문이 Task마다 다시 읽힌다.
  • Review가 구현 대화에 섞이면 자기 검토 편향이 생긴다.

목표

  1. 사람 개입 없이 Task 단위로 구현·검증·(필요 시) 리뷰·수정해 RELEASE_READY까지 간다. Merge/배포는 V1 밖.
  2. Task·Review·Fix마다 새 local Agent. 대화 재사용 없음.
  3. Git·테스트·린트·타입체크·범위 검사는 AI 토큰 0.
  4. Task별 사용량을 기록하고 Cost per Verified Task로 이후 분할·모델·중단을 판단한다. V1은 측정만.
  5. 엔진은 독립 repo. 프로젝트에는 어댑터만.

비목표

  • Cursor GUI 매크로. cloud Agent. 무승인 Production. 프롬프트 문구 최적화 도구.
  • V1의 병렬 Task, MCP 제어, SQLite, 상태바, porch release.

성공 게이트

게이트기준
G0Plan 규격이 실제 기획 1건을 표현한다. FakeAgent 테스트가 통과한다. probe-sdk가 usage·도구 이름을 기록한다. Cost per Verified Task가 수동 대비 개선되거나, 절감 없음이 숫자로 명시된다.
G1샌드박스 E2E가 RELEASE_READY. 가능하면 autogen-labs core에 설정만 붙여 소규모 plan 1건.

G0에서 절감이 없으면 V1 자동 run을 확대하지 않는다.


2. 범위와 설계 원칙

구분V1 포함제외 (후속)
개발 자동화구조화 Plan 컴파일, 순차 Task, 검증, Scope Guard, 체크포인트, 최종 검증비구조 Markdown AI 분해 (V1.5), 교차 리뷰 (V2)
릴리스RELEASE_READY에서 정지PR/CI/Merge/Deploy (V3)
계측usage.jsonl 기록 (observe)warn/enforce, 과금 정산
환경엔진 1개 + 프로젝트 .orchestrator/ + repo별 cwd거대 모노레포로 합치기

원칙 (고정)

  1. Python이 기본, Cursor는 예외. 정적 분석·테스트·Git으로 알 수 있는 것은 묻지 않는다.
  2. Task마다 새 Agent, cwd는 대상 repo 하나. send() 정확히 1회. dirs 없음. 엔진 repo는 탐색 범위에 넣지 않는다. resume 금지.
  3. 변경되지 않은 기획서만 컴파일한다. 원문 해시가 바뀌면 PLAN_CHANGED. 구조화 Plan은 AI 없이 파싱한다. 기획 대화는 구현으로 넘기지 않는다.
  4. 검증은 AI 없이, 그리고 먼저. 실패 시에만 stderr 앞부분을 Fix Capsule에 넣는다.
  5. 불확실하면 멈춘다. 한도·범위 위반·형식 오류 → BLOCKED 또는 HUMAN_REQUIRED.
  6. 측정 후 개입한다. V1은 observe. 자동 분할·중단은 표본이 쌓인 뒤.
  7. 정책은 계층이다. defaults + override를 run 시작 시 스냅샷. 안전 키는 강화만.
  8. 엔진과 프로젝트를 분리한다. 상태는 XDG 상태 홈. 수동 Cursor 명령과 자동 모드는 같은 정책 파일을 공유하되 UI에 의존하지 않는다.
  9. 최소 권한. 단계별 도구 allowlist. 셸 없음. run 환경에는 CURSOR_API_KEY와 최소 PATH만.
  10. 완료는 증거다. Agent의 DONE 선언은 무시한다. AC 매핑 + 검증 + (필요 시) 리뷰 + 체크포인트 SHA가 있어야 DONE.
  11. 로컬 env 격리. GitHub·배포 비밀은 run 프로세스에 넣지 않는다. Agent는 프로세스 env를 상속하므로 시작 전에 걸러진다.
  12. FakeAgent 우선. 오케스트레이터 로직은 cursor-sdk 없이 테스트한다. 실 Agent는 cursor_client와 probe-sdk 뒤에만 둔다.

3. 아키텍처

flowchart TB
PLAN["PLAN.md"] --> PC["Plan Compiler"]
PC --> LOCK["plan.lock.json + ledger.json"]
subgraph ENGINE["infra-orchestrator 로컬 프로세스"]
PA["Project Adapter · Lock"]
SCH["Scheduler"]
CB["Context Builder"]
AR["cursor_client"]
VE["Verifier"]
PA --> SCH --> CB --> AR --> VE
VE -. 실패 .-> SCH
end
LOCK --> PA
AR --> CUR["cursor-sdk local Agent\ncwd=대상 repo · send 1회"]

Run 수명주기

flowchart TD
A1["Cursor IDE에서 PLAN.md 작성"] --> B1["porch plan · lint"]
B1 --> B2{"사람 승인 N Tasks"}
B2 -- 승인 --> B3["Task 루프 구현→검증→리뷰→커밋"]
B3 --> B4["최종 검증 AC 커버리지"]
B4 --> RR(["RELEASE_READY 정지"])
B2 -- 거절 --> A1
RR -.-> C1["V3 porch release 사람 승인"]

porch run은 RELEASE_READY에서 멈춘다. 실행 중 원문 해시가 바뀌면 PLAN_CHANGED.

디렉터리

infra-orchestrator/
├── src/infra_orchestrator/
│ ├── cli.py
│ ├── project.py
│ ├── locks.py
│ ├── planner.py
│ ├── scheduler.py
│ ├── context_builder.py
│ ├── cursor_client.py # cursor-sdk 유일 import
│ └── verifier.py
├── prompts/
├── schemas/
├── policies/defaults.yaml
├── examples/sandbox-app/
└── tests/
<project>/
└── .orchestrator/
├── project.yaml
└── policy.yaml
$XDG_STATE_HOME/infra-orchestrator/projects/<id>/runs/<run-id>/
├── run.json
├── ledger.json
├── events.jsonl
├── usage.jsonl
└── effective-policy.yaml

$XDG_STATE_HOME가 없으면 ~/.local/state/infra-orchestrator.

프로젝트 어댑터 (이것만 복사하지 않고 작성)

<project>/.orchestrator/
project.yaml # id, engine_version, plans.root, repositories
policy.yaml # override only
  • 저장소가 하나여도 1급이다.
  • checks는 키 → argv 배열. Plan의 verify: ID만 verify_ids로 선택자에 매핑한다.
  • 엔진은 Agent cwd/dirs에 넣지 않는다.

4. 모듈과 Plan 규격

모듈책임AI
Project Adapter설정 로드, 정책 병합, 스냅샷없음
Lock Manager프로젝트·repo 락, dirty tree 거부없음
Plan Compiler구조화 Plan → lock + ledgerV1: 0회
Scheduler의존성·상태로 다음 Task없음
Context BuilderCapsule없음
cursor_clientSDK 또는 FakeAgent, usage 정규화호출 시
VerifierRegistry 명령, Scope Guard없음

Plan 규격 (HTML 주석 금지)

앞머리 orchestrator + Task마다 YAML 펜스 orchestrator. 동반 파일 *.tasks.yaml도 허용한다.

---
orchestrator:
version: 1
project: example
mode: phase
repositories: [sandbox-app]
---
# Example
## Decisions
| id | decision |
| --- | --- |
| D-1 | 공개 API만 변경한다 |
## Phase 1
### DEMO-01
```orchestrator
repo: sandbox-app
risk: low
depends_on: []
decisions: [D-1]
```
#### Goal
인사 함수가 이름을 반환한다.
#### Acceptance Criteria
- AC-1: `greet`가 Hello를 포함한다. (verify: UT-1)
#### Scope
- sandbox-app: src/hello.py

필수: repo, risk, AC 1개 이상, 각 AC의 verify 또는 review. lint는 순환 의존, 고아, ID 중복, 미등록 repo, 해석 불가 verify ID, 누락 D-id를 오류로 한다. 모호한 AC 문구는 경고.

사람 승인 게이트: lint 통과 후 “N Tasks / M Phases”.

Capsule (상한 가이드, 실측 전 상수 아님)

  • Task id, goal, AC
  • 참조된 D-id만
  • scope expected / forbidden
  • 힌트 파일·심볼 (있으면)
  • verify id
  • 이전 실패 stderr 앞부분 (있을 때만)
  • handoff.json (Review/Fix만)

전체 기획서·전체 대화·엔진 소스는 넣지 않는다.

cursor_client (로컬 SDK)

  • 패키지 cursor-sdk, Python 3.11+, CURSOR_API_KEY (User 또는 Service Account. Team Admin 불가). 레포에 키를 두지 않는다.
  • LocalAgentOptions(cwd=대상repo). cloud 금지. model 필수. 시작 시 Cursor.models.list().
  • observe/warn: Agent.prompt() (자동 dispose). enforce(후속): Agent.create + send 1회 + wait / cancel + close.
  • CursorAgentError = 미시작. result.status == "error" = 실행 중 실패.
  • 도구는 호출마다 지정. Review는 읽기 전용. 셸 없음. 잘못된 이름은 생성 에러 → V0에서 표 갱신.
  • 설정 소스 기본은 inline. project는 V0에서 안전할 때만.

검증과 Git

  • verify ID → project.yaml의 checks + verify_ids만 실행. argv 배열.
  • Scope Guard: expected / auto_allowed / needs_approval / forbidden.
  • 기존 테스트 파일 삭제·축소는 플래그.
  • run 시작 시 dirty이면 거부. repo마다 porch/<run-id> 브랜치. VERIFIED 후 Python이 로컬 커밋 (Porch-Task: <id>). push 없음.
  • hook 실패는 VERIFY_FAILED. --no-verify 금지. 롤백은 run 브랜치 안의 마지막 DONE만.

최종 검증

  1. Plan 해시
  2. AC가 verify 또는 review에 매핑되고 PASS. 미매핑은 unverifiable → 사람
  3. final.checks
  4. 미해결 required finding 없음. discovered_issues는 보고서에만
  5. 통합 리뷰는 V1 기본 끔 (정책 high_risk_only는 V2)
  6. reviewed_shas 기록, RELEASE_READY

5. 데이터 모델

계층: Project → Run → Task → AgentCall. 원자적 기록 (temp + rename). V1은 JSON.

정지 상태 (ledger가 재개에 쓰는 값)

TODO · PARTIAL · IMPLEMENTED · VERIFY_FAILED · NEEDS_FIX · VERIFIED · DONE · BLOCKED · HUMAN_REQUIRED

실행 중 표시 (비정상 종료 시 증거로 정지 상태로 복원)

IMPLEMENTING · VERIFYING · REVIEWING · FIXING

판정은 ledger, git diff, 검증 로그, 리뷰 JSON, 체크포인트 SHA. 충돌·재개에서만 읽기 전용 state Agent를 Task당 1회까지 (V2).

run.json 고정값: plan 해시, lock 해시, 정책 해시, engine_version, schema_version, repo별 base SHA. 불일치 → HUMAN_REQUIRED (PLAN_CHANGED / POLICY_CHANGED / BASE_MOVED / ENGINE_MISMATCH).


6. 상태 머신과 정책

stateDiagram-v2
[*] --> TODO
TODO --> IMPLEMENTING
IMPLEMENTING --> IMPLEMENTED
IMPLEMENTING --> HUMAN_REQUIRED
IMPLEMENTED --> VERIFYING
VERIFYING --> VERIFY_FAILED
VERIFY_FAILED --> FIXING
VERIFYING --> REVIEWING: MEDIUM_HIGH
VERIFYING --> VERIFIED: LOW
REVIEWING --> VERIFIED: PASS
REVIEWING --> NEEDS_FIX
NEEDS_FIX --> FIXING
REVIEWING --> HUMAN_REQUIRED: BLOCKED
FIXING --> VERIFYING
FIXING --> HUMAN_REQUIRED: 한도
VERIFIED --> DONE: checkpoint

LOW는 AI 리뷰 없음. MEDIUM은 리뷰. HIGH 교차 리뷰는 V2. 수정 후 항상 VERIFYING부터.

기본 모드: phase (Phase 끝나면 승인). 초기 실험은 guided.

정책 병합: 일반 키는 override. risk.force_high_paths는 추가만. agent.tools.*는 축소만, 셸 추가 불가. 잠금 키(sends_per_agent, cwd, dirs, production_credentials, release.create_pr, release.merge, release.production, require_sha_match) 완화는 로드 오류.

잠긴 기본값: local · send 1회 · dirs=[] · shell 없음 · tools 미지정 시 빈 allowlist (SDK 전체 도구 금지) · Plan 셸 미실행 · release.create_pr=disabled · merge/prod 승인 · MCP로 release 없음 · HTML 주석 없음 · XDG 상태 홈 · CLI porch. probe-sdk Agent.prompt는 명시적 sandbox --cwd만. 엔진 repo는 cwd/dirs에 넣지 않는다. Agent env는 allowlist (CURSOR_API_KEY + 최소 PATH).


7. 사용량

V1은 observe. 프롬프트 LLM 사전 분석은 하지 않는다.

우선순위: SDK result.usage / 스트림 → get_usage() → 프록시(호출 수, Capsule 길이, 시간). 없으면 confidence=estimated로 실행은 계속.

최우선 지표: Cost per Verified Task = (실패 포함 총 토큰) ÷ (검증 완료 Task). Context ROI(읽은 파일 / 수정한 파일)는 측정 후 사람 제안만.


8. 신뢰성·보안

위험대응
반쯤 수정된 트리Task 전 체크포인트, 실패 시 run 브랜치만 롤백
JSON 형식 오류스키마 → 1회 재요청 → BLOCKED
루프max_fix_cycles 3, max_review_cycles 4, max_agent_calls 6
Plan 명령 주입Registry만 실행
env 상속run에 배포 비밀 없음
동시 run락, 못 잡으면 거부 (대기 없음)
dirty 작업 트리시작 거부
SDK 스키마 변경cursor_client 격리, 모르는 필드 무시

멱등: 단계 시작 전 ledger·git으로 완료 여부를 본다. resume은 마지막 기록된 정지 상태에서만.


9. 로드맵

단계범위게이트
V0스키마, FakeAgent, porch doctor / probe-sdk, 토큰 비교 3–5 TaskG0
V1순차 MVP, JSON 상태, Scope Guard, 체크포인트, RELEASE_READYG1
V1.5일반 Markdown 1회 분해, 두 번째 프로젝트는 설정만G2
V2위험도, Fix 루프, usage warnG3
V2.5+cross-repo, release, MCP, 병렬필요 확인 후

V0 체크리스트: 구조화 기획 1건 수작업 컴파일, Registry 해석, uv sync + CURSOR_API_KEY, Cursor.models.list(), 읽기 전용 Agent로 usage/allowlist/setting_sources/대화 기록 위치 확인, prompt vs create+send 비교.


10. 테스트·지표·남은 결정

  • 단위: 상태 전이, Scope Guard, Plan lint, 정책 병합(잠금 키), 락, run 고정값.
  • FakeAgent: PASS / NEEDS_FIX / BLOCKED / 형식 오류 / 중도 종료.
  • 복구: 전이 직전·직후 강제 종료 후 resume.
  • 실 Cursor: 샌드박스, 비용 있으므로 릴리스 전.

지표: Cost per Verified Task, Task당 토큰, 단일 호출 최대, Context ROI, AI 회피율, AC 커버리지, 재작업률, 사람 개입률, 범위 위반율.

V0에만 남는 결정: usage 필드 실측, 실제 도구 이름, setting_sources=project 여부, 고정 model id.


변경 이력

버전내용
v1 G0 isolationtools allowlist → SDK AgentOptions, 기본 도구 집합 금지, Agent env allowlist, probe-sdk는 명시적 sandbox cwd, release.create_pr=disabled 잠금
v1 (이 문서)slug infra-orchestrator, 로컬 SDK, FakeAgent, YAML 펜스, 단일 상태 enum, V1에서 릴리스/MCP 제거, 범용 .orchestrator/
초안 v4분석만 internal 리뷰