docs(agent-ops): 검증 게이트를 최소화한다

누적된 잠금·승인·증거 체인이 구현과 완료를 반복 차단해 작업 비용을 키웠다. 보안·데이터 손상·명시적 외부 의존성만 차단 조건으로 남기고 로드맵과 스킬의 기본 흐름을 단순화한다.
This commit is contained in:
toki 2026-08-15 16:53:32 +09:00
parent eee4f883e7
commit 6c52e7b56f
77 changed files with 882 additions and 4175 deletions

View file

@ -1,59 +1,38 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- **과설계를 금지한다.** 기능을 먼저 최소 구현하며, 구현 단계의 검증은 보안·데이터 손상 방지처럼 반드시 필요한 경우 외에는 두지 않는다. 추가 검증은 실제 문제가 확인된 뒤에만 보강한다.
- `agent-ops/rules/common/**``agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
- **최우선 방향은 검증 게이트 최소화다.** 새 게이트를 만들지 않는 것에 그치지 않고, 기존 게이트도 계속 제거·병합해 최소 개수로 유지한다.
- 차단형 검증 게이트는 보안·자격증명, 데이터 손상·비가역 외부 변경, 사용자가 명시한 실제 프로젝트 간 선행 의존성에만 허용한다. 그 밖의 테스트·문서·승인·정합성·evidence는 차단형 게이트로 만들지 않는다.
- 기존 구조를 우선하고 요청 범위 안에서 가장 작은 변경으로 구현한다.
- 과설계를 금지한다. 새 추상화·문서·상태·검증은 현재 요청에 반드시 필요할 때만 추가한다.
- 테스트·SDD·spec·plan·review·evidence는 필요에 따라 사용하는 산출물이며 서로의 선행 허가 조건으로 자동 연결하지 않는다.
- 코드 변경 전 변경 경로에 대응하는 `agent-ops/rules/project/domain/**/rules.md`만 읽는다.
- `agent-ops/rules/project/rules.md`는 프로젝트 구조나 도메인 매핑 확인이 필요할 때만 읽는다.
- `agent-ops/skills/common/router.md`는 사용자가 Agent-Ops 산출물이나 명시적인 skill workflow를 요청했을 때만 읽는다.
- `agent-ops/rules/common/**``agent-ops/skills/common/**`은 사용자가 직접 지시한 경우에만 수정한다. 프로젝트별 변경은 대응하는 `project/**` 영역을 우선한다.
- 불확실한 제품 결정이 구현에 직접 필요하면 후보와 영향을 제시하고 사용자 결정을 기다린다. 관련 없는 작업까지 잠그지 않는다.
- 최종 답변은 한국어로 한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우, plan 스킬이 같은 task group의 새 index를 충돌 없이 할당하는 경우, `sync-milestone-workstate`가 활성 대상 Milestone의 동일 `m-<milestone-slug>` task group evidence를 집계하는 경우, 또는 `sync-agent-ui mode=reconcile-completion`에 exact `completion-log` 경로가 전달된 경우에만 필요한 범위를 좁게 읽는다. split 의존성 확인과 Milestone workstate 동기화는 같은 task group의 후보 `complete.log`와 직접 연결된 plan/review log만 읽을 수 있다. index 할당은 같은 task group의 archived sibling directory basename만 열람하고 내부 파일은 읽지 않는다. UI 완료 정합화는 전달된 exact `complete.log` 한 건만 읽고 sibling archive log를 탐색하지 않는다.
- `agent-roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- `agent-spec/` 디렉터리가 있는 프로젝트에서 현재 구현 스펙 확인, 기존 기능 변경, 완료 검토, 구현 스펙 생성/갱신 요청은 세션 1회 `agent-ops/rules/common/rules-agent-spec.md`를 읽고, `agent-spec/index.md`와 매칭되는 spec 문서만 읽는다.
- `agent-spec/archive/**`는 일반 작업에서 읽지 않는다. 과거 스펙 확인, 복원, 비교, 특정 archive 경로 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-spec.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- project skill 경로 `agent-ops/skills/project/<skill-name>/SKILL.md`를 선택했을 때 같은 이름의 `agent-ops/skills/private/<skill-name>/SKILL.md`가 있으면 private skill을 우선한다. 없으면 project skill을 사용한다.
- project skill과 짝이 없는 private skill은 `agent-ops/rules/private/rules.md`에 명시적으로 라우팅한다. private skill 디렉터리 전체를 탐색하지 않는다.
- API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
## 필요한 경우에만 읽는 문서
1. `agent-ops/rules/project/rules.md`
2. `agent-ops/rules/private/rules.md`
3. `agent-roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
- 로드맵 생성·갱신·상태 확인: `agent-ops/rules/common/rules-roadmap.md`
- agent-spec 생성·갱신 또는 현재 구현 스펙 확인: `agent-ops/rules/common/rules-agent-spec.md`와 매칭되는 spec
- agent-ui 작업: `agent-ops/rules/common/rules-agent-ui.md`
- Agent-Ops 구조·책임 경계 변경: `agent-ops/rules/common/philosophy.md`
- API, wire, runtime call, event/config schema 계약 확인: `agent-contract/index.md`와 매칭되는 계약
- 환경 의존 live/full-cycle 검증을 사용자가 요청했거나 변경 위험상 필요한 경우: 해당 `agent-test/<env>/rules.md`
# 프로젝트 간 잠금
## 아카이브
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
- `agent-task/archive/**`, `agent-roadmap/archive/**`, `agent-spec/archive/**`, `agent-ui/**/archive/**`는 일반 작업에서 읽지 않는다.
- 사용자가 과거 작업 확인·복원·비교를 요청했거나 활성 문서가 정확한 evidence 경로를 가리킬 때만 필요한 파일 하나로 범위를 좁혀 읽는다.
# 스킬 규칙
## 프로젝트 간 의존성
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
- agent-ops 초기화
- domain rule 생성
- skill 생성/갱신
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- agent-spec 생성/갱신, 현재 구현 스펙 문서화, 구현 스펙 업데이트, 스펙 동기화
- README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신
- SDD 작성/갱신, SDD 필요 여부, SDD gate 확인, SDD 사용자 리뷰, SDD 잠금 해제
- 로드맵 현지점 / 현재 작업 지점 확인
- 현재 또는 지정 마일스톤 시작 전 정합성 체크 / 전체 프로젝트 작업현황과 마일스톤 정합성 확인 / plan 전 마일스톤 리프레시
- 마일스톤 완료 검토 / 종료 검토 / 현재 마일스톤 닫기 / 다음 마일스톤 지정
- 계획 작성 / plan 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
- 사용자가 Milestone 간 선행 의존성을 명시한 경우에만 `update-roadmap`으로 기록한다.
- 관련성, 권장 순서, 문서 미비, 테스트 미실행은 프로젝트 간 잠금으로 만들지 않는다.
# 테스트 규칙
## 테스트
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- 기본 검증은 변경한 패키지나 컴포넌트의 가장 작은 관련 테스트다.
- 전체 테스트, E2E, live provider, full-cycle, 외부 CLI 검증은 사용자가 요청했거나 변경이 그 경로를 직접 수정해 국소 테스트로 위험을 확인할 수 없을 때만 수행한다.
- 테스트를 실행할 수 없다는 이유만으로 구현이나 다른 독립 작업을 차단하지 않는다. 수행하지 못한 검증과 남은 위험만 보고한다.

View file

@ -1,79 +1,27 @@
---
test_env: <local|dev|qa|prod>
test_env: <env>
test_profile: <test-profile>
domain: <domain|project-wide>
verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
verification_type: <smoke|unit|integration|e2e|manual>
last_rule_updated_at: <YYYY-MM-DD>
---
# <test_profile> <test_env> 테스트
## 읽기 조건
- < 도메인/검증 시나리오의 테스트, 검증, 실행 조건 판단이 필요한 경우>
# <test-profile> <env> 테스트
## 적용 범위
- <검증 대상 entrypoint, command, API, UX, profile, service>
- <직접 검증할 동작>
## 분류
## 최소 검증
- domain: <domain|project-wide>
- verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
- scope: <검증 대상 변경 범위 요약>
- 명령:
- 성공 기준:
## 환경
## 선택 검증
- host:
- port:
- runtime:
- package manager:
- docker:
- external service:
- model endpoint:
- credential:
- <실제 실패나 구체적 위험이 있을 때만 실행>
## 명령
## 제약
- setup:
- lint:
- unit:
- smoke:
- e2e:
- model:
- full-cycle:
## 필수 검증
- <작업 완료 반드시 실행하거나 판단해야 하는 검증>
## 보조 검증
- <실행하면 좋지만 필수 검증을 대체하지 않는 smoke/helper 검증>
## 판정 기준
- <통과로 판단할 출력, 상태, UX, artifact, endpoint 조건>
## 기준 출력 예시
```text
<필요한 경우 기대 출력 예시>
```
## 차단 기준
- <테스트를 계속할 없는 환경/권한/도구/서비스 조건>
## 보고 항목
- 실행한 명령:
- 성공한 검증:
- 실패/차단된 검증:
- 생략 사유:
- 남은 위험:
## 금지 사항
- < 도메인/검증 시나리오에서 하면 되는 >
- secret, token, 개인 endpoint 원문은 tracked 파일에 기록하지 않는다.
- <보안·데이터 손상 방지 또는 환경 제약>
- secret과 개인 endpoint 원문은 기록하지 않는다.

View file

@ -5,39 +5,23 @@ last_rule_updated_at: <YYYY-MM-DD>
# <env> 테스트 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
## 방향
## 공통 규칙
- <env> 테스트/검증은 이 파일을 기준으로 판단한다.
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
- 검증 게이트 최소화를 최우선으로 한다.
- 변경 위험에 직접 대응하는 가장 작은 검증을 기본으로 선택한다.
- 확대 검증은 사용자 요청, 실제 실패, 구체적 위험이 있을 때만 추가한다.
- 실행하지 않은 선택 검증은 완료를 자동 차단하지 않는다.
- secret과 개인 endpoint 원문은 기록하지 않는다.
## 기본 환경
- host:
- repo root:
- sync 기준:
- runtime:
- package manager:
- external service:
- credential:
## 프리플라이트
- plan 작성 시 필수 검증이 현재 checkout을 벗어나 원격 runner, 외부 서비스, Docker/code-server, emulator/device, 공유 장기 runtime을 사용하면 먼저 테스트 환경 프리플라이트를 계획에 기록한다.
- 테스트 환경 프리플라이트에는 runner, repo root/workdir, branch/HEAD/dirty 상태, local 변경과 원격 source 동기화 여부, binary/artifact 경로와 필요한 help/version 출력, config path, runtime identity, port/process 상태, 외부 host, OS/arch 가정을 포함한다.
- 프리플라이트에서 dirty/divergent checkout, stale artifact, 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 plan은 먼저 setup/sync/rebuild 단계를 만들거나 blocker로 보고한다.
## 라우팅
- <domain 또는 project-wide> / <verification-type> / <scope 요약>: `agent-test/<env>/<test-profile>.md`
- <scope>: `agent-test/<env>/<test-profile>.md`
## 라우팅 규칙
- 여러 항목이 맞으면 모두 읽는다.
- 도메인 매핑이나 domain rule이 있으면 각 도메인의 `<domain>-smoke` 문서를 기본 baseline으로 둔다.
- 도메인이 아직 없을 때만 `project-smoke`를 fallback baseline으로 둔다.
- 도메인/검증 시나리오별 문서는 다른 테스트 문서로 라우팅하지 않는다.
관련 profile만 읽는다. 여러 profile을 기본으로 누적하지 않는다.

View file

@ -5,6 +5,8 @@
## 핵심
- 최우선 운영 방향은 **검증 게이트 최소화**다. 새 게이트 억제뿐 아니라 기존 게이트 제거·병합을 지속하며, 보안·자격증명, 데이터 손상·비가역 외부 변경, 사용자가 명시한 실제 프로젝트 간 선행 의존성 외에는 차단형 게이트를 두지 않는다.
- 테스트, 문서, SDD, spec, plan, review, 정합성, evidence는 필요에 따라 사용하는 도구이며 서로의 선행 허가 조건으로 연결하지 않는다.
- agent-ops는 AI agent가 작업하기 위한 규칙이자 가이드다.
- 사람 문서처럼 장황하게 설명하지 않고, agent가 바로 실행할 수 있게 작성한다.
- 필요한 컨텍스트만 읽게 만든다. 모든 문서를 항상 읽게 만들지 않는다.
@ -53,7 +55,7 @@
- 그룹 간 연결은 사용자 명령, 런타임 이벤트, 또는 판별 가능한 파일 상태로만 한다.
- 구현 작업 그룹은 `plan``code-review`의 PLAN/CODE_REVIEW 루프를 소유한다.
- 로드맵 그룹은 `create-roadmap``update-roadmap`의 문서 작성, 의미 판단, 배치 제안, file-based fallback 갱신 흐름을 소유한다.
- Phase/Milestone 상태 전환, 구현 잠금 동기화, archive 이동, 완료 이벤트 반영처럼 결정적으로 판별 가능한 action은 Core/MCP 또는 런타임이 있으면 그쪽 책임으로 둔다.
- Phase/Milestone 상태 전환, archive 이동, 완료 이벤트 반영처럼 결정적으로 판별 가능한 action은 Core/MCP 또는 런타임이 있으면 그쪽 책임으로 둔다.
- `code-review`가 남긴 PASS 완료 이벤트를 로드맵에 반영할지, 언제 반영할지는 런타임이 판단하고 Core/MCP action이 있으면 그쪽으로, 없으면 `update-roadmap` file-based fallback 흐름으로 넘긴다.
- cross-project 잠금이나 `.agent-roadmap-sync` 같은 workspace-level 상태는 로드맵 그룹, Core, 런타임의 공동 경계다. `plan``code-review`에 의존성 동기화 규칙을 넣지 않는다.
- 새 스킬을 만들기 전에 기존 그룹의 자연스러운 입력, 상태 전환, 후처리 지점에 넣을 수 있는지 먼저 본다. 다만 다른 그룹 경계를 침범해야 하면 런타임 이벤트로 분리한다.

View file

@ -1,220 +1,78 @@
# 로드맵 규칙
`agent-roadmap/` 디렉터리가 있는 프로젝트에서만 적용한다.
`agent-roadmap/`이 있는 프로젝트에서 로드맵 작업에만 적용한다.
## 구조
- 최우선 방향은 **검증 게이트 최소화**다. roadmap은 새 차단 조건을 만드는 곳이 아니며, 기존 문서의 중복 잠금·승인·정합성·evidence 게이트도 제거·병합한다.
- 최상위 로드맵은 `agent-roadmap/ROADMAP.md`다.
- Phase를 가로지르는 전역 Milestone 실행 순서는 `agent-roadmap/priority-queue.md`에 둔다.
- 활성 Phase는 `agent-roadmap/phase/<phase-slug>/PHASE.md`에 둔다.
- 활성 Milestone은 해당 Phase 아래 `agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`에 둔다.
- `<phase-slug>``<milestone-slug>`는 소문자 영문, 숫자, 하이픈만 사용한다.
- 완료된 Phase는 scaffold 그대로 `agent-roadmap/archive/phase/<phase-slug>/PHASE.md`로 이동하고, 하위 Milestone도 `archive/phase/<phase-slug>/milestones/` 아래에 둔다.
- 진행중 Phase 안에서 완료된 Milestone은 활성 `PHASE.md`에 짧은 archive 링크를 남기고, 상세 문서는 `agent-roadmap/archive/phase/<phase-slug>/milestones/`로 이동한다.
- archive `PHASE.md`는 Phase 자체가 완료/폐기될 때만 만들며, 진행중 Phase의 완료 Milestone만 archive된 경우 archive Phase 디렉터리에 `milestones/`만 있을 수 있다.
- 큰 Milestone의 설계 게이트는 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`에 둔다.
- SDD 사용자 리뷰가 필요하면 같은 디렉터리에 `USER_REVIEW.md`를 둔다. 해결된 리뷰는 `user_review_N.log`로 남긴다.
- 완료 또는 폐기된 Milestone의 SDD는 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 이동한다.
## 목적과 구조
## 링크 표기
- 사용자에게 보여주는 답변과 활성 로드맵 문서의 문서 포인터는 raw path만 쓰지 말고 `[표시 제목](상대경로)` Markdown 링크로 쓴다.
- 로드맵 문서 안의 링크 target은 링크를 작성하는 Markdown 파일 위치 기준 상대경로로 쓴다. 예: `ROADMAP.md`에서는 `[PHASE.md](phase/example-phase/PHASE.md)`, Phase 문서에서는 `[Milestone](milestones/example-milestone.md)`, Milestone 문서에서는 `[ROADMAP.md](../../../ROADMAP.md)``[PHASE.md](../PHASE.md)`를 쓴다.
- 채팅 결과 보고처럼 저장 위치가 없는 출력은 repo root 기준 상대경로를 쓸 수 있다. 예: `[PHASE.md](agent-roadmap/phase/example-phase/PHASE.md)`.
- 채팅 결과에 로드맵 문서에서 읽은 링크를 재사용할 때는 원본 Markdown 파일 위치 기준으로 target을 해석한 뒤 repo root 기준 상대경로로 다시 쓴다. 예: `agent-roadmap/current.md`에서 읽은 `(phase/foo/PHASE.md)`는 채팅 출력에서 `(agent-roadmap/phase/foo/PHASE.md)`로, `agent-roadmap/phase/foo/PHASE.md`에서 읽은 `(milestones/bar.md)``(agent-roadmap/phase/foo/milestones/bar.md)`로 쓴다.
- 실제 활성 로드맵 문서에는 `<phase-slug>`, `<milestone-slug>`, `<relative-...>` 같은 placeholder가 들어간 링크 target을 남기지 않는다. 템플릿 placeholder는 문서 생성/갱신 시 실제 파일 위치 기준 상대경로 또는 `없음`으로 치환한다.
- 기존 raw path 또는 backtick path는 읽기 입력으로 허용한다. 갱신 범위에 포함된 활성 문서 포인터만 Markdown 링크로 보정하고, archive 스냅샷은 링크 표기만을 이유로 재포맷하지 않는다.
- `.agent-roadmap-sync/locks.yaml``locked`, `rely-on.target`, Milestone identity(`<project>:agent-roadmap/...`)처럼 machine-readable 계약 값은 raw 값을 유지할 수 있다. 사용자-facing 설명에는 가능하면 별도 Markdown 문서 링크를 함께 붙인다.
## Runtime Action Boundary
- 로드맵 스킬은 기본적으로 로드맵 문서 작성, 의미 판단, 배치 제안, file-based fallback 갱신을 담당한다.
- Core/MCP가 있는 프로젝트에서는 Phase/Milestone 상태 전환, archive 이동, 외부 의존 lock 동기화, 완료 이벤트 반영 같은 action을 Core/MCP 또는 런타임이 처리한다.
- Core/MCP가 없거나 아직 해당 action을 제공하지 않는 프로젝트에서만 `update-roadmap` 스킬이 file-based fallback으로 직접 문서를 갱신한다.
- `update-roadmap`은 fallback 갱신을 수행하더라도 런타임 action 경계를 문서화하고, Core/MCP로 넘길 수 있는 입력과 결과를 함께 남긴다.
- roadmap은 장기 목표와 기능 범위를 기록한다. 구현 절차와 검증 로그는 roadmap에 복제하지 않는다.
- 최상위는 `agent-roadmap/ROADMAP.md`, 전역 실행 순서는 `agent-roadmap/priority-queue.md`다.
- 활성 Phase는 `agent-roadmap/phase/<phase-slug>/PHASE.md`, 활성 Milestone은 그 아래 `milestones/<milestone-slug>.md`에 둔다.
- `agent-roadmap/current.md`는 브랜치별 활성 후보 창이며 현재 작업 하나나 완료 상태의 원본이 아니다.
- SDD는 필요한 설계 참고 문서로 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`에 둘 수 있다. SDD 자체가 구현 승인 게이트는 아니다.
- 완료·폐기 문서는 기존 archive scaffold로 이동한다.
## 로딩
- 세션 최초 1회 `agent-roadmap/current.md`가 있으면 읽고 활성 Phase, 활성 Milestone의 이름, 경로, 선택 규칙만 짧게 기억한다.
- `agent-roadmap/priority-queue.md`가 있으면 Phase를 가로지르는 다음 작업 후보 선택, 사용자가 요청한 순서 조정, archive/폐기/경로 변경/split/merge 후 큐 정리, 깨진 링크 복구가 필요할 때만 읽는다.
- `agent-roadmap/current.md`는 브랜치별 로컬 포인터이며 git 추적 대상이 아니다.
- `current.md`가 없고 로드맵 기반 계획 또는 갱신이 필요하면 `agent-ops/skills/common/_templates/roadmap-current-template.md` 형식으로 로컬 파일을 만들거나 `ROADMAP.md`와 활성 `PHASE.md`에서 후보를 고른다.
- 읽기 전용 로드맵 현지점 확인에서는 `current.md`가 없어도 만들지 않고, 로컬 current 없음으로 보고한 뒤 `priority-queue.md`가 있으면 전역 실행 순서와 `ROADMAP.md`의 Phase 흐름을 보여준다.
- 일반 작업에서는 `ROADMAP.md`를 읽지 않는다.
- 일반 작업에서는 `priority-queue.md`를 읽지 않는다. 단, 구현 계획이나 다음 작업 선택처럼 Phase를 가로지르는 후보 선택이 필요하면 읽는다.
- 일반 작업에서는 `agent-roadmap/archive/**`를 읽지 않는다.
- 기능 추가, 구조 변경, 구현 계획 전에는 요청과 변경 파일에 맞는 활성 Phase와 활성 Milestone 문서를 읽는다.
- 선택한 Milestone의 `구현 잠금``SDD: 필요`가 있으면 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`와 같은 디렉터리의 `USER_REVIEW.md` 존재 여부를 확인한다.
- 로드맵 현지점 확인은 로컬 `current.md`, `priority-queue.md`의 실행 순서, `ROADMAP.md`의 Phase 흐름, 활성 `PHASE.md`의 Milestone 흐름, 활성 Milestone의 제목/목표/상태를 기본으로 읽는다. `SDD: 필요`이면 SDD 본문을 읽지 말고 SDD 문서 링크와 `USER_REVIEW.md` 존재 여부만 확인한다.
- `ROADMAP.md`는 로드맵 생성/갱신, Phase 추가/삭제/전환, 전체 구조 변경, 활성 범위 밖 작업 확인 때만 읽는다.
- 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`에 있는 archive 링크를 따라가서 필요한 archive 문서만 읽는다.
- 일반 구현 작업에서는 roadmap을 읽지 않는다.
- 로드맵 작업에서는 `current.md`와 관련 Phase/Milestone만 먼저 읽는다.
- `ROADMAP.md`는 전체 Phase 구조를 바꿀 때, `priority-queue.md`는 실행 순서나 명시적 차단 관계를 바꿀 때만 읽는다.
- archive는 사용자가 과거 내용 확인·복원·비교를 요청했거나 활성 문서가 정확한 archive evidence를 가리킬 때만 필요한 파일 하나를 읽는다.
## Phase와 Milestone 선택
## 상태
- `current.md`는 현재 작업 위치가 아니라 활성 Phase와 활성 Milestone 후보 목록이다.
- `priority-queue.md`는 현재 작업 위치가 아니라 Phase를 가로지르는 실행 lane과 차단 예외를 한눈에 보는 문서다.
- 각 실행 후보는 `[[<prefix>-<NN>] <Milestone 제목>](<active-milestone-path>)` 형식의 제목 링크와 1~2문장 설명을 가진다. 실행 태그는 소문자 영문으로 시작하는 ASCII prefix, 하이픈, 두 자리 숫자로 작성한다. 예: `[route-01]`.
- 같은 prefix 항목은 하나의 `### <prefix>` 그룹에 모으고 `NN` 오름차순으로 둔다. 같은 prefix에서는 더 작은 활성 `NN`이 정상 선행 순서이며, 별도 차단 줄로 반복하지 않는다.
- 서로 다른 prefix는 기본적으로 병렬 실행할 수 있다. 예외만 설명 바로 아래의 exact label `선행 차단:` 또는 `동시 차단:`과 backtick 실행 태그 목록으로 기록한다.
- `선행 차단`은 다른 prefix의 특정 Milestone 완료 전 시작할 수 없을 때만 쓴다. `동시 차단`은 두 작업을 동시에 실행할 수 없을 때 낮은 우선순위 쪽 한 곳에만 쓴다. 일반적인 관련성이나 권장 순서는 차단으로 만들지 않는다.
- 실행 태그와 차단 줄은 `priority-queue.md`가 유일한 실행 순서 원본이다. Milestone 파일 경로/slug는 안정적인 identity이며, 실행 태그를 바꿔도 파일명을 바꾸지 않는다.
- 실행 태그를 재배치하면 같은 변경에서 queue 제목, Milestone H1, 활성 `PHASE.md`와 로컬 `current.md`의 표시 제목, queue 안의 차단 참조를 함께 갱신한다. archive 문서는 재표기하지 않는다.
- runtime은 `## 실행 순서` 아래의 `### <prefix>` 그룹, numbered item의 첫 실행 태그와 링크 target, exact blocker label만 파싱한다. 설명 본문은 표시용이며 scheduling 판단에 사용하지 않는다. 중복 태그, prefix heading 불일치, malformed blocker, 존재하지 않는 active tag 참조는 fail-closed 검증 오류다.
- 실행 가능한 후보는 각 prefix에서 가장 작은 활성 `NN` 항목 중 `선행 차단`이 없는 항목이다. `동시 차단`은 참조 대상이 실제 진행 중일 때만 막는다. 여러 prefix 후보가 동시에 열리면 그룹의 문서상 위아래 순서는 기본 선택용 tie-breaker일 뿐 선행 의존성이 아니다.
- `priority-queue.md`의 실행 태그, 그룹 순서, 차단 예외는 사용자가 순서 조정을 요청한 경우에만 바꾼다. 단, archive/폐기 제거, 경로 변경, split/merge, 실행 의미 변경, 깨진 링크·태그·차단 참조 복구는 예외다.
- `priority-queue.md` 링크가 깨졌으면 추측하지 말고 활성 Milestone 문서를 기준으로 큐를 재정렬하거나 재생성한다.
- `current.md`는 공유 진행 상태가 아니며, 공유해야 할 상태는 `ROADMAP.md`, `PHASE.md`, Milestone 문서, `.agent-roadmap-sync/locks.yaml`에 남긴다.
- 활성 Phase는 `agent-roadmap/phase/**/PHASE.md`만 대상으로 한다.
- 활성 Milestone은 `agent-roadmap/phase/**/milestones/*.md`만 대상으로 한다.
- `current.md`에는 `[완료]` 또는 `[폐기]` Phase/Milestone을 남기지 않는다. 완료 후보는 완료 근거와 archive 전환이 정리될 때까지 `[검토중]`으로 둔다.
- "로드맵에 추가", "마일스톤에 추가"처럼 target 없는 신규 작업 추가 요청은 `update-roadmap` 스킬로 배치 제안 또는 file-based fallback 갱신을 처리하고, Phase/Milestone/Epic/Task 배치를 자동 판단한다.
- target 없는 신규 추가 요청은 먼저 요청 규모를 `phase`, `milestone`, `epic`, `task`, `subtask`, `context` 중 가장 작은 충분한 단위로 판정한다.
- target 없는 신규 추가 요청은 활성 창만으로 결정하지 말고 필요한 경우 `ROADMAP.md`의 Phase 흐름과 관련 Phase/Milestone 문서를 비교한다.
- 배치는 Phase -> Milestone -> Epic -> Task 순서로 내려가며 같은 레벨의 동일/유사 후보를 먼저 찾는다.
- 동일/유사 항목이 이미 있으면 새로 만들지 말고 기존 항목을 업데이트한다.
- 적절한 기존 후보가 없을 때만 판정한 규모에 맞는 새 항목을 만든다.
- 부모 후보는 있고 판정 규모의 항목만 없으면 부모 아래에 새 항목을 만들고, 부모도 없을 때만 필요한 부모 항목을 함께 만든다.
- 자동 배치할 때는 선택한 Phase/Milestone/Epic/Task와 밀린 후보의 이유를 결과에 남긴다.
- `current.md`가 아카이브 경로를 가리키면 해당 항목은 활성 후보로 읽지 말고 로드맵 갱신이 필요하다고 보고한다.
- 선택한 Phase/Milestone의 목표 또는 범위 제외와 요청이 충돌하면 구현을 진행하지 않고 충돌을 보고한다. 에이전트가 확정할 수 없는 제품/범위 결정은 Milestone `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- 상태는 `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]`를 사용한다.
- `[스케치]`는 아직 구현 단위가 정리되지 않은 후보이고 `[계획]`은 구현 가능한 범위가 정리된 상태다.
- `[검토중]`은 필요할 때만 사용하는 선택적 상태다. 기능과 필요한 검증이 충족되면 `[완료]`로 바로 전환할 수 있다.
- 상태만으로 코드 작업을 자동 차단하지 않는다. 다만 `[스케치]`에서 구현에 필요한 제품 결정이 실제로 빠져 있다면 해당 결정이 필요한 부분만 보류한다.
- 기존 `구현 잠금`, SDD 승인, Evidence Map, complete.log 형식은 호환 정보로 읽을 수 있지만 새 작업의 선행 게이트로 사용하지 않는다.
## 상태 표기
## 결정 사항
- Phase와 Milestone 상태 표기는 `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
- `[스케치]`는 방향성, 문제의식, 후보 범위, 미정 질문을 기록하는 컨셉 상태다. 구현 가능한 계획이 아니므로 `agent-task` 구현 계획 생성과 코드 구현을 시작하지 않는다.
- `[스케치]` 항목은 `[계획]`으로 승격하기 위한 `승격 조건`, 에이전트가 확정할 수 없는 결정, 범위 경계, 후속 Milestone 후보를 정리하는 것이 목적이다.
- `[계획]` 이상 상태의 Milestone에서 `승격 조건` 섹션은 선택 사항이다. 섹션이 없거나 `- 없음`이면 템플릿 오류로 보지 않는다.
- `[스케치]``[계획]`으로 전환하려면 `승격 조건`의 미정 항목이 해소되고, 목표, 범위, 기능 Task, 직접 필요한 결정 항목, 후속 구현 단위가 구현 계획을 만들 수 있을 만큼 정리되어야 한다.
- `[계획]`은 목표, 범위, 기능 Task, 구현 잠금, 결정 필요 항목이 문서화되어 잠금 해제 후 구현 계획을 만들 수 있는 상태다.
- 갱신 범위에 포함된 기존 진행 상태 표기는 `[진행중]`으로 정리한다.
- `[검토중]`은 모든 기능 Task와 Task 안에 명시된 검증이 충족되고 `구현 잠금`이 해제되었으나, 완료 근거 정리와 archive 전환이 아직 남은 완료 후보 상태다.
- `[검토중]` 항목은 활성 경로에 남기고 `current.md`의 활성 후보로 유지할 수 있다.
- 검토 결과 보완이 필요하면 별도 reopen 상태를 만들지 않고 `[진행중]`으로 되돌린 뒤 `완료 리뷰` 또는 `작업 컨텍스트`에 보완 방향을 남긴다.
- 검토 결과 보류 또는 폐기 결정이 나면 `[보류]` 또는 `[폐기]`로 전환한다.
- `ROADMAP.md`의 Phase 흐름은 실행 순서가 아니라 도메인/책임 영역의 구조적 지도다. 상태 그룹은 완료, 검토중, 진행중, 계획, 스케치 순서를 기본으로 하되 실제 다음 작업 선택은 `priority-queue.md`를 우선한다.
- `PHASE.md`의 Milestone 흐름은 해당 Phase 안의 상태 정리 흐름이다. Phase를 가로지르는 실행 순서로 해석하지 않는다.
- 에이전트가 기존 구조와 요청 범위로 합리적으로 정할 수 있는 세부는 구현 가정으로 처리한다.
- 제품 방향·권한·비용·데이터 보존처럼 사용자가 결정해야 하고 현재 구현에 직접 필요한 항목만 Milestone의 `결정 사항`에 남긴다.
- 미정 결정은 그 결정에 의존하는 작업만 보류한다. 다른 Epic, Task, Milestone까지 연쇄 잠금하지 않는다.
## 구현 잠금
## 실행 순서와 프로젝트 간 의존성
- `구현 잠금`은 승인 의식이 아니라 에이전트가 확정할 수 없는 결정이 필요한지 표시하는 얇은 상태다.
- 제품 방향, 범위, 우선순위, 책임 경계처럼 에이전트가 확정할 수 없는 항목이 남아 있으면 상태를 `잠금`으로 두고 `결정 필요` 목록에 남긴다.
- 기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 합리적으로 정할 수 있는 항목은 `결정 필요`가 아니라 `작업 컨텍스트`의 표준선이나 구현 가정으로 기록한다.
- Milestone 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `해제`로 둔다.
- 선택한 Milestone에 `구현 잠금` 섹션이 없거나, 상태가 `잠금`이거나, 미완료 `결정 필요` 항목이 하나라도 있으면 코드 구현, `agent-task` 구현 계획, 세부 API/파일 구조 확정을 시작하지 않는다.
- 잠금 상태에서 허용되는 작업은 로드맵 현지점 확인, 잠금 해소, SDD gate 처리, 범위/후속 Milestone 정리 같은 roadmap-only 갱신뿐이다. 실구현 계획 요청이면 잠금 차단으로 보고하고 `PLAN-*.md`/`CODE_REVIEW-*.md`를 만들지 않는다.
- 남은 `결정 필요` 항목이 현재 Milestone 실구현 범위가 아니라면 먼저 `update-roadmap`으로 `범위 제외`, 후속 Milestone, 또는 `작업 컨텍스트`로 옮기고 `구현 잠금``해제`한 뒤 별도 실구현 계획을 시작한다.
- `구현 잠금`은 SDD gate를 포함할 수 있다. `SDD: 필요`이면 SDD 상태가 `[승인됨]`이고 `SDD 잠금``해제`이며 SDD `USER_REVIEW.md`가 없어야 구현 잠금 해제 후보가 된다.
- SDD 사용자 리뷰는 채팅 질문으로 직접 처리하지 않고 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md`에 남긴다. 사용자의 답변이 반영되면 `user_review_N.log`로 이동한다.
- SDD가 필요한데 문서가 없거나 gate 정보가 부족하면 Milestone 구현 잠금을 해제하지 않는다. 실구현 계획 요청은 잠금 차단으로 보고하고, SDD 작성/확인은 `roadmap-sdd` 또는 `update-roadmap` 흐름에서 처리한다.
- SDD가 불필요한 Milestone은 `SDD: 불필요`과 짧은 사유를 `구현 잠금`에 남긴다.
- 잠금 상태의 Milestone에서는 "현재 요청과 직접 관련 없음"을 이유로 실구현 계획이나 코드 구현을 진행하지 않는다. 관련 없음 판단은 잠금 해소용 roadmap-only 갱신으로 먼저 문서화한다.
- 잠금 상태를 바꾸더라도 `기능` Task를 자동 완료 처리하지 않는다.
- `[스케치]` 상태의 Milestone은 `구현 잠금``해제`로 보이더라도 구현 계획과 코드 구현 대상이 아니다. 먼저 `[계획]`으로 승격해야 한다.
- 같은 prefix의 작은 index는 기본 순서이며 서로 다른 prefix는 기본적으로 병렬이다.
- `선행 차단``.agent-roadmap-sync/locks.yaml`은 사용자가 실제 선행 의존성을 명시한 경우에만 만든다.
- 관련성, 권장 순서, SDD/spec/plan/review 미비, 테스트 미실행은 차단 관계가 아니다.
- 외부 의존 상태는 대상 Milestone 상태로 동기화할 수 있지만, 문서 정합성만을 이유로 새 잠금을 만들지 않는다.
## 프로젝트 간 잠금
## SDD
- 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`은 프로젝트 간 Milestone 잠금 인덱스다. 외부 의존 잠금을 생성하거나 동기화해야 하면 Core/MCP가 있으면 그쪽 action이 만들고, 없으면 `update-roadmap` file-based fallback이 디렉터리와 파일을 만든다.
- entry는 `id`, `locked`, `rely-on[].target`, `rely-on[].status`, `rely-on[].note`만 사용한다.
- `locks.yaml`은 root sequence block style을 기본으로 작성한다. 예: `- id: ...` 아래에 `locked`, `rely-on`을 둔다.
- `id`는 기본적으로 `<잠긴-project>:<잠긴-milestone-slug>`로 만든다.
- `locked``rely-on[].target``<project>:agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md` 형식으로 기록한다.
- Milestone 경로가 `agent-roadmap/...` 상대 경로이면 현재 프로젝트명을 prefix로 붙인다. workspace 하위 절대/상대 경로이면 workspace 바로 아래 디렉터리명을 project로 삼고, 그 뒤 `agent-roadmap/...` 경로를 붙인다.
- `locked`는 잠긴 Milestone, `rely-on.target`은 선행 조건 Milestone이다. 둘 다 같은 workspace의 어느 활성 Phase 하위 Milestone이어도 된다. 의존 대상이 `current.md`에 있어야 한다고 가정하지 않는다.
- "현재 마일스톤은 X 프로젝트 작업 뒤에 진행", "X 프로젝트 때문에 현재 작업 잠금", "의존성 설정해"처럼 잠긴 Milestone을 생략한 외부 의존 잠금 요청은 현재 프로젝트 로컬 `current.md`의 활성 Milestone 단일 후보를 잠긴 대상으로 삼는다.
- 의존 대상은 명시 경로, 명시 slug, 명시 제목, 잠긴 Milestone 문서의 선행 Milestone 힌트, 대상 프로젝트 로컬 `current.md`가 있을 때의 단일 후보 순서로 확정한다.
- 정규화 비교는 소문자 변환, backtick/따옴표 제거, 영문/숫자가 아닌 연속 문자를 `-` 하나로 치환, 앞뒤 `-` 제거 후 Milestone 파일 slug와 정규화한 제목에 대조한다.
- 의존 대상 탐색은 대상 프로젝트의 `agent-roadmap/phase/*/milestones/*.md` 활성 문서만 대상으로 한다. archive 문서는 사용자가 archive 경로를 명시한 경우 외에는 읽거나 후보로 삼지 않는다.
- 후보가 없거나 둘 이상이면 locks.yaml을 만들거나 고치지 말고 모호성을 보고한다. 잠금 대상 확정이 제품/범위 결정이면 대상 Milestone의 `구현 잠금 > 결정 필요`로 분리한다.
- 외부 의존 잠금을 만들 때 대상 Milestone의 `구현 잠금``잠금`으로 둔다.
- 새 `rely-on.status`는 선행 Milestone 상태에서 파생한다. `[검토중]` 또는 `[완료]`이면 `enable`, 그 외 상태거나 상태를 확인할 수 없으면 `disable`이다.
- 같은 `id` entry를 upsert할 때 기존 `rely-on` 항목을 삭제하지 않는다. 같은 `rely-on.target`만 status/note를 갱신하고, 없는 target은 추가하며, `locked` 경로가 바뀐 경우에만 `locked`를 갱신한다.
- `locks.yaml`이 있고 Milestone을 갱신하거나 archive할 때는 대상 Milestone identity로 `agent-ops/bin/roadmap-dependency-checker.sh --find-milestone "<identity>" both "<locks-file>"`를 먼저 실행한다.
- find 결과가 `none`이면 결과 보고의 `Workspace 잠금``관련 lock 없음`을 남긴다. 외부 의존 잠금 생성/동기화 요청이 아니라면 `locks.yaml`을 새로 만들거나 수정하지 않는다.
- Core/MCP action 또는 `update-roadmap` fallback이 갱신한 Milestone identity가 어느 entry의 `rely-on.target`과 일치하면 Milestone 상태 기준으로 `status`를 동기화한다. `[검토중]` 또는 `[완료]`이면 `enable`, 그 외 상태면 `disable`이다.
- Core/MCP action 또는 `update-roadmap` fallback이 갱신하거나 선택한 Milestone identity가 어느 entry의 `locked`와 일치하면 모든 `rely-on.status``enable`인지 결과 보고에 남긴다. 모든 조건이 충족되어도 잠금 해제 실행은 Core/MCP 또는 런타임의 별도 action으로 처리한다.
- archive 모드에서는 파일 이동 전에 대상 Milestone의 활성 경로 identity를 보존하고, 그 identity로 `--find-milestone "<identity>" both "<locks-file>"`를 먼저 실행한다. 보존한 identity가 어느 entry의 `rely-on.target`과 일치하고 Milestone 상태가 `[완료]`이면 archive 이동 전에 해당 `rely-on.status``enable`로 바꾼다.
- archive 모드에서 보존한 identity가 어느 entry의 `locked`와 일치하면 archive 이동 전에 모든 `rely-on.status``enable`인지 결과 보고에 남긴다. 미충족이어도 archive 자체는 막지 않고 `Workspace 잠금: 미충족`으로 보고한다.
- 잠금 해제 조건 충족 여부만 확인할 때는 `agent-ops/skills/common/check-roadmap-dependency/SKILL.md`를 읽는다. lock id가 없으면 해당 스킬은 `agent-ops/bin/roadmap-dependency-checker.sh --find-milestone "<identity>" "<direction>" "<locks-file>"`로 현재 Milestone이 `locked`인지 `rely-on.target`인지 양방향으로 찾은 뒤 `agent-ops/bin/roadmap-dependency-checker.sh "<lock-id>" "<locks-file>"`를 사용한다.
- checker exit code는 `0=true`, `1=false`, `2=설정/입력/파싱 오류`로 해석한다.
- SDD는 API·schema·상태 전이·권한·비가역 외부 쓰기처럼 구현 전에 합의가 유용한 큰 변경에 선택적으로 사용한다.
- 기존 계약과 범위가 명확하면 SDD 없이 구현할 수 있다.
- SDD의 상태, 사용자 리뷰, Acceptance Scenario, Evidence Map은 설계와 검증을 돕는 정보이며 plan·구현·완료의 자동 선행 조건이 아니다.
- 사용자 결정이 필요한 경우 질문과 결정 결과만 남긴다. 별도 승인 체크박스나 SDD 잠금 해제 의식을 만들지 않는다.
## SDD 게이트
## Epic과 Task
- SDD는 큰 Milestone의 설계 계약을 로드맵에 녹이는 하위 문서다. 별도 작업 관리 체계로 쓰지 않는다.
- SDD 작성, 갱신, gate 확인, 사용자 리뷰 대기, 잠금 해제는 `agent-ops/skills/common/roadmap-sdd/SKILL.md`를 따른다.
- SDD는 cross-repo 계약, 외부 provider 쓰기, 상태 머신, idempotency/retry/identity map, API/proto/config/env/schema, field smoke, 사용자 승인 gate에 영향을 주는 Milestone에만 강제한다.
- 작은 리팩터링, 문서 정리, 테스트 보강, 작은 UI 보강, Milestone Task의 `검증:`만으로 닫히는 작업에는 SDD를 강제하지 않는다.
- 로드맵 갱신으로 새 Milestone을 만들거나 `[스케치]` Milestone을 `[계획]`으로 승격하면서 `SDD: 필요`로 판정하면 같은 흐름에서 SDD 파일도 만든다. 사용자가 명시적으로 SDD 생성을 뒤로 미루지 않았는데 `SDD: 필요`와 SDD 문서 링크만 있고 파일이 없는 상태로 종료하지 않는다.
- SDD 문서는 `agent-ops/skills/common/_templates/roadmap-sdd-template.md`의 표준 섹션, 순서, 필수 표 컬럼을 유지해야 한다.
- SDD의 `Acceptance Scenarios`는 Milestone 기능 Task id와 연결되어야 한다.
- SDD의 `Evidence Map`은 code-review/complete.log의 `Roadmap Completion`과 최종 검증 evidence로 검증 가능해야 한다.
- `SDD: 필요` Milestone의 구현 계획은 승인된 SDD를 입력으로 삼아 작성한다. 구현 계획은 Milestone 기능 Task만 보고 실행 항목을 만들지 않고, 연결된 Acceptance Scenario와 Evidence Map에서 구현 범위, 검증, 완료 evidence를 역산해야 한다.
- 외부 API 또는 프로젝트 간 호출 계약 원문은 `agent-contract/`에 두고 SDD에는 링크만 남긴다.
- SDD 전체 검토를 채팅 질문으로 처리하지 않는다. 에이전트가 확정할 수 없는 source of truth, 상태 전이, 책임 경계, 권한, 비용, 데이터 보존, 실패 처리만 `USER_REVIEW.md`로 분리한다.
- Milestone의 실행 체크리스트는 `기능` 섹션에 둔다.
- Epic은 `### Epic: [epic-id] <이름>`, Task는 `- [ ] [item-id] 설명` 형식을 사용한다.
- Task는 기능이나 산출물 단위로 작성한다. 구현 세부나 테스트만을 별도 하위 Task로 만들지 않는다.
- 검증이 실제로 필요한 Task에만 같은 줄의 `검증:`으로 가장 작은 확인 방법을 적는다.
- 기능이 구현됐고 필요한 검증이 확인되면 evidence 형식과 관계없이 `[x]`로 바꿀 수 있다.
## Epic과 Task id
## Plan, review, 완료 반영
- Milestone 문서의 실행 체크리스트는 `기능` 섹션 하나로 작성한다. 새 Milestone이나 갱신 범위에 포함된 Milestone에는 별도 `완료 기준` 섹션을 만들지 않는다.
- 기존 Milestone에 `필수 기능``완료 기준`이 분리되어 있으면, 갱신 시 `완료 기준`을 관련 기능 Task 안의 선택적 `검증:` 문구로 흡수하고 섹션을 제거한다.
- 기능 Task는 기능 또는 산출물 단위다. 검증이 필요한 기능만 같은 Task 안에 `검증: <명령/확인 방법/기대 결과>`를 붙인다.
- 검증이 명시된 Task의 `[x]`는 기능/산출물과 해당 검증이 모두 충족되었다는 뜻이다. 검증이 명시되지 않은 Task의 `[x]`는 기능/산출물 완료 근거가 충분하다는 뜻이다.
- 에이전트가 확정할 수 없는 검토/선택/우선순위 항목은 기능 Task로 쓰지 않는다. 현재 구현에 직접 필요하면 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리하고, 그렇지 않으면 `작업 컨텍스트`에 표준선/가정/후속 후보로 남긴다.
- `기능` 섹션의 Task 체크리스트는 Epic 바로 아래의 flat list를 기본으로 한다. 구현 세부, 테스트만 따로 떼어낸 하위 체크박스는 roadmap에 만들지 말고 plan 내부 체크리스트나 같은 Task의 `검증:`으로 흡수한다.
- Epic heading은 `### Epic: [epic-id] <이름>` 형식을 사용한다.
- Task는 `- [ ] [item-id] 설명` 또는 `- [x] [item-id] 설명` 형식을 사용한다.
- epic-id와 item-id는 공백 없는 짧은 ASCII 토큰이며, 영문/숫자 segment 1~4개로 작성하고 segment 구분자는 `-`, `_`, `+`, `=`만 사용한다. 가능하면 1~3 segment를 우선하며, 전체 길이는 32자 이하를 권장한다.
- epic-id와 item-id는 해당 Milestone 안에서만 유일하면 된다.
- 다른 Milestone에서는 같은 id를 다시 사용할 수 있다. 여러 Milestone 후보에서 같은 id가 발견되면 Milestone 이름이나 문서 경로로 대상을 확정한다.
- 사용자가 epic-id 또는 item-id를 언급하면 해당 Milestone의 Epic/Task 항목을 우선 anchor로 삼고, 기존 id는 명시적 요청 없이 바꾸지 않는다.
- plan과 code review는 사용자가 요청했거나 변경 규모상 유용할 때만 사용한다. 로드맵 상태, SDD, preflight가 자동으로 plan을 요구하지 않는다.
- 시작 전 전체 정합성 preflight는 사용자가 요청한 경우에만 read-only로 수행한다.
- `complete.log``milestone-task``Roadmap Completion`은 자동 반영을 위한 선택적 힌트다. 정확한 Milestone과 Task가 확인되면 코드·테스트·사용자 설명 같은 다른 근거로도 완료를 반영할 수 있다.
- 모든 Task가 완료되면 별도 완료 리뷰 단계를 강제하지 않고 Milestone을 `[완료]`로 전환할 수 있다.
- 미실행 환경 검증은 남은 위험으로 기록하되, 보안·데이터 손상·비가역 외부 변경을 확인하는 필수 검증이 아닌 한 완료를 자동 차단하지 않는다.
## Milestone 시작 전 정합성
## 링크와 갱신
- 사용자가 현재 또는 지정 Milestone의 시작, 정합성 체크, Plan 전 리프레시를 요청하면 `sync-milestone-workstate mode=consistency-check`로 Plan 전에 read-only preflight를 수행한다.
- preflight는 전체 활성 Phase/Milestone, `current.md`, `priority-queue.md`, workspace lock과 active agent-task를 얕게 확인하고 대상 Milestone의 목표·범위·기능·SDD·spec·contract를 현재 코드·config·proto·테스트와 깊게 대조한다. unrelated archive와 전체 코드를 무차별 탐색하지 않는다.
- 아직 구현되지 않은 미래 capability는 정상 planned delta다. 현재 owner/API/wire/config/공통 기반과 충돌하거나 이미 대체·구현된 경우만 drift로 판정한다.
- 결과는 `ready`, `refresh-required`, `blocked` 중 하나다. `refresh-required`이면 미반영 완료 Task에 대한 `sync-milestone-workstate mode=sync`와 필요한 `update-roadmap`/`roadmap-sdd`/`update-spec`/`update-contract` 갱신 후 `consistency-check`를 다시 실행하고, `blocked`이면 차단을 해소하기 전 Plan을 만들지 않는다.
- `consistency-check`는 어떤 파일도 수정하지 않는다. 완료 evidence 반영 후보만 보는 `check-only`와 의미를 합치지 않는다.
## Milestone 기반 agent-task
- `plan` 스킬이 활성 Milestone 범위의 구현 계획을 만들면 task group은 `agent-task/m-<milestone-slug>/` 형식을 사용한다.
- `<milestone-slug>`는 활성 Milestone 파일명에서 `.md`를 제거한 값이며, Phase slug, Epic id, Task id, 별도 task slug를 task group에 넣지 않는다.
- split 작업은 기존 규칙 그대로 `agent-task/m-<milestone-slug>/<subtask_dir>/` 아래에 둔다.
- `m-<milestone-slug>`는 Milestone 기반 작업 전용 예약 prefix이며, 일반 작업 task group은 `m-`으로 시작하지 않는다.
- 런타임은 파일 내부가 아니라 task group 이름만으로 Milestone 기반 작업 여부를 판별한다.
- `code-review`에서 `m-<milestone-slug>` 작업이 PASS되면 roadmap을 직접 수정하거나 `update-roadmap`을 직접 호출하지 않는다.
- 런타임은 PASS 완료 이벤트의 task group에서 `m-<milestone-slug>`를 판별하고, 상태 체크 후 Core/MCP action으로 Milestone 업데이트를 호출한다. Core/MCP action이 없으면 `update-roadmap` file-based fallback 흐름을 호출한다. 단, Milestone 기능 Task 체크는 `complete.log``Roadmap Completion` 섹션과 명시 Task id가 있을 때만 수행하고, 섹션이 없으면 no-op으로 둔다.
- SDD 대상 Milestone은 런타임 완료 이벤트의 `complete.log`에 있는 `Roadmap Completion`과 최종 검증 evidence가 SDD `Evidence Map`을 충족해야 roadmap Task 체크 후보가 된다. 단, 사용자가 명시적으로 evidence를 전달한 수동 `update-roadmap` 갱신에서는 Evidence Map 충족 근거를 보조 근거로 사용할 수 있다.
- 런타임 완료 이벤트가 최종 archive 경로만 갖고 있으면 `agent-task/archive/YYYY/MM/m-<milestone-slug>/...``agent-task/m-<milestone-slug>/...` 형태의 `origin-task`로 정규화해 전달한다.
- 런타임 호출에서 매칭되는 활성 Milestone이 없거나 둘 이상이면 추정하지 말고 수동 target 선택이 필요하다고 보고한다.
- `WARN` 또는 `FAIL`은 Milestone 완료 업데이트를 하지 않는다. 일반적으로 같은 `m-<milestone-slug>` task group에서 후속 계획/리뷰를 이어간다. code-review의 `milestone-lock` user-review gate가 트리거되면 연결된 Milestone 잠금 결정을 `USER_REVIEW.md`에 남기고, `external-execution` gate가 트리거되면 Milestone 문서를 바꾸지 않은 채 task-local `USER_REVIEW.md`에 필요한 외부 실행 조치와 재개 조건을 남긴다.
- `[스케치]` Milestone은 Milestone 기반 `agent-task` 생성 대상이 아니다. 런타임이나 plan 스킬은 이를 구현 작업으로 라우팅하지 않고 `[계획]` 승격 필요를 보고한다.
## 완료 리뷰
- Task 완료나 Milestone 갱신 시 모든 기능 Task와 Task 안에 명시된 검증이 evidence와 함께 `[x]`가 되었는지 확인하고, `구현 잠금``해제`이며 미완료 `결정 필요` 항목이 없는지 함께 확인한다.
- 기능 Task가 모두 충족되어도 `구현 잠금`이 남아 있으면 Milestone을 `[검토중]`으로 바꾸지 않는다. 완료 리뷰 또는 작업 컨텍스트에 잠금 차단 항목을 남기고, 잠금 해소 roadmap 갱신을 먼저 요구한다.
- 기능 Task와 구현 잠금이 모두 충족된 것으로 보이면 Milestone을 `[완료]`로 바로 바꾸거나 archive로 이동하지 말고 `[검토중]`으로 바꾼다.
- `[검토중]`으로 바꿀 때는 Milestone 문서에 `완료 리뷰` 섹션을 만들거나 갱신하고, 완료 근거 1~3줄과 남은 차단 항목을 남긴다. 에이전트가 확정할 수 없는 결정 항목은 완료 리뷰가 아니라 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- 기능 Task, 검증, 구현 잠금이 모두 충족되면 `[완료]` 전환과 archive 이동을 수행할 수 있다.
- Phase도 모든 하위 Milestone이 `[완료]` 또는 `[폐기]`로 정리되고 Phase 목표가 충족되면 `[완료]` 또는 `[폐기]`로 전환한다.
## 로드맵 현지점
- 현재 작업 지점이나 로드맵상 현 위치 확인 요청은 `analyze-roadmap-position` 스킬로 처리한다.
- 답변은 `agent-ops/skills/common/_templates/roadmap-position-report-template.md` 섹션과 필드 순서를 따른다.
- 기본 동작에서는 코드, git 상태, diff를 읽지 않고 `로드맵 > Phase > Milestone` breadcrumb와 흐름 목록으로 현재 좌표를 보여준다.
- current가 Phase 또는 Milestone 후보를 여럿 가리키면 모두 `현재 후보`로 표시하고 짧은 역할 태그만 붙인다.
- 사용자-facing 문서 포인터는 Markdown 링크를 사용한다. machine-readable identity는 raw path를 유지할 수 있다.
- target 없는 추가 요청은 같은 목표의 기존 Phase → Milestone → Epic → Task를 찾아 가장 작은 충분한 단위로 갱신한다.
- 중복 항목을 만들지 않고, 요청 범위를 넘어 기존 id나 실행 순서를 바꾸지 않는다.
- 갱신 후에는 수정한 링크가 존재하는지와 `git diff --check`만 확인한다. 전체 roadmap 정합성 검사를 자동 실행하지 않는다.
## 아카이브
- 완료 또는 폐기되어 현재 작업 후보에서 제외할 Phase/Milestone은 Core/MCP action으로 아카이빙한다. Core/MCP action이 없으면 `update-roadmap` file-based fallback으로 아카이빙한다.
- `[검토중]` Phase/Milestone은 archive 대상이 아니며, 완료 근거와 남은 차단 항목이 정리될 때까지 활성 경로에 남긴다.
- Phase 아카이브 대상은 `agent-roadmap/archive/phase/<phase-slug>/PHASE.md`와 같은 scaffold로 이동한다.
- Milestone 아카이브 대상은 `agent-roadmap/archive/phase/<phase-slug>/milestones/<milestone-slug>.md`로 이동한다.
- 활성 SDD가 있으면 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 함께 이동한다. SDD `USER_REVIEW.md`가 남아 있으면 먼저 해결한다.
- Milestone 아카이브 전에는 이동 전 활성 경로 identity로 `.agent-roadmap-sync/locks.yaml`을 확인한다. 해당 identity가 `rely-on.target`이면 `[완료]` 상태에서 `enable`로 동기화하고, 해당 identity가 `locked`이면 의존 조건 충족 여부를 보고하며, 어느 쪽에도 없으면 `관련 lock 없음`으로 보고한다.
- `구현 잠금`이 남아 있는 Milestone은 `[완료]` 전환이나 완료 archive 대상으로 삼지 않는다. 명시적인 폐기 근거가 있는 `[폐기]` archive는 허용한다.
- 아카이빙할 때는 활성 `ROADMAP.md` 또는 활성 `PHASE.md`에 archive 문서 링크와 짧은 요약만 남긴다.
- 아카이빙할 때 `priority-queue.md`가 있으면 이동 전 활성 Milestone 경로 항목을 제거하고, 해당 실행 태그를 가리키는 충족된 `선행 차단` 참조도 제거한다. archive 경로로 바꿔 남기지 않는다.
- 아카이브된 Phase/Milestone은 로컬 `current.md`에 남기지 않고, 일반 Phase/Milestone 선택이나 위치 분석의 후보로 삼지 않는다.
- 아카이브 문서는 과거 기록 스냅샷으로 보고, 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.
- `[완료]` 또는 `[폐기]` Milestone만 archive한다.
- 활성 Phase 문서에는 archive 링크와 짧은 요약만 남기고, `priority-queue.md``current.md`에서는 제거한다.
- archive 문서는 과거 스냅샷으로 보존하고 최신 형식으로 재작성하지 않는다.

View file

@ -1,59 +1,38 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- **과설계를 금지한다.** 기능을 먼저 최소 구현하며, 구현 단계의 검증은 보안·데이터 손상 방지처럼 반드시 필요한 경우 외에는 두지 않는다. 추가 검증은 실제 문제가 확인된 뒤에만 보강한다.
- `agent-ops/rules/common/**``agent-ops/skills/common/**`은 중앙 관리되는 공통 영역이므로 어떤 프로젝트 작업에서도 사용자가 직접 지시하지 않는 이상 절대 직접 수정하지 않는다. 프로젝트별 규칙과 스킬은 반드시 대응하는 `project/**` 영역에만 반영한다.
- **최우선 방향은 검증 게이트 최소화다.** 새 게이트를 만들지 않는 것에 그치지 않고, 기존 게이트도 계속 제거·병합해 최소 개수로 유지한다.
- 차단형 검증 게이트는 보안·자격증명, 데이터 손상·비가역 외부 변경, 사용자가 명시한 실제 프로젝트 간 선행 의존성에만 허용한다. 그 밖의 테스트·문서·승인·정합성·evidence는 차단형 게이트로 만들지 않는다.
- 기존 구조를 우선하고 요청 범위 안에서 가장 작은 변경으로 구현한다.
- 과설계를 금지한다. 새 추상화·문서·상태·검증은 현재 요청에 반드시 필요할 때만 추가한다.
- 테스트·SDD·spec·plan·review·evidence는 필요에 따라 사용하는 산출물이며 서로의 선행 허가 조건으로 자동 연결하지 않는다.
- 코드 변경 전 변경 경로에 대응하는 `agent-ops/rules/project/domain/**/rules.md`만 읽는다.
- `agent-ops/rules/project/rules.md`는 프로젝트 구조나 도메인 매핑 확인이 필요할 때만 읽는다.
- `agent-ops/skills/common/router.md`는 사용자가 Agent-Ops 산출물이나 명시적인 skill workflow를 요청했을 때만 읽는다.
- `agent-ops/rules/common/**``agent-ops/skills/common/**`은 사용자가 직접 지시한 경우에만 수정한다. 프로젝트별 변경은 대응하는 `project/**` 영역을 우선한다.
- 불확실한 제품 결정이 구현에 직접 필요하면 후보와 영향을 제시하고 사용자 결정을 기다린다. 관련 없는 작업까지 잠그지 않는다.
- 최종 답변은 한국어로 한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우, plan 스킬이 같은 task group의 새 index를 충돌 없이 할당하는 경우, `sync-milestone-workstate`가 활성 대상 Milestone의 동일 `m-<milestone-slug>` task group evidence를 집계하는 경우, 또는 `sync-agent-ui mode=reconcile-completion`에 exact `completion-log` 경로가 전달된 경우에만 필요한 범위를 좁게 읽는다. split 의존성 확인과 Milestone workstate 동기화는 같은 task group의 후보 `complete.log`와 직접 연결된 plan/review log만 읽을 수 있다. index 할당은 같은 task group의 archived sibling directory basename만 열람하고 내부 파일은 읽지 않는다. UI 완료 정합화는 전달된 exact `complete.log` 한 건만 읽고 sibling archive log를 탐색하지 않는다.
- `agent-roadmap/` 디렉터리가 있는 프로젝트에서도 `agent-roadmap/archive/**`는 일반 작업에서 읽지 않는다. 로드맵 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `agent-ops/rules/common/rules-roadmap.md`의 archive 접근 규칙을 따른다.
- `agent-ui/` 디렉터리가 있는 프로젝트에서도 `agent-ui/definition/archive/**``agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다. UI 과거 결정, 복원, 비교, 해결된 user review 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-ui.md`의 archive 접근 규칙을 따른다.
- `agent-spec/` 디렉터리가 있는 프로젝트에서 현재 구현 스펙 확인, 기존 기능 변경, 완료 검토, 구현 스펙 생성/갱신 요청은 세션 1회 `agent-ops/rules/common/rules-agent-spec.md`를 읽고, `agent-spec/index.md`와 매칭되는 spec 문서만 읽는다.
- `agent-spec/archive/**`는 일반 작업에서 읽지 않는다. 과거 스펙 확인, 복원, 비교, 특정 archive 경로 확인이 필요한 경우에만 `agent-ops/rules/common/rules-agent-spec.md`의 archive 접근 규칙을 따른다.
- agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 `agent-ops/rules/common/philosophy.md`를 읽는다.
- tracked `docs/`는 사람용 최신 가이드와 공개 설명만 둔다.
- project skill 경로 `agent-ops/skills/project/<skill-name>/SKILL.md`를 선택했을 때 같은 이름의 `agent-ops/skills/private/<skill-name>/SKILL.md`가 있으면 private skill을 우선한다. 없으면 project skill을 사용한다.
- project skill과 짝이 없는 private skill은 `agent-ops/rules/private/rules.md`에 명시적으로 라우팅한다. private skill 디렉터리 전체를 탐색하지 않는다.
- API, wire protocol, 런타임 호출, event/config schema, 프로젝트 간 또는 내부 프로세스/컴포넌트 간 요청/응답 계약을 확인해야 하는 작업은 `agent-contract/index.md` 파일이 있을 때만 세션 1회 읽고, 매칭되는 계약 문서만 읽는다.
**세션 최초 1회 아래 파일을 순서대로 반드시 읽는다.** 파일이나 디렉터리가 없는 항목은 건너뛴다. 그외에 스킵은 금지한다.
## 필요한 경우에만 읽는 문서
1. `agent-ops/rules/project/rules.md`
2. `agent-ops/rules/private/rules.md`
3. `agent-roadmap/` 디렉터리가 있으면 `agent-ops/rules/common/rules-roadmap.md`
- 로드맵 생성·갱신·상태 확인: `agent-ops/rules/common/rules-roadmap.md`
- agent-spec 생성·갱신 또는 현재 구현 스펙 확인: `agent-ops/rules/common/rules-agent-spec.md`와 매칭되는 spec
- agent-ui 작업: `agent-ops/rules/common/rules-agent-ui.md`
- Agent-Ops 구조·책임 경계 변경: `agent-ops/rules/common/philosophy.md`
- API, wire, runtime call, event/config schema 계약 확인: `agent-contract/index.md`와 매칭되는 계약
- 환경 의존 live/full-cycle 검증을 사용자가 요청했거나 변경 위험상 필요한 경우: 해당 `agent-test/<env>/rules.md`
# 프로젝트 간 잠금
## 아카이브
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
- `agent-task/archive/**`, `agent-roadmap/archive/**`, `agent-spec/archive/**`, `agent-ui/**/archive/**`는 일반 작업에서 읽지 않는다.
- 사용자가 과거 작업 확인·복원·비교를 요청했거나 활성 문서가 정확한 evidence 경로를 가리킬 때만 필요한 파일 하나로 범위를 좁혀 읽는다.
# 스킬 규칙
## 프로젝트 간 의존성
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `agent-ops/skills/common/router.md`를 작업 최초 1회 읽고 수행한다.** 자동으로 수행하지 않는다. **절대 스킵하지 말고 정독해야한다**
- agent-ops 초기화
- domain rule 생성
- skill 생성/갱신
- agent-ui 생성/갱신/검증/코드 동기화, UI 스캐폴드, 화면 정의서, view/component/frame/wireframe 정의, agent-ui USER_REVIEW
- 테스트 룰 작성/생성/수정, 도메인별/검증 시나리오별 테스트 문서, create-test/update-test
- 계약 생성/업데이트, agent-contract 생성/갱신, inner/outer 계약 문서 작성/정리, 계약 포인터 관리
- agent-spec 생성/갱신, 현재 구현 스펙 문서화, 구현 스펙 업데이트, 스펙 동기화
- README 생성
- 핸즈오프 작성 / handoff / 인수인계 / 다른 세션에서 이어가기
- 로드맵/마일스톤 생성·갱신
- SDD 작성/갱신, SDD 필요 여부, SDD gate 확인, SDD 사용자 리뷰, SDD 잠금 해제
- 로드맵 현지점 / 현재 작업 지점 확인
- 현재 또는 지정 마일스톤 시작 전 정합성 체크 / 전체 프로젝트 작업현황과 마일스톤 정합성 확인 / plan 전 마일스톤 리프레시
- 마일스톤 완료 검토 / 종료 검토 / 현재 마일스톤 닫기 / 다음 마일스톤 지정
- 계획 작성 / plan 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
- 사용자가 Milestone 간 선행 의존성을 명시한 경우에만 `update-roadmap`으로 기록한다.
- 관련성, 권장 순서, 문서 미비, 테스트 미실행은 프로젝트 간 잠금으로 만들지 않는다.
# 테스트 규칙
## 테스트
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- 기본 검증은 변경한 패키지나 컴포넌트의 가장 작은 관련 테스트다.
- 전체 테스트, E2E, live provider, full-cycle, 외부 CLI 검증은 사용자가 요청했거나 변경이 그 경로를 직접 수정해 국소 테스트로 위험을 확인할 수 없을 때만 수행한다.
- 테스트를 실행할 수 없다는 이유만으로 구현이나 다른 독립 작업을 차단하지 않는다. 수행하지 못한 검증과 남은 위험만 보고한다.

View file

@ -1,177 +1,58 @@
---
domain: testing
last_rule_review_commit: 495996fee4b55eabef58505f73ab23848794eeef
last_rule_updated_at: 2026-08-08
last_rule_review_commit: 790dd69ceb4d08ebcbe53008b3e3185d31e52451
last_rule_updated_at: 2026-08-15
---
# testing
## 목적 / 책임
작업 완료 후 어떤 테스트와 full-cycle 실제 구동 검증을 거쳐야 하는지 정리한다. 테스트 파일을 바꿨는지가 아니라, 변경 작업이 어떤 사용자 실행 파이프라인에 닿았는지를 기준으로 검증 범위를 정한다. 대상 host에서 사용자가 복사해 실행하는 bootstrap/install command의 기본 UX 기준도 이 도메인에서 다룬다.
최우선 방향은 **검증 게이트 최소화**다. 변경 범위에 맞는 가장 작은 회귀 검증과 사용자가 요청한 실행 검증만 제공한다. 기존 검증 게이트도 제거·병합하며, 테스트를 일반 작업의 구현·완료 게이트로 사용하지 않는다.
## 포함 경로
- `Makefile` — 공식 test target, proto generation, 보조 smoke target을 선언하는 위치이다.
- `scripts/dev/edge.sh` — repo 내부 edge console/server 개발 진단 helper이다.
- `scripts/dev/node.sh` — repo 내부 node 연결 개발 진단 helper이다. field 사용자 기본 경로로 안내하지 않는다.
- `scripts/dev/edge-node-reconnect-diagnostic.sh` — repo 내부 Edge-Node disconnect/reconnect lifecycle 진단 helper이다.
- `scripts/dev/web.sh` — repo 내부 Flutter Web client 개발 진단 helper이다. field 배포 기본 경로로 안내하지 않는다.
- `scripts/e2e-smoke.sh` — mock/real profile 기반 보조 edge-node smoke 검증이다.
- `scripts/e2e-openai-cli-workspace.sh` — OpenAI-compatible `/v1/responses` CLI workspace isolation 보조 smoke 검증이다.
- `scripts/e2e-openai-ollama.sh` — OpenAI-compatible Ollama 입력 표면 보조 smoke 검증이다.
- `scripts/e2e-openai-vllm.sh` — OpenAI-compatible vLLM/SGLang류 provider 입력 표면 보조 smoke 검증이다.
- `scripts/e2e-openai-lemonade.sh` — OpenAI-compatible Lemonade/provider API 입력 표면 보조 smoke 검증이다.
- `scripts/e2e-long-context-admission-smoke.sh` — live provider pool long-context admission/capacity 보조 smoke 검증이다.
- `scripts/e2e-control-plane-edge-wire.sh` — Control Plane-Edge wire hello/disconnect 보조 smoke 검증이다.
- `scripts/e2e-provider-capacity-smoke.sh` — provider resource capacity와 queue 동작을 확인하는 보조 smoke 검증이다.
- `scripts/fixtures/` — E2E smoke 입력 fixture 위치이다.
- `scripts/inventory-query/``agent-test` 환경 inventory를 bounded projection 또는 exact selector 결과로 조회하는 helper와 테스트이다.
- `scripts/readability_audit.py` — tracked/worktree의 파일·함수·task read-set 가독성 기준을 검사하는 deterministic audit이다.
- `scripts/readability_audit_test.py` — readability audit parser/policy/ratchet 단위 테스트이다.
- `scripts/readability_baseline.json` — readability violation ratchet 기준선이다.
- `scripts/readability_read_sets.json` — task별 ordered read-set budget 정의이다.
- `cmd/iop-provider-smoke/` — redacted provider catalog readiness와 status/run/resume/cancel lifecycle을 실제 CLI로 검증하는 smoke command이다.
- `docker-compose.yml` — local dev용 Control Plane, datastore, Flutter Web client stack 조립 표면이다.
- `Makefile` — 공식 빌드·테스트 진입점이다.
- `scripts/dev/` — repo 내부 개발 진단 helper다.
- `scripts/e2e-*.sh` — 입력 표면과 런타임 경로의 선택적 smoke다.
- `scripts/fixtures/` — E2E fixture다.
- `scripts/inventory-query/` — 제한된 환경 inventory 조회 helper다.
- `scripts/readability_*` — 선택적 가독성 audit와 기준 데이터다.
- `cmd/iop-provider-smoke/` — 외부 provider lifecycle smoke command다.
- `docker-compose.yml` — local dev stack 조립 표면이다.
## 제외 경로
- `apps/node/` — node 실행 구현의 소유자는 node 도메인이다. testing 도메인은 작업 후 검증 기준만 정의한다.
- `apps/edge/` — edge 실행 구현의 소유자는 edge 도메인이다. testing 도메인은 작업 후 검증 기준만 정의한다.
- `apps/control-plane/` — Control Plane 구현의 소유자는 control-plane 도메인이다. testing 도메인은 작업 후 검증 기준만 정의한다.
- `apps/client/` — Flutter client 구현과 client test 파일의 소유자는 client 도메인이다. testing 도메인은 작업 후 검증 기준만 정의한다.
- `packages/go/``proto/` — 공통 계약의 소유자는 platform-common 도메인이다. testing 도메인은 해당 변경 후 필요한 검증 기준만 정의한다.
- `apps/**` — 각 앱 도메인이 구현과 단위 테스트를 소유한다.
- `packages/**`, `proto/**` — platform-common 또는 client 도메인이 구현과 단위 테스트를 소유한다.
## 주요 구성 요소
- 대상 패키지 테스트 — 변경한 패키지와 인접한 패키지의 빠른 회귀 검증이다.
- `go test ./...` — 저장소 전체 Go 테스트 회귀 검증이다.
- `flutter test` / `make client-test` — Flutter client 단위/widget/wire 테스트 검증이다.
- `make client-build-web` — Flutter Web build와 `--dart-define` 설정 주입 검증이다.
- edge-node 개발 진단 흐름 검증 — `scripts/dev/edge.sh``scripts/dev/node.sh`를 각각 실행하고, edge console에서 메시지 2회와 command 명령을 직접 보내 결과가 edge 화면에 도착하는지 확인하는 저수준 검증이다. field 사용자 기본 UX는 Edge가 제시한 bootstrap 명령이다.
- client 개발 진단 흐름 검증 — `scripts/dev/web.sh`로 Flutter Web dev server를 띄우고 Control Plane HTTP/WS URL 주입과 `/client` wire 연결 상태를 확인하는 저수준 검증이다.
- 보조 E2E smoke — 임시 설정과 mock adapter로 최소 생존을 빠르게 확인하는 보조 검증이다. 이 결과만으로 완료 처리하지 않는다.
- OpenAI-compatible Ollama smoke — `scripts/e2e-openai-ollama.sh`로 OpenAI HTTP 입력 표면이 edge service와 node adapter 경로로 수렴하는지 확인하는 보조 검증이다.
- Generic OpenAI-compatible provider smoke covers standard inference, streaming, caller tools, cancellation, and provider-pool routing without host process or filesystem context. A dedicated execution-preset smoke may use only the approved request-scoped Node workspace executor and must separately prove containment, cleanup, no external tool continuation, and exact caller ingress count.
- OpenAI-compatible provider smoke — `scripts/e2e-openai-vllm.sh``scripts/e2e-openai-lemonade.sh`로 provider API route, request body, expected output을 확인하는 live-dependency 보조 검증이다.
- Long-context admission smoke — `scripts/e2e-long-context-admission-smoke.sh`로 provider pool capacity, queue, long-context slot, Control Plane status snapshot 회복을 live dev provider pool에서 확인하는 보조 검증이다.
- Control Plane-Edge wire smoke — `scripts/e2e-control-plane-edge-wire.sh`로 실제 Control Plane/Edge 프로세스의 Edge hello, 연결 성공, disconnect marker를 확인하는 보조 검증이다.
- Provider capacity smoke — `scripts/e2e-provider-capacity-smoke.sh`로 provider resource 단위 admission, queue와 release 동작을 확인하는 보조 검증이다.
- Inventory query — 전체 private inventory를 불필요하게 읽지 않고 환경 projection이나 exact model/node/provider selector 결과만 정렬된 JSON으로 조회하는 도구이다.
- Readability audit — file/function LOC와 task-local read-set budget을 deterministic JSON과 baseline ratchet으로 검증하는 repository quality gate이다.
- Agent provider smoke — `cmd/iop-provider-smoke`로 catalog readiness와 status/run/resume/cancel terminal을 redacted evidence로 확인하는 live external-CLI 검증이다.
- compose local dev stack 검증 — `docker-compose.yml` 변경 시 Control Plane, datastore, Flutter Web service의 build/env/healthcheck wiring을 확인하는 검증이다.
- full-cycle 실제 구동 — 비효율적이어도 관련 사용자 명령과 실행 cycle을 한 번씩 실제 entrypoint로 통과시키는 검증이다.
- 실제 외부 CLI 검증 — `claude`, `antigravity`, `codex`, `opencode`처럼 외부 CLI 설치와 계정/환경이 필요한 기준 profile을 실제 호출하는 검증이다.
- one-line bootstrap/install UX — Node, specialized agent, domain agent, Control Plane enrollment처럼 사용자가 대상 host에서 복사해 실행하는 연결/설치 명령의 사용자 경험 기준이다.
- task-loop provider 격리 guard — task-loop dry-run 및 command test에서 runtime reader/fake seam을 사용하고 실제 provider command 생성·subprocess 실행을 차단하는 test-owned guard이다.
- 대상 패키지 테스트 — 기본 검증이다.
- 저장소 전체 테스트 — 공통 계약이나 여러 패키지에 영향을 주는 변경에서만 사용한다.
- mock smoke — 실제 외부 의존성 없이 사용자 경로의 최소 생존을 확인한다.
- live/full-cycle 검증 — 사용자가 요청했거나 외부 환경에서만 확인 가능한 변경에 한해 수행한다.
- readability audit — 사용자가 요청하거나 관련 정책을 변경할 때만 수행한다.
## 유지할 패턴
- 테스트는 테스트 파일 변경 여부가 아니라 작업 영향 범위로 결정한다.
- 사용자 실행 파이프라인에 닿는 작업을 한 경우, 작업 완료 후 일반 Go 테스트와 변경 범위에 맞는 full-cycle 실제 구동을 검증한다. repo 내부 edge-node 진단에는 `scripts/dev/edge.sh` + `scripts/dev/node.sh`를 사용할 수 있지만, field 사용자 기본 UX는 bootstrap 명령으로 확인한다.
- 사용자 실행 파이프라인에는 `scripts/dev/**`, `scripts/e2e-*.sh`, `Makefile`, `docker-compose.yml`, `apps/*/cmd/**`, `apps/*/internal/bootstrap/**`, edge-node transport/service/registry/input surface, Control Plane wire endpoint, client wire surface, adapter 실행/stream/cancel/status 경로, `configs/**`, `packages/go/config/**`, `packages/go/hostsetup/**`, 관련 protobuf 계약 변경이 포함된다.
- edge-node 개발 진단 흐름 검증은 `scripts/dev/edge.sh``scripts/dev/node.sh`를 별도 프로세스로 직접 실행하고, edge console prompt에 명령을 한 줄씩 입력한 뒤 기대 출력이 도착한 것을 확인하고 다음 입력으로 넘어간다.
- 메시지 검증 기준은 edge console에서 같은 session으로 메시지 2회를 보내고, 각 요청마다 `[edge] sent`, `[node-*-event] start`, 기대 payload를 포함한 비어 있지 않은 `[node-*-message]`, 같은 run의 `[node-*-event] complete`가 edge 화면에 표시되는 것이다.
- 완료 이벤트만으로 정상 판정하지 않는다. `[edge] sent``[edge-message]`에 보이는 사용자 입력 echo는 응답 relay 증거가 아니며, node 로컬 출력에 생성된 같은 run의 `[node-message]` payload 라인 목록이 edge console의 `[node-*-message]` 라인 목록과 내용/순서까지 동일해야 한다. complete event는 동일성 확인 대상인 모든 message payload가 edge에 표시된 뒤의 마감 신호이며, 답변이 끝나기 전에 complete가 먼저 표시되거나 complete 뒤에 같은 run의 message가 추가로 표시되면 실패다.
- command 검증 기준은 edge console에서 `/nodes`와 변경 범위에 닿는 command를 직접 입력하고, node에서 온 결과가 edge 화면에 `[node-*-<command>]` 또는 명확한 성공/unsupported/error 출력으로 표시되는 것이다. CLI 경로 변경 시 최소 `/capabilities`, `/transport`, `/sessions`, persistent profile이면 `/terminate-session`을 확인한다.
- 보조 E2E smoke는 mock adapter와 임시 설정/포트를 사용해 외부 CLI 의존성 없이 수행한다.
- 보조 E2E smoke에서는 최소한 node 등록, `/nodes` 확인, console 메시지 전송, delta/message 출력, complete event를 확인한다.
- task-loop의 unit 또는 integration simulation은 실제 provider process, provider session, 네트워크 호출을 실행하지 않는다. 실행 outcome이 필요한 경우 highest runtime port를 deterministic fake로 대체하고 provider command가 호출되지 않았음을 assertion으로 남긴다.
- task-loop dry-run 상태 전이 테스트는 runtime reader만 사용한다. execution을 검증해야 하면 fake provider의 입력·반환 locator·호출 횟수를 명시하고 provider command가 호출되지 않았음을 함께 검증한다.
- dispatcher/selector의 unit 또는 integration simulation은 실제 `pi`, `agy`, `claude`, `codex` provider process, provider session, 네트워크 호출을 실행하지 않는다. 실행 outcome이 필요한 경우 가장 높은 runner seam을 deterministic fake로 대체하고 provider command 생성·subprocess 실행이 없었음을 assertion으로 남긴다.
- Inventory query는 selector 없는 경우 bounded environment projection만 반환하고, model/node/provider selector는 exact match와 stable path ordering을 유지한다.
- Readability audit는 공통 Agent-Ops rules/skills와 생성물을 제외한 project-owned tracked/worktree 입력을 deterministic하게 측정하고, `--check`에서는 새롭거나 증가한 violation만 실패시키는 ratchet을 유지한다.
- `cmd/iop-provider-smoke``-redact` 없이 실행 evidence를 만들지 않고 provider output, credential, token과 private endpoint를 출력하지 않는다. 이 live smoke를 dispatcher unit/integration simulation 경로로 호출하지 않는다.
- header만 가진 PLAN/CODE_REVIEW fixture 또는 action item이 없는 fixture는 provider prompt가 될 수 없다. 그런 fixture는 dry-run, empty task scan, 또는 fake runner 아래에서만 사용한다.
- 새 task-loop test는 기본 provider-deny guard를 설치하고, 실제 invocation 결과를 의도적으로 검증하는 test만 해당 guard 위에 명시 fake provider를 둔다. 새 test가 guard 없이 runner 경로를 열면 실패해야 한다.
- 실제 외부 CLI 검증은 사용자가 요구한 full-cycle/profile 검증으로 명시적으로 분리할 때만 수행한다. retained reference fixture 또는 agent-task plan fixture를 그 검증의 실행 경로로 사용하지 않는다.
- full-cycle 실제 구동에서는 startup/register, foreground run, session 변경, background run, terminate-session, status, 관련 routing/cancel/timeout/persistent session cycle을 실제 entrypoint로 한 번씩 통과시킨다.
- one-line bootstrap/install command는 Jenkins agent 연결처럼 간결해야 한다. 사용자에게 전달하는 명령은 artifact/bootstrap URL이 완성된 한 줄이어야 하며, 사용자가 직접 바꾸는 값은 token 같은 단일 positional 값만 둔다.
- one-line bootstrap/install command의 Edge 주소, artifact 주소, target, platform, config path 같은 값은 작업자/Edge/Control Plane이 미리 굽거나 완성해서 제공한다. 사용자 기본 경로에서 `IOP_*=` 같은 named environment parameter나 여러 주소 조합을 직접 입력하게 하지 않는다.
- field Node bootstrap의 사용자 명령은 대상 OS에 맞는 완성된 bootstrap URL과 실제 token 값을 포함한 한 줄 명령을 기준으로 한다. Linux/macOS는 `curl -fsSL ... | bash -s ...`, Windows native는 PowerShell `.ps1` bootstrap과 `Start-IopNode`를 기준으로 한다. 다른 bootstrap/enrollment 작업에서도 같은 수준의 단일 token UX를 우선 적용하고, 예외가 필요하면 사용자에게 먼저 확인한다.
- 사용자에게 실행 방법을 알려줄 때는 placeholder 형식을 쓰지 않는다. token 원문을 현재 채널에 적기 어렵다면 placeholder 명령을 주지 말고, 안전한 secret 전달 절차를 먼저 끝낸 뒤 실제 값이 들어간 완성 명령만 제공한다.
- field bootstrap 안내에서 token을 숨기겠다는 이유로 `ssh ... awk ...`, command substitution, 여러 환경 변수 선언, inline config 생성, 수동 binary download를 한 줄에 합치지 않는다.
- 추가 설정이 필요한 경우 기본 bootstrap 명령 뒤에 “선택 옵션”으로 분리한다. 기본 성공 경로는 사용자가 값 치환 없이 실행하면 동작해야 하며, 환경 변수나 config 편집은 고급/디버그 override로만 검증한다.
- repo 내부 edge-node 진단의 상세 수행 절차와 기능별 체크리스트는 `agent-ops/skills/project/e2e-smoke/SKILL.md`를 따른다.
- `make test-e2e`, `scripts/e2e-smoke.sh`, `scripts/e2e-openai-ollama.sh`, `scripts/e2e-control-plane-edge-wire.sh`는 보조 smoke 명령이다. 실행할 수 있으면 보조 확인으로 기록하되, full-cycle 실제 구동이나 field bootstrap 검증을 대체하지 않는다.
- Client-Control Plane wire나 client UI를 바꾸면 `make client-test`를 기본 검증으로 기록한다. Web build/deploy 경로를 바꾸면 `make client-build-web`, `scripts/dev/web.sh`, compose build 중 변경 범위에 맞는 경로를 추가 확인한다.
- Control Plane-Edge wire나 Edge outbound connector를 바꾸면 대상 Go 테스트와 함께 `make test-control-plane-edge-wire`를 보조 검증으로 기록한다. status snapshot, node event relay, HTTP `/edges` 조회를 바꾼 경우 해당 동작을 별도로 확인한다.
- OpenAI-compatible route, `/v1/responses`, CLI workspace handoff, provider tunnel, provider auth, tool validation, usage metering을 바꾸면 대상 Go 테스트와 함께 관련 OpenAI smoke(`test-openai-ollama`, `scripts/e2e-openai-cli-workspace.sh`, `scripts/e2e-openai-vllm.sh`, `scripts/e2e-openai-lemonade.sh`) 중 변경 범위에 맞는 것을 보조 검증으로 기록한다.
- Anthropic single-request execution preset과 Node workspace executor를 바꾸면 실제 Claude Code에서 작은 작업을 한 번 요청하고 Edge `/v1/messages` ingress 1회, Gemini plan → ornith-fast work → Gemini review/repair, bounded Node tool lifecycle, 최종 workspace 결과와 terminal 1회를 redacted evidence로 확인한다. generic provider smoke나 caller tool round-trip으로 대체하지 않는다.
- provider pool, model catalog, queue admission, long-context capacity, Control Plane provider snapshot을 바꾸면 `scripts/e2e-long-context-admission-smoke.sh --preflight`와 필요한 `--scenario`를 live 환경 가용성에 따라 실행하고, 실행 불가/실패는 profile별 blocker로 보고한다.
- `iop-edge bootstrap pack`, `make pack-edge`, 내장 artifact server 변경 시 최소 현재 host target build를 실행하고 archive 압축 해제, artifact 폴더 위치, checksum 생성, node bootstrap script가 positional token UX를 유지하는지 확인한다.
- 풀테스트에서는 실제 외부 CLI profile 검증을 필수로 수행한다. 환경, 계정, provider, 원격 endpoint 문제로 호출할 수 없거나 실패한 profile은 누락하지 말고 profile별 실패 또는 blocker로 보고한다.
- 작업 최종 보고에는 실행한 테스트 명령, repo 내부 edge-node 진단 수행 여부, 보조 E2E smoke 수행 여부, full-cycle 실제 구동 수행 여부를 명시한다. 수행하지 못한 필수 검증은 이유와 남은 위험을 함께 적는다.
## 기준 출력 예시
아래처럼 edge console에서 입력한 메시지 2회와 command 결과가 edge 화면에 도착해야 기준을 통과한 것으로 본다. run id와 node alias는 실행 환경에 따라 달라질 수 있다.
```text
edge> /nodes
test-node (test-node)
edge> Convert token iop_manual_one and reply only with converted token
[edge] sent run_id=manual-... node=test-node adapter=cli target=fake-cli session=default background=false
[node-test-node-event] start run_id=manual-...
[node-test-node-message] IOP_MANUAL_ONE_OK
[node-test-node-message] IOP_MANUAL_ONE_TAIL
[node-test-node-event] complete run_id=manual-... detail="idle-timeout"
edge> Convert token iop_manual_two and reply only with converted token
[edge] sent run_id=manual-... node=test-node adapter=cli target=fake-cli session=default background=false
[node-test-node-event] start run_id=manual-...
[node-test-node-message] IOP_MANUAL_TWO_OK
[node-test-node-message] IOP_MANUAL_TWO_TAIL
[node-test-node-event] complete run_id=manual-... detail="idle-timeout"
edge> /capabilities
[node-test-node-capabilities] target=fake-cli session=default
adapter = cli
max_concurrency = 4
targets = fake-cli
edge> /transport
[node-test-node-transport] target=fake-cli session=default
adapter = cli
connected = true
node_id = test-node
session_id = default
target = fake-cli
edge> /sessions
[node-test-node-sessions] target=fake-cli session=default
count = 1
sessions = persistent:fake-cli/default
edge> /terminate-session
terminated session default node=test-node
```
- 기본값은 변경한 패키지나 컴포넌트의 가장 작은 관련 테스트다.
- 여러 패키지의 공통 계약을 변경한 경우에만 `go test ./...` 또는 대응하는 전체 client test로 넓힌다.
- E2E, live provider, 실제 외부 CLI, full-cycle, field bootstrap은 서로 대체 관계를 강제하지 않는다. 변경 위험이나 사용자 요청에 맞는 하나를 선택한다.
- smoke 성공을 모든 작업의 완료 조건으로 만들지 않는다. 반대로 smoke가 필요한 작업에서는 관찰한 사용자-visible 결과를 간단히 기록한다.
- 외부 endpoint, 계정, provider 또는 host가 없어 실행하지 못한 검증은 blocker가 아니라 미실행 검증과 남은 위험으로 보고한다. 단, 배포·외부 쓰기 자체가 요청 결과인 경우에는 해당 실행 실패를 완료로 보고하지 않는다.
- secret, token, credential, private endpoint 원문은 출력이나 evidence에 남기지 않는다.
- task-loop simulation은 실제 provider process나 네트워크를 호출하지 않고 fake seam을 사용한다.
- bootstrap/install UX를 직접 변경한 경우에만 대상 OS의 한 줄 기본 경로를 확인한다.
- 최종 보고에는 실제 실행한 테스트와 실행하지 않은 위험 관련 테스트만 적는다. 고정된 전체 검증 체크리스트를 반복하지 않는다.
## 다른 도메인과의 경계
- **node**: node는 adapter 실행과 edge 연결 구현을 소유한다. testing은 node 변경 후 어떤 검증을 거칠지 정한다.
- **edge**: edge는 registry, service, transport, console, HTTP/A2A input surface 구현을 소유한다. testing은 edge 변경 후 사용자 실행 흐름을 어떻게 확인할지 정한다.
- **control-plane**: control-plane은 server endpoint, Edge wire registry, Client WS boundary 구현을 소유한다. testing은 해당 변경 후 어떤 smoke와 실제 구동 검증을 거칠지 정한다.
- **client**: client는 Flutter UI와 Dart wire wrapper 구현을 소유한다. testing은 client 변경 후 어떤 Flutter test/build/dev-server 검증을 거칠지 정한다.
- **platform-common**: platform-common은 config/proto 계약을 소유한다. testing은 해당 계약 변경이 edge-node 실행 흐름에 닿을 때 필요한 검증을 정한다.
- **node/edge/control-plane/client/platform-common**: 각 도메인이 구현과 단위 테스트를 소유한다. testing은 공통 진입점과 선택적 통합 검증만 소유한다.
- **agent-test**: 환경별 값과 secret-safe 실행 방법만 제공한다. 테스트 선택 정책은 이 문서가 소유한다.
## 금지 사항
- 사용자 실행 파이프라인에 닿는 변경을 하고 유닛/패키지 테스트만으로 완료 처리하지 않는다.
- `make test-e2e`, `scripts/e2e-smoke.sh`, `scripts/e2e-openai-ollama.sh`, `scripts/e2e-control-plane-edge-wire.sh`, 또는 smoke 통과 출력만으로 완료 처리하지 않는다.
- 관련 작업 후 full-cycle 실제 구동을 비용이 크다는 이유만으로 생략하지 않는다.
- task-loop unit/integration test에서 실제 provider CLI 또는 provider session을 시작하지 않는다.
- Agent-Ops task-loop dispatcher의 대체 실행 경로를 사용하지 않는다. 활성 `agent-task`의 worker/review 실행은 명시적 사용자 요청에 따른 Python dispatcher만 허용한다. 이 dispatcher는 Agent-Ops 작업 진행 도구일 뿐 IOP 제품 runtime/API 경로가 아니며, execution preset이나 `/v1/messages` 단일 요청의 내부 stage/tool loop 구현·검증에 사용하거나 참조하지 않는다.
- action item이 없는 plan fixture를 live task-loop worker/review 입력으로 사용하지 않는다.
- state-only test가 실제 runner 호출을 필요로 한다고 가정하지 않는다. fake runner 또는 empty scan으로 state transition을 격리하지 못하면 test plan을 먼저 보완한다.
- provider 실행을 mock하지 않은 채 실제 provider가 우연히 종료·응답했다는 결과를 unit/integration test evidence로 기록하지 않는다.
- 보조 E2E smoke를 외부 CLI 설치, 로그인, 네트워크 계정 상태에 의존하게 만들지 않는다.
- live-dependency smoke(`e2e-openai-vllm`, `e2e-openai-lemonade`, `e2e-long-context-admission-smoke`)가 필요한 작업에서 endpoint/account/token 문제를 성공으로 간주하지 않는다. 실행 불가는 명확한 blocker 또는 남은 위험으로 보고한다.
- 검증을 위해 기본 `configs/*.yaml`을 임시값으로 오염시키지 않는다. 임시 설정 파일이나 환경 변수 override를 사용한다.
- smoke script가 bearer token, provider token, API key를 stdout/stderr, evidence output, tracked fixture에 기록하지 않게 한다.
- 사용자 기본 bootstrap/install 안내에 `IOP_ARTIFACT_BASE_URL=...`, `IOP_EDGE_ADDR=...`, `IOP_NODE_TOKEN=...` 같은 named environment parameter를 요구하지 않는다. 이런 값은 작업자용 디버그/override 경로로만 분리한다.
- 사용자 기본 bootstrap/install 안내에 원격 token 조회, shell quoting이 복잡한 wrapper, 수동 `node.yaml` 생성, 수동 `iop-node serve --config ...` 실행을 섞지 않는다.
- 사용자 기본 bootstrap/install 안내에 angle-bracket placeholder, `YOUR_TOKEN`, `REPLACE_ME` 같은 치환용 값을 넣지 않는다. 실제 값을 제공할 수 없으면 실행 명령을 제시하지 않고 필요한 값의 안전 전달이 먼저 필요하다고 보고한다.
- 필수 검증을 실행하지 못했는데 조용히 생략하지 않는다.
- 작은 변경에 전체 테스트, E2E, live provider, full-cycle을 일괄 강제하지 않는다.
- 문서·plan·review·evidence 형식 충족을 테스트 성공의 선행 조건으로 만들지 않는다.
- 실제 문제가 확인되지 않았는데 예방 목적으로 새 검증 게이트를 추가하지 않는다.

View file

@ -43,6 +43,7 @@
## 프로젝트 특화 컨벤션
- IOP 작업 운영의 최우선 방향은 **검증 게이트 최소화**다. 기존 검증 게이트를 제거·병합해 최소화하며, 보안·자격증명, 데이터 손상·비가역 외부 변경, 사용자가 명시한 실제 프로젝트 간 선행 의존성 외에는 구현이나 완료를 차단하지 않는다.
- Preserve the existing hexagonal structure. Keep host-neutral provider interfaces in `packages/go/execution`, protobuf translation at `apps/node/internal/node`, and adapter/store implementations outside that core.
- Execution preset의 request-scoped workspace/tool 실행은 IOP Edge가 조정하고 선택된 IOP Node가 수행한다. provider `RunRequest`, caller metadata, closed `NodeCommand` 또는 `packages/go/execution`에 이 책임을 섞지 않고 전용 typed Edge-Node request/result 경계로 둔다.
- request-scoped tool executor는 operator가 승인한 workspace root, path containment, bounded process/output/timeout/cancel을 강제한다. 범용 interactive shell, persistent host process, desktop session, scheduler 또는 caller가 고른 임의 Node/path 실행으로 확대하지 않는다.

View file

@ -1,10 +1,5 @@
# 현재 로드맵 컨텍스트
## 고정 참조
- Phase를 가로지르는 다음 작업 후보는 [전역 마일스톤 실행 순서](priority-queue.md)를 먼저 확인한다.
- Phase는 도메인/책임 영역이며 순차 실행 게이트가 아니다.
## 활성 Phase
- [<스케치 | 계획 | 진행중 | 검토중 | 보류>] <phase-name>
@ -18,18 +13,8 @@
## 선택 규칙
- 이 문서는 활성 Phase와 활성 Milestone 후보 목록이며, 개인별 현재 작업 위치나 완료 상태를 기록하지 않는다.
- 이 문서는 브랜치별 로컬 포인터이며 git 추적 대상이 아니다.
- 활성 Phase는 [PHASE.md](phase/<phase-slug>/PHASE.md)를 가리킨다.
- 활성 Milestone은 [Milestone 문서](phase/<phase-slug>/milestones/<milestone-slug>.md)를 가리킨다.
- 활성 항목은 아카이브 경로를 포함하지 않는다.
- `[검토중]` 항목은 완료 근거와 archive 조건이 정리될 때까지 활성 항목으로 남길 수 있다.
- `[스케치]` 항목은 활성 후보로 남길 수 있지만 구현 계획 생성 대상은 아니며, `[계획]` 승격 조건을 정리하는 대상으로만 다룬다.
- `[완료]` 또는 `[폐기]` 항목은 archive 링크를 남긴 뒤 활성 항목에서 제거한다.
- 요청 내용, 현재 브랜치, 변경 파일, 관련 코드 경로를 보고 가장 관련 있는 Phase와 Milestone을 선택하고 같은 세션에서 1회 읽는다.
- 활성 Phase 또는 Milestone 둘 이상에 걸치면 필요한 문서를 모두 읽고 작업 범위를 좁힌다.
- 활성 범위 밖의 작업이면 [ROADMAP.md](ROADMAP.md)의 Phase 흐름을 확인하고 범위 충돌을 보고한다. 제품/범위 결정이 필요하면 대상 Milestone의 `구현 잠금 > 결정 필요` 또는 SDD [USER_REVIEW.md](sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md)로 분리한다.
- 완료된 과거 내용이 필요할 때만 `ROADMAP.md` 또는 `PHASE.md`에 있는 archive 링크를 따라가서 읽는다.
- 선택된 Milestone의 `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 구현이나 구현 계획을 시작하기 전에 현재 요청에 직접 영향을 주는 `결정 필요` 항목만 확인한다. 관련 결정이 없고 표준선으로 처리 가능하면 잠금 해소용 roadmap-only 갱신으로 결정 항목을 정리한 뒤 진행하며, Milestone 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없을 때만 `구현 잠금` 상태를 `해제`로 둔다.
- 선택된 Milestone에 `SDD: 필요`가 있으면 [SDD.md](sdd/<phase-slug>/<milestone-slug>/SDD.md)가 `[승인됨]`이고 SDD 잠금이 해제되었으며 SDD [USER_REVIEW.md](sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md)가 없어야 구현이나 구현 계획을 시작한다.
- 선택된 Milestone 상태가 `[스케치]`이면 `구현 잠금` 상태와 관계없이 구현이나 구현 계획을 시작하지 않고 `[계획]` 승격 필요를 보고한다.
- 이 문서는 활성 후보 목록이며 구현 허가 상태가 아니다.
- 요청과 가장 직접 관련된 후보를 선택한다.
- `[스케치]`라도 명확한 독립 Task는 진행할 수 있고, 미정 결정에 의존하는 부분만 보류한다.
- SDD, spec, plan, review, 정합성, evidence 상태로 구현을 차단하지 않는다.
- 완료·폐기 항목과 archive 경로는 활성 후보에서 제거한다.

View file

@ -7,7 +7,7 @@
## 목표
<Milestone이 끝났을 달성되어야 하는 결과를 1~3문장으로 작성>
<완료 달성할 결과를 1~3문장으로 작성>
## 상태
@ -15,78 +15,48 @@
## 승격 조건
<!--
[스케치] Milestone일 때만 필수다.
[스케치]에서는 [계획]으로 전환하기 위해 필요한 정의, 결정, 경계, 후속 구현 Milestone 후보를 체크리스트로 적는다.
[계획] 이상 상태에서는 이 섹션을 생략하거나 아래처럼 `- 없음`으로 둔다.
-->
<!-- [스케치]일 때 구현 가능한 단위로 만들기 위해 실제로 필요한 항목만 적는다. [계획] 이상이면 생략할 수 있다. -->
- 없음
<!-- [스케치] 예시:
- [ ] 구현 가능한 목표와 범위를 확정한다.
- [ ] 에이전트가 확정할 수 없는 제품/우선순위/책임 경계를 `구현 잠금 > 결정 필요`로 분리한다.
- [ ] 기능 단위와 후속 구현 Milestone 후보를 나눈다.
-->
## 결정 사항
## 구현 잠금
<!-- 현재 구현에 직접 필요하고 에이전트가 확정할 수 없는 제품 결정만 적는다. 결정은 관련 작업만 보류하며 Milestone 전체 잠금으로 사용하지 않는다. -->
- 상태: <잠금 | 해제>
- SDD: <필요 | 불필요>
- SDD 문서: <없음 | [SDD.md](../../../sdd/<phase-slug>/<milestone-slug>/SDD.md)>
- SDD 사유: <필요/불필요 판정 근거 >
- 잠금 해제 조건: <없음 | 아래 체크리스트>
- [ ] <SDD가 필요한 경우: SDD 잠금이 해제되어 있다>
- [ ] <SDD가 필요한 경우: SDD 사용자 리뷰가 없거나 승인/해결되었다>
- [ ] <SDD가 필요한 경우: Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다>
- [ ] <SDD가 필요한 경우: Evidence Map이 완료 complete.log의 milestone-task id별 집계와 최종 검증 evidence로 검증 가능하게 연결되어 있다>
- 결정 필요: <없음 | 아래 목록>
- <에이전트가 확정할 없는 제품/범위/우선순위/책임 경계 결정 항목>
- 없음
## 설계 참고
<!-- SDD나 계약 문서가 실제로 도움이 될 때만 링크한다. 승인 상태나 unlock checklist를 두지 않는다. -->
- 없음
## 범위
- <Milestone에 포함되는 제품/기술/문서 범위>
- <포함 범위>
## 기능
<!--
Epic은 `### Epic: [epic-id] <이름>` 형식을 사용한다.
epic-id는 공백 없는 짧은 ASCII 영문/숫자 segment 1~4개로 작성하고 segment 구분자는 -_+= 만 사용한다.
Task는 `- [ ] [item-id] 설명` 형식을 사용한다.
item-id는 공백 없는 짧은 ASCII 영문/숫자 segment 1~4개로 작성하고 segment 구분자는 -_+= 만 사용한다.
epic-id와 item-id는 해당 Milestone 안에서만 유일하면 되고, 다른 Milestone에서는 같은 id를 다시 사용할 수 있다.
Task는 기능 또는 산출물 단위다. 검증이 필요한 기능만 같은 Task 안에 `검증: <명령/확인 방법/기대 결과>`를 덧붙인다.
각 Epic에는 기능 Task를 최대 5개만 둔다. 여섯 번째 Task가 필요하면 capability, 산출물, 의존성, 검증 경계 중 하나로 Epic을 분리한다. 분리된 Epic이 독립 목표면 새 Milestone 후보로 둔다.
Task 체크리스트는 Epic 바로 아래의 flat list로 유지하고, 구현 세부나 테스트만 따로 떼어낸 하위 체크박스는 만들지 않는다.
별도 `완료 기준` 섹션은 만들지 않는다.
-->
### Epic: [epic-id] <Epic 이름>
< Epic이 묶는 capability 또는 산출물 설명>
- [ ] [item-id] <구현 세부가 아닌 기능 또는 산출물>
- [ ] [item-id] <구현 세부가 아니라 Milestone에서 달성해야 capability 또는 산출물>
<!-- 검증이 필요한 기능 Task 예시:
- [ ] [item-id] <기능 설명>. 검증: <명령/확인 방법/기대 결과>
-->
<!-- 위험에 비례한 검증이 필요한 경우에만 같은 Task에 `검증:`을 덧붙인다. -->
## 완료 리뷰
- 상태: <없음 | 검토중 | 통과 | 보완 필요 | 보류 | 폐기>
- 요청일: <YYYY-MM-DD | 없음>
- 완료 근거: <모든 기능 Task와 Task 안에 명시된 검증 충족 구현 잠금 해제 여부를 1~3줄로 요약>
- 검토 항목: <없음 | 에이전트/런타임이 확인할 완료 근거 또는 archive 조건>
- 리뷰 코멘트: <없음 | 보완/보류/폐기 방향성>
<!-- 사용자가 완료 리뷰를 요청했거나 남은 위험을 별도로 기록할 때만 유지한다. -->
- 상태: 없음
- 완료 근거: 없음
- 남은 위험: 없음
## 범위 제외
- <Milestone에서 의도적으로 하지 않는 >
- <의도적으로 하지 않는 >
## 작업 컨텍스트
- 관련 경로: `<path>`
- 표준선(선택): <기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 진행할 기본 기준>
- 실행 순서와 차단 관계: [전역 마일스톤 실행 순서](../../../priority-queue.md)
- 관련 Milestone(선택): <없음 또는 파일 위치 기준 Markdown 링크(예: [Milestone 이름](../other-milestone.md))>
- 확인 필요: <없음 | `구현 잠금 > 결정 필요` 또는 [USER_REVIEW.md](../../../sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md) 분리할 항목>
- 실행 순서: [전역 마일스톤 실행 순서](../../../priority-queue.md)
- 관련 Milestone: 없음

View file

@ -7,79 +7,45 @@
## 상태
[<초안 | 검토중 | 승인됨 | 대체됨 | 폐기>]
## SDD 잠금
- 상태: <잠금 | 해제>
- 사용자 리뷰: <없음 | [USER_REVIEW.md](USER_REVIEW.md)>
- 잠금 항목:
- [ ] [D01] <사용자만 결정할 source of truth, 상태 전이, 책임 경계, 범위, 권한, 비용, 실패 처리 항목>
[<초안 | 확정 | 대체됨 | 폐기>]
## 문제 / 비목표
- 문제: < SDD가 고정해야 하는 작업의 모호함>
- 비목표:
- <이번 Milestone에서 의도적으로 다루지 않는 설계 범위>
- 문제: < 문서가 명확히 설계 문제>
- 비목표: <다루지 않는 범위>
## Source of Truth
| 영역 | 기준 | 메모 |
|------|------|------|
| Roadmap | [Milestone 문서](../../../phase/<phase-slug>/milestones/<milestone-slug>.md) | <장기 원장, 상태 반영 기준> |
| Code | `<path>` | <구현 source of truth> |
| External Provider | <없음 또는 provider> | <provider id/revision/status 기준> |
| User Decision | <없음 또는 D-id> | <사용자 결정이 필요한 기준> |
- <영역>: <code, contract, provider 또는 사용자 결정>
## State Machine
## State / Lifecycle
| 상태 | 진입 조건 | 다음 상태 | 근거 |
|------|-----------|-----------|------|
| <state> | <condition> | <state> | <event/file/provider> |
## Interface Contract
- 계약 원문: <없음 또는 [계약 문서](../../../../agent-contract/...)>
- 입력:
- <field>: <의미>
- 출력:
- <field>: <의미>
- 금지:
- <하면 되는 동작>
## Acceptance Scenarios
| ID | Milestone Task | Given | When | Then |
|----|----------------|-------|------|------|
| S01 | `<task-id>` | <상태/입력> | <행동> | <관찰 가능한 결과> |
## Evidence Map
| Scenario | Required Evidence | `agent-task` 연결 | 완료 Evidence 기대 |
|----------|-------------------|------------------|---------------------------|
| S01 | <test/smoke/search/user-review evidence> | `agent-task/m-<milestone-slug>/...` | <complete.log의 milestone-task id별 집계/최종 검증으로 확인할 근거> |
## Cross-repo Dependencies
<!-- 상태 전이가 있을 때만 유지한다. -->
- 없음
<!-- 필요한 경우:
- `<project>:agent-roadmap/phase/<phase>/milestones/<milestone>.md`
- `.agent-roadmap-sync/locks.yaml` entry: `<id>`
-->
## Interface Contract
## Drift Check
<!-- 인터페이스 계약이 있을 때만 유지하고 계약 원문은 링크한다. -->
- [ ] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
- [ ] Evidence Map이 code-review/complete.log에서 검증 가능하다.
- [ ] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
- [ ] 사용자 리뷰가 필요한 항목은 `USER_REVIEW.md`에만 남겼다.
- 계약 원문: 없음
## 사용자 리뷰 이력
## Acceptance Scenarios
<!-- 설계를 구체화하는 데 유용할 때만 작성한다. 완료 metadata 형식과 연결할 필요는 없다. -->
- 없음
## Open Decisions
<!-- 현재 구현에 직접 필요한 사용자 소유 결정만 적는다. 승인·잠금 체크리스트로 사용하지 않는다. -->
- 없음
## Dependencies
- 없음
## 작업 컨텍스트
- 표준선: <기존 구조, 도메인 rule, 플랫폼 관례>
- 후속 SDD: <없음 또는 [SDD.md](../<other-milestone-slug>/SDD.md)>
- 관련 경로: `<path>`

View file

@ -1,37 +1,20 @@
# SDD User Review
## 상태
요청됨
# SDD Decision Note
## 검토 대상
- SDD: [SDD.md](SDD.md)
- Milestone: [Milestone 문서](../../../phase/<phase-slug>/milestones/<milestone-slug>.md)
## 사용자 결정 항목
## 필요한 결정
### [D01] <결정 제목>
- 결정 필요: <사용자만 결정할 질문>
- 추천안: <agent가 제안하는 기본안>
- 대안: <없음 또는 대안>
- 영향: < 결정이 상태 전이, provider 쓰기, 권한, 비용, scope, 실패 처리에 미치는 영향>
- 적용 위치:
- SDD: `<section>`
- Milestone: `<item-id 또는 구현 잠금>`
- 질문: <현재 구현에 직접 필요한 사용자 소유 결정>
- 추천안: <기존 구조와 요청 범위에 따른 기본안>
- 대안과 영향: <실질적인 대안이 있을 때만 작성>
## 승인 항목
- [ ] 위 결정 항목을 승인했다.
- [ ] SDD 잠금 해제를 승인했다.
## 답변 기록
## 답변
- 없음
## 해결 조건
- 모든 사용자 결정 항목의 답변이 SDD에 반영되어 있다.
- `USER_REVIEW.md``user_review_N.log`로 이동되어 있다.
- 남은 잠금 항목이 없으면 SDD 상태가 `[승인됨]`이고 `SDD 잠금` 상태가 `해제`다.
이 문서는 결정 기록이며 승인 게이트가 아니다. 미정 항목은 그 결정에 의존하는 작업만 보류한다.

View file

@ -1,58 +1,30 @@
# 로드맵
## 고정 실행 순서
## 운영 원칙
- 전역 Milestone 실행 순서는 [전역 마일스톤 실행 순서](priority-queue.md)를 먼저 확인한다.
- Phase는 도메인/책임 영역이며 순차 실행 게이트가 아니다.
- Phase 흐름과 상태는 로드맵 구조를 설명하고, 실제 다음 작업 선택은 `priority-queue.md`의 prefix별 index와 차단 표기를 따른다.
- `priority-queue.md`는 순서 전용 문서이며, 상태, 목표, 범위, 잠금, 기능, 완료 근거는 각 Milestone 문서를 원본으로 삼는다.
- `priority-queue.md` 항목은 `[prefix-NN]`을 포함한 Milestone 제목 링크, 1~2문장 설명, 필요한 `선행 차단`/`동시 차단` 예외만 둔다.
- `priority-queue.md`는 로드맵 생성 시 함께 만들며, 실행 후보가 없을 때도 문서와 `실행 순서` 섹션은 유지한다.
- 같은 prefix의 작은 index는 큰 index보다 먼저 실행하고, 다른 prefix는 차단 표기가 없으면 병렬 실행할 수 있다. 여러 열린 prefix 중 문서상 위쪽 그룹은 기본 선택 tie-breaker다.
- `priority-queue.md`는 사용자가 순서 조정을 요청한 경우, Milestone archive 시 완료 항목과 충족된 차단 참조 제거가 필요한 경우, 큐에 있는 Milestone이 폐기, 경로 변경, split/merge, 또는 실행 의미가 바뀔 정도로 수정된 경우에만 재정렬한다.
- `priority-queue.md`의 링크가 깨졌으면 활성 Milestone 문서를 기준으로 큐를 재정렬하거나 재생성한다.
- 최우선 방향은 **검증 게이트 최소화**다.
- roadmap은 목표와 범위를 기록하며 구현 허가 절차가 아니다.
- 차단 관계는 사용자가 명시한 실제 선행 의존성만 기록한다.
- SDD, spec, plan, review, 정합성, evidence는 선택적 도구이며 서로의 선행 조건이 아니다.
## 전체 목표
<프로젝트가 최종적으로 달성하려는 결과를 1~3문장으로 작성>
## 실행 순서
- [전역 마일스톤 실행 순서](priority-queue.md)
## Phase 흐름
Phase는 실행 순서가 아니라 도메인/책임 영역의 구조적 지도다.
완료된 Phase도 로드맵에서 제거하지 않고, archive의 Phase 문서로 연결한다.
상태 그룹은 완료, 검토중, 진행중, 계획, 스케치 순서로 정리해 각 도메인 축의 성숙도와 정리 상태를 읽기 쉽게 한다.
실제 다음 작업 선택은 [전역 마일스톤 실행 순서](priority-queue.md)의 위아래 순서를 우선한다.
- [<스케치 | 계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>] <Phase 이름>
- 경로: [PHASE.md](phase/<phase-slug>/PHASE.md) 또는 [archive PHASE.md](archive/phase/<phase-slug>/PHASE.md)
- 요약: <Phase의 목표와 역할 1문장>
- 경로: [PHASE.md](phase/<phase-slug>/PHASE.md)
- 요약: <목표와 역할 문장>
## 로딩 정책
- 일반 작업에서는 [ROADMAP.md](ROADMAP.md)를 매번 읽지 않는다.
- Phase를 가로지르는 다음 작업 후보를 고를 때는 [전역 마일스톤 실행 순서](priority-queue.md)를 먼저 확인한다.
- 기능 추가, 구조 변경, 스킬 추가/수정, 문서 구조 변경 작업을 수행할 때는 [current.md](current.md)를 먼저 읽는다.
- `current.md`는 현재 작업 위치가 아니라 활성 Phase와 활성 Milestone 후보 목록이다.
- `current.md`는 브랜치별 로컬 포인터이며 git 추적 대상이 아니다. 로드맵 기반 계획/갱신에서 없으면 `agent-ops/skills/common/_templates/roadmap-current-template.md` 형식으로 생성해 사용하고, 읽기 전용 현지점 확인에서는 생성하지 않는다.
- `current.md`에는 개인별 현재 작업 위치나 완료 상태를 기록하지 않는다.
- `current.md`의 활성 Phase는 [PHASE.md](phase/<phase-slug>/PHASE.md)를 가리킨다.
- `current.md`의 활성 Milestone은 [Milestone 문서](phase/<phase-slug>/milestones/<milestone-slug>.md)를 가리킨다.
- `current.md``agent-roadmap/archive/**` 경로를 활성 항목으로 포함하지 않는다.
- 요청 내용, 현재 브랜치, 변경 파일, 관련 코드 경로를 보고 가장 관련 있는 활성 Phase와 Milestone 문서를 같은 세션에서 1회 읽는다.
- 활성 Phase 또는 Milestone 밖의 작업이면 이 문서의 Phase 흐름을 확인하고 범위 충돌을 보고한다. 제품/범위 결정이 필요하면 대상 Milestone의 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- 이 문서는 로드맵 생성/갱신, Phase 전환, Phase 추가/수정, 전체 구조 변경 요청이 있을 때만 읽는다.
- 상세 작업은 각 Milestone 문서의 `기능`으로 관리한다. 검증이 필요한 기능만 같은 Task 안에 `검증:`으로 통합한다.
- 큰 Milestone의 설계 게이트는 [SDD.md](sdd/<phase-slug>/<milestone-slug>/SDD.md)에 두고, Milestone `구현 잠금`의 SDD 조건과 연결한다.
- SDD 사용자 리뷰가 필요하면 [USER_REVIEW.md](sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md)로 남기며, 해결 후 `user_review_N.log`로 보존한다.
- `[스케치]` Phase/Milestone은 방향성, 문제의식, 후보 범위, 미정 질문을 기록하는 컨셉 상태이며 구현 계획 생성 대상이 아니다.
- `[스케치]` 항목은 `승격 조건`을 정리해 `[계획]`으로 전환한 뒤 구현 계획을 만든다.
- 모든 기능 Task와 Task 안에 명시된 검증이 충족되고 `구현 잠금`이 해제된 Milestone은 먼저 `[검토중]`으로 두고, 완료 근거와 archive 조건이 정리되면 `[완료]`로 전환한다.
- 완료된 Phase는 [archive PHASE.md](archive/phase/<phase-slug>/PHASE.md)로 이동하고, 하위 Milestone도 같은 archive Phase scaffold 아래에 둔다.
- 진행중 Phase 안에서 완료된 Milestone은 활성 Phase 문서에 짧은 링크를 남기고, 상세 문서는 [archive milestones](archive/phase/<phase-slug>/milestones/)로 이동한다.
- archive `PHASE.md`는 Phase 자체가 완료 또는 폐기될 때만 만들며, 진행중 Phase의 완료 Milestone만 archive된 경우 archive Phase 디렉터리에 `milestones/`만 있을 수 있다.
- `agent-roadmap/archive/**`는 일반 작업에서 읽지 않는다. 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라가서 읽는다.
- 아카이브된 Phase/Milestone 문서는 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.
- 선택된 Milestone의 `구현 잠금` 섹션이 없거나, 상태가 `잠금`이거나, 미완료 `결정 필요` 항목이 있으면 코드 구현, `agent-task` 구현 계획 생성, 세부 API/파일 구조 확정을 시작하지 않는다.
- 선택된 Milestone에 `SDD: 필요`가 있으면 SDD 상태가 `[승인됨]`이고 SDD 잠금이 해제되었으며 SDD 사용자 리뷰가 없어야 구현 계획을 만들 수 있다.
- 잠금 상태의 Milestone에서는 "현재 요청과 직접 관련 없음"을 이유로 실구현 계획이나 코드 구현을 진행하지 않는다. 먼저 roadmap-only 갱신으로 범위 제외, 후속 Milestone, 작업 컨텍스트 이동 또는 잠금 해제를 문서화한다.
- Milestone 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `구현 잠금` 상태를 `해제`로 둔다.
- 일반 구현에서는 이 문서를 읽지 않는다.
- 로드맵 갱신에는 관련 Phase와 Milestone만 먼저 읽는다.
- archive는 과거 확인·복원·비교가 요청된 경우에만 읽는다.
- 미정 결정은 관련 Task만 보류하며 다른 작업을 잠그지 않는다.
- 기능 Task가 완료되면 별도 승인 단계 없이 Milestone을 완료할 수 있다.

View file

@ -1,115 +1,27 @@
---
name: analyze-roadmap-position
metadata:
version: "1.14.0"
description: "여러 레포를 전환할 때 코드/git 분석 없이 priority-queue 실행 순서와 ROADMAP → Phase → Milestone → current 현지점을 링크 달린 흐름 목록으로 빠르게 보여주는 읽기 전용 스킬"
description: Show the current roadmap Phase and Milestone candidates with concise links and explicit user-created dependencies.
---
# 로드맵 현지점
# Analyze Roadmap Position
## 목적
## Purpose
여러 레포를 병렬 운용하다가 돌아왔을 때, 현재 작업이 전체 로드맵의 어느 Phase와 Milestone에 있는지 빠르게 보여준다.
기본 출력은 전역 Milestone 실행 순서, `로드맵 > Phase > Milestone` breadcrumb, 전체 Phase 흐름, 현재 Phase의 Milestone 흐름이다.
Phase 흐름은 실행 순서가 아니라 도메인/책임 영역의 구조적 지도이며, 다음 작업 후보는 `priority-queue.md`의 prefix별 index와 차단 예외를 우선한다.
코드 진행도 감사, git diff 분석, 테스트 근거 확인, 남은 작업 정밀 판정은 기본 책임이 아니다.
Provide a read-only `Roadmap > Phase > Milestone` view. This is navigation, not a readiness or validation gate.
## 언제 호출할지
## Procedure
- 사용자가 "지금 작업이 뭐지?", "현재 작업이 뭐야?", "어디까지 했지?"라고 물을 때
- 사용자가 레포 전환 직후 로드맵상 현재 좌표를 빠르게 알고 싶어 할 때
- "로드맵상 현 위치", "현재 마일스톤 위치", "current 기준 breadcrumb"를 요청할 때
- Phase를 가로지르는 다음 작업 후보 순서를 함께 보고 싶어 할 때
- 구현 시작 전 전체 Roadmap > Phase > Milestone 관계만 확인하면 될 때
1. Read `agent-roadmap/current.md` when present.
2. Read `priority-queue.md` for lane order and explicit blockers.
3. Read `ROADMAP.md`, the active Phase documents, and the active candidate Milestones' title, goal, and status.
4. Show optional SDD links only when the Milestone already contains one. Do not inspect SDD approval, lock, Evidence Map, or user-review state.
5. Do not read code, git diff, tests, task evidence, or archive contents unless the user separately requests them.
## 먼저 확인할 것
## Output
- [ ] `agent-ops/skills/common/_templates/roadmap-position-report-template.md`를 읽어 최신 답변 템플릿 확인
- [ ] `agent-roadmap/` 디렉터리 존재 여부 확인
- [ ] 로컬 `agent-roadmap/current.md` 존재 여부 확인
- [ ] `agent-roadmap/priority-queue.md`가 있으면 `실행 순서` 항목 확인
- [ ] 로드맵이 있으면 `ROADMAP.md``Phase 흐름`을 확인
- [ ] 로컬 `current.md`의 활성 Phase와 활성 Milestone 이름, 상태, 경로 확인
- [ ] 활성 Phase 문서의 `Milestone 흐름` 확인
- [ ] 활성 Milestone 문서의 제목, `목표`, `상태`, `구현 잠금`의 SDD 문서 링크/경로만 확인
- active Phase and Milestone breadcrumb;
- queue lane heads and only explicit blockers;
- candidate title, status, goal, and optional design-reference link;
- broken link or ambiguous target notes.
## 실행 절차
1. `agent-roadmap/` 존재 여부를 확인한다.
- 없으면 로드맵 없음으로 짧게 보고하고 멈춘다.
2. `agent-ops/skills/common/_templates/roadmap-position-report-template.md`를 읽는다.
3. 로컬 `agent-roadmap/current.md`를 확인한다.
- 없으면 로컬 current 없음으로 보고하고, `priority-queue.md`가 있으면 전역 실행 순서와 `ROADMAP.md``Phase 흐름`을 보여준다.
4. `agent-roadmap/priority-queue.md`가 있으면 `실행 순서` 항목을 읽어 prefix별 Milestone 실행 lane 목록을 만든다.
- 각 항목은 `[prefix-NN]`, Milestone 제목 링크, 1~2문장 설명, `선행 차단``동시 차단`을 그대로 남긴다.
- 같은 prefix의 작은 active index를 lane head로 표시하고, 다른 prefix의 head는 차단이 없으면 병렬 가능 후보로 표시한다.
- 상태, 잠금, 목표, 기능 Task는 각 Milestone 문서 원본을 읽기 전에는 추정하지 않는다.
- archive 링크가 있거나 링크가 깨진 것으로 보이면 `큐 정리 필요`로 표시하고 archive 문서는 읽지 않는다.
- 파일이 없으면 `전역 실행 순서: 없음`으로 출력한다.
5. `ROADMAP.md``Phase 흐름`을 읽어 전체 Phase 목록을 만든다.
- 각 Phase는 상태, 이름, 링크만 남긴다.
- current의 활성 Phase와 일치하는 항목에 `← 현재` 표시를 붙인다.
- 완료된 Phase가 archive 경로를 가리켜도 링크만 표시하고 archive 문서는 읽지 않는다.
6. current의 활성 Phase 경로를 열고 `Milestone 흐름`을 읽는다.
- 각 Milestone은 상태, 이름, 링크만 남긴다.
- current의 활성 Milestone과 일치하는 항목에 `← 현재 후보` 표시를 붙인다.
7. current의 활성 Milestone 문서를 열고 제목, `목표`, `상태`, `구현 잠금`의 SDD 문서 링크/경로만 읽는다.
- `SDD 문서` 링크/경로가 있고 해당 `SDD.md` 파일이 존재하면 Milestone 아래에 `SDD: SDD_LINK`로 출력한다.
- `SDD 문서` 링크/경로는 있으나 해당 파일이 없으면 Milestone 아래에 `SDD: SDD_LINK (파일 없음)` 형식으로 출력한다.
- `SDD 문서` 링크/경로가 없거나 `SDD: 불필요`이면 Milestone 아래에 `SDD: 없음`으로 출력한다.
- `SDD.md`와 같은 디렉터리에 `USER_REVIEW.md`가 있으면 Milestone 아래에 `사용자 리뷰: USER_REVIEW_LINK`로 출력하고, 없으면 `사용자 리뷰: 없음`으로 출력한다.
- SDD 상태, 잠금, 승인 여부를 역할 태그나 상태 요약으로 출력하지 않는다. 필요한 독자는 출력된 SDD 링크를 열어 확인하게 한다.
- SDD 본문은 읽지 않는다.
- `기능`, `완료 리뷰`, `범위 제외`, `작업 컨텍스트`는 사용자가 명시적으로 요청한 경우에만 읽는다.
8. 결과를 템플릿의 섹션 순서와 필드 의미에 맞춰 출력한다. 템플릿의 placeholder, 선택지 표기, HTML 주석은 출력하지 않는다.
## 링크 정규화
- 출력 링크는 채팅 결과이므로 항상 repo root 기준 상대경로를 target으로 쓴다. 예: `[PHASE.md](agent-roadmap/phase/example-phase/PHASE.md)`.
- `current.md`, `ROADMAP.md`, `PHASE.md`, Milestone 문서에서 읽은 Markdown 링크는 그대로 복사하지 않는다. 반드시 링크가 들어 있던 원본 파일 위치 기준으로 target을 해석한 뒤 repo root 기준 상대경로로 다시 쓴다.
- 예: `agent-roadmap/current.md``[PHASE.md](phase/foo/PHASE.md)`는 출력에서 `[PHASE.md](agent-roadmap/phase/foo/PHASE.md)`로 쓴다.
- 예: `agent-roadmap/priority-queue.md``[Milestone](phase/foo/milestones/bar.md)`는 출력에서 `[Milestone](agent-roadmap/phase/foo/milestones/bar.md)`로 쓴다.
- 예: `agent-roadmap/phase/foo/PHASE.md``[Milestone](milestones/bar.md)`는 출력에서 `[Milestone](agent-roadmap/phase/foo/milestones/bar.md)`로 쓴다.
- 예: `agent-roadmap/phase/foo/PHASE.md``[Archive](../../archive/phase/foo/milestones/bar.md)`는 출력에서 `[Archive](agent-roadmap/archive/phase/foo/milestones/bar.md)`로 쓴다. archive 문서는 읽지 않고 링크만 표시한다.
- 링크 label은 사람이 이해할 수 있는 이름을 쓰고, target에는 `<phase-path>`, `<milestone-path>`, `<sdd-path>`, `<user-review-path>`, `<phase-slug>`, `<milestone-slug>` 또는 `{PHASE_LINK}` 같은 placeholder를 남기지 않는다.
- 템플릿의 `{PHASE_LINK}`, `{MILESTONE_LINK}`, `{SDD_LINK}`, `{USER_REVIEW_LINK}`는 실제 `[제목](repo-root-relative-path)` Markdown 링크로 치환한다.
- 대상 경로를 확정할 수 없으면 Markdown 링크를 만들지 말고 `링크 없음: <사유>`로 표시한다. raw path만 단독으로 출력하거나 깨진 링크를 만들지 않는다.
- 출력 전 자체 점검으로 `](<`, `](...<...>)`, `{PHASE_LINK}` 같은 placeholder 링크가 남아 있지 않은지 확인한다.
## 실행 결과 검증
- [ ] `roadmap-position-report-template.md`의 출력 구조를 유지했는가
- [ ] `priority-queue.md`가 있으면 `실행 순서` 항목을 표시했고, 없으면 `전역 실행 순서: 없음`으로 표시했는가
- [ ] 로컬 `current.md`, `priority-queue.md`, `ROADMAP.md`, 활성 `PHASE.md`, 활성 Milestone의 제목/목표/상태/SDD 문서 링크/경로만 기본으로 읽었는가
- [ ] 현재 후보 Milestone 아래에 SDD와 사용자 리뷰를 링크 또는 `없음`으로 출력했는가
- [ ] Phase, Milestone, SDD, 사용자 리뷰 등 모든 문서 포인터가 raw path만 남지 않고 Markdown 링크로 출력되었는가
- [ ] 문서에서 읽은 file-location-relative 링크를 채팅 출력용 repo root 상대 링크로 정규화했는가
- [ ] 출력에 placeholder 링크 target이나 `(제목)[링크]`처럼 뒤집힌 Markdown 문법이 남지 않았는가
- [ ] SDD 상태, 잠금, 승인 여부를 역할 태그나 상태 요약으로 출력하지 않았는가
- [ ] 완료 또는 archive Phase/Milestone은 링크만 표시하고 archive 문서를 읽지 않았는가
- [ ] Phase 흐름을 실행 순서로 설명하지 않고, 전역 실행 순서는 별도 섹션으로 출력했는가
- [ ] current가 여러 Milestone을 가리키면 모두 `현재 후보`로 표시했는가
- [ ] 코드 파일, 테스트 파일, `git status`, `git diff`를 기본 동작에서 읽지 않았는가
- [ ] 로드맵 파일을 수정하지 않았는가
## 출력 형식
- 템플릿 경로: `agent-ops/skills/common/_templates/roadmap-position-report-template.md`
- 템플릿의 섹션 순서와 필드 의미를 따른다. placeholder 줄을 그대로 복사하지 말고, 실제 항목 수에 맞춰 행을 생성한다.
- 출력에는 `<phase-path>`, `<milestone-path>`, `<sdd-path>`, `<user-review-path>`, `{PHASE_LINK}`, `{MILESTONE_LINK}`, `{SDD_LINK}`, `{USER_REVIEW_LINK}` placeholder를 그대로 남기지 않고 실제 repo root 기준 상대 링크 target으로 치환한다.
- 섹션 제목과 필드명을 임의로 번역, 축약, 삭제하지 않는다.
- current가 여러 Milestone을 가리키면 breadcrumb와 Milestone 흐름에 모두 표시한다.
- 현재 후보의 역할 태그는 `선행 스케치`, `다음 구현 계획`, `검토 후보`, `보류 후보`처럼 짧게 쓰되 SDD 상태를 역할 태그에 넣지 않는다.
- 현재 후보에 `SDD 문서` 링크/경로가 있으면 Milestone 아래에 SDD 링크를 배치한다. `USER_REVIEW.md`가 있으면 그 링크도 SDD 아래에 배치한다.
- 문서 포인터는 항상 `[표시 제목](상대경로)` Markdown 링크로 출력한다. 파일이 없어도 raw path만 쓰지 말고 `SDD_LINK (파일 없음)`처럼 링크와 상태를 함께 쓴다.
- `전역 마일스톤 실행 순서`에는 `priority-queue.md`의 prefix 그룹, index, 설명, blocker를 그대로 출력한다. Milestone 상태나 구현 잠금은 각 Milestone 문서를 읽지 않았다면 출력하지 않는다.
- 로드맵이 없는 프로젝트에서는 로드맵 없음으로 짧게 보고하고 템플릿을 억지로 채우지 않는다.
- 로컬 `current.md`가 없으면 `local current: 없음`으로 출력하고, `[current.md](agent-roadmap/current.md)` 링크를 만들지 않는다.
## 금지 사항
- 기본 동작에서 코드 파일, 테스트 파일, `git status`, `git diff`를 읽지 않는다.
- 기본 동작에서 Milestone의 `기능` 체크리스트를 감사하지 않는다.
- 완료 여부, 남은 작업, 코드와 문서의 동기화 상태를 evidence 기반으로 판정하지 않는다.
- 사용자가 명시하지 않은 상태에서 `ROADMAP.md`, 로컬 `current.md`, Phase, Milestone 문서를 수정하지 않는다.
- 사용자가 과거 기록 확인을 명시하지 않으면 `agent-roadmap/archive/**`를 읽지 않는다.
Do not label candidates ready, blocked, refresh-required, approved, or unlocked. Roadmap position does not control implementation permission.

View file

@ -1,348 +1,69 @@
---
name: code-review
description: Use for active task review requests such as 리뷰 진행해, 리뷰해줘, 코드 리뷰해줘, code review, CODE_REVIEW.md, USER_REVIEW.md resolution, or 리뷰 루프. Review the active PLAN/CODE_REVIEW pair, append PASS/WARN/FAIL, archive both active files, and create the required next state. PASS writes complete.log and moves the task to archive; WARN/FAIL must invoke the plan skill, which reruns finalize-task-routing before writing the next pair, unless the review-agent-owned user-review gate requires USER_REVIEW.md.
description: Review the requested code or one active PLAN/CODE_REVIEW task and report concrete correctness findings without automatically creating another workflow state.
---
# Code Review
## Purpose
Review the implementation phase of the plan-code-review loop:
Judge correctness, regressions, contracts, and proportionate test coverage. The review ends with findings and a verdict. It does not automatically generate a new plan, SDD review, user-review file, routing pass, completion log, or roadmap sync.
```text
plan skill -> finalize-task-routing -> implementation -> code-review skill
^ |
+----- WARN/FAIL: materialize closed reviewer findings -+
```
## Scope
Implementation agents never decide or request user review. They record implementation, verification, deviation, and blocker evidence in implementation-owned review fields. The official code-review agent alone evaluates the review-agent-owned gate and, when justified, writes `USER_REVIEW.md` from `agent-ops/skills/common/code-review/templates/user-review-template.md`.
1. Use the task or files named by the user.
2. If the user refers to an active task, select the exact active `PLAN-*.md` and `CODE_REVIEW-*.md` pair.
3. If multiple active tasks match and the request does not identify one, report the paths and ask for the target.
4. Start from the diff, then inspect only callers, contracts, and tests needed to judge changed behavior.
5. Do not read unrelated archive history.
## Core Loop Rules
## Review method
- Trigger: Korean or English active-task review requests, including `리뷰 진행해` and `리뷰해줘`, must use this skill when an active `CODE_REVIEW-*-G??.md` or `USER_REVIEW.md` exists under `agent-task/*/` or `agent-task/*/*/`, excluding `agent-task/archive/**`.
- Finalize every selected state unless Step 5 returns blocked. Normally append one verdict, prepare one next state, archive the pair, and materialize that state. For `dependency-wait`, keep the pair and persist `next-task`/resume condition without another verdict. A resolved `USER_REVIEW.md` writes `complete.log` and archives the task.
- Next state: `PASS` writes `complete.log` and moves the task under `agent-task/archive/YYYY/MM/`; if the task group is `m-<milestone-slug>`, report completion metadata for the runtime event. `WARN` or `FAIL` normally invokes `agent-ops/skills/common/plan/SKILL.md`, which must run `finalize-task-routing` before writing the next active pair; if the user-review gate triggers, write `USER_REVIEW.md` instead. A completed `USER_REVIEW.md` uses the same terminal `complete.log` and archive path as `PASS`.
- The user-review gate is review-agent-owned and triggers only when current evidence proves either that a concrete selected Milestone `구현 잠금 > 결정 필요` item blocks the next safe implementation step or that required external verification cannot proceed without a user-controlled capability or authorization. Generic status fields or blocker text written by implementation are never a user-review request.
- Do not replace `USER_REVIEW.md` with an inline user question. When the user-review gate triggers, write the file-based stop state and report its path.
- Do not ask for confirmation before WARN/FAIL follow-up files. If the user-review gate triggers, write `USER_REVIEW.md`; otherwise finish the reviewer-owned evidence/root-cause/fix packet and let the plan skill materialize the smallest concrete follow-up after fresh routing.
- Verification, defect analysis, and fix selection are review-agent-owned at verdict time. When implementation is present but its recorded verification output is missing, incomplete, stale, or only summarized, run the applicable plan/repository commands directly, record the fresh output in the active review artifact, and judge the implementation from that result. When fresh evidence exposes a defect, finish the root-cause analysis and choose the concrete fix before creating the follow-up plan; do not delegate diagnosis or solution selection to the plan skill or implementing agent. Do not create a finding or another plan solely because the implementing agent left insufficient verification evidence.
- Recovery: if a prior turn appended a verdict without archive or next-state files, do not append another verdict; resume Step 5 preparation/archive from that verdict. If a pre-existing verdict predates stable finding ids, assign `R1..` and `S1..` once in displayed order in the recovery handoff and record that mapping without appending a second verdict. If exactly one member of the pair was archived after both archive destinations had been preflighted, verify the archived member and remaining source/destination, finish that archive, then use the post-archive recovery below. If both logs exist with a verdict but the required next state is absent, reconstruct it from those exact logs: PASS resumes `complete.log`; WARN/FAIL first reconstructs and, when necessary, completes the reviewer-owned evidence/root-cause/selected-fix packet from those exact logs and current source, then reruns the plan skill in `write` mode with `isolated-reassessment`; a valid user-review gate rerenders `USER_REVIEW.md`. If a prior turn resolved `USER_REVIEW.md` without `complete.log`, resume at the matching finalization step.
- Compare the implementation with the user request and applicable public or internal contract.
- Run the smallest relevant tests when safe and available.
- Add a focused reproducer only when needed to prove a suspected defect.
- Missing copied command output or an unfilled review stub is not a code defect.
- Missing optional live/full-cycle verification is reported as residual risk, not a failed verdict.
- A test is blocking only when it protects security, credentials, data integrity, irreversible external change, or the directly changed behavior cannot otherwise be judged.
## User Review Gate
## Findings
`USER_REVIEW.md` is a loop stop state with exactly one of these types:
Use three severities:
- `milestone-lock`: a concrete selected Milestone `구현 잠금 > 결정 필요` item requires a user decision.
- `external-execution`: required verification needs an exact user-controlled runner, device, credential, interactive session, evidence handoff, or explicit authorization that no currently authorized executor can use.
- `Required`: a concrete correctness, security, data-loss, compatibility, or directly required test defect.
- `Suggested`: a useful improvement that does not block the requested result.
- `Nit`: optional cleanup.
Apply these rules:
Every Required finding includes exact evidence, affected file/line, impact, and one concrete fix. Do not create Required findings for preferred architecture, missing process metadata, unrun optional environments, SDD divergence, or lack of exhaustive evidence.
- Compute `review-number` as `count(agent-task/{task_name}/code_review_*.log) + 1` before archiving the active review.
- Repeated `WARN`/`FAIL`, loop exhaustion, missing verification evidence, and a transient test failure do not trigger `USER_REVIEW.md` by themselves.
- For `milestone-lock`, resolve the selected Milestone from the first path segment of the task header (`m-<milestone-slug>`) or another exact active Milestone path already fixed by the task. Read its current `구현 잠금 > 결정 필요` items and require one exact unresolved decision that blocks the next safe implementation step.
- For `external-execution`, first resolve the repository-declared runner, transport, workdir, credentials source, and safe read-only preflight. Use an already authorized configured executor, including SSH or another declared remote runner, when it can perform the step. A current-host OS mismatch, missing local command, closed current-host localhost port, agent execution limit, or incomplete evidence is not enough while such an executor remains usable.
- Trigger `external-execution` only when the required target and attempted routing/preflight are concrete, the next verification step is required for the verdict, no authorized automatic route can perform it, and progress requires a user to grant access or authorization, prepare or operate a user-controlled environment, or supply the required evidence. Do not create another follow-up PLAN that repeats the same inaccessible preflight.
- Generic scope conflict, missing optional handoff evidence, arbitrary `상태` text, and repository-fixable setup remain normal WARN/FAIL follow-up inputs.
- Create `USER_REVIEW.md` from `agent-ops/skills/common/code-review/templates/user-review-template.md`. Fill the archived loop history, current archived plan/review paths, verdict, loop count, blocking evidence, exact target, one gate type, required user action or decision, and resume condition.
## Verdict
## User Review Resolution
- `PASS`: no Required findings.
- `FAIL`: one or more Required findings.
- `WARN`: use only when the user or existing task protocol requires a middle state; Suggested findings alone may still PASS with residual suggestions.
When an active `USER_REVIEW.md` exists and its recorded user action or decision closes the task as complete/PASS, finalization is still owned by this skill.
Append a short result to the active review file when one exists. Otherwise report findings directly in chat.
- Read `USER_REVIEW.md`, archived `plan_*.log`, and archived `code_review_*.log` in that task directory.
- Verify the recorded action or decision and any follow-up evidence are sufficient to close the task. For `external-execution`, access or authorization that merely enables verification normally resumes through a new plan; user-supplied final evidence may close the task only when it satisfies the archived acceptance criteria. If a new implementation or verification plan is needed, do not close; route back to the plan skill, which archives `USER_REVIEW.md` to `user_review_N.log` before writing a new plan.
- Update `USER_REVIEW.md` in place to show a resolved state, final verdict, loop history, fulfilled user actions or decisions, and the evidence that closed the stop state.
- Write `complete.log` from `agent-ops/skills/common/code-review/templates/complete-log-template.md` before moving or archiving the task artifacts. Include both the original archived review verdict and the user-review resolution line in `루프 이력`.
- Then apply the same task-directory archive move and `m-<milestone-slug>` PASS completion metadata rules as a normal `PASS`.
- Do not leave an active task directory that contains `USER_REVIEW.md` and `*.log` files but no `complete.log` after the recorded action or decision resolves the task as complete/PASS.
## After the verdict
## Workflow Contract
- `PASS`: report completion and the tests actually run. Archive task artifacts or write `complete.log` only when the user explicitly requested task-loop finalization.
- `FAIL`: report the minimal fixes. Do not automatically invoke `plan`, `finalize-task-routing`, `sync-milestone-workstate`, or `update-roadmap`.
- Ask the user directly only when a product decision or new authorization is truly required. Do not create `USER_REVIEW.md` as a stop-state unless the user explicitly asks for a file-based handoff.
- `milestone-task`, SDD Evidence Map, and `Roadmap Completion` metadata may help identify scope but are not verdict gates.
Active work must live under an active task directory using routed filenames. This is the state protocol shared with the plan skill.
## Optional task finalization
Task path terms:
When the user explicitly asks to finalize an active task after PASS:
- `{task_group}` is the top-level work category under `agent-task/`. Normal task groups use a short snake_case name such as `refactoring`.
- Milestone-linked work uses the reserved task group form `m-<milestone-slug>`, where `<milestone-slug>` is the active Milestone filename without `.md`.
- `{subtask_dir}` is used only for split work and follows the indexed directory naming contract, such as `01_core` or `02+01_db`.
- `{subtask_name}` is the short snake_case name after the index or dependency prefix inside `{subtask_dir}`.
- `{task_name}` in headers and templates means the active task path relative to `agent-task/`: either `{task_group}` for a single-plan task or `{task_group}/{subtask_dir}` for a split subtask.
- A single-plan task stores active files directly under `agent-task/{task_group}/`.
- Split work stores active files under `agent-task/{task_group}/{subtask_dir}/`; the parent `agent-task/{task_group}/` is only the grouping folder and must not contain active plan/review files.
1. Preserve the active plan and review as logs using the existing naming convention.
2. Write a concise `complete.log` from the template.
3. Move the completed task to the existing archive path without overwriting data.
4. Report exact Milestone/Task metadata if present; do not require it.
Filename rules:
## Quality rules
- Plan file: `PLAN-{build_lane}-GNN.md`
- Review file: `CODE_REVIEW-{review_lane}-GNN.md`
- `{lane}` is only `local` or `cloud`; never put model names in filenames.
- `GNN` is a two-digit capability grade from `G01` to `G10`; runtime maps lane+grade to current models externally.
- This skill reads the active routed names but does not choose follow-up lane/G. Follow-up basenames come only from `plan` executing `finalize-task-routing`.
Multi-plan runtime contract:
- Multi-plan work is represented as multiple subtask directories under one shared `{task_group}`. Each subtask directory owns exactly one normal active plan file and one normal active review file.
- Multi-plan subtask directory names encode runtime scheduling metadata:
- `NN_{subtask_name}` has no runtime dependencies.
- `NN+PP[,QQ...]_{subtask_name}` depends on the listed earlier task indices.
- Subtask directory names are the runtime dependency source of truth. Preserve them verbatim; do not normalize, reinterpret, infer extra dependencies from numeric order, or choose execution order by agent judgment.
- If the user/runtime names a task group, task path, or subtask directory that identifies exactly one active review file, review that directory even when other active review files exist.
Milestone task group contract:
- `agent-task/m-<milestone-slug>/` is reserved for Milestone-linked work created by the plan skill.
- Do not treat normal task groups that do not start with `m-` as runtime milestone completion targets.
- For a selected task path, parse only the first path segment as `{task_group}`. If it matches `^m-[a-z0-9][a-z0-9-]*$`, strip `m-` to get `<milestone-slug>`.
- Do not modify `agent-roadmap/**` for milestone routing during code-review finalization. Resolve the active Milestone from the `m-<milestone-slug>` task group and read its SDD path only when needed to verify the first-line `milestone-task` ids against the SDD Evidence Map.
- Do not call `update-roadmap` from this skill. The runtime consumes the PASS completion event and invokes `sync-milestone-workstate`, which aggregates all same-group `complete.log` evidence before changing a Task checkbox.
- For `m-<milestone-slug>` PASS tasks, report the original active task path, final archive path, complete log path, task group, milestone slug, and `milestone-task` ids so the runtime has deterministic aggregation inputs.
Follow-up routing boundary:
- This skill records current source, actual verification output, and findings, but it must not estimate or recommend the next lane/G.
- Decide each Required/Suggested disposition here and validate it directly; dispatcher use is optional. Default repository-fixable work to `direct-fix`, expanding stale exclusions when required by original acceptance. Allow `verified-dependency` only with the exact PLAN/task ordering proof, or `complete.log` plus fresh proof that the precondition is satisfied; vague owners and `complete.log` alone are invalid. Set `ownership_closed=true` only after every id has that proof.
- Never send an unchanged-precondition verification packet. For an unordered dependency, keep the verdict pair and return `status=blocked`, `blocked_reason=dependency-wait`, `next-task`, and resume condition; do not redispatch it or request user review.
- On WARN/FAIL, invoke the plan skill in `prepare-follow-up` mode with the selected task path and closed reviewer-owned evidence/root-cause/selected-fix packet before archiving the current pair.
- Do not pass the archived lane, grade, routing score, rationale, or filename as plan-routing input. Archive paths remain evidence pointers, and actual logs/findings remain raw evidence.
- The plan skill must validate and materialize the reviewer-owned root cause, selected fix, scope, evidence, and acceptance commands, then complete mandatory `finalize-task-routing` before it writes the next pair. It must not reopen diagnosis or solution selection. Code-review must not create a routed follow-up pair directly.
- Repair non-behavioral review artifact drift during review instead of failing solely for it when implementation correctness, tests, and contracts remain judgeable.
Directory states:
| State | Meaning |
|-------|---------|
| `PLAN-*-G??.md` + wholly unfilled `CODE_REVIEW-*-G??.md` stub/placeholders and no implementation-readiness evidence | Implementation was not submitted for review and is not judgeable. Do not use this state for an implemented change whose recorded verification output alone is incomplete; the reviewer verifies that change directly. |
| `PLAN-*-G??.md` + filled `CODE_REVIEW-*-G??.md` without verdict | Ready for code-review skill |
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` with appended verdict | Review finalization pending or `dependency-wait`; do not append another verdict. Resume Step 5 immediately for unfinished finalization, or only after the recorded dependency changes for a wait. |
| Exactly one active pair member + its newly archived counterpart | Partial archive after a preflighted finalization; verify both identities, finish the remaining archive, then resume post-archive recovery |
| `complete.log` + `*.log` files | Task complete (PASS or user-review-resolved PASS), before final task-directory archive move |
| `USER_REVIEW.md` + `*.log` files | Automatic loop stopped; its recorded Milestone decision or external-execution user action must be resolved before creating another plan |
| `agent-task/archive/YYYY/MM/{task_name}/complete.log` + `*.log` files | Archived completed task path (PASS or user-review-resolved PASS); not active |
| Only `*.log` files (no `complete.log`) | If the newest review log has a verdict and its required next state is absent, post-archive finalization is pending; otherwise the task is terminated mid-loop or abandoned |
The implementing agent never archives or deletes active files; archiving is this skill's responsibility.
## Step 1 - Find Active Task
Find active review files with both globs, excluding `agent-task/archive/**`:
- `agent-task/*/CODE_REVIEW-*-G??.md`
- `agent-task/*/*/CODE_REVIEW-*-G??.md`
Also note active user-review stops, excluding `agent-task/archive/**`:
- `agent-task/*/USER_REVIEW.md`
- `agent-task/*/*/USER_REVIEW.md`
Classify the combined set of active `CODE_REVIEW-*-G??.md` and `USER_REVIEW.md` paths. Apply the first matching row:
| Result | Action |
|--------|--------|
| Exactly one active path and it is `CODE_REVIEW-*-G??.md` | Review that task; exactly one `PLAN-*-G??.md` is normally expected beside it. If the review already has a verdict and its exact plan counterpart was just archived, use partial-archive recovery instead of reporting a missing plan. |
| Exactly one active path and it is `USER_REVIEW.md`, with a recorded user action/decision resolution | Perform User Review Resolution for that task. |
| One or more active paths and every active path is `USER_REVIEW.md`, with no action/decision resolution | Report the required user action or decision and list the paths. |
| No active paths | Apply the finalization-recovery scan below; stop only when it finds no recoverable task. |
| Multiple active paths | If the user/runtime named a task group, task path, or subtask directory that identifies exactly one active path, use that directory. Otherwise list paths and stop with an ambiguity report; do not choose by agent judgment and do not create a user-review request for routing ambiguity. |
If a selected task directory contains both `USER_REVIEW.md` and active `PLAN-*-G??.md` or `CODE_REVIEW-*-G??.md`, report an inconsistent loop state instead of overwriting either state.
Finalization-recovery scan, excluding `agent-task/archive/**`:
- Candidate A has exactly one active plan, no active review/USER_REVIEW/complete.log, and a newest review log whose verdict belongs to that plan's current loop.
- Candidate B has no active plan/review/USER_REVIEW/complete.log, and its newest plan/review logs form one loop whose review verdict requires a missing next state.
- Accept only candidates whose exact source/archive identities and verdict can be proven from headers, log suffixes, and review contents. Do not treat a generic log-only abandoned directory as recoverable.
- If the user/runtime names one candidate task path, resume it. Otherwise resume only when exactly one candidate exists; list multiple candidates as ambiguity. Use the Core Loop Rules recovery path and never append a second verdict.
## Step 2 - Load Context
Count `agent-task/{task_name}/code_review_*.log` in the selected active task directory:
- `0`: first review. Read the active review file, active plan file, every planned source file, related tests, and files importing/imported by changed files up to 2 levels deep.
- `>=1`: follow-up review. Start with `git diff`, `git diff --cached`, and `git log --oneline -5`, then expand to related callers, implementers, tests, and any planned files missing from the diff.
The diff is the starting point, not the boundary. Follow behavior and API connections far enough to judge correctness.
Review scope control:
- Use the plan's commands and checkpoints as the primary evidence. Add one focused, possibly table-driven reproducer only when needed to prove a suspected blocking defect; do not build speculative exhaustive probe matrices.
- **NO OVERENGINEERING** — Do not require or propose anything beyond the user request and correctness.
- Execute the applicable plan verification commands and any focused reproducer needed for the verdict. Treat implementation-owned output as a handoff and comparison source, not as a substitute for fresh reviewer verification. If recorded output is absent or insufficient but the command is available and safe in the current authorized environment, run it and repair `Verification Results` before classifying findings. If a check fails, collect enough source/runtime data to establish the root cause and one implementable fix; never emit a diagnostic-only finding that asks the next worker to investigate or choose among alternatives.
- In a follow-up review, keep Required findings within the current plan, inherited Required findings, direct regressions from the fix, and concrete violations of the original SDD or contract acceptance criteria. Exclude unrelated pre-existing work from the verdict and Required/Suggested/Nit counts; mention it only in the final report as an out-of-scope task candidate.
- Before adding a new Required that the current plan did not state, cite the exact original plan/SDD/contract criterion it violates or provide a concrete failing case. Do not require a preferred test shape when existing deterministic evidence proves the same behavior.
- When one invariant fails in multiple already-observed variants, report that known set together instead of revealing one variant per follow-up.
## Step 3 - Pre-Review Checklist
Before writing the verdict:
- Compare actual source files against every planned checklist item.
- Compare the plan `Implementation Checklist` and review stub `Implementation Checklist` (legacy: `구현 체크리스트`); repair non-behavioral drift when implementation remains judgeable.
- When the active artifacts use an `m-*` task header, require identical non-empty `milestone-task` ids in PLAN and CODE_REVIEW, resolve the active Milestone by slug, and verify every id exists. If the Milestone has `SDD: 필요`, read only that Milestone and its SDD, compare the implementation and fresh reviewer verification against the SDD Acceptance Scenarios/Evidence Map for those ids. Missing implementation-recorded evidence alone is not a finding; obtain it directly when an authorized runner is available.
- Directly repair obvious non-behavioral source nits when safe: typos, stale comments, docs, or formatting only, with no behavior/test/API contract change.
- If a checklist item contains integrated verification for a feature, run its applicable verification before the verdict. When the implementation exists and fresh verification passes, fill or correct the matching output and checklist state instead of treating the missing handoff evidence as incomplete implementation. Do not accept a separate unchecked completion-criteria item as a substitute.
- Confirm the implementation marked the matching checklist items in the active review file, including the mandatory `CODE_REVIEW-*-G??.md` evidence item; repair clear artifact drift when evidence supports completion.
- Repair review artifact gaps from fresh reviewer evidence. Treat a gap as a finding only when it is itself a required durable deliverable or remains impossible to reconstruct after the reviewer exhausts every safe, authorized repository-declared verification route.
- Treat every generic `상태` field and implementation blocker record as ordinary evidence, never as a request to stop for the user. Evaluate both user-review gate types independently only after a WARN/FAIL finding requires a next state.
- Grep renamed/removed symbols for stale references.
- Confirm every required test exists, name matches, and assertions are meaningful.
- Cross-check claimed verification output in the active review file against actual code and project commands.
- For follow-up reviews, compare diff against the plan and scan for unplanned changes, debug prints, dead code, TODOs, formatting-only noise, and unrelated edits.
## Step 4 - Append Verdict
Append the review result to the active `CODE_REVIEW-*-G??.md`. For a canonical English review file, append `## Code Review Result`. For a legacy active review file using Korean headings, append `## 코드리뷰 결과` using Korean field labels to preserve schema compatibility for running legacy dispatchers.
Required fields for canonical English active pairs:
- `Overall Verdict`: exactly `PASS`, `WARN`, or `FAIL`.
- `Dimension Assessment`: Pass/Warn/Fail for correctness, completeness, test coverage, API contract, code quality, implementation deviation, verification trust. If SDD Evidence Map applies through `milestone-task`, also include spec conformance.
- `Findings`: `None`, or bullets using stable `Required R1`, `Required R2`, `Suggested S1`, or `Suggested S2` ids. Every Required/Suggested finding must contain `Evidence` with the reviewer-run command/observation, `Root Cause` with exact source/runtime ownership, and `Selected Fix` with concrete file/symbol/behavior/test changes. Diagnostic-only findings, unresolved alternatives, and instructions for the worker to investigate are invalid. Nit findings do not need ids. Keep every Required/Suggested id and its reviewer-owned decision unchanged in the follow-up handoff and plan.
- `Routing Signals`: calculate once and append `review_rework_count=<N>` and `evidence_integrity_failure=true|false`. Set rework count to archived same-task `WARN|FAIL` verdicts plus one only when the current verdict is non-PASS. Set integrity failure to true only when a claimed test, command, exit code, or production path is contradicted by fresh reviewer evidence, or required evidence remains unavailable or unverifiable after reviewer-owned verification. Missing implementation-recorded output that the reviewer successfully reconstructs does not set this signal.
- `Next Step`: keep only the matching PASS, WARN/FAIL follow-up, or USER_REVIEW line.
For legacy active pairs, use the equivalent legacy field labels: `종합 판정`, `차원별 평가`, `발견된 문제`, `라우팅 신호`, `다음 단계`.
Do not check archive/next-state items in `Review-Only Checklist` (legacy: `코드리뷰 전용 체크리스트`) during Step 4. Complete the applicable dedicated checklist items in the archived `code_review_*.log` during Step 7, after archive, next-state writes, and PASS task-artifact moves are done.
Severity semantics:
| Verdict | Meaning | Follow-up plan |
|---------|---------|----------------|
| `PASS` | No Required/Suggested issues. Nit-only findings may still PASS. | No |
| `WARN` | One or more Suggested issues, zero Required. | Yes, unless the user-review gate triggers |
| `FAIL` | One or more Required issues. | Yes, unless the user-review gate triggers |
Issue severity:
- `Required`: correctness, API contract, a missing required test implementation, a failing reviewer-run required verification, a plan-completeness issue, or a required durable evidence gap that remains after reviewer-owned verification. Missing or incomplete implementation-recorded verification output alone is not `Required`.
- `Suggested`: useful improvement that should enter the loop but does not block correctness.
- `Nit`: tiny cleanup; directly repair obvious non-behavioral cases when safe, otherwise record without forcing WARN.
Verdict consistency:
- `PASS` requires all dimensions to be Pass and no Required/Suggested issues. Nit-only findings may still PASS only when every dimension remains Pass.
- Any Fail dimension or any Required issue forces `FAIL`.
- Any Warn dimension or any Suggested issue forces `WARN`, unless the only findings are explicitly Nit and every dimension remains Pass.
## Step 5 - Prepare Next State And Archive Active Files
Do not archive WARN/FAIL files until the next-state content is fully prepared in memory.
- `PASS`: no routed follow-up preparation is required.
- `WARN`/`FAIL`: apply the user-review gate before any rename.
- If the gate triggers, render the complete `USER_REVIEW.md` body from `agent-ops/skills/common/code-review/templates/user-review-template.md` in memory.
- Otherwise build the follow-up handoff described below and fully execute `agent-ops/skills/common/plan/SKILL.md` in `prepare-follow-up` mode.
Reuse the routing signals appended in Step 4; do not recount verdict history for routing. Separately count the existing logs once for archive identity: set `current_review_archive_number=count(code_review_*.log)` and `current_plan_archive_number=count(plan_*.log)`, then derive both archive names from the current active files' own lane/grade. These archive values describe the pair being closed, not the next route.
The follow-up handoff contains the selected `{task_name}`, revalidated outcome/acceptance/exclusions, current verdict and stable Required/Suggested ids, reviewer-collected evidence and actual verification output, reviewer-determined root cause, one selected fix with exact files/symbols/behavior/tests, each id's `direct-fix` or `verified-dependency` disposition, acceptance commands, roadmap carryover, routing signals, `REVIEW_<PARENT_TAG>`, and predicted current-pair archive names. Keep current active paths only as evidence pointers. Omit prior lane, grade, routing score, rationale, filename, and preferred next route from routing input. Do not invoke the plan skill until every id has this closed reviewer decision; collect missing data and finish the analysis in the current review pass. The plan may use current archive names only after routing to render `Archive Evidence Snapshot`.
- `prepare-follow-up` must return `status: routed`, the exact routed basenames, `prepared_plan`, `prepared_review`, `plan_number`, `current_plan_archive_name`, `current_plan_archive_number`, `current_review_archive_name`, `current_review_archive_number`, `plan_log_number`, `review_log_number`, and `gitignore_repair_needed`. It must have executed `finalize-task-routing` in `isolated-reassessment` mode.
- Verify that the returned current archive names/numbers equal the values derived before preparation, and that `plan_log_number` / `review_log_number` are the post-archive counts embedded in the new review stub for its future archive.
- Before archiving either active file, inspect `prepared_plan` directly. Require one non-empty `Finding Resolution Map` that maps every Required/Suggested id exactly once and preserves its reviewer-collected evidence, root cause, selected fix, and acceptance commands; every `direct-fix` target appears in `Modified Files Summary`; every `verified-dependency` has the exact task-protocol/current-state proof above; and a planned change or satisfied dependency makes repeated verification meaningful. Reject any plan that asks the worker to diagnose, investigate, choose an approach, or recover evidence the reviewer could collect. Reuse the existing review analysis; do not add a separate model pass.
- If preparation returns `needs_evidence`, collect all named new evidence and rerun after the input changes; never rerun with unchanged evidence. If the evidence cannot be obtained in the current scope, leave the verdict-appended pair in place and report the exact finalization blocker.
- If preparation returns `blocked` or the direct prepared-PLAN check fails, correct the handoff/plan from already collected evidence in the same review pass. If exact new evidence is genuinely required, leave the verdict-appended active PLAN/CODE_REVIEW pair in place, do not check archive/next-state items, and report a resumable internal finalization blocker. A later code-review invocation resumes this step without appending another verdict; this condition is not user review by itself.
- For `dependency-wait`, keep one `### Finalization State` under the verdict with status, next task, resume condition, and checked state. Do no work while unchanged; when satisfied, mark it resolved with evidence and resume without another verdict.
After the required next state is prepared, archive is mandatory for `PASS`, `WARN`, and `FAIL`. Ensure `.gitignore` has the Agent-Ops managed gitignore block for task artifacts before writing `*.log` outputs. Prefer `source agent-ops/bin/ai-ignore.sh && agent_ops_ensure_gitignore_task_artifact_block .gitignore`; if the helper is unavailable, add or update a block containing `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, and `agent-roadmap/current.md`. Apply the repair here when `prepare-follow-up` returned `gitignore_repair_needed: true`.
Preflight both archive operations before either rename:
1. Recount existing `code_review_*.log` as `current_review_archive_number`. Parse the active review's lane/grade from its own basename and derive `current_review_archive_name=code_review_{current_review_lane}_{current_review_grade}_{current_review_archive_number}.log`.
2. Recount existing `plan_*.log` as `current_plan_archive_number`. Parse the active plan's lane/grade from its own basename and derive `current_plan_archive_name=plan_{current_build_lane}_{current_build_grade}_{current_plan_archive_number}.log`.
3. Require both destinations not to exist. When the active stub contains concrete expected archive names, require them to match the derived names; legacy generic placeholders do not override the derived values.
4. For WARN/FAIL, require exact matches with both prepared current archive names/numbers. If any check fails, do not rename either file.
After both operations pass preflight, rename the active review and then the active plan to those exact names. If either current archive count or derived name changed after preparation, discard the prepared pair and rerun plan `prepare-follow-up` before renaming. After archiving, verify that the actual plan/review log counts equal the prepared `plan_log_number` and `review_log_number`; neither active `.md` file remains until Step 6 materializes the prepared next state.
## Step 6 - Post-Review Actions
For `PASS`, write `agent-task/{task_name}/complete.log` before reporting. If a `USER_REVIEW.md` stop is resolved as complete/PASS, write the same `complete.log` before archiving that task.
Complete log template:
- Template path: `agent-ops/skills/common/code-review/templates/complete-log-template.md`
- Copy the template's section order and fill every placeholder from the archived plan/review logs and final verdict.
- Do not leave placeholders in `complete.log`.
- Copy the archived PLAN's exact first-line generation header to the first line of `complete.log`. For `m-*`, this preserves the non-empty `milestone-task` ids; for non-milestone work it preserves the ordinary `task/plan/tag` header.
- If the task did not close through `USER_REVIEW.md`, remove the optional user-review row from the `루프 이력` table.
- Use `없음` for empty `잔여 Nit` or `후속 작업`.
- A PASS `complete.log` must not contain unresolved Required or Suggested issues. Nit-only leftovers may be recorded under `잔여 Nit`.
- The `milestone-task` field is contribution scope, not a completion assertion. Do not write a new `Roadmap Completion` section or claim that any listed Task id is complete merely because this review passed.
For `WARN` or `FAIL`, materialize the next state prepared in Step 5 immediately after archive:
- If the user-review gate triggered, write the prepared body to `agent-task/{task_name}/USER_REVIEW.md`. It must use exactly one supported type, `milestone-lock` or `external-execution`, contain every archived loop entry plus the exact required user action or decision, and contain no placeholder. Do not write active PLAN/CODE_REVIEW files or `complete.log`.
- Otherwise write `prepared_plan` and `prepared_review` byte-for-byte to their routed basenames. Do not rerun, adjust, compare, or upgrade their lane/G after archive.
- Verify the written follow-up pair contains the predicted archived plan/review paths in identical `Archive Evidence Snapshot` sections and contains no unresolved token from the review-stub template inventory. Unrelated braces in commands or code are allowed.
- Read the written PLAN once and confirm byte-for-byte materialization retained the checked `Finding Resolution Map` and `Modified Files Summary` invariants.
- Do not adjust the prepared route after finalization. For a `local-fit` base, `review_rework_count >= 2` or `evidence_integrity_failure=true` must produce `recovery-boundary`; `capability-gap` and `grade-boundary` keep their own basis.
If the task group is `m-<milestone-slug>` and the user-review gate triggered, report that the milestone task is blocked on user review; do not emit PASS completion metadata and do not call `update-roadmap`.
## Step 7 - Complete Review-Only Checklist, Move PASS Task, And Report
After Step 6:
- If verdict is `PASS`, determine archive month from the current completion date as `YYYY/MM`, create the needed archive parent directories, then move the selected task artifacts from `agent-task/{task_name}/` to `agent-task/archive/YYYY/MM/{task_name}/`. For split work, move the selected subtask directory itself and preserve the task group path, e.g. `agent-task/refactoring/01_core/` moves to `agent-task/archive/YYYY/MM/refactoring/01_core/`.
- Do not overwrite an existing archive directory. If `agent-task/archive/YYYY/MM/{task_name}/` already exists, append the next numeric suffix to the final path segment: single-plan `agent-task/archive/YYYY/MM/{task_group}_1/`, split-plan `agent-task/archive/YYYY/MM/{task_group}/{subtask_dir}_1/`, and so on.
- After moving a split subtask, remove the active parent `agent-task/{task_group}/` only when it is empty.
- If verdict is `PASS` and `{task_group}` matches `m-<milestone-slug>`, do not resolve the roadmap target and do not call `update-roadmap`. Report completion event metadata after the task archive move: `origin-task=agent-task/{task_name}` from the original active task path, `task-group={task_group}`, `milestone-slug=<milestone-slug>`, final archive path, `complete.log` path, archived plan/review log paths, and `milestone-task=<ids copied from the header>`.
- The runtime consumes that completion event and invokes `sync-milestone-workstate target-milestone=<milestone-slug> complete-log=<path>`. The sync skill scans every same-group active/archive `complete.log`, aggregates evidence by the listed ids, and checks only Tasks whose full current contract is satisfied.
- `WARN` and `FAIL` do not update the roadmap Milestone; the follow-up plan remains under the same `m-<milestone-slug>` task group when the original task was Milestone-linked.
- `USER_REVIEW` does not update the roadmap Milestone and does not produce PASS completion metadata. Keep the active task directory in place with `USER_REVIEW.md` and archived plan/review logs until its recorded user action or decision is resolved.
- If `USER_REVIEW.md` is later resolved as complete/PASS by the recorded action or decision and evidence, write `complete.log`, move the task artifacts to archive, and report `m-*` PASS completion metadata just like a normal `PASS`.
- For `PASS`, open the moved `agent-task/archive/YYYY/MM/{final_task_name}/{current_review_archive_name}`, where `{final_task_name}` is the archived task path, including `{task_group}/` for split work.
- For user-review-resolved PASS, confirm the moved archive contains the resolved `USER_REVIEW.md`, `complete.log`, and the existing archived `plan_*.log` / `code_review_*.log`; do not recreate an active review file only to add a new checklist item.
- For `WARN` or `FAIL`, open `agent-task/{task_name}/{current_review_archive_name}`.
- Run `git check-ignore -q --` on the generated task artifacts (`plan_*.log`, `code_review_*.log`, `user_review_*.log` when present, `complete.log` when present, and active follow-up `.md` files). If any are ignored, apply the Agent-Ops managed gitignore block and re-check before reporting.
- Check every applicable item in `Review-Only Checklist` (legacy: `코드리뷰 전용 체크리스트`); leave mutually exclusive verdict items unchecked.
- If any applicable item cannot be checked, finish the missing archive, `complete.log`, task-artifact move, mandatory plan-skill follow-up, or `USER_REVIEW.md` write first.
- Do not recreate an active review file just to update this checklist; update the archived `code_review_*.log`.
- Only report after the archived review log has the verdict, applicable checked review-only checklist, required next-state files, for `PASS` or user-review-resolved PASS the final task archive move, for `m-*` PASS tasks the completion event metadata, and for unresolved `USER_REVIEW` the filled `USER_REVIEW.md`.
Report Required/Suggested counts, archive names, the final task archive path for `PASS`, the new plan path for normal `WARN`/`FAIL`, the `USER_REVIEW.md` path for user review stops, and any `m-*` runtime completion event metadata.
## Review Dimensions
| Dimension | Check |
|-----------|-------|
| Correctness | Logic, edge cases, concurrency, errors |
| Completeness | Planned implementation is done; the reviewer runs applicable verification and repairs review artifact drift when judgeable |
| Test coverage | Required tests present and meaningful |
| API contract | Call sites, compatibility, docs |
| Code quality | No debug prints, dead code, leftover TODOs |
| Plan deviation | Deviations justified, no unrelated risk |
| Verification trust | Reported output matches actual code |
## Quality Rules
- Lead with findings; use specific `file:line`.
- Provide a concrete fix for every Required issue.
- Name exact stale symbols or missing tests.
- Do not write vague praise or style opinions without a rule.
- Every dimension gets Pass/Warn/Fail.
- Run applicable required verification before assigning a verdict, and record the fresh command/output in `Verification Results`. Do not forward reviewer-executable evidence collection to another plan.
- For every Required/Suggested finding, close `Evidence`, `Root Cause`, and one `Selected Fix` before invoking the plan skill. The worker implements that decision; it does not perform review analysis or choose the remedy.
- For follow-up plans about verification trust, specify deterministic commands, for example `rg --sort path`, and forbid repo-local tool artifacts.
## Final Checklist
For `status=blocked`, keep the verdict pair and persist/report blocker, next task, and resume condition. Archive/next-state items below wait until it changes; unchanged dependency state triggers no review work.
- `{current_review_archive_name}` exists with the verdict appended and was derived from the archived active review's own route.
- `{current_plan_archive_name}` exists and was derived from the archived active plan's own route.
- Applicable required verification was run by the reviewer and fresh command/output was recorded in `Verification Results`; any unavailable required route was exhausted and classified through the supported blocker/gate rules rather than forwarded as missing implementer evidence.
- `.gitignore` unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores local `agent-roadmap/current.md`; generated task artifacts are not ignored by `git check-ignore`.
- No active `PLAN-*.md`, `CODE_REVIEW-*.md`, or `USER_REVIEW.md` remains after PASS or user-review-resolved PASS.
- PASS or user-review-resolved PASS: `complete.log` written from `agent-ops/skills/common/code-review/templates/complete-log-template.md`, then task artifacts moved under `agent-task/archive/YYYY/MM/` with task-group path preserved for split work.
- PASS milestone task group: `m-<milestone-slug>` completion event metadata was reported for runtime; roadmap was not modified by code-review.
- PASS `complete.log` first line is byte-for-byte identical to the archived PLAN header. An `m-*` log contains non-empty `milestone-task` ids and reports them in completion metadata; a non-milestone log omits the field.
- PASS does not create `Roadmap Completion` or directly check a Milestone Task. Aggregated evaluation is deferred to `sync-milestone-workstate`.
- WARN/FAIL without user-review gate: the plan skill was invoked for the exact task path with verified `review_rework_count` and `evidence_integrity_failure`, completed `finalize-task-routing`, and created new active `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` files matching the fresh routed output; no `complete.log`.
- WARN/FAIL prepared PLAN passed the intrinsic finding-resolution and write-boundary checks before active-pair archive and retained them after byte-for-byte materialization. Invalid resolution or write claims leave the verdict-appended prior pair active.
- WARN/FAIL follow-up: the plan input omitted prior route fields, revalidated outcome/acceptance/exclusions from current evidence, mapped every stable Required/Suggested id to a direct fix or exact verified dependency, used the completed in-memory PLAN as the packet, and copied identical `Archive Evidence Snapshot` sections into the new plan/review pair.
- Follow-up plans and review stubs keep implementation agents limited to implementation/test/evidence and contain no implementation-owned user-review request section.
- USER_REVIEW: `USER_REVIEW.md` exists from template, no active `PLAN-*.md` or `CODE_REVIEW-*.md` remains, and no `complete.log` was written.
- Review-agent-owned USER_REVIEW: the generated `USER_REVIEW.md` records one supported gate type, the exact Milestone decision or external-execution user action, and evidence that made automatic continuation unsafe.
- USER_REVIEW resolved as PASS: archived task contains both resolved `USER_REVIEW.md` and `complete.log`.
- The applicable review-agent-only finalization checklist was completed before reporting.
- Lead with findings ordered by severity.
- Cite exact files and lines.
- Keep unrelated pre-existing issues out of the verdict.
- Do not force a review loop for Suggested or Nit findings.
- Do not add verification or documentation beyond the requested behavior and actual risk.

View file

@ -2,33 +2,9 @@
# Complete - {task_name}
## 완료 일시
{YYYY-MM-DD or ISO-8601}
## 요약
{one-line task summary, loop count, and final verdict; include user-review resolution if applicable}
## 루프 이력
| Plan | Review | Verdict | 메모 |
|------|--------|---------|------|
| `plan_{build_lane}_GNN_N.log` | `code_review_{review_lane}_GNN_N.log` | PASS/WARN/FAIL | {main outcome or follow-up reason} |
| `USER_REVIEW.md` | recorded user action or decision | PASS/RESOLVED | {only when a user-review stop was resolved as the terminal completion path; remove this row otherwise} |
## 구현/정리 내용
- {implemented or cleaned-up change}
## 최종 검증
- `{command}` - {PASS/FAIL/BLOCKED}; {actual output summary or saved output path}
## 잔여 Nit
- 없음
## 후속 작업
- 없음
- 완료 일시: {YYYY-MM-DD or ISO-8601}
- 결과: PASS
- 요약: {one-line task summary}
- 변경: {implemented change}
- 검증: {commands actually run or 미실행과 남은 위험}
- 후속 작업: 없음

View file

@ -1,50 +1,8 @@
# User Review Required - {task_name}
# Decision or Authorization Needed - {task_name}
## Requested At
- 질문 또는 필요한 권한: {one exact item}
- 영향받는 작업: {only the work that directly depends on it}
- 추천안: {default based on current code and request}
- 재개 조건: {one concrete answer or authorization}
{YYYY-MM-DD or ISO-8601}
## Status
USER_REVIEW
## Reason
- Type: {milestone-lock | external-execution}
- Target: {agent-roadmap/phase/<phase>/milestones/<milestone>.md | exact runner/device/service/access target}
- Current review number: {review-number}
- Final verdict: {WARN or FAIL}
- Summary: {why the Milestone decision or user-controlled external execution blocks the next safe step}
## Loop History
| Plan | Review | Verdict | Note |
|------|--------|---------|------|
| `{plan-log-0}` | `{code-review-log-0}` | {PASS/WARN/FAIL/unknown} | {main issue or blocking reason} |
| `{current-archived-plan-log}` | `{current-archived-review-log}` | {WARN/FAIL} | {main issue or blocking reason} |
## Blocking Evidence
- Problem: {review finding summary}
- Current archived plan: `{current-archived-plan-log}`
- Current archived review: `{current-archived-review-log}`
- Verification command: {command or none}
- Actual output: {stdout/stderr excerpt or saved output path}
- Blocking rationale: {evidence matching the Milestone decision | evidence that the declared runner/transport was checked but automatic execution remains unsafe without user action}
## Required User Action
- [ ] {Milestone `구현 잠금 > 결정 필요` item | exact access/authorization/environment/evidence action}
## Resume Condition
- {concrete evidence proving the required action or decision is resolved, plus the next review/plan entry condition}
## Next Execution Hint
- {the correct resolve-review, update-roadmap, or external-verification replan entry point and target path}
## Closure Rules
- If the recorded user action and evidence resolve this stop as complete/PASS, update `USER_REVIEW.md` to the resolved state, write `complete.log` from `agent-ops/skills/common/code-review/templates/complete-log-template.md`, and move the task directory to the archive.
- If new implementation is required, the `plan` skill archives `USER_REVIEW.md` as `user_review_N.log` before writing a new `PLAN-*-G??.md` / `CODE_REVIEW-*-G??.md` pair.
이 문서는 사용자가 파일 기반 handoff를 요청한 경우에만 만든다. 일반 review stop-state나 자동 게이트로 사용하지 않는다.

View file

@ -1,136 +1,47 @@
---
name: complete-milestone
description: "마일스톤 완료해도 될지 검토, 현 마일스톤 종료 검토, 현재 마일스톤 닫고 다음 마일스톤 지정, 검토중 Milestone 코드레벨 종료 감사 요청에 사용한다. 코드/테스트/계약/evidence를 점검하고 작은 보완은 처리하거나 큰 보완은 plan으로 넘기며, agent-spec이 있으면 update-spec을 필수 gate로 수행한 뒤 update-roadmap으로 완료/archive와 다음 Milestone 지정을 처리한다."
description: Check whether one active Milestone's functional Tasks are complete and optionally close and archive it with minimal verification.
---
# complete-milestone
# Complete Milestone
## 목적
## Purpose
`[검토중]` 또는 완료 후보 Milestone을 코드레벨에서 종료해도 되는지 감사하고, 종료 가능할 때 spec sync와 roadmap 완료/archive까지 이어지는 오케스트레이션을 수행한다.
`update-spec``update-roadmap`의 책임을 합치지 않고, 이 스킬이 완료 workflow의 순서와 gate를 관리한다.
Close one Milestone when its promised functional outcome is complete. Completion does not require an intermediate review state, spec sync, SDD approval, implementation lock release, complete-log format, or a full verification matrix.
## 언제 호출할지
## Inputs
- 사용자가 "마일스톤 완료해도 될지 검토해봐"라고 요청할 때
- 사용자가 "현 마일스톤 종료 검토해", "현재 마일스톤 닫고 다음 마일스톤 지정해"라고 요청할 때
- `[검토중]` Milestone의 완료 리뷰 통과, archive, 다음 Milestone current 지정 여부를 코드레벨 evidence로 확인해야 할 때
- Milestone 종료 시점에 `agent-spec` 갱신이 함께 필요할 때
- exact target Milestone, or one unambiguous current candidate;
- `check` or `close` mode;
- optional code, test, commit, task-log, or user evidence;
- optional next Milestone selected by the user.
## 입력
## Procedure
- `target-milestone`: 종료 검토할 Milestone 경로, 이름, slug. 없으면 `agent-roadmap/current.md`의 활성 Milestone 단일 후보를 사용한다. (선택)
- `next-milestone`: 종료 후 `current.md`에 둘 다음 Milestone 후보. 없으면 Phase 흐름에서 자동 후보를 찾되 모호하면 보고한다. (선택)
- `mode`: `check-only` 또는 `close`. 기본값은 `close`다. (선택)
- `evidence`: 완료 판단에 사용할 complete.log, 테스트 결과, 사용자 설명, PR/커밋 등. (선택)
- `verification-context`: 환경, 출처, 명령, 기대 결과, precondition, 제약, gap, confidence를 담은 중립 검증 handoff. 있으면 사용하고 현재 checkout과 다시 대조한다. (선택)
1. Read the target Milestone, Phase, and directly related implementation/tests.
2. Confirm every functional Task is implemented. Run only the smallest validation needed for the changed behavior.
3. Treat optional or unavailable live/full-cycle checks as residual risk unless they protect security, data integrity, irreversible external actions, or are the requested deliverable.
4. In `check` mode, report complete or incomplete without writing.
5. In `close` mode, mark completed Tasks, set the Milestone to `[완료]`, and archive it using the existing roadmap structure.
6. Remove the archived Milestone from active current/queue entries and preserve a short Phase link.
7. Update a matching spec or contract only when the user asked for it or the completion change itself would otherwise leave a false current public contract. Missing optional documentation does not block closure.
8. Set the next Milestone only when the user chose one or there is one unambiguous active candidate.
## 먼저 확인할 것
## Real blockers
- [ ] `agent-roadmap/current.md`와 대상 활성 Milestone, 대상 Phase `PHASE.md`를 읽는다.
- [ ] `agent-roadmap/priority-queue.md`가 있으면 종료 후 다음 후보와 archive 제거 대상 확인을 위해 읽는다.
- [ ] 대상 Milestone의 `상태`, `기능`, `구현 잠금`, `완료 리뷰`, `작업 컨텍스트`, SDD gate를 확인한다.
- [ ] 완료 근거 동기화가 필요하면 `sync-milestone-workstate` 절차를 확인한다.
- [ ] 종료/archive가 가능하면 `update-roadmap` 절차를 확인한다.
- [ ] `agent-spec/`가 있으면 `agent-ops/rules/common/rules-agent-spec.md``update-spec` 절차를 확인한다.
- [ ] 코드, 계약, 테스트에 닿는 범위는 project/domain/test/contract 규칙을 따른다.
- a promised functional Task is not implemented;
- a directly relevant required test fails;
- closing would hide a known security, credential, data-loss, or irreversible-action defect;
- an explicit user-created project dependency is unresolved.
## 실행 절차
No other documentation, approval, review, evidence, environment, or state field blocks completion.
1. **대상 Milestone 확정**
- `target-milestone`이 있으면 활성 Milestone에서 정확히 하나를 찾는다.
- 없으면 `agent-roadmap/current.md`의 활성 Milestone 단일 후보를 사용한다.
- 대상이 archive 경로이거나 둘 이상이면 수정하지 않고 target 불명확으로 보고한다.
## Output
2. **완료 후보 상태 확인**
- 대상 Milestone이 `[검토중]`이면 종료 감사로 진행한다.
- `[진행중]` 또는 `[계획]`이면 `sync-milestone-workstate` 기준으로 기능 Task/evidence를 동기화할 수 있는지 먼저 확인한다. 동기화 후 `[검토중]` 조건을 충족하지 못하면 종료 감사로 진행하지 않는다.
- `[스케치]`, `[보류]`, `[폐기]`, `[완료]`이면 일반 종료 감사를 진행하지 않고 상태 불일치를 보고한다.
- `구현 잠금`이 남아 있거나 미완료 `결정 필요`가 있으면 archive하지 않는다.
Report the target, completed and remaining Tasks, tests actually run, residual risk, archive result, and next Milestone if selected.
3. **코드레벨 종료 감사**
- Milestone `기능` Task와 검증 문구, `완료 리뷰`, complete.log, SDD Evidence Map, 관련 코드/계약/테스트를 비교한다.
- `agent-task/archive/**`는 같은 `m-<milestone-slug>` complete.log 후보처럼 규칙상 허용된 범위만 좁게 읽는다.
- 코드/계약 변경에 닿으면 관련 domain rule과 `agent-contract/index.md` 라우팅을 따른다.
- `verification-context`가 있으면 출처 경로, 명령, 기대 결과, precondition, 제약, gap, confidence가 현재 checkout에 맞는지 확인한다.
- handoff가 없거나 불완전하면 repository manifest, script, workflow, domain rule, 관련 테스트와 안전한 read-only probe에서 부족한 검증 사실을 보완한다. 선택 handoff 누락만으로 종료 검토를 차단하지 않는다.
## Prohibited
4. **보완 분기**
- 작은 문서/코드/테스트 보완으로 바로 해결 가능한 이슈는 직접 수정하고 검증한다.
- Milestone 범위 안의 큰 구현 보완이 필요하면 `plan`을 작성하고 종료를 중단한다.
- 제품/범위/우선순위/책임 경계 결정이 필요하면 Milestone `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리하고 종료를 중단한다.
- 보완이 발생하면 Milestone 완료 리뷰를 `보완 필요`로 남기고 `[완료]` 전환이나 archive를 하지 않는다.
5. **Spec Sync Gate**
- `mode=check-only`이고 `agent-spec/`가 있으면 `update-spec mode=check-only`로 갱신 필요 여부만 확인한다.
- `agent-spec/`가 없으면 `Spec sync: skipped-no-agent-spec`으로 기록하고 종료 흐름을 계속할 수 있다.
- `agent-spec/`가 있고 `mode=close`이면 `update-spec`을 필수로 수행한다.
- 관련 spec이 없고 Milestone 결과가 현재 구현 지도에 영향을 주면 `create-spec` 필요로 보고하고 종료를 중단한다.
- 결과는 반드시 `Spec updated`, `Spec update not needed`, `create-spec needed`, `Spec blocked`, `skipped-no-agent-spec` 중 하나로 정리한다.
- `Spec blocked` 또는 `create-spec needed`이면 Milestone을 `[완료]`로 전환하거나 archive하지 않는다.
- `Spec updated` 또는 `Spec update not needed`이면 Milestone 완료 리뷰에 `Spec sync` 결과와 spec 문서 링크 또는 사유를 남긴다.
6. **Milestone 완료와 archive**
- `mode=check-only`이면 여기서 쓰지 않고 종료 가능 여부만 보고한다.
- 모든 기능 Task, 검증, 구현 잠금, SDD gate, code audit, spec sync gate가 충족되면 `update-roadmap` archive 흐름으로 Milestone을 `[완료]`로 전환하고 archive한다.
- `.agent-roadmap-sync/locks.yaml`이 있으면 `update-roadmap`의 workspace lock 검사/동기화 규칙을 따른다.
- Phase `PHASE.md`에는 archive 링크와 짧은 요약을 남긴다.
- `priority-queue.md`가 있으면 완료/archive된 Milestone 항목을 제거하도록 `update-roadmap` archive 흐름에 포함한다.
- `agent-roadmap/current.md`에서 완료 Milestone을 제거한다.
7. **다음 Milestone 지정**
- `next-milestone`이 있으면 활성 Milestone에서 정확히 하나인지 확인하고 `current.md`에 반영한다.
- 없고 `priority-queue.md`가 있으면 각 prefix의 가장 작은 active index 중 `선행 차단`이 없고, 현재 진행 중인 `동시 차단` target이 없는 lane head를 다음 후보로 찾는다. 여러 후보가 열리면 방금 완료한 prefix의 다음 항목을 우선하고, 없으면 queue group 순서를 tie-breaker로 쓴다.
- `priority-queue.md`가 없으면 같은 Phase의 Milestone 흐름에서 완료/폐기/archive가 아닌 다음 후보를 찾는다.
- 후보가 없거나 둘 이상이면 자동 지정하지 않고 후보와 이유를 보고한다.
- 다음 후보가 `[스케치]`이면 구현 대상이 아니라 구체화 대상임을 보고한다.
8. **결과 보고**
- 종료 가능 여부, 수정/생성한 파일, 실행 검증, spec sync 결과, roadmap archive 결과, 다음 Milestone을 보고한다.
## 실행 결과 검증
- [ ] 대상 Milestone이 활성 경로에서 정확히 하나로 확정되었는가
- [ ] Milestone 상태, 기능 Task, 구현 잠금, 완료 리뷰, SDD gate를 확인했는가
- [ ] 코드/계약/테스트 evidence를 확인했거나 범위 불명확 사유를 보고했는가
- [ ] 전달된 verification context와 repository-native fallback의 출처·gap·confidence를 구분했는가
- [ ] 작은 보완은 검증까지 수행하고, 큰 보완은 plan으로 넘겼는가
- [ ] `agent-spec/`가 있으면 `update-spec` 결과를 확인하고 완료 진행 가능 상태가 `Spec updated` 또는 `Spec update not needed`인지 판단했는가
- [ ] `Spec blocked` 또는 `create-spec needed` 상태에서 Milestone 완료/archive를 하지 않았는가
- [ ] `update-roadmap` 완료/archive 규칙과 workspace lock 규칙을 따랐는가
- [ ] `priority-queue.md`가 있으면 완료/archive된 Milestone과 충족된 blocker 참조가 제거되었고 다음 후보 판단에 prefix index와 차단 예외가 반영되었는가
- [ ] 완료 Milestone이 `current.md`에 남아 있지 않은가
- [ ] 다음 Milestone 지정이 모호하면 자동 선택하지 않았는가
- [ ] `git diff --check`를 실행했는가
- 검증 실패 시: archive 이동을 하지 않고 실패 사유와 필요한 후속 작업을 보고한다.
## 출력 형식
```markdown
## Milestone 종료 검토 결과
- 대상 Milestone: [<title>](agent-roadmap/phase/<phase>/milestones/<milestone>.md)
- 판정: <종료 완료 | 종료 가능-check-only | 보완 필요 | plan 작성 | 차단>
- 코드레벨 감사: <통과 | 보완 내용 | 차단 사유>
- 검증:
- `<command>` - <PASS | FAIL | BLOCKED>; <요약>
- Spec sync: <updated | not-needed | create-spec needed | blocked | skipped-no-agent-spec>
- <[spec](agent-spec/<area>/<spec-id>.md) | 사유>
- Roadmap: <archive 완료 | 변경 없음 | 차단>
- 다음 Milestone: <[title](agent-roadmap/phase/<phase>/milestones/<next>.md) | 미지정: 사유>
- 수정 파일:
- <없음 | [path](path)>
## TODO 항목
- <남은 차단 항목 또는 없음>
```
## 금지 사항
- `update-spec``update-roadmap`의 책임을 이 스킬 본문에 합쳐서 재정의하지 않는다.
- `Spec blocked` 또는 `create-spec needed`인데 Milestone을 `[완료]`로 전환하거나 archive하지 않는다.
- 큰 구현 보완을 종료 검토 중 임의로 처리하지 않는다. `plan`으로 넘긴다.
- archive 전체를 일반 탐색하지 않는다.
- 구현 잠금이나 미해결 SDD 사용자 리뷰가 남은 Milestone을 완료 처리하지 않는다.
- 다음 Milestone 후보가 모호한데 자동으로 선택하지 않는다.
- Do not create a plan automatically for remaining work.
- Do not create USER_REVIEW, SDD, spec, or evidence gates.
- Do not read unrelated archive history.

View file

@ -1,237 +1,52 @@
---
name: create-roadmap
description: AI-first 개인/소규모 프로젝트의 전체 목표, Phase scaffold, Phase 하위 Milestone 문서, 전역 priority-queue.md 실행 순서 문서, 로컬 current.md 활성 Phase/Milestone 창, archive Phase scaffold를 처음 생성할 때 사용한다.
description: Create a minimal roadmap scaffold with goals, Phases, Milestones, Tasks, active candidates, and explicit user-stated dependencies.
---
# 로드맵 생성
# Create Roadmap
## 목적
## Purpose
`agent-roadmap/` 하위에 `Roadmap -> priority-queue -> Phase -> Milestone` 기반 한국어 로드맵 구조를 처음 생성한다.
전체 로드맵은 전체 방향과 Phase index만 담당하고, 일반 작업에서는 브랜치별 로컬 `current.md`의 활성 Phase/Milestone 링크와 관련 문서만 읽도록 만든다.
`priority-queue.md`는 Phase를 가로지르는 prefix별 실행 순서와 막히는 지점의 차단 예외만 담당한다.
Milestone은 구현 계획이 아니라 방향성, 범위, 위험, 확인 필요 사항을 기록하는 협업 문서다.
Epic과 Task는 별도 파일로 분리하지 않고 Milestone 문서의 `기능` 안에서 관리한다. 별도 `완료 기준` 섹션은 만들지 않고, 검증이 필요한 기능에만 같은 Task 안의 `검증:` 문구로 통합한다.
Create `agent-roadmap/` as a lightweight long-term map. The primary direction is **verification gate minimization**: roadmap creation must not introduce implementation locks, approval chains, mandatory SDDs, consistency preflights, or evidence-format gates.
## 언제 호출할지
## Structure
- 프로젝트에 파일 기반 로드맵을 처음 만들 때
- 사용자가 "로드맵 만들어줘", "마일스톤 설계해줘", "goal/phase 구조 잡아줘"라고 요청할 때
- 기존 README나 메모에 흩어진 계획을 `agent-roadmap/` 구조로 분리할 때
- `ROADMAP.md`: overall goal and Phase links.
- `priority-queue.md`: lane order and only explicit user-stated blockers.
- `current.md`: local active Phase and Milestone candidates.
- `phase/<phase>/PHASE.md`: one Phase goal and Milestone links.
- `phase/<phase>/milestones/<milestone>.md`: goal, state, optional promotion notes, decisions, optional design references, scope, functional Tasks, exclusions, and context.
- `sdd/.../SDD.md`: optional design reference only when requested or materially useful.
- `archive/...`: completed or discarded snapshots.
## 입력
## Rules
- `overall-goal`: 프로젝트 전체 목표 한 줄 또는 짧은 문단 (선택, 없으면 README와 현재 구조에서 추론)
- `phase-hints`: 예상 Phase 목록 또는 단계 힌트 (선택)
- `milestone-hints`: 예상 Milestone 목록 또는 기능 힌트 (선택)
- `active-phases`: 현재 열어둘 Phase 목록 (선택, 없으면 현재 구현 상태와 요청에서 추론)
- `active-milestones`: 현재 열어둘 Milestone 목록 (선택, 없으면 현재 구현 상태와 요청에서 추론)
- Use the smallest number of Phases and Milestones that explains the actual work.
- Prefer existing project terminology.
- Use `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, or `[폐기]`.
- A sketch records unclear scope; it is not an approval gate.
- Record only directly required user-owned product decisions under `결정 사항`.
- Create an SDD only when the user asks or a large contract/lifecycle change benefits materially from one. SDD status never blocks implementation.
- Create a queue blocker or workspace lock only for a dependency explicitly stated by the user.
- Functional verification belongs on the relevant Task only when actually needed.
- `[검토중]` is optional; a completed Milestone may move directly to `[완료]`.
## 생성 구조
## Procedure
```text
agent-roadmap/
ROADMAP.md
priority-queue.md
current.md # local, git ignored
phase/
<phase-slug>/
PHASE.md
milestones/
<milestone-slug>.md
sdd/
<phase-slug>/
<milestone-slug>/
SDD.md
USER_REVIEW.md
archive/
phase/
<phase-slug>/
PHASE.md
milestones/
<milestone-slug>.md
sdd/
<phase-slug>/
<milestone-slug>/
SDD.md
```
1. Confirm that an existing roadmap will not be overwritten.
2. Read the project overview and inspect only the top-level structure needed to identify domains.
3. Create the smallest Phase → Milestone → Epic → Task hierarchy.
4. Create active current links and a minimal queue.
5. Add optional design references and explicit dependencies only when justified above.
6. Validate links, ids, status values, and `git diff --check`.
| 파일 | 역할 |
|------|------|
| `agent-roadmap/ROADMAP.md` | 전체 목표와 Phase 흐름만 담는 최상위 지도. 로드맵 생성/갱신/Phase 전환 때만 읽는다 |
| `agent-roadmap/priority-queue.md` | Phase를 가로지르는 prefix별 Milestone 순서, 설명, 차단 예외를 담는 실행 순서 문서 |
| `agent-roadmap/current.md` | 활성 Phase와 활성 Milestone 후보, 선택 규칙을 담는 브랜치별 로컬 포인터 |
| `agent-roadmap/phase/<phase-slug>/PHASE.md` | Phase 목표, 상태, Milestone 흐름, Phase 경계를 담는 문서 |
| `agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md` | 일반 작업 시 읽는 Milestone 단위 목표, 스케치 승격 조건, 구현 잠금, 범위, 기능 Epic/Task 체크리스트, 범위 제외 항목 |
| `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md` | 큰 Milestone의 source of truth, 상태 전이, interface, acceptance scenario, evidence map을 담는 설계 게이트 |
| `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md` | SDD에서 에이전트가 확정할 수 없는 결정 항목이 있을 때 열리는 파일 기반 리뷰 gate |
| `agent-roadmap/archive/phase/<phase-slug>/...` | 완료 또는 폐기되어 현재 후보에서 제외한 과거 Phase/Milestone. 일반 작업에서는 읽지 않는다 |
| `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/...` | 완료 또는 폐기된 Milestone의 SDD 스냅샷과 해결된 사용자 리뷰 로그 |
## Prohibited
## 템플릿
- Do not create `구현 잠금`, SDD lock, approval checklist, USER_REVIEW gate, mandatory preflight, Evidence Map requirement, or spec-sync gate.
- Do not create documents or empty sections solely to satisfy a template.
- Do not infer dependencies or execution blockers.
- Do not overwrite an existing roadmap; use `update-roadmap` instead.
- `ROADMAP.md``agent-ops/skills/common/_templates/roadmap-template.md` 형식을 따른다.
- `priority-queue.md``agent-ops/skills/common/_templates/roadmap-priority-queue-template.md` 형식을 따른다.
- `current.md``agent-ops/skills/common/_templates/roadmap-current-template.md` 형식을 따른다.
- `PHASE.md``agent-ops/skills/common/_templates/roadmap-phase-template.md` 형식을 따른다.
- Milestone 문서는 `agent-ops/skills/common/_templates/roadmap-milestone-template.md` 형식을 따른다.
- SDD 본문은 `agent-ops/skills/common/_templates/roadmap-sdd-template.md` 형식을 따른다.
- SDD 사용자 리뷰는 `agent-ops/skills/common/_templates/roadmap-sdd-user-review-template.md` 형식을 따른다.
- `ROADMAP.md`에는 Milestone 상세 체크리스트를 넣지 않는다.
- `priority-queue.md``[prefix-NN]` 제목 링크, 1~2문장 설명, 필요한 `선행 차단`/`동시 차단`만 둔다.
- `current.md`는 git 추적 대상이 아니며, 예시 파일을 `agent-roadmap/`에 따로 만들지 않는다.
- `current.md`는 활성 Phase/Milestone 후보만 담고, 개인별 현재 작업 위치나 완료 상태를 적지 않는다.
- archive 경로는 `current.md`의 활성 항목에 넣지 않는다.
## Output
## 작성 규칙
- **NO OVERENGINEERING** — Do not add anything beyond the user request and required behavior.
- 기본 작성 언어는 한국어다.
- 상태 표기는 `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
- `[스케치]`는 방향성, 문제의식, 후보 범위, 미정 질문을 기록하는 컨셉 상태다. 구현 가능한 계획이 아니므로 구현 계획 생성 대상이 아니다.
- `[계획]`은 목표, 범위, 기능 Task, 구현 잠금, 결정 필요 항목이 문서화되어 잠금 해제 후 구현 계획을 만들 수 있는 상태다.
- Phase 이름과 파일명, Milestone 파일명에는 `1`, `2`, `M01`, `P1` 같은 순번을 붙이지 않는다. Milestone 표시 제목에는 실행 태그 `[prefix-NN]`을 반드시 붙인다.
- Phase 흐름은 실행 순서가 아니라 도메인/책임 영역의 구조적 지도다.
- Phase를 가로지르는 실제 실행 순서는 `priority-queue.md`의 prefix 그룹과 두 자리 index로 표현한다. 같은 prefix는 작은 index부터 순차 실행하고, 다른 prefix는 차단 표기가 없으면 병렬 실행할 수 있다.
- `priority-queue.md`에는 상태, 목표, 범위, 잠금, 기능, 완료 근거를 복제하지 않는다. 설명은 생략하지 않고, 일반 순서로 표현할 수 없는 차단 예외만 exact blocker label로 둔다.
- 실행 후보가 없더라도 `priority-queue.md` 파일과 `실행 순서` 섹션은 생성한다.
- Phase 파일명은 `agent-roadmap/phase/<phase-slug>/PHASE.md`로 만든다.
- Milestone 파일명은 `agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`로 만든다.
- `<phase-slug>``<milestone-slug>`는 소문자 영문, 숫자, 하이픈만 사용하고, 공백/언더스코어/순번 prefix를 넣지 않는다.
- 중간에 Phase나 Milestone을 끼워 넣을 수 있도록 기존 항목의 이름과 파일명을 불필요하게 바꾸지 않는다.
- 실행 태그는 `^[a-z][a-z0-9-]*-[0-9]{2}$` 형태로 만들고 프로젝트 안에서 유일하게 유지한다. 같은 작업 lane은 같은 prefix로 묶고, 관련성만 있고 순차 관계가 없으면 다른 prefix를 사용한다.
- 실행 태그 재배치가 필요하면 파일명은 유지하고 Milestone H1, `PHASE.md`, 로컬 `current.md`, `priority-queue.md`와 queue blocker 참조만 함께 바꾼다.
- 로드맵 문서 안에서 다른 로드맵 문서, SDD, `USER_REVIEW.md`, archive 문서를 가리킬 때는 raw path만 쓰지 말고 `[표시 제목](상대경로)` Markdown 링크로 쓴다.
- 문서 안의 링크 target은 링크를 작성하는 Markdown 파일 위치 기준 상대경로로 쓴다. 예: `ROADMAP.md``current.md`에서는 `[PHASE.md](phase/<phase-slug>/PHASE.md)`, Phase 문서에서는 `[Milestone](milestones/<milestone-slug>.md)`, Milestone 문서에서는 `[ROADMAP.md](../../../ROADMAP.md)``[PHASE.md](../PHASE.md)`를 쓴다.
- `경로:`, `Phase:`, `Milestone:`, `SDD 문서:` 같은 필드명을 유지해야 해도 값은 `경로: [PHASE.md](phase/<phase-slug>/PHASE.md)`처럼 링크로 작성한다.
- 실제 생성한 로드맵 문서에는 `<phase-slug>`, `<milestone-slug>`, `<relative-...>` 같은 placeholder가 들어간 링크 target을 남기지 않는다. 템플릿 placeholder는 실제 파일 위치 기준 상대경로 또는 `없음`으로 치환한다.
- 코드 경로, 명령 입력, `.agent-roadmap-sync/locks.yaml`의 machine-readable identity는 raw 값이 필요하면 유지할 수 있지만, 사용자에게 보여주는 문서 포인터에는 Markdown 링크를 함께 둔다.
## Milestone 작성 규칙
- Milestone 기본 섹션은 `위치`, `목표`, `상태`, `구현 잠금`, `범위`, `기능`, `완료 리뷰`, `범위 제외`, `작업 컨텍스트`다.
- Milestone H1은 `# Milestone: [prefix-NN] <Milestone 이름>` 형식으로 작성한다. scheduling 관계는 `priority-queue.md`를 원본으로 두고 Milestone `작업 컨텍스트`에는 queue 링크만 둔다.
- `승격 조건``[스케치]` Milestone에서 필수다. `[계획]` 이상 상태에서는 섹션을 생략하거나 `- 없음`으로 둘 수 있다.
- `[스케치]` Milestone은 `승격 조건`을 체크리스트로 작성하고, `[계획]`으로 전환하기 위해 필요한 정의, 결정, 경계, 후속 구현 Milestone 후보를 적는다.
- 새 Milestone은 에이전트가 확정할 수 없는 제품 방향, 범위, 우선순위, 책임 경계가 남아 있으면 `구현 잠금``잠금`으로 둔다.
- 새 `[스케치]` Milestone은 `구현 잠금``잠금`으로 둔다.
- Milestone 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `해제`로 둔다.
- `구현 잠금`에는 상태, SDD 필요 여부, 잠금 해제 조건, `결정 필요` 체크리스트를 적는다. 결정할 항목이 없으면 `결정 필요: 없음`으로 적는다.
- SDD가 필요한 기준: cross-repo 계약, 외부 provider 쓰기, 상태 머신/lifecycle, idempotency/retry/identity map, API/proto/config/env/schema 변경, field smoke, 사용자 승인 gate 영향.
- SDD가 불필요한 기준: 단일 repo 내부의 작은 리팩터링, 문서 정리, 테스트 보강, 작은 UI 보강, Milestone Task `검증:`만으로 닫히는 작업.
- SDD가 필요한 Milestone은 `SDD 문서` 값을 해당 Milestone 파일 위치 기준 `[SDD.md](../../../sdd/<phase-slug>/<milestone-slug>/SDD.md)` Markdown 링크로 적고, SDD 잠금이 해제될 때까지 `구현 잠금``잠금`으로 둔다.
- 로드맵 생성 흐름에서 SDD가 필요한 신규 Milestone은 SDD 문서 링크만 남기지 않고 해당 파일에 SDD 초안을 만든다.
- 새 Milestone이 다른 프로젝트 Milestone 완료 전까지 잠겨야 하면 `구현 잠금``잠금`으로 두고 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`에 entry를 만든다. 의존 대상 확정과 entry 형식은 `update-roadmap`의 프로젝트 간 잠금 규칙을 따른다.
- `기능`은 Epic heading과 Task 체크리스트로 작성한다.
- Epic heading은 `### Epic: [epic-id] <이름>` 형식으로 작성한다.
- 각 Epic에는 기능 Task를 최대 5개만 둔다. 5개를 초과하는 Task는 허용하지 않는다.
- 여섯 번째 Task가 필요하면 capability, 산출물, 의존성, 검증 경계 중 하나로 기존 Epic을 둘 이상으로 분리한다. 분리 후에도 독립 목표가 남으면 새 Milestone 후보로 둔다.
- Task는 `- [ ] [item-id] 설명` 형식으로 작성한다.
- epic-id와 item-id는 공백 없는 짧은 ASCII 토큰이며, 해당 Milestone 안에서만 유일하면 된다.
- 검증이 필요한 Task에만 같은 항목 안에 `검증: <명령/확인 방법/기대 결과>`를 붙인다. 검증이 필요 없는 기능에는 억지 검증을 붙이지 않는다.
- `완료 리뷰`는 새 Milestone에서는 `상태: 없음`, `요청일: 없음`으로 두고, 모든 기능 Task와 Task 안에 명시된 검증이 충족되고 `구현 잠금`이 해제된 뒤 에이전트/런타임 완료 근거를 기록할 때 갱신한다. 에이전트가 확정할 수 없는 결정 항목은 완료 리뷰가 아니라 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- `범위`, `범위 제외`, `작업 컨텍스트`는 설명 목록으로 작성하고, 실행해야 할 작업을 이 섹션에 숨기지 않는다.
## 먼저 확인할 것
- [ ] `agent-roadmap/ROADMAP.md` 또는 로컬 `agent-roadmap/current.md`가 이미 존재하는지 확인
- [ ] 이미 존재하면 덮어쓰지 말고 `update-roadmap` 스킬 사용을 안내
- [ ] `README.md`, `agent-ops/GUIDE.md`, `agent-ops/rules/project/rules.md` 등 프로젝트 방향을 설명하는 문서를 확인
- [ ] `rg --files`로 현재 프로젝트의 주요 구조를 가볍게 확인
- [ ] `roadmap-template.md`, `roadmap-priority-queue-template.md`, `roadmap-current-template.md`, `roadmap-phase-template.md`, `roadmap-milestone-template.md`를 읽어 최신 형식 확인
- [ ] SDD가 필요한 Milestone 후보가 있으면 `agent-ops/skills/common/roadmap-sdd/SKILL.md`, `roadmap-sdd-template.md`, `roadmap-sdd-user-review-template.md`를 읽어 최신 절차와 형식 확인
- [ ] `agent-ops/rules/common/rules.md`가 로드맵 디렉터리 존재 시 `agent-ops/rules/common/rules-roadmap.md`를 읽도록 라우팅하는지 확인
## 실행 절차
1. **기존 로드맵 확인**
- `agent-roadmap/` 하위 기존 파일 존재 여부를 확인한다.
- 기존 로드맵이 있으면 새로 만들지 않고 `update-roadmap`을 사용하도록 안내한다.
2. **프로젝트 방향 분석**
- README와 프로젝트 규칙에서 대상 사용자, 해결하려는 문제, 현재 구현 상태를 파악한다.
- 전체 코드를 정독하지 않는다. 로드맵 설계에 필요한 문서와 상위 구조만 확인한다.
- 불확실한 제품 방향은 단정하지 않고 "가정" 또는 `<!-- TODO: 확인 필요 -->`로 남긴다.
3. **목표 / Phase / Milestone 설계**
- 전체 목표는 프로젝트가 궁극적으로 만들려는 결과를 1~3문장으로 작성한다.
- Phase는 큰 진화 단위로 나누고, 각 Phase에 목표와 상태를 둔다.
- Milestone은 Phase 안에서 완료 판단이 가능한 단위로 나눈다.
- Milestone 내부에서 여러 기능 묶음이 필요하면 Epic으로 선언하고, Epic 아래 flat Task 체크리스트를 둔다.
- 각 Epic의 기능 Task 수는 최대 5개로 제한한다. 여섯 번째 Task가 필요하면 책임과 산출물 경계를 기준으로 Epic을 분리한다.
4. **파일 생성**
- `ROADMAP.md`, `priority-queue.md`, 로컬 `current.md`, 각 Phase의 `PHASE.md`, 각 Milestone 문서를 템플릿 순서대로 생성한다.
- `ROADMAP.md` 최상단에는 `priority-queue.md`를 먼저 확인하도록 `고정 실행 순서` 섹션을 둔다.
- `priority-queue.md`에는 실행 후보를 prefix별 `### <prefix>` 그룹으로 묶고 index 오름차순으로 둔다. 각 항목의 설명 1~2문장을 유지하고, 다른 prefix의 필수 선행은 `선행 차단`, 실제 동시 충돌은 낮은 우선순위 쪽 `동시 차단`으로만 둔다. 후보가 없으면 `실행 순서` 섹션만 비워 둔다.
- 활성 Phase와 활성 Milestone은 `current.md`에 모두 기록한다.
- `.gitignore`의 Agent-Ops 관리 block에 `agent-roadmap/current.md`가 있는지 확인하고 없으면 추가한다.
- `ROADMAP.md`의 Phase 흐름에는 완료/검토중/진행중/계획/스케치 Phase 모두를 상태 그룹별로 정리한다. 이 순서는 실행 우선순위가 아니며, 실제 다음 작업 선택은 `priority-queue.md`를 따른다.
- 완료된 Phase가 초기 구조에 포함되어야 하는 경우 `archive/phase/<phase-slug>/PHASE.md`로 만들고 `ROADMAP.md`에서 archive 경로를 가리킨다.
- 완료된 Milestone이 진행중 Phase에 포함되어야 하는 경우 `archive/phase/<phase-slug>/milestones/<milestone-slug>.md`로 만들고 해당 활성 `PHASE.md`에서 archive 경로를 가리킨다.
- archive `PHASE.md`는 Phase 자체가 완료/폐기된 경우에만 만든다. 진행중 Phase의 완료 Milestone만 archive된 경우 archive Phase 디렉터리에 `milestones/`만 둘 수 있다.
- SDD가 필요한 Milestone은 `구현 잠금`에 해당 Milestone 파일 위치 기준 `SDD 문서` Markdown 링크와 잠금 해제 조건을 적고, 같은 흐름에서 `roadmap-sdd``create` 절차를 적용해 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md` 초안을 만든다.
- `roadmap-sdd create` 결과 SDD 결정 항목이 있으면 `roadmap-sdd``review-ready` 절차에 따라 같은 디렉터리에 `USER_REVIEW.md`를 만들고, SDD와 Milestone 구현 잠금을 `잠금`으로 둔다.
- 외부 의존 잠금이 있으면 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`을 생성하거나 기존 entry를 upsert한다. 의존 대상이 명시 경로, slug, 제목, 문서 힌트, 로컬 current 단일 후보 중 하나로 확정되지 않으면 lock entry를 만들지 않고 TODO로 남긴다.
5. **검증**
- 생성한 링크가 실제 파일을 가리키는지 확인한다.
- `priority-queue.md`가 존재하고 `실행 순서` 섹션이 있는지 확인한다.
- `priority-queue.md`의 모든 링크가 활성 Milestone 파일을 가리키고, 실행 태그가 유일하며, group prefix와 tag prefix가 일치하고, 같은 prefix index가 오름차순인지 확인한다. blocker는 다른 active tag만 참조하고 같은 prefix 정상 순서를 중복하지 않아야 한다. 실행 후보가 없어서 빈 큐이면 정상으로 보고하되, 활성 실행 후보가 있는데 비어 있으면 큐 동기화 필요로 본다.
- 생성한 로드맵 문서의 문서/산출물 포인터가 raw path만 남지 않고 Markdown 링크로 작성되었는지 확인한다.
- 생성한 로드맵 문서의 Markdown 링크 target에 템플릿 placeholder가 남지 않았는지 확인한다.
- 로컬 `current.md` 활성 항목에 `agent-roadmap/archive/**` 경로가 없는지 확인한다.
- Epic heading과 Task 체크리스트 id가 형식을 따르는지 확인한다.
- 각 Epic의 기능 Task 수가 최대 5개인지 확인한다. 6개 이상이면 검증 실패로 보고하고 Epic 분리를 요구한다.
- 상태 표기가 `[진행중]`처럼 공백 없는 표준값인지 확인한다.
- `[스케치]` Milestone에 `승격 조건` 섹션이 있고 `구현 잠금``잠금`인지 확인한다.
- 각 Milestone의 `구현 잠금``SDD: 필요|불필요`와 판정 사유가 있는지 확인한다.
- `SDD: 필요` Milestone은 SDD 문서 링크와 잠금 해제 조건이 있고, 해당 `SDD.md` 파일이 실제 존재하는지 확인한다.
- 생성된 각 `SDD.md``roadmap-sdd``check-gate` 절차로 표준 top-level 섹션, 필수 표 컬럼, SDD 상태, SDD 잠금, `USER_REVIEW.md` 존재 여부, Acceptance Scenario와 Milestone 기능 Task 연결, Evidence Map 연결성을 최종 확인한다.
- `check-gate` 결과는 `SDD gate` 항목에 `pass`, `review-required`, `blocked`, `invalid` 중 하나로 분리해 남긴다. `review-ready`로 만든 `USER_REVIEW.md` 때문에 막힌 경우는 `review-required`로 보고하고 형식 보완 실패로 보지 않는다.
- `[검토중]` Milestone이 있다면 `구현 잠금`이 해제되어 있고 미완료 `결정 필요` 항목이 없는지 확인한다.
- Milestone 문서에 `완료 리뷰` 섹션이 있는지 확인한다.
## 출력 형식
```markdown
## 생성 결과
- 로드맵: [ROADMAP.md](agent-roadmap/ROADMAP.md)
- 전역 실행 순서: [priority-queue.md](agent-roadmap/priority-queue.md)
- 로컬 현재 컨텍스트: [current.md](agent-roadmap/current.md)
- Phase 문서: <N개>
- Milestone 문서: <N개>
- 활성 Phase: <N개>
- 활성 Milestone: <N개>
- 구현 잠금: <잠금 Milestone N개 | 해제 Milestone N개>
- SDD gate: <필요 N개 | 불필요 N개 | 작성 N개 | pass N개 | review-required N개 | blocked/invalid N개>
- 전역 실행 순서: <항목 N개 | | 동기화 필요>
- 최종 확인: <통과 | 사용자 리뷰 필요 | 보완 필요: SDD gate/링크/상태/형식>
- Workspace 잠금: <생성/갱신 N개 | 없음>
- 공통 로드맵 룰: <확인함 | 설치 필요 | 해당 없음>
## 활성 항목
- Phase: <phase-name>: [PHASE.md](agent-roadmap/phase/<phase-slug>/PHASE.md)
- Milestone: <milestone-name>: [<milestone-name>](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
## TODO 항목
- <확인이 필요한 가정 또는 미정 항목> (해당 시)
```
## 금지 사항
- 기존 `agent-roadmap/` 파일을 덮어쓰지 않는다.
- 일반 작업마다 전체 `ROADMAP.md`를 읽도록 규칙을 만들지 않는다.
- `priority-queue.md`를 두 번째 로드맵처럼 사용하지 않는다. 상태, 목표, 범위, 잠금, 기능, 완료 근거를 복제하지 않되, 항목 설명과 최소 차단 예외는 생략하지 않는다.
- `priority-queue.md`에 archive Milestone 링크를 넣지 않는다.
- 로컬 `current.md``agent-roadmap/archive/**` 경로를 넣지 않는다.
- `agent-roadmap/current.md`를 git 추적 대상으로 만들지 않는다.
- Phase 이름/파일명이나 Milestone 파일명에 순번을 강제하지 않는다. Milestone 표시 제목의 `[prefix-NN]` 실행 태그는 예외다.
- `ROADMAP.md`에 Milestone 상세 작업 체크리스트를 넣지 않는다.
- Epic과 Task를 별도 파일로 분리하지 않는다.
- Milestone 문서에서 `구현 잠금` 섹션을 생략하지 않는다.
- 에이전트가 확정할 수 없는 결정 항목이 남아 있는데 새 Milestone을 `해제` 상태로 만들지 않는다.
- 확정되지 않은 제품 방향을 사실처럼 단정하지 않는다.
Report created files, active candidates, explicit dependencies, optional design references, and unresolved product decisions. Do not report lock or gate counts.

View file

@ -1,138 +1,48 @@
---
name: create-test
version: 1.1.4
description: agent-test 환경 rules.md와 도메인/검증 시나리오별 테스트 rule 문서를 생성하거나 구조적 blank/skeleton baseline을 보완하는 스킬
version: 2.0.0
description: 필요한 경우에만 최소 테스트 환경 규칙 또는 테스트 profile 문서를 생성한다.
---
# create-test
## 목적
## 방향
`agent-test/<env>/rules.md``agent-test/<env>/<test-profile>.md`를 템플릿 기준으로 생성하거나 구조적 blank/skeleton 상태에서 baseline으로 보완한다.
공통 진입점은 얇게 유지하고, 실제 테스트 기준은 환경/도메인/검증 시나리오별 문서에 둔다.
검증 게이트 최소화를 최우선으로 한다. 테스트 문서는 검증을 돕는 참고 자료이며 plan·구현·완료의 자동 선행 조건이 아니다.
`test-case`는 기존 호출과의 호환을 위한 alias이며, 새 문서 기준 이름은 `test-profile`이다.
## 사용 조건
## 언제 호출할지
- 사용자가 테스트 규칙이나 profile 생성을 요청했다.
- 실제 반복 실패로 재사용할 검증 절차가 필요하다.
- 보안·데이터 손상 방지를 위한 검증 절차를 명시해야 한다.
- 새 테스트 환경을 추가할 때
- 특정 환경의 `rules.md`가 없을 때
- 특정 환경의 `rules.md`가 비어 있거나 템플릿 뼈대만 있어 baseline 보완이 필요할 때
- 새 도메인/검증 시나리오별 테스트 문서와 라우팅을 추가할 때
- `init-agent-ops` 후 local 테스트 환경 보완이 필요할 때
단순 기능 구현이나 일회성 검증만으로는 테스트 문서를 만들지 않는다.
## 입력
- `env`: `local`, `dev`, `qa`, `prod` 중 하나 (필수)
- `test-profile`: 도메인/검증 시나리오별 테스트 문서 이름, kebab-case (선택)
- `test-case`: `test-profile`의 호환 alias (선택)
- `domain`: 대상 도메인 이름, kebab-case (선택)
- `verification-type`: `smoke`, `unit`, `integration`, `e2e`, `model`, `migration`, `manual`, `full-cycle` 중 하나 (선택)
- `scope`: 검증 대상 또는 변경 범위 설명 (선택)
- `env`: 대상 환경
- `test-profile`: 선택적 profile 이름
- `scope`: 검증 대상
## 핵심 규칙
## 절차
- 도메인 매핑이나 domain rule에서 도메인이 하나 이상 확인되면, 누락된 `agent-test/<env>/<domain>-smoke.md`를 도메인별로 항상 생성한다.
- 명시 `test-profile`은 추가 생성 대상이다. 명시 대상만 만들고 도메인 baseline을 생략하지 않는다.
- 도메인이 하나도 확인되지 않을 때만 `agent-test/<env>/project-smoke.md`를 fallback baseline으로 만든다.
- env rules는 빈 파일, 제목/frontmatter만 있는 파일, 필수 섹션 누락, 또는 `## 라우팅`에 실제 profile 경로가 없으면 구조적 blank/skeleton으로 본다.
- test-profile 문서는 빈 파일, 제목/frontmatter만 있는 파일, 필수 섹션 누락, 또는 적용 범위/분류/명령/필수 검증/판정 기준 섹션 자체가 없으면 구조적 blank/skeleton으로 본다.
- 필수 섹션은 있고 일부 값이 비어 있거나 `<확인 필요>`인 상태는 구조적 blank/skeleton이 아니다. 이 경우 structured-incomplete로 보고 확인된 구체 값과 미확인 항목을 결과에 남긴다.
- 구조적 blank/skeleton env rules나 profile은 기존 완성 문서가 아니라 baseline 보완 대상으로 본다. 확인된 구체 값은 보존하고, 빠진 필수 섹션과 baseline 라우팅만 채운다.
1. 기존 `agent-test/<env>/rules.md`와 직접 관련 profile만 읽는다.
2. 기존 문서 수정으로 충분하면 새 파일을 만들지 않는다.
3. 새 문서가 꼭 필요하면 적용 범위, 최소 명령, 성공 기준, 알려진 제약만 기록한다.
4. 변경 위험에 직접 대응하는 가장 작은 검증을 기본값으로 둔다.
5. full-suite, E2E, 외부 provider, 원격 runner는 사용자가 요청했거나 실제 위험에 직접 필요할 때만 선택 항목으로 둔다.
## 먼저 확인할 것
## 금지
- [ ] `agent-ops/rules/common/rules.md`의 스킬 규칙과 테스트 규칙이 분리되어 있는지 확인한다.
- [ ] `agent-ops/skills/common/router.md``create-test` 라우팅이 있는지 확인한다.
- [ ] `agent-ops/rules/project/rules.md`가 있으면 도메인 매핑 테이블을 확인한다.
- [ ] `agent-ops/rules/project/domain/` 하위 domain rule 목록을 확인한다.
- [ ] 테스트 명령 확인을 위해 프로젝트의 대표 manifest, build 설정, container 설정, CI workflow를 가볍게 확인한다.
- [ ] `agent-ops/rules/common/_templates/test-env-rules-template.md`를 읽는다.
- [ ] `agent-ops/rules/common/_templates/test-case-rule-template.md`를 읽는다.
- [ ] 프로젝트에 `agent-test/_templates/env-rules-template.md` 또는 `agent-test/_templates/test-profile-template.md`가 있으면 해당 프로젝트 템플릿을 공통 템플릿보다 우선한다.
- [ ] `agent-test/<env>/rules.md` 존재 여부를 확인한다.
- [ ] `agent-test/<env>/rules.md`가 있으면 읽고 missing / blank-skeleton / structured-incomplete / usable 중 하나로 분류한다.
- [ ] 도메인 baseline과 추가 생성 대상 `agent-test/<env>/*.md`의 존재 여부를 확인하고, 있으면 blank-skeleton / structured-incomplete / usable 중 하나로 분류한다.
- 모든 domain의 smoke 문서를 자동 생성하지 않는다.
- 필수 섹션 수를 늘리거나 문서 형식 때문에 검증을 차단하지 않는다.
- preflight, evidence 형식, 다른 profile을 새 선행 게이트로 만들지 않는다.
- 확인되지 않은 명령·host·port·credential을 추측하지 않는다.
- secret을 tracked 문서에 기록하지 않는다.
## 실행 절차
## 결과 보고
1. **환경 rules 생성**
- `agent-test/<env>/rules.md`가 없으면 프로젝트 `agent-test/_templates/env-rules-template.md`가 있을 때는 그 형식으로 만들고, 없으면 공통 `test-env-rules-template.md` 형식으로 만든다.
- `agent-test/<env>/rules.md`가 구조적 blank/skeleton이면 기존 구체 값을 보존한 채 빠진 frontmatter, 정독 필수 문구, 필수 섹션, baseline 라우팅 영역만 보완한다.
- usable한 기존 env rules는 덮어쓰지 않고 라우팅 추가가 필요한 경우에만 최소 수정한다.
- 제목은 `# <env> 테스트 규칙`으로 쓴다.
- 제목 바로 아래 정독 필수 문구를 유지한다.
- `last_rule_updated_at`은 생성/보완일 `YYYY-MM-DD`로 쓴다.
2. **생성 대상 확정**
- `test-case`가 있고 `test-profile`이 없으면 `test-profile`로 취급한다.
- 도메인 매핑 테이블과 `agent-ops/rules/project/domain/*/rules.md`에서 확인된 전체 도메인 목록을 만든다.
- 확인된 도메인이 있으면 전체 도메인의 `<domain>-smoke` 문서를 생성 대상으로 삼는다. 개수가 많아도 생략하지 않는다.
- 확인된 도메인이 없으면 `project-smoke` 문서 1개를 fallback baseline으로 생성 대상으로 삼는다.
- `test-profile`이 있으면 baseline 생성 대상에 해당 문서 1개를 추가한다.
- `test-profile`이 없고 `domain`이 있으면 `<domain>-<verification-type>` 형식의 문서를 추가한다. `verification-type`이 없으면 `smoke`를 기본값으로 둔다.
- `test-profile``domain`이 모두 없고 `scope`가 특정 검증 시나리오를 가리키면, 해당 도메인의 `<domain>-<verification-type>` 문서를 baseline 외 추가 생성 대상으로 둘 수 있다.
- 도메인은 새로 발명하지 않는다. 도메인 매핑이나 domain rule에서 확인되지 않은 이름은 `project-wide`로 기록한다.
3. **도메인/검증 시나리오별 문서 생성**
- 생성 대상 문서가 없으면 프로젝트 `agent-test/_templates/test-profile-template.md`가 있을 때는 그 형식으로 만들고, 없으면 공통 `test-case-rule-template.md` 형식으로 만든다.
- 대상 문서가 이미 있고 usable하면 덮어쓰지 않는다.
- 대상 문서가 구조적 blank/skeleton이면 기존 구체 값을 보존한 채 빠진 frontmatter와 필수 섹션을 보완한다.
- frontmatter에는 `test_profile`, `domain`, `verification_type`, `last_rule_updated_at`을 채운다.
- 파일명은 kebab-case로 쓴다.
- 실제 확인된 환경, 명령, 판정 기준만 채운다.
- 불확실한 값은 비워 두거나 `<확인 필요>`로 둔다.
- 테스트 코드를 생성하는 스킬이 아니라 테스트 판단 기준 문서를 생성하는 스킬임을 유지한다.
4. **라우팅 갱신**
- 새 환경을 만들었고 `agent-ops/rules/common/rules.md`에 해당 env 라인이 없으면 `# 테스트 규칙`에 한 줄을 추가한다.
- 생성하거나 보완한 `test-profile` 문서는 `agent-test/<env>/rules.md``## 라우팅`에 한 줄씩 추가한다.
- 이미 같은 profile로 향하는 라우팅이 있으면 중복 추가하지 않고 설명만 필요할 때 최소 보정한다.
- 라우팅 설명은 `<domain 또는 project-wide> / <verification-type> / <scope 요약>` 형식으로 쓴다.
- 도메인/검증 시나리오별 문서에서 다른 테스트 문서로 라우팅하지 않는다.
- 공통룰에서 스킬 최종 진입까지의 경로는 `rules.md` -> `router.md` -> `create-test/SKILL.md`로 유지한다.
5. **local 추적 제외**
- `env``local`이면 `.gitignore``agent-test/local/``agent-test/runs/`가 있는지 확인하고 없으면 추가한다.
6. **결과 보고**
- 생성한 파일
- 추가한 라우팅
- 자동 생성 기준: 도메인 baseline / 명시 입력 / scope 매칭 / project-smoke fallback
- 구조적 blank/skeleton 보완 대상
- 비워 둔 확인 필요 항목
## 실행 결과 검증
- [ ] 생성 파일이 해당 템플릿의 필수 섹션을 포함하는가
- [ ] `rules.md` -> `router.md` -> `create-test/SKILL.md` 경로가 끊기지 않는가
- [ ] `agent-test/<env>/rules.md`가 3홉을 넘는 라우팅을 만들지 않는가
- [ ] 새 도메인/검증 시나리오별 문서가 env rules의 라우팅에 연결되었는가
- [ ] 확인된 모든 도메인에 `<domain>-smoke` 문서가 생성되었는가
- [ ] 도메인이 없을 때 `project-smoke` fallback 문서가 생성되었는가
- [ ] 생성/보완 대상에 섹션 누락이나 라우팅 없는 구조적 blank/skeleton 파일이 남아 있지 않고, 불확실한 값은 `<확인 필요>`로 보고되었는가
- [ ] local 생성 시 `.gitignore`에 local 경로가 반영되었는가
- 검증 실패 시: 누락된 파일/섹션/라우팅만 보완한다.
## 출력 형식
```md
## 생성 완료
- 환경: <env>
- 환경 rules: agent-test/<env>/rules.md
- 테스트 profiles: <agent-test/<env>/<test-profile>.md 목록>
- 라우팅 추가: <내용>
- 자동 생성 기준: <도메인 baseline | 명시 입력 | scope 매칭 | project-smoke fallback>
- 구조적 blank/skeleton 보완: <파일 목록 또는 없음>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- usable한 기존 테스트 문서를 덮어쓰지 않는다.
- 구조적 blank/skeleton 보완 시에도 확인된 구체 환경값, 명령, 판정 기준을 추측으로 교체하지 않는다.
- 도메인/검증 시나리오별 문서에서 추가 테스트 문서로 라우팅하지 않는다.
- 도메인 매핑이나 domain rule에 없는 도메인을 확정값처럼 만들지 않는다.
- 확인되지 않은 host, port, token, endpoint를 추측해 쓰지 않는다.
- secret, token, 개인 endpoint 원문을 tracked 파일에 기록하지 않는다.
- 생성·수정한 문서
- 기본 최소 검증
- 필요할 때만 실행하는 선택 검증
- 확인되지 않은 항목

View file

@ -1,377 +1,80 @@
---
name: plan
description: Analyze the current repository and write a detailed PLAN-{build_lane}-GNN.md plus CODE_REVIEW-{review_lane}-GNN.md stub for implementation work. Use for every feature, refactor, bug fix, and code-review WARN/FAIL follow-up that enters the plan-code-review loop. Every initial or follow-up pair must run finalize-task-routing after analysis and before routed filenames are chosen. Milestone-linked work uses an m-prefixed task group and first-line milestone-task ids so PASS logs can be aggregated by sync-milestone-workstate.
description: Create a concise implementation plan when the user explicitly asks for one or when a large change needs a durable execution handoff.
---
# Plan
## Purpose
Create the planning artifacts for the implementation loop:
Create the smallest plan that lets an implementer make the requested change safely. A plan is optional for ordinary implementation and is not gated by roadmap status, SDD state, preflight, review history, or evidence metadata.
```text
plan skill -> analysis -> finalize-task-routing -> PLAN-{build_lane}-GNN.md + CODE_REVIEW-{review_lane}-GNN.md stub
implementation -> code changes + filled implementation evidence in CODE_REVIEW-{review_lane}-GNN.md
code-review skill -> verdict + archive, complete.log and task-directory archive move, USER_REVIEW.md, or mandatory plan-skill follow-up
runtime -> for m-prefixed PASS completion events, aggregate complete.log evidence with sync-milestone-workstate
```
## When to use
`code-review` may stop the automatic loop with `USER_REVIEW.md` for either a selected Milestone `구현 잠금 > 결정 필요` item (`milestone-lock`) or required external verification that cannot proceed without a user-controlled runner, device, credential, interactive session, evidence handoff, or explicit authorization (`external-execution`). A current-host mismatch or missing command is not enough when a repository-declared runner or authorized executor can perform the step automatically. Repeated non-PASS reviews and missing evidence are not user-review reasons by themselves. Plan creation after `USER_REVIEW.md` requires its recorded user action or decision to be resolved. If that resolution closes the task as complete/PASS, code-review writes `complete.log` and archives the task instead of creating a new plan.
- The user explicitly asks for a plan or durable handoff.
- The change is large enough that multiple files or ownership boundaries need an ordered checklist.
- A reviewer asks for one concrete follow-up plan.
The plan file and review stub must be self-sufficient for implementation agents that do not read this skill. Implementing agents fill the active review's implementation evidence. They never decide whether user review is needed, write a user-review request, ask the user for a decision, create `USER_REVIEW.md`, or modify runtime-owned artifacts; those control-plane responsibilities belong to the official code-review skill and runtime.
Do not create a plan for a small fix that can be implemented and verified directly.
## Workflow Contract
## Context
This skill intentionally uses routed active files under an active task directory as the state protocol. Do not change this directory or filename contract unless the paired code-review skill is updated together.
1. Read the user request and only the relevant project/domain rules.
2. Inspect the files and tests directly related to the change. Full-file reads are not mandatory when a focused range is sufficient.
3. If a matching active Milestone exists, use its goal, scope, Tasks, and plain decision notes as context.
4. Treat an SDD as an optional design reference. Its status and evidence tables do not block planning.
5. Read archive evidence only when an active task points to an exact file needed for a follow-up.
Invocation modes:
## Decisions and blockers
- `write` is the default for initial plans and explicit replans. After routing, this skill archives any prior active pair and writes the new pair.
- `prepare-follow-up` is used only when code-review has appended WARN/FAIL but has not archived the active pair. This skill validates the reviewer-owned evidence, root cause, selected fix, scope, and acceptance commands against current source, then completes final routing and exact PLAN/review-stub rendering in memory without mutating repository files. It must not redo diagnosis, choose another solution, or leave either decision to the implementing agent. It returns `prepared_plan`, `prepared_review`, their routed basenames, the current pair's predicted archive names/numbers, and the post-archive log counts used by the new pair.
- Both modes execute the same mandatory Step 3. `prepare-follow-up` is not a route-only shortcut.
- Infer normal technical details from current code and conventions.
- If one user-owned product decision is directly required, ask for that decision and continue all independent planning work.
- Only credentials/security, data-loss or irreversible external actions, and explicit project dependencies may block execution.
- Missing live environments, optional tests, documents, metadata, or prior review evidence are not plan blockers.
Optional context:
## Task shape
- `verification_context` is a neutral handoff containing environment, source paths, commands, expected results, preconditions, read-only preflight results, constraints, gaps, and confidence. Consume it when supplied, but verify that its paths and commands still match the current checkout. The plan remains responsible for repository-native fallback analysis when it is absent or incomplete.
- Prefer one plan.
- Split only when children can be implemented and verified independently or when the user asks for parallel tasks.
- Preserve existing `agent-task/<task>/` naming when continuing an active task.
- Existing routed filenames such as `PLAN-local-GNN.md` remain valid. Choose the smallest existing grade convention needed by repository tooling; do not run a separate routing workflow unless the user requests routing.
- `milestone-task` metadata is optional target information, not a completion contract.
Task path terms:
## Required plan content
- `{task_group}` is the top-level work category under `agent-task/`. Normal task groups use a short snake_case name such as `refactoring`.
- Milestone-linked work uses the reserved task group form `m-<milestone-slug>`, where `<milestone-slug>` is the active Milestone filename without `.md`.
- `{subtask_dir}` is used only for split work and follows the existing indexed directory naming rules below, such as `01_core` or `02+01_db`.
- `{subtask_name}` is the short snake_case name after the index or dependency prefix inside `{subtask_dir}`.
- `{task_name}` in headers and templates means the active task path relative to `agent-task/`: either `{task_group}` for a single-plan task or `{task_group}/{subtask_dir}` for a split subtask.
- A single-plan task stores active files directly under `agent-task/{task_group}/`.
- Split work stores active files under `agent-task/{task_group}/{subtask_dir}/`; the parent `agent-task/{task_group}/` contains no active plan/review files.
- Goal and concise background.
- Files or components expected to change.
- Ordered implementation checklist.
- Product decisions already made and any one directly required open decision.
- Minimal verification proportional to the change.
- Explicit dependencies only when they are real execution dependencies.
Filename rules:
Do not require:
- Plan file: `PLAN-{build_lane}-GNN.md`
- Review stub: `CODE_REVIEW-{review_lane}-GNN.md`
- `{lane}` is only `local` or `cloud`; never put model names in filenames.
- `GNN` is a two-digit capability grade from `G01` to `G10`; the runtime maps lane+grade to current models externally.
- Lane, grade, and both canonical basenames come only from `agent-ops/skills/common/finalize-task-routing/SKILL.md`.
- exhaustive files-read inventories;
- before/after snippets for every edit;
- SDD approval or Evidence Map reconstruction;
- external environment preflight for optional verification;
- a mandatory review stub evidence form;
- routing scores, loop-risk analysis, or capability-grade justification.
Role boundary rules:
## Review reference
- First-pass analysis belongs to plan. After WARN/FAIL, evidence collection, root cause, solution selection, scope, ownership, and next-state decisions belong to code-review; `prepare-follow-up` only validates and materializes that closed reviewer packet. Let implementing agents execute it without investigating the cause, choosing among remedies, reinterpreting findings, or changing its owner/write boundary.
- Implementing agents fill implementation-owned `CODE_REVIEW-*-G??.md` sections, keep active files in place, and report ready for review.
- If implementation cannot continue, implementing agents record the exact blocker, attempted commands/output, and resume condition only in `Verification Results` or `Deviations from Plan` (legacy: `검증 결과` or `계획 대비 변경 사항`), then leave the active files in place for official review.
- During implementation, do not ask the user directly, present choices, call user-input tools, or create control-plane stop files. The official reviewer owns all next-state classification.
- Required evidence capture that needs a user-owned runner, device, emulator, permission, secret, interactive access, evidence handoff, or explicit external authorization unavailable to the agent is a verification blocker for the implementing agent. Record the declared execution target, attempted routing/preflight commands, actual output, authorization state, and resume condition in `Verification Results` or `Deviations from Plan` (legacy: `검증 결과` or `계획 대비 변경 사항`) so the official reviewer can evaluate the `external-execution` gate.
- Finalization (`Code Review Result` [legacy: `코드리뷰 결과`], plan/review log rename, `complete.log`, task artifact archive moves, review-only checklist) is code-review-skill only.
When the existing task loop expects a review file, create one `CODE_REVIEW-<lane>-GNN.md` beside the plan from the simple review template. It is a convenience for a later explicit review, not an implementation completion gate. The implementer may add notes, but blank evidence fields do not invalidate completed code.
Split decision policy:
## Follow-up
- Split only by behavior/contract boundaries whose children each have a stable intermediate contract and deterministic PASS verification.
- Keep every production change with its required tests; use a test-only child only for additional integration evidence.
- Keep one plan when the work is compact or split would sever one correctness/transaction invariant. Never split to lower lane, grade, context, or signature count.
- If the existing analysis cannot prove that children independently PASS, keep the atomic work together and route it as one packet.
- Record either each child's contract/dependency or the invariant that makes one plan indivisible.
- A WARN/FAIL review may be fixed directly or receive one concise follow-up plan.
- Do not automatically create another plan, reroute the task, generate `USER_REVIEW.md`, or restart a loop.
- Preserve useful findings; discard obsolete process metadata.
Split gates:
## Validation
- Separate foundation from rollout only when the foundation preserves compatibility and independently passes.
- Split domains, verification profiles, or risk slices only when each independently passes.
- Split work that can produce a useful earlier `complete.log` without invalid intermediate state.
- Isolate mobile/UI/external verification that can block otherwise completed implementation.
- The plan matches the user request and does not expand scope.
- Referenced files and commands exist.
- Verification is the smallest relevant test set.
- No documentation, approval, evidence-format, or environment-availability gate was introduced.
Task directory naming rules:
## Output
- A normal single-plan task uses `agent-task/{task_group}/` with a short snake_case category name, e.g. `agent-task/refactoring/`.
- If the plan is based on a selected active Milestone, use `agent-task/m-<milestone-slug>/` as the task group. Do not include the Phase slug, Epic id, Task id, or a separate task slug in the task group.
- `m-<milestone-slug>` is a reserved top-level task group namespace for Milestone-linked work. Non-roadmap tasks must not use `m-`.
- Runtime completion-event routing for `m-*` reads the top-level `{task_group}` name and the first-line `milestone-task` ids preserved in `complete.log`. It resolves `<milestone-slug>` by matching exactly one active file at `agent-roadmap/phase/*/milestones/<milestone-slug>.md`; archive paths are not target candidates.
- When split gates require decomposition, create one shared category folder and multiple subtask directories under it. Each subtask directory owns exactly one normal active plan file and one normal active review stub.
- Multi-plan output is a set of independent `PLAN-{build_lane}-GNN.md` + `CODE_REVIEW-{review_lane}-GNN.md` pairs across `agent-task/{task_group}/{subtask_dir}/` folders, not multiple plan files inside one folder.
- Multi-plan subtask directory names must start with a stable two-digit task index. The index must increase across sibling subtask directories for sorting, but it is not a serial execution dependency.
- Assign new sibling indices in topological dependency order so every producer precedes its consumers. For ties, keep the planned sibling order; assign each task the lowest collision-free two-digit index greater than all of its predecessors.
- Before writing the pairs, verify that the sibling dependency graph has no cycle and every predecessor index is lower than its consumer index. Skip an index only when it is not greater than an unchanged existing predecessor or is already occupied by an active/archived sibling.
- Use `NN_{subtask_name}` for a task with no runtime dependencies, e.g. `01_core`, `04_docs`, `05_ui`.
- Use `NN+PP[,QQ...]_{subtask_name}` for a task that depends on earlier task indices, e.g. `02+01_db`, `03+01,02_api`, `06+05_integration`.
- Valid independent pattern: `^[0-9]{2}_[a-z0-9_]+$`.
- Valid dependent pattern: `^[0-9]{2}\+[0-9]{2}(,[0-9]{2})*_[a-z0-9_]+$`.
- `NN`, `PP`, and `QQ` are two-digit indices. Every predecessor index after `+` must be lower than `NN` and must refer to a sibling multi-plan subtask directory under the same `{task_group}`.
- The first `_` after the index or dependency list starts `{subtask_name}`. `{subtask_name}` stays short snake_case and may contain additional underscores.
- Runtime scheduling reads only the `{subtask_dir}` name: `_` means `depends_on=[]`; `+` means `depends_on` is the comma-separated index list between `+` and the first `_`.
- Subtask directory names are the source of truth for runtime dependencies. Do not hide extra dependencies only in the plan body, and do not create a bare `NN+{subtask_name}` without predecessor indices.
- A predecessor index is satisfied by a `complete.log` for the matching predecessor subtask under the same `{task_group}`. Check active siblings first, then matching archived subtasks across all archive month folders. This is a narrow exception to the normal archive skip rule: read only candidate predecessor `complete.log` files needed to prove split dependency completion.
- For predecessor index `PP`, the only valid active lookup candidates are `agent-task/{task_group}/PP_*/complete.log` and `agent-task/{task_group}/PP+*/complete.log`.
- For predecessor index `PP`, the only valid archive lookup candidates are `agent-task/archive/*/*/{task_group}/PP_*/complete.log` and `agent-task/archive/*/*/{task_group}/PP+*/complete.log`.
- Archive lookup matches the predecessor index at the start of the archived subtask directory name, such as `01_...` or `01+...`, under the same `{task_group}`. If multiple candidates match one predecessor index, do not choose by guess; record the ambiguity and require a concrete task path or runtime selection.
- Do not treat an archived predecessor as the active task to edit. Archive lookup is only for dependency satisfaction before writing or implementing a dependent split plan.
- Example: split a refactoring common core plus two app integrations under `agent-task/refactoring/` as `01_core`, `02+01_app_a_integration`, `03+01_app_b_integration`. Both integrations depend only on `01_core` and may run in parallel after `01_core` has `complete.log`.
- Example: split three sequential tasks under one task group as `01_schema`, `02+01_migration`, `03+02_api`.
- Example: split independent docs/UI plus an integration under one task group as `01_core`, `02+01_db`, `03+02_api`, `04_docs`, `05_ui`, `06+05_integration`; `01_core`, `04_docs`, and `05_ui` can start together, and `06+05_integration` waits only for `05_ui`.
- After a pair is written, preserve its task group and subtask directory name verbatim. Only an explicit `refine-plans` run may rename eligible unstarted siblings by its dependency-order rules.
Final routing boundary:
- Keep the task `unrouted` until split, PLAN body, verification, evidence, ownership, and decisions are complete.
- Treat each final in-memory PLAN as its build packet. Derive `large_indivisible_context` and positive loop-risk signatures once from analysis already required to write that PLAN; do not create a separate packet summary or search for negative risk evidence.
- Execute `finalize-task-routing` once for build/review and use only its lane/G/filenames. Apply it to first-pass, follow-up, USER_REVIEW replan, and each split subtask independently.
- Quarantine previous lane/G/score/rationale. Carry only revalidated code, findings, command output, `review_rework_count`, and `evidence_integrity_failure`.
- `needs_evidence` names genuinely missing closure evidence; `blocked` stops file creation. Changed plan facts invalidate the route.
- Only `refine-plans` may replace an unstarted pair with strict-subset children. It must run `finalize-task-routing` in `isolated-reassessment` mode for every completed child packet and must not retain the parent route.
Directory states:
| State | Meaning |
|-------|---------|
| `PLAN-*-G??.md` only | Invalid; plan skill always writes both active files |
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` stub | Implementation is pending/in progress |
| `PLAN-*-G??.md` + filled `CODE_REVIEW-*-G??.md` without verdict | Ready for code-review skill |
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` with appended verdict | Review finalization is pending. Continue only when code-review invokes `prepare-follow-up`; `write` mode must not overwrite this state. |
| `complete.log` + `*.log` files | Task complete (PASS or user-review-resolved PASS), before final task-directory archive move |
| `USER_REVIEW.md` + `*.log` files | Automatic loop stopped; its recorded Milestone decision or external-execution user action must be resolved before creating another plan |
| `agent-task/archive/YYYY/MM/{task_name}/complete.log` + `*.log` files | Archived completed task path (PASS or user-review-resolved PASS); not active |
| Only `*.log` files (no `complete.log`) | Inspect the newest review log. A verdict with no required next state is post-archive finalization pending; otherwise the task is terminated mid-loop or abandoned. |
## Step 1 - Determine Task
If the user names the task explicitly, use that task group or task path.
Otherwise, find active plan files with both globs, excluding `agent-task/archive/**`:
- `agent-task/*/PLAN-*-G??.md`
- `agent-task/*/*/PLAN-*-G??.md`
Also note active user-review stops, excluding `agent-task/archive/**`:
- `agent-task/*/USER_REVIEW.md`
- `agent-task/*/*/USER_REVIEW.md`
| Result | Action |
|--------|--------|
| Exactly one | Continue that task |
| None | Create a new task only for a feature/refactor/fix/follow-up that belongs in this workflow |
| Multiple | If the user/runtime named a task group, task path, or subtask directory that identifies exactly one active plan, use it. Otherwise list paths and stop with an ambiguity report; do not choose by agent judgment and do not create a user-review request for routing ambiguity. |
The routed plan file is the loop entry point. A missing active plan normally means only that no plan has been started for a new task; do not create task files for casual analysis, status, or review requests unless the user explicitly asks for a plan.
If no active plan exists but one or more `USER_REVIEW.md` files exist, report the recorded user action or decision and list the paths unless one path is explicitly selected for resolution or replanning. If a selected active task directory contains `USER_REVIEW.md`, read it before planning. Do not write a new follow-up plan unless the recorded action or decision has been resolved or the new plan explicitly replans around that resolution. When planning resumes from `USER_REVIEW.md`, archive it to `user_review_N.log` in the same task directory before writing the new active plan/review pair, and record the resolved action or decision in the new plan `Background` or `Analysis` (legacy: `배경` or `분석 결과`).
If a selected task directory contains both `USER_REVIEW.md` and active `PLAN-*-G??.md` or `CODE_REVIEW-*-G??.md`, report an inconsistent loop state and do not overwrite either state until a later explicit command selects either user-review resolution or the active plan/review path.
If the selected review already has an appended verdict, accept it only in `prepare-follow-up` mode invoked by code-review. In every other mode, leave the pair unchanged and report that code-review finalization must resume.
로드맵 확인:
- `agent-roadmap/current.md`는 브랜치별 로컬 포인터다. 있으면 구현 계획 파일을 만들기 전에 읽고, 사용자 요청, 브랜치, 변경 경로를 기준으로 관련 Phase와 Milestone을 선택한다.
- `agent-roadmap/priority-queue.md`가 있으면 명시 target이 없는 구현 계획에서 prefix별 후보와 차단 예외를 확인하기 위해 읽는다. 상태/잠금/기능 원본은 각 Milestone 문서다.
- 각 prefix에서 가장 작은 active index 하나만 lane head 후보로 둔다. `선행 차단`이 남은 후보는 제외하고, `동시 차단` target이 현재 실행 중이면 제외한다. 다른 prefix의 열린 head들은 병렬 후보이며 문서상 위쪽 group은 target 없는 "다음 작업"의 tie-breaker로만 쓴다.
- 사용자가 Milestone을 명시해도 같은 prefix의 더 작은 active index, `선행 차단`, 현재 진행 중인 `동시 차단` target이 있으면 plan을 만들지 않고 실행 순서 차단을 보고한다.
- queue의 설명은 후보 이해에 유지하되 scheduling 판단에는 tag, link target, exact `선행 차단`/`동시 차단` label만 사용한다.
- `priority-queue.md` 링크, 실행 태그, group-prefix, blocker 참조가 깨졌으면 Milestone을 추측해 계획하지 말고 `update-roadmap`으로 큐 정리가 필요하다고 보고한다.
- `agent-roadmap/`이 있는데 `current.md`가 없으면 `agent-ops/skills/common/_templates/roadmap-current-template.md` 형식으로 로컬 파일을 만들거나, `ROADMAP.md`의 Phase 흐름과 관련 `PHASE.md`에서 후보를 고른 뒤 로컬 current를 채운다. current 없음만으로 일반 task routing으로 빠지지 않는다.
- `current.md``agent-roadmap/archive/**`를 가리키면 해당 문서는 읽지 말고 활성 Phase/Milestone이 아니라고 보고한다.
- 선택한 Phase를 한 번 읽어 Phase 목표, Milestone 흐름, Phase 경계를 확인한다.
- 선택한 Milestone을 한 번 읽어 목표, 상태, 승격 조건, 범위, 기능 Task, 완료 리뷰, 범위 제외, 구현 잠금을 확인한다. `승격 조건``[스케치]`에서만 필수이며, `[계획]` 이상에서 섹션이 없으면 `없음`으로 본다. `구현 잠금` 섹션이 없거나, 상태가 `잠금`이거나, 미완료 `결정 필요` 항목이 하나라도 있으면 실구현 계획을 만들지 않는다.
- 구현 잠금에 걸린 Milestone에서는 `PLAN-*-G??.md`, `CODE_REVIEW-*-G??.md`, task directory, file/API/package 수준 구현 단계를 확정하지 말고 `구현 잠금 차단`으로 보고한다. 보고에는 Milestone 경로, 잠금 상태, 남은 `결정 필요` 항목, 다음에 필요한 `update-roadmap` 조치를 적는다.
- 남은 `결정 필요` 항목이 현재 실구현 범위가 아니라고 판단되더라도 같은 plan 요청 안에서 구현 계획을 계속 쓰지 않는다. 먼저 roadmap-only 갱신으로 해당 항목을 `범위 제외`, 후속 Milestone, 또는 `작업 컨텍스트`로 옮기고 `구현 잠금``해제`한 뒤 새 plan 요청에서 진행한다.
- 선택한 Milestone에 `SDD: 필요`가 있으면 승인된 SDD를 구현 계획 작성의 입력으로 읽는다. SDD 문서가 없거나, 상태가 `[승인됨]`이 아니거나, `SDD 잠금``잠금`이거나, 같은 디렉터리에 `USER_REVIEW.md`가 있으면 plan 파일을 만들지 말고 `roadmap-sdd` 또는 `update-roadmap` 조치가 필요하다고 보고한다.
- `SDD: 필요` Milestone의 구현 계획은 Milestone 기능 Task만 보고 작성하지 않는다. 요청 대상 Task id에 연결된 SDD Acceptance Scenario와 Evidence Map을 먼저 매핑하고, 그 결과에서 구현 범위, checklist, 검증 명령, 완료 evidence를 역산한다. 매핑이 없거나 SDD와 Milestone Task가 어긋나면 plan 생성을 멈추고 SDD와 Milestone의 정합성 갱신이 필요하다고 보고한다.
- 선택한 Milestone에 legacy `필수 기능`/`완료 기준`이 분리되어 있으면 plan 파일을 만들지 말고 `update-roadmap` 정규화가 필요하다고 보고한다.
- 선택한 Phase 또는 Milestone 상태가 `[스케치]`이면 구현 계획 파일을 만들지 않는다. `[스케치]`는 컨셉 상태이므로 `update-roadmap`의 concretize 흐름으로 승격 조건, 결정 필요, 범위, 기능 Task를 정리해 `[계획]`으로 전환해야 한다고 보고한다.
- Phase 또는 Milestone 후보가 여럿이면 요청 문장, 변경 경로 직접성, Milestone 상태, 구현 잠금, 선후 의존성, Phase/Milestone 흐름상 위치를 기준으로 1순위와 2순위를 추천하고 필요한 후보 문서만 읽어 범위를 좁힌다.
- 로드맵 current가 있고 활성 Phase/Milestone 밖 작업이면 `ROADMAP.md`의 Phase 흐름을 확인하고 전환, 신규 Phase/Milestone, 또는 기존 활성 범위 내 배치 필요성을 보고한다.
- 사용자가 선택한 Milestone의 작업, 구현, 계획 작성을 명시했더라도 `구현 잠금`이 완전히 해제되어 있지 않으면 계획 작성을 이어가지 않는다. Milestone 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없을 때만 roadmap update 흐름으로 `구현 잠금` 상태를 `해제`로 갱신할 수 있다.
- 제품 선택, 우선순위 결정처럼 에이전트가 확정할 수 없는 항목은 구현 계획의 실행 checklist로 쓰지 않는다. 그런 항목이 남아 있으면 plan 생성을 멈추고 `구현 잠금 > 결정 필요`로 분리한다.
- 기능 Task에 `검증:`이 있으면 구현 계획의 같은 plan item 안에 해당 검증을 포함한다. 검증이 명시되지 않은 기능 Task에는 억지 검증 항목을 만들지 말고, 필요한 일반 빌드/회귀 확인만 최종 검증에 둔다.
- 선택한 활성 Milestone 범위에 속하는 구현 계획이면 `{task_group}``m-<milestone-slug>`로 정한다. `<milestone-slug>`는 선택한 Milestone 경로의 파일명에서 `.md`를 제거한 값이다.
- 같은 Milestone에서 split work가 필요하면 기존 split 규칙 그대로 `agent-task/m-<milestone-slug>/<subtask_dir>/` 아래에 계획 파일을 만든다.
- Milestone 작업 계획은 첫 줄에 `milestone-task=<task-id>[,<task-id>...]`를 넣어 이 작업이 기여하는 기존 기능 Task id를 고정한다. id는 선택한 활성 Milestone `기능` 섹션에 실제로 존재해야 하고, `rules-roadmap.md`의 item-id 문법을 따르며, 중복 없이 쉼표로 구분하고 공백을 넣지 않는다.
- `milestone-task`는 PASS 즉시 체크할 완료 주장이나 plan 하나당 Task 하나라는 뜻이 아니다. 여러 plan이 같은 id에 기여할 수 있고 한 plan이 여러 id에 기여할 수 있다. 이후 `sync-milestone-workstate`가 같은 Milestone task group의 모든 `complete.log`를 id별로 모아 Task 설명·검증·SDD evidence 충족 여부를 평가한다.
- Milestone 범위의 하위 구현이나 조사도 관련 기능 Task id가 명확하면 같은 id를 기록한다. 관련 id를 정할 수 없다면 `m-*` task group으로 계획하지 말고, 먼저 Milestone 기능 Task를 보강하거나 비마일스톤 task group으로 분리한다.
- WARN/FAIL follow-up은 범위가 그대로면 이전 `milestone-task` id 목록을 정확히 유지한다. 범위를 바꾸는 경우에만 현재 Milestone과 SDD mapping을 다시 확인해 id를 명시적으로 교정하며, id가 조용히 누락되거나 다른 id로 바뀌면 안 된다.
- `agent-roadmap/` 디렉터리가 없으면 기존 task routing 규칙대로 진행한다.
Use short snake_case task group names for non-roadmap work, e.g. `api_refactor`.
Before choosing plan files or task directory names, apply the split decision policy above. When the policy allows a single plan, write active files directly under `agent-task/{task_group}/` and record the exception rationale. When the policy requires multiple plans, choose one shared `{task_group}` and `{subtask_dir}` names using the task directory naming rules above. Do not put multiple active plan files in one active task directory, and do not mix split subtask directories with active plan/review files directly in the parent task group.
## Step 2 - Analyze Before Writing
Complete all items below before creating active plan/review files. Work through them in order; do not proceed to the next step until every checkbox is done. Keep the user request as the scope anchor and reconcile derived acceptance conditions before the split decision; do not create a separate routing summary. In `prepare-follow-up`, treat the reviewer's closed finding packet as the decision authority: repository reads validate its consistency and supply implementation mechanics, but do not reopen root cause or solution selection. If required evidence, root cause, or a selected fix is missing or contradicted, return `needs_evidence` to code-review so the reviewer corrects it in the same review pass; never pass investigation or alternatives to the worker. The only allowed file edits before writing plan/review files are local `agent-roadmap/current.md` creation or `.gitignore` block repair needed for roadmap routing.
- [ ] **Resolve verification context** — because implementation plans include verification, consume supplied `verification_context` when present and confirm its source paths, commands, expected results, preconditions, constraints, gaps, and confidence still apply. On first pass, derive missing facts from repository manifests, scripts, workflows, domain rules, related tests, user-provided environment facts, and safe read-only probes. In `prepare-follow-up`, require the reviewer to have collected every fact needed for diagnosis and fix selection; derive only mechanical command/path details, and return `needs_evidence` rather than performing missing review analysis. Record which facts came from the handoff and which came from repository-native validation. A missing optional first-pass handoff is not a user-review blocker.
- [ ] **NO OVERENGINEERING** — Do not add anything beyond the user request and required behavior.
- [ ] **Read all source files in full** — read every source file the change will touch, whole file. No partial reads.
- [ ] **Preflight external verification** — when any required verification leaves the current checkout, including remote runner, field/bootstrap, external provider, Docker/code-server, emulator/device, or shared long-running runtime, confirm or derive a read-only preflight before writing final verification commands. Record runner, repo root/workdir, branch/HEAD/dirty state, source sync status, binary/artifact paths, command help/version output needed by the verification, config path, runtime identity, ports/process state, external hosts, and OS/arch assumptions. If the preflight shows stale artifacts, dirty/divergent checkout, wrong identity, missing command, closed ports, host OS mismatch, or unsynced source, add an explicit setup/sync/rebuild step or report the blocker.
- [ ] **Read all test files in full** — read every test file that exercises the changed behavior, including files identified by the verification context and repository test layout.
- [ ] **Assess test coverage** — for each behavior change, explicitly record whether existing tests cover it.
- [ ] **Assess split boundaries once** — reconcile request acceptance with source/tests, then split only where every child has a stable contract and independent PASS verification. Otherwise keep the invariant together; do not gather extra evidence solely to lower routing risk.
- [ ] **Capture recovery signals once** — first-pass uses `review_rework_count=0` and `evidence_integrity_failure=false`. In `prepare-follow-up`, reuse the values already validated and appended by code-review; do not recount verdict history. For another isolated replan, derive them once from the same-task state already loaded for planning, without a routing-only log pass.
- [ ] **Resolve follow-up findings once** — in `prepare-follow-up`, require every inherited Required/Suggested id to carry reviewer-collected evidence, exact root cause, one selected fix, affected files/symbols/behavior/tests, acceptance commands, and a `direct-fix` or `verified-dependency` disposition. Validate those decisions against current source without replacing them. Allow `verified-dependency` only when an exact active PLAN claims those files and task-protocol ordering applies, or when `complete.log` plus fresh evidence proves the failed precondition is satisfied; vague owners or `complete.log` alone are invalid. Set `ownership_closed=true` only after all mappings are proven. Reject diagnostic-only packets, unresolved alternatives, unchanged-precondition verification loops, and any worker-facing investigation step. Reuse the reviewer analysis; add no model, sub-agent, or routing-only pass.
- [ ] **Resolve split predecessor completion** — if the selected or proposed subtask directory has `NN+PP[,QQ...]_...`, resolve each predecessor index under the same task group. Check only the active and archive candidate patterns defined in the task directory naming rules. Record found active/archive paths, missing predecessors, or ambiguous matches in `Analysis > Split Judgment` (legacy: `분석 결과 > 분할 판단`) and, when order matters, `Dependencies and Execution Order` (legacy: `의존 관계 및 구현 순서`).
- [ ] **Grep all symbol references** — for any renamed or removed symbol, find every call site and import chain.
- [ ] **Check dependency manifests** — before adding any dependency, inspect the repository's relevant dependency manifest and lockfile, confirm whether it already exists, and follow the repository-native version and update policy.
- [ ] **Pre-check compile issues** — identify missing interface implementations, type mismatches, and broken imports.
- [ ] **Verify verification commands** — confirm that the final verification commands actually run in this repository layout.
- [ ] **Stabilize fragile verification** — for search or generated-output checks, choose deterministic commands up front, such as `rg --sort path`, and decide whether cached test output is acceptable or the repository's test runner must use its fresh-run or cache-bypass option.
- [ ] **Derive routing signals once** — treat each completed in-memory PLAN as the worker packet. From facts already collected, record `large_indivisible_context`, positive matched loop-risk names/count, and recovery signals. Do not reread files, prove unmatched signatures false, or aggregate parent/sibling risk for routing.
## Step 3 - Finalize Task Routing
This step is mandatory and must be the last semantic decision before routed filenames are fixed. Complete Step 2 and prepare the full plan structure in memory before starting it.
- [ ] **Freeze routing input and mode** — use the completed in-memory PLAN and existing analysis facts. Include closure, grade, `large_indivisible_context`, positive risk names/count, and recovery signals; exclude previous route fields. Use `first-pass` with no prior route, otherwise `isolated-reassessment`. Remove prior route fields in memory; do not create a sub-agent, packet document, or routing-only evidence pass.
- [ ] **Run routing once** — fully execute `agent-ops/skills/common/finalize-task-routing/SKILL.md` for build/review. Do not duplicate its decision rules in this skill.
- [ ] **Stop or accept**`needs_evidence` may rerun only after collecting all named new evidence; `blocked` stops without task-file mutation. Accept `routed` only when finalizer identity, closure, base/final basis, signals, grade, lane, and filenames satisfy the routing skill.
- [ ] **Freeze routed names** — use the returned basenames unchanged in Steps 4-6. If an input fact changes before write, invalidate both routes and perform this step once again on the changed input.
## Step 4 - Archive Existing Active Files
In `write` mode, complete this step before writing new active files. In `prepare-follow-up` mode, calculate the same counts and archive names but do not modify any repository file; code-review owns the later archive.
- Validate that the task directory contains at most one active `PLAN-(local|cloud)-G(0[1-9]|10).md`, at most one active `CODE_REVIEW-(local|cloud)-G(0[1-9]|10).md`, and at most one `USER_REVIEW.md`. Reject ambiguous or malformed active names.
- In `write` mode, ensure `.gitignore` has the Agent-Ops managed gitignore block before renaming any active file to `*.log` or creating local `agent-roadmap/current.md`. Prefer `source agent-ops/bin/ai-ignore.sh && agent_ops_ensure_gitignore_task_artifact_block .gitignore`; if the helper is unavailable, add or update a block containing `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, and `agent-roadmap/current.md`. In `prepare-follow-up` mode, only inspect the block and return `gitignore_repair_needed: true|false`; code-review performs any repair after preparation.
- Count existing `plan_*.log` as `current_plan_archive_number`. If an active plan exists, parse `current_build_lane` and `current_build_grade` from that active filename and set `current_plan_archive_name=plan_{current_build_lane}_{current_build_grade}_{current_plan_archive_number}.log`. Require that destination not to exist. In `write` mode rename that exact active file to the calculated name; in `prepare-follow-up` only return the name and number. Never use the newly routed build lane/grade to archive the old active plan.
- Count existing `code_review_*.log` as `current_review_archive_number`. If an active review exists, parse `current_review_lane` and `current_review_grade` from that active filename and set `current_review_archive_name=code_review_{current_review_lane}_{current_review_grade}_{current_review_archive_number}.log`. Require that destination not to exist. In `write` mode rename that exact active file to the calculated name; in `prepare-follow-up` only return the name and number. Never use the newly routed review lane/grade to archive the old active review.
- Count existing `user_review_*.log` as `current_user_review_archive_number`. If `USER_REVIEW.md` exists and its recorded user action or decision is resolved for replanning, set `current_user_review_archive_name=user_review_{current_user_review_archive_number}.log`; require that destination not to exist and rename it only in `write` mode.
- Compute `post_archive_plan_log_count`, `post_archive_review_log_count`, and `post_archive_user_review_log_count` from the filesystem after actual archive in `write` mode, or from the predicted addition of each current active file in `prepare-follow-up` mode.
Set `plan_number=post_archive_plan_log_count`. The new pair's future archive suffixes are `plan_log_number=post_archive_plan_log_count` and `review_log_number=post_archive_review_log_count`. These are intentionally different concepts from `current_plan_archive_number` and `current_review_archive_number`.
## Step 5 - Write Plan File
Render the complete plan in memory first. In `write` mode, write it to the routed plan basename. In `prepare-follow-up` mode, return the exact rendered body as `prepared_plan` and do not write it.
Header line must be exactly one of these forms:
```markdown
<!-- task={task_name} plan={plan_number} tag={TAG} -->
<!-- task=m-<milestone-slug>[/<subtask_dir>] plan={plan_number} tag={TAG} milestone-task=<task-id>[,<task-id>...] -->
```
Use the second form for every `m-*` task and the first form for every non-milestone task. The PLAN and review stub first lines must be identical.
Example:
```markdown
<!-- task=m-sample-capability/03+01,02_storage plan=0 tag=API milestone-task=sample-item -->
```
Required sections:
- Title.
- `For the Implementing Agent`: warn that filling implementation-owned `CODE_REVIEW-*-G??.md` sections is mandatory. Tell the implementer to run verification, fill actual notes/output, keep active files in place, and report ready for review; finalization is code-review-skill only. If blocked, the implementer records only exact blocker evidence, attempted commands/output, and resume conditions in implementation-owned evidence fields. It must not ask the user, call user-input tools, create control-plane stop files, classify the next state, archive logs, or write `complete.log`.
- `Background`: 2-4 sentences explaining why the work is needed.
- `Archive Evidence Snapshot`: include this section only when the plan resumes from `USER_REVIEW.md`, a prior archived review, or any archive evidence. Omit it for first-pass plans with no archive evidence. The section must contain only the archive facts needed to implement without rereading archive by default: prior task/archive paths, verdict, Required/Suggested/Nit summary, affected files, verification evidence, and any roadmap carryover. If exact prior context is still required, cite the specific archive file paths allowed to read; do not ask the implementer to search `agent-task/archive/**` broadly.
- `Finding Resolution Map`: for WARN/FAIL follow-ups only, use one row per Required/Suggested id: reviewer evidence, exact root cause, selected fix, mode, changed/satisfied precondition, and acceptance commands. Put every `direct-fix` file in `Modified Files Summary`. Do not include investigation tasks or solution alternatives. For an unordered dependency, emit no worker packet; return `status=blocked`, `blocked_reason=dependency-wait`, `next-task`, and resume condition.
- `Analysis`: on first pass, record the findings from Step 2 and the final routed output from Step 3. On WARN/FAIL follow-up, preserve the reviewer's analysis and selected fix, adding only source-consistency validation and routing facts; do not replace the diagnosis or propose alternatives. This section contains the actual findings that justify the plan's scope and decisions. Must include all of the following subsections:
- `Files Read`: list every source and test file read during analysis, with path. List verification-context source files only when they were actually present and read.
- `SDD Criteria`: for `SDD: 필요` Milestones, list the SDD path, status, first-line `milestone-task` ids, targeted Acceptance Scenario ids, and the Evidence Map rows that drive the plan. State explicitly how those rows shaped the implementation checklist and final verification. If the selected Milestone has `SDD: 불필요`, state the recorded reason. If the work is not Milestone-linked, state "not applicable".
- `Verification Context`: state whether a handoff was supplied, every source path actually read, concrete commands/criteria applied, preconditions, constraints, gaps, confidence, and repository-native fallback evidence. If required verification leaves the current checkout, include an `External Verification Preflight` record with runner, repo root/workdir, branch/HEAD/dirty state, source sync status, binary/artifact paths, required command help/version output, config path, runtime identity, ports/process state, external hosts, OS/arch assumptions, and the exact setup/sync/rebuild step or blocker derived from mismatches.
- `Test Coverage Gaps`: list each behavior change and whether existing tests cover it; explicitly note gaps.
- `Symbol References`: list renamed/removed symbols and every call site found, or state "none" if no symbols were changed.
- `Split Judgment`: for one plan, name the indivisible invariant or compact boundary; for split plans, list each child's stable contract, PASS evidence, and dependency. For dependent subtask plans, include each predecessor index and whether it is satisfied by an active or archived `complete.log`, missing, or ambiguous.
- `Scope Rationale`: state which files or areas were explicitly excluded from this change and why. This is the boundary justification — the implementing agent must not silently expand scope beyond what is recorded here.
- `Final Routing`: record `evaluation_mode`, finalizer, both targets' closure/grade/route, `large_indivisible_context`, positive loop-risk names/count, recovery signals, capability-gap evidence, and canonical filenames. Do not include or compare a previous loop's lane/G.
- `Implementation Checklist`: a top-level checklist the implementing agent must follow while coding. Include one item per implementation/verification unit; if the roadmap feature Task has `검증:`, keep that verification in the same checklist item instead of making a separate completion-criteria item. Include one item for whole-plan intermediate/final verification only when it is not already covered by the feature items. Make the last item exactly `- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.` Copy this checklist into the review stub's `Implementation Checklist` section with the same item text and order.
- One item per change: `### [TAG-1] Title`, `TAG-2`, etc.
- `Modified Files Summary`: table mapping files to item ids. This is the skill-owned implementation write boundary.
- Include exactly one `## Modified Files Summary` section and at least one exact workspace file path.
- Wrap every claimed file path in backticks. A bare path cell is invalid.
- Use repository-relative or canonical absolute file paths. Never use a glob (`*`, `?`, `[]`), directory path, workspace root, URL, path outside the workspace, malformed path, or prose placeholder as a claim.
- Enumerate only implementer- or reviewer-owned workspace files, including the active review evidence file and deterministic workspace evidence artifacts.
- For generated verification artifacts, choose deterministic exact workspace filenames or write them under a task-specific temporary directory outside the repository. Never substitute a directory or glob claim for dynamic filenames.
- Before writing or returning a prepared pair, inspect the rendered PLAN itself and confirm this section occurs exactly once, is non-empty, and satisfies every path rule above. For a follow-up, also confirm every `direct-fix` target in `Finding Resolution Map` is present here.
- `Final Verification`: runnable commands and expected outcome. Prefer commands from verified handoff facts when supplied; fill missing coverage from repository manifests, scripts, workflows, domain rules, and related tests, and record the source in `Analysis > Verification Context`. Commands must be exact and deterministic enough for the reviewer to rerun; use stable ordering for searches and state whether cached test output is acceptable. End this section with **"After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`."**
Each plan item must include:
- `Problem`: concrete problem with file:line references.
- `Solution`: exact approach and before/after code block for non-trivial changes. In a WARN/FAIL follow-up, materialize the reviewer's selected fix exactly; do not ask the worker to investigate, analyze the cause, or choose an approach.
- `Modified Files and Checklist`: exhaustive file-level checklist.
- `Test Strategy`: explicit write/skip decision. If writing tests, include path, test name, assertion goal, and fixtures. If skipping, justify.
- `Verification`: runnable commands and expected result.
Include `Dependencies and Execution Order` only when order matters.
For split multi-plan work, the `{subtask_dir}` directory name is the runtime source of truth. If a plan has a `NN+PP[,QQ...]_...` subtask directory name, `Dependencies and Execution Order` (legacy: `의존 관계 및 구현 순서`) must echo the decoded predecessor subtask directories under the same task group that must produce `complete.log` before implementation starts, and it must not add dependencies that are absent from the directory name. If a predecessor already completed, cite the active or archived `complete.log` path that satisfies it.
Quality rules:
- Exact line numbers in every Before snippet.
- Use the language's required override annotation/keyword wherever an abstract method is implemented.
- Include full import statements for new packages.
- List all call sites for renamed/removed symbols.
- Never write "add tests as needed"; decide up front.
- Do not cite files you did not read.
- Be concise. Write the minimum words needed to convey the decision or fact. No preamble, no restatement of context already in the plan, no closing summaries.
Test policy:
| Change | Test requirement |
|--------|------------------|
| Bug fix | Regression test required |
| New public API | Normal + boundary tests required |
| API rename | Existing test call-site updates usually enough |
| Internal refactor | Existing tests may be enough |
| Concurrency logic | Race/ordering test recommended |
Verification fidelity rules:
- Plan verification commands are a contract. The implementing agent must run them exactly as written.
- If a command must be changed, the implementing agent must record the replacement command and reason in `Deviations from Plan` (legacy: `계획 대비 변경 사항`), then paste the replacement command's actual stdout/stderr.
- Before claiming a tool is unavailable, run and record `command -v <tool>` or the project-equivalent check.
- Before a remote/field/external verification command assumes a checkout, binary, config, runtime identity, or listening port, the plan must include a preflight command that proves those assumptions or a setup command that makes them true.
- Do not download, generate, or leave verification tools inside the repository. Temporary tools belong outside the repo, such as under `/tmp`, and must not become task artifacts.
- For search commands whose output order may vary, specify deterministic options in the plan, for example `rg --sort path`.
- `Verification Results` (legacy: `검증 결과`) must contain actual stdout/stderr, not summarized or reconstructed output. If output is too long, record the saved output file path and the exact command used to create it.
- If mobile/UI verification has no progress for 2 minutes or times out, stop blind retries; collect focused stdout plus screenshot/window/UI-tree evidence when available, or record why capture is impossible.
- If the plan's pass condition says all leftovers must be intentional exceptions, any `변경 필요` item forces FAIL until resolved or explicitly reclassified with evidence.
- Decide in the plan whether cached test output is acceptable. If fresh execution matters, use the repository's test runner option that forces a fresh run or bypasses cached results, and record the exact command.
## Step 6 - Write Review Stub
Read `agent-ops/skills/common/plan/templates/review-stub-template.md` in full only after Step 3 returns `status: routed`.
Replace every occurrence of each token below:
- Scalar tokens: `{date}`, `{task_group}`, `{task_name}`, `{plan_number}`, `{TAG}`, `{milestone_task_metadata_or_omit}`, `{build_lane}`, `{build_grade}`, `{review_lane}`, `{review_grade}`, `{plan_log_number}`, `{review_log_number}`. Set `{milestone_task_metadata_or_omit}` to ` milestone-task=<ids>` for `m-*` and to an empty string otherwise.
- Plan-copy tokens: `{archive_evidence_snapshot_or_omit}`, `{implementation_checklist}`, `{review_checkpoints}`.
- Generated row/section tokens: `{implementation_completion_rows}` contains one row for every plan item, and `{verification_result_sections}` contains the fixed verification instructions plus every intermediate/final command from the plan.
Use the routed build/review grades independently. Remove optional plan-copy content by replacing its token with an empty string, not by leaving template instructions.
In `write` mode, write the rendered stub to the routed review basename. In `prepare-follow-up` mode, return it as `prepared_review` without writing.
Do not write or return a prepared pair when either routing target is not `routed`. After rendering, scan for the exact template-token inventory above and reject the output if any known token remains; do not reject unrelated braces in copied commands or code.
## Naming
| Tag | Use for |
|-----|---------|
| `API` | Public API changes |
| `REFACTOR` | Internal refactoring |
| `TEST` | Test additions/fixes |
| `REVIEW_<TAG>` | Follow-up fixes after review |
## Final Checklist
- In `write` mode, the routed `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` both exist under `agent-task/{task_name}/`. In `prepare-follow-up` mode, neither routed file was written; both exact bodies and basenames were returned while the verdict-appended current pair remained active.
- The plan skill directly checked the rendered PLAN before the pair was written or returned. Its single non-empty `Modified Files Summary` contains only exact workspace file claims and no glob or directory claim.
- In `write` mode, `.gitignore` has the Agent-Ops managed block that unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores local `agent-roadmap/current.md`. In `prepare-follow-up` mode, the block was only inspected and any needed repair was returned as `gitignore_repair_needed`.
- Single-plan work stores active files directly under `agent-task/{task_group}/`.
- Split work, if any, uses one shared `agent-task/{task_group}/` parent and one subtask directory per plan/review pair with names like `01_core`, `02+01_app_a_integration`, `03+01_app_b_integration`; dependency details live in the subtask directory name as `NN+PP[,QQ...]_subtask_name`.
- Split sibling indices follow topological dependency order: every predecessor is lower than its consumer, and every gap is explained by an unchanged existing predecessor or an occupied active/archive index.
- Milestone-linked work uses `agent-task/m-<milestone-slug>/` as the task group; non-roadmap task groups do not start with `m-`.
- Both first lines are identical. Non-milestone pairs match `<!-- task={task_name} plan={plan_number} tag={TAG} -->`; `m-*` pairs append exactly ` milestone-task=<task-id>[,<task-id>...]` before ` -->`.
- The review stub was rendered from `agent-ops/skills/common/plan/templates/review-stub-template.md` after routing and has no unresolved known template token.
- In `write` mode, previous active files, if any, were archived with lane/grade parsed from their own basenames and the correct current archive suffixes. In `prepare-follow-up` mode, those archive names were only predicted.
- In `write` mode when resuming from `USER_REVIEW.md`, it was archived to the calculated `current_user_review_archive_name` and the resolved user action or decision was recorded in the new plan.
- Every `m-*` pair has a non-empty, duplicate-free `milestone-task` list whose ids exist in the selected active Milestone; non-milestone pairs omit the field.
- `milestone-task` ids describe evidence contribution scope, not check-on-PASS completion. Split/follow-up pairs preserve their declared scope under the refinement and follow-up rules.
- If the selected Milestone has `SDD: 필요`, the plan's `Analysis > SDD Criteria` (legacy: `분석 결과 > SDD 기준`) proves that the implementation checklist and final verification were derived from the approved SDD Acceptance Scenarios and Evidence Map. Missing SDD mapping blocks plan creation.
- If the plan is a follow-up or resumes from prior archive evidence, it has `Archive Evidence Snapshot` and the review stub contains the identical section.
- `Analysis > Verification Context` records supplied handoff facts, source paths actually read, external preflight, gaps, confidence, and repository-native fallback evidence.
- Dependent split plans record predecessor completion using active sibling `complete.log` or matching archived `complete.log`; ambiguous archive matches are not guessed.
- Every plan item has problem, solution, checklist, test decision, and intermediate verification.
- The plan and review stub have matching `Implementation Checklist` (legacy: `구현 체크리스트`) item text/order; their final checkbox is the mandatory `CODE_REVIEW-*-G??.md` evidence item.
- `finalize-task-routing` ran once after the PLAN body was complete, used no routing-only evidence pass, counted only positive packet-local risk, kept capability/grade basis from being relabeled by escalation signals, and produced matching filenames.
- Review WARN/FAIL follow-ups entered through this plan skill and did not inherit or compare the archived lane/G.
- Every WARN/FAIL finding has one proven direct fix or ordered/satisfied dependency; only then is ownership closed, and verification does not repeat against an unchanged precondition.
- Every WARN/FAIL follow-up preserves reviewer-collected evidence, root cause, one selected fix, affected implementation/test targets, and acceptance commands; it contains no worker-owned diagnosis, investigation, or solution choice.
- The plan's implementer instructions and review stub limit local implementation agents to implementation/test/evidence work and keep user-review classification plus control-plane stop files out of their input and ownership.
- The review stub has a clearly marked `Review-Only Checklist` (legacy: `코드리뷰 전용 체크리스트`) owned only by the review agent.
- Routed review file completion table lists every plan item.
- In `prepare-follow-up`, no repository file was mutated and the returned prepared basenames/bodies, `plan_number`, current archive names/numbers, post-archive log counts, and `gitignore_repair_needed` are complete; in `write`, prior active state was archived with its own parsed route and both new active files were written.
Report the plan path, scope, key files, minimal verification, and any directly required decision or explicit dependency.

View file

@ -2,98 +2,27 @@
# Code Review Reference - {TAG}
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `Implementation Checklist`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> Execute the plan's selected root cause, scope, files, and dependency decisions as written. Do not choose another owner, narrow/expand the write boundary, or replace a fix with another verification attempt.
> If implementation is blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence fields.
> Do not ask the user directly, present choices, call user-input tools, create control-plane stop files, or classify the next state.
> Finalization (`Code Review Result`, log rename, `complete.log`, archive moves, `Review-Only Checklist`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.
## Goal
## Overview
<one-line implementation goal>
date={date}
task={task_name}, plan={plan_number}, tag={TAG}
## Changed Areas
{archive_evidence_snapshot_or_omit}
- <file or component>
## For the Review Agent
## Implementation Notes
> **[REVIEW AGENT ONLY]** The finalization steps below are review-agent only. Implementing agents must not execute this section.
- 없음
Compare implementation of each item against source files. Run the applicable verification commands directly and record fresh output in `Verification Results`; implementation-owned output is handoff evidence, not a substitute for reviewer verification. If implementation is present, repair missing or stale verification output instead of failing solely for insufficient recorded evidence. When verification exposes a defect, collect the necessary data, determine the exact root cause, and select one concrete fix before generating the follow-up plan; never delegate investigation or remedy selection to the worker.
Review completion means the following steps are finished:
## Verification Run
1. Append verdict and `review_rework_count` / `evidence_integrity_failure` routing signals.
2. Archive `CODE_REVIEW-{review_lane}-{review_grade}.md``code_review_{review_lane}_{review_grade}_{review_log_number}.log` and `PLAN-{build_lane}-{build_grade}.md``plan_{build_lane}_{build_grade}_{plan_log_number}.log`.
3. If PASS, write `complete.log` and move active task directory to `agent-task/archive/YYYY/MM/{task_name}/`. If WARN/FAIL, fully write the next filesystem state required by the code-review skill.
4. If PASS and task group is `m-<milestone-slug>`, preserve the first-line `milestone-task` metadata in `complete.log` and report it for the runtime aggregation event. Roadmap state evaluation belongs to `sync-milestone-workstate`.
5. Check applicable `Review-Only Checklist` items at the final `.log` location before reporting.
- 없음
---
## Review Result
## Implementation Item Completion
- Verdict: pending
- Required findings: 없음
- Suggested findings: 없음
- Residual risk: 없음
| Item | Status |
|------|---------|
{implementation_completion_rows}
## Implementation Checklist
{implementation_checklist}
## Review-Only Checklist
> **[REVIEW AGENT ONLY]** This checklist is used only by the review agent.
> Implementing agents must not modify or check this section.
- [ ] Append one verdict of `PASS`, `WARN`, or `FAIL` and verified `review_rework_count`, `evidence_integrity_failure` to `Code Review Result`.
- [ ] Verify that verdict, `Dimension Assessment`, and Required/Suggested/Nit classifications match.
- [ ] Run applicable required verification and record fresh command/output; repair reviewer-reconstructable evidence gaps instead of forwarding them to another plan.
- [ ] For every Required/Suggested finding, record reviewer-collected `Evidence`, exact `Root Cause`, and one `Selected Fix` with affected files/symbols/tests and acceptance commands before creating a follow-up plan.
- [ ] Archive active `CODE_REVIEW-*-G??.md` to `code_review_{review_lane}_{review_grade}_{review_log_number}.log`.
- [ ] Archive active `PLAN-*-G??.md` to `plan_{build_lane}_{build_grade}_{plan_log_number}.log`.
- [ ] Verify that the Agent-Ops managed block in `.gitignore` unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores `agent-roadmap/current.md`.
- [ ] If PASS, write `complete.log` based on `agent-ops/skills/common/code-review/templates/complete-log-template.md` and leave no active `.md` files.
- [ ] If PASS, move active task directory `agent-task/{task_name}/` to `agent-task/archive/YYYY/MM/{task_name}/` and update this checklist at the final archive path.
- [ ] If PASS and task group is `m-<milestone-slug>`, preserve and report `milestone-task` metadata for runtime aggregation, without modifying roadmap or directly calling `update-roadmap`.
- [ ] If PASS for split work, remove empty active parent `agent-task/{task_group}/` or verify it was kept due to remaining siblings/files.
- [ ] If WARN/FAIL, write the next filesystem state matching code-review verdict and do not write `complete.log`.
## Deviations from Plan
_Record any deviations from the plan and the rationale here._
## Key Design Decisions
_Record key design decisions here._
## Reviewer Checkpoints
{review_checkpoints}
## Verification Results
{verification_result_sections}
---
> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.
## Section Ownership
| Section | Owner | Note |
|---------|-------|------|
| Header comment, Overview, Review Agent Instructions | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) |
| Archive Evidence Snapshot | Fixed at stub creation from plan when present | Implementing agent uses it as default prior-loop context; read only the specific archive files cited there when more detail is required |
| Implementation Item Completion (item names) | Fixed at stub creation | Implementing agent checks `[ ]``[x]` only |
| Implementation Checklist (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]``[x]` only |
| Review-Only Checklist | Review agent only | Implementing agent must not modify or check this section |
| Deviations from Plan, Key Design Decisions | Implementing agent | Replace placeholder text with actual content |
| Reviewer Checkpoints | Fixed at stub creation | Pre-filled from plan |
| Verification Results (section headings + commands) | Implementing agent, then review agent | Implementing agent records initial output; review agent reruns applicable commands and may fill, replace, or append fresh verified output before verdict. Implementing-agent command changes require a `Deviations from Plan` entry |
| Code Review Result | Review agent appends | Not included in stub |
This file is a review aid. Filling every field, archiving it, or producing additional metadata is not required for the implementation itself to be complete.

View file

@ -1,129 +1,37 @@
---
name: prepare-epic-work-items
description: 현재 또는 지정 Milestone의 정확히 한 Epic을 작은 직접 작업과 큰 PLAN/CODE_REVIEW pair로 변환하고, fresh one-shot 자가검토, refine-plans 세분화, 최종 재검토와 push까지 수행할 때 사용한다. "현 마일스톤의 X Epic에서 작은 작업은 바로 처리하고 큰 작업은 plan으로 작성해", "X 마일스톤 Y Epic 작업 준비해" 요청에서 사용한다.
description: Prepare one Epic by implementing small tasks directly and creating concise plans only for genuinely large tasks.
---
# Prepare Epic Work Items
## 목적
## Purpose
정확히 한 Epic을 한 사이클로 준비한다. 작은 작업은 구현·검증하고 큰 작업은 실행 가능한 PLAN/CODE_REVIEW pair로 만든 뒤 두 번의 fresh 검토와 한 번의 세분화를 거쳐 remote branch에 보존한다.
Turn one Epic into executable work with **verification gate minimization**. Small tasks are implemented directly; large tasks receive one concise plan. Repeated review, refinement, routing, commit, push, or dispatcher barriers are not automatic.
## 입력
## Procedure
- `workspace`: 준비된 feature worktree 절대 경로 (필수)
- `target-milestone`: 활성 Milestone slug 또는 경로 (필수)
- `target-epic`: 정확한 Epic id 또는 이름 (필수)
- `execution-catalog`: 런타임이 주입한 agent-model 실행 카탈로그 경로. `AGENT_TASK_EXECUTION_CATALOG`로 대신 주입할 수 있다. (필수)
- `planner-target`: 카탈로그에 선언된 materialize/refine 실행 target id. `AGENT_TASK_PLANNER_TARGET`로 대신 주입할 수 있다. (필수)
- `review-target`: 카탈로그에 선언된 initial/final review target id. `AGENT_TASK_REVIEW_TARGET`로 주입하거나 생략하면 `planner-target`과 같다. (선택)
- `retry`: terminal failure의 원인을 사용자가 해소한 뒤 같은 Epic 상태를 재개할 때만 사용한다. (선택)
- `batch-task-ids`: 상위 `prepare-milestone-workspace`가 고정한 선택 Epic Task id 합집합. 직접 호출에서는 사용하지 않는다. (내부 선택)
1. Resolve one exact Milestone and Epic.
2. Classify each Task:
- direct work when it is local, bounded, and safe;
- plan work when it spans meaningful ownership or contract boundaries.
3. Implement direct work and run the smallest related test.
4. Create at most one plan per coherent large change unless independent parallel work clearly benefits from a split.
5. Report prepared and completed Task ids.
## 범위 계약
## Real blockers
- 한 실행은 Epic 하나만 다룬다. Epic 범위 요청은 `prepare-milestone-workspace` coordinator가 문서 순서대로 하나씩 실행한다.
- 실행 identity는 `<milestone-slug>:<epic-id>`다.
- standalone 사이클의 다음 Epic은 현재 Epic의 모든 Task가 workstate sync에서 완료된 `EPIC_COMPLETED` 뒤에 시작한다.
- 상위 coordinator가 고정한 batch에서는 현재 Epic의 `EPIC_WORK_ITEMS_READY`도 다음 선택 Epic 준비를 허용한다. 이때 현재 Epic pair는 유지하고, 다음 Epic cycle은 batch Task id 합집합 안의 앞선 pair를 구조 검증하되 소유하거나 변경하지 않는다.
- 실행 중 Epic cycle의 batch Task id 합집합은 바꾸지 않는다. 준비 terminal 뒤에는 같은 Epic을 이후 단독/복수 batch의 일부로 다시 검증할 수 있다.
- `EPIC_WORK_ITEMS_READY`는 큰 작업 plan이 준비됐다는 뜻이며 구현 완료가 아니다.
- 개별 `EPIC_WORK_ITEMS_READY`는 dispatcher 시작 신호가 아니다. 복수 선택의 dispatcher gate는 상위 coordinator의 `MILESTONE_WORK_ITEMS_READY` 하나다.
- 같은 identity를 다시 실행하면 active pair, USER_REVIEW, runtime state를 먼저 대조하고 중복 plan을 만들지 않는다.
- a directly required product decision;
- security or credential authorization;
- data-loss or irreversible external change risk;
- an explicit user-created dependency;
- dirty-worktree or branch mutation risk.
작은 작업은 아래를 모두 만족해야 한다.
Milestone state, SDD status, implementation-lock metadata, consistency preflight, review files, routing grade, evidence formatting, commit/push, and optional environment validation are not blockers.
- 하나의 응집된 변경이고 한 번의 bounded 실행과 명시 검증으로 완료할 수 있다.
- 새 API, wire, schema, migration, 외부 side effect 또는 책임 경계 변경이 없다.
- 사용자·SDD 결정이 필요하지 않고 큰 작업의 write set과 충돌하지 않는다.
## Prohibited
하나라도 거짓이거나 불명확하면 큰 작업으로 분류한다. 고정 LOC나 파일 수만으로 분류하지 않는다.
## 실행 절차
1. **Epic을 고정한다**
- target Milestone이 `[계획]` 또는 `[진행중]`, 구현 잠금 해제인지 확인한다.
- `### Epic: [<epic-id>] <title>`을 정확히 하나 찾고 그 아래 Task id를 고정한다.
- standalone에서 다른 Epic의 active pair가 있거나 target이 모호하면 `FAILED`로 멈춘다. 상위 batch에서는 선택 Task id 합집합 밖 pair 또는 Epic 경계를 가로지르는 pair만 거부한다.
2. **foreground 사이클을 실행한다**
- 아래 스크립트를 한 번 실행하고 execution-layer event wait를 유지한다.
```bash
python3 agent-ops/skills/common/prepare-epic-work-items/scripts/run_epic_cycle.py \
--workspace "$WORKSPACE" \
--milestone "$MILESTONE" \
--epic "$EPIC" \
--execution-catalog "$EXECUTION_CATALOG" \
--planner-target "$PLANNER_TARGET" \
--review-target "$REVIEW_TARGET"
```
- agent, model, 실행 명령과 provider별 옵션은 스킬이나 스크립트에 고정하지 않고 카탈로그 target의 opaque metadata와 argv template에서 가져온다.
- target id와 카탈로그 revision은 실행 evidence에 보존한다. `--retry`는 동일 카탈로그 계약과 target을 사용한다.
- 상위 batch에서 호출할 때만 고정된 Task id 합집합을 `--batch-task-ids`로 전달한다.
- 스크립트는 카탈로그가 지시한 각 target을 새 one-shot session으로 실행한다.
- model stdout/stderr는 git common dir의 locator log에만 저장한다. caller stdout에는 lifecycle/attention event만 출력한다.
3. **상태 전이를 따른다**
- `MATERIALIZE`: 작은 작업을 먼저 구현·검증하고, 변경된 source를 기준으로 큰 작업에 `plan`을 적용한다.
- `INITIAL_REVIEW`: fresh reviewer가 전체 변경과 PLAN/CODE_REVIEW stub을 재검토하고 누락을 수정한다. 구현 전 stub에 공식 `code-review`를 실행하지 않는다.
- 첫 검토가 유효하면 변경을 commit/push한다.
- `REFINE`: target Epic Task id를 가진 모든 미착수 pair에 `refine-plans`를 한 번 적용한다. 분리 가치가 없으면 `no-change`를 허용한다.
- `FINAL_REVIEW`: fresh reviewer가 child scope 합집합, 중복, dependency, `milestone-task`, routing, 검증을 다시 확인하고 수정한다.
- 최종 validator가 통과하면 남은 변경을 commit/push하고 `EPIC_WORK_ITEMS_READY`를 낸다.
4. **중단 상태를 처리한다**
- 사용자만 결정할 범위·설계 문제는 roadmap SDD `USER_REVIEW.md`로 남기고 유효한 stop artifact를 commit/push한 뒤 `USER_REVIEW`로 끝낸다.
- agent-task 구현 review gate가 아니므로 preparation agent가 `agent-task/**/USER_REVIEW.md`를 만들지 않는다.
- agent exit, invalid pair, plan validator, git commit/push 실패는 자동 삭제 없이 `FAILED`로 끝낸다.
- foreground wait가 끊겼지만 동일 PID/start-token의 one-shot이 살아 있으면 state를 `tracking`으로 유지하고 `AGENT_TRACKING`만 낸다. 재호출은 새 agent를 만들지 않는다.
- tracking handle이 종료되면 `AGENT_RECOVERY_REQUIRED`에서 멈춘다. locator 확인 뒤 `--retry`하면 현재 artifact를 먼저 채택·검증한다. 검증 실패 뒤의 명시적 `--retry`만 새 one-shot을 허용한다.
- `EPIC_WORK_ITEMS_READY` 뒤 dispatcher와 workstate sync가 Task와 active pair를 모두 닫으면 같은 identity 재호출이 clean HEAD를 재검증해 `EPIC_COMPLETED`로 승격한다.
## 상태 이벤트
- `EPIC_SCOPE_RESOLVED`
- `MATERIALIZE_STARTED`, `MATERIALIZE_FINISHED`
- `INITIAL_REVIEW_STARTED`, `INITIAL_REVIEW_FINISHED`
- `INITIAL_CHECKPOINT_PUSHED`
- `REFINE_STARTED`, `REFINE_FINISHED`
- `FINAL_REVIEW_STARTED`, `FINAL_REVIEW_FINISHED`
- `FINAL_ARTIFACTS_PUSHED`
- `AGENT_TRACKING`, `AGENT_RECOVERY_REQUIRED`, `AGENT_RESULT_RECOVERED`
- `EPIC_BATCH_VALIDATED` (상위 batch의 deterministic barrier 검증)
- `EPIC_WORK_ITEMS_READY`, `EPIC_COMPLETED`, `USER_REVIEW`, `FAILED`
routine event는 caller 판단을 요구하지 않는다. caller는 `USER_REVIEW`, `AGENT_RECOVERY_REQUIRED`, 복구 불가능한 `FAILED`, terminal completion에서만 깨어난다.
## 실행 결과 검증
- [ ] active PLAN/CODE_REVIEW가 항상 pair이고 첫 줄 metadata가 일치하는가
- [ ] 모든 `milestone-task`가 target Epic Task id의 비어 있지 않은 부분집합인가
- [ ] 상위 batch 호출이면 다른 pair도 선택 batch 합집합 안에 있고 target Epic 경계를 가로지르지 않는가
- [ ] 모든 PLAN이 dispatcher `--validate-plan`을 통과하는가
- [ ] refine 전후 Task id 합집합과 scope가 보존됐는가
- [ ] repository에 unresolved template token이나 preparation runtime state가 추적되지 않는가
- [ ] 완료 checkpoint가 현재 feature branch remote에 push됐는가
- 검증 실패 시: partial artifact를 commit하지 않고 locator와 복구 조건을 남겨 `FAILED`로 끝낸다.
## 출력 형식
```text
Epic work preparation
- identity: <milestone-slug>:<epic-id>
- direct work: <completed task ids 또는 없음>
- plans: <active pair paths 또는 없음>
- refinement: <split | no-change>
- event: <EPIC_WORK_ITEMS_READY | EPIC_COMPLETED | USER_REVIEW | FAILED>
- remote: <branch와 pushed commit>
```
## 금지 사항
- 여러 Epic을 한 agent context에서 처리하지 않는다.
- 같은 session을 self-review에 resume하지 않는다.
- plan/refine agent가 nested agent나 task dispatcher를 실행하지 않는다.
- 구현 전 CODE_REVIEW stub에 공식 code-review verdict를 쓰지 않는다.
- timer polling, LLM keepalive, routine model stream 중계를 하지 않는다.
- validation 실패 상태를 commit/push하거나 force push하지 않는다.
- Do not run automatic initial review → refine → final review loops.
- Do not create USER_REVIEW stop artifacts unless the user explicitly requests a file handoff.
- Do not auto-start a dispatcher, commit, or push unless requested.
- Do not expand beyond the selected Epic.

View file

@ -1,136 +1,33 @@
---
name: prepare-milestone-workspace
description: 계획 상태의 Milestone을 명시 workspace의 Git Flow feature worktree로 준비하거나, 사용자가 지정한 현재 workspace에서 대상 feature branch를 생성·재사용해 선택한 한 개·범위·남은 모든 Epic을 검토된 작업으로 변환하고 전체 준비 배리어 뒤 dispatcher를 시작할 때 사용한다. "../sample-feature-worktree 위치에 X 작업 준비해", "현재 워크스페이스에서 현 마일스톤 시작해", "현 마일스톤에 두 번째 에픽 작업 시작해", "X 마일스톤에 1,2번째 에픽까지 작업 시작해", "현 마일스톤에 남은 에픽 작업들 시작해" 요청에서 사용한다.
description: Prepare a requested Milestone branch or worktree and selected Epic work with only Git data-safety checks.
---
# Prepare Milestone Workspace
`<workspace>에 <milestone> 작업 준비해`는 workspace 생성 모드로, `현|<이름> 마일스톤에 <범위> Epic 작업 시작해`는 현재 workspace 실행 모드로 해석한다. 두 모드 모두 정합성 확인부터 선택 Epic 준비와 dispatcher 전환까지 수행한다.
## Purpose
## 목적
Prepare the requested workspace and work items without roadmap readiness gates. The only blocking checks are those needed to avoid overwriting user changes, branch collisions, credential/security issues, or an explicit user-stated dependency.
계획 가능한 Milestone 하나를 검증된 `feature/<milestone-slug>` workspace로 전환한다. 현재 workspace 실행 모드에서 사용자가 지정한 workspace가 Git Flow develop branch이면 그 자리에서 대상 feature branch를 생성·전환하고, 이미 대상 feature branch이면 재사용한다. 선택 Epic 전체가 준비된 뒤에만 구현 dispatcher를 시작한다. 의미 정합성은 roadmap 스킬이, branch/worktree/current와 batch lifecycle은 번들 스크립트가 소유한다.
## Procedure
## 입력
1. Resolve one exact active Milestone and requested workspace.
2. Refuse destructive branch/worktree mutation when the checkout is dirty, the target path is owned by another worktree, or the branch target is ambiguous.
3. Create or reuse `feature/<milestone-slug>` according to the repository's existing Git Flow setup.
4. Select the requested Epic range and call `prepare-epic-work-items` only for those Epics.
5. Start a dispatcher only when the user requested execution and prepared runnable work exists.
- `target-milestone`: 활성 Milestone 이름, id, slug 또는 경로 (필수)
- `workspace`: 생성 모드에서는 feature worktree 절대 경로 또는 develop repository root 기준 상대 경로가 필수다. 현재 workspace 실행 모드에서는 현재 repository root를 사용한다.
- `execution-catalog`: 런타임이 주입한 agent-model 실행 카탈로그 경로. `AGENT_TASK_EXECUTION_CATALOG`로 대신 주입할 수 있다. (필수)
- `planner-target`: 카탈로그에 선언된 Epic materialize/refine 실행 target id. `AGENT_TASK_PLANNER_TARGET`로 대신 주입할 수 있다. (필수)
- `review-target`: 카탈로그에 선언된 review 실행 target id. `AGENT_TASK_REVIEW_TARGET`로 주입하거나 생략하면 `planner-target`과 같다. (선택)
- `target-epics`: `remaining`, `first-incomplete`, 정확한 Epic id/title의 comma list, 또는 문서 순서의 1-based inclusive range `N..M`. 생략하면 `first-incomplete`를 사용한다. (선택)
- `retry`: 기록된 attention/recovery 조건을 사용자가 해소한 뒤 batch를 재개할 때만 사용한다. (선택)
## Non-gates
생성 모드의 첫 번째 위치 표현(`<workspace>`)은 workspace로, 두 번째 표현(`<milestone>`)은 대상 Milestone으로 각각 확정한다. 상대 workspace는 develop repository root 기준으로 해석한다. 현재 workspace 실행 모드의 `현 마일스톤`은 그 workspace의 `current.md`가 가리키는 단일 Milestone으로 확정하고, 이름을 지정하면 같은 `current.md`와 정확히 일치해야 한다. branch 이름으로 target을 선택하지 않는다. `두 번째 Epic``2..2`, `두 번째 Epic까지``1,2번째 Epic까지``1..2`, `세 번째부터 네 번째 Epic까지``3..4`, `남은 Epic`은 문서 순서의 미완료 Epic 전체를 선택하는 `remaining`으로 변환한다.
- Milestone state, former implementation-lock fields, SDD status, consistency checks, plan routing grade, review history, push state, and full validation matrices do not block preparation.
- An open product decision pauses only the selected Epic work that needs it.
- A missing optional execution target or live environment is reported; it does not invalidate already prepared independent work.
## 사전 조건
## Safety
- 생성 모드는 clean Git Flow develop checkout과 정확히 `[계획]`인 Milestone을 요구한다.
- 현재 workspace 실행 모드는 일치하는 local `current.md`와 clean/upstream-synced workspace를 요구하고 Milestone `[계획]` 또는 `[진행중]`을 허용한다. 현재 branch가 target slug와 일치하는 `feature/<milestone-slug>`이면 재사용하고, Git Flow develop branch이면 같은 workspace에서 target feature branch를 생성·전환한다. 기록된 active batch 재개만 상태 소유 변경을 허용한다.
- 두 모드 모두 `구현 잠금: 해제`, `결정 필요: 없음`이어야 한다.
- `sync-milestone-workstate mode=consistency-check``ready`여야 한다.
- remote와 `gitflow.branch.develop`, `gitflow.prefix.feature`를 확인할 수 있어야 한다.
- 선택 target의 카탈로그 검증과 비대화식 one-shot capability probe가 branch 생성 전에 성공해야 한다.
- Never force-push, overwrite dirty work, delete branches/worktrees automatically, or expose credentials.
- Preserve any partially created branch/worktree and report the exact recovery condition after a failure.
## 절차
## Output
1. **대상과 정합성을 고정한다**
- `agent-roadmap/current.md`를 선택 근거로만 사용하고 target이 명시됐으면 target을 우선한다.
- `sync-milestone-workstate mode=consistency-check`를 먼저 실행한다.
- 기계적으로 고칠 수 있는 drift는 보고된 owner 스킬로 갱신하고 commit/push한 뒤 consistency check를 다시 실행한다.
- 사용자만 결정할 수 있는 drift는 `roadmap-sdd mode=review-ready``agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md`로 남기고 commit/push한 뒤 `USER_REVIEW`로 멈춘다. pre-plan 문제에 `agent-task/**/USER_REVIEW.md`를 만들지 않는다.
2. **실행 모드를 선택한다**
- workspace 위치를 명시한 준비 요청은 생성 모드로 실행한다.
```bash
python3 agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py \
--repo "$REPO" \
--milestone "$MILESTONE" \
--workspace "$WORKSPACE" \
--epics "$EPICS" \
--execution-catalog "$EXECUTION_CATALOG" \
--planner-target "$PLANNER_TARGET" \
--review-target "$REVIEW_TARGET"
```
- agent, model, 실행 명령과 provider별 옵션은 스킬이나 스크립트에 고정하지 않고 주입된 카탈로그 target에서 가져온다.
- 스크립트는 develop HEAD와 remote develop의 일치, target probe, branch 충돌, worktree 소유권을 mutation 전에 검사한다.
- branch는 Milestone id가 아니라 파일 basename을 사용한 `feature/<milestone-slug>`다.
- 기존 branch/worktree는 정확히 같은 branch·경로이고 clean할 때만 재개한다.
- remote branch 생성 뒤 후속 단계가 실패해도 branch/worktree를 자동 삭제하지 않는다.
- `Epic 작업 시작해` 요청은 현재 workspace 실행 모드로 foreground 실행한다.
```bash
python3 agent-ops/skills/common/prepare-milestone-workspace/scripts/prepare_workspace.py \
--existing-workspace \
--workspace "$CURRENT_WORKSPACE" \
--milestone "$MILESTONE" \
--epics "$EPICS" \
--execution-catalog "$EXECUTION_CATALOG" \
--planner-target "$PLANNER_TARGET" \
--review-target "$REVIEW_TARGET"
```
- 현재 workspace가 Git Flow develop branch이면 별도 worktree를 만들지 않고 그 workspace에서 target feature branch를 생성·전환한다.
- 현재 workspace가 target feature branch도 develop branch도 아니거나 `current.md` target이 다르면 다른 worktree를 탐색하지 않고 `FAILED`로 멈춘다.
- `remaining`에 미완료 Epic이 없으면 agent/dispatcher를 시작하지 않고 완료 event로 종료한다.
- 두 모드 모두 실행 중 caller LLM이 timer polling, `ps`, state 파일 검사 또는 중복 실행을 하지 않는다.
3. **선택 Epic batch를 준비한다**
- `WORKSPACE_READY` 뒤 스크립트가 선택 Epic을 문서 순서대로 하나씩 `prepare-epic-work-items`에 전달한다.
- 각 Epic은 별도 fresh one-shot context를 사용한다. 앞선 Epic의 `EPIC_WORK_ITEMS_READY` plan은 같은 batch의 다음 Epic 준비 동안 유지한다.
- 두 개 이상이면 마지막 Epic 준비 뒤 fresh cross-Epic review를 한 번 수행해 scope union, dependency, write set, metadata, routing과 검증을 교정하고 push한다.
- `USER_REVIEW`, `AGENT_RECOVERY_REQUIRED`, `AGENT_TRACKING`, `FAILED`가 발생하면 batch를 멈추고 dispatcher를 시작하지 않는다.
4. **전체 준비 배리어 뒤 dispatcher로 전환한다**
- 모든 선택 Epic이 `EPIC_WORK_ITEMS_READY` 또는 `EPIC_COMPLETED`이고 deterministic batch validation과 모든 push가 끝난 경우에만 `MILESTONE_WORK_ITEMS_READY`를 낸다.
- active plan이 있으면 공통 `orchestrate-agent-task-loop` dispatcher에 런타임 카탈로그를 주입하고 같은 task group `m-<milestone-slug>``--dry-run`을 먼저 실행한 뒤 live를 정확히 한 번 시작한다.
- 모든 선택 Epic이 `EPIC_COMPLETED`이면 dispatcher를 생략한다.
- foreground dispatcher가 종료될 때까지 caller는 timer polling이나 상태 파일 검사를 하지 않는다. batch/dispatcher PID와 start token은 git common dir 상태에 기록해 재진입 중복 실행을 막는다.
## lifecycle event
- `PREFLIGHT_READY`: mutation 전 검증 완료
- `FEATURE_BRANCH_PUSHED`: remote feature branch 준비 완료
- `WORKSPACE_READY`: worktree와 local current 준비 완료
- `MILESTONE_WORK_ITEMS_READY`: 선택 Epic 전체 준비와 cross-Epic 검증·push 완료
- `DISPATCHER_DRY_RUN_FINISHED`, `DISPATCHER_STARTED`, `DISPATCHER_TRACKING`, `DISPATCHER_BLOCKED`
- `MILESTONE_PREPARATION_COMPLETED`: 선택 Epic 구현과 workstate sync까지 완료, 또는 all-direct라 dispatcher 생략
- `USER_REVIEW`: 사전 정합화 또는 연결된 Epic 준비에서 사용자 결정이 필요해 정상 정지
- `FAILED`: 안전하게 계속할 수 없음
## 실행 결과 검증
- [ ] 생성 모드와 현재 workspace 실행 모드 모두 최종 branch가 `gitflow.prefix.feature + milestone file slug`인가
- [ ] branch가 remote에 존재하고 upstream이 연결됐는가
- [ ] 요청 workspace가 정확히 해당 branch의 clean worktree인가
- [ ] workspace-local `agent-roadmap/current.md`가 대상 Milestone만 가리키는가
- [ ] 선택 Epic의 Task id 합집합 밖 active pair가 없는가
- [ ] 복수 Epic이면 cross-Epic review와 push가 완료됐는가
- [ ] dispatcher dry-run이 live보다 먼저이고 `MILESTONE_WORK_ITEMS_READY` 전에는 live가 시작되지 않았는가
- [ ] state와 locator가 repository 문서가 아니라 git common dir 아래에 있는가
- 검증 실패 시: branch/worktree를 삭제하지 않고 `FAILED` event와 복구 조건을 보고한다.
## 출력 형식
```text
Milestone workspace preparation
- milestone: <path>
- branch: <feature/milestone-slug>
- workspace: <absolute path>
- epics: <selected Epic ids in document order>
- event: <MILESTONE_PREPARATION_COMPLETED | USER_REVIEW | AGENT_RECOVERY_REQUIRED | DISPATCHER_BLOCKED | FAILED>
- next: <completed | user action | recovery condition>
```
## 금지 사항
- `[계획]`이 아니거나 잠긴 Milestone의 branch를 만들지 않는다.
- consistency check의 `refresh-required``ready`로 간주하지 않는다.
- 사용자 소유 변경이 있는 develop checkout이나 기존 workspace를 덮어쓰지 않는다.
- 현재 workspace 실행 모드에서 Git Flow develop branch는 target feature branch로 전환한다. 그 외 target이 다른 feature/topic branch나 다른 `current.md`를 자동 전환하지 않는다.
- 선택 Epic 중 하나라도 attention/terminal failure 상태면 dispatcher를 시작하지 않는다.
- 복수 Epic batch에서 개별 `EPIC_WORK_ITEMS_READY`만 보고 dispatcher를 먼저 시작하지 않는다.
- `git push --force`, destructive rollback, branch/worktree 자동 삭제를 하지 않는다.
- caller LLM이 주기적으로 process나 상태 파일을 모니터링하지 않는다.
Report Milestone, branch, workspace, selected Epics, prepared work, execution started or not started, and any real safety blocker.

View file

@ -1,212 +1,72 @@
---
name: roadmap-sdd
description: 로드맵 Milestone에 녹아 있는 SDD 설계 게이트를 판정, 생성, 갱신, 사용자 리뷰 대기, 잠금 해제, archive 처리할 때 사용한다. 사용자가 SDD, spec gate, 설계 게이트, SDD 필요 여부, SDD 승인 준비, SDD 사용자 리뷰, SDD 잠금 해제, SDD archive를 요청하거나, 큰 Milestone의 구현 잠금이 SDD 필요 상태일 때 사용한다.
description: Create or update an optional Milestone design document when a large contract or lifecycle change benefits from a stable design reference.
---
# Roadmap SDD
## 목적
## Purpose
큰 Milestone에서 로드맵만으로 부족한 계약, 상태 전이, 수용 시나리오, 검증 근거를 `agent-roadmap/sdd/` 아래에 기록한다.
SDD는 로드맵과 분리된 별도 운영물이 아니라 Milestone `구현 잠금`을 해제하고, 이후 Milestone 구현 계획이 따라야 할 설계 입력을 고정하는 하위 설계 게이트다.
`SDD: 필요` Milestone의 구현 계획은 승인된 SDD의 Acceptance Scenario와 Evidence Map에서 구현 범위, 검증, 완료 evidence를 역산해야 한다.
Use an SDD as a concise design reference for a large or ambiguous change. An SDD is not an approval gate and does not automatically block planning, implementation, review, completion, or archive.
## 모드
## When to use
- `classify`: Milestone 또는 신규 작업 설명이 SDD 대상인지 판정한다.
- `create`: SDD 초안을 만든다.
- `update`: 기존 SDD를 갱신한다.
- `check-gate`: SDD 잠금, 사용자 리뷰, Acceptance Scenario, Evidence Map 연결성을 확인한다.
- `review-ready`: 사용자 결정이 필요한 항목을 `USER_REVIEW.md`로 만든다.
- `resolve-review`: 사용자의 답변을 SDD에 반영하고 `USER_REVIEW.md``user_review_N.log`로 보낸다.
- `archive`: Milestone archive와 함께 SDD를 archive 경로로 이동할 준비 상태인지 확인한다.
Use this skill when the user asks for an SDD or when documenting one of these materially improves the requested work:
## 구조
- cross-repository ownership or contract changes;
- API, protocol, schema, or persistent state transitions;
- permissions, credentials, irreversible external writes, rollback, or data retention;
- a product decision that cannot be inferred from current code and rules.
```text
agent-roadmap/
sdd/
<phase-slug>/
<milestone-slug>/
SDD.md
USER_REVIEW.md
user_review_0.log
archive/
sdd/
<phase-slug>/
<milestone-slug>/
SDD.md
user_review_*.log
```
Do not create an SDD for a local refactor, documentation cleanup, test addition, small UI change, or an implementation that already follows an established contract.
- `USER_REVIEW.md`는 필요한 경우에만 존재한다.
- `user_review_N.log`는 해결된 사용자 리뷰 기록이다.
- 완료 또는 폐기된 Milestone의 SDD는 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 이동한다.
- SDD 경로는 같은 Milestone의 slug를 그대로 사용한다. 별도 SDD slug를 만들지 않는다.
## Modes
## 표준 형식
- `create`: create the smallest useful design reference.
- `update`: update the affected sections only.
- `review`: list only user-owned product decisions that are directly required.
- `archive`: move the SDD with its completed or discarded Milestone.
- `SDD.md`는 반드시 `agent-ops/skills/common/_templates/roadmap-sdd-template.md`의 top-level 섹션을 같은 순서로 사용한다.
- `Source of Truth`, `State Machine`, `Acceptance Scenarios`, `Evidence Map` 표는 템플릿의 컬럼을 유지한다.
- 값이 아직 없으면 섹션을 삭제하지 말고 `없음`, `확인 필요`, 또는 잠금 항목으로 남긴다.
- `update`는 기존 SDD의 내용을 갱신하더라도 표준 섹션과 순서를 유지한다. 누락된 표준 섹션이 있으면 먼저 복원한 뒤 변경을 반영한다.
- `check-gate`는 표준 섹션이나 필수 표 컬럼이 누락된 SDD를 `invalid`로 보고하고, Milestone 구현 잠금 해제 대상으로 보지 않는다.
- SDD별 추가 설명은 `작업 컨텍스트` 또는 해당 표준 섹션 안에 넣고 임의 top-level 섹션을 늘리지 않는다.
- SDD 안에서 Milestone, Phase, 계약 문서, `USER_REVIEW.md`, 후속 SDD 같은 문서 포인터를 남길 때는 raw path만 쓰지 말고 `[표시 제목](상대경로)` Markdown 링크로 쓴다.
- SDD 링크 target은 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/` 디렉터리 기준 상대경로로 쓴다. 예: `[Milestone 문서](../../../phase/<phase-slug>/milestones/<milestone-slug>.md)`, `[PHASE.md](../../../phase/<phase-slug>/PHASE.md)`, `[USER_REVIEW.md](USER_REVIEW.md)`.
- 실제 생성/갱신한 SDD에는 `<phase-slug>`, `<milestone-slug>`, `<path>` 같은 placeholder가 들어간 링크 target을 남기지 않는다. 템플릿 placeholder는 실제 파일 위치 기준 상대경로 또는 `없음`으로 치환한다.
- 코드 source path나 machine-readable identity는 raw 값이 필요하면 유지할 수 있다.
## Structure
## SDD 대상 판정
Use `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`. Keep only sections useful to the design:
아래 중 하나라도 해당하면 `SDD: 필요`로 판정한다.
- location and status;
- problem and non-goals;
- source of truth;
- state or lifecycle, when applicable;
- interface contract, when applicable;
- acceptance scenarios, when useful;
- open decisions;
- related contracts and dependencies.
- cross-repo 계약 또는 프로젝트 간 source of truth가 있다.
- Plane, Jira, Mattermost 같은 외부 provider 상태를 변경한다.
- lifecycle, state machine, 사용자 승인 gate, archive 자동화, work item sync에 영향을 준다.
- idempotency, retry, identity map, revision 보존이 필요하다.
- API, proto, config, env, DB/schema, 이벤트 계약을 바꾼다.
- field smoke, 원격 runner, 사용자 소유 환경이 완료 근거의 일부다.
- 실패 처리 방식이 제품 판단, 보안, 비용, 권한, 데이터 보존에 영향을 준다.
Do not add empty tables or placeholder sections merely to satisfy a template.
아래에만 해당하면 `SDD: 불필요`로 판정한다.
## User decisions
- 단일 repo 내부의 작고 국소적인 리팩터링이다.
- 문서 정리, 테스트 보강, 작은 UI 보강이다.
- Milestone Task의 `검증:`과 일반 plan/code-review 루프만으로 완료 판단이 충분하다.
- 기존 SDD 또는 agent-contract를 그대로 소비하고 새 설계 결정이 없다.
- Ask only for product direction, ownership, permission, cost, retention, or irreversible behavior that the agent cannot infer.
- Record the decision in the SDD or Milestone `결정 사항`.
- A pending decision pauses only the implementation part that depends on it.
- Do not create approval checkboxes, `SDD 잠금`, unlock steps, or a mandatory `USER_REVIEW.md` lifecycle.
## Milestone 연결
## Evidence
SDD가 필요한 Milestone은 `구현 잠금`에 아래 필드를 둔다.
- Acceptance scenarios and evidence mappings are optional aids.
- Tests, code, commits, and user confirmation may demonstrate completion without SDD-specific metadata.
- Do not require `complete.log`, `milestone-task`, `Roadmap Completion`, or code-review output.
```md
- 상태: 잠금
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/<phase-slug>/<milestone-slug>/SDD.md)
- 잠금 해제 조건:
- [ ] SDD 잠금이 해제되어 있다
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다
- [ ] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다
- [ ] Evidence Map이 완료 시 `complete.log` 첫 줄의 `milestone-task` id별 집계와 최종 검증 evidence로 검증 가능하게 연결되어 있다
- 결정 필요: 없음
```
## Procedure
SDD가 불필요한 Milestone은 사유를 남긴다.
1. Read the target active Milestone and any matching contract index entry.
2. Confirm that an SDD is requested or materially useful.
3. Create or update only the necessary sections.
4. Link contracts rather than copying their source text.
5. Report open decisions without creating a workflow lock.
6. Check changed links and `git diff --check`.
```md
- SDD: 불필요
- SDD 사유: 단일 repo 내부 변경이며 외부 계약, 상태 머신, provider mutation이 없다.
```
## Prohibited
## SDD 잠금
SDD 문서는 자체 잠금을 가진다.
- `SDD 잠금: 잠금`이면 Milestone `구현 잠금` 해제 대상이 아니다.
- `USER_REVIEW.md`가 존재하면 사용자 답변 전까지 SDD 잠금을 해제하지 않는다.
- 사용자 결정이 필요 없는 기술 세부는 agent가 코드, 규칙, 기존 계약을 근거로 채우고 잠금 항목으로 만들지 않는다.
- 모든 잠금 항목이 해결되고 사용자 리뷰가 없으면 SDD 상태를 `[승인됨]`, SDD 잠금을 `해제`로 둔다.
- SDD 잠금이 해제되어야 Milestone `구현 잠금`도 해제 후보가 된다.
사용자 리뷰가 필요한 항목:
- source of truth 선택
- 상태 전이 의미 변경
- 사용자 승인, 검토, 폐기 흐름 변경
- 외부 provider 쓰기 동작 추가
- cross-repo 책임 경계 변경
- scope 확대/축소
- 보안, 비용, 데이터 보존, 권한 영향
- 실패 시 처리 정책이 제품 판단인 경우
사용자 리뷰가 필요 없는 항목:
- 기존 코드/문서/rule에서 답이 명확한 세부
- 기존 agent-contract를 그대로 따르는 인터페이스
- 일반 파일 구조, 테스트 명령, Evidence Map 작성
- 구현자가 plan/code-review 루프에서 검증할 수 있는 기술 선택
## 실행 절차
### classify
1. 관련 Milestone 또는 신규 작업 설명을 읽는다.
2. SDD 대상 판정 기준을 적용한다.
3. 결과를 `필요`, `불필요`, `불명확` 중 하나로 보고한다.
4. `필요`이면 Milestone `구현 잠금`에 해당 Milestone 파일 위치 기준 `SDD 문서` Markdown 링크와 잠금 해제 조건을 갱신한다.
5. 신규 Milestone 생성 또는 `[스케치] -> [계획]` 승격 흐름에서 호출된 경우, `classify`에서 멈추지 않고 같은 턴에 `create`까지 이어간다. 사용자만 결정할 항목이 없으면 승인 가능한 SDD로 만들고, 사용자 결정이 있으면 SDD 초안과 `USER_REVIEW.md`를 함께 만든다.
### create
1. `agent-ops/skills/common/_templates/roadmap-sdd-template.md`를 읽는다.
2. 대상 Milestone의 목표, 범위, 기능 Task, 범위 제외, 구현 잠금을 읽는다.
3. 필요하면 `agent-contract/index.md`를 읽고 매칭 계약 원문을 링크한다. 계약 본문을 SDD에 복제하지 않는다.
4. 표준 템플릿의 top-level 섹션, 섹션 순서, 필수 표 컬럼을 유지해 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`를 만든다.
5. 사용자 결정이 필요한 항목이 있으면 `review-ready`를 수행한다. 없으면 SDD 상태를 `[승인됨]`, SDD 잠금을 `해제`로 둘 수 있다.
6. SDD가 `[승인됨]`이고 SDD 잠금이 `해제`이며 `USER_REVIEW.md`가 없으면 같은 흐름의 `update-roadmap` 갱신에서 Milestone `구현 잠금` 해제 후보로 반영한다.
### update
1. 기존 SDD와 Milestone을 읽는다.
2. 변경 요청이 문제, source of truth, 상태 전이, interface, scenario, evidence 중 어디에 해당하는지 판정한다.
3. 표준 섹션 또는 필수 표 컬럼이 누락되어 있으면 먼저 복원한다.
4. 사용자 결정이 필요한 변경이면 SDD 잠금을 `잠금`으로 두고 `USER_REVIEW.md`를 갱신한다.
5. 기술 세부 보강이면 SDD 본문과 Evidence Map만 갱신한다.
### check-gate
1. Milestone `구현 잠금``SDD` 필드를 확인한다.
2. `SDD: 불필요`이면 `not-required`로 보고한다.
3. `SDD: 필요`인데 SDD 문서가 없으면 `blocked`로 보고한다.
4. SDD가 표준 top-level 섹션 또는 필수 표 컬럼을 갖추지 못했으면 `invalid`로 보고한다.
5. SDD 상태가 `[승인됨]`이 아니거나 `SDD 잠금``잠금`이면 `blocked`로 보고한다.
6. `USER_REVIEW.md`가 있으면 `blocked`로 보고한다.
7. Acceptance Scenario가 Milestone 기능 Task id와 연결되어 있는지 확인한다.
8. Evidence Map이 완료 시 같은 Milestone task group의 `complete.log``milestone-task` id별로 집계하고 최종 검증 evidence와 대조할 수 있도록 scenario, task, evidence가 매핑되어 있는지 확인한다.
9. 모두 충족하면 `pass`로 보고한다.
### review-ready
1. `agent-ops/skills/common/_templates/roadmap-sdd-user-review-template.md`를 읽는다.
2. 사용자만 결정할 항목만 추린다.
3. `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md`를 만든다.
4. SDD의 `SDD 잠금``잠금`으로 둔다.
5. 채팅으로 즉시 선택지를 묻지 않고 파일 경로와 필요한 결정만 보고한다.
### resolve-review
1. `USER_REVIEW.md`와 SDD를 읽는다.
2. 사용자의 답변을 관련 SDD 섹션과 `사용자 리뷰 이력`에 반영한다.
3. `USER_REVIEW.md``user_review_N.log`로 이동한다.
4. 남은 잠금 항목이 없으면 SDD 상태를 `[승인됨]`, SDD 잠금을 `해제`로 바꾼다.
5. SDD gate가 pass이면 Milestone `구현 잠금`을 해제할 수 있다고 보고한다. 직접 해제는 요청 또는 runtime/update-roadmap 흐름에 따른다.
### archive
1. Milestone이 `[완료]` 또는 `[폐기]`인지 확인한다.
2. 활성 SDD 디렉터리가 있으면 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 이동한다.
3. 활성 `PHASE.md` 또는 Milestone archive 링크와 SDD archive 경로가 어긋나지 않는지 확인한다.
4. `USER_REVIEW.md`가 남아 있으면 archive하지 말고 해결 필요로 보고한다.
## 출력 형식
```markdown
## SDD 결과
- mode: `<classify|create|update|check-gate|review-ready|resolve-review|archive>`
- milestone: <[Milestone 문서](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md) | 해당 없음>
- sdd: <[SDD.md](agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md) | 없음>
- 결과: `<pass | blocked | not-required | created | updated | review-required | archived | invalid>`
- 잠금: `<해제 | 잠금 | 해당 없음>`
- 사용자 리뷰: <없음 | [USER_REVIEW.md](agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md) | [user_review_N.log](agent-roadmap/sdd/<phase-slug>/<milestone-slug>/user_review_N.log)>
- 다음 단계: `<없음 | 사용자 리뷰 필요 | Milestone 구현 잠금 해제 가능 | SDD 작성 필요>`
```
## 금지 사항
- SDD 본문에 agent-contract 계약 원문을 복제하지 않는다.
- 사용자 결정이 필요한 항목을 chat 질문으로 바로 던지지 않는다. `USER_REVIEW.md`로 남긴다.
- 작은 작업에 SDD를 강제하지 않는다.
- `USER_REVIEW.md`가 남아 있는데 SDD 상태를 `[승인됨]`으로 두지 않는다.
- SDD gate가 막힌 Milestone의 구현 잠금을 해제하지 않는다.
- Do not turn the SDD into an implementation or completion gate.
- Do not create an SDD solely because a schema, API, lifecycle, or field smoke is mentioned.
- Do not duplicate contract source text.
- Do not block unrelated work on an open design decision.

View file

@ -1,25 +1,15 @@
# 공통 스킬 라우터
라우팅 우선순위:
라우팅 원칙:
- project skill 경로를 선택한 뒤 같은 이름의 `agent-ops/skills/private/<skill-name>/SKILL.md`가 있으면 private skill을 우선한다. 없으면 선택한 project skill을 사용한다.
- project skill과 짝이 없는 private skill은 `agent-ops/rules/private/rules.md`에 명시적으로 라우팅한다. private skill 전체를 탐색하지 않는다.
- SDD/spec gate 자체의 작성, 갱신, gate 확인, 사용자 리뷰, 잠금 해제는 `roadmap-sdd`로 보낸다.
- 로드맵/마일스톤 생성 또는 갱신 요청 안에 SDD 필요 여부와 gate 연결이 포함되면 `create-roadmap` 또는 `update-roadmap`을 진입점으로 삼고, 해당 흐름에서 `roadmap-sdd` create/check를 처리한다.
- agent-spec은 구현 후 현재 상태를 설명하는 living spec이다. SDD/spec gate와 구분하며, 현재 구현 스펙 생성은 `create-spec`, 갱신은 `update-spec`으로 보낸다.
- "마일스톤 완료해도 될지 검토", "현 마일스톤 종료 검토", "현재 마일스톤 닫고 다음 마일스톤 지정"처럼 종료 판단, spec sync, roadmap archive, 다음 Milestone 지정을 함께 요구하는 요청은 `complete-milestone`으로 보낸다. 이 흐름 안에서 `update-spec`을 필수 gate로 수행한다. 사용할 테스트 환경 규칙이 있으면 먼저 `update-test mode=resolve-context`의 중립 `Verification Context`를 전달하고, 없거나 불완전하면 complete-milestone의 repository-native fallback을 사용한다.
- 구현 계획 요청에서 선택 Milestone의 구현 잠금이 남아 있으면 `plan`은 구현 계획을 만들지 않고 잠금 차단을 보고한다.
- SDD 생성/갱신/잠금 해제는 `roadmap-sdd` 또는 `update-roadmap` 요청으로 처리한다.
- 런타임이 새 형식의 `origin-task`/`complete-log` 완료 이벤트를 전달하고 첫 줄에 `milestone-task`가 있으면 `sync-milestone-workstate`로 처리해 같은 Milestone task group의 evidence를 집계한다. first-line metadata가 없고 legacy `Roadmap Completion`만 있는 과거 단건 이벤트는 `update-roadmap` 호환 흐름으로 처리할 수 있다.
- active/archive `complete.log`, 관련 파일, git history를 종합해 Milestone 작업 상태를 복구하거나 확인하는 요청은 `sync-milestone-workstate`로 처리한다.
- 현재 또는 지정 Milestone의 시작 전 정합성 체크, 전체 프로젝트 작업현황과 Milestone의 현재 코드·spec·contract drift 확인, Plan 전 리프레시 필요성 판정은 `sync-milestone-workstate mode=consistency-check`로 처리한다. 이 모드는 read-only이며 기존 완료 evidence용 `check-only`와 구분한다.
- "정합성 체크해", "확인해"는 `consistency-check` 보고에서 멈춘다. "정합성 맞춰줘", "리프레시해", "검사하고 반영해"는 `consistency-check` 결과를 먼저 만든 뒤 미반영 완료 Task는 `sync-milestone-workstate mode=sync`, Milestone/queue/lock은 `update-roadmap`, SDD는 `roadmap-sdd`, living spec은 `update-spec`, contract는 `update-contract`로 넘긴다. 갱신 뒤 `consistency-check`를 다시 실행해 `ready`를 확인한 경우에만 연결된 `plan` 요청을 계속한다.
- plan 요청에 사용할 테스트 환경 규칙이 있으면 `update-test mode=resolve-context`로 read-only `Verification Context`를 만든 뒤 `plan`에 전달한다. 규칙이 없거나 매칭되지 않으면 파일을 생성하지 않고 plan의 repository-native fallback을 사용한다.
- `sync-agent-ui``plan-required`로 라우팅한 작업은 plan pair 생성 뒤 `sync-agent-ui mode=prepare-code-work`로 task/UI 매핑을 기록한다. 일반 code-review PASS와 exact `complete.log` 생성 뒤에는 원래 `task-path``completion-log``sync-agent-ui mode=reconcile-completion`에 전달해 해당 매핑만 정합화한다.
- pending UI task가 WARN/FAIL follow-up plan으로 교체되면 새 pair 생성 뒤 `prepare-code-work`를 다시 실행한다. 매핑 범위가 실제로 달라진 경우에만 검증 후 state helper의 `--replace`를 사용한다.
- pending UI task를 `refine-plans`로 분할하거나 sibling reindex해 경로를 바꾼 경우에는 refine 완료 뒤 `sync-agent-ui mode=prepare-code-work`를 호출한다. 기존 경로는 `previous-task-path`, status 대상 전체를 닫는 child 하나는 새 `task-path`로 넘겨 매핑을 rebind하고, scope/evidence가 달라질 때만 검증 후 `--replace`를 사용한다.
- `sync-agent-ui``milestone-required`로 라우팅한 작업은 `update-roadmap`이 exact active Milestone을 확정한 뒤 `sync-agent-ui mode=prepare-milestone-work`로 Milestone/UI 매핑을 기록한다. 일반 Milestone 문서에는 agent-ui 전용 완료 필드를 넣지 않는다.
- Milestone 종료 요청에서 exact target이 `.sync-state.json.pending_milestone_work`에 있으면 `complete-milestone mode=check-only`를 먼저 실행한다. 종료 가능 근거를 `sync-agent-ui mode=reconcile-milestone-completion`에 전달해 성공 또는 동일 evidence의 already-reconciled를 확인한 뒤에만 `complete-milestone mode=close`를 실행한다. UI 정합화가 실패하면 close하지 않는다.
- 최우선 방향은 **검증 게이트 최소화**다. skill routing은 workflow를 연결하는 허가 체인이 아니며 기존 자동 연쇄 게이트도 만들거나 복원하지 않는다.
- 사용자가 요청한 산출물이나 동작에 직접 대응하는 skill 하나를 선택한다.
- project skill을 선택했고 같은 이름의 private skill이 있으면 private skill을 우선한다. private skill 디렉터리 전체를 탐색하지 않는다.
- skill은 다른 skill을 자동 선행 게이트로 호출하지 않는다. 추가 skill은 사용자가 함께 요청했거나 현재 산출물을 만드는 데 직접 필요한 경우에만 사용한다.
- SDD, spec, plan, review, test context, workstate sync는 서로 독립적인 선택적 workflow다.
- Milestone의 상태·구현 잠금·SDD 상태·evidence 형식 때문에 plan이나 구현을 자동 차단하지 않는다. 현재 구현에 꼭 필요한 사용자 결정이나 명시적 외부 의존성만 해당 작업을 보류한다.
- 정합성 확인은 사용자가 요청했을 때 read-only로 수행한다. 확인 결과를 이유로 다른 sync/update workflow를 자동 연쇄 실행하지 않는다.
- 완료 이벤트의 `milestone-task``Roadmap Completion`은 정확한 대상 매칭을 돕는 힌트이며, 특정 형식이 없다는 이유만으로 실제 완료 반영을 막지 않는다.
| 요청 키워드 | SKILL.md |
|------------|----------|
@ -59,13 +49,8 @@
| agent-ops pull해, agent-ops 가져와, agentic-framework에서 가져와, agent-ops 내려받아 | `agent-ops/skills/common/sync-pull/SKILL.md` |
| 도메인 업데이트, domain rule 갱신, 도메인 검토, domain 스캔 | `agent-ops/skills/common/update-domain-rule/SKILL.md` |
라우팅 우선순위:
세부 라우팅:
- `X에 Y 작업 준비해`처럼 workspace 위치와 대상 Milestone이 함께 명시되면 `prepare-milestone-workspace` 생성 모드를 선택한다. 상대 workspace는 develop repository root 기준으로 해석한다. 이 형식에서 workspace 위치가 없으면 확인을 요청한다.
- `현 마일스톤에 N번째 에픽 작업 시작해`, `Y 마일스톤에 1,2번째 에픽까지 작업 시작해` 또는 `현|Y 마일스톤에 남은 에픽 작업들 시작해`는 같은 스킬의 현재 workspace 실행 모드를 선택한다. `현 마일스톤`은 현재 workspace의 `current.md` 단일 target, 이름 있는 Milestone은 같은 workspace의 `current.md`와 정확히 일치하는 target만 허용한다. 현재 branch가 대상 `feature/<milestone-slug>`이면 그대로 재사용하고, Git Flow develop branch이면 사용자가 지정한 그 workspace에서 대상 feature branch를 생성·전환한 뒤 실행한다. `N번째``N..N`, `N번째까지``1..N`, `1,2번째까지``1..2`, `남은 에픽`은 문서 순서의 미완료 Epic 전체를 뜻하는 `remaining`으로 해석한다. 다른 feature/topic branch이거나 target이 다르면 workspace를 추정·전환하지 않고 거부한다.
- 두 모드 모두 선택 Epic을 각각 `prepare-epic-work-items`로 준비하되 전체 `MILESTONE_WORK_ITEMS_READY` 전에는 dispatcher를 시작하지 않는다.
- 한 Epic 안에서 작은 작업 직접 처리와 큰 작업 plan 작성을 함께 요청하면 `prepare-epic-work-items`를 선택한다. 이미 존재하는 plan만 세분화하는 요청과 새로운 plan만 작성하는 요청에는 이 스킬을 선택하지 않는다.
- 이미 생성된 미착수 pair의 분할만 요청하면 lane과 관계없이 `refine-plans`를 선택한다. 새 plan 작성이나 구현 범위 재분석이 포함되면 `plan`을 선택한다.
- `refine-plans` 대상이 아닌 PLAN/CODE_REVIEW 작성 또는 재작성이 요청 범위에 포함되면 `plan`을 선택한다. `plan`이 최종 단계에서 `finalize-task-routing`을 필수 호출한다.
- lane/G/canonical filename 판단만 요청되고 plan 문서 작성은 요청되지 않았을 때만 `finalize-task-routing`을 직접 선택한다.
- 코드 리뷰 요청은 `code-review`를 선택한다. WARN/FAIL follow-up은 `code-review -> plan -> finalize-task-routing` 순서를 유지한다.
- workspace와 Milestone 준비를 함께 요청하면 `prepare-milestone-workspace`, 한 Epic의 작업 분류를 요청하면 `prepare-epic-work-items`를 선택한다.
- 기존 plan 분할만 요청하면 `refine-plans`, 새 plan 작성이나 재작성은 `plan`, routing 판단만 요청하면 `finalize-task-routing`을 선택한다.
- 코드 리뷰 요청은 `code-review`를 선택한다. WARN/FAIL 결과가 나와도 후속 plan이나 routing은 자동 호출하지 않고 결과와 최소 수정 사항만 보고한다.

View file

@ -1,251 +1,52 @@
---
name: sync-milestone-workstate
description: 현재 또는 지정 Milestone을 시작하기 전 전체 활성 workstate와 대상의 코드·SDD·spec·contract 정합성을 검사해 Plan 준비 상태를 판정하거나, 진행·종료 시 complete.log·파일·git evidence를 Task별로 집계해 상태를 동기화하는 절차. "현재 마일스톤 정합성 체크해", "특정 마일스톤 정합성 체크해", Plan 전 리프레시, 완료내역 반영, 체크박스 재동기화 요청에서 사용한다.
description: Compare one active Milestone with current repository evidence or update its Task checkboxes without introducing readiness gates.
---
# sync-milestone-workstate
# Sync Milestone Workstate
## 목적
## Purpose
현재 또는 지정 Milestone의 시작 전 정합성과 진행·종료 workstate를 실제 repository evidence에 맞춘다.
Reconcile one active Milestone with current code, tests, commits, task logs, and user-provided evidence. The workflow is informational or updates existing Task state; it does not decide whether planning or implementation is allowed.
- 시작 전 `consistency-check`는 프로젝트 전체 활성 작업현황을 얕게 확인하고 대상 Milestone의 목표·범위·기능·SDD·spec·contract 가정을 현재 코드와 깊게 대조해 Plan 준비 상태를 판정한다.
- 진행·종료의 `check-only``sync`는 같은 Milestone task group의 완료 evidence를 현재 기능 Task 계약에 집계한다.
## Modes
`consistency-check``check-only`는 read-only다. 이 스킬은 새 작업을 배치하거나 구현 계획을 만들지 않는다. 시작 전 발견한 미반영 완료는 같은 스킬의 `sync`로 검증·반영하고, 문서 drift는 `update-roadmap`, `roadmap-sdd`, `update-spec`, `update-contract` 책임으로 넘긴다.
- `check`: read-only comparison of the Milestone and current repository.
- `sync`: update Task checkboxes and status from sufficient evidence.
새 계약의 `complete.log` 첫 줄 `milestone-task=<id>[,<id>...]`는 해당 완료 작업의 evidence가 어느 Milestone Task에 기여하는지 나타내는 인덱스다. 이 값만으로 Task 완료를 선언하지 않는다. 같은 Milestone task group의 모든 완료 로그를 id별로 모은 뒤 현재 Task 설명, Task 안의 `검증:`, 관련 파일/git evidence, 필요한 SDD Acceptance Scenario와 Evidence Map을 함께 평가해 계약 전체가 충족된 Task만 `[x]`로 바꾼다.
## Scope
한 plan이 여러 Task id에 기여하거나 여러 plan이 같은 Task id에 기여할 수 있다. 따라서 plan 하나의 PASS와 Milestone Task 하나의 완료를 1:1로 가정하지 않는다.
1. Resolve one exact active Milestone from the user target or `current.md`.
2. Read that Milestone, its Phase, and only the code/tests/contracts directly related to its Tasks.
3. Use exact `complete.log` files when provided. Search the same `m-<milestone-slug>` task group only when completion history is required.
4. Treat `milestone-task` and `Roadmap Completion` as optional indexing hints.
5. Do not require SDD status, Evidence Map, plan/review logs, spec sync, queue readiness, or prior consistency checks.
## 언제 호출할지
## Task evaluation
- 사용자가 "현재 마일스톤 정합성 체크해", "<이름> 마일스톤 정합성 체크해"처럼 현재 또는 지정 Milestone을 시작하기 전 실제 프로젝트 상태와 대조해 달라고 요청할 때
- 사용자가 마일스톤 시작, Plan 전 마일스톤 리프레시, 전체 프로젝트 작업현황과 대상 Milestone 정합성 확인을 요청할 때
- 사용자가 현 마일스톤과 작업현황 동기화, 마일스톤 완료내역 반영, 체크박스 재동기화를 요청할 때
- code-review가 `m-*` PASS completion event와 `complete-log`를 전달했을 때
- `complete.log``milestone-task` id별 evidence를 모아 현재 Task 계약을 평가해야 할 때
- 과거 `Roadmap Completion` 또는 task metadata가 없는 완료 기록을 새 계약과 함께 복구해야 할 때
- agent-task 기록이 없지만 실제 파일/git 기준 완료 가능성을 감사해야 할 때
- Mark a Task complete when its described capability or artifact exists and any genuinely required `검증:` is satisfied.
- Code, tests, commits, task logs, and explicit user evidence are all valid.
- Missing metadata does not negate observable completion.
- Missing optional live/full-cycle validation is residual risk, not an automatic incomplete result.
- An unresolved product decision affects only the Task that needs it.
## 입력
## Status update
- `target-milestone`: 활성 Milestone 이름, slug, 또는 경로. 없으면 `agent-roadmap/current.md`의 단일 활성 Milestone을 사용한다. (선택)
- `complete-log`: 방금 완료된 exact `complete.log` 경로. `sync` 또는 `check-only`에서 이 파일을 우선 검증하되 같은 Milestone task group의 다른 완료 로그도 집계한다. (선택)
- `mode`: `consistency-check`, `sync`, `check-only` 중 하나다. 기본값은 `sync`다. `consistency-check``check-only`에서는 어떤 파일도 수정하지 않는다. (선택)
- Keep the current status while incomplete Tasks remain unless the user requests another status.
- When all functional Tasks are complete, the Milestone may move directly to `[완료]`; `[검토중]` is optional.
- Do not consult or recreate `구현 잠금` or SDD approval state.
- Check an explicit workspace dependency only when the Milestone has a matching entry created from a user-stated dependency.
## 모드 경계
## Validation
| mode | lifecycle | 책임 | 쓰기 |
|------|-----------|------|------|
| `consistency-check` | 시작 전 | 전역 활성 workstate를 얕게 확인하고 대상 Milestone과 현재 repository의 semantic drift 및 Plan 준비 상태를 판정 | 금지 |
| `check-only` | 진행·종료 | 완료 evidence를 Task별로 집계하고 반영 후보만 판정 | 금지 |
| `sync` | 진행·종료 | 검증된 완료 evidence를 Task 체크와 허용된 Milestone/Phase/current 상태에 반영 | 허용 |
- `check` modifies no files.
- `sync` changes only the target Milestone and necessary Phase/current labels.
- Run `git diff --check` after writes.
- Report evidence used, Tasks changed, remaining work, and residual risk without a readiness verdict such as blocked/refresh-required.
`check-only`는 완료 evidence dry-run이고 `consistency-check`는 시작 전 semantic drift 감사다. 두 모드를 같은 의미로 사용하지 않는다.
## Prohibited
## consistency-check 실행 절차
1. **대상 Milestone 확정**
- `target-milestone`이 있으면 활성 `agent-roadmap/phase/*/milestones/*.md`에서 정확히 하나를 찾는다.
- 없으면 `agent-roadmap/current.md`의 단일 활성 Milestone을 사용한다.
- 대상이 없거나 둘 이상이거나 archive 경로이면 어떤 파일도 수정하지 않고 `blocked`로 보고한다.
2. **프로젝트 활성 workstate snapshot 구성**
- `agent-roadmap/current.md``priority-queue.md`는 존재할 때만 읽고, 없으면 만들지 않은 채 각각 `local current 없음`, `전역 실행 순서 없음`으로 기록한다. 명시 target이 있으면 current 부재만으로 차단하지 않고, queue 부재·파싱 오류는 `refresh-required`로 판정한다.
- `ROADMAP.md`의 Phase 흐름, 모든 active Phase `PHASE.md`의 Milestone 흐름, active Milestone 문서의 H1·상태·구현 잠금 상태와 `.agent-roadmap-sync/locks.yaml` 존재 시 관련 lock을 얕게 읽는다.
- 각 prefix의 active lane head, 대상의 선행 차단과 실제 진행 중인 참조 대상에 대한 동시 차단, Milestone/Phase/current 라벨 불일치와 구현 잠금 상태를 확인한다. prefix 그룹 순서와 일반적인 관련성은 의존성으로 만들지 않는다.
- `current.md`는 활성 후보 창이지 실제 진행 상태가 아니다. 실제 진행 중 여부는 사용자 명시와 active task evidence로 구분한다.
- `agent-task/`의 active task group 이름과 PLAN/CODE_REVIEW/USER_REVIEW 존재 상태를 얕게 확인한다. unrelated task 본문을 전부 읽지 않는다.
- `git status --short`로 checkout의 활성 변경을 확인하되 사용자 변경을 수정하거나 완료 evidence로 간주하지 않는다.
3. **대상 Milestone 계약 읽기**
- `목표`, `상태`, `구현 잠금`, `범위`, `기능`, `범위 제외`, `작업 컨텍스트`와 관련 Phase/queue 설명을 읽는다.
- `SDD: 필요`이면 SDD의 현재 책임 경계, Acceptance Scenario, Evidence Map과 같은 디렉터리의 `USER_REVIEW.md` 존재 여부를 확인한다.
- 대상 task group이 이미 있으면 이 스킬의 완료 로그 수집·Task별 evidence 집계 기준을 재사용해 구현됐지만 Milestone에 반영되지 않은 capability가 있는지 확인한다. 다른 slug의 archive는 읽지 않는다.
4. **현재 repository 기준선 확인**
- 프로젝트와 대상 경로의 domain rule을 먼저 읽는다.
- `agent-spec/`이 있으면 `rules-agent-spec.md`, `agent-spec/index.md`, 매칭되는 현재 spec만 읽는다.
- API, wire, config, schema 또는 컴포넌트 간 계약이 관련되며 `agent-contract/index.md`가 있으면 index와 매칭되는 active contract만 읽는다.
- Milestone `작업 컨텍스트`의 관련 경로에서 `rg --files`, symbol 검색, 현재 코드·config·proto·테스트를 확인한다. 필요할 때만 관련 경로의 `git log`, `git show`, `git diff`를 사용한다.
- 전체 repository를 무차별 감사하지 않고 전역 workstate는 얕게, 대상 Milestone과 직접 의존 기반만 깊게 확인한다.
5. **semantic drift 분류**
- `already-implemented`: 현재 capability가 구현됐지만 Task/evidence에 반영되지 않았다.
- `stale-assumption`: Milestone 또는 SDD가 현재 존재하지 않는 owner, 경로, 상태 전이, API/wire/config 구조를 전제한다.
- `dependency-drift`: 선행 기반이나 공통 coordinator가 변경돼 계획한 구현·검증·retry/identity 경계를 다시 써야 한다.
- `scope-drift`: 현재 기능 Task가 중복·누락됐거나 현재 책임 경계와 충돌한다.
- `queue-lock-drift`: 실제 의존·배타적 변경 책임과 priority queue blocker 또는 workspace lock이 충돌한다. 경로 중복이나 일반적인 관련성만으로 동시 차단을 만들지 않는다.
- `evidence-gap`: 구현 가능성 판단에 필요한 spec, contract, test 또는 provenance가 부족하다.
- 아직 구현되지 않은 미래 capability 자체는 정상 planned delta다. 현재 구조와 충돌하거나 이미 대체된 경우에만 drift로 분류한다.
6. **Plan 준비 상태 판정**
- `ready`: 대상이 `[계획]` 또는 `[진행중]`, 구현 잠금과 SDD gate가 해제되고 blocker가 없으며 Plan 입력을 바꿀 semantic drift가 없다.
- `refresh-required`: 대상 identity는 유효하지만 Milestone/SDD/spec/contract/queue를 현재 기준으로 갱신해야 Plan 범위를 확정할 수 있다.
- `blocked`: 대상이 모호하거나 `[스케치]`·`[보류]`, 해당 prefix의 active lane head가 아니거나 구현 잠금·사용자 결정·SDD review·선행/동시/외부 의존이 남아 Plan을 시작할 수 없다.
7. **read-only 보고와 후속 라우팅**
- 어떤 파일도 수정하지 않고 아래 `consistency-check 판정 보고 형식`으로 결과를 남긴다.
- 사용자가 "체크해", "확인해"만 요청했으면 보고 후 멈춘다.
- 사용자가 "정합성 맞춰줘", "리프레시해", "검사하고 반영해"까지 요청했으면 caller/router가 보고 evidence를 유지한다. `already-implemented` Task는 같은 스킬의 `mode=sync`, Milestone/queue/lock은 `update-roadmap`, SDD는 `roadmap-sdd`, living spec은 `update-spec`, contract는 `update-contract`로 넘긴다.
- 후속 갱신 뒤 `consistency-check`를 다시 실행한다. `ready`가 확인되고 별도 Plan 요청 또는 연결된 사용자 요청이 있을 때만 `plan`으로 진행한다.
## first-line metadata 계약
`m-*` 완료 로그의 첫 줄은 다음 형식이다.
```markdown
<!-- task=m-<milestone-slug>[/<subtask_dir>] plan=<N> tag=<TAG> milestone-task=<task-id>[,<task-id>...] -->
```
- 주석은 파일 첫 줄에 있어야 한다.
- `task`의 첫 path segment는 집계 대상 `m-<milestone-slug>`와 정확히 같아야 한다.
- `milestone-task`는 비어 있지 않은 쉼표 구분 목록이며 공백과 중복 id를 허용하지 않는다. 각 id는 `rules-roadmap.md`의 item-id 문법과 일치해야 한다.
- 모든 id는 대상 활성 Milestone `기능`에 존재해야 한다.
- PLAN, CODE_REVIEW, `complete.log`는 같은 generation header를 보존한다.
- metadata는 evidence routing 범위다. PASS 또는 id 존재만으로 `[x]` 처리하지 않는다.
## sync/check-only 실행 절차
1. **대상 Milestone 확정**
- `target-milestone`이 있으면 활성 `agent-roadmap/phase/*/milestones/*.md`에서 정확히 하나를 찾는다.
- 없으면 `agent-roadmap/current.md`의 활성 Milestone 단일 후보를 사용한다.
- 대상이 없거나 둘 이상이거나 archive 경로이면 어떤 상태도 수정하지 않고 target 불명확으로 보고한다.
- 대상 Phase `PHASE.md``current.md`의 현재 라벨도 함께 기록한다.
2. **현재 Task 계약 읽기**
- 대상 Milestone `기능``- [ ] [id]``- [x] [id]`만 Task 후보로 추출한다.
- 각 Task 설명, 같은 Task 안의 `검증:`, 관련 Epic 범위, `작업 컨텍스트` 관련 경로를 기록한다.
- `구현 잠금`, `결정 필요`, `SDD: 필요|불필요`, SDD 경로, SDD `USER_REVIEW.md` 존재 여부를 확인한다.
- 동기화 기준은 과거 plan 문구가 아니라 현재 Milestone Task 계약이다. 계약이 변경되어 evidence가 부족해졌으면 자동 완료하지 않는다.
3. **같은 task group의 완료 로그 수집**
- task group을 `m-<milestone-slug>`로 고정한다.
- active 후보: `agent-task/m-<milestone-slug>/complete.log`, `agent-task/m-<milestone-slug>/**/complete.log`
- archive 후보: `agent-task/archive/*/*/m-<milestone-slug>/complete.log`, `agent-task/archive/*/*/m-<milestone-slug>/**/complete.log`
- 전달된 `complete-log`도 포함하되 resolved path가 위 task group과 일치해야 한다.
- 다른 slug의 `agent-task/archive/**`는 탐색하지 않는다.
- 동일 resolved path는 한 번만 센다.
4. **로그 분류와 id별 인덱스 구성**
- canonical 로그는 first-line metadata를 파싱하고 task group, id 문법, 중복, 대상 Milestone의 기존 id 여부를 검증한다.
- 유효한 canonical 로그를 각 `milestone-task` id bucket에 모두 넣는다. 한 로그가 여러 id를 가지면 각 bucket에 기여한다.
- unknown id, 다른 task group, PLAN/review header 불일치, PASS가 아닌 terminal 결과, unresolved Required/Suggested, 상충하는 검증 결과가 있으면 해당 로그를 자동 완료 evidence에서 제외하고 이유를 보고한다.
- 같은 id에 로그가 여러 개면 어느 하나를 대표로 고르지 말고 모두 보존한다.
- first-line metadata가 없고 legacy `Roadmap Completion`이 있는 로그는 명시 완료 주장과 연결 evidence를 호환 근거로 분류한다. 현재 Task 계약과 SDD gate를 다시 평가하며 섹션만 보고 즉시 체크하지 않는다.
- metadata와 `Roadmap Completion`이 모두 없는 legacy 로그는 관련 파일/git 탐색을 위한 힌트로만 사용한다.
5. **Task별 evidence 집계**
- 각 Task id마다 bucket의 모든 `complete.log`에서 `구현/정리 내용`, `최종 검증`, archived plan/review 포인터, final verdict를 모은다.
- 필요한 경우 같은 완료 디렉터리의 exact `plan_*.log``code_review_*.log`만 읽어 metadata 일치와 구체적인 구현·검증 evidence를 확인한다. sibling archive task group 밖으로 확장하지 않는다.
- Milestone의 관련 경로를 `rg --files`와 Task 키워드로 확인하고, 현재 파일 내용이 Task 설명의 각 요구를 실제로 제공하는지 대조한다.
- `git log --oneline -- <관련 경로>`와 필요한 `git show --stat --name-only <commit>`으로 provenance를 보조 확인한다. 커밋 메시지만으로 완료 처리하지 않는다.
- 한 로그가 Task 계약 전체를 충족하면 단독으로 완료 evidence가 될 수 있다. 여러 로그가 각각 세분화된 하위 범위를 맡았다면 합집합이 계약 전체와 검증을 충족할 때 완료 evidence가 된다.
- 로그 수, plan 수, 특정 tag 존재, 파일명 유사성은 완료 기준이 아니다.
6. **검증과 SDD gate 평가**
- Task에 `검증:`이 있으면 집계된 실제 실행 결과, 현재 재실행 결과, 또는 같은 범위를 검증하는 명시 evidence가 있어야 한다.
- 테스트 자체가 산출물인 Task는 테스트 코드와 실행 evidence를 모두 요구한다.
- `SDD: 필요`이면 해당 Task id에 연결된 모든 필요한 Acceptance Scenario와 Evidence Map row를 찾는다. 집계한 로그·파일·검증 evidence가 그 mapping을 충족해야 한다.
- SDD 파일 부재, 미승인/잠금 상태, 남은 SDD `USER_REVIEW.md`, Task mapping 부재는 해당 Task 자동 체크를 차단한다.
- evidence가 의미상 유사하지만 id와의 연결 또는 요구 범위가 불명확하면 `검토 필요`로 남긴다.
7. **완료 판정**
- 다음이 모두 참인 Task만 `[x]` 후보로 판정한다.
- 현재 Task 설명의 capability와 산출물이 모두 확인된다.
- 명시 `검증:`이 충족된다.
- 필요한 SDD mapping과 evidence가 충족된다.
- 집계 evidence 사이에 미완료 선언, 실패, scope 충돌이 없다.
- canonical bucket이 비어 있어도 파일/git 감사로 계약 전체가 명확히 충족되면 완료 후보가 될 수 있으나, 어떤 evidence가 각 요구를 충족했는지 보고한다.
- canonical 로그가 하나 이상 있어도 계약 일부만 충족하면 `[x]` 처리하지 않는다.
8. **Milestone/Phase/current 반영**
- `mode=check-only`이면 후보만 보고하고 파일을 수정하지 않는다.
- 새로 검증된 Task만 `[x]`로 바꾸고 기존 `[x]`는 유지한다. evidence가 상실된 기존 `[x]`는 자동으로 되돌리지 않고 불일치로 보고한다.
- 미완료 Task가 남으면 일반적으로 `[진행중]`을 유지한다. 기존 `[검토중]`, `[보류]`, `[폐기]`는 자동 하향하지 않고 차이를 보고한다.
- 모든 Task가 `[x]`이고 구현 잠금 해제, `결정 필요: 없음`, SDD gate 충족이면 Milestone을 `[검토중]`으로 바꾸고 `완료 리뷰`에 id별 집계 로그와 파일/git evidence를 1~3줄로 요약한다.
- 이 스킬은 `[완료]` 전환이나 archive 이동을 하지 않는다.
- 대상 Phase `PHASE.md``agent-roadmap/current.md`의 대상 라벨을 Milestone 본문과 맞춘다. `current.md`에는 `[완료]` 또는 `[폐기]`를 남기지 않는다.
9. **workspace lock 확인**
- `.agent-roadmap-sync/locks.yaml`이 있으면 `agent-ops/bin/roadmap-dependency-checker.sh --find-milestone "<project>:<milestone-path>" both "<locks-file>"`를 실행한다.
- 대상이 `rely-on.target`이면 `[검토중]` 또는 `[완료]`에서 `enable`, 그 외에는 `disable`로 동기화한다. `check-only`에서는 쓰지 않는다.
- 새 lock을 만들거나 다른 Milestone 잠금을 직접 해제하지 않는다.
10. **검증과 보고**
- `git diff --check`를 실행한다.
- active/archive 후보 수, canonical/legacy/제외 수, Task id별 연결 로그와 판정, 파일/git 범위, SDD gate, 상태 변경, 남은 차단을 보고한다.
- 문서와 산출물 포인터는 Markdown 링크로 쓴다.
## 판정 보고 형식
### consistency-check 판정 보고 형식
```markdown
## 마일스톤 시작 정합성 체크
- 대상 Milestone: [<milestone-name>](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
- 모드: consistency-check
- Plan 준비 상태: <ready | refresh-required | blocked>
## 프로젝트 작업현황
- current/Phase/Milestone 상태: <정합 | 불일치 요약>
- queue/lock: <실행 가능 | 차단 요약 | 정리 필요>
- active agent-task: <관련 상태 요약 또는 없음>
- checkout 변경: <관련 변경 요약 또는 없음>
- 깊게 확인한 범위: <문서·코드·config·proto·테스트 링크 또는 없음>
## Drift 판정
- <already-implemented | stale-assumption | dependency-drift | scope-drift | queue-lock-drift | evidence-gap>: <evidence와 영향 또는 없음>
## 후속 라우팅
- 필요한 갱신: <쉼표로 구분한 sync-milestone-workstate mode=sync | update-roadmap | roadmap-sdd | update-spec | update-contract 목록 또는 없음>
- Plan 진행 조건: <충족 | 필요한 선행 조치>
```
### sync/check-only 판정 보고 형식
```markdown
## 동기화 완료
- 대상 Milestone: [<milestone-name>](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
- 모드: <sync | check-only>
- 상태: <변경 없음 | 이전 -> 이후>
- complete.log 후보: active <N>개, archive <N>개, canonical <N>개, legacy <N>개, 제외 <N>
## Task별 집계
- `<task-id>`: <완료 | 미완료 | 검토 필요>
- 연결 로그: <N>
- 충족 evidence: <요약 또는 없음>
- 미충족/충돌: <요약 또는 없음>
- SDD gate: <불필요 | 충족 | 차단>
## 반영 내용
- 새로 완료 처리한 Task: <id 목록 또는 없음>
- 남은 Task: <id 목록 또는 없음>
- 수정 파일: <Markdown 링크 목록 또는 없음>
- Workspace 잠금: <관련 lock 없음 | 상태 요약 | 미확인 사유>
- TODO: <남은 차단 항목 또는 없음>
```
## 금지 사항
- `consistency-check`에서 파일을 수정하거나 Task 체크박스·Milestone 상태·queue·lock을 변경하지 않는다.
- 정상 planned delta를 현재 미구현이라는 이유만으로 drift 또는 차단으로 판정하지 않는다.
- 전역 workstate 확인을 이유로 unrelated 코드, unrelated active task 본문 또는 다른 Milestone의 archive를 무차별 탐색하지 않는다.
- `refresh-required` 또는 `blocked` 상태에서 Plan을 만들거나 구현을 시작하지 않는다.
- `milestone-task` id 존재, plan PASS, 로그 개수만으로 Task를 `[x]` 처리하지 않는다.
- plan 하나와 Task 하나를 1:1로 가정하거나, 같은 id의 여러 로그 중 하나만 임의 선택하지 않는다.
- 새 canonical 로그에 `Roadmap Completion` 작성을 요구하지 않는다.
- legacy `Roadmap Completion`도 현재 Task 계약과 SDD gate 재평가 없이 즉시 반영하지 않는다.
- active task만 보고 archive 후보를 생략하거나 `complete.log` 부재만으로 미완료를 단정하지 않는다.
- 커밋 메시지, 파일명, plan/review log만으로 완료 처리하지 않는다.
- 의미 유사도, 순서, 파일명으로 unknown id를 보정하지 않는다.
- 구현 잠금이나 SDD gate가 남은 상태에서 `[검토중]`, `[완료]`, archive를 수행하지 않는다.
- 새 Milestone/Epic/Task를 만들거나 기존 id를 바꾸지 않는다.
- Do not run a whole-project preflight automatically.
- Do not chain update-roadmap, roadmap-sdd, update-spec, update-contract, or plan.
- Do not require complete-log aggregation or evidence-format conformance.
- Do not read unrelated archives.

View file

@ -1,517 +1,98 @@
---
name: update-roadmap
description: 로드맵 업데이트, 로드맵에 추가, 마일스톤 추가·갱신, phase 변경, 전역 Milestone 실행 순서 갱신 요청에 사용한다. 기존 항목 upsert, runtime 완료 반영, 완료 후보 전환과 archive, workspace 외부 의존 잠금 동기화를 처리한다.
description: Update existing roadmap phases, milestones, tasks, status, ordering, explicit dependencies, and archives with the smallest sufficient change.
---
# 로드맵 업데이트
# Update Roadmap
## 목적
## Purpose
기존 `agent-roadmap/` 구조를 현재 프로젝트 방향과 진행 상태에 맞게 갱신한다.
표준 구조는 `ROADMAP.md -> priority-queue.md -> phase/<phase-slug>/PHASE.md -> phase/<phase-slug>/milestones/<milestone-slug>.md`다.
archive도 같은 Phase scaffold를 유지하며 `archive/phase/<phase-slug>/...` 아래에 둔다.
로드맵 전체를 매 작업마다 읽지 않도록 유지하면서, 브랜치별 로컬 `current.md`의 활성 Phase와 활성 Milestone 창이 실제 작업 후보 목록으로 동작하게 한다.
`priority-queue.md`는 Phase를 가로지르는 prefix별 실행 순서, 설명, 최소 차단 예외만 담당하며 Milestone 상세 정보는 복제하지 않는다.
Milestone은 구현 계획이 아니라 방향성, 범위, 위험, 확인 필요 사항을 기록하는 협업 문서로 유지한다.
Epic과 Task는 별도 파일로 분리하지 않고 Milestone 문서의 `기능` 안에서 관리한다. 별도 `완료 기준` 섹션은 만들지 않고, 검증이 필요한 기능에만 같은 Task 안의 `검증:` 문구로 통합한다.
Keep `agent-roadmap/` aligned with current product direction without turning roadmap metadata into an implementation gate. Roadmap records goals, scope, status, explicit decisions, and real dependencies. It does not duplicate implementation plans or require approval artifacts before code work.
## 언제 호출할지
## Inputs
- 사용자가 "로드맵 업데이트", "마일스톤 갱신", "phase 변경", "현재 활성 마일스톤 바꿔줘"라고 요청할 때
- 사용자가 "로드맵에 추가", "로드맵 작업 추가", "로드맵 기능 추가", "로드맵 Epic/Task 추가", "로드맵 에픽/태스크 추가", "마일스톤에 추가", "마일스톤 추가"처럼 로드맵에 새 내용을 넣어 달라고 요청할 때
- Milestone 완료, 보류, 폐기, 신규 추가가 필요할 때
- Phase 완료, 보류, 폐기, 신규 추가가 필요할 때
- 완료 또는 폐기된 Phase/Milestone을 archive로 이동해야 할 때
- 런타임이 first-line `milestone-task`가 없는 legacy `m-<milestone-slug>` PASS 완료 이벤트를 Milestone에 반영해야 할 때. 새 metadata 이벤트는 `sync-milestone-workstate`로 라우팅한다.
- 특정 기능이나 작업을 새 Milestone, 기존 Milestone의 Epic, 기존 Epic의 Task 중 적절한 위치에 추가해야 할 때
- 활성 Phase/Milestone 창에 포함할 목록이 달라졌을 때
- 기존 로드맵을 `phase/<phase-slug>/PHASE.md` scaffold로 마이그레이션하거나 표준화해야 할 때
- 사용자가 "순서 바꿔", "이거 먼저", "이거 뒤로", "우선순위 재정렬"처럼 전역 Milestone 실행 순서 변경을 요청할 때
- `priority-queue.md`에 있는 Milestone이 archive, 폐기, 경로 변경, split/merge, 또는 실행 의미가 바뀔 정도로 수정되어 큐 정리가 필요할 때
- `priority-queue.md` 링크가 깨져 활성 Milestone 문서 기준으로 큐를 재정렬하거나 재생성해야 할 때
- 사용자가 "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"처럼 외부 의존 잠금을 말할 때
- `mode`: `status`, `milestone`, `phase`, `replan`, `sync`, or `archive`
- `target-phase` / `target-milestone`: exact name, slug, or active path when provided
- `new-feature`: work to place when adding scope
- `target-status`: one of the standard roadmap states
- `evidence`: code, test, document, commit, or user-provided completion evidence
- `workspace-lock`: an explicit cross-project dependency stated by the user
- `priority-queue-order`: an explicit ordering change requested by the user
## 입력
## Loading
- `mode`: `status` / `milestone` / `phase` / `replan` / `sync` / `concretize` / `archive` 중 하나 (선택, 요청에서 추론 가능)
- `target-phase`: 갱신할 Phase 이름, slug, 파일 경로 (선택)
- `target-milestone`: 갱신할 Milestone 이름, slug, 파일 경로 (선택)
- `active-phases`: 활성 Phase 창에 둘 Phase 이름, slug, 파일 경로 목록 (선택)
- `active-milestones`: 활성 Milestone 창에 둘 Milestone 이름, slug, 파일 경로 목록 (선택)
- `new-feature`: 추가할 기능, 작업, 또는 새 Milestone 설명 (선택)
- `placement`: 새 작업 배치 위치. 예: `<phase-name> 안`, `<milestone-name> 안`, `<epic-id> 아래`, `<item-id> 앞`, `<item-id> 뒤`, `auto` (선택)
- `placement-unit`: 삽입 단위. `phase` / `milestone` / `epic` / `task` / `subtask` / `auto` 중 하나 (선택)
- `target-status`: 전환할 Phase/Milestone 상태. `[스케치]` / `[계획]` / `[진행중]` / `[검토중]` / `[완료]` / `[보류]` / `[폐기]` 중 하나 (선택)
- `lock-state`: Milestone 구현 잠금 상태. `잠금` / `해제` 중 하나 (선택)
- `decision-needed`: `구현 잠금`에 남길 에이전트가 확정할 수 없는 제품/범위/우선순위/책임 경계 결정 목록 (선택)
- `sdd-state`: Milestone SDD gate. `필요` / `불필요` / `확인 필요` 중 하나 (선택)
- `sdd-path`: SDD 문서 경로. 기본값은 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md` (선택)
- `sdd-review`: SDD 사용자 리뷰 상태. `없음` / `요청됨` / `해결됨` 중 하나 (선택)
- `evidence`: 완료 판단에 사용할 파일, PR, 테스트, 커밋, 사용자 설명 (선택)
- `complete-log`: 런타임 완료 이벤트가 전달한 `complete.log` 경로. 첫 줄에 `milestone-task`가 있으면 이 스킬에서 직접 체크하지 않고 `sync-milestone-workstate`로 라우팅한다. metadata가 없는 legacy 로그는 `Roadmap Completion` 호환 검증에만 사용한다 (선택)
- `review-state`: 완료 리뷰 상태. `검토중` / `통과` / `보완 필요` / `보류` / `폐기` 중 하나 (선택)
- `review-comment`: 완료 리뷰에 남길 보완, 보류, 폐기 방향성 또는 근거 메모 (선택)
- `origin-task`: 런타임 완료 이벤트가 전달한 `agent-task/m-<milestone-slug>` 또는 `agent-task/m-<milestone-slug>/<subtask_dir>` 형식의 원래 active task 경로. 이벤트가 최종 archive 경로만 갖고 있으면 런타임이 이 형식으로 정규화해 전달한다 (선택)
- `archive-date`: Phase/Milestone 아카이브 날짜. 없으면 현재 날짜를 사용한다 (선택)
- `workspace-lock`: 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`에 기록하거나 동기화할 외부 의존 잠금 설명 (선택)
- `priority-queue-order`: `agent-roadmap/priority-queue.md`에 반영할 Milestone 경로/제목 순서 목록. 사용자가 순서 조정을 명시한 경우에만 사용한다 (선택)
1. Read `agent-roadmap/current.md` when it exists.
2. Read only the relevant active Phase and Milestone documents.
3. Read `ROADMAP.md` only for whole-Phase structure or out-of-window placement.
4. Read `priority-queue.md` only for ordering, blockers, archive cleanup, or broken links.
5. Do not read archive content unless the user requests history, restore, or comparison, or an active document points to one exact evidence file.
## 표준 구조
## Placement
```text
agent-roadmap/
ROADMAP.md
priority-queue.md
current.md # local, git ignored
phase/
<phase-slug>/
PHASE.md
milestones/
<milestone-slug>.md
sdd/
<phase-slug>/
<milestone-slug>/
SDD.md
USER_REVIEW.md
archive/
phase/
<phase-slug>/
PHASE.md
milestones/
<milestone-slug>.md
sdd/
<phase-slug>/
<milestone-slug>/
SDD.md
```
- Choose the smallest sufficient unit: Phase, Milestone, Epic, Task, or context note.
- Search for an existing equivalent item before creating one.
- Keep implementation details in code or an implementation plan, not in roadmap subtasks.
- Preserve existing ids unless the user explicitly asks to change them.
- Do not change queue order unless requested or required to remove an archived, deleted, or broken target.
- `ROADMAP.md`는 전체 목표와 Phase 흐름, `priority-queue.md` 고정 라우팅만 담는다.
- `priority-queue.md`는 Phase를 가로지르는 prefix별 Milestone 실행 순서와 차단 예외를 담는다. 항목은 `[prefix-NN]` 제목 링크, 1~2문장 설명, 필요한 exact blocker label만 둔다.
- `PHASE.md`는 해당 Phase의 목표, 상태, Milestone 흐름, Phase 경계를 담는다.
- Milestone 문서는 해당 Phase 하위 `milestones/`에 둔다.
- 완료된 Phase는 `archive/phase/<phase-slug>/PHASE.md`로 이동하고, 하위 Milestone도 같은 archive Phase scaffold 아래에 둔다.
- 진행중 Phase 안에서 완료된 Milestone은 `archive/phase/<phase-slug>/milestones/<milestone-slug>.md`로 이동하고, 활성 `PHASE.md`에는 짧은 archive 링크를 남긴다.
- archive `PHASE.md`는 Phase 자체가 완료/폐기될 때만 만든다. 진행중 Phase의 완료 Milestone만 archive된 경우에는 archive Phase 디렉터리에 `milestones/`만 있을 수 있다.
- 큰 Milestone의 SDD는 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`에 둔다.
- SDD 사용자 리뷰는 같은 디렉터리의 `USER_REVIEW.md`로 두고, 해결 후 `user_review_N.log`로 남긴다.
- 완료 또는 폐기된 Milestone의 SDD는 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 이동한다.
- `<phase-slug>``<milestone-slug>`는 소문자 영문, 숫자, 하이픈만 사용한다.
- `current.md`는 브랜치별 로컬 포인터이며 활성 Phase와 활성 Milestone을 모두 가리킨다.
- `current.md`는 git 추적 대상이 아니며, 공유 진행 상태는 `ROADMAP.md`, `PHASE.md`, Milestone 문서, `.agent-roadmap-sync/locks.yaml`에 기록한다.
- `current.md`에는 archive 경로를 넣지 않는다.
- `current.md`에는 `[완료]` 또는 `[폐기]` Phase/Milestone을 남기지 않는다. 완료 후보는 완료 근거와 archive 전환이 정리될 때까지 `[검토중]`으로 둔다.
- `priority-queue.md`에는 archive 경로를 넣지 않는다. 완료 Milestone은 archive 시 항목과 충족된 `선행 차단` 참조를 제거하고, 폐기 Milestone은 큐에서 제거한다.
## States and decisions
## 실행 태그와 차단 예외
- Use `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, or `[폐기]`.
- `[스케치]` means the implementation unit is not yet clear. `[계획]` means it is clear enough to implement.
- A Milestone may move directly to `[완료]` when its functional Tasks and genuinely required validation are complete. `[검토중]` is optional.
- Record user-owned product decisions under `결정 사항`. Do not create an implementation lock, SDD lock, approval checklist, or evidence-format gate.
- An unresolved decision pauses only the work that directly depends on that decision.
- 실행 태그는 `[prefix-NN]` 형식이며 내부 값은 `^[a-z][a-z0-9-]*-[0-9]{2}$`를 따른다. 같은 prefix는 동일 작업 lane, `NN`은 그 lane 안의 선후 순서다.
- 같은 prefix의 항목은 `### <prefix>` 그룹에 모아 index 오름차순으로 둔다. 더 작은 active index가 기본 선행이므로 blocker로 중복하지 않는다.
- 다른 prefix는 기본 병렬이다. 반드시 다른 lane 완료를 기다리는 지점만 exact label `선행 차단:`과 backtick tag 목록으로, 실제 동시 실행 충돌만 낮은 우선순위 항목의 exact label `동시 차단:`과 backtick tag 목록으로 둔다.
- blocker target은 같은 queue의 active tag여야 한다. 프로젝트 간 잠금은 queue tag로 대체하지 않고 `.agent-roadmap-sync/locks.yaml`을 사용한다.
- 실행 태그는 scheduling label이고 Milestone link target/slug는 identity다. 재index해도 파일명을 바꾸지 않으며, H1, 활성 Phase/current 표시, queue 제목과 blocker 참조만 원자적으로 갱신한다.
- Milestone 본문의 선행/후속 설명은 scheduling source가 아니다. 갱신 범위에서는 `작업 컨텍스트``priority-queue.md` 링크와 관련 Milestone 설명만 남긴다.
## SDD and evidence
## 상태와 id
- Link an SDD as an optional design reference when one exists or would materially clarify a large contract change.
- Do not require SDD status, user-review files, Acceptance Scenario mapping, Evidence Map mapping, plan files, review files, or `complete.log` metadata before implementation or completion.
- `milestone-task` and `Roadmap Completion` metadata may identify a target, but code, tests, commits, and explicit user evidence are also valid.
- 상태 표기는 `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
- 기존 비표준 상태 표기는 갱신 범위에 포함될 때 표준 상태 표기로 정리한다.
- `[스케치]`는 방향성, 문제의식, 후보 범위, 미정 질문을 기록하는 컨셉 상태다. 구현 가능한 계획이 아니므로 `agent-task` 구현 계획 생성과 코드 구현 대상으로 삼지 않는다.
- `[스케치]` 항목은 `[계획]`으로 승격하기 위한 `승격 조건`, 에이전트가 확정할 수 없는 결정, 범위 경계, 후속 Milestone 후보를 정리한다.
- `[계획]` 이상 Milestone에서 `승격 조건` 섹션은 선택 사항이다. 섹션이 없거나 `- 없음`이면 템플릿 오류로 보지 않는다.
- `[스케치]``[계획]`으로 전환할 때는 `승격 조건`의 미정 항목이 해소되고, 목표, 범위, 기능 Task, 직접 필요한 결정 항목, 후속 구현 단위가 구현 계획을 만들 수 있을 만큼 정리되었는지 확인한다.
- `[계획]`은 목표, 범위, 기능 Task, 구현 잠금, 결정 필요 항목이 문서화되어 잠금 해제 후 구현 계획을 만들 수 있는 상태다.
- `[검토중]`은 모든 기능 Task와 Task 안에 명시된 검증이 충족되고 `구현 잠금`이 해제되었으나, 완료 근거 정리와 archive 전환이 남은 완료 후보 상태다.
- 검토 결과 보완이 필요하면 별도 reopen 상태를 만들지 않고 `[진행중]`으로 되돌린 뒤 `완료 리뷰` 또는 `작업 컨텍스트`에 보완 방향을 남긴다.
- 검토 결과 보류 또는 폐기 결정이 나면 `[보류]` 또는 `[폐기]`로 전환한다.
- `ROADMAP.md`의 Phase 흐름은 실행 순서가 아니라 도메인/책임 영역의 구조적 지도다. 상태 그룹은 완료, 검토중, 진행중, 계획, 스케치 순서를 기본으로 하되 실제 다음 작업 선택은 `priority-queue.md`를 우선한다.
- `PHASE.md`의 Milestone 흐름은 해당 Phase 안의 상태 정리 흐름이다. Phase를 가로지르는 실행 순서로 해석하지 않는다.
- Epic heading은 `### Epic: [epic-id] <이름>` 형식으로 작성한다.
- 새 Epic과 기능 Task를 추가하거나 구조를 갱신하는 기존 Epic에는 기능 Task를 최대 5개만 둔다. 갱신 범위 밖 기존 Epic은 자동으로 재구성하지 않는다.
- 여섯 번째 Task가 필요하면 capability, 산출물, 의존성, 검증 경계 중 하나로 기존 Epic을 둘 이상으로 분리한다. 분리 후에도 독립 목표가 남으면 새 Milestone 후보로 둔다.
- 갱신 범위에 포함된 기존 Epic이 이미 6개 이상이면 같은 기준으로 분리한다. 이때 기존 item-id는 사용자가 명시하지 않는 한 바꾸지 않는다.
- Task는 `- [ ] [item-id] 설명` 또는 `- [x] [item-id] 설명` 형식으로 작성한다.
- epic-id와 item-id는 공백 없는 짧은 ASCII 토큰이며, 해당 Milestone 안에서만 유일하면 된다.
- 사용자가 epic-id 또는 item-id를 언급하면 해당 항목을 우선 anchor로 삼고, 기존 id는 명시적 요청 없이 바꾸지 않는다.
## Explicit dependencies
## 로딩 원칙
- Create or update `.agent-roadmap-sync/locks.yaml` only when the user explicitly states that one Milestone cannot proceed before another.
- Do not infer blockers from related work, recommended order, missing documents, missing validation, or queue proximity.
- Resolve exact active Milestone paths before writing a lock. If the target is ambiguous, report it and do not write.
- A lock pauses only the named Milestone. Other work remains available.
- 일반 갱신은 로컬 `current.md`, 관련 활성 Phase, 관련 활성 Milestone을 우선 읽는다.
- `current.md`가 없고 활성 창 갱신이 필요하면 `agent-ops/skills/common/_templates/roadmap-current-template.md` 형식으로 로컬 파일을 만든다.
- `ROADMAP.md`는 Phase 흐름, 전체 구조, 활성 범위 밖 작업, 전체 재계획, archive 링크 갱신이 필요할 때 읽는다.
- `priority-queue.md`는 Phase를 가로지르는 다음 작업 후보 선택, 사용자가 요청한 순서 조정, archive/폐기/경로 변경/split/merge 후 큐 정리, 깨진 링크 복구가 필요할 때 읽고 갱신한다.
- `agent-roadmap/archive/**`는 일반 작업이나 sync에서 읽지 않는다.
- archive 모드에서 이동 대상이 아직 활성 경로에 있으면 그 대상 문서는 읽을 수 있다.
- 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 요청이면 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라 필요한 archive 문서만 읽는다.
## Archive
## 템플릿
- Archive only `[완료]` or `[폐기]` items.
- Move the active Milestone and optional SDD to the existing archive scaffold.
- Remove the active item from `priority-queue.md` and `current.md`; leave a short archive link in the active Phase document.
- Do not reformat archive snapshots.
- `ROADMAP.md`: `agent-ops/skills/common/_templates/roadmap-template.md`
- `priority-queue.md`: `agent-ops/skills/common/_templates/roadmap-priority-queue-template.md`
- `current.md`: `agent-ops/skills/common/_templates/roadmap-current-template.md`
- `PHASE.md`: `agent-ops/skills/common/_templates/roadmap-phase-template.md`
- Milestone: `agent-ops/skills/common/_templates/roadmap-milestone-template.md`
- SDD: `agent-ops/skills/common/_templates/roadmap-sdd-template.md`
- SDD 사용자 리뷰: `agent-ops/skills/common/_templates/roadmap-sdd-user-review-template.md`
## Procedure
## 링크 표기
1. Normalize the requested target, change, and smallest sufficient unit.
2. Compare the request with the relevant active Phase, Milestone, Epic, and Task.
3. Update only the files needed for that change.
4. Preserve unresolved decisions as plain decision notes, not gates.
5. Apply explicit dependency changes only when the user requested them.
6. For completion, verify the functional outcome and only the validation proportionate to the change.
7. Check changed Markdown links and run `git diff --check`.
- 사용자에게 보여주는 결과 보고와 새로 생성/갱신하는 로드맵 문서에서 `ROADMAP.md`, `priority-queue.md`, `current.md`, `PHASE.md`, Milestone 문서, SDD, `USER_REVIEW.md`, archive 문서, `complete.log` 같은 문서/산출물 포인터는 raw path만 쓰지 말고 `[표시 제목](상대경로)` Markdown 링크로 쓴다.
- 로드맵 문서 안의 링크 target은 링크를 작성하는 Markdown 파일 위치 기준 상대경로로 쓴다. 예: `ROADMAP.md``current.md`에서는 `[PHASE.md](phase/<phase-slug>/PHASE.md)`, Phase 문서에서는 `[Milestone](milestones/<milestone-slug>.md)`, Milestone 문서에서는 `[ROADMAP.md](../../../ROADMAP.md)``[PHASE.md](../PHASE.md)`를 쓴다.
- 채팅 결과 보고처럼 저장 위치가 없는 출력은 repo root 기준 상대경로를 쓸 수 있다. 예: `[PHASE.md](agent-roadmap/phase/<phase-slug>/PHASE.md)`.
- `경로:`, `Phase:`, `Milestone:`, `SDD 문서:`, `수정 파일:` 같은 필드명을 유지해야 해도 값은 Markdown 링크로 작성한다.
- 실제 갱신한 활성 로드맵 문서에는 `<phase-slug>`, `<milestone-slug>`, `<relative-...>` 같은 placeholder가 들어간 링크 target을 남기지 않는다. 템플릿 placeholder는 실제 파일 위치 기준 상대경로 또는 `없음`으로 치환한다.
- 기존 문서에 남아 있는 raw path나 backtick path는 읽기/마이그레이션 입력으로 허용한다. 갱신 범위에 포함된 활성 문서 포인터만 Markdown 링크로 보정하고, archive 스냅샷은 링크 표기만을 이유로 재포맷하지 않는다.
- `.agent-roadmap-sync/locks.yaml``locked`, `rely-on.target`, Milestone identity(`<project>:agent-roadmap/...`), 명령 입력값처럼 machine-readable 계약 값은 raw 값을 유지할 수 있다. 다만 사용자-facing 설명에는 가능한 경우 별도 Markdown 문서 링크를 함께 붙인다.
## Validation
## 구현 잠금
- Changed links point to existing active or exact archive targets.
- Status values and Epic/Task ids use the existing format.
- No new `구현 잠금`, SDD approval checklist, automatic preflight, or evidence-format requirement was introduced.
- No unrelated queue order, id, Phase, Milestone, or archive content changed.
- `구현 잠금`은 승인 절차가 아니라 에이전트가 확정할 수 없는 결정이 필요한지 표시하는 얇은 상태다.
- 제품 방향, 범위, 우선순위, 책임 경계처럼 에이전트가 확정할 수 없는 항목이 남아 있으면 `잠금`으로 두고 `결정 필요` 목록에 남긴다.
- 기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 합리적으로 정할 수 있는 항목은 `결정 필요`가 아니라 `작업 컨텍스트`의 표준선으로 기록한다.
- Milestone 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `해제`로 둔다.
- `구현 잠금` 섹션이 없거나, 상태가 `잠금`이거나, 미완료 `결정 필요` 항목이 하나라도 있으면 실구현 계획, 코드 구현, Milestone 완료 후보 전환을 차단한다.
- 잠금 상태에서 허용되는 갱신은 잠금 해소, SDD gate 처리, 범위 제외/후속 Milestone 이동, 작업 컨텍스트 정리 같은 roadmap-only 변경뿐이다.
- 남은 `결정 필요` 항목이 현재 Milestone 실구현 범위가 아니면 먼저 그 항목을 `범위 제외`, 후속 Milestone, 또는 `작업 컨텍스트`로 옮긴 뒤 `구현 잠금``해제`한다. 잠금 해제 전에는 기능 Task 완료 근거가 있어도 `[검토중]`으로 올리지 않는다.
- SDD gate가 필요한 Milestone은 `구현 잠금``SDD: 필요`, 해당 Milestone 파일 위치 기준 `SDD 문서` Markdown 링크, 잠금 해제 조건을 남기고 SDD 잠금이 해제될 때까지 `잠금`으로 둔다.
- 새 Milestone을 만들거나 `[스케치]``[계획]`으로 승격하면서 `SDD: 필요`로 판정한 경우, 같은 `update-roadmap` 흐름 안에서 `roadmap-sdd create`까지 수행해 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md`를 만든다. `SDD: 필요`와 SDD 문서 링크만 남기고 파일이 없는 상태로 종료하지 않는다.
- SDD 작성에 필요한 목표, 범위, 기능 Task, Acceptance Scenario 후보를 이미 판단했고 사용자만 결정할 항목이 없으면 SDD 상태를 `[승인됨]`, SDD 잠금을 `해제`로 두고 Milestone `구현 잠금``해제`한다.
- 사용자만 결정할 항목이 있으면 SDD 초안을 만들고 `roadmap-sdd review-ready` 방식으로 `USER_REVIEW.md`를 남긴다. 이 경우 Milestone `구현 잠금``잠금`으로 둔다.
- SDD 파일을 만들 수 없는 예외는 사용자가 명시적으로 SDD 생성을 뒤로 미룬 경우뿐이다. 이때 결과 보고에 `SDD gate: 필요-작성 전`과 구체적인 지연 사유를 남긴다.
- SDD gate가 불필요한 Milestone은 `SDD: 불필요`과 짧은 사유를 남긴다.
- SDD가 필요한 기준: cross-repo 계약, 외부 provider 쓰기, 상태 머신/lifecycle, idempotency/retry/identity map, API/proto/config/env/schema 변경, field smoke, 사용자 승인 gate 영향.
- SDD 사용자 리뷰가 필요한 결정은 chat으로 즉시 묻지 않고 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md`에 남긴다.
- 잠금 상태 변경은 Milestone 완료 판정이 아니므로 `기능` Task를 자동 완료 처리하지 않는다.
- `[스케치]` Milestone은 `구현 잠금``해제`로 보이더라도 구현 계획과 코드 구현 대상이 아니다. 먼저 승격 조건을 충족해 `[계획]`으로 전환한다.
## Output
## 프로젝트 간 잠금
Report:
- 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`은 프로젝트 간 Milestone 잠금 인덱스다. 외부 의존 잠금을 생성하거나 동기화해야 하면 파일이 없어도 디렉터리와 파일을 만든다.
- entry는 `id`, `locked`, `rely-on[].target`, `rely-on[].status`, `rely-on[].note`만 사용한다.
- `locks.yaml`은 root sequence block style을 기본으로 작성한다. 예: `- id: ...` 아래에 `locked`, `rely-on`을 둔다.
- `id`는 기본적으로 `<잠긴-project>:<잠긴-milestone-slug>`로 만든다.
- `locked``rely-on[].target``<project>:agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md` 형식으로 기록한다.
- Milestone 경로가 `agent-roadmap/...` 상대 경로이면 현재 프로젝트명을 prefix로 붙인다. workspace 하위 절대/상대 경로이면 workspace 바로 아래 디렉터리명을 project로 삼고, 그 뒤 `agent-roadmap/...` 경로를 붙인다.
- `locked`는 잠긴 Milestone, `rely-on.target`은 선행 조건 Milestone이다. 둘 다 같은 workspace의 어느 활성 Phase 하위 Milestone이어도 된다. 의존 대상이 `current.md`에 있어야 한다고 가정하지 않는다.
- 의존 Milestone 확정 순서:
1. 사용자가 명시한 `<project>:agent-roadmap/phase/.../milestones/<slug>.md` 또는 파일 경로
2. 사용자가 명시한 프로젝트와 Milestone slug
3. 사용자가 명시한 프로젝트와 Milestone 제목의 정규화 일치
4. 잠긴 Milestone 문서의 `선행 <project> Milestone: ...`, `관련 <project> Milestone: ...`, `외부 의존 잠금: ...`에 적힌 slug/제목 힌트
5. 프로젝트명만 있고 Milestone 힌트가 없을 때만 해당 프로젝트 로컬 `current.md`의 활성 Milestone 단일 후보
- 정규화 비교는 소문자 변환, backtick/따옴표 제거, 영문/숫자가 아닌 연속 문자를 `-` 하나로 치환, 앞뒤 `-` 제거 후 비교한다. 정규화한 힌트는 Milestone 파일 slug와 정규화한 제목 둘 다에 대조한다.
- 2-4번 탐색은 대상 프로젝트의 `agent-roadmap/phase/*/milestones/*.md` 활성 문서만 대상으로 한다. archive 문서는 사용자가 archive 경로를 명시한 경우 외에는 읽거나 후보로 삼지 않는다.
- 후보가 없거나 둘 이상이면 `locks.yaml`을 만들거나 고치지 말고 모호성을 보고한다. 잠금 대상 확정이 제품/범위 결정이면 대상 Milestone의 `구현 잠금 > 결정 필요`로 분리한다.
- 외부 의존 잠금 요청이 있거나, 갱신 대상 Milestone이 `구현 잠금: 잠금`이며 문서에 외부 의존 잠금/선행 Milestone 컨텍스트가 있으면 `.agent-roadmap-sync/locks.yaml`을 upsert한다. resolvable한 외부 의존 문구를 Milestone에 남기고 lock entry를 누락하지 않는다.
- 외부 의존 잠금을 만들 때 대상 Milestone의 `구현 잠금``잠금`으로 둔다.
- 새 `rely-on.status`는 선행 Milestone 상태에서 파생한다. `[검토중]` 또는 `[완료]`이면 `enable`, 그 외 상태거나 상태를 확인할 수 없으면 `disable`이다.
- 같은 `id` entry를 upsert할 때 기존 `rely-on` 항목을 삭제하지 않는다. 같은 `rely-on.target`만 status/note를 갱신하고, 없는 target은 추가하며, `locked` 경로가 바뀐 경우에만 `locked`를 갱신한다.
- `locks.yaml`이 있고 Milestone을 갱신하거나 archive할 때는 대상 Milestone identity로 `agent-ops/bin/roadmap-dependency-checker.sh --find-milestone "<identity>" both "<locks-file>"`를 먼저 실행한다.
- find 결과가 `none`이면 결과 보고의 `Workspace 잠금``관련 lock 없음`을 남긴다. 외부 의존 잠금 생성/동기화 요청이 아니라면 `locks.yaml`을 새로 만들거나 수정하지 않는다.
- 이 스킬이 갱신한 Milestone identity가 어느 entry의 `rely-on.target`과 일치하면 해당 `rely-on.status`를 Milestone 상태 기준으로 동기화한다. `[검토중]` 또는 `[완료]`이면 `enable`, 그 외 상태면 `disable`이다.
- 이 스킬이 갱신하거나 선택한 Milestone identity가 어느 entry의 `locked`와 일치하면 모든 `rely-on.status``enable`인지 확인하고 결과 보고의 `Workspace 잠금``런타임 해제 대기` 또는 `미충족`으로 남긴다.
- archive 모드에서는 파일 이동 전에 대상 Milestone의 활성 경로 identity를 보존하고, 그 identity로 `--find-milestone "<identity>" both "<locks-file>"`를 먼저 실행한다. 보존한 identity가 어느 entry의 `rely-on.target`과 일치하고 Milestone 상태가 `[완료]`이면 archive 이동 전에 해당 `rely-on.status``enable`로 바꾼다.
- archive 모드에서 보존한 identity가 어느 entry의 `locked`와 일치하면 archive 이동 전에 모든 `rely-on.status``enable`인지 확인해 결과 보고에 남긴다. 미충족이면 archive 자체를 막지 않지만 `Workspace 잠금: 미충족`으로 보고한다.
- 모든 `rely-on.status``enable`이어도 여기서 다른 프로젝트 Milestone을 직접 해제하지 않는다. 잠금 해제 실행은 런타임이 별도 `update-roadmap` 호출로 처리한다.
- files changed;
- existing item updated or new smallest unit created;
- status, scope, decision, ordering, or dependency change;
- tests or link checks actually run;
- unresolved product decision or explicit dependency, if any.
## 완료 리뷰와 검토중 상태
## Prohibited
- Task 완료 또는 Milestone 갱신 후 모든 기능 Task와 Task 안에 명시된 검증이 evidence와 함께 `[x]`인지 확인하고, `구현 잠금``해제`이며 미완료 `결정 필요` 항목이 없는지 함께 확인한다.
- 기능 Task가 모두 충족되어도 `구현 잠금`이 남아 있으면 Milestone을 `[검토중]`으로 바꾸지 않는다. `완료 리뷰` 또는 `작업 컨텍스트`에 잠금 차단 항목을 남기고, 잠금 해소 roadmap 갱신을 먼저 요구한다.
- 기능 Task와 구현 잠금이 모두 충족된 것으로 보이면 Milestone을 `[완료]`로 바로 바꾸거나 archive로 이동하지 말고 `[검토중]`으로 바꾼다.
- `[검토중]`으로 바꿀 때는 Milestone 문서의 `완료 리뷰` 섹션을 만들거나 갱신한다.
- `완료 리뷰`에는 `상태: 검토중`, `요청일`, 완료 근거 1~3줄, 남은 차단 항목, 리뷰 코멘트를 남긴다. 에이전트가 확정할 수 없는 결정 항목은 완료 리뷰가 아니라 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- `구현 잠금`이 해제되어 있지 않으면 `[완료]`로 전환하거나 archive하지 않는다. 잠금 해소 roadmap 갱신을 먼저 요구한다.
- 기능 Task, 검증, 구현 잠금이 모두 충족되어 있으면 `완료 리뷰``상태: 통과`로 바꾸고 Milestone 상태를 `[완료]`로 전환한 뒤 archive 모드를 수행할 수 있다.
- 보완 근거가 있으면 `완료 리뷰``상태: 보완 필요`로 바꾸고 Milestone 상태를 `[진행중]`으로 되돌린다. 이때 보완 방향을 `완료 리뷰` 또는 `작업 컨텍스트`에 남기며 별도 reopen 상태는 만들지 않는다.
- 보류 또는 폐기 근거가 있으면 `완료 리뷰`와 Milestone 상태를 각각 `보류`/`[보류]`, `폐기`/`[폐기]`로 맞춘다. `[폐기]`는 archive 대상이 될 수 있다.
- Phase는 하위 Milestone이 모두 `[완료]` 또는 `[폐기]`로 정리되고 Phase 목표도 충족된 것으로 보일 때 `[완료]` 또는 `[폐기]`로 archive한다.
## Milestone task group 연동
- 런타임 완료 이벤트의 `origin-task`에서 `agent-task/` 다음 첫 path segment가 `m-<milestone-slug>`이면 Milestone 기반 plan/review 완료에서 온 요청으로 본다. `origin-task`는 archive 이동 전 active task 경로 또는 런타임이 그 형태로 정규화한 경로를 사용한다.
- `<milestone-slug>`는 활성 `agent-roadmap/phase/*/milestones/<milestone-slug>.md`에서 정확히 하나만 찾아야 한다. archive Milestone은 target 후보가 아니다.
- target이 없거나 둘 이상이면 Milestone 내용을 추정해 수정하지 말고 target 불명확으로 보고한다.
- `complete-log` 첫 줄에 `milestone-task`가 있으면 새 계약 이벤트다. 여기서 단건 PASS를 Task 완료로 해석하거나 체크하지 말고 `sync-milestone-workstate target-milestone=<milestone-slug> complete-log=<path>`로 라우팅한다. 그 스킬이 같은 task group의 모든 완료 로그를 id별로 집계한다.
- first-line metadata가 없는 legacy 로그만 `Roadmap Completion` 호환 흐름을 사용할 수 있다. 섹션이 없으면 no-op이며 일반 `m-*` 완료 이벤트만으로 Task를 추정하지 않는다.
- legacy `Roadmap Completion`이 있으면 Milestone 경로와 Completed task ids를 exact match하고 PASS/검증/SDD Evidence Map을 확인한다. 현재 Task 계약을 충족하지 않거나 충돌 evidence가 있으면 체크하지 않는다.
- 사용자가 이 스킬에 별도 evidence를 명시한 수동 갱신은 일반 완료 리뷰 규칙으로 평가할 수 있지만, `milestone-task` 단건 이벤트를 check-on-pass로 바꾸는 근거로 사용하지 않는다.
- 갱신 후 모든 기능 Task와 Task 안에 명시된 검증이 충족되어도 `구현 잠금`이 해제되어 있지 않으면 `[검토중]` 전환을 하지 않고 잠금 차단으로 보고한다. 기능 Task와 구현 잠금이 모두 충족될 때만 `[검토중]` 전환과 `완료 리뷰` 요청 규칙을 적용한다.
- target Milestone이 `[스케치]`이면 완료 이벤트를 반영하지 말고 상태 불일치로 보고한다. `[스케치]`는 Milestone 기반 `agent-task` 완료 이벤트의 target이 될 수 없다.
## 삽입 단위 정책
| 삽입 단위 | 사용 기준 |
|-----------|-----------|
| 새 Phase | 독립적인 제품 진화 단계와 여러 Milestone 묶음이 필요하다 |
| 새 Milestone | 독립적인 목표와 기능 Task 묶음이 필요하고 Phase 흐름에 의미 있는 경계를 만든다 |
| 새 Epic | 기존 Milestone 안에서 여러 Task를 묶는 상위 capability 또는 산출물이다 |
| 새 Task | 기존 Epic 아래에 들어가는 완료 가능한 capability 또는 산출물이다. 검증이 필요한 경우에만 같은 Task 안에 붙인다 |
| 하위 작업 | 기존 Task를 완성하기 위한 구현 세부다. Milestone `기능`에는 하위 체크박스로 만들지 않고, plan 내부 체크리스트나 기존 Task의 `검증:`/설명 보강으로 다룬다 |
| 작업 컨텍스트/TODO | 에이전트가 확정할 수 없는 결정 또는 조사/확인이 먼저 필요해 기능 Task로 확정하기 어렵다 |
- 먼저 요청 내용의 규모를 판정한다. 배치 위치를 찾기 전에 `phase`, `milestone`, `epic`, `task`, `subtask`, `context` 중 가장 작은 충분한 단위를 고른다.
- **NO OVERENGINEERING** — Do not add or retain anything beyond the user request and required behavior.
- 요청이 방향성, 문제의식, 컨셉, 운영 원칙 수준이고 기능 Task나 실행 범위가 아직 부족하면 새 항목의 상태는 `[스케치]`로 둔다.
- `[스케치]` Phase/Milestone을 만들 때는 `승격 조건``[계획]`으로 전환하기 위해 필요한 정의, 결정, 경계, 후속 구현 Milestone 후보를 체크리스트로 남긴다.
- 가장 작은 충분한 단위 원칙을 따른다. 애매하면 새 Phase나 새 Milestone으로 키우지 말고, 기존 Milestone의 Epic/Task에 넣을 수 있는지 먼저 확인한다.
- 기존 Epic에 기능 Task가 5개 있으면 새 Task를 추가하지 않는다. 여섯 번째 Task는 capability, 산출물, 의존성, 검증 경계 중 하나로 분리한 새 Epic에 배치하고, 분리된 Epic이 독립 목표면 새 Milestone 후보로 재판정한다.
- 위치 지정이 있으면 anchor의 레벨을 먼저 확인한다.
- `<epic-id> 아래`는 해당 Epic 아래 Task로 넣는다.
- `<item-id> 앞/뒤`는 같은 Epic 안의 형제 Task로 넣는다.
- `<item-id> 아래`는 해당 Task의 설명 또는 `검증:`을 보강한다. 구현 세부나 테스트만 따로 떼어낸 하위 체크박스는 Milestone `기능` 아래에 만들지 않는다.
- `<phase-name> 안`은 새 Milestone 또는 기존 Milestone/Epic/Task 중 작업 성격에 맞는 단위로 배치한다.
- 위치 지정이 없으면 `auto`로 본다. 로컬 `current.md`의 활성 창만으로 결정하지 않고, 필요한 경우 `ROADMAP.md`의 Phase 흐름까지 확인해 완료/검토중/진행중/계획/스케치 Phase를 비교한다.
- target 없는 신규 추가 요청은 요청 문장, 관련 파일/도메인 힌트, Phase 목표, Milestone 목표, 기존 Epic/Task, 선후 의존성, 상태, 활성 창을 비교해 가장 자연스러운 위치를 자동 판단한다.
- 자동 배치 후보가 여러 개이면 1순위와 2순위 후보를 비교하고, 선택한 Phase/Milestone/Epic/Task와 밀린 후보의 이유를 짧게 남긴다.
- 관련성이 비슷하면 `[진행중]` Milestone을 `[계획]` Milestone보다 우선하되, `[검토중]` Milestone은 리뷰 보완 요청이 아닌 신규 작업의 기본 배치 대상으로 삼지 않는다.
- 자동 배치한 경우 결과 보고에 선택한 삽입 단위, 위치, 판단 근거, 비교한 후보를 짧게 남긴다.
- 사용자 지정 위치가 Phase 목표, Milestone 범위 제외, 선후 의존성과 충돌하면 충돌을 보고하고 수정하지 않는다. 제품/범위 결정으로 해소해야 하면 대상 Milestone의 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
## 레벨별 탐색과 upsert 정책
target 없는 신규 추가 요청은 append가 아니라 upsert로 처리한다.
1. **요청 정규화**
- 요청 문장에서 기능명, 목표, 산출물, 관련 경로/도메인, 완료 기대, 제약, 명시 anchor를 뽑는다.
- 사용자가 Phase/Milestone/Epic/Task/id/path를 명시했으면 그 anchor를 우선 후보로 둔다.
2. **규모 판정**
- 여러 Milestone을 묶는 제품/운영 단계면 Phase 규모다.
- 독립 목표, 기능 Task 묶음, 여러 Epic이 필요한 결과면 Milestone 규모다.
- 컨셉은 충분히 크지만 구현 가능한 목표/범위/기능 Task가 아직 없으면 `[스케치]` Phase 또는 Milestone 후보로 둔다.
- 한 Milestone 안의 capability 묶음이면 Epic 규모다.
- Epic 아래에서 완료 가능한 단일 capability 또는 산출물이면 Task 규모다. 검증이 필요한 경우에만 같은 Task 안에 포함한다.
- Task를 완성하기 위한 구현 세부면 subtask 규모다. roadmap에는 하위 체크박스로 기록하지 않고, 구현 계획 내부 또는 기존 Task 보강으로 처리한다.
- 조사, 결정, 보류 질문이면 작업 컨텍스트/TODO 규모다.
3. **레벨별 탐색**
- Phase 후보를 먼저 찾는다. 로컬 `current.md`의 활성 Phase를 우선 보되, target이 없거나 활성 범위 밖 가능성이 있으면 `ROADMAP.md`의 Phase 흐름도 본다.
- 선택한 Phase 안에서 Milestone 후보를 찾는다. 활성 Milestone을 우선 보되, 요청이 계획 Milestone 목표와 더 직접 맞으면 계획 Milestone도 후보로 둔다.
- 선택한 Milestone 안에서 Epic 후보를 찾는다. `기능`의 Epic heading, 목표 설명, Task 묶음을 비교한다. 기존 문서가 `필수 기능`을 쓰면 갱신 시 `기능`으로 정규화한다.
- 선택한 Epic 안에서 Task 후보를 찾는다. item-id, 문장 의미, Task 안의 검증 문구, 관련 경로를 비교한다.
- archive 문서는 기본 탐색 대상이 아니다. 사용자가 과거 기록 비교를 명시했거나 완료 내용 확인이 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라 필요한 문서만 읽는다.
4. **중복/업데이트 판정**
- 같은 id, 같은 제목, 같은 목표, 같은 관련 경로, 같은 Task 안의 검증 문구, 또는 같은 산출물을 다루면 동일/유사 후보로 본다.
- 동일 항목이면 새로 만들지 않고 기존 Phase/Milestone/Epic/Task를 업데이트한다.
- 기존 항목의 범위를 보강하는 내용이면 해당 항목의 설명, Task 안의 검증 문구, 작업 컨텍스트 중 알맞은 곳에 병합한다.
- 기존 항목과 충돌하거나 범위 제외를 건드리면 충돌을 보고하고 수정하지 않는다. 제품/범위 결정으로 해소해야 하면 대상 Milestone의 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- 같은 레벨에 적절한 후보가 없을 때만 새 항목을 만든다. 새 항목도 판정한 규모보다 크게 만들지 않는다.
- 부모 레벨 후보는 있고 판정 규모의 항목만 없으면, 부모 아래에 판정 규모의 새 항목을 만든다. 부모 레벨도 없을 때만 필요한 부모 항목을 함께 만든다.
## archive 정책
### Milestone archive
- 대상 Milestone이 `[완료]` 또는 `[폐기]`인지 확인한다.
- `[검토중]` Milestone은 archive하지 않는다. 완료 근거가 있어도 `구현 잠금`이 해제되어 있지 않으면 `[완료]`로 바꾸지 않는다. 명시적인 폐기 근거가 있으면 `[폐기]`로 바꾼 뒤 archive할 수 있다.
- `[완료]` archive 대상은 `구현 잠금`이 해제되어 있고 미완료 `결정 필요` 항목이 없어야 한다. `[폐기]` archive는 이 완료 잠금 조건을 요구하지 않는다.
- archive 이동 전에 대상 Milestone의 활성 경로 identity(`<project>:agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`)를 보존한다.
- `locks.yaml`이 있으면 보존한 identity로 `--find-milestone "<identity>" both "<locks-file>"`를 실행해 이 Milestone이 `locked`인지, `rely-on.target`인지, 관련 lock이 없는지 먼저 확인한다.
- 보존한 identity가 `.agent-roadmap-sync/locks.yaml``rely-on.target`에 있으면 archive 이동 전에 상태를 동기화한다. `[완료]`이면 `enable`, `[폐기]`이면 `disable`이다.
- 보존한 identity가 `.agent-roadmap-sync/locks.yaml``locked`에 있으면 archive 이동 전에 의존 조건 충족 여부를 결과 보고에 남긴다.
- find 결과가 `none`이면 `Workspace 잠금: 관련 lock 없음`으로 보고한다.
- 대상 파일을 `agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`에서 `agent-roadmap/archive/phase/<phase-slug>/milestones/<milestone-slug>.md`로 이동한다.
- 활성 SDD 디렉터리 `agent-roadmap/sdd/<phase-slug>/<milestone-slug>/`가 있으면 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 이동한다. `USER_REVIEW.md`가 남아 있으면 archive하지 말고 해결 필요로 보고한다.
- 활성 `PHASE.md`의 Milestone 흐름에는 `[완료]` 또는 `[폐기]` 항목을 남기고, 경로는 archive 경로로 바꾼다.
- `priority-queue.md`가 있으면 대상 Milestone의 활성 경로 항목과 해당 실행 태그를 가리키는 충족된 `선행 차단` 참조를 제거한다. `동시 차단` 참조는 target이 더는 active하지 않으므로 함께 제거한다. archive 경로로 바꿔 남기지 않는다.
- 로컬 `current.md`의 활성 Milestone에서는 제거한다.
- `ROADMAP.md`는 Phase 상태나 경로가 바뀌지 않으면 수정하지 않는다.
- 이동한 archive 문서는 스냅샷으로 보존하고 최신 템플릿에 맞춰 재포맷하지 않는다.
### Phase archive
- Phase 전체가 `[완료]` 또는 `[폐기]`인지 확인한다.
- `[검토중]` Phase는 archive하지 않는다. 완료 또는 폐기 근거가 충족되면 먼저 `[완료]` 또는 `[폐기]`로 바꾼 뒤 archive한다.
- `agent-roadmap/phase/<phase-slug>/PHASE.md``agent-roadmap/archive/phase/<phase-slug>/PHASE.md`로 이동한다.
- 해당 Phase의 하위 Milestone도 `archive/phase/<phase-slug>/milestones/` 아래로 이동한다.
- `ROADMAP.md`의 Phase 흐름에는 해당 Phase 항목을 남기고, 상태와 경로를 archive `PHASE.md`로 바꾼다.
- `priority-queue.md`가 있으면 해당 Phase 하위 활성 Milestone 항목을 모두 제거한다. archive 경로로 바꿔 남기지 않는다.
- 로컬 `current.md`의 활성 Phase와 활성 Milestone에서는 해당 Phase와 하위 Milestone을 제거한다.
- archive 문서는 스냅샷으로 보존하고 최신 템플릿에 맞춰 재포맷하지 않는다.
## 실행 절차
1. **갱신 범위 결정**
- 요청에서 mode, 대상 Phase/Milestone, placement, placement-unit을 추론한다.
- 런타임 완료 이벤트의 `origin-task` task group이 `m-<milestone-slug>`이면 `target-milestone`을 활성 Milestone 경로 매칭으로 확정한다.
- 런타임 완료 이벤트가 `complete-log`를 전달하면 첫 줄 metadata를 먼저 확인한다. `milestone-task`가 있으면 직접 수정하지 않고 `sync-milestone-workstate`로 라우팅한다. 없는 legacy 로그만 `Roadmap Completion`과 Completed task ids, 필요한 SDD `Evidence Map`을 확인한다.
- 구조 전환, 템플릿 보정, current 동기화는 `sync`로 본다.
- `priority-queue.md` 생성, 순서 조정, 깨진 링크 복구, archive/폐기/경로 변경/split/merge 후 큐 정리는 `sync` 또는 `replan`으로 본다.
- 완료/폐기 근거가 충족된 이동은 `archive`로 본다.
- 새 기능 배치, Epic/Task 추가는 `milestone` 또는 `phase`로 본다.
- "로드맵에 추가"처럼 target이 없는 신규 작업 요청은 `placement=auto`, `placement-unit=auto`, `new-feature=<요청 내용>`으로 본다.
- 외부 의존 잠금 요청이면 `workspace-lock` 갱신으로 본다.
- 외부 의존 잠금 요청이 아니어도, 갱신 대상 Milestone이 `구현 잠금: 잠금`이고 외부 의존 잠금/선행 Milestone 컨텍스트가 있으면 `workspace-lock` 동기화 후보로 본다.
- 외부 의존 잠금 요청에서 "현재 마일스톤" 또는 target 생략 표현이 있으면 로컬 `current.md`의 활성 Milestone 단일 후보를 잠긴 대상으로 확정한다.
- 의존 대상은 명시 경로, 명시 slug, 명시 제목, 잠긴 Milestone 문서의 선행 Milestone 힌트, 대상 프로젝트 로컬 `current.md` 단일 후보 순서로 확정한다.
- 잠긴 대상 또는 의존 대상 후보가 없거나 둘 이상이면 `locks.yaml`을 수정하지 말고 모호성을 보고한다. 잠금 대상 확정이 제품/범위 결정이면 대상 Milestone의 `구현 잠금 > 결정 필요`로 분리한다.
2. **요청 정규화와 규모 판정**
- 요청에서 기능명, 목표, 관련 경로, 명시 anchor, 완료 기대, 제약을 추출한다.
- `phase`, `milestone`, `epic`, `task`, `subtask`, `context` 중 가장 작은 충분한 규모를 판정한다.
- 동일/유사 항목이 이미 있으면 신규 추가가 아니라 업데이트 후보로 기록한다.
3. **레벨별 후보 탐색**
- 로컬 `current.md`의 활성 Phase와 활성 Milestone 후보를 확인한다.
- target이 명시된 경우 대상 Phase의 `PHASE.md`를 읽고 Milestone 흐름과 Phase 경계를 확인한다.
- target이 없거나 활성 창 밖 배치 가능성이 있으면 `ROADMAP.md`의 Phase 흐름을 확인하고, 관련성이 높은 Phase 문서를 읽는다.
- 대상 또는 후보 Milestone 문서의 목표, 상태, 승격 조건, 범위, 기능 Task, 완료 리뷰, 범위 제외, 구현 잠금을 확인한다. SDD가 필요한 Milestone이면 SDD 문서 링크와 사용자 리뷰 상태도 확인한다. 기존 문서에 `필수 기능`/`완료 기준`이 분리되어 있으면 갱신 범위에서 `기능` Task로 흡수할 후보를 기록한다.
- Phase -> Milestone -> Epic -> Task 순서로 내려가며 같은 레벨의 동일/유사 후보를 먼저 찾는다.
- 로컬 `current.md`에 archive 경로가 있으면 읽지 말고 제거 대상으로 기록한다.
- 필요한 경우에만 `ROADMAP.md`를 읽어 전체 Phase 흐름을 확인한다.
- Phase를 가로지르는 다음 작업 후보를 고르거나 큐 정리가 필요하면 `priority-queue.md`를 읽는다. 링크가 깨진 항목은 추측하지 말고 활성 `phase/*/milestones/*.md` 후보를 기준으로 재정렬 또는 재생성 대상으로 기록한다.
4. **스케치 승격 판단**
- `target-status=[계획]`, `mode=concretize`, 또는 사용자가 "구체화", "계획으로 올려"처럼 요청하면 `[스케치] -> [계획]` 승격 검토로 본다.
- 대상이 `[스케치]`가 아니면 일반 상태 갱신이나 Milestone 갱신으로 처리한다.
- 대상이 `[스케치]`이면 `승격 조건`, `구현 잠금`, SDD 필요 여부, `목표`, `범위`, `기능`, `작업 컨텍스트`를 확인한다.
- `승격 조건` 체크리스트가 남아 있거나 구현 계획에 직접 필요한 결정 항목이 남아 있으면 상태를 `[스케치]`로 유지하고, 부족한 항목을 `승격 조건` 또는 `결정 필요`에 보강한다.
- 구현 가능한 목표, 범위, 기능 Task, 필요한 결정 항목, 후속 구현 단위가 정리되면 상태를 `[계획]`으로 전환하고, `승격 조건`은 충족 요약으로 남기거나 `- 없음`으로 정리한다.
- 승격은 구현 완료가 아니므로 `기능` Task를 자동 완료 처리하지 않는다.
5. **변경 내용 작성**
- `ROADMAP.md`는 전체 목표, Phase 흐름, 로딩 정책이 바뀔 때만 수정한다.
- `priority-queue.md`가 없고 로드맵 구조를 표준화하거나 생성/동기화하는 요청이면 `roadmap-priority-queue-template.md` 형식으로 만든다.
- `priority-queue.md`는 사용자 순서 조정 요청, archive/폐기 제거, 경로 변경, split/merge, 실행 의미 변경, 깨진 링크·태그·차단 참조 복구 때만 수정한다.
- `priority-queue.md`를 수정할 때는 prefix 그룹, `[prefix-NN]` Milestone 제목 링크, 1~2문장 설명, 필요한 blocker 줄을 유지하고 상태, 목표, 범위, 잠금, 기능, 완료 근거는 복제하지 않는다.
- 새 Milestone은 관련 lane이 있으면 같은 prefix의 적절한 index를 할당하고, 순차 관계가 없으면 새 prefix를 만든다. 중간 삽입으로 재index가 필요하면 경로는 유지하고 모든 표시 제목과 queue blocker 참조를 같은 변경에서 갱신한다.
- 로컬 `current.md`는 활성 Phase/Milestone 창이 바뀔 때 수정한다.
- `.gitignore`의 Agent-Ops 관리 block에 `agent-roadmap/current.md`가 있는지 확인하고 없으면 추가한다.
- `PHASE.md`는 Phase 목표, 상태, Milestone 흐름, Phase 경계가 바뀔 때 수정한다.
- Milestone 문서는 목표, 상태, 승격 조건, 구현 잠금, 범위, Epic/Task, Task 안의 검증 문구, 완료 리뷰, 범위 제외, 작업 컨텍스트가 바뀔 때 수정한다.
- 신규 또는 갱신 Milestone이 SDD 대상이면 `구현 잠금``SDD: 필요`, 해당 Milestone 파일 위치 기준 `SDD 문서` Markdown 링크, 잠금 해제 조건을 남기고 같은 흐름에서 `roadmap-sdd create`로 SDD 본문을 작성한다. 사용자 결정이 필요 없고 gate가 충족되면 SDD와 Milestone 잠금을 함께 해제한다.
- SDD 대상이 아니면 `구현 잠금``SDD: 불필요`와 짧은 사유를 남긴다.
- 동일/유사 후보가 있으면 기존 항목을 업데이트하고 중복 항목을 만들지 않는다.
- 새 Milestone은 해당 Phase의 `milestones/` 아래에 만든다.
- 새 `[스케치]` Milestone은 `승격 조건` 섹션을 포함하고 `구현 잠금``잠금`으로 둔다.
- 새 Epic은 `기능` 아래 `### Epic: [epic-id] <이름>`으로 만든다.
- 새 Task는 관련 Epic의 기능 Task가 5개 미만일 때만 `- [ ] [item-id] 설명`으로 만든다. 검증이 필요한 경우에만 같은 항목에 `검증: <명령/확인 방법/기대 결과>`를 붙인다.
- 관련 Epic에 여섯 번째 Task가 필요하면 capability, 산출물, 의존성, 검증 경계 중 하나로 Epic을 분리한 뒤 새 Task를 배치한다. 분리된 Epic이 독립 목표면 새 Milestone 후보로 재판정한다.
- 갱신 범위에 포함된 기존 Epic이 6개 이상이면 새 Task를 쓰기 전에 같은 기준으로 Epic을 분리한다. 기존 item-id는 사용자가 명시하지 않는 한 유지한다.
- 새 항목은 레벨별 탐색에서 적절한 기존 후보가 없을 때만 만든다.
- 완료 체크는 evidence가 있을 때만 `[x]`로 바꾼다.
- 모든 기능 Task와 Task 안에 명시된 검증이 evidence와 함께 `[x]`이어도 `구현 잠금``해제`가 아니거나 미완료 `결정 필요` 항목이 있으면 Milestone 상태를 `[검토중]`으로 바꾸지 않는다. `완료 리뷰` 또는 `작업 컨텍스트`에 잠금 차단 항목을 남긴다.
- 모든 기능 Task와 Task 안에 명시된 검증이 evidence와 함께 `[x]`이고 `구현 잠금`도 해제되어 있으면 Milestone 상태를 `[검토중]`으로 바꾸고 `완료 리뷰`에 완료 근거와 남은 차단 항목을 남긴다.
- `[검토중]` 전환만으로 archive 이동, 로컬 `current.md` 제거, archive 링크 변경을 수행하지 않는다.
- 기능 Task, 검증, 구현 잠금, 완료 근거가 모두 충족되면 `[검토중]``[완료]`로 전환하고 archive 모드를 수행할 수 있다.
- `locks.yaml`이 있으면 갱신 대상 Milestone identity로 `--find-milestone "<identity>" both "<locks-file>"`를 실행해 이 Milestone이 `locked`인지, `rely-on.target`인지, 관련 lock이 없는지 확인한다.
- archive 모드이면 파일 이동 전 active Milestone identity를 보존하고, 그 identity로 `--find-milestone "<identity>" both "<locks-file>"`를 먼저 실행한다.
- 외부 의존 잠금 요청 또는 외부 의존 컨텍스트 동기화가 필요하면 대상 Milestone의 `구현 잠금``잠금`으로 두고 `.agent-roadmap-sync/locks.yaml`을 upsert한다.
- `.agent-roadmap-sync/locks.yaml`이 없으면 `.agent-roadmap-sync/` 디렉터리와 `locks.yaml` 파일을 만든다.
- `locks.yaml` entry는 `id=<잠긴-project>:<잠긴-milestone-slug>`, `locked=<잠긴-project>:<잠긴-milestone-path>`, `rely-on.target=<의존-project>:<의존-milestone-path>`, `rely-on.status=<enable|disable>`, `rely-on.note=<사용자 요청 요약>`으로 기록한다.
- 같은 `id` entry가 있으면 기존 `rely-on` 목록을 보존하고 같은 `target`만 갱신하거나 새 `target`을 추가한다.
- find 결과가 `none`이면 결과 보고의 `Workspace 잠금``관련 lock 없음`을 남긴다.
- 갱신한 Milestone identity와 일치하는 `rely-on.target`은 Milestone 상태 기준으로 `enable` 또는 `disable`을 동기화한다.
- archive 모드에서 보존한 active Milestone identity와 일치하는 `rely-on.target`도 archive 이동 전에 Milestone 상태 기준으로 `enable` 또는 `disable`을 동기화한다.
- 갱신하거나 선택한 Milestone identity와 일치하는 `locked` entry가 있으면 모든 `rely-on.status``enable`인지 확인하고 결과 보고에 남긴다.
- archive 모드에서 보존한 active Milestone identity와 일치하는 `locked` entry도 archive 이동 전에 모든 `rely-on.status``enable`인지 확인하고 결과 보고에 남긴다.
- archive, 폐기, 경로 변경, split/merge 결과로 `priority-queue.md`를 수정했다면 제거/갱신된 항목을 결과 보고에 남긴다.
6. **검증**
- 로컬 `current.md`의 활성 Phase/Milestone 경로가 실제 파일을 가리키는지 확인한다.
- 로컬 `current.md`의 활성 항목이 archive 경로를 가리키지 않는지 확인한다.
- 로컬 `current.md`의 활성 항목이 `[완료]` 또는 `[폐기]` 상태로 남아 있지 않은지 확인한다.
- `agent-roadmap/current.md`가 git 추적 대상으로 남아 있지 않은지 확인한다.
- `agent-roadmap/priority-queue.md`가 있으면 `실행 순서` 섹션이 있고 모든 링크가 실제 활성 Milestone 파일을 가리키는지 확인한다.
- queue 실행 태그가 유일하고 두 자리 index 형식이며 group prefix와 일치하는지, 같은 prefix가 오름차순인지, 각 항목에 1~2문장 설명이 있는지 확인한다.
- `선행 차단`/`동시 차단` 외 blocker label이 없는지, 모든 target이 active tag로 해석되는지, 같은 prefix 기본 순서를 `선행 차단`으로 중복하지 않았는지 확인한다.
- queue tag가 Milestone H1, 활성 `PHASE.md`, 로컬 `current.md`의 표시 제목과 일치하는지 확인한다. tag 불일치는 파일 slug로 추정 보정하지 않고 검증 실패로 보고한다.
- `priority-queue.md`에 archive 경로, `[완료]` archive 대상, `[폐기]` Milestone 항목이 남아 있지 않은지 확인한다.
- `priority-queue.md`가 비어 있는데 활성 실행 후보가 있으면 큐 동기화 필요로 보고한다. 실행 후보가 없으면 빈 큐를 허용한다.
- `ROADMAP.md`의 Phase 경로가 실제 `PHASE.md` 파일을 가리키는지 확인한다.
- 각 `PHASE.md`의 Milestone 경로가 실제 파일을 가리키는지 확인한다.
- 상태 표기가 표준값인지 확인한다.
- `[스케치]` Milestone에 `승격 조건`이 있고 `구현 잠금``잠금`인지 확인한다.
- `[계획]` 이상 Milestone에 `승격 조건` 섹션이 없더라도 오류로 보지 않는다. 섹션이 있으면 `- 없음` 또는 승격 충족 요약인지 확인한다.
- `[스케치] -> [계획]` 전환을 수행했다면 승격 조건 해소 근거가 Milestone 내용이나 결과 보고에 남았는지 확인한다.
- `[검토중]` Milestone이 archive 경로로 이동되지 않았는지 확인한다.
- 모든 기능 Task와 Task 안에 명시된 검증이 `[x]`인 Milestone은 `구현 잠금`이 해제되어야 `[검토중]`이 될 수 있다. 잠금이 남아 있으면 `완료 리뷰` 또는 `작업 컨텍스트`에 잠금 차단 항목이 있는지 확인한다.
- `[검토중]` Milestone에는 `완료 리뷰` 섹션과 완료 근거/남은 차단 항목이 있는지 확인한다.
- 각 Milestone의 `구현 잠금`에 SDD 필요 여부와 사유가 있는지 확인한다.
- `SDD: 필요` Milestone은 SDD 문서 링크, SDD 파일 존재, 잠금 해제 조건, SDD 사용자 리뷰 상태가 일관되는지 확인한다. 사용자가 명시적으로 SDD 생성을 뒤로 미루지 않았는데 SDD 파일이 없으면 검증 실패로 본다.
- Epic heading과 Task id 형식이 맞고, 새 Epic과 갱신 범위에 포함된 기존 Epic의 기능 Task 수가 최대 5개인지 확인한다. 6개 이상이면 검증 실패로 보고하고 Epic 분리를 요구한다.
- 요청 규모가 판정되었고 결과 보고에 남았는지 확인한다.
- 동일/유사 기존 항목을 검색했고 신규/업데이트 판정이 결과 보고에 남았는지 확인한다.
- 자동 배치한 신규 작업이면 선택한 후보와 밀린 후보의 근거가 결과 보고에 포함되는지 확인한다.
- `.agent-roadmap-sync/locks.yaml`을 갱신했다면 `locked`, `rely-on.target`, `rely-on.status`가 채워졌는지 확인한다.
- 갱신 대상 Milestone에 resolvable한 외부 의존 잠금/선행 Milestone 컨텍스트가 있으면 해당 lock entry가 존재하는지 확인한다.
- 갱신 대상 Milestone identity가 `locked` 또는 `rely-on.target` 어느 쪽에 있든 결과 보고의 `Workspace 잠금`에 반영했는지 확인한다.
- `locks.yaml`이 있는데 갱신 대상 Milestone identity가 `locked``rely-on.target` 어느 쪽에도 없으면 `Workspace 잠금: 관련 lock 없음`으로 보고했는지 확인한다.
- archive 모드이면 이동 전 active Milestone identity로 `locks.yaml`을 검사하고 필요한 `rely-on.status` 동기화 또는 `관련 lock 없음` 보고를 수행했는지 확인한다.
- 결과 보고와 갱신한 활성 로드맵 문서의 문서/산출물 포인터가 raw path만 남지 않고 Markdown 링크로 작성되었는지 확인한다.
- 갱신한 활성 로드맵 문서의 Markdown 링크 target에 템플릿 placeholder가 남지 않았는지 확인한다.
- `git diff --check`로 공백 오류를 확인한다.
7. **결과 보고**
- 수정한 파일 목록
- 요청 규모 판정과 근거
- Phase -> Milestone -> Epic -> Task 탐색 경로와 후보
- 신규 추가인지 기존 항목 업데이트인지
- 변경된 Phase / Milestone / 상태
- 신규 작업의 삽입 단위와 배치 위치
- 자동 배치한 경우 비교한 후보와 선택 근거
- 전역 실행 순서 변경 사항
- 로컬 current.md 활성 창 변경 사항
- 완료 리뷰 상태와 남은 차단 항목
- SDD gate 상태와 사용자 리뷰 필요 여부
- 런타임 완료 이벤트의 `origin-task``m-<milestone-slug>`이면 원래 active task 경로와 매칭된 target Milestone, 새 `milestone-task` 집계 라우팅 또는 legacy `Roadmap Completion` Task ids/no-op 사유
- archive 모드이면 이동 경로와 남긴 링크
- 확인 필요로 남긴 항목
## 출력 형식
```markdown
## 업데이트 완료
- 모드: <status | milestone | phase | replan | sync | concretize | archive>
- 수정 파일: <실제로 변경한 ROADMAP/queue/current/Phase/Milestone/SDD/archive Markdown 링크 목록>
## 변경 사항
- Phase / Milestone: <변경 없음 | 요약>
- 삽입 단위: <Phase | Milestone | Epic | Task | 하위 작업 | 작업 컨텍스트/TODO | 변경 없음>
- 규모 판정: <phase | milestone | epic | task | subtask | context | 변경 없음> - <근거>
- 탐색 경로: <Phase 후보 -> Milestone 후보 -> Epic 후보 -> Task 후보 | 해당 없음>
- 신규/업데이트 판정: <신규 생성 | 기존 항목 업데이트 | 변경 없음> - <동일/유사 후보 근거>
- 배치: <사용자 지정 위치 반영 | 자동 배치 위치와 근거 | 변경 없음>
- 배치 후보: <자동 배치 1순위/2순위 후보와 선택/제외 근거 | 해당 없음>
- 템플릿 보정: <ROADMAP | local current.md | PHASE | Milestone | 이미 일치 | 변경 없음>
- 전역 실행 순서: <변경 없음 | 생성 | 순서 조정 | archive/폐기 항목 제거 | 경로 갱신 | 재생성 필요>
- 구현 잠금: <잠금 유지 | 잠금 추가 | 해제 | 잠금 차단 | 변경 없음>; 결정 필요: <없음 | 항목 요약>
- SDD gate: <불필요 | 필요-작성 | 필요-잠금 | 필요-사용자 리뷰 | 필요-승인됨 | 변경 없음>
- 승격 조건: <해당 없음 | 추가/수정/미충족 유지/충족 요약>
- 완료 리뷰: <변경 없음 | 검토중 | 통과 | 보완 필요 | 보류 | 폐기>
- runtime m-task 라우팅: <해당 없음 | milestone-task -> sync-milestone-workstate | legacy Roadmap Completion -> target Milestone | target 불명확>
- Workspace 잠금: <변경 없음 | 관련 lock 없음 | entry 생성/갱신 | rely-on enable | rely-on disable | 미충족 | 런타임 해제 대기>
- 활성 항목: <변경 없음 | Phase/Milestone 추가/제거 요약>
- 아카이브: <변경 없음 | 이동 링크와 남긴 링크>
- 상태: <변경 없음 | 이전 -> 이후>
- Epic/Task: <추가/수정/완료/제거 요약>
## TODO 항목
- <남은 차단 항목 또는 `구현 잠금 > 결정 필요`/SDD `USER_REVIEW.md` 분리한 항목> (해당 시)
```
## 금지 사항
- 로드맵 파일이 없는데 새 구조를 임의로 만들지 않는다. 이 경우 `create-roadmap`을 사용한다.
- evidence 없이 Phase, Milestone, Epic, Task를 `[완료]` 또는 `[검토중]`으로 처리하지 않는다.
- 전체 `ROADMAP.md`를 모든 작업의 필수 로딩 파일로 만들지 않는다.
- `ROADMAP.md`에 Milestone 상세 작업 체크리스트를 남기지 않는다.
- `priority-queue.md`에 상태, 목표, 범위, 잠금, 기능, 완료 근거를 복제하지 않는다. 1~2문장 설명과 최소 blocker 예외는 삭제하지 않는다.
- `priority-queue.md`에 archive 경로를 남기지 않는다.
- 사용자 순서 조정 요청 없이 `priority-queue.md`의 그룹/index/차단 관계를 에이전트 판단만으로 바꾸지 않는다. 단, archive/폐기 제거, 경로 변경, split/merge, 실행 의미 변경, 깨진 링크·태그·차단 참조 복구는 예외다.
- 로컬 `current.md`에 개인별 현재 작업 위치나 완료 상태를 남기지 않는다.
- 로컬 `current.md``agent-roadmap/archive/**` 경로를 남기지 않는다.
- `agent-roadmap/current.md`를 git 추적 대상으로 만들지 않는다.
- archive 문서를 명시 요청 없이 읽거나 최신 템플릿으로 재포맷하지 않는다.
- 완료된 Phase/Milestone 기록을 삭제하지 않는다.
- Epic과 Task를 별도 파일로 분리하지 않는다.
- Phase 이름/파일명이나 Milestone 파일명에 순번을 강제하지 않는다. Milestone 표시 제목의 `[prefix-NN]` 실행 태그는 예외다.
- 에이전트가 확정할 수 없는 결정 항목이 남아 있는데 Milestone의 `구현 잠금``해제`로 바꾸지 않는다.
- `구현 잠금`이 남아 있는 Milestone을 `[검토중]`, `[완료]`, 또는 완료 archive 대상으로 전환하지 않는다. 명시적인 폐기 근거가 있는 `[폐기]` archive는 허용한다.
- 사용자가 지정한 Phase/Milestone/Epic/Task anchor를 무시하지 않는다.
- 사용자가 명시하지 않은 기존 epic-id나 item-id를 바꾸지 않는다.
- `rely-on.status=enable`만으로 다른 프로젝트 Milestone의 `구현 잠금`을 직접 해제하지 않는다.
- Do not create gates for documentation completeness, plan/review presence, test-environment availability, or evidence formatting.
- Do not create duplicate roadmap items.
- Do not infer cross-project locks.
- Do not read or rewrite unrelated archive content.

View file

@ -1,170 +1,48 @@
---
name: update-test
description: 기존 agent-test 환경 rules.md 또는 테스트 profile을 수정하고 파일 수정 없는 Verification Context를 제공한다. 테스트 규칙 수정·갱신, 테스트 컨텍스트 해석, Verification Context 생성 요청에 사용한다.
description: 기존 테스트 규칙이나 profile을 최소 범위로 갱신하거나 현재 작업의 최소 Verification Context를 반환한다.
---
# update-test
## 목적
## 방향
기존 `agent-test/<env>/rules.md` 또는 `agent-test/<env>/<test-profile>.md`를 최신 테스트 기준에 맞게 갱신한다.
라우팅은 3홉 안에 유지하고, 도메인/검증 시나리오별 문서는 자체 완결되게 보완한다.
`resolve-context` 모드에서는 해당 문서를 수정하지 않고 현재 task에 적용할 명령, 판정 기준, 제약, 외부 환경 preflight를 중립 `Verification Context`로 반환한다.
`test-case`는 기존 호출과의 호환을 위한 alias이며, 새 문서 기준 이름은 `test-profile`이다.
## 언제 호출할지
- 기존 테스트 환경 규칙을 수정할 때
- 도메인/검증 시나리오별 테스트 기준, 명령, 판정 기준을 보완할 때
- 테스트 라우팅을 추가, 제거, 정리할 때
- plan 또는 다른 소비자가 구현 범위에 맞는 테스트 환경/profile 정보를 필요로 할 때
검증 게이트 최소화를 최우선으로 한다. 테스트 문서와 환경 상태는 구현·완료의 자동 게이트가 아니다.
## 입력
- `mode`: `update` 또는 `resolve-context`. 기본값은 `update` (선택)
- `env`: `local`, `dev`, `qa`, `prod` 중 하나. 기본값은 `local` (선택)
- `test-profile`: 수정할 도메인/검증 시나리오별 테스트 문서 이름, kebab-case (선택)
- `test-case`: `test-profile`의 호환 alias (선택)
- `domain`: 대상 도메인 이름, kebab-case (선택)
- `change`: 수정할 내용 요약. `mode=update`에서 필수 (선택)
- `task-summary`: 검증할 동작과 완료 조건 요약. `mode=resolve-context`에서 필수 (선택)
- `scope-paths`: 변경 후보 source/test 경로 목록. `mode=resolve-context`에서 선택
- `verification-type`: 예: `unit`, `smoke`, `integration`, `e2e`. `mode=resolve-context`에서 선택
- `mode`: `update` 또는 `resolve-context`
- `env`: 기본 `local`
- `test-profile`: 선택
- `change` 또는 `task-summary`
- `scope-paths`: 선택
## 먼저 확인할 것
## update
- [ ] `agent-ops/rules/common/rules.md`의 스킬 규칙과 테스트 규칙이 분리되어 있는지 확인한다.
- [ ] `agent-ops/skills/common/router.md``update-test` 라우팅이 있는지 확인한다.
- [ ] `test-case`가 있고 `test-profile`이 없으면 `test-profile`로 취급한다.
- [ ] `mode=update`이면 `change`가 있는지, `mode=resolve-context`이면 `task-summary`가 있는지 확인한다.
- [ ] `agent-test/<env>/rules.md` 존재 여부를 확인한다. `mode=update`에서 없으면 `create-test` 대상으로 보고 중단하고, `mode=resolve-context`에서는 `rules_state: missing`으로 반환한다.
- [ ] `agent-test/<env>/rules.md`가 있으면 읽는다.
- [ ] `test-profile`이 있으면 `agent-test/<env>/<test-profile>.md` 존재 여부를 확인한다. `mode=update`에서 없으면 `create-test` 대상으로 보고 중단하고, `mode=resolve-context`에서는 gap으로 기록한다.
- [ ] `test-profile` 문서가 있으면 읽는다.
- [ ] `test-profile`이 없으면 `domain`, `change`, `task-summary`, `scope-paths`, `verification-type`을 env rules의 `## 라우팅`과 대조해 모든 matching profile을 찾는다.
- [ ] 템플릿 구조 확인이 필요하면 `agent-ops/rules/common/_templates/`의 테스트 템플릿을 읽는다.
- [ ] 기존 라우팅이 3홉 안에 있는지 확인한다.
1. 직접 관련된 env rules와 profile만 읽는다.
2. 기존 환경값과 확인된 명령은 보존한다.
3. 중복 규칙과 실제 위험 근거가 없는 필수 검증·preflight·차단 기준을 제거한다.
4. 기본 검증은 변경 위험에 직접 대응하는 가장 작은 명령으로 둔다.
5. 확대 검증은 사용자 요청, 실제 실패, 구체적 회귀 위험이 있을 때만 선택 항목으로 둔다.
## 실행 절차
## resolve-context
1. **모드 확정**
- `mode=resolve-context`이면 아래 `resolve-context 절차`만 수행하고 파일, `.gitignore`, `last_rule_updated_at`을 수정하지 않는다.
- `mode=update`이면 아래 `update 절차`를 수행한다.
1. 직접 관련된 문서만 읽고 파일은 수정하지 않는다.
2. 가장 작은 관련 명령과 성공 기준을 반환한다.
3. 외부 환경 검증은 현재 변경에 직접 필요할 때만 표시한다.
4. 실행할 수 없는 선택 검증은 남은 위험으로 기록하되 완료를 자동 차단하지 않는다.
### update 절차
## 출력
1. **대상 확정**
- 환경 공통 규칙 변경이면 `agent-test/<env>/rules.md`만 수정한다.
- 특정 도메인/검증 기준 변경이면 해당 `test-profile` 문서를 수정한다.
- 특정 대상이 암시되지만 라우팅에서 찾지 못하면 생성하지 말고 `create-test` 대상이라고 보고한다.
- 대상 문서가 없으면 생성하지 말고 `create-test` 대상이라고 보고한다.
- 읽거나 수정한 파일
- 최소 검증 명령과 성공 기준
- 선택 검증과 적용 조건
- 남은 위험 또는 확인되지 않은 값
2. **문서 갱신**
- 기존 환경값, 명령, 금지 사항을 보존한다.
- 오래된 기준은 새 기준으로 교체하고 같은 뜻의 중복 문장은 줄인다.
- 도메인/검증 시나리오별 문서는 읽기 조건, 적용 범위, 명령, 필수 검증, 판정 기준, 차단 기준을 자체 포함하게 유지한다.
- `last_rule_updated_at`은 수정일 `YYYY-MM-DD`로 갱신한다.
## 금지
3. **라우팅 갱신**
- env rules의 `## 라우팅`은 도메인/검증 시나리오별 문서로만 향하게 한다.
- 맞지 않는 라우팅은 제거하거나 더 정확한 `domain / verification-type / scope` 설명으로 바꾼다.
- 도메인/검증 시나리오별 문서에서 다른 테스트 문서로 이어지는 라우팅은 제거한다.
- 공통룰에서 스킬 최종 진입까지의 경로는 `rules.md` -> `router.md` -> `update-test/SKILL.md`로 유지한다.
4. **local 추적 제외 확인**
- `env``local`이면 `.gitignore``agent-test/local/``agent-test/runs/`가 있는지 확인하고 없으면 추가한다.
5. **결과 보고**
- 수정한 파일
- 바꾼 라우팅
- 보존한 환경값
- 남은 확인 필요 항목
### resolve-context 절차
1. **환경 규칙 상태 판정**
- env rules를 `missing`, `blank-skeleton`, `structured-incomplete`, `usable` 중 하나로 판정한다.
- `missing` 또는 `blank-skeleton`이어도 생성하거나 보완하지 않는다.
- 실제 파일에 없는 명령, endpoint, credential, 판정 기준을 추측하지 않는다.
2. **matching profile 해석**
- 명시된 `test-profile` 또는 env rules의 `## 라우팅`에서 `domain / verification-type / scope`가 맞는 모든 profile을 선택한다.
- 매칭 근거가 없는 profile은 읽거나 반환하지 않는다.
- route가 가리키는 profile이 없거나 구조적으로 비어 있으면 gap으로 기록한다.
3. **검증 사실 추출**
- env rules와 matching profile에서 실행 위치, 명령, 필수 순서, 기대 결과, 차단 기준, cache 허용 여부, 외부 서비스/secret 요구 여부를 원문 의미를 바꾸지 않고 추출한다.
- 명령이 여러 profile에 걸치면 profile별 출처와 적용 범위를 유지한다.
- `<확인 필요>` 또는 서로 충돌하는 값은 확정하지 않고 gap으로 기록한다.
- env rules와 matching profile이 usable이고 적용 명령·판정 기준에 gap이 없으면 confidence를 `high`, 일부 값에 repository-native 확인이 더 필요하면 `medium`, rules가 missing/blank이거나 핵심 값이 unresolved이면 `low`로 판정한다.
4. **외부 환경 preflight 구성**
- 현재 checkout 밖의 runner, field/bootstrap, external provider, Docker/code-server, emulator/device, shared runtime이 필요한 검증만 read-only preflight 대상으로 삼는다.
- env/profile에 적힌 범위 안에서 repo root/workdir, branch/HEAD/dirty state, source sync, binary/artifact, command help/version, config path, runtime identity, ports/process, external host, OS/arch 확인 항목을 구성한다.
- 안전한 read-only probe를 현재 환경에서 실행할 수 있으면 실제 결과를 반환하고, 실행할 수 없으면 필요한 probe와 blocker를 구분해 반환한다.
- secret, token, credential 원문은 읽거나 출력하지 않는다.
5. **중립 handoff 반환**
- 소비 스킬 이름이나 문서 section 이름에 결합하지 않고 아래 출력 형식을 그대로 반환한다.
- test rule 유지보수는 사용자가 요청했거나 확인된 구조 결함이 있을 때만 `create-test` 또는 `update-test` 후보로 표시한다. `resolve-context` 실행 중 직접 호출하거나 수정하지 않는다.
## 실행 결과 검증
- [ ] 수정 대상 문서가 여전히 필수 섹션을 포함하는가
- [ ] `rules.md` -> `router.md` -> `update-test/SKILL.md` 경로가 끊기지 않는가
- [ ] env rules 라우팅이 3홉 제한을 넘기지 않는가
- [ ] 도메인/검증 시나리오별 문서가 다른 테스트 문서로 라우팅하지 않는가
- [ ] local 수정 시 `.gitignore`에 local 경로가 반영되었는가
- [ ] `resolve-context`에서 파일과 `.gitignore`를 수정하지 않았는가
- [ ] `resolve-context`가 읽은 env/profile 경로와 각 명령의 출처를 정확히 반환하는가
- [ ] 외부 검증이 있으면 read-only preflight 결과 또는 실행 불가 blocker가 구분되어 있는가
- [ ] 누락, `<확인 필요>`, 충돌 값을 확정된 명령이나 기준으로 반환하지 않았는가
- [ ] secret, token, 개인 endpoint 원문이 tracked 파일에 추가되지 않았는가
- 검증 실패 시: 문제 문서만 다시 보완한다.
## 출력 형식
```md
## 수정 완료
- 환경: <env>
- 수정 파일: <path>
- 라우팅 변경: <내용 또는 없음>
- 보존한 환경값: <요약>
- 확인 필요: <항목 또는 없음>
```
`mode=resolve-context`:
```md
## Verification Context
- Environment: <env>
- Rules State: <missing|blank-skeleton|structured-incomplete|usable>
- Sources Read:
- <env rules/profile path 또는 없음>
- Scope Match:
- <domain / verification-type / scope와 매칭 근거 또는 없음>
- Commands:
- `<command>`: source=`<path>`; scope=`<scope>`; expected=`<result>`; cache=`<allowed|fresh|required|unspecified>`
- Preconditions:
- <필수 순서, 실행 위치, config/runtime 요구 또는 없음>
- Read-only Preflight:
- `<probe>`: <PASS|BLOCKED|NOT_RUN>; <actual result or reason>
- Constraints:
- <금지 사항, 외부 서비스/secret 요구 여부 또는 없음>
- Gaps:
- <missing profile, blank value, `<확인 필요>`, conflict 또는 없음>
- Confidence: <high|medium|low>; <판정 근거>
- Maintenance: <not-needed|create-test-candidate|update-test-candidate>; <근거>
```
## 금지 사항
- 기존 local 환경값을 추측으로 바꾸지 않는다.
- 확인되지 않은 테스트 명령을 필수 검증으로 단정하지 않는다.
- 도메인/검증 시나리오별 문서를 router처럼 쓰지 않는다.
- `resolve-context`에서 테스트 문서 생성, 수정, `.gitignore` 갱신을 수행하지 않는다.
- `resolve-context` 출력에 특정 소비 스킬 전용 필드나 파일명을 강제하지 않는다.
- secret, token, 개인 endpoint 원문을 tracked 파일에 기록하지 않는다.
- full-suite, E2E, 외부 provider, 원격 runner를 기본값으로 승격하지 않는다.
- 테스트 profile 누락이나 문서 형식만으로 구현을 차단하지 않는다.
- 다른 스킬, plan, review, preflight를 자동 호출하지 않는다.
- 확인되지 않은 명령이나 환경값을 확정하지 않는다.
- secret을 tracked 문서나 출력에 기록하지 않는다.

View file

@ -1,168 +1,52 @@
---
name: e2e-smoke
version: 1.1.0
description: scripts/dev/edge.sh와 scripts/dev/node.sh 기반 repo 내부 edge-node 진단, 보조 E2E smoke, 실제 외부 CLI 통합 검증 절차
version: 2.0.0
description: Edge-Node 실행 경로에 직접 필요한 경우 최소 E2E smoke를 선택해 수행한다.
---
# e2e-smoke
## 목적
## 방향
repo 내부 edge-node 진단이 필요할 때 `scripts/dev/edge.sh``scripts/dev/node.sh`를 각각 실행하고, edge console에서 메시지 2회와 command 명령을 직접 보내 결과가 edge 화면에 표시되는지 검증한다. field 사용자 기본 UX는 Edge가 제시한 bootstrap 명령이며, `scripts/dev/*` helper를 공식 사용자 경로로 안내하지 않는다. `make test-e2e``scripts/e2e-smoke.sh`는 최소 생존을 빠르게 확인하는 보조 smoke일 뿐이며, 사용자 실행 파이프라인 변경의 완료 기준이 아니다.
검증 게이트 최소화를 최우선으로 한다. E2E와 full-cycle은 기본 완료 게이트가 아니며, 변경 범위와 위험에 직접 필요한 최소 cycle만 실행한다.
## 언제 호출할지
## 사용 조건
- 사용자 실행 파이프라인에 닿는 작업을 완료한 뒤 검증 단계에 들어갈 때
- `scripts/dev/**`, `Makefile`, `apps/*/cmd/**`, `apps/*/internal/bootstrap/**`, edge-node transport/service/registry, adapter 실행/stream/cancel/status 경로를 변경했을 때
- `configs/**`, `packages/go/config/**`, 관련 protobuf 계약 변경이 edge-node 실행 방식에 영향을 줄 때
- `make test-e2e` 또는 보조 E2E smoke 스크립트를 만들거나 갱신할 때
- 사용자가 E2E 또는 실제 CLI 검증을 요청했다.
- 변경이 Edge-Node 연결·stream·cancel·status 경로를 직접 바꿨고 작은 단위 테스트만으로 핵심 위험을 확인할 수 없다.
- 실제 회귀가 재현되어 E2E 확인이 필요하다.
## 입력
- `scope`: 검증할 변경 범위와 영향을 받은 도메인 (필수)
- `mode`: `bin-diagnostic`, `mock-smoke`, `real-cli`, `full-cycle`, `all` 중 하나 (선택, 기본값: `bin-diagnostic`)
- `profiles`: 검증할 실제 외부 CLI profile 목록. 지정하지 않으면 기준 profile인 `claude`, `antigravity`, `codex`, `opencode`를 대상으로 한다. (선택)
- `config_strategy`: 임시 config 파일 또는 환경 변수 override 방식 (선택)
- `scope`: 변경 범위
- `mode`: `mock-smoke`, `bin-diagnostic`, `real-cli`, `full-cycle` 중 필요한 하나
- `profiles`: 실제 CLI가 필요한 경우에만 지정
## 먼저 확인할 것
## 절차
- [ ] `agent-ops/rules/project/domain/testing/rules.md`를 읽고 이번 작업에 필요한 repo 내부 edge-node 진단 또는 field bootstrap 검증 범위를 확인한다.
- [ ] `scripts/dev/edge.sh``scripts/dev/node.sh`는 repo 내부 진단 helper이며 field 사용자 기본 entrypoint가 아님을 확인한다.
- [ ] `make test-e2e` 같은 고정 smoke 명령은 보조 확인으로만 취급한다.
- [ ] 기본 `configs/*.yaml`을 오염시키지 않도록 임시 config 또는 환경 변수 override 전략을 정한다.
- [ ] 실제 외부 CLI 검증이 필요한 경우 command 경로, 로그인/계정 상태, provider 설정, workspace 권한이 준비되어 있는지 확인한다.
1. 변경 위험 하나를 정하고 그 위험을 확인하는 가장 작은 mode를 선택한다.
2. mock smoke로 충분하면 실제 CLI나 full-cycle로 확대하지 않는다.
3. repo 내부 진단이 필요하면 임시 config와 충돌 없는 port를 사용한다.
4. 연결 경로 검증은 register, 관련 요청 1회, terminal 순서만 확인한다. 2회 요청이나 모든 command 검사는 해당 동작을 변경했을 때만 추가한다.
5. 실제 CLI profile은 변경된 profile 또는 대표 profile 하나만 기본 대상으로 한다. 전체 profile 검사는 사용자가 명시했을 때만 한다.
6. 실패가 확인되면 해당 영향 범위만 보강해 재검증한다.
## 실행 절차
## 판정
1. **검증 범위 결정**
- 변경 파일이 사용자 실행 파이프라인에 닿는지 확인한다.
- 필수 검증은 `go test ./...` 또는 대상 패키지 테스트와 변경 범위에 맞는 full-cycle 실제 구동이다. repo 내부 edge-node 진단에는 `scripts/dev/edge.sh``scripts/dev/node.sh`를 사용할 수 있다.
- 보조 smoke는 실행할 수 있으면 기록하되, 통과만으로 완료 처리하지 않는다.
- 풀테스트에서는 실제 외부 CLI profile 검증을 full-cycle에 포함한다.
- 선택한 최소 시나리오가 기대 동작을 보이면 통과다.
- 실행하지 않은 확대 검증은 필요할 때만 남은 위험으로 기록하며 완료를 자동 차단하지 않는다.
- 보안·데이터 손상·비가역 외부 변경 검증이 실패하면 중단한다.
2. **repo 내부 edge-node 진단 준비**
- edge와 node는 `scripts/dev/edge.sh`, `scripts/dev/node.sh`를 각각 별도 프로세스로 실행한다. 이 흐름은 내부 진단용이며 사용자-facing field bootstrap 안내가 아니다.
- 임시 edge/node config 또는 환경 변수 override를 사용하고, edge listen 주소와 node edge 주소는 충돌을 피하기 위해 임시 포트를 사용한다.
- 검증용 target은 변경 범위에 맞춘다. 외부 CLI 자체가 검증 대상이 아니면 deterministic CLI profile을 사용해 메시지 출력 내용을 분명하게 만든다.
## 결과 보고
3. **startup/register cycle**
- 먼저 `scripts/dev/edge.sh`를 실행해 edge console prompt가 뜨는지 확인한다.
- 다른 프로세스에서 `scripts/dev/node.sh`를 실행해 node가 edge에 연결되는지 확인한다.
- edge 화면에 `[node-*-event] connected reason="registered"`가 표시되어야 한다.
- edge console에서 `/nodes`를 입력하고 node ID와 alias가 표시되어야 한다.
- 선택한 mode와 이유
- 실행 명령과 결과
- 확인한 동작
- 실패 또는 남은 구체적 위험
4. **메시지 2회 왕복 기준**
- edge console prompt에 메시지를 한 번 입력한다.
- 첫 번째 요청에서 `[edge] sent`, `[node-*-event] start`, 비어 있지 않은 `[node-*-message]`, `[node-*-event] complete`가 edge 화면에 도착해야 한다.
- node 로컬 출력에 생성된 같은 run의 `[node-message]` payload 라인 목록이 edge console의 `[node-*-message]` payload 라인 목록과 내용/순서까지 동일한지 비교한다.
- complete event만으로 정상 판정하지 않는다. complete event는 node가 생성한 모든 message payload가 edge에 동일하게 표시된 뒤의 마감 신호여야 한다.
- 답변이 끝나기 전에 edge complete가 먼저 표시되거나 complete 뒤에 같은 run의 message가 추가로 표시되면 실패로 판정한다.
- 같은 session에서 두 번째 메시지를 입력하고 같은 출력 흐름이 다시 도착해야 한다.
- 두 번째 메시지가 첫 번째 메시지 이후에도 같은 edge-node 연결에서 정상 처리되는지 확인한다.
- foreground run에서는 complete event 전에 다음 검증으로 넘어가지 않는다.
## 금지
5. **edge command 응답 기준**
- edge console에서 command를 직접 입력하고 결과가 edge 화면에 도착하는지 확인한다.
- 기본 command 기준은 `/nodes`, `/capabilities`, `/transport`, `/sessions`이다.
- persistent profile이면 `/terminate-session`을 실행하고 성공 출력 또는 명확한 unsupported/error 출력을 확인한다.
- status 경로를 바꾼 작업은 `/status` 결과를 확인한다. 지원 profile이면 status 출력 내용을 확인하고, 미지원 profile이면 명확한 unsupported error를 확인한다.
- multi-node/routing을 바꾼 작업은 node 2대를 실제로 붙여 ambiguous error와 `/node <id|alias>` 선택 후 라우팅을 확인한다.
- cancel/timeout/persistent session을 바꾼 작업은 해당 cycle도 실제 구동으로 확인한다.
6. **기준 출력 예시**
```text
edge> /nodes
test-node (test-node)
edge> Convert token iop_manual_one and reply only with converted token
[edge] sent run_id=manual-... node=test-node adapter=cli target=fake-cli session=default background=false
[node-test-node-event] start run_id=manual-...
[node-test-node-message] IOP_MANUAL_ONE_OK
[node-test-node-message] IOP_MANUAL_ONE_TAIL
[node-test-node-event] complete run_id=manual-... detail="idle-timeout"
edge> Convert token iop_manual_two and reply only with converted token
[edge] sent run_id=manual-... node=test-node adapter=cli target=fake-cli session=default background=false
[node-test-node-event] start run_id=manual-...
[node-test-node-message] IOP_MANUAL_TWO_OK
[node-test-node-message] IOP_MANUAL_TWO_TAIL
[node-test-node-event] complete run_id=manual-... detail="idle-timeout"
edge> /capabilities
[node-test-node-capabilities] target=fake-cli session=default
adapter = cli
max_concurrency = 4
targets = fake-cli
edge> /transport
[node-test-node-transport] target=fake-cli session=default
adapter = cli
connected = true
node_id = test-node
session_id = default
target = fake-cli
edge> /sessions
[node-test-node-sessions] target=fake-cli session=default
count = 1
sessions = persistent:fake-cli/default
edge> /terminate-session
terminated session default node=test-node
```
7. **보조 E2E smoke**
- `make test-e2e` 또는 `scripts/e2e-smoke.sh`는 보조 확인으로 실행할 수 있다.
- 보조 smoke에서는 mock adapter와 임시 설정/포트를 사용해 외부 CLI 의존성 없이 최소 생존을 확인한다.
- 보조 smoke 통과를 repo 내부 edge-node 진단 또는 field bootstrap 검증 통과로 대체해 보고하지 않는다.
8. **CLI profile 실제 구동 검증**
- 풀테스트에서는 기준 실제 외부 CLI profile을 한 번씩 실제 구동한다.
- `claude`, `antigravity`, `codex`, `opencode`를 대상으로 같은 session 메시지를 최소 2회 주고받는다.
- 각 profile에서 start, delta-or-message, complete 출력이 모두 생기는지 확인한다.
- command, 로그인, provider, workspace 권한, 원격 endpoint 문제로 실행할 수 없거나 실패한 profile은 누락이 아니라 실패/blocker로 profile별 보고한다.
9. **결과 보고**
- 실행한 Go 테스트 명령과 결과를 적는다.
- repo 내부 edge-node 진단에서 사용한 config 전략, 메시지 2회 결과, command 응답 결과를 적는다.
- 보조 smoke를 실행했다면 별도 항목으로만 적는다.
- full-cycle에서 돌린 cycle 목록과 돌리지 못한 cycle 목록을 구분해 적는다.
- 필수 검증을 실행하지 못했다면 이유와 남은 위험을 명시한다.
## 실행 결과 검증
- [ ] 일반 Go 테스트 또는 대상 패키지 테스트 결과가 보고되었는가
- [ ] `scripts/dev/edge.sh``scripts/dev/node.sh`를 각각 실행한 repo 내부 edge-node 진단 결과가 보고되었는가
- [ ] node register와 `/nodes` 결과가 edge 화면에 표시되었는가
- [ ] 같은 session에서 메시지 2회가 각각 sent/start/message/complete로 표시되었는가
- [ ] node 로컬 `[node-message]` payload 라인 목록이 edge `[node-*-message]` 출력과 run별로 내용/순서까지 동일한가
- [ ] edge complete가 같은 run의 마지막 message 출력 이후에 표시되고, complete 뒤에 같은 run의 message가 추가로 표시되지 않았는가
- [ ] `/capabilities`, `/transport`, `/sessions`, 관련 command 결과가 edge 화면에 표시되었는가
- [ ] 보조 smoke를 실행했다면 repo 내부 edge-node 진단 또는 field bootstrap 검증과 구분해 보고했는가
- [ ] 풀테스트에서 실제 외부 CLI profile별 메시지 왕복과 `/status` 결과가 보고되었는가
- 검증 실패 시: 실패한 항목, 관련 로그/출력 요약, 남은 위험을 최종 보고에 포함한다.
## 출력 형식
```text
검증 결과
- Go 테스트: <명령> - <통과|실패|미실행 사유>
- Repo 내부 edge-node 진단: <통과|실패|미실행 사유>
- 메시지 왕복: message x2 - <통과|실패|미실행 사유>
- Node message relay: node local payload == edge rendered payload - <통과|실패|미실행 사유>
- Edge command 응답: /nodes, /capabilities, /transport, /sessions, <관련 command> - <통과|실패|미실행 사유>
- 보조 E2E smoke: <mock|real-cli|미실행> - <통과|실패|미실행 사유>
- Full-cycle 실제 구동: <통과|실패|미실행 사유>
- Real CLI profile: <profile별 통과|실패|blocker>
- 남은 위험: <없음 또는 내용>
```
## 금지 사항
- 사용자 실행 파이프라인에 닿는 변경을 하고 유닛/패키지 테스트만으로 완료 처리하지 않는다.
- `make test-e2e`, `scripts/e2e-smoke.sh`, 또는 smoke 통과 출력만으로 완료 처리하지 않는다.
- 관련 작업 후 필요한 full-cycle 실제 구동 또는 repo 내부 edge-node 진단을 비용이 크다는 이유만으로 생략하지 않는다.
- 보조 E2E smoke를 외부 CLI 설치, 로그인, 네트워크 계정 상태에 의존하게 만들지 않는다.
- 검증을 위해 기본 `configs/*.yaml`을 임시값으로 오염시키지 않는다.
- 필수 검증을 실행하지 못했는데 조용히 생략하지 않는다.
- 모든 변경에 `go test ./...`, full-cycle, 실제 외부 CLI 전체를 강제하지 않는다.
- smoke 통과 뒤 추가 근거 없이 검증 범위를 확대하지 않는다.
- 기본 config를 임시값으로 오염시키지 않는다.
- credential 원문을 읽거나 출력하지 않는다.

View file

@ -38,7 +38,7 @@ RAG, context 구성/압축, web search, MCP 정책, tool policy, output validati
1차 MVP는 다중 IOP Node/디바이스의 model group queue와 추가 provider 검증, provider 요청 사용량·실행 로그와 운영 관측, 사용자/토큰/credential 추적, provider catalog와 로컬 디바이스 상태 관찰, request-local 단계 호출·workspace 도구 실행과 runtime schema 검증의 최소 실행 모드를 기준으로 둔다. request-scoped tool executor는 IOP 범위에 포함하고, standalone 장기 workflow, 범용 interactive terminal과 desktop delivery는 별도 제품 축으로 둔다.
provider/device/model별 qualification report와 모델 lifecycle 관리는 provider serving 경로와 capacity/concurrency 기준선이 잡힌 뒤 `운영 관측과 Provider 관리` Phase의 후반부에서 깊게 구체화한다.
`(2차)`로 분류한 누적 요청 컨텍스트 최적화, 장기 기억/RAG update loop, advisor와 Context Hook, cross-Edge/cloud fallback 고도화는 IOP MVP 이후 스케치로 잠근다. 특정 제품 전용 CLI agent, 범용 원격 terminal과 oto 기반 scheduler/CI-CD는 IOP 후속 후보에서 제외하되 execution preset의 request-scoped Node tool executor는 이 제외에 포함하지 않는다.
로 추가되는 MVP/2차 Milestone은 모두 사용자 검토 전까지 `구현 잠금: 잠금` 상태를 유지하고, 구현 계획이나 세부 API 확정은 별도 구체화 요청에서 다룬다.
Milestone에도 검증·승인·문서 상태 기반 게이트를 기본 추가하지 않는다. 현재 구현에 꼭 필요한 제품 결정만 해당 범위에서 확인하고, 나머지는 최소 구현과 직접 관련 검증으로 진행한다.
## Phase 흐름
@ -101,12 +101,12 @@ Phase는 실행 순서가 아니라 도메인/책임 영역의 구조적 지도
- 활성 Phase 또는 Milestone 밖의 작업이면 이 문서의 Phase 흐름을 확인하고 사용자에게 진행 또는 전환 여부를 확인한다.
- 이 문서는 로드맵 생성/갱신, Phase 전환, Phase 추가/수정, 전체 구조 변경 요청이 있을 때만 읽는다.
- 상세 작업은 각 Milestone 문서의 `기능`으로 관리한다. 검증이 필요한 기능만 같은 Task 안에 `검증:`으로 통합한다.
- 모든 기능 Task와 Task 안에 명시된 검증이 충족된 Milestone은 먼저 `[검토중]`으로 두고, 사용자 완료 확인과 archive 승인을 받은 뒤 `[완료]`로 전환한다.
- 모든 기능 Task가 충족된 Milestone은 바로 `[완료]`로 전환할 수 있다. 별도 사용자 승인이나 archive 절차를 완료 조건으로 두지 않는다.
- 완료된 Phase는 archive Phase 문서 경로로 이동하고, 하위 Milestone도 같은 archive Phase scaffold 아래에 둔다.
- 진행중 Phase 안에서 완료된 Milestone은 활성 Phase 문서에 짧은 링크를 남기고, 상세 문서는 해당 archive Phase 하위 `milestones/` 경로로 이동한다.
- archive `PHASE.md`는 Phase 자체가 완료 또는 폐기될 때만 만들며, 진행중 Phase의 완료 Milestone만 archive된 경우 archive Phase 디렉터리에 `milestones/`만 있을 수 있다.
- `agent-roadmap/archive/**`는 일반 작업에서 읽지 않는다. 과거 완료 내용, 완료 근거, 복원, 비교가 필요한 경우에만 `ROADMAP.md` 또는 `PHASE.md`의 archive 링크를 따라가서 읽는다.
- 아카이브된 Phase/Milestone 문서는 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.
- 선택된 Milestone의 `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 코드 구현, `agent-task` 구현 계획 생성, 세부 API/파일 구조 확정을 시작하지 않는다.
- 현재 요청과 직접 관련 없는 미정 항목도 잠금 상태의 Milestone 안에서는 실구현 진행 예외가 아니다. 먼저 roadmap-only 갱신으로 해당 항목을 `범위 제외`, 후속 Milestone, 또는 `작업 컨텍스트`로 옮기고 `구현 잠금``해제`한 뒤 별도 구현 계획에서 진행한다.
- Milestone 전체에서 사용자만 결정할 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `구현 잠금` 상태를 `해제`로 둔다.
- Milestone 상태, SDD 상태, 계획·리뷰·evidence 문서 유무는 구현과 완료의 선행 게이트가 아니다.
- 미정 항목은 직접 의존하는 작업만 보류한다. 관련 없는 Task와 최소 구현은 계속 진행한다.
- 검증은 변경 위험에 직접 대응하는 최소 범위로 한정하며, 추가 검증은 실제 실패나 구체적 위험이 확인된 뒤에만 보강한다.

View file

@ -15,10 +15,9 @@ Control Plane은 Edge의 inference 실행·취소·상태·usage·lifecycle을
[계획]
## 구현 잠금
## 결정 사항
- 상태: 해제
- 결정 필요: 없음 (아래 결정 기록)
- 결정 기록:
- [x] Multi-Edge 1차 범위를 observe-only로 둘지, fleet-wide 명령까지 포함할지 결정한다. 결정: 관찰은 Edge 연결/health 확인 수준으로 제한하고, 1차 범위는 multi-edge 운영이 실제 가능하도록 fleet-wide 명령과 제어를 포함한다.
- [x] Control Plane과 Edge 사이의 상태 소유권과 aggregation 깊이를 결정한다. 결정: Edge 설정, IOP Node registry, provider/device/model 실행 상태의 원본은 Edge가 소유한다. Control Plane은 연결된 Edge를 제어하기 위한 연결/health, provider capability 요약, inference 명령 요청/결과, audit에 필요한 최소 운영 기록만 가진다. Edge는 다른 Control Plane으로 옮길 수 있어야 하며 Control Plane에 실질 데이터를 묶지 않는다.
- [x] OTO/build-deploy domain agent 상태를 fleet 화면의 1차 범위에 포함할지 결정한다. 결정: 포함하지 않는다. Agent/CLI/workspace/tool/terminal/PTY/file/process/log/remote와 OTO/build-deploy 자동화는 Chronos Server/Chronos Node가 소유하며, IOP Control Plane·Edge·IOP Node에는 Chronos bridge/target/registry나 domain-agent status/command를 두지 않는다.
@ -61,7 +60,6 @@ OpenAI-compatible inference를 특정 Edge/provider adapter로 위임하고 Agen
- 완료 근거: 모든 기능 Task와 Task 안에 명시된 검증이 아직 충족되지 않았다.
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -22,16 +22,9 @@ advisor 역할과 여러 최적화·검증 기능을 실행 흐름에 연결할
- [ ] advisor 또는 hook 실행 target을 선택할 때의 비용, 지연, 품질 기준을 정리한다.
- [ ] 사용자에게 advisor/context hook 결과를 노출할지 내부 정책으로 둘지 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 Milestone은 Advisor 역할과 Context Hook 경계를 정리하는 스케치이며, hook runtime/API 계약으로 승격할 때 SDD 필요 여부를 재판정한다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 미정 항목이 사용자 검토로 해소되어 있다.
- [ ] Advisor와 Context Hook의 구현 단위와 후속 Milestone이 분리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] advisor를 별도 사용자 기능으로 노출할지 내부 최적화 역할로 둘지 결정한다.
- [ ] Context Hook을 독립적인 재사용 extension lifecycle로 구현할지 advisor 통합 지점으로 한정할지 결정한다.
- [ ] hook 실행에 local target을 우선할지 실행 라우팅 정책을 따르게 할지 결정한다.
@ -63,7 +56,6 @@ MVP 이후 advisor 역할과 재사용 가능한 Context Hook 경계를 검토
- 완료 근거: 스케치 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -18,23 +18,10 @@ OpenAI Chat/Responses, Anthropic Messages, Gemini ingress의 서로 다른 외
- 없음
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/knowledge-tool-optimization-extension/inference-api-surface-execution-lifecycle-refactor/SDD.md)
- SDD 사유: 세 외부 API 계약과 stream lifecycle, cross-repo benchmark baseline을 함께 보존해야 하는 경계 리팩터링이다.
- SDD 상태: 승인됨
- SDD 잠금: 해제
- SDD 사용자 리뷰: 없음
- 잠금 해제 조건: 아래 체크리스트
- [x] SDD 잠금이 해제되어 있다.
- [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
- [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
- [x] Evidence Map이 완료 시 `complete.log``milestone-task` id별 집계와 최종 검증 evidence로 검증 가능하게 연결되어 있다.
- [ ] workspace lock `iop:inference-api-surface-execution-lifecycle-refactor`의 모든 의존 상태가 `enable`이다.
- [ ] 구현 plan 시작 시 `iop-s0` 벤치마크 이후 변경을 제품 code/spec/contract와 benchmark-only harness/data로 분류하고, 제품 동작에 필요한 변경만 현재 `dev`에 반영됐거나 명시적으로 제외됐는지 확인한 뒤 baseline을 고정한다.
- 결정 필요: 없음
- 설계 참고: [SDD.md](../../../sdd/knowledge-tool-optimization-extension/inference-api-surface-execution-lifecycle-refactor/SDD.md)
- 없음
## 범위
@ -52,7 +39,7 @@ OpenAI Chat/Responses, Anthropic Messages, Gemini ingress의 서로 다른 외
리팩터링이 공통 API 스키마 설계가 아니라 외부 동작 보존과 내부 책임 분리임을 먼저 고정한다.
- [ ] [baseline-freeze] `iop-s0` `[bench-02]``[검토중]` 또는 `[완료]`로 진입한 시점의 호출 matrix와 revision을 기록하고 제품 code/spec/contract delta와 benchmark-only harness/data delta를 분리한다. 현재 `dev`에 반영할 제품 delta, 명시적 제외 근거, direct·single-request terminal과 provider-native option characterization을 baseline으로 고정한다. 검증: benchmark report/evidence 포인터, 양쪽 commit과 대상 workspace lock `true`를 확인한다.
- [ ] [baseline-freeze] 사용 가능한 `iop-s0` `[bench-02]` 호출 matrix와 revision을 비교 baseline으로 기록하고 제품 code/spec/contract delta와 benchmark-only harness/data delta를 분리한다. benchmark 결과가 없거나 진행 중이면 현재 코드의 characterization test를 baseline으로 사용한다. 검증: 사용한 baseline과 대상 revision을 기록한다.
- [ ] [boundary-map] OpenAI Chat/Responses, Anthropic Messages, Gemini ingress별 credential 추출·decode·validation·execution preparation·provider execution·wire projection·terminal 소유권과 허용 의존 방향을 확정한다. 공통 principal resolver, 기존 service와 endpoint runtime의 재사용 지점을 함께 표시한다.
### Epic: [execution-boundary] Surface와 실행 lifecycle 분리

View file

@ -28,18 +28,9 @@
- [ ] Claude Messages 이후 endpoint 확장과 IOP-owned workspace capability admission 범위를 확정한다.
- [ ] API/config/event/artifact lifecycle 구현 전 필수 SDD를 작성·승인한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재는 `heavy` mode의 책임과 `light`와의 경계를 정리한 후속 스케치다. 장기 state, artifact 갱신, retry/review와 resume 계약을 구현하기 전에 필수 SDD가 필요하다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 lifecycle·artifact·budget·resume 결정이 모두 해소되어 있다.
- [ ] single-request Hot Path에 추가할 부분과 공통 coordinator를 변경할 부분이 분리되어 있다.
- [ ] 구현 가능한 첫 heavy profile과 후속 확장 범위가 분리되어 있다.
- [ ] 필요한 SDD가 작성·승인되어 있다.
- 결정 필요: `승격 조건`과 동일
- 미정:
## 범위
@ -99,4 +90,4 @@
- 표준선(선택): artifact 구조는 필요가 확정된 시점에만 확장하며 route-02에 manifest/revision/empty directory를 선반영하지 않는다.
- 후속 작업: [Execution Preset 하이브리드 Mode 라우팅](openai-compatible-hybrid-request-execution-routing.md), [RAG 기반 Local Routing Model 운영 전환](rag-local-routing-model-operations.md)
- 큐 배치: `[route-02]` 바로 뒤인 `[route-03]` 3번이다.
- 확인 필요: `구현 잠금 > 결정 필요`
- 확인 필요: `결정 사항`

View file

@ -25,17 +25,9 @@ runtime-only 패턴 검출만으로는 최종 답변과 missing tool-call을 안
- [ ] request 전체 `max_judge_invocations_total`, 호출별 hard deadline, judge timeout, invalid JSON, provider 오류, judge와 deterministic observation 충돌 같은 불확실 케이스의 fallback 정책을 확정한다. judge invocation cap은 Core의 최초 실행 제외 기본값/절대 상한 3회 `max_recovery_attempts_total`과 별도로 request 시작 시 고정하고 어느 쪽이든 먼저 소진되면 추가 judge/recovery를 금지한다.
- [ ] OpenAI-compatible API/stream/retry 계약 변경으로 승격할 때 SDD 필요 여부와 후속 구현 Milestone 분리 방식을 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 Milestone은 정책 스케치이며, buffered stream/API/retry 계약 구현으로 승격할 때 SDD 필요 여부를 재판정한다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 종료/재시도 정책 질문이 해소되어 있다.
- [ ] judge/retry가 적용되는 요청 경계와 제외 경계가 문서화되어 있다.
- [ ] 구현 Milestone으로 넘길 기능 Task와 SDD gate 필요 여부가 정리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] LLM judge를 blocking gate로 둘지 advisory signal로만 둘지 결정한다.
- [ ] 현재 모델/provider 제약 안에서 judge 호출을 구성할지, 별도 judge route가 준비될 때까지 구현을 잠글지 결정한다.
- [ ] `indeterminate` 판정을 원응답 통과, 사용자-visible 오류, 내부 retry 중 어느 쪽으로 처리할지 결정한다.
@ -67,14 +59,14 @@ judge 결과를 공통 recovery budget과 운영 관측으로 연결하는 복
- [ ] [retry-loop] `missing_tool_call_judge`는 corrective prompt 의미를 typed directive로 가진 RecoveryIntent만 반환하고, 내부 재요청 횟수, request 전체 `max_judge_invocations_total`, recursive judge guard, tool side-effect 중복 방지, request rebuild/dispatch, 최종 실패는 [Stream Evidence Gate Core](stream-evidence-gate-core.md)의 strategy budget과 최초 실행 제외 기본값/절대 상한 3회 request 전체 recovery hard cap 안에서 공통 RecoveryPlan Coordinator가 처리하도록 정리되어 있다.
- [ ] [ops-signal] `missing_tool_call_judge` stable filter id, judge outcome, retry 여부, 최종 종료 원인과 sanitized evidence를 [Stream Evidence Gate Core](stream-evidence-gate-core.md)의 `FilterObservation` timeline으로 model/provider/run correlation에 연결할 관측 필드 후보가 정리되어 있다. judge input·원응답·tool args/result은 남기지 않는다.
- [ ] [promotion-plan] 정책 확정 후 `[계획]` 구현 Milestone과 SDD gate 필요 여부가 분리되어 있다.
- [ ] [promotion-plan] 구현 범위가 확정되면 후속 `[계획]` Milestone으로 분리한다. SDD는 복잡한 설계 결정이 실제로 필요할 때만 선택한다.
## 완료 리뷰
- 상태: 없음
- 요청일: 없음
- 완료 근거: 스케치 Milestone이며 종료/재시도 정책과 구현 경계가 아직 확정되지 않았다.
- 검토 항목: 사용자 리뷰 통과, 승격 조건 충족, 후속 구현 Milestone 및 SDD gate 분리 여부
- 검토 항목: 구현 범위와 후속 Milestone 분리 여부
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
@ -98,4 +90,4 @@ judge 결과를 공통 recovery budget과 운영 관측으로 연결하는 복
- 표준선(선택): 이 consumer는 stable filter id `missing_tool_call_judge`, judge 의미 판정과 typed intent, sanitized judge outcome만 소유하고 stable id와 judge outcome을 Core `FilterObservation`에 제공한다. recovery가 승인되면 Core `RecoveryPlan`과 strategy/request-total cap, bounded ingress snapshot을 사용하며 raw stream buffer, request snapshot/rebuild, retry loop, 공개 오류 사슬 직렬화를 재구현하지 않는다. judge/preparer/rebuild 실패는 sanitized `FailureCauseChain`으로 전달하고 endpoint host가 외부 오류 하나만 직렬화한다.
- 선행 작업: [Stream Evidence Gate Core](stream-evidence-gate-core.md), [OpenAI-compatible 출력 검증 필터](openai-compatible-output-validation-filters.md)
- 후속 작업: 정책 확정 후 별도 implementation Milestone, [Tool Call 판정 모델 Gate 리뷰](tool-call-validator-model-gate-review.md)
- 확인 필요: `구현 잠금 > 결정 필요` 항목
- 확인 필요: `결정 사항`

View file

@ -21,10 +21,9 @@
- [ ] MCP를 context 절약 경계로 사용할지, IOP native knowledge endpoint를 우선할지 결정한다.
- [ ] worker/background job 경계와 저장소 후보를 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] 장기 기억의 첫 저장 단위를 결정한다.
- [ ] RAG update cycle을 수동, watcher, scheduler 중 어디서 시작할지 결정한다.
- [ ] embedding/index 저장소와 권한 metadata 동기화 기준을 결정한다.
@ -54,7 +53,6 @@ MVP 이후 장기 기억/RAG 라인을 구체화하기 위한 최소 산출물
- 완료 근거: 스케치 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -37,19 +37,9 @@
- route evidence의 저장 위치, 보존 기간, 민감정보 제거, 학습 후보 승격 기준이 확정된다.
- API/config/event schema가 수반되는 구현 전 필수 SDD가 작성·승인된다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재는 복원된 cloud-first mode router와 후속 local selector의 경계를 정의하는 개념 스케치다. decision/evidence schema와 운영 policy 구현 전에 필수 SDD가 필요하다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 decision·failure·evidence 항목이 모두 해소되어 있다.
- [ ] route-02/03에서 재사용할 preset/mode/runtime 계약과 이 milestone의 일반화 범위가 분리되어 있다.
- [ ] 기존 fused preset을 재해석하지 않는 selection strategy와 mode entry migration/validation이 확정되어 있다.
- [ ] cloud-first 운영과 RAG local selector 후속 범위가 분리되어 있다.
- [ ] 필요한 SDD가 작성·승인되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] cloud selector model, 입력 feature, confidence 의미와 stage budget을 결정한다.
- [ ] preset별 mode 난이도·비용·지연 policy와 deterministic hard gate를 결정한다.
- [ ] route evidence 최소 표본·품질·보존 기간과 민감정보 제거 기준을 결정한다.
@ -132,4 +122,4 @@
- 선행: [`IOP 단일 요청 Agent 실행`](iop-owned-single-request-agent-execution.md), [`Heavy Plan/Review 실행과 검증 MVP`](knowledge-tool-validation-optimization.md)
- 후속: [`RAG 기반 Local Routing Model 운영 전환`](rag-local-routing-model-operations.md)
- 큐 배치: `[route-03]` 바로 뒤인 `[route-04]` 4번이다.
- 확인 필요: `구현 잠금 > 결정 필요`
- 확인 필요: `결정 사항`

View file

@ -19,17 +19,9 @@ OpenAI-compatible provider stream이 terminal 상태로 닫혔지만 완성된 t
- 없음
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 범위는 provider 원문/조립 결과를 비교하는 runtime classification과 관측 필드이며, public API/proto/config schema를 확정 변경하지 않는다. 감지 후 retry/error stream 정책을 확장할 경우 별도 SDD 필요 여부를 재판정한다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] matcher가 의존할 marker grammar와 provider별 적용 범위가 정리되어 있다.
- [ ] gate에 걸린 terminal 응답을 내부 retry로 처리할지 invalid-provider-output으로 처리할지 결정되어 있다.
- [ ] content marker가 이미 downstream으로 흘렀을 때의 처리와 first-byte 전 buffer 필요 여부가 정리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] 초기 marker set을 Gemma 계열 `<tool_call|>` 중심으로 시작할지, provider별 registry로 시작할지 결정한다.
- [ ] `incomplete_at_eof`, `marker_attempt_count > assembled_tool_call_count`, `complete_marker_count > assembled_tool_call_count` 각각의 action을 결정한다.
- [ ] matched response를 1회 internal retry로 돌릴지, tool-call syntax error로 즉시 닫을지 결정한다.
@ -70,7 +62,7 @@ syntax 판정 결과를 stream recovery, 운영 관측, fixture 검증에 연결
- 검토 항목:
- [ ] fixture test가 marker/count mismatch와 정상 종료를 구분한다.
- [ ] dev-corp Pi 실패 사례와 같은 `assembled_reasoning="<tool_call|>"`, `assembled_tool_call_count=0` 케이스가 gate에 걸린다.
- [ ] gate action 정책과 stream boundary가 잠금 해제 조건과 일치한다.
- [ ] gate action 정책과 stream boundary가 결정 사항과 일치한다.
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
@ -93,4 +85,4 @@ syntax 판정 결과를 stream recovery, 운영 관측, fixture 검증에 연결
- 상위 통합 후보: [OpenAI-compatible Runtime Output Integrity Filter](openai-compatible-runtime-output-integrity-filter.md)
- 선행 작업: [OpenAI-compatible Tool Call Boundary Hardening](../../../archive/phase/knowledge-tool-optimization-extension/milestones/openai-compatible-tool-call-boundary-hardening.md), [Stream Evidence Gate Core](stream-evidence-gate-core.md), [OpenAI-compatible 출력 검증 필터](openai-compatible-output-validation-filters.md)
- 후속 작업: [LLM 판별 기반 Missing Tool Call 재시도 Gate](llm-judged-missing-tool-call-retry-gate.md)
- 확인 필요: `구현 잠금 > 결정 필요` 항목
- 확인 필요: `결정 사항`

View file

@ -20,19 +20,10 @@ rolling evidence threshold를 통과한 tail은 검증 안전성을 낮추지
- 없음
## 구현 잠금
## 결정 사항
- 상태: 해제
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md)
- SDD 사유: OpenAI-compatible metadata schema, streaming retry/abort 상태 전이, provider 응답 검증 계약이 바뀌는 Milestone이다.
- 잠금 해제 조건:
- [x] SDD 잠금이 해제되어 있다
- [x] SDD 사용자 리뷰가 없거나 승인/해결되었다
- [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다
- [x] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다
- 결정 필요:
- [x] [D01] assistant history anchor의 preflight history sanitation, live reasoning dedupe, no-progress repair와 온도 단계 복구 정책
- 설계 참고: [SDD.md](../../../sdd/knowledge-tool-optimization-extension/openai-compatible-output-validation-filters/SDD.md)
- 미정:
- [x] [D02] `/v1/chat/completions``/v1/responses`를 공통 필터 코어와 endpoint별 codec으로 함께 구현하는 범위
- [x] [D03] assembled output/reasoning 원문 로그의 설정 기반 기록·중단 정책
- [x] [D04] 기존 Tool Call Runtime 검증 재시도와 공유하는 request-local exact-replay 최대 3회 및 commit 경계 정책
@ -102,10 +93,8 @@ filter가 승인한 rolling tail의 전달 속도를 provider 수집 cadence에
- 요청일: 없음
- 완료 근거: 기능 Task가 아직 충족되지 않았다.
- 검토 항목:
- [ ] `complete.log``Roadmap Completion`이 각 기능 Task id를 기록한다.
- [ ] 최종 검증 출력이 SDD Evidence Map과 일치한다.
- [ ] 모든 기능 Task 구현과 1차 검증이 끝난 뒤 비동기 collection/delivery 분리, filter 승인 경계, rune/event 순서, queue/backpressure, terminal/cancel/timer cleanup, Chat/Responses 양쪽 codec과 문서·계약 drift를 다시 검토한다.
- [ ] 재검토에서 발견된 actionable issue를 수정하고 영향 테스트와 관련 전체 검증을 다시 실행한 뒤, 추가 actionable issue가 없을 때까지 review-fix-retest를 반복한다. 최종 `complete.log`에는 review findings, 수정 내역, 재검증 evidence와 잔여 위험을 기록한다.
- [ ] 기능 Task가 구현되고 변경 위험에 직접 대응하는 최소 검증이 통과한다.
- [ ] 확인된 결함이 있으면 해당 결함과 영향 범위만 수정·재검증한다.
- [ ] generic raw HTTP/OpenAI SDK 기준 staged response-start, single-stream 반복 continuation, assistant history anchor, provider error/Tool Call validation의 최초 실행 제외 공통 최대 3회 exact budget, 모든 strategy를 합산한 request 전체 recovery cap, bounded ingress snapshot/schema terminal gate, same action과 provider/path switch가 확인된다. 반복 검증에는 multi-byte 한국어 장문, 200/500-rune rolling/look-behind, idle no-release, stream-open continuation과 dev `ornith:35b` 다회 smoke가 포함된다.
- [ ] approved tail pacing은 filter 승인 전 release 조건을 바꾸지 않고 window별 수집 시간과 전달 시간을 맞추며, 다음 window 수집과 비동기 전달의 중첩, bounded queue/backpressure, 정확한 rune/event 순서, 단일 terminal/cancel cleanup을 deterministic clock과 dev `ornith:35b` 비교 evidence로 확인한다.
- [ ] managed `length` continuation은 작은 provider attempt cap으로 중간 terminal을 숨기고 context-window 기반 trajectory를 같은 stream에 연결하며, fault recovery cap·tool boundary·최종 usage/terminal 관측을 보존한다.

View file

@ -25,17 +25,9 @@ OpenAI-compatible provider 응답에서 절대 정상 완료로 인정하면 안
- [ ] 기존 [Stream Evidence Gate Core](stream-evidence-gate-core.md), [OpenAI-compatible 출력 검증 필터](openai-compatible-output-validation-filters.md), [OpenAI-compatible Incomplete Tool Call Syntax Gate](openai-compatible-incomplete-tool-call-syntax-gate.md)를 어떻게 소비하는지와 detector policy 중복 제거 방식을 결정한다.
- [ ] OpenAI-compatible stream/retry/error 계약 변경으로 승격할 때 SDD 필요 여부와 후속 구현 Milestone 분리 방식을 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 Milestone은 runtime filter 통합 정책 스케치이며, public API/stream/retry/error 계약 구현으로 승격할 때 SDD 필요 여부를 재판정한다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 invariant, detector taxonomy, action policy가 해소되어 있다.
- [ ] detector별 retry 가능 여부와 fatal 처리 기준이 문서화되어 있다.
- [ ] 기존 output validation/filter Milestone과의 중복/통합 경계가 정리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] "재귀"를 허용하지 않고 bounded retry로만 표현할지 결정한다.
- [ ] `empty_terminal_response``reasoning_only_terminal`을 기본 retryable로 볼지 fatal로 볼지 결정한다.
- [ ] `incomplete_tool_call_syntax`를 retryable로 볼지 invalid-provider-output으로 볼지 결정한다.
@ -75,7 +67,7 @@ detector 판정을 bounded recovery 정책과 stream 통합·운영 관측으로
- 상태: 없음
- 요청일: 없음
- 완료 근거: 스케치 Milestone이며 invariant와 action policy가 아직 확정되지 않았다.
- 검토 항목: 사용자 리뷰 통과, 승격 조건 충족, 후속 구현 Milestone 및 SDD gate 분리 여부
- 검토 항목: 구현 범위와 후속 Milestone 분리 여부
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
@ -97,4 +89,4 @@ detector 판정을 bounded recovery 정책과 stream 통합·운영 관측으로
- 표준선(선택): 이 consumer는 `runtime_output_integrity` consumer id와 detector 이름 기반 stable filter/rule id, invariant 의미 판정과 typed intent, sanitized assembled count만 소유하고 consumer/filter/rule id와 count를 Core `FilterObservation`에 제공한다. recovery가 승인되면 Core `RecoveryPlan`과 strategy/request-total cap, bounded ingress snapshot을 사용하며 raw stream buffer, request snapshot/rebuild, retry loop, 공개 오류 사슬 직렬화를 재구현하지 않는다. detector/rebuild 실패는 sanitized `FailureCauseChain`으로 전달하고 endpoint host가 외부 오류 하나만 직렬화한다.
- 선행 작업: [Stream Evidence Gate Core](stream-evidence-gate-core.md), [OpenAI-compatible 출력 검증 필터](openai-compatible-output-validation-filters.md), [OpenAI-compatible Incomplete Tool Call Syntax Gate](openai-compatible-incomplete-tool-call-syntax-gate.md)
- 후속 작업: detector별 implementation Milestone 또는 기존 output validation filter Milestone 통합
- 확인 필요: `구현 잠금 > 결정 필요` 항목
- 확인 필요: `결정 사항`

View file

@ -33,18 +33,9 @@
- canary 대상, 비율, 자동 rollback, cloud fallback budget이 확정된다.
- API/config/event schema 및 model lifecycle을 다루는 필수 SDD가 작성·승인된다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재는 최종 운영 목표와 선행 gate를 정의하는 개념 스케치다. 구현 마일스톤 승격 시 corpus/index, model lifecycle, shadow/canary/rollback 계약을 다루는 SDD가 필요하다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 evidence·corpus·평가·rollout 기준이 모두 확정되어 있다.
- [ ] routing RAG와 repository 장기 기억 RAG의 corpus/index/retention 경계가 검증되어 있다.
- [ ] shadow MVP, canary, primary 승격 범위가 분리되어 있다.
- [ ] 필요한 SDD가 작성·승인되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] production 학습 corpus로 승격할 최소 표본·coverage·품질·보존 기간을 결정한다.
- [ ] local routing model, embedding model, index backend와 갱신 주기를 결정한다.
- [ ] 허용 disagreement/regret/latency 임계값, cloud audit 비율과 fallback budget을 결정한다.
@ -115,4 +106,4 @@
- 선행: [`Execution Preset 하이브리드 Mode 라우팅`](openai-compatible-hybrid-request-execution-routing.md), [`요청 실행 로그와 Usage Ledger 기반`](../../operational-observability-provider-management/milestones/request-execution-log-usage-ledger-foundation.md), [`Provider-Device-Model Qualification 리포트와 Lifecycle 관리`](../../operational-observability-provider-management/milestones/provider-device-model-qualification-report.md)
- 구분 대상: [`Long-term Memory RAG 2nd Wave`](long-term-memory-rag-second-wave.md)
- 큐 배치: route lane의 `[route-05]` 5번이며 [`Execution Preset 하이브리드 Mode 라우팅`](openai-compatible-hybrid-request-execution-routing.md) 뒤에 실행한다. 별도 선행 gate는 [`Provider-Device-Model Qualification 리포트와 Lifecycle 관리`](../../operational-observability-provider-management/milestones/provider-device-model-qualification-report.md)다.
- 확인 필요: `구현 잠금 > 결정 필요`
- 확인 필요: `결정 사항`

View file

@ -33,16 +33,9 @@ Agent, Open WebUI 같은 OpenAI-compatible chat client와 일반 API caller의
- [ ] 요청-답변 단위 절단과 단위 내부 내용 절단을 각각 독립적으로 구현·검증할 후속 Milestone으로 분리한다.
- [ ] 후속 구현 Milestone별 provider 입력 API/request schema/runtime 호출 계약과 SDD를 작성할 수 있을 만큼 acceptance/evidence 경계를 정리한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 Milestone은 caller-neutral provider 입력 컨텍스트 최적화의 제품·책임 경계를 정리하는 스케치다. API/request schema와 runtime 호출 계약을 다루는 후속 구현 Milestone은 각각 SDD 대상으로 둔다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 미정 항목이 사용자 검토로 해소되어 있다.
- [ ] 구현 가능한 MVP 범위와 후속 Milestone이 분리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] 최초 MVP가 직접 처리할 provider 입력 request surface와 source 조합을 결정한다.
- [ ] 요청-답변 단위 및 단위 내부 segment의 관련성을 rule, embedding/rerank, 별도 모델 판정 또는 hybrid 중 어떤 방식으로 판정할지 결정한다.
- [ ] 최초 배포를 observe-only/shadow, 명시 opt-in, 정책 기반 기본 적용 중 어떤 방식으로 시작할지 결정한다.
@ -138,4 +131,4 @@ provider 입력 최적화의 source, budget, selector, request invariant와 fide
- 큐 배치: [Provider-Device-Model Qualification 리포트와 Lifecycle 관리](../../operational-observability-provider-management/milestones/provider-device-model-qualification-report.md) 뒤, [장기 기억과 RAG 업데이트 사이클 (2차)](long-term-memory-rag-second-wave.md) 앞
- 선행 작업: 기본 OpenAI-compatible 입력/relay 안정화, [요청 실행 로그와 Usage Ledger 기반](../../operational-observability-provider-management/milestones/request-execution-log-usage-ledger-foundation.md)
- 후속 작업: 요청-답변 단위 절단 구현 Milestone, 단위 내부 내용 절단 구현 Milestone, 두 단계 결합 replay 평가, RAG와 Context Hook 연동
- 확인 필요: `구현 잠금 > 결정 필요` 항목
- 확인 필요: `결정 사항`

View file

@ -19,14 +19,9 @@
- [ ] 기존 필터 동작과 경량 통과 모드를 구분하는 설정 형태와 기본값을 확정한다.
- [ ] 설정 변경이 포함되므로 `[계획]` 승격 시 SDD 필요 여부를 다시 판정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재는 모드 의미와 경계를 정하는 스케치이며, 설정·상태 전이 구현 범위가 확정되지 않았다. `[계획]` 승격 시 SDD 필요 여부를 다시 판정한다.
- 잠금 해제 조건: 승격 조건 충족
- 결정 필요: 아래 목록
- 미정:
- 경량 통과에서 남길 최소 동기 관측 항목
- 설정 이름과 기본값
@ -70,4 +65,4 @@
- 표준선: 경량 통과는 공통 StreamGate 수명주기를 유지하고 최소한의 동기 추적 외에는 응답을 보류하거나 자동 복구하지 않는다.
- 실행 순서와 차단 관계: [전역 마일스톤 실행 순서](../../../priority-queue.md)
- 관련 Milestone: [OpenAI-compatible 출력 검증 필터](openai-compatible-output-validation-filters.md), [Inference API Surface와 실행 Lifecycle 책임 경계 리팩터링](inference-api-surface-execution-lifecycle-refactor.md)
- 확인 필요: 승격 조건과 `구현 잠금 > 결정 필요` 항목
- 확인 필요: 승격 조건과 `결정 사항`

View file

@ -23,16 +23,9 @@
- [ ] validator 모델 사용 비용, latency, default enable 여부, 호출 표면을 결정한다.
- [ ] 사용자 리뷰를 통해 MVP 포함 여부와 후속 구현 Milestone 분리 방식을 확정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 Milestone은 모델 판정 gate의 제품/정책 스케치이며, API/config/schema 구현으로 승격할 때 SDD 필요 여부를 재판정한다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 아래 결정 필요 항목이 사용자 리뷰로 해소되어 있다.
- [ ] runtime-only Milestone과 겹치지 않는 구현 범위가 정리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] 명시적 `tools[]`가 없는 요청에서 validator 모델을 호출할지 결정한다.
- [ ] 모델이 tool call 필요성, tool call 후보 여부, schema 위반 여부 중 무엇을 판정할지 결정한다.
- [ ] validator 모델 판정을 실패 처리의 source of truth로 삼을지 advisory signal로만 둘지 결정한다.
@ -64,7 +57,7 @@ runtime-only validation으로 해결되지 않는 애매한 tool-call 후보를
- 상태: 없음
- 요청일: 없음
- 완료 근거: 스케치 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 검토 항목: 사용자 리뷰 통과, 잠금 해제 여부, 후속 구현 Milestone 분리 여부
- 검토 항목: 구현 범위와 후속 Milestone 분리 여부
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
@ -83,4 +76,4 @@ runtime-only validation으로 해결되지 않는 애매한 tool-call 후보를
- 표준선(선택): 모델 판정은 오판 가능성이 있으므로 사용자 승인 전에는 blocking source of truth로 삼지 않는다.
- 선행 작업: Tool Call Runtime 검증 재시도 MVP
- 후속 작업: 단계 호출과 검증 최적화 MVP 또는 별도 model-assisted validation 구현 Milestone
- 확인 필요: `구현 잠금 > 결정 필요` 항목
- 확인 필요: `결정 사항`

View file

@ -24,17 +24,9 @@ provider별 모델 lifecycle capability 차이를 IOP가 어떻게 흡수하고,
- [ ] Control Plane, Edge-local CLI, Client 중 report 조회와 lifecycle 제어 표면을 어디에 둘지 결정한다.
- [ ] 현재 provider 확장 Phase의 vLLM/SGLang serving path 검증 결과를 seed evidence로 어떻게 연결할지 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 경로: 없음 (작성 전)
- SDD 사유: provider lifecycle 제어, report schema, 저장 책임, 운영 UI/API 경계가 함께 걸리는 제품 설계 Milestone이다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] SDD 잠금이 해제되어 있다.
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다.
- [ ] provider lifecycle 추상화와 report MVP 범위가 구현 계획을 만들 수 있을 만큼 확정되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] IOP가 provider별 모델 설치/삭제/load/unload 또는 container/process start/stop을 어느 수준까지 직접 제어할지 결정한다.
- [ ] qualification report를 route recommendation에 바로 사용할지, 초기에는 관찰/리포트로만 둘지 결정한다.
- [ ] 성능/품질 테스트가 자동 실행이어야 하는지, 사용자 승인 기반 수동 실행으로 시작할지 결정한다.
@ -85,7 +77,6 @@ provider lifecycle 차이와 qualification report의 운영 표면 및 routing
- 완료 근거: 스케치 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -18,15 +18,9 @@ Edge가 이미 소유한 provider capacity, in-flight, queued 상태와 queue ad
- 없음
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 기존 Edge `/metrics` scrape 경로와 provider snapshot/queue state를 재사용하는 additive 관측 Milestone이며, proto/API/storage 계약이나 raw payload 보관 정책을 바꾸지 않는다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 사용자가 이 Milestone의 metric/dashboard 범위와 low-cardinality label 표준선을 검토했다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] 구현 시작 전 `provider_id`, `model_group`, `queue_reason`, `context_class` 등 Grafana 분석에 필요한 label 세트가 충분한지 최종 확인한다.
## 범위
@ -54,7 +48,7 @@ provider capacity 사용률과 queue 적체를 운영자가 시간대별로 분
- 상태: 없음
- 요청일: 없음
- 완료 근거: 계획 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 검토 항목: 기능 Task와 검증이 충족되고 구현 잠금이 해제되었는지 확인한다.
- 검토 항목: 기능 Task와 변경 위험에 직접 대응하는 최소 검증이 충족되었는지 확인한다.
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
@ -74,4 +68,4 @@ provider capacity 사용률과 queue 적체를 운영자가 시간대별로 분
- 표준선(선택): request-level 원장, redaction, storage/export는 [요청 실행 로그와 Usage Ledger 기반](request-execution-log-usage-ledger-foundation.md)에서 별도로 다룬다.
- 선행 작업: 사용자별 OpenAI-compatible 토큰 측정 MVP, Model Group Long-Context Admission
- 후속 작업: [요청 실행 로그와 Usage Ledger 기반](request-execution-log-usage-ledger-foundation.md), [Provider-Device-Model Qualification 리포트와 Lifecycle 관리](provider-device-model-qualification-report.md)
- 확인 필요: `구현 잠금 > 결정 필요`의 label 세트 최종 확인
- 확인 필요: `결정 사항`의 label 세트 최종 확인

View file

@ -23,17 +23,9 @@ model group의 context/capacity 계약을 실제 provider launch option, 모델
- [ ] runtime 설정 검증을 `config check`, dry-run, health, `/v1/models`, context/capacity smoke 중 어디까지 요구할지 결정한다.
- [ ] long-context admission의 `context_window_tokens`, `total_context_tokens`, `long_context_capacity`와 provider runtime option을 어떻게 일관 검증할지 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 문서: 없음 (작성 전)
- SDD 사유: provider runtime launch/restart, 모델 다운로드, artifact cache, rollback, 외부 provider 쓰기와 host 자원 변경을 포함하는 장기 설계 Milestone이다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] SDD 잠금이 해제되어 있다.
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다.
- [ ] provider runtime 설정 책임과 모델 다운로드/적용 승인 경계가 구현 계획을 만들 수 있을 만큼 확정되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] IOP가 vLLM/vLLM-MLX process/container 기동 옵션을 직접 쓰고 재시작할 권한을 가질지 결정한다.
- [ ] Lemonade처럼 별도 앱/API가 설정을 소유하는 provider를 IOP가 어디까지 제어할지 결정한다.
- [ ] 모델 선정과 다운로드를 자동 추천/자동 실행/사용자 승인 실행 중 어떤 수준으로 시작할지 결정한다.
@ -81,7 +73,6 @@ runtime 설정과 모델 변경의 적용, rollback, 운영 상태 및 안전
- 리뷰 필요:
- [ ] 사용자가 provider runtime 설정 소유 범위를 검토했다.
- [ ] 사용자가 모델 선정/다운로드 자동화 수준을 검토했다.
- [ ] archive 이동을 승인했다.
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음

View file

@ -17,18 +17,10 @@ provider가 일정 시간 HTTP body 또는 normalized progress를 내지 않는
- 없음
## 구현 잠금
## 결정 사항
- 상태: 해제
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/operational-observability-provider-management/provider-stall-watchdog-removal/SDD.md)
- SDD 사유: Node/Edge lifecycle, API·proto·config 계약, provider health와 retry 의미를 함께 축소한다.
- 잠금 해제 조건:
- [x] SDD 잠금이 해제되어 있다.
- [x] SDD 사용자 리뷰가 없거나 승인/해결되었다.
- [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
- [x] Evidence Map이 완료 시 `complete.log``milestone-task` id별 집계와 최종 검증 evidence로 검증 가능하게 연결되어 있다.
- 결정 필요: 없음
- 설계 참고: [SDD.md](../../../sdd/operational-observability-provider-management/provider-stall-watchdog-removal/SDD.md)
- 없음
## 범위

View file

@ -25,18 +25,10 @@ provider/tool-call bridge에서 native tool call, text fallback, synthesized too
- [ ] prompt/response/reasoning preview redaction, raw payload 보관 여부, export 권한 경계를 결정한다.
- [ ] 기존 zap 로그, runtime event, audit/observability package, Control Plane operation history를 어떻게 migration 또는 병행 운용할지 결정한다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/operational-observability-provider-management/request-execution-log-usage-ledger-foundation/SDD.md)
- SDD 사유: 요청 실행 로그와 usage ledger는 proto/event/schema/storage/API, 데이터 보존, 권한, 실패 처리 경계를 함께 바꾸는 설계 Milestone이다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] SDD 잠금이 해제되어 있다.
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다.
- [ ] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다.
- [ ] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다.
- 결정 필요: 아래 체크리스트
- 설계 참고: [SDD.md](../../../sdd/operational-observability-provider-management/request-execution-log-usage-ledger-foundation/SDD.md)
- 미정:
- [ ] request ledger의 canonical 저장 책임을 Edge와 Control Plane 중 어디에 둘지 결정한다.
- [ ] token usage source가 provider-reported, estimated, mixed, unavailable일 때 운영 UI와 export에서 어떻게 표시할지 결정한다.
- [ ] hidden think/reasoning token을 provider가 보고하지 않는 경우 표시 reasoning text 기반 추정을 허용할지 결정한다.
@ -86,7 +78,6 @@ request ledger의 저장·조회 책임과 기존 로그 체계에서의 도입
- 완료 근거: 스케치 Milestone이며 기능 Task가 아직 충족되지 않았다.
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외
@ -106,7 +97,7 @@ request ledger의 저장·조회 책임과 기존 로그 체계에서의 도입
- 표준선(선택): usage는 provider-reported 값을 우선하고, provider가 주지 않는 값은 estimated 또는 unavailable로 명시해 정확도와 추정을 분리한다.
- 표준선(선택): tool-call 추적은 기본적으로 raw 원문 저장보다 `run_id` 기준 판정 필드, 길이, hash, 짧은 redacted preview를 우선하고, bounded raw capture는 명시적으로 켠 진단 모드로 제한한다.
- 우선순위: [OpenAI-compatible 출력 검증 필터](../../knowledge-tool-optimization-extension/milestones/openai-compatible-output-validation-filters.md)와 [Seulgivibe OpenAI-compatible Provider 연동](../../../archive/phase/routing-policy-model-orchestration/milestones/seulgivibe-openai-compatible-provider.md) 이후 재개한다.
- SDD gate: [SDD.md](../../../sdd/operational-observability-provider-management/request-execution-log-usage-ledger-foundation/SDD.md), 사용자 리뷰 [USER_REVIEW.md](../../../sdd/operational-observability-provider-management/request-execution-log-usage-ledger-foundation/USER_REVIEW.md)
- 설계 참고: [SDD.md](../../../sdd/operational-observability-provider-management/request-execution-log-usage-ledger-foundation/SDD.md), 결정 기록 [DECISIONS.md](../../../sdd/operational-observability-provider-management/request-execution-log-usage-ledger-foundation/DECISIONS.md). 두 문서는 구현 선행 게이트가 아니다.
- 선행 작업: 사용량, 토큰, 로그 운영 추적 MVP
- 후속 작업: Provider-Device-Model Qualification 리포트, 운영 리포트, 품질 기반 routing/fallback 고도화
- 확인 필요: ledger canonical owner, usage source 표시 정책, tool-call/raw chunk redaction과 capture 수준, redaction/retention 기본값, schema 분리 여부

View file

@ -26,16 +26,9 @@
- [ ] server/team mode로 확장할 때 기존 personal Edge 상태를 어떻게 이전하거나 enrollment할지 결정한다.
- [ ] 후속 구현 Milestone과 SDD 필요 범위를 나눈다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 현재 Milestone은 personal/server 배포 토폴로지와 패키징 방향성 스케치이며, installer/config/update/security 계약 구현으로 승격할 때 SDD 필요 여부를 재판정한다.
- 잠금 해제 조건: 아래 체크리스트
- [ ] 승격 조건의 미정 항목이 사용자 검토로 해소되어 있다.
- [ ] 구현 가능한 목표, 범위, 기능 Task, 후속 구현 Milestone 후보가 분리되어 있다.
- 결정 필요: 아래 체크리스트
- 미정:
- [ ] 초기 제품 표면을 `iop-edge` 단일 바이너리로 유지할지, 별도 host/tray/app wrapper를 둘지 결정한다.
- [ ] personal/local 모드의 기본 backend를 embedded, local child Node, remote Node disabled 중 어떤 조합으로 시작할지 결정한다.
- [ ] personal/local 모드에서 multi-user 관리, 조직 RBAC, fleet audit를 완전히 끌지, minimal local identity/audit만 남길지 결정한다.
@ -87,7 +80,6 @@ server/team mode와 personal Edge의 enrollment 및 후속 구현 경계를 묶
- 검토 항목:
- [ ] 사용자가 동일 코어, 배포 모드, personal local UX 방향을 검토했다.
- [ ] 승격 조건과 결정 필요 항목이 후속 구현 Milestone으로 분리되었다.
- [ ] archive 이동을 승인했다.
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 없음
@ -109,4 +101,4 @@ server/team mode와 personal Edge의 enrollment 및 후속 구현 경계를 묶
- 표준선(선택): local mode에서도 보안을 제거하지 않고 localhost bind, local API token, credential storage, 최소 usage ledger 기준을 둔다.
- 선행 작업: [Update Plane 안정 프로토콜](../../update-plane-self-update-foundation/milestones/update-plane-stable-protocol.md), [Host-local Manager 기반 자체 업데이트](../../update-plane-self-update-foundation/milestones/host-local-manager-self-update.md)
- 후속 작업: personal Edge installer 구현, deployment mode config schema, local provider setup wizard, Control Plane optional enrollment
- 확인 필요: `구현 잠금 > 결정 필요` 항목
- 확인 필요: `결정 사항`

View file

@ -22,17 +22,9 @@ Node 연결 단절, Edge 재시작, protocol mismatch, artifact 검증 실패
- [ ] rollback과 manual intervention 상태를 Control Plane에 보고하는 기준을 정한다.
- [ ] 후속 구현 Milestone과 SDD 필요 범위를 나눈다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 문서: 없음 (작성 전)
- SDD 사유: Edge/Node update lifecycle, drain/restart/rollback 정책, 상태 캐시와 Control Plane 보고 계약이 필요하다.
- 잠금 해제 조건:
- [ ] SDD 잠금이 해제되어 있다
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다
- 결정 필요:
- [ ] 자동 롤아웃의 기본 허용 범위와 수동 승인 gate가 필요한 환경 기준을 정한다.
- 미정:
## 범위
@ -61,7 +53,6 @@ Edge가 Node와 자기 자신의 업데이트를 조율하고 Control Plane에
- 완료 근거: 스케치 상태이므로 완료 근거 없음
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -22,17 +22,9 @@ Linux, macOS, Windows에서 공통으로 유지할 release directory와 current
- [ ] manager가 담당하지 않을 IOP Node/Edge runtime 책임을 명확히 한다.
- [ ] 후속 구현 Milestone과 SDD 필요 범위를 나눈다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 문서: 없음 (작성 전)
- SDD 사유: cross-OS 프로세스 lifecycle, 파일 전환, rollback 상태 머신, service manager 연동에 영향을 준다.
- 잠금 해제 조건:
- [ ] SDD 잠금이 해제되어 있다
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다
- 결정 필요:
- [ ] 초기 MVP를 one-shot updater helper로 시작할지, 항상 실행되는 manager로 시작할지 결정한다.
- 미정:
## 범위
@ -61,7 +53,6 @@ Edge/Node 앱과 별개로 프로세스 바꿔치기 구간만 담당하는 작
- 완료 근거: 스케치 상태이므로 완료 근거 없음
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -22,17 +22,9 @@ hello/status, release manifest, update command, update event, recovery 판단에
- [ ] 너무 오래된 updater protocol을 만났을 때의 manual/bootstrap fallback 기준을 정리한다.
- [ ] 후속 구현 Milestone과 SDD 필요 범위를 나눈다.
## 구현 잠금
## 결정 사항
- 상태: 잠금
- SDD: 필요
- SDD 문서: 없음 (작성 전)
- SDD 사유: 업데이트 프로토콜, manifest schema, 상태 전이, recovery 규칙이 proto/config/schema와 lifecycle 계약에 직접 닿는다.
- 잠금 해제 조건:
- [ ] SDD 잠금이 해제되어 있다
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다
- 결정 필요:
- [ ] 기본 release channel과 자동 적용/승인 적용의 제품 정책을 정한다.
- 미정:
## 범위
@ -62,7 +54,6 @@ hello/status, release manifest, update command, update event, recovery 판단에
- 완료 근거: 스케치 상태이므로 완료 근거 없음
- 리뷰 필요:
- [ ] 사용자가 완료 결과를 확인했다
- [ ] archive 이동을 승인했다
- 리뷰 코멘트: 없음
## 범위 제외

View file

@ -19,7 +19,7 @@
### surface
1. [[surface-01] Inference API Surface와 실행 Lifecycle 책임 경계 리팩터링](phase/knowledge-tool-optimization-extension/milestones/inference-api-surface-execution-lifecycle-refactor.md)
OpenAI, Anthropic, Gemini wire 계약은 분리하고 기존 provider service 경계를 재사용하면서 cross-surface handler 재진입과 단계별 lifecycle 소유권을 정리한다. 구현 시작 조건은 workspace lock과 Milestone의 제품-delta 정합성 gate에서 관리한다.
OpenAI, Anthropic, Gemini wire 계약은 분리하고 기존 provider service 경계를 재사용하면서 cross-surface handler 재진입과 단계별 lifecycle 소유권을 정리한다. 사용 가능한 benchmark는 비교 자료로만 쓰며 workspace lock이나 별도 정합성 gate를 구현 시작 조건으로 두지 않는다.
### gate

View file

@ -7,18 +7,16 @@
## 상태
[승인됨]
[확정]
## SDD 잠금
## 결정 사항
- 상태: 해제
- 사용자 리뷰: 없음
- 잠금 항목:
- 결정 기록:
- [x] [D01] OpenAI, Anthropic, Gemini wire contract는 공통 DTO로 합치지 않고 각 surface adapter에 남긴다.
- [x] [D02] provider admission·dispatch·attempt·cancel은 기존 `runService`/`SubmitProviderPool` 경계를 재사용하고, protocol별 실행 준비와 endpoint commit·terminal은 각 기존 runtime이 소유한다. 하나의 universal lifecycle owner나 terminal DTO를 만들지 않는다.
- [x] [D03] 리팩터링은 caller-visible behavior, provider selection, native option passthrough와 benchmark 조건을 바꾸지 않는다.
- [x] [D04] `iop-s0` `[bench-02]`가 검토중 또는 완료 상태로 진입하고 workspace lock이 해제된 뒤 구현 plan을 시작한다.
- [x] [D05] 구현 plan 시작 시 benchmark 이후 drift를 제품 code/spec/contract와 benchmark-only harness/data로 분류한다. 제품 delta는 현재 `dev` 반영 여부 또는 제외 근거를 고정하고, benchmark-only delta는 제품 baseline에 섞지 않는다.
- [x] [D04] `iop-s0` `[bench-02]` 결과가 있으면 리팩터링의 비교 baseline으로 사용하되, 결과 상태나 workspace lock을 구현 선행 조건으로 사용하지 않는다.
- [x] [D05] benchmark 비교가 현재 작업 범위에 포함되면 제품 code/spec/contract와 benchmark-only harness/data의 차이를 분리한다.
- [x] [D06] 완료 evidence는 deterministic characterization과 기존 benchmark artifact 비교를 기본으로 한다. 외부 provider live smoke나 benchmark 재실행은 별도 환경·비용 승인이 있을 때만 추가한다.
## 문제 / 비목표
@ -35,7 +33,7 @@
| 영역 | 기준 | 메모 |
|------|------|------|
| Roadmap | [Milestone 문서](../../../phase/knowledge-tool-optimization-extension/milestones/inference-api-surface-execution-lifecycle-refactor.md) | 범위, Task와 구현 잠금 원장 |
| Roadmap | [Milestone 문서](../../../phase/knowledge-tool-optimization-extension/milestones/inference-api-surface-execution-lifecycle-refactor.md) | 범위와 Task 원장 |
| API Contracts | [OpenAI-Compatible API](../../../../agent-contract/outer/openai-compatible-api.md), [Anthropic-Compatible Messages API](../../../../agent-contract/outer/anthropic-compatible-api.md), [Gemini-Compatible API](../../../../agent-contract/outer/gemini-compatible-api.md) | caller-visible 동작 baseline |
| Current Spec | [OpenAI-Compatible 입력 표면](../../../../agent-spec/input/openai-compatible-surface.md), [Stream Evidence Gate](../../../../agent-spec/runtime/stream-evidence-gate.md) | 현재 구현 책임과 lifecycle 설명 |
| Surface/Ingress Code | `apps/edge/internal/openai/` | surface codec, validation, projector, Stream Evidence Gate와 operation-specific ingress orchestration 구현 |
@ -90,7 +88,7 @@ State invariant:
| ID | Milestone Task | Given | When | Then |
|----|----------------|-------|------|------|
| S01 | `baseline-freeze` | `iop-s0` benchmark가 검토중 또는 완료이고 final report/evidence가 고정됨 | 구현 plan 전 consistency check를 수행 | target/current revision, 제품 delta 반영·제외 근거, benchmark-only delta 분리, 대표 terminal/native-option baseline과 workspace lock `true`가 연결된다. |
| S01 | `baseline-freeze` | 현재 동작을 비교할 기준이 필요함 | 기존 characterization 또는 사용 가능한 benchmark 결과를 선택 | target/current revision과 제품 delta, benchmark-only delta가 구분된다. benchmark 상태와 workspace lock은 선행 조건이 아니다. |
| S02 | `boundary-map` | 세 외부 API와 raw/normalized/single-request 경로가 존재 | 책임/의존 지도를 검토 | surface, shared auth resolver, 기존 service, endpoint runtime의 단계별 소유권이 겹치지 않고 API/terminal DTO 공통화가 비범위로 표시된다. |
| S03 | `execution-entrypoint` | Gemini direct와 virtual preset 요청 | Gemini ingress를 실행 | Chat handler 내부 HTTP 재진입이나 중복 service port 없이 기존 provider/preset execution capability를 호출하고 Gemini contract 결과를 반환한다. |
| S04 | `surface-adapters` | 각 surface의 정상·validation·auth·provider 오류 입력 | endpoint별 adapter/projector를 실행 | 외부 status, error envelope, model echo와 SSE event 순서가 baseline과 동일하다. |
@ -99,32 +97,10 @@ State invariant:
| S07 | `contract-regression` | OpenAI Chat/Responses, Anthropic Messages, Gemini direct/single-request characterization matrix와 기존 benchmark artifact | deterministic package test와 artifact 비교를 실행 | caller-visible behavior와 benchmark admission 조건에 의도하지 않은 차이가 없고 별도 승인 없는 live provider 호출은 발생하지 않는다. |
| S08 | `spec-sync` | 리팩터링 구현과 회귀 검증 완료 | contract source pointer와 implementation spec을 점검 | 외부 계약 의미는 유지되고 source path·책임 경계·현재 스펙이 실제 코드와 일치하며 기존 계약과 다른 제품 동작은 별도 후보로 분리된다. |
## Evidence Map
## Cross-repo Reference
| Scenario | Required Evidence | `agent-task` 연결 | 완료 Evidence 기대 |
|----------|-------------------|------------------|---------------------------|
| S01 | benchmark target/current revision, 제품/benchmark-only delta 분류, lock checker `true`, baseline matrix와 digest | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/baseline-freeze/` | `baseline-freeze` task id별 dependency/drift/baseline evidence |
| S02 | surface/common responsibility map와 forbidden dependency check | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/boundary-map/` | `boundary-map` task id별 architecture evidence |
| S03 | Gemini production call graph/search, 기존 service 호출과 direct/preset regression | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/execution-entrypoint/` | `execution-entrypoint` task id별 no-handler-reentry/no-duplicate-port evidence |
| S04 | endpoint codec/projector ownership tests와 dependency review | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/surface-adapters/` | `surface-adapters` task id별 wire-contract evidence |
| S05 | terminal/cancel/usage concurrency matrix | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/lifecycle-owner/` | `lifecycle-owner` task id별 exactly-once evidence |
| S06 | raw/translated request capture와 native field preservation tests | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/native-option-preservation/` | `native-option-preservation` task id별 lossless evidence |
| S07 | deterministic Edge package test 결과와 기존 benchmark artifact comparison | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/contract-regression/` | `contract-regression` task id별 baseline comparison 및 no-unapproved-live-call evidence |
| S08 | agent-spec/contract drift check와 문서 diff | `agent-task/m-inference-api-surface-execution-lifecycle-refactor/spec-sync/` | `spec-sync` task id별 final source-pointer/spec evidence |
## Cross-repo Dependencies
- 대상: [iop-s0 `[bench-02]` IOP 원샷 Agent 모델 비교 벤치마크](../../../../../iop-s0/agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/iop-one-shot-agent-model-comparison.md)
- `.agent-roadmap-sync/locks.yaml` entry: `iop:inference-api-surface-execution-lifecycle-refactor`
- workspace lock 해제 기준: 대상 Milestone이 `[검토중]` 또는 `[완료]`로 전환되어 benchmark matrix/report와 baseline evidence가 더 이상 실행 중 변경되지 않고, lock status가 `enable`로 동기화된다.
- 로컬 구현 잠금 추가 기준: 대상/current revision 사이의 변경을 제품 delta와 benchmark-only delta로 분류하고, 제품 delta가 현재 `dev`에 반영됐거나 명시적으로 제외됐다는 근거를 `baseline-freeze`에 남긴다.
## Drift Check
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
- [x] Evidence Map이 code-review/complete.log에서 검증 가능하다.
- [x] agent-contract를 쓰며 SDD에 계약 원문을 복제하지 않았다.
- [x] 사용자 리뷰가 필요한 항목은 없고 D01-D06으로 경계를 확정했다.
- 참고: [iop-s0 `[bench-02]` IOP 원샷 Agent 모델 비교 벤치마크](../../../../../iop-s0/agent-roadmap/phase/knowledge-tool-optimization-extension/milestones/iop-one-shot-agent-model-comparison.md)
- 사용 가능한 결과가 있으면 비교 자료로 사용한다. 해당 Milestone의 상태나 workspace lock은 이 구현의 선행 조건이 아니다.
## 사용자 리뷰 이력

View file

@ -7,13 +7,11 @@
## 상태
[승인됨]
[확정]
## SDD 잠금
## 결정 사항
- 상태: 해제
- 사용자 리뷰: [user_review_0.log](user_review_0.log) (해결됨)
- 잠금 항목:
- 결정 기록:
- [x] [D01] assistant history anchor의 preflight history sanitation, live reasoning dedupe, no-progress repair와 온도 단계 복구 정책
- [x] [D02] `/v1/chat/completions``/v1/responses`를 공통 필터 코어와 endpoint별 codec으로 함께 구현하는 범위
- [x] [D03] assembled output/reasoning 원문 로그의 설정 기반 기록·중단 정책
@ -185,49 +183,13 @@
| S23 | `observable-core-smoke` | local/dev diagnostic smoke가 deterministic Chat/Responses provider stream과 `pass`, `observe_only` violation, pre-release `blocking` violation을 반환하는 diagnostic `Filter` mock을 사용한다 | 한 명령으로 실제 codec, Core, all-complete Arbiter, Recovery Coordinator, ReleaseSink와 observation sink를 통과시킨다 | 모든 batch가 평가 전에 stage된다. pass와 observe-only는 stage/evaluate/arbitrate/release/single-terminal로 수렴하고 observe-only violation은 출력 차단 없이 관측된다. blocking은 current attempt를 abort하고 recovery를 한 번 dispatch한 뒤 새 attempt의 출력과 terminal만 한 번 전달한다. 전체 timeline의 correlation은 안정적이고 attempt 전환은 명시되며 raw prompt/output/tool args/result/auth는 구조화된 결과나 일반 로그에 남지 않는다 |
| S24 | `approved-tail-pacing` | fake monotonic clock의 200/500/1000-rune rolling pass window, short terminal tail, blocking recovery, tool fragment, cancel/sink failure와 bounded queue fixture가 Chat/Responses tunnel·normalized path에 입력된다 | filter pass로 승인된 이전 window를 scheduler가 전달하는 동안 다음 provider window가 계속 수집·평가된다 | 시간은 승인 전 release eligibility나 idle fail-open으로 사용되지 않는다. 각 approved window의 delivery duration은 수집 시간 `T`의 ±10%이고 exact rune/event/channel 순서와 UTF-8을 보존하며 threshold whole-batch burst와 `collect T + deliver T` 직렬 지연이 없다. recovery는 unapproved tail만 교체하고 structural/tool event는 원자적이며 queue drain 뒤 terminal 하나만 전달한다. cancel·sink failure는 timer/queue/provider ownership을 정리한다 |
## Evidence Map
| Scenario | Required Evidence | `agent-task` 연결 | 완료 Evidence 기대 |
|----------|-------------------|------------------|---------------------------|
| S01 | outer API·inner config 계약 문서 diff, Go request/metadata/config type tests | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``contract-doc`, pre-read raw-canonical limit/default/range/refresh 분류와 initial/rebuild error contract, `go test ./apps/edge/internal/openai -count=1` 결과 |
| S02 | mode selection unit tests, unsupported 조합 tests | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``filter-pipeline`, handler test 결과 |
| S03 | Korean multi-byte 6-paragraph repeat, 500-rune pending+look-behind, continuation cursor, duplicate opening/prefix and temperature fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``repeat-guard`, safe stream-open continuation/single `[DONE]`/byte-boundary assertion |
| S04 | tool side-effect/action repeat guard fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``repeat-guard`, automatic repair block assertion |
| S05 | valid JSON schema, bounded terminal gate and eager response-start/content absence fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``schema-contract`, validated-only commit assertion |
| S06 | invalid recovery, retry exhausted, lossless unknown-field RequestRebuilder fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``schema-contract`, uncommitted recovery/field preservation assertion |
| S07 | generic raw HTTP/OpenAI SDK smoke, dev `ornith:35b` Korean long-output capacity+1 stream smoke 3회, optional Pi field smoke, Edge provider log, D03 원문 기록 `on`/`off` 전환 logging tests | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``ops-evidence`, Korean smoke의 repeat fingerprint/offset 또는 `not_reproduced`, generic smoke evidence, optional caller field evidence, role preservation, `on` 원문 기록·`off` 비원문 기록·항상 제외되는 prompt/tool/auth assertion |
| S08 | qwen/gemma/ornith policy, config reload isolation, provider-switch and required capability admission fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``filter-policy`, request snapshot/attempt re-resolution/pre-dispatch 400 assertion |
| S09 | incoming request-history repeated tool/action fingerprint fixture, Ornith 반복 toolUse 로그 재현 | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``repeat-guard`, tool call delta hold/block/release assertion, repeated_action observation, no-progress threshold, observe-only 불확실성 처리, side-effect safe stop assertion |
| S10 | [2026-07-16 sanitized incident evidence](evidence/2026-07-16-pi-ornith-cross-request-history-anchor.log)에서 파생한 caller-neutral content/reasoning alias fixture, completed distinct action/result fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``repeat-guard`, assistant-only provenance, incoming-history threshold, D01 decision assertion, distinct action non-block assertion |
| S11 | generic assistant anchor + completed no-progress/churn fixture, released/unreleased tool call fixture, caller 온도 지정/미지정과 후보 배열 소진 fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``repeat-guard`, D01 정책, sanitized repair history, 원문 보존·요약 금지, caller 온도 보존, `[0.2, 0.4, 0.6]` 후보 소진, final content non-suppression, side-effect safe stop assertion |
| S12 | reasoning history omitted fixture, no conversation identity fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``repeat-guard`, no inferred TTL/lineage와 current-request degradation assertion |
| S13 | raw HTTP/OpenAI SDK/Pi equivalent-payload table test | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``filter-policy`, caller-name-independent path/threshold/decision assertion |
| S14 | two-endpoint response-start, evaluated/deferred/not-applicable outcomes, bounded ingress and simultaneous violation tests | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``stream-gate-adoption`, blocking-deferred/event-only distinction/no eager commit assertion |
| S15 | staged response-start/body matched error, shared 1~3회 plan, request-total cap, raw-canonical equality, abort and pool readmission fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``provider-error-retry`, original start hidden/final response once/total-cap assertion |
| S16 | stream-open pending error, released role/content/tool, cancel/side-effect and continuation-vs-exact matrix | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``provider-error-retry`, exact no-replay/continuation distinction/no duplicate dispatch assertion |
| S17 | simultaneous/sequential cross-strategy intents, shared exact 3회, request-total 0/1/3회와 4 이상 config rejection, abort-before-dispatch and abort-failure fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``provider-error-retry`, deterministic one plan/no overlap/no strategy bypass/absolute-cap assertion |
| S18 | Responses unknown item, response-start, split event, raw-body canonical repair, retained/rebuild overflow and path-switch fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``responses-codec`, endpoint-specific lossless shape/single opening-terminal/no-dispatch overflow assertion |
| S19 | terminal-gate hard-limit overflow/cancel/no partial release fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``schema-contract`, bounded fail-closed assertion |
| S20 | all-complete/abort-before-build, content·think/reasoning channel provenance, exact fixed-English directive, user request/message exclusion, context overflow no-dispatch, Chat/Responses rebuild fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``resume-notice-builder`, 고정 문구 일치/no translator·local-model·preparer call/no summary·truncation·rewrite/actual dispatch-only budget/endpoint shape assertion |
| S21 | Chat/Responses raw-body limit-1/limit/limit+1 pre-read, exact-limit body+typed-view overflow, no-full-read overflow, rebuild pre/post-allocation peak and release fixtures | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``stream-gate-adoption`, body-gate-vs-total-retained 구분/initial 413/rebuild commit-aware terminal/no-dispatch/no-budget/no-raw-log assertion |
| S22 | 16K output-cap `length` 2회 이상, original request + channel prefix/prefill rebuild, same-stream cursor/opening/prefix suppression, context/reserve 또는 caller logical cap exhaustion과 complete tool-call, lossless fragment serialization 가능/불가, cancel fixture | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``length-continuation`, fault cap과 trajectory budget 분리·no summary/truncation/new user message·single final terminal assertion |
| S23 | 한 명령 local/dev diagnostic smoke, deterministic pass/observe-only/blocking provider fixtures, Chat/Responses 실제 codec/Core/Arbiter/recovery/ReleaseSink 연결, ordered raw-free observation timeline | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``observable-core-smoke`, 모든 batch의 stage-before-evaluate/release, observe-only nonblocking, single abort/recovery, stable correlation/attempt switch, output·terminal 중복 부재와 prompt/output/tool/auth 미기록 assertion |
| S24 | fake clock 200/500/1000-rune·short-tail duration fixture, overlapping collection/delivery trace, bounded queue/backpressure, recovery/tool/cancel/sink-failure tests, dev `ornith:35b` direct OneX 대 Edge gap 비교, active spec/contract diff | `agent-task/m-openai-compatible-output-validation-filters/...` | `Roadmap Completion``approved-tail-pacing`, 승인 전 no-release, window별 `T` ±10%, exact rune/event/channel order, no serial double-latency, single terminal/timer cleanup, 2ms 미만 gap 비율과 threshold burst 감소, 구현 스펙·API/config 계약 동기화 assertion |
## Cross-repo Dependencies
- 없음
## Drift Check
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
- [x] Evidence Map이 code-review/complete.log에서 검증 가능하다.
- [x] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
- [x] 사용자 결정과 최종 승인이 [user_review_0.log](user_review_0.log), 현재 요청의 D08과 SDD에 반영됐다.
## 사용자 리뷰 이력
- 2026-07-16: caller-neutral 경계 보강 후 D01-D03 사용자 리뷰 요청. 해결 전 SDD 잠금 유지.
- 2026-07-16: caller-neutral 경계 보강 후 D01-D03 결정을 확인했다.
- 2026-07-23: provider error filter를 `code`/`message` array로 제한하고 완료된 Tool Call Runtime validation의 exact-replay path/counter를 Core Coordinator가 흡수하도록 1차 확정했다. 이후 D04에서 최초 실행 제외 최대 3회와 기존 provider-pool 재admission 정책까지 확정했다.
- 2026-07-23: provider 출력 전체가 아닌 pending tail을 기본 500 Unicode rune의 반복 판정 증거가 쌓일 때까지 filter 앞에 보류하고, environment/model/provider policy로 값을 조정하도록 확정. 시간 경과는 미검증 출력 release 조건으로 사용하지 않는다.
- 2026-07-23: D01에서 반복 전 원문 보존·반복 구간 제외, plain reasoning 한정 sanitation/live dedupe, tool release·side-effect 구간의 자동 복구 금지, 사용자 지정 온도 제외 `[0.2, 0.4, 0.6]` 순차 복구를 확정했다. 재개 안내문의 언어 판별·번역 로컬 모델 호출은 D05로 분리해 잠금 유지한다.
@ -247,7 +209,7 @@
- 2026-07-23: D01/D05 복구 입력을 모델 응답 content로만 제한하는 것으로 다시 확정했다. 사용자 요청·message는 번역 호출뿐 아니라 실제 재작업 요청에서도 제외하며 think/reasoning도 넣지 않는다. 번역 표본은 모델 응답 content의 마지막 500 Unicode rune이고, 재작업 요청은 반복 전 모델 응답 content 원문과 고정 복구 지시문만 사용한다.
- 2026-07-23: D01/D05 모델 출력 범위를 content와 think/reasoning 두 channel로 다시 확장했다. 번역 입력은 channel별 마지막 500 Unicode rune을 사용하고 `content → think/reasoning → 설정 기본 언어` 순으로 언어를 정한다. 재작업 요청도 반복 전 두 channel 원문과 복구 지시문만 사용하며 사용자 요청·message는 계속 제외한다.
- 2026-07-23: D05의 앞선 번역 관련 결정을 모두 대체했다. 언어 판별·번역·로컬 모델 호출·모델 별칭·20초 제한시간·구조화 반환·번역 실패 오류는 구현하지 않고, 반복 복구에는 고정 영어 지시문을 직접 사용한다. 재작업 요청은 반복 전 content와 think/reasoning 원문을 channel별로 구분해 넣고 사용자 요청·message는 제외한다.
- 2026-07-23: 사용자의 최종 승인을 반영해 SDD 상태를 `[승인됨]`, SDD 잠금을 `해제`로 전환하고 사용자 리뷰를 [user_review_0.log](user_review_0.log)로 보존했다.
- 2026-07-23: 사용자의 최종 결정을 반영해 SDD 상태를 `[확정]`으로 정리하고 당시 결정 기록을 [user_review_0.log](user_review_0.log)로 보존했다.
- 2026-07-24: 사용자가 provider의 큰 `max_tokens`가 local scheduling·동시성에 주는 부작용을 작은 attempt cap과 IOP managed continuation으로 분리하도록 확정했다. `length` 중간 terminal은 숨기고 원본 요청과 channel별 assistant prefix를 보존해 context-window/reserve가 허용하는 논리 trajectory를 같은 stream에 이어 간다. 이는 fault recovery 3회 cap과 별도이며 요약·문장 경계 절단·새 user message 방식은 사용하지 않는다.
- 2026-07-25: 재검증에서 rebuilt prompt가 assistant prefix를 이미 포함하므로 누적 output 이중 계상을 제거했다. provider attempt cap은 내부 운영 단위로만 쓰고 caller 명시 output cap은 논리 요청 전체에 한 번 적용한다. context 또는 caller logical cap 소진은 중간 provider terminal이 아닌 endpoint-native logical `length` terminal 한 번으로 표현하며, 미완성 tool fragment는 lossless serializer가 있는 경우에만 내부 continuation prefix로 사용한다.
- 2026-07-28: 사용자가 실제 의미 필터 구현 전에 pipeline 자체를 관측·검증할 deterministic diagnostic mock smoke를 선행 조건으로 확정했다. pass, observe-only violation, blocking violation 뒤 단일 recovery가 실제 codec/Core/Arbiter/ReleaseSink와 raw-free observation 경로를 통과해야 하며 production 기본 등록과 caller 활성화는 금지한다.

View file

@ -7,13 +7,11 @@
## 상태
[승인됨]
[확정]
## SDD 잠금
## 결정 사항
- 상태: 해제
- 사용자 리뷰: 없음
- 잠금 항목: 없음
- 없음
## 문제 / 비목표
@ -68,27 +66,10 @@
| S05 | `contract-spec-sync` | 구현과 테스트가 제거된 lifecycle을 반영함 | contract, living spec과 dev guide를 조회함 | 명시적 hard timeout·cancel·provider/transport terminal만 종료 권한으로 문서화된다. |
| S06 | `dev-rollout` | 새 Edge와 4개 Node가 동일 source ref로 dev에 배포됨 | Pi `ornith:35b` 장시간 tool-call을 GX10/OneX 경로에서 실행함 | 60초 무출력로 인한 `response_stalled` 없이 정상 terminal 또는 명시적 hard timeout까지 유지되고 queue가 0/0으로 회복한다. |
## Evidence Map
| Scenario | Required Evidence | `agent-task` 연결 | 완료 Evidence 기대 |
|----------|-------------------|------------------|---------------------------|
| S01-S02 | fake clock/context 기반 Node normalized+tunnel lifecycle test와 race test | `agent-task/m-provider-stall-watchdog-removal/...` | `milestone-task=watchdog-removal` complete.log와 fresh test output |
| S03 | Edge service/OpenAI provider error·terminal·lease release 회귀 test | `agent-task/m-provider-stall-watchdog-removal/...` | `milestone-task=edge-recovery-removal` complete.log와 fresh test output |
| S04 | config validation, protobuf generation/round-trip, deterministic symbol search | `agent-task/m-provider-stall-watchdog-removal/...` | `milestone-task=wire-config-cleanup` complete.log와 generated diff 검증 |
| S05 | matching contract/spec/dev guide diff와 link 검증 | `agent-task/m-provider-stall-watchdog-removal/...` | `milestone-task=contract-spec-sync` complete.log와 문서 정합성 검토 |
| S06 | source/build identity, 4-node snapshot, GX10/OneX Pi 장시간 tool-call와 final queue snapshot | `agent-task/m-provider-stall-watchdog-removal/...` | `milestone-task=dev-rollout` complete.log와 redacted dev evidence |
## Cross-repo Dependencies
- 없음
## Drift Check
- [x] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
- [x] Evidence Map이 code-review/complete.log에서 검증 가능하다.
- [x] agent-contract 원문을 복제하지 않고 링크했다.
- [x] 사용자 리뷰가 필요한 항목이 없다.
## 사용자 리뷰 이력
- 2026-08-15: 사용자가 운영 비활성화와 stall watchdog 전용 구현 제거를 함께 진행하도록 결정했다.

View file

@ -1,8 +1,4 @@
# SDD User Review
## 상태
요청됨
# SDD Decision Notes
## 검토 대상
@ -19,7 +15,7 @@
- 영향: source of truth, 장애 복구, 다중 Control Plane 전환, export API, 저장소 schema 경계에 영향을 준다.
- 적용 위치:
- SDD: `Source of Truth`, `Interface Contract`, `Acceptance Scenarios`
- Milestone: `storage-query`, `구현 잠금`
- Milestone: `storage-query`, `결정 사항`
### [D02] Usage Source 표시 정책
@ -71,17 +67,12 @@
- SDD: `Interface Contract`, `Acceptance Scenarios`
- Milestone: `tool-call-trace`, `log-redaction`
## 승인 항목
- [ ] 위 결정 항목을 승인했다.
- [ ] SDD 잠금 해제를 승인했다.
## 답변 기록
- 없음
## 해결 조건
## 적용 원칙
- 모든 사용자 결정 항목의 답변이 SDD에 반영되어 있다.
- [USER_REVIEW.md](USER_REVIEW.md)가 `user_review_N.log`로 이동되어 있다.
- 남은 잠금 항목이 없으면 SDD 상태가 `[승인됨]`이고 `SDD 잠금` 상태가 `해제`다.
- 각 결정은 답변이 필요한 구현 부분에만 적용한다.
- 미정 결정은 다른 독립 Task나 Milestone을 차단하지 않는다.
- 답변은 이 문서와 SDD의 `결정 사항`에 반영하며 별도 승인·잠금 해제 절차를 요구하지 않는다.

View file

@ -9,11 +9,9 @@
[초안]
## SDD 잠금
## 결정 사항
- 상태: 잠금
- 사용자 리뷰: [USER_REVIEW.md](USER_REVIEW.md)
- 잠금 항목:
- 미정:
- [ ] [D01] request ledger의 canonical 저장 책임을 Edge와 Control Plane 중 어디에 둘지 결정한다.
- [ ] [D02] provider-reported, estimated, mixed, unavailable usage source를 운영 UI와 export에서 어떻게 표시할지 결정한다.
- [ ] [D03] provider가 hidden think/reasoning token을 보고하지 않는 경우 표시 reasoning text 기반 추정치를 허용할지 결정한다.
@ -34,7 +32,7 @@
| 영역 | 기준 | 메모 |
|------|------|------|
| Roadmap | [request-execution-log-usage-ledger-foundation](../../../phase/operational-observability-provider-management/milestones/request-execution-log-usage-ledger-foundation.md) | Milestone 목표, 기능 Task, 잠금 항목 기준 |
| Roadmap | [request-execution-log-usage-ledger-foundation](../../../phase/operational-observability-provider-management/milestones/request-execution-log-usage-ledger-foundation.md) | Milestone 목표, 기능 Task, 미정 결정 기준 |
| Code | `apps/edge/internal/openai`, `apps/edge/internal/service`, `apps/node/internal/node`, `apps/node/internal/adapters/openai_compat`, `apps/node/internal/adapters/vllm`, `apps/node/internal/adapters/ollama`, `proto/iop/runtime.proto` | OpenAI-compatible input, dispatch, runtime event, usage/tool-call propagation 구현 기준 |
| External Provider | OpenAI-compatible provider usage chunk | provider-reported token usage가 있으면 우선 사용하고, 없으면 estimated/unavailable로 표시 |
| User Decision | D01-D06 | 저장 책임, usage source 표시, reasoning token 추정, redaction/retention, schema 분리, tool-call raw capture/redaction 결정 필요 |
@ -90,30 +88,10 @@
| S07 | `migration-plan` | 기존 zap log, runtime event, Control Plane operation history가 존재한다 | request ledger를 추가한다 | 병행 운용 또는 migration 전략 후보가 문서화되어 있다 |
| S08 | `tool-call-trace` | provider/model route가 tool call을 native tool_calls, text fallback, raw text 중 하나로 반환한다 | Edge가 OpenAI-compatible 응답을 구성하거나 parser/fallback 실패를 만난다 | native/text/synthesized/leaked/parse-failure 판정 필드와 redaction/capture 기준이 문서화되어 있다 |
## Evidence Map
| Scenario | Required Evidence | `agent-task` 연결 | 완료 Evidence 기대 |
|----------|-------------------|------------------|---------------------------|
| S01 | Milestone 문서와 SDD에서 lifecycle 표와 event source 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``event-lifecycle`와 S01 충족 근거 |
| S02 | correlation field 목록과 provider/device/model identity mapping 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``identity-correlation`와 S02 충족 근거 |
| S03 | usage field/source 정책과 provider-reported/estimated 구분 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``token-usage`와 S03 충족 근거 |
| S04 | latency metric 후보와 timestamp 계산 기준 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``latency-metrics`와 S04 충족 근거 |
| S05 | redaction/retention 결정 항목과 기본 후보 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``log-redaction`와 S05 충족 근거 |
| S06 | canonical owner 사용자 리뷰 해결 또는 결정 기록 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``storage-query`와 S06 충족 근거 |
| S07 | 기존 로그/event와 새 ledger 병행 또는 migration 전략 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``migration-plan`와 S07 충족 근거 |
| S08 | tool-call bridge 판정 필드, parser/fallback 실패 기록, redaction/capture 기준 확인 | `agent-task/m-request-execution-log-usage-ledger-foundation/...` | `Roadmap Completion``tool-call-trace`와 S08 충족 근거 |
## Cross-repo Dependencies
- 없음
## Drift Check
- [ ] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
- [ ] Evidence Map이 code-review/complete.log에서 검증 가능하다.
- [ ] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
- [ ] 사용자 리뷰가 필요한 항목은 [USER_REVIEW.md](USER_REVIEW.md)에만 남겼다.
## 사용자 리뷰 이력
- 없음

View file

@ -5,101 +5,23 @@ last_rule_updated_at: <YYYY-MM-DD>
# <env> 테스트 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
**<env> 테스트 환경의 핵심 실행 모드와 local/dev/qa 등 다른 환경과의 공존 기준을 이 문서에 둔다.**
## 방향
## 공통 규칙
- <env> 테스트/검증은 이 파일을 기준으로 판단한다.
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
- token/secret 원문은 원격 환경에서 주입하고, shell stdout/stderr와 최종 보고에 출력하지 않는다.
- 테스트용 Docker 환경을 작성/수정할 때는 Docker Compose `networks`, IPAM subnet, static IPv4, `extra_hosts`, host publish 문서 어디에도 host LAN/VPN과 충돌하는 대역을 사용하지 않는다.
- 검증 게이트 최소화를 최우선으로 한다.
- 현재 변경에 직접 관련된 profile과 가장 작은 검증만 선택한다.
- full-cycle, 외부 provider, 원격 runner는 사용자 요청이나 구체적 위험이 있을 때만 사용한다.
- 실행하지 않은 선택 검증은 남은 위험으로 기록할 수 있으나 완료를 자동 차단하지 않는다.
- secret과 개인 endpoint 원문은 기록하지 않는다.
## 기본 환경
- host: <기본 실행 host 또는 runner SSH>
- repo root: <원격/로컬 repo root>
- sync 기준: <source sync 판단 기준>
- env file: <compose/env file 기준 또는 해당 없음>
- compose identity: <COMPOSE_PROJECT_NAME / network 또는 해당 없음>
- port: <핵심 포트 요약>
- optional field ports: <선택 포트 또는 해당 없음>
- runtime: <Go/Flutter/Docker/외부 runtime>
- package manager: <Go modules / Makefile / Flutter pub >
- docker: <Docker 사용 기준>
- external service: <외부 서비스 URL/host 요약>
- model endpoint: <OpenAI-compatible 모델 endpoint>
- credential: secret/token/API key 원문은 문서에 기록하지 않는다.
## 포트 매핑
| 용도 | local/test | dev | <env> |
|---|---:|---:|---:|
| Web preview | `13000-13099` | `13001` | `<port 또는 해당 없음>` |
| Control Plane HTTP | `18000` | `18001` | `<port 또는 해당 없음>` |
| CP Client WS | `19080` | `19001` | `<port 또는 해당 없음>` |
| CP-Edge wire | `19081` | `19002` | `<port 또는 해당 없음>` |
| Edge-Node TCP | `19090` | `19003` | `<port 또는 해당 없음>` |
| Edge artifact/bootstrap | `18080` | `18082` | `<port 또는 해당 없음>` |
| Edge OpenAI-compatible | `18081` | `18083` | `<port 또는 해당 없음>` |
| Edge metrics | `19092` | `19101` | `<port 또는 해당 없음>` |
| Control Plane metrics | `19100` | `19103` | `<port 또는 해당 없음>` |
| Prometheus UI/API | `19110` | `19111` | `<port 또는 해당 없음>` |
| Grafana UI | `19120` | `19121` | `<port 또는 해당 없음>` |
| PostgreSQL host publish | `15400` | `15401` | `<port 또는 해당 없음>` |
| Redis host publish | `16300` | `16301` | `<port 또는 해당 없음>` |
<환경 안에서 compose/native/dev-runtime처럼 Edge-Node TCP가 갈라지면 여기에 명시한다.>
## 런타임 프로필
- local quick check: 현재 checkout에서 가능한 quick check를 우선 실행한다.
- remote runner: <SSH, repo root, 어떤 evidence에 쓰는지>
- compose <env> stack: <compose file/env file/project/network/주요 포트>
- native/direct Edge profile: <필요 artifact/openai/metrics/edge-node 포트>
- provider pool profile: <필요 config path, model alias, Edge-Node TCP>
- external provider field: <필요 SSH/user/IP/provider endpoint>
## 프리플라이트
- plan 작성 시 필수 검증이 현재 checkout을 벗어나 원격 runner, field/bootstrap, 외부 provider, Docker/code-server, emulator/device, 공유 장기 runtime을 사용하면 먼저 테스트 환경 프리플라이트를 계획에 기록한다.
- 테스트 환경 프리플라이트에는 runner, repo root/workdir, branch/HEAD/dirty 상태, local 변경과 원격 source 동기화 여부, binary/artifact 경로와 필요한 help/version 출력, config path, runtime identity, port/process 상태, 외부 host, OS/arch 가정을 포함한다.
- 프리플라이트에서 dirty/divergent checkout, stale artifact, 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 plan은 먼저 setup/sync/rebuild 단계를 만들거나 blocker로 보고한다. remote deploy 환경에서 dirty 변경을 보존하지 않는 정책이면 배포 전 clean sync와 rebuild를 기본 단계로 둔다. profile 값을 이미 참이라고 가정한 검증 명령만 쓰지 않는다.
## 노드/Provider 인벤토리 위치
- 공통 machine-readable 인벤토리 기준: `agent-test/inventory.yaml`
- 환경별 machine-readable 인벤토리 기준: `agent-test/inventory-<env>.yaml` 또는 `해당 없음`
- Edge/OpenAI-compatible 입력 표면 상세 기준: `agent-test/<env>/edge-smoke.md`
- Node 접속과 bootstrap 상세 기준: `agent-test/<env>/node-smoke.md`
- 공통 provider config 계약 기준: `agent-test/<env>/platform-common-smoke.md`
- compose stack 기준: `agent-test/<env>/control-plane-smoke.md`, `agent-test/<env>/client-smoke.md`, `agent-test/<env>/testing-smoke.md`
## Field/bootstrap 반복 테스트 기준
- field/bootstrap 검증은 이 환경의 runner, checkout, artifact 기준으로 수행한다. 세부 Edge/Node profile은 해당 env의 `edge-smoke.md``node-smoke.md`를 따른다.
- compose stack과 native/provider-pool profile이 서로 다른 Edge-Node TCP를 쓰면 두 프로필을 섞어서 판정하지 않는다.
- Node bootstrap은 Edge의 `node register`가 출력한 OS별 완성 명령을 그대로 사용한다. 사용자에게 안내하는 명령에는 임의 placeholder, 수동 token 치환, `IOP_*=` named environment parameter를 넣지 않는다.
- token, API key, private credential 원문은 tracked docs, roadmap, 테스트 규칙에 기록하지 않는다. 실행 증거에는 token을 마스킹하거나 명령 생성 사실만 남긴다.
- Linux/macOS Node는 생성된 `curl | bash` 계열 명령을 사용한다. Windows Node는 native PowerShell bootstrap을 기본으로 사용한다.
- provider capacity, model/provider mapping의 live apply는 해당 Edge binary가 `config refresh`를 제공하는 경우에만 사용한다. refresh 지원이 필요한 환경에서 subcommand나 admin port가 없으면 stale binary로 보고 clean sync/rebuild를 먼저 수행한다.
- Edge process restart 또는 일시 단절 후에는 Node reconnect 정책을 검증한다. retry 한계를 넘겨 Node process가 종료된 경우에만 해당 Node host에서 새 bootstrap 실행이 필요하다.
- host:
- repo root:
- runtime:
- external service:
## 라우팅
- node / smoke / node 실행 파이프라인 baseline: `agent-test/<env>/node-smoke.md`
- edge / smoke / edge 실행 그룹과 입력 표면 baseline: `agent-test/<env>/edge-smoke.md`
- control-plane / smoke / control-plane health와 wire baseline: `agent-test/<env>/control-plane-smoke.md`
- client / smoke / Flutter client와 IOP console package baseline: `agent-test/<env>/client-smoke.md`
- platform-common / smoke / 공통 설정과 protobuf 계약 baseline: `agent-test/<env>/platform-common-smoke.md`
- testing / smoke / 테스트 도구와 full-cycle 검증 baseline: `agent-test/<env>/testing-smoke.md`
- <scope>: `agent-test/<env>/<test-profile>.md`
## 라우팅 규칙
- 여러 항목이 맞으면 모두 읽는다.
- 도메인 매핑이나 domain rule이 있으면 각 도메인의 `<domain>-smoke` 문서를 기본 baseline으로 둔다.
- 도메인이 아직 없을 때만 `project-smoke`를 fallback baseline으로 둔다.
- 도메인/검증 시나리오별 문서는 다른 테스트 문서로 라우팅하지 않는다.
관련 profile만 읽으며 모든 domain baseline을 누적하지 않는다.

View file

@ -2,78 +2,26 @@
test_env: <env>
test_profile: <test-profile>
domain: <domain|project-wide>
verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
verification_type: <smoke|unit|integration|e2e|manual>
last_rule_updated_at: <YYYY-MM-DD>
---
# <test-profile> <env> 테스트
## 읽기 조건
- < 도메인/검증 시나리오의 테스트, 검증, 실행 조건 판단이 필요한 경우>
## 적용 범위
- <검증 대상 entrypoint, command, API, UX, profile, service>
- <직접 검증할 동작>
## 분류
## 최소 검증
- domain: <domain|project-wide>
- verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
- scope: <검증 대상 변경 범위 요약>
- 명령:
- 성공 기준:
## 환경
## 선택 검증
- host:
- port:
- runtime:
- package manager:
- docker:
- external service:
- model endpoint:
- credential: secret/token/API key 원문은 문서에 기록하지 않는다.
- <실제 실패나 구체적 위험이 있을 때만 실행>
## 명령
- setup:
- lint:
- unit:
- smoke:
- e2e:
- model:
- full-cycle:
## 필수 검증
- <작업 완료 반드시 실행하거나 판단해야 하는 검증>
## 보조 검증
- <실행하면 좋지만 필수 검증을 대체하지 않는 smoke/helper 검증>
## 판정 기준
- <통과로 판단할 출력, 상태, UX, artifact, endpoint 조건>
## 기준 출력 예시
```text
<필요한 경우 기대 출력 예시>
```
## 차단 기준
- <테스트를 계속할 없는 환경/권한/도구/서비스 조건>
## 보고 항목
- 실행한 명령:
- 성공한 검증:
- 실패/차단된 검증:
- 생략 사유:
- 남은 위험:
## 금지 사항
- secret, token, 개인 endpoint 원문은 tracked 파일에 기록하지 않는다.
## 제약
- <보안·데이터 손상 방지 또는 환경 제약>
- secret과 개인 endpoint 원문은 기록하지 않는다.

View file

@ -53,7 +53,7 @@ last_rule_updated_at: 2026-07-11
- model:
- full-cycle:
## 필수 검증
## 최소 검증
- client 또는 `packages/flutter/iop_console` 변경은 최소 `cd apps/client && flutter test`로 확인한다.
- `packages/flutter/iop_console` 자체 API나 widget 구조가 바뀌면 `cd packages/flutter/iop_console && flutter test` 실행 가능 여부를 확인한다.

View file

@ -51,7 +51,7 @@ last_rule_updated_at: 2026-07-14
- model:
- full-cycle: Control Plane command, health/readiness, wire hello 수동 검증
## 필수 검증
## 최소 검증
- 변경한 control-plane 패키지 또는 `go test ./apps/control-plane/...`를 실행한다.
- HTTP lifecycle 변경 시 dev-corp port `/healthz``/readyz`를 확인한다.

View file

@ -127,7 +127,7 @@ Mac Studio의 `http://192.168.2.3:8005/v1` mlx-vlm DiffusionGemma endpoint는
- direct-provider: mac-mini에서 `curl -fsS http://192.168.2.2:8003/v1/models`, `curl -fsS http://192.168.2.4:8005/v1/models`, `curl -fsS http://192.168.2.3:8004/v1/models`
- full-cycle: repo 내부 edge-node 진단, `iop-edge smoke openai`, OpenAI-compatible 입력 표면 수동 검증
## 필수 검증
## 최소 검증
- 변경한 edge 패키지 또는 `go test ./apps/edge/...`를 실행한다.
- registry, service, transport, console, HTTP/A2A 입력 표면을 바꾼 경우 edge-node 메시지 2회 왕복과 command 응답을 확인한다.

View file

@ -121,7 +121,7 @@ Mac Studio의 secondary `http://192.168.2.3:8005/v1` endpoint는 기본 Node/pro
- provider-health: mac-mini에서 `curl -fsS http://192.168.2.2:8003/health`, `curl -fsS http://192.168.2.4:8005/health`, `curl -fsS http://192.168.2.3:8004/health`
- full-cycle: repo 내부 edge-node 진단과 사용자 실행 cycle 수동 검증
## 필수 검증
## 최소 검증
- 변경한 node 패키지 또는 `go test ./apps/node/...`를 실행한다.
- 실행 요청, stream, cancel, status, session, adapter registry 경로를 바꾼 경우 repo 내부 edge-node 진단과 full-cycle 실제 구동 기준을 함께 적용한다.

View file

@ -48,7 +48,7 @@ last_rule_updated_at: 2026-07-11
- model:
- full-cycle: 설정/proto 변경이 사용자 실행 파이프라인에 닿으면 edge-node 실제 구동 검증
## 필수 검증
## 최소 검증
- 공통 패키지 변경 시 변경 패키지 테스트 또는 `go test ./packages/go/... ./proto/gen/...`를 실행한다.
- protobuf 원본 변경 시 `make proto`로 Go 생성물을 갱신하고 생성물 diff를 확인한다.

View file

@ -14,7 +14,7 @@ last_rule_updated_at: 2026-07-14
- 일반 `dev`, 테스트 환경, 배포, rollout, runtime 검증 요청에서 dev-corp로 fallback하거나 접근 가능한 대체 경로로 탐색하지 않는다. 해당 경우에는 `agent-test/dev/**`를 기준으로 한다.
- dev-corp 테스트/검증은 이 파일을 기준으로 판단한다.
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
- 검증 게이트 최소화를 최우선으로 하며, 변경 위험에 직접 대응하는 가장 작은 검증을 기본으로 한다.
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
- token/secret/API key 원문은 원격 환경에서 주입하고, shell stdout/stderr와 최종 보고에 출력하지 않는다.
@ -78,14 +78,10 @@ dev-corp native/provider-pool profile은 compose Edge-Node TCP `19006`이 아니
- current native Control Plane: 2026-07-02 기준 provider-pool runtime에서 `build/dev-corp-runtime/bin/control-plane``18002/19004/19005`를 listen하고, Edge id `dev-corp-edge``127.0.0.1:19005`로 연결된다. provider snapshot status 기준은 `http://127.0.0.1:18002/edges/dev-corp-edge/status`다.
- external provider field: DGX Spark 01/02와 Mac Studio는 mac-mini에서 내부 SSH로 접속한다. 직접 접속 경로와 provider endpoint는 `agent-test/inventory-dev-corp.yaml`을 따른다.
## 프리플라이트
## 외부 환경 확인
- plan 작성 시 필수 검증이 현재 checkout을 벗어나 mac-mini runner, field/bootstrap, 외부 provider, Docker/code-server, emulator/device, 공유 장기 runtime을 사용하면 먼저 테스트 환경 프리플라이트를 계획에 기록한다.
- 테스트 환경 프리플라이트에는 runner, repo root/workdir, branch/HEAD/dirty 상태, local 변경과 원격 source 동기화 여부, binary/artifact 경로와 필요한 help/version 출력, config path, runtime identity, port/process 상태, 외부 host, OS/arch 가정을 포함한다.
- mac-mini에 `/Users/fe/agent-work/iop-dev-corp` checkout이 없으면 배포/검증을 시작하지 말고 checkout 생성과 source sync를 setup blocker로 보고한다.
- provider pool 검증 전 mac-mini에서 내부 provider endpoint `192.168.2.2:8003`, `192.168.2.4:8005`, `192.168.2.3:8004``/health``/v1/models`를 먼저 확인하고, 각 Node의 `edge_addr``iop.ai.kr:18087`인지 확인한다.
- 현재 dev-corp model/provider mapping은 `gemma4:26b` -> Mac Studio capacity `5`, `ornith:35b` -> Spark01/02 합산 capacity `8`이다. 새 배포에서 Edge config 반영과 model-specific capacity smoke가 통과하기 전에는 새 결과를 확정값으로 보고하지 않는다.
- 프리플라이트에서 dirty/divergent checkout 또는 stale artifact가 확인되면 dev-corp 배포에서는 먼저 원격 checkout을 clean sync하고 dev-corp runtime 바이너리를 rebuild한다. 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 plan은 setup/sync/rebuild 단계를 만들거나 blocker로 보고한다.
- 현재 변경에 직접 필요한 dev-corp 배포·provider 검증을 선택했을 때만 checkout, source/build identity, 대상 endpoint와 `edge_addr`를 확인한다.
- 이 확인은 잘못된 대상 배포와 credential·운영 데이터 손상을 막는 범위로 제한한다. 선택 검증을 실행하지 못한 사실만으로 구현 완료를 자동 차단하지 않는다.
## 노드/Provider 인벤토리 위치

View file

@ -55,7 +55,7 @@ last_rule_updated_at: 2026-07-13
- model: `./scripts/e2e-openai-ollama.sh` 또는 dev-corp OpenAI-compatible smoke
- full-cycle: `make pack-node-target`, repo 내부 edge-node 진단, field bootstrap UX, 실제 provider pool 검증
## 필수 검증
## 최소 검증
- 테스트 도구 자체를 바꾼 경우 해당 도구를 직접 실행해 성공/실패 판정을 확인한다.
- 사용자 실행 파이프라인에 닿는 변경은 일반 Go 테스트와 변경 범위에 맞는 full-cycle 실제 구동을 함께 검증한다.
@ -93,7 +93,7 @@ curl -fsS http://192.168.2.3:8004/v1/models
## 차단 기준
- mac-mini 접근, 지정 port, provider 상태가 없어 필수 검증을 수행할 수 없다.
- mac-mini 접근, 지정 port, provider 상태가 없어 선택한 검증을 수행할 수 없다.
- mac-mini에 `/Users/fe/agent-work/iop-dev-corp` checkout이 없다.
- 사용자가 명시하지 않았는데 code-server 컨테이너 재시작이 필요한 상황이다.
- dev-corp 포트가 이미 사용 중이라 local/test/dev stack과 공존할 수 없다.

View file

@ -55,7 +55,7 @@ last_rule_updated_at: 2026-07-30
- model:
- full-cycle:
## 필수 검증
## 최소 검증
- client 또는 `packages/flutter/iop_console` 변경은 최소 `cd apps/client && flutter test`로 확인한다.
- `packages/flutter/iop_console` 자체 API나 widget 구조가 바뀌면 `cd packages/flutter/iop_console && flutter test` 실행 가능 여부를 확인한다.

View file

@ -49,7 +49,7 @@ last_rule_updated_at: 2026-06-12
- model:
- full-cycle: Control Plane command, health/readiness, wire hello 수동 검증
## 필수 검증
## 최소 검증
- 변경한 control-plane 패키지 또는 `go test ./apps/control-plane/...`를 실행한다.
- HTTP lifecycle 변경 시 dev port `/healthz``/readyz`를 확인한다.

View file

@ -126,7 +126,7 @@ GX10/OneXPlayer/RTX5090 Ornith sampling은 `temperature=0.6`, `top_p=0.95`, `top
- model: dev OpenAI-compatible profile을 띄운 경우 `iop-edge smoke openai --base-url http://127.0.0.1:18083`
- full-cycle: repo 내부 edge-node 진단, `iop-edge smoke openai`, OpenAI-compatible 입력 표면 수동 검증
## 필수 검증
## 최소 검증
- 변경한 edge 패키지 또는 `go test ./apps/edge/...`를 실행한다.
- registry, service, transport, console, HTTP/A2A 입력 표면을 바꾼 경우 edge-node 메시지 2회 왕복과 command 응답을 확인한다.

View file

@ -84,7 +84,7 @@ ssh toki@toki-labs.com 'cd /Users/toki/agent-work/iop-dev && \
- `mixed`: 선택 모델 그룹의 long slot 총합만큼 long 요청으로 slot을 채운 뒤 normal 요청을 보낸다. Laguna-S 기준 long slot은 GX10의 `1`이다. long slot full 중에도 normal 요청이 head-of-line blocking 없이 dispatch/완료되고, 최종 counters가 0으로 회복.
- `all-long-slot-full`: 선택 모델 그룹의 long slot 총합보다 많은 long 요청(`slot_total + 2`)을 보내 일부가 queue 대기한 뒤 long slot 회복 시 dispatch되고, 최종 counters가 0으로 회복.
## 필수 검증
## 최소 검증
- preflight가 source state(`git rev-parse HEAD`, `git status --short`), config check(`edge config check`), base URL `/models` reachability, Control Plane status reachability, 선택 모델 그룹의 provider identity, 초기 provider snapshot을 기록한다. Laguna-S 선택 시 provider identity는 `gx10-vllm`만 포함해야 한다.
- 세 시나리오 각각에서 요청 발사 중 status를 poll해 peak `in_flight`/`queued`를 저장하고, 완료 후 최종 snapshot에서 `in_flight=0`, `queued=0` 회복을 확인한다.

View file

@ -121,7 +121,7 @@ Qwen runtime에는 Qwen 전용 parser/template 검증값만 사용한다. dev-co
- model:
- full-cycle: repo 내부 edge-node 진단과 사용자 실행 cycle 수동 검증
## 필수 검증
## 최소 검증
- 변경한 node 패키지 또는 `go test ./apps/node/...`를 실행한다.
- Windows Node candidate는 cross-build 성공만으로 완료하지 않는다. `packages/go/credentiallease` Windows test executable을 실제 Windows host에서 실행해 현재 사용자/System/Administrators만 읽을 수 있는 key file은 허용하고 Everyone read ACE는 거부하는지 확인한다.

View file

@ -47,7 +47,7 @@ last_rule_updated_at: 2026-06-12
- model:
- full-cycle: 설정/proto 변경이 사용자 실행 파이프라인에 닿으면 edge-node 실제 구동 검증
## 필수 검증
## 최소 검증
- 공통 패키지 변경 시 변경 패키지 테스트 또는 `go test ./packages/go/... ./proto/gen/...`를 실행한다.
- protobuf 원본 변경 시 `make proto`로 Go 생성물을 갱신하고 생성물 diff를 확인한다.

View file

@ -15,7 +15,7 @@ last_rule_updated_at: 2026-08-02
- `dev-corp``dev`의 fallback이나 자동 접근 경로가 아니다. 사용자가 `dev-corp` 또는 동등한 회사망/public dev-corp 환경을 명시하지 않은 경우 `agent-test/dev-corp/**`, `iop.ai.kr`, `fe@172.24.63.178`, dev-corp port로 접근하지 않는다.
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
- dev-runtime 배포 범위는 Control Plane, Edge, Node와 이들이 사용하는 공용 package다. `apps/agent/**`와 정확한 package `packages/go/agenttask`는 제외하지만, mac-codex-node가 사용하는 `packages/go/agentprovider/**``packages/go/agentruntime`은 포함한다. 제외 범위를 이유로 common orchestration 또는 `dispatch.py`를 수정·삭제하지 않는다.
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
- 검증 게이트 최소화를 최우선으로 하며, 변경 위험에 직접 대응하는 가장 작은 검증을 기본으로 한다.
- 원격 runtime, smoke, full-cycle, field/bootstrap 같은 배포형 검증은 테스트 시작 시 확정한 배포 기준 ref의 최신 build로 환경 전체를 갱신한 뒤 시작한다. dev-runtime provider pool은 Edge와 macOS/Linux ARM64/Windows AMD64 Node를 모두 같은 source ref에서 rebuild·redeploy·restart하고, compose profile은 검증에 참여하는 Control Plane/Web/Edge image를 같은 source ref에서 rebuild·redeploy·restart한다. 이미 실행 중인 build는 최신으로 추정해 재사용하지 않는다.
- 배포형 검증 전에 source commit과 각 build의 checksum 또는 동등한 build identity가 배포 기준 ref와 일치하는지 확인한다. 하나라도 갱신 또는 일치 확인을 할 수 없으면 과거 build로 테스트하지 말고 차단 사유로 보고한다. 현재 checkout에서 수행하는 source 단위/패키지 테스트와 build 전 테스트는 이 선행조건의 대상이 아니다.
- 새 테스트 환경을 추가하거나 환경 구조를 바꿀 때는 `agent-test/README.md``agent-test/_templates/`의 확장 기준을 따른다.
@ -74,11 +74,10 @@ dev-runtime provider pool은 compose Edge-Node TCP `19003`이 아니라 native E
- dev-runtime provider pool: `/Users/toki/agent-work/iop-dev/build/dev-runtime/edge.yaml`과 Edge-Node TCP `toki-labs.com:18084`를 사용한다. 4-node/provider 세부는 `agent-test/dev/edge-smoke.md``agent-test/dev/node-smoke.md`를 따른다.
- external provider field: GX10 vLLM은 `ssh toki@192.168.0.91`, OneXPlayer Lemonade는 현재 작업 호스트에서 `ssh r0bin@192.168.0.59`, RTX5090 Lemonade는 `ssh iop-dev-rtx5090`으로 직접 접속해 확인한다. Windows provider 접속은 원격 runner 경유를 필수 조건으로 보지 않는다.
## 프리플라이트
## 외부 환경 확인
- plan 작성 시 필수 검증이 현재 checkout을 벗어나 원격 runner, field/bootstrap, 외부 provider, Docker/code-server, emulator/device, 공유 장기 runtime을 사용하면 먼저 테스트 환경 프리플라이트를 계획에 기록한다.
- 테스트 환경 프리플라이트에는 runner, repo root/workdir, branch/HEAD/dirty 상태, local 변경과 원격 source 동기화 여부, binary/artifact 경로와 필요한 help/version 출력, config path, runtime identity, port/process 상태, 외부 host, OS/arch 가정을 포함한다.
- 배포형 검증 프리플라이트는 stale 여부와 관계없이 원격 checkout clean sync, 환경 전체 rebuild·redeploy·restart, source/build identity 확인을 필수 선행 단계로 둔다. 잘못된 identity, missing command, closed port, host OS 불일치, source 미동기화가 확인되면 테스트를 시작하지 않고 setup/sync/rebuild 단계를 수행하거나 blocker로 보고한다. profile 값을 이미 참이라고 가정한 검증 명령만 쓰지 않는다.
- 현재 변경에 직접 필요한 원격·배포 검증을 선택했을 때만 대상 runner, source/build identity, config, runtime과 port를 확인한다.
- 이 확인은 비가역 배포나 잘못된 대상 덮어쓰기를 막는 범위로 제한한다. 선택 검증을 실행하지 못한 사실만으로 구현 완료를 자동 차단하지 않는다.
## 노드/Provider 인벤토리 위치

View file

@ -54,7 +54,7 @@ last_rule_updated_at: 2026-07-30
- model: `./scripts/e2e-openai-ollama.sh`
- full-cycle: `make pack-node-target`, repo 내부 edge-node 진단, field bootstrap UX, 실제 외부 CLI profile 검증
## 필수 검증
## 최소 검증
- 테스트 도구 자체를 바꾼 경우 해당 도구를 직접 실행해 성공/실패 판정을 확인한다.
- 사용자 실행 파이프라인에 닿는 변경은 일반 Go 테스트와 변경 범위에 맞는 full-cycle 실제 구동을 함께 검증한다.
@ -89,7 +89,7 @@ curl -fsS http://127.0.0.1:18001/healthz
## 차단 기준
- dev host 접근, 지정 port, 외부 CLI 설치/계정/provider 상태가 없어 필수 검증을 수행할 수 없다.
- dev host 접근, 지정 port, 외부 CLI 설치/계정/provider 상태가 없어 선택한 검증을 수행할 수 없다.
- 사용자가 명시하지 않았는데 code-server 컨테이너 재시작이 필요한 상황이다.
- dev 포트가 이미 사용 중이라 local/test stack과 공존할 수 없다.