initial commit
Some checks are pending
ci / validate (push) Waiting to run

This commit is contained in:
toki 2026-07-18 18:41:17 +09:00
commit fdc86c7ff4
148 changed files with 13835 additions and 0 deletions

4
.aiexclude Normal file
View file

@ -0,0 +1,4 @@
# BEGIN Agent-Ops managed ignore
agent-task/archive/**
agent-roadmap/archive/**
# END Agent-Ops managed ignore

6
.claude/settings.json Normal file
View file

@ -0,0 +1,6 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"deny": []
}
}

4
.clineignore Normal file
View file

@ -0,0 +1,4 @@
# BEGIN Agent-Ops managed ignore
agent-task/archive/**
agent-roadmap/archive/**
# END Agent-Ops managed ignore

55
.clinerules Normal file
View file

@ -0,0 +1,55 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 사용자에게 보이는 최종 답변과 설명은 기본적으로 한국어로 작성한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. split 의존성 확인은 같은 task group의 후보 `complete.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/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 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`
# 프로젝트 간 잠금
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
# 스킬 규칙
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `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 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
# 테스트 규칙
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

4
.cursorignore Normal file
View file

@ -0,0 +1,4 @@
# BEGIN Agent-Ops managed ignore
agent-task/archive/**
agent-roadmap/archive/**
# END Agent-Ops managed ignore

55
.cursorrules Normal file
View file

@ -0,0 +1,55 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 사용자에게 보이는 최종 답변과 설명은 기본적으로 한국어로 작성한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. split 의존성 확인은 같은 task group의 후보 `complete.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/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 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`
# 프로젝트 간 잠금
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
# 스킬 규칙
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `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 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
# 테스트 규칙
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

18
.editorconfig Normal file
View file

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.go]
indent_style = tab
[*.{yaml,yml,json,proto,py,sql,md}]
indent_style = space
indent_size = 2
[*.py]
indent_size = 4

5
.env.example Normal file
View file

@ -0,0 +1,5 @@
RARA_DATABASE_URL=postgres://rara:rara@localhost:5432/rara?sslmode=disable
RARA_ARTIFACT_ROOT=./var/artifacts
RARA_LOG_LEVEL=info
RARA_OTEL_ENDPOINT=

4
.geminiignore Normal file
View file

@ -0,0 +1,4 @@
# BEGIN Agent-Ops managed ignore
agent-task/archive/**
agent-roadmap/archive/**
# END Agent-Ops managed ignore

34
.gitea/workflows/ci.yaml Normal file
View file

@ -0,0 +1,34 @@
name: ci
on:
push:
pull_request:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26.x"
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Python worker
run: |
python -m venv .venv
.venv/bin/pip install -e 'packages/python[dev]'
- name: Verify generated SQL
run: |
go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.31.1
sqlc diff
- name: Go tests
run: go test ./...
- name: Python checks
run: |
.venv/bin/ruff format --check packages/python/src packages/python/tests
.venv/bin/ruff check packages/python/src packages/python/tests
PYTHONPATH=packages/python/src .venv/bin/pytest packages/python/tests
- name: Build services
run: make build

43
.gitignore vendored Normal file
View file

@ -0,0 +1,43 @@
.env
.venv/
.tools/
__pycache__/
.pytest_cache/
.ruff_cache/
.mypy_cache/
*.py[cod]
*.egg-info/
bin/
build/
dist/
var/
.coverage
.coverage.*
coverage.out
coverage.xml
htmlcov/
.dart_tool/
.pub-cache/
.flutter-plugins
.flutter-plugins-dependencies
.idea/
.vscode/
.DS_Store
# BEGIN Agent-Ops managed gitignore
!agent-task/
!agent-task/**/
!agent-task/**/*.md
!agent-task/**/*.log
agent-roadmap/current.md
# END Agent-Ops managed gitignore
# Agent-Ops Private Rules
agent-ops/rules/private/
# Agent-Test Local Environment
agent-test/local/
agent-test/runs/

55
AGENTS.md Normal file
View file

@ -0,0 +1,55 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 사용자에게 보이는 최종 답변과 설명은 기본적으로 한국어로 작성한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. split 의존성 확인은 같은 task group의 후보 `complete.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/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 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`
# 프로젝트 간 잠금
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
# 스킬 규칙
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `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 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
# 테스트 규칙
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

67
ARCHITECTURE.md Normal file
View file

@ -0,0 +1,67 @@
# RARA architecture
## Responsibility
RARA is responsible for RAG behavior and quality while remaining independent of
the physical storage and model products used to implement that behavior.
```text
Consumers
|
v
RAG data plane
retrieve | answer | trace
|
+--> retrieval backend integrations
+--> embedding/reranking providers
+--> generation providers
Control plane
projects | knowledge bases | workflows | datasets
evaluations | releases | schedules | lineage
|
+--> PostgreSQL control state
+--> artifact store integrations
+--> Go/Python executors
```
## Planes
### Control plane
The control plane owns lifecycle state: projects, integrations, knowledge
bases, datasets, artifacts, workflows, evaluations, schedules, and releases.
### RAG data plane
The RAG API owns online retrieval and answer behavior. A request resolves a
knowledge base and release alias, applies the release's retrieval policy, and
returns evidence and release identity. `answer` additionally invokes a selected
generation provider and may stream output over SSE.
### Adaptation plane
Python executors curate evaluation and training data and later run LoRA/QLoRA
jobs. The control plane owns job state and artifacts; Python owns ML library
execution.
## Storage
PostgreSQL stores control state and lineage only. Large artifacts live in an
`ArtifactStore`. Retrieval indexes live in a `RetrievalBackend`. Both are
selected through integration instances with versioned capabilities and secret
references.
Integrations implement typed, product-neutral ports for source change streams,
index publication and retrieval, embeddings, reranking, generation, artifacts,
and secret resolution. The initial registry is compile-time Go composition;
out-of-process ML execution uses the versioned Protobuf executor contract.
## Initial safety defaults
- release promotion is explicit
- production indexes are immutable
- updates build candidate artifacts before promotion
- source deletion and ACL changes are tracked through lineage
- integration secrets are referenced, never stored in integration config
- stored RAG traces always have an expiry; raw query and answer fields remain optional

55
CLAUDE.md Normal file
View file

@ -0,0 +1,55 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 사용자에게 보이는 최종 답변과 설명은 기본적으로 한국어로 작성한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. split 의존성 확인은 같은 task group의 후보 `complete.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/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 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`
# 프로젝트 간 잠금
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
# 스킬 규칙
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `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 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
# 테스트 규칙
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

55
GEMINI.md Normal file
View file

@ -0,0 +1,55 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 사용자에게 보이는 최종 답변과 설명은 기본적으로 한국어로 작성한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. split 의존성 확인은 같은 task group의 후보 `complete.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/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 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`
# 프로젝트 간 잠금
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
# 스킬 규칙
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `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 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
# 테스트 규칙
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

97
Makefile Normal file
View file

@ -0,0 +1,97 @@
SHELL := /bin/sh
GO_MODULE := git.toki-labs.com/toki/rara
PROTO_ROOT := api/proto
PROTO_FILE := $(PROTO_ROOT)/rara/v1/executor.proto
PYTHON_ROOT := packages/python
VENV := .venv
VENV_READY := $(VENV)/.ready
TOOLS_DIR := $(CURDIR)/.tools
PROTOC_GEN_GO := $(TOOLS_DIR)/protoc-gen-go
PROTOC_GEN_GO_GRPC := $(TOOLS_DIR)/protoc-gen-go-grpc
SQLC := $(TOOLS_DIR)/sqlc
DATABASE_URL ?= postgres://rara:rara@localhost:5432/rara?sslmode=disable
.PHONY: all setup tools generate proto sqlc fmt test test-go test-python build \
python-sync db-up db-down migrate-up migrate-down migrate-status
all: setup fmt test build
setup: generate
tools: $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_GRPC) $(SQLC)
generate: proto sqlc
proto: $(VENV_READY) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_GRPC)
mkdir -p gen/go $(PYTHON_ROOT)/src
protoc -I $(PROTO_ROOT) \
--plugin=protoc-gen-go=$(PROTOC_GEN_GO) \
--plugin=protoc-gen-go-grpc=$(PROTOC_GEN_GO_GRPC) \
--go_out=gen/go --go_opt=paths=source_relative \
--go-grpc_out=gen/go --go-grpc_opt=paths=source_relative \
$(PROTO_FILE)
$(VENV)/bin/python -m grpc_tools.protoc -I $(PROTO_ROOT) \
--python_out=$(PYTHON_ROOT)/src \
--grpc_python_out=$(PYTHON_ROOT)/src \
$(PROTO_FILE)
sqlc: $(SQLC)
$(SQLC) generate
fmt: $(VENV_READY)
gofmt -w $$(find apps packages gen -name '*.go' -type f 2>/dev/null)
$(VENV)/bin/python -m ruff format $(PYTHON_ROOT)/src $(PYTHON_ROOT)/tests
$(VENV)/bin/python -m ruff check --fix $(PYTHON_ROOT)/src $(PYTHON_ROOT)/tests
test: test-go test-python
test-go:
go test ./...
test-python: $(VENV_READY)
PYTHONPATH=$(PYTHON_ROOT)/src $(VENV)/bin/python -m pytest $(PYTHON_ROOT)/tests
build:
mkdir -p bin
go build -o bin/rara-control-plane ./apps/control-plane/cmd/control-plane
go build -o bin/rara-rag-api ./apps/rag-api/cmd/rag-api
go build -o bin/rara-worker ./apps/worker/cmd/worker
python-sync: $(VENV_READY)
$(VENV_READY): $(PYTHON_ROOT)/pyproject.toml
python3 -m venv $(VENV)
$(VENV)/bin/pip install --upgrade pip
$(VENV)/bin/pip install -e '$(PYTHON_ROOT)[dev]'
touch $(VENV_READY)
$(PROTOC_GEN_GO):
mkdir -p $(TOOLS_DIR)
GOBIN=$(TOOLS_DIR) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
$(PROTOC_GEN_GO_GRPC):
mkdir -p $(TOOLS_DIR)
GOBIN=$(TOOLS_DIR) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.6.1
$(SQLC):
mkdir -p $(TOOLS_DIR)
GOBIN=$(TOOLS_DIR) go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.31.1
db-up:
docker compose -f deploy/compose.yaml up -d postgres
db-down:
docker compose -f deploy/compose.yaml down
migrate-up:
go run github.com/pressly/goose/v3/cmd/goose@v3.24.1 \
-dir db/migrations postgres '$(DATABASE_URL)' up
migrate-down:
go run github.com/pressly/goose/v3/cmd/goose@v3.24.1 \
-dir db/migrations postgres '$(DATABASE_URL)' down
migrate-status:
go run github.com/pressly/goose/v3/cmd/goose@v3.24.1 \
-dir db/migrations postgres '$(DATABASE_URL)' status

99
README.md Normal file
View file

@ -0,0 +1,99 @@
# RARA
RARA is an internal, storage-agnostic platform for operating the complete RAG
lifecycle and promoting verified data into optional LoRA/QLoRA workflows.
RARA owns the logical RAG contract end to end:
- source synchronization and normalization
- versioned datasets and artifact lineage
- retrieval, reranking, context assembly, and answer generation
- evaluation, release promotion, and rollback
- training-candidate curation and adaptation execution
Physical retrieval stores, artifact stores, model providers, and executors stay
replaceable behind capability-aware integrations.
## Repository layout
```text
apps/
control-plane/ Go lifecycle and management API
rag-api/ Go online retrieve/answer data plane
worker/ Go workflow step worker
client/ reserved for the operations UI
api/
openapi/ public HTTP API contract
proto/ internal Go/Python executor contract
packages/
go/ shared Go packages
python/ Python adaptation worker
db/
migrations/ PostgreSQL schema migrations
queries/ sqlc queries
configs/ service configuration examples
deploy/ local deployment assets
```
## Baseline
- Go 1.26
- Python 3.12
- PostgreSQL 18
- Protobuf for internal executor contracts
- HTTP/JSON and SSE for the public RAG API
PostgreSQL is the required control-state database. It is not the default RAG
retrieval backend and there is no SQLite fallback.
## Development
The local prerequisites are Go, Python, and `protoc`. `make setup` installs
version-pinned Go code-generation tools under `.tools/` and creates `.venv/`.
Bootstrap the Python environment and generate contracts:
```sh
make setup
```
Run checks and build the three Go services:
```sh
make test
make build
```
Start PostgreSQL when a container runtime is available:
```sh
make db-up
make migrate-up
```
The current workspace may instead use an external PostgreSQL instance through
`RARA_DATABASE_URL`.
Run services after PostgreSQL is migrated:
```sh
bin/rara-control-plane --config configs/control-plane.yaml
bin/rara-rag-api --config configs/rag-api.yaml
bin/rara-worker --config configs/worker.yaml
```
The Python executor starts with:
```sh
.venv/bin/rara-python-worker
```
ML dependencies are optional. Install
`packages/python[training]` or `packages/python[training,quantized]` only on
hosts that execute adaptation jobs.
## Status
This repository currently contains the platform scaffold. Retrieval backends,
model providers, source connectors, and production workflows are added as
versioned integrations rather than hard-coded infrastructure.

1
agent-ops/.version Normal file
View file

@ -0,0 +1 @@
1.1.167

View file

@ -0,0 +1,35 @@
---
domain: <domain-name>
last_rule_review_commit: <git rev-parse HEAD before editing this file>
last_rule_updated_at: <YYYY-MM-DD>
---
# <domain-name>
## 목적 / 책임
< 도메인이 담당하는 책임을 1~2문장으로>
## 포함 경로
- `<path>/`< 경로가 도메인에 속하는 이유>
## 제외 경로
- `<path>/`< 도메인이 아닌지>
## 주요 구성 요소
- `<ClassName>`<역할>
## 유지할 패턴
- <네이밍 규칙 또는 아키텍처 패턴>
## 다른 도메인과의 경계
- **<인접 domain>**: <어디까지가 도메인이고 어디서부터 도메인인지>
## 금지 사항
- < 도메인 코드에서 하면 되는 >

View file

@ -0,0 +1,79 @@
---
test_env: <local|dev|qa|prod>
test_profile: <test-profile>
domain: <domain|project-wide>
verification_type: <smoke|unit|integration|e2e|model|migration|manual|full-cycle>
last_rule_updated_at: <YYYY-MM-DD>
---
# <test_profile> <test_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 파일에 기록하지 않는다.

View file

@ -0,0 +1,43 @@
---
test_env: <env>
last_rule_updated_at: <YYYY-MM-DD>
---
# <env> 테스트 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
## 공통 규칙
- <env> 테스트/검증은 이 파일을 기준으로 판단한다.
- 작업 완료 검증은 변경 범위 기준으로 선택한다.
- 필수 검증을 실행하지 못하면 차단 사유로 보고한다.
- 최종 보고에는 실행 명령, 결과, 생략 사유, 남은 위험을 남긴다.
- 환경값, secret, 개인 endpoint는 tracked docs/roadmap에 쓰지 않는다.
## 기본 환경
- 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`
## 라우팅 규칙
- 여러 항목이 맞으면 모두 읽는다.
- 도메인 매핑이나 domain rule이 있으면 각 도메인의 `<domain>-smoke` 문서를 기본 baseline으로 둔다.
- 도메인이 아직 없을 때만 `project-smoke`를 fallback baseline으로 둔다.
- 도메인/검증 시나리오별 문서는 다른 테스트 문서로 라우팅하지 않는다.

View file

@ -0,0 +1,98 @@
# Agent-Ops 철학
이 문서는 agent-ops 구조, 규칙, 스킬, 로드맵, 런타임 책임 경계를 설계하거나 수정할 때만 읽는다.
일반 구현 작업에서는 읽지 않는다.
## 핵심
- agent-ops는 AI agent가 작업하기 위한 규칙이자 가이드다.
- 사람 문서처럼 장황하게 설명하지 않고, agent가 바로 실행할 수 있게 작성한다.
- 필요한 컨텍스트만 읽게 만든다. 모든 문서를 항상 읽게 만들지 않는다.
- 애매한 형식을 만들지 않는다. 경로, 상태, id, 입력, 출력은 판별 가능해야 한다.
- 문서는 짧고 단단해야 한다. 길어서 이해되는 문서보다 짧아서 헷갈리지 않는 문서가 낫다.
## 문서 작성
- 규칙과 스킬은 핵심만 쓴다.
- 같은 말을 여러 문서에 반복하지 않는다. 한 곳에 두고 링크한다.
- 설명보다 조건, 입력, 행동, 금지 사항을 우선한다.
- "적절히", "필요하면", "가능하면" 같은 말은 판별 기준이 없으면 쓰지 않는다.
- 예외가 있으면 예외 조건을 같이 쓴다.
- 긴 배경 설명은 README나 별도 참조 문서로 보내고, 실행 문서에는 실행 규칙만 남긴다.
- 룰 문서는 협업자가 직접 읽는 계약 문서이므로 한국어 `한다`체로 작성한다.
- README, GUIDE, roadmap 문서는 사람이 함께 검토하는 협업 문서이므로 한국어 설명체 또는 존댓말을 사용할 수 있다.
- 스킬 문서는 실행 안정성을 우선한다. 한국어 또는 영어를 사용할 수 있고, 이미 잘 동작하는 절차 계약은 언어 통일만을 위해 수정하지 않는다.
- path, filename, 상태값, id, regex, command, frontmatter key, runtime protocol token은 원문 ASCII 식별자를 유지한다.
## 라우팅
- 라우팅은 얕아야 한다.
- 1홉은 진입 파일에서 공통/프로젝트 규칙을 읽는 단계다.
- 2홉은 규칙에서 domain rule, roadmap rule, router를 따라가는 단계다.
- 3홉은 router에서 SKILL.md를 읽는 단계다.
- 4홉은 skill이 템플릿이나 참조 문서를 추가로 읽는 단계다.
- 4홉 이상이 필요하면 구조가 과하게 쪼개졌는지 먼저 의심한다. 필요하면 앞 문서에 바로 가는 링크를 추가한다.
- 깊은 링크 체인을 만들지 않고, 필요한 문서가 무엇인지 앞 문서에서 바로 보이게 한다.
- 일반 작업마다 router, 모든 skill, 전체 roadmap, archive를 읽게 만들지 않는다.
## LLM과 런타임
- LLM은 의미 판단, 범위 판단, 요약, 설계 선택을 맡는다.
- 런타임은 파일명, 폴더명, 상태값, exit code처럼 결정적으로 판별 가능한 일을 맡는다.
- LLM 없이 처리할 수 있는 구간은 파일 규약으로 뺀다.
- 런타임 신호는 문서 본문보다 경로와 이름에 둔다.
- 런타임 신호를 만들 때는 agent가 본문을 읽지 않아도 판별 가능해야 한다.
- `m-<milestone-slug>` 같은 prefix는 런타임 판별을 위한 신호다.
- code-review는 PASS 산출물을 만들고 완료 이벤트 메타데이터를 남긴다.
- roadmap 반영 여부와 호출 타이밍은 런타임이 완료 이벤트를 보고 판단한다.
## 스킬 그룹 경계
- 스킬 그룹은 자기 라이프사이클 안에서만 강한 계약을 가진다.
- 스킬 그룹끼리는 다른 그룹의 내부 절차를 자동 호출하거나 전제하지 않는다.
- 그룹 간 연결은 사용자 명령, 런타임 이벤트, 또는 판별 가능한 파일 상태로만 한다.
- 구현 작업 그룹은 `plan``code-review`의 PLAN/CODE_REVIEW 루프를 소유한다.
- 로드맵 그룹은 `create-roadmap``update-roadmap`의 문서 작성, 의미 판단, 배치 제안, file-based fallback 갱신 흐름을 소유한다.
- 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`에 의존성 동기화 규칙을 넣지 않는다.
- 새 스킬을 만들기 전에 기존 그룹의 자연스러운 입력, 상태 전환, 후처리 지점에 넣을 수 있는지 먼저 본다. 다만 다른 그룹 경계를 침범해야 하면 런타임 이벤트로 분리한다.
## 로드맵
- roadmap은 장기 기억이고, agent-task는 실행 상태다.
- current는 현재 작업 하나가 아니라 브랜치별 로컬 활성 Phase/Milestone 후보 창이다.
- Phase와 Milestone은 큰 방향과 기능 단위를 담는다.
- 구현 계획은 agent-task의 PLAN/CODE_REVIEW 루프에 둔다.
- 완료 후보는 바로 archive하지 말고 `[검토중]`으로 둔다.
- archive는 일반 작업에서 읽지 않는다. 과거 근거가 필요할 때만 링크를 따라 읽는다.
## 스킬
- skill은 절차 문서다.
- skill 하나에 책임 하나만 둔다.
- skill이 다른 skill을 자동으로 깊게 호출하는 구조를 만들지 않는다.
- skill 본문은 실행에 필요한 규칙만 둔다.
- 템플릿은 출력 형식이 흔들릴 때만 둔다.
- 스킬 업데이트 시 router, rules, template, 출력 형식이 같은 계약을 말하는지 같이 확인한다.
- plan과 code-review처럼 짝 계약을 양쪽에서 반복해 강제하는 구조는 의도된 중복으로 본다. 동작 중인 짝 계약은 일관성 정리만을 위해 합치지 않는다.
## 좋은 구조
- 진입 파일은 최소 규칙만 둔다.
- common rules는 공통 시작점만 둔다.
- project rules는 프로젝트 특화 판단만 둔다.
- domain rules는 특정 코드 영역 규칙만 둔다.
- skills는 반복 작업 절차만 둔다.
- roadmap은 장기 목표와 기능 단위만 둔다.
- agent-task는 실행 중인 작업 상태와 완료 산출물만 둔다.
## 경고 신호
- 같은 내용을 세 군데 이상 설명하고 있다.
- 어떤 문서를 읽어야 할지 문서 안에서 다시 찾아야 한다.
- 상태값이 사람은 이해하지만 런타임은 판별하기 어렵다.
- skill이 너무 많은 예외를 품고 있다.
- README가 내부 규칙 문서처럼 길어지고 있다.
- archive를 일반 작업 컨텍스트로 끌어오고 있다.
- LLM이 파일명만 봐도 될 일을 본문까지 읽어 판단하고 있다.

View file

@ -0,0 +1,108 @@
# agent-spec 규칙
`agent-spec/`가 있는 프로젝트 또는 agent-spec 생성, 갱신, 마일스톤 종료 검토 요청에서 적용한다.
## 목적
`agent-spec/`는 사람과 AI agent가 현재 구현된 기능 목록, 동작 흐름, 계약 링크, 검증 방법을 함께 파악하기 위한 living spec 저장소다.
로드맵 완료 이력, SDD 설계 논의, 계약 원문, 사람용 가이드를 대체하지 않는다.
## 기본 구조
```text
agent-spec/
index.md
archive/
<area>/
<spec-id>.log
<area>/
<spec-id>.md
```
- `index.md`는 현재 스펙 목록과 읽기 라우팅 source of truth다.
- `<area>/<spec-id>.md`는 현재 구현 스펙 문서다.
- `archive/**`는 폐기되거나 대체된 과거 스펙 스냅샷이다.
- `<area>``<spec-id>`는 소문자 영문, 숫자, 하이픈만 사용한다.
## Source of Truth
- `agent-spec/**`는 현재 구현 지도를 제공하지만 최종 truth는 코드, `agent-contract/`, 테스트, 설정 예시다.
- API, wire protocol, runtime call, event/config schema, 프로세스 간 요청/응답 계약 원문은 `agent-contract/`에 두고 agent-spec에는 링크와 사용 맥락만 남긴다.
- 코드 배치, 주요 구성 요소, 구현 진입점, 도메인 간 책임 경계, 유지할 패턴, 금지 사항은 domain rule에 둔다.
- agent-spec에는 기능 이해에 필요한 최소 경계만 적고, 코딩할 때 따라야 하는 경계 규칙을 반복하지 않는다.
- SDD는 구현 전 설계 게이트다. agent-spec은 구현 후 현재 상태를 설명한다.
- 로드맵과 complete.log는 완료 근거와 변경 힌트로 사용한다. 현재 동작은 코드와 계약으로 재확인한다.
- 사람용 최신 가이드는 `docs/`에 둔다. agent-spec은 기능 파악과 작업 문맥을 우선한다.
## Frontmatter Schema
- 활성 Markdown 문서는 YAML frontmatter를 둔다.
- `spec_doc_type``index`, `spec`, `archive-log` 중 하나다.
- spec 문서는 `spec_id`, `status`, `source_evidence`를 둔다.
- 활성 spec 문서의 `status` 값은 `구현됨`, `부분`, `가정`, `불명확` 중 하나다.
- archive log의 `status` 값은 `폐기됨`을 사용할 수 있다.
- `구현됨`은 코드/계약/테스트 evidence로 현재 동작이 확인된 상태다.
- `부분`은 핵심 경로는 확인됐지만 일부 흐름, 설정, 검증, 한계가 남은 상태다.
- `가정`은 사용자 입력 또는 제한된 evidence를 바탕으로 임시 정리한 상태다.
- `불명확`은 코드와 계약 기준으로 현재 동작을 확정할 수 없는 상태다.
- `폐기됨`은 활성 spec 문서에 두지 않는다.
- `source_evidence`는 list이며 각 항목은 `type`, `path`, `notes`를 둔다.
- `source_evidence.type``code`, `contract`, `roadmap`, `sdd`, `test`, `docs`, `complete-log`, `user` 중 하나다.
- 실제 파일 근거가 없으면 `path: null`을 사용한다. placeholder 문자열을 현재 근거처럼 남기지 않는다.
## 읽기 규칙
- 일반 작업마다 `agent-spec/`를 읽지 않는다.
- 기존 기능의 기능 목록, 주요 흐름, 계약 링크, 현재 구현 상태가 필요한 작업에서만 세션 1회 `agent-spec/index.md`를 읽는다.
- `index.md`에서 매칭되는 spec 문서만 읽는다.
- 매칭 spec이 없으면 스펙이 없다고 보고하고 코드, 계약, 테스트에서 직접 확인한다. 추측으로 spec 내용을 만들지 않는다.
- spec 문서가 코드/계약과 충돌하면 코드/계약을 우선하고 `update-spec` 필요를 보고한다.
- 코드 배치, 구현 위치, 패턴, 금지 사항, 도메인 간 상세 책임 경계가 필요하면 프로젝트 규칙의 도메인 매핑에 따라 domain rule을 읽는다.
- API, wire protocol, runtime call, event/config schema, 프로세스 간 요청/응답 계약에 닿으면 `agent-contract/index.md`의 규칙에 따라 매칭 계약 문서도 읽는다.
- `agent-spec/archive/**`는 일반 작업에서 읽지 않는다.
- 예외: 사용자가 과거 스펙 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우에만 필요한 archive 문서만 좁게 읽는다.
## 생성/갱신 흐름
- agent-spec 최초 도입, 현재 구현 스펙 신규 작성, 전체 bootstrap 작성은 `create-spec`을 사용한다.
- 기존 spec을 코드/계약/테스트/완료 근거에 맞게 갱신하는 작업은 `update-spec`을 사용한다.
- 마일스톤 종료 검토에서는 `complete-milestone``update-spec`을 필수 gate로 실행한다.
- `agent-spec/`가 없으면 `complete-milestone`의 spec gate는 `skipped-no-agent-spec`으로 기록할 수 있다.
- `agent-spec/`가 있으면 `complete-milestone``Spec updated` 또는 `Spec update not needed`를 완료 리뷰에 남긴 뒤에만 Milestone 완료/archive를 진행한다.
- `Spec blocked` 또는 `create-spec needed`이면 Milestone 완료/archive를 진행하지 않는다.
- 새 스펙 작성이나 갱신은 현재 코드/계약/테스트 evidence를 우선하고, 완료된 roadmap archive는 사용자가 요청했거나 현재 스펙의 배경 확인이 꼭 필요한 경우에만 좁게 읽는다.
## 문서 작성 기준
- 현재형으로 작성한다.
- 과거 작업 일지, 설계 논쟁 전문, 완료된 roadmap task 전체 복사, 함수 단위 코드 설명을 넣지 않는다.
- 스펙 본문은 기능 단위의 작동 지도여야 한다. 먼저 기능 목록을 두고, 필요한 흐름만 뒤에 보강한다.
- 기능 목록은 `기능``설명` 중심으로 작성한다. 활성 spec은 구현된 기능만 기록하므로 기능별 `상태` 칼럼을 기본으로 두지 않는다.
- 기능별 부분 지원, 조건부 동작, 한계는 설명 또는 `한계와 주의사항`에 짧게 적는다.
- 주요 흐름은 텍스트만 길게 나열하지 말고 Mermaid `sequenceDiagram` 또는 `flowchart`를 우선 고려한다. 단순 기능은 짧은 목록으로 충분하다.
- 책임 경계는 기능 오해를 막는 최소 수준만 허용한다. 패키지 배치, 구현 진입점, 유지할 패턴, 금지 사항은 domain rule에 둔다.
- `코드 진입점` 섹션은 기본 섹션으로 두지 않는다. 필요한 코드 근거는 frontmatter `source_evidence`와 domain rule로 좁힌다.
- 계약 원문, proto field 전체 목록, config schema 원문을 복제하지 말고 `agent-contract/` 또는 코드 경로를 링크한다.
- 불확실한 내용은 단정하지 말고 `불명확` 또는 `확인 필요`로 남긴다.
- spec 갱신이 필요 없으면 `Spec update not needed: <사유>`를 결과 보고나 Milestone 완료 리뷰에 남긴다.
## 기본 섹션
spec 문서는 아래 섹션을 기본 순서로 작성한다. 해당 spec에 의미가 없는 섹션은 만들지 않는다.
1. `목적`
2. `기능 목록`
3. `범위`
4. `주요 흐름`
5. `계약`
6. `설정/데이터/이벤트`
7. `검증`
8. `한계와 주의사항`
9. `변경 기록`
`책임 경계`가 기능 이해에 꼭 필요하면 별도 섹션으로 짧게 둘 수 있다. 이때 domain rule의 구성 요소, 코드 배치, 금지 사항을 반복하지 않는다.
## 템플릿
- `index.md`: `agent-ops/skills/common/_templates/agent-spec/index-template.md`
- spec 문서: `agent-ops/skills/common/_templates/agent-spec/spec-template.md`

View file

@ -0,0 +1,161 @@
# agent-ui 규칙
`agent-ui/`가 있는 프로젝트 또는 agent-ui 생성, 갱신, 검증 요청에서 적용한다.
## 목적
`agent-ui/`는 AI agent와 사람이 UI 의도, 화면 구조, 와이어프레임, 반복 구성요소, 코드 반영 상태를 동기화하기 위한 작업 문맥 저장소다.
초기 기준은 ops/dev UI이며, product UI는 같은 구조 위에 brand, content, assets, tokens, motion 같은 레이어를 추가할 수 있다.
## 기본 구조
```text
agent-ui/
README.md
.sync-state.json # 선택: agent-ui -> code 동기화 기준점
USER_REVIEW.md # 선택: 사용자 판단이 필요한 활성 리뷰
archive/
user-review/
user_review_001.log
definition/
index.md
views/
index.md
<view-id>/
index.md
components/
index.md
<component-id>/
index.md
archive/
views/
<view-id>/
index.log
components/
<component-id>/
index.log
frame/
index.md
views/
<view-id>/
index.md # visual source가 있을 때만 생성
wire.excalidraw # 선택: 1차 visual source 후보
```
## Source of Truth
- `agent-ui/definition/**`은 현재 UI 정의의 source of truth다.
- `agent-ui/frame/**`은 와이어프레임과 visual source를 연결하는 보조 자료다.
- visual source가 없는 view는 `frame/views/<view-id>/`를 만들지 않는다. view 문서의 `frame``null`로 둔다.
- `.excalidraw` 파일만으로 현재 UI 기준을 확정하지 않는다. visual source가 있으면 반드시 대응되는 `frame/views/<view-id>/index.md`가 있어야 한다.
- `frame/views/<view-id>/index.md`는 대응되는 `definition/views/<view-id>/index.md`를 가리켜야 한다.
- 화면 의도, 상태, 액션, 정보 우선순위는 definition에 둔다.
- 배치, 밀도, 시각적 영역 관계는 frame에 둔다.
- 생성된 view/component는 코드, 문서, 사용자 입력 중 어떤 근거에서 왔는지 `Source Evidence`에 남긴다.
## Frontmatter Schema
- 활성 Markdown 문서는 YAML frontmatter를 둔다.
- `ui_doc_type``readme`, `definition-index`, `views-index`, `view`, `components-index`, `component`, `frame-index`, `frame-view`, `user-review`, `archive-log` 중 하나다.
- definition-index 문서는 `surface_type`, `source_evidence`를 둘 수 있다.
- view 문서는 `view_id`, `status`, `frame`, `source_evidence`를 둔다.
- component 문서는 `component_id`, `status`, `source_evidence`를 둔다.
- view 문서의 `frame`은 frame-view 문서가 있으면 경로, 없으면 `null`로 둔다.
- frame-view 문서는 visual source가 있을 때만 만들며 `view_id`, `definition`, `visual_source`, `regions`를 둔다.
- `source_evidence`는 list이며 각 항목은 `type`, `path`, `notes`를 둔다.
- `source_evidence.type``code`, `docs`, `user` 중 하나다.
- 실제 파일 근거가 없으면 `path: null`을 사용한다. placeholder 문자열을 현재 근거처럼 남기지 않는다.
- view에 visual source가 없으면 view 문서의 `frame``null`로 두고 frame-view 문서를 만들지 않는다.
- frame-view를 만들 때 `visual_source`는 실제 존재하는 visual source 경로여야 한다. 없는 `wire.excalidraw`를 기본 근거처럼 쓰지 않는다.
- `status` 값은 `구현됨`, `계획`, `가정`, `불명확` 중 하나다.
- `구현됨`은 코드 반영 완료 상태다. 코드 근거가 있으면 존재하는 `code` evidence path를 함께 둔다.
- `계획`은 정합화된 UI 정의지만 아직 코드 반영 전이거나 사용자 확인 후 재작업 대상인 상태다.
- `가정`은 사용자 입력 또는 추정만 있고 확정 근거가 부족한 상태다.
- `불명확`은 근거가 부족하거나 판단할 수 없는 상태다.
- `가정``불명확`은 코드 동기화 대상이 아니며, sync 전에 `agent-ui/USER_REVIEW.md`로 분리한다.
- frontmatter의 `status`, `source_evidence`, `regions`와 본문 `Status`, `Source Evidence`, `Regions`는 같은 기준을 말해야 한다.
- frontmatter는 기계적 검증을 위한 최소 schema이고, 본문 Markdown은 사람과 agent가 읽는 설명을 유지한다.
## 운영 동기화 흐름
- 초기 생성 이후 기본 방향은 `agent-ui -> code` 단방향이다. 코드에서 agent-ui를 만드는 흐름은 `create-agent-ui` 최초 생성에만 사용한다.
- 화면정의서, view, component, frame, wireframe을 agent로 수정하는 요청은 `update-agent-ui`로 처리한다.
- 사용자 리뷰 결정 반영, `UIR-NNN` 해결, "화면정의서와 코드가 안 맞아" 같은 회귀 요청도 `update-agent-ui` 또는 `validate-agent-ui`로 들어와 같은 루프를 재개한다.
- `update-agent-ui`는 agent-ui 문서 갱신을 맡는다. 코드 구현 규모 판정, plan 라우팅, roadmap/milestone 라우팅은 하지 않는다.
- `update-agent-ui` 후에는 변경 범위에 따라 `validate-agent-ui` 필요 여부와 code sync intent 전달 여부만 판단한다. 실행한다면 `validate-agent-ui`가 항상 `sync-agent-ui`보다 먼저 실행된다.
- `validate-agent-ui`는 agent-ui 내부 문서 그래프를 정합화한다. definition, frame, visual source, component, archive, USER_REVIEW 사이의 누락과 충돌을 같은 수준으로 맞춘다.
- 운영 단계의 `validate-agent-ui`는 코드 후보만 보고 새 view/component를 자동 생성하지 않는다. 코드와 agent-ui가 어긋나면 agent-ui 기준 sync 대상, status 회귀, 또는 USER_REVIEW로 분리한다.
- `sync-agent-ui`는 정합화된 agent-ui 변경분을 코드에 반영하기 전에 코드 작업 규모를 판정한다. 작은 코드 작업은 직접 반영하고, 중간 코드 작업은 `plan` 루프로, Milestone이 필요한 큰 코드 작업은 `update-roadmap`의 Milestone/Epic/Task 갱신으로 넘긴다.
- `sync-agent-ui`의 기본 모드는 `.sync-state.json` 기준 이후 변경분만 동기화한다.
- 사용자가 "agent-ui와 코드 전체 동기화"처럼 전체 동기화를 명시한 경우에만 현재 agent-ui 전체를 코드와 대조한다.
- `update-agent-ui` 또는 수동 `validate-agent-ui`가 코드 반영 필요성을 판단했으면 그 판단을 다음 단계로 전달한다. 전달된 판단이 있으면 뒤 단계는 문서 정합성과 sync intent 자체를 재판단하지 않지만, `sync-agent-ui`는 실제 코드 반영 방식 판정을 수행한다.
- 직접 sync가 검증되면 반영된 view/component의 `status``구현됨`으로 바꾼다.
- `sync-agent-ui`가 코드 작업을 `plan-required`로 라우팅한 경우에는 plan이 `Agent UI Completion`을 남기고, code-review PASS 시점에 해당 view/component/frame만 `구현됨`으로 반영한다. 이 경로에서는 `sync-agent-ui`가 status를 직접 변경하지 않는다.
- `sync-agent-ui`가 코드 작업을 `milestone-required`로 라우팅해 `agent-ui 상태 반영: 대기`를 남긴 Milestone만 종료 검토 통과 시 `구현됨` 반영 gate가 된다. 최종 검증과 code evidence가 확인된 view/component/frame만 반영하며, Milestone 완료만으로 agent-ui 전체 status를 일괄 변경하지 않는다.
- 사용자 확인 또는 후속 검증에서 불일치가 발견되면 해당 항목은 `계획`으로 되돌릴 수 있다.
- `sync-agent-ui`가 검증 실패, 환경 차단, 구현 방향 충돌, 반복 실패를 스스로 해결하지 못하면 commit/push하지 않고 `agent-ui/USER_REVIEW.md`에 게이트를 남긴다.
- 실패한 `sync-agent-ui`가 남긴 작업트리 변경은 사용자 결정과 충돌하지 않으면 보존하고, USER_REVIEW 해결 후 같은 변경을 이어서 재검증할 수 있다.
## Sync State
- `agent-ui/.sync-state.json`은 agent-ui 변경분을 코드에 반영한 기준점이다.
- `create-agent-ui`는 생성 결과를 최초 baseline으로 보고 `.sync-state.json`을 만든다.
- 기존 방식으로 생성되어 `.sync-state.json`이 없는 agent-ui는 legacy 상태다. 이 경우 기본 변경분 sync를 시작하지 말고 validate 후 baseline migration으로 기준점을 먼저 만든다.
- baseline은 `code-first`, `concept-first`, `blank` 모두에서 생성된 agent-ui 기준선을 뜻한다. `concept-first` baseline은 코드 구현 완료가 아니라 agent-ui 기준선 확정이다.
- `last_synced_head`는 agent-ui 변경분과 코드 반영이 들어간 sync 결과 commit hash다. `.sync-state.json` 자체를 기록한 commit hash가 아니다.
- baseline 또는 sync 완료 시 commit은 두 단계로 남길 수 있다. 먼저 agent-ui/code 변경 commit을 만들고, 그 commit hash를 `.sync-state.json`에 기록한 별도 commit을 만든 뒤 push한다.
- 변경분 판정에서는 `.sync-state.json` 자체 변경을 제외한다.
## 명명 규칙
- view id, component id, 파일명, 디렉터리명은 kebab-case를 사용한다.
- view 기준 문서는 `definition/views/<view-id>/index.md`에 둔다.
- component 기준 문서는 `definition/components/<component-id>/index.md`에 둔다.
- 같은 레벨에서 `<name>.md``<name>/`를 함께 두지 않는다.
- 하위 정의가 필요하면 `<name>/index.md``<name>/<child>.md`를 사용한다.
## ID 규칙
- region id는 `<view-id>.<region>` 형식을 사용한다.
- 하위 region은 `<view-id>.<region>.<subregion>` 형식을 사용할 수 있다.
- component id는 `definition/components/` 아래 경로에서 `index.md`를 제외한 path id로 본다. 예: `data-table`, `data-table/job-list`.
- frame-view가 있으면 view 정의서의 region id와 frame 정의서의 region id는 동일해야 한다.
- view에서 참조한 component id는 대응되는 component 정의 문서가 있어야 한다.
- frame-view가 있으면 frame-view frontmatter의 `regions`와 view 본문의 region id는 같은 집합이어야 한다. 단, 차이가 제품 판단을 요구하면 USER_REVIEW로 남긴다.
## Archive 접근
- `agent-ui/definition/archive/**`는 일반 작업에서 읽지 않는다.
- `agent-ui/archive/user-review/**`는 일반 작업에서 읽지 않는다.
- 예외: 사용자가 과거 결정 확인, 복원, 비교, 특정 archive 경로 확인, 해결된 user review 확인을 요청한 경우에만 필요한 파일을 좁게 읽는다.
- validate 작업은 archive 경로 존재 여부와 tree 대응 여부를 확인할 수 있지만, 위 예외가 없으면 archive 본문을 읽지 않는다.
## USER_REVIEW
- agent가 확정할 수 없는 UI 의도, 화면 구조, region 추가/삭제, component 신규 생성 여부, page/drawer/split 같은 UX 결정은 `agent-ui/USER_REVIEW.md`에 남긴다.
- `agent-ui/USER_REVIEW.md``update-agent-ui`, `validate-agent-ui`, `sync-agent-ui`의 통합 gate다.
- 항목에는 어느 단계에서 막혔는지 알 수 있게 `Source Skill`, `Stage`, `Blocking Step`, `Context`, `Options`, `Needed For`를 남긴다.
- 현재 동기화 범위에 미해결 USER_REVIEW 항목이 있으면 `sync-agent-ui`는 실행하지 않는다.
- 해결된 user review는 `agent-ui/archive/user-review/user_review_N.log`로 이동할 수 있다.
- USER_REVIEW 해결 요청은 관련 결정을 agent-ui 활성 문서에 반영한 뒤, 해당 항목을 archive log로 이동하고, 필요하면 `validate-agent-ui``sync-agent-ui`를 순서대로 재개한다.
- `USER_REVIEW.md`가 있으면 관련 agent-ui 갱신이나 검증 결과에 남은 review id를 보고한다.
## Excalidraw
- 1차 visual source 후보는 `wire.excalidraw`다.
- VS Code Excalidraw extension은 초기 편집 워크플로우로 사용할 수 있다.
- excalidraw.com import/export 워크플로우는 기본 표준으로 삼지 않는다.
- Excalidraw self-host는 R&D 후보이며, 기본 agent-ui scaffold의 필수 조건이 아니다.
- `.excalidraw`는 JSON으로 다룬다. 검증 시 가능하면 JSON parser로 `elements`의 text label 또는 `customData.region_id`를 확인한다.
- visual source에 region label이 있으면 `frame-view.regions``definition` region id의 집합과 비교한다.
- visual source가 있는데 region label이 없으면 frame과 definition의 연결 근거가 부족한 상태로 본다.
- visual source에 정의되지 않은 region label이 있거나 필수 region label이 없으면 자동으로 UI 의도를 확정하지 않고 USER_REVIEW로 남긴다.
## 스킬
- agent-ui 초기 scaffold 생성은 `create-agent-ui`를 사용한다.
- 화면정의서, view, component, frame, wireframe 갱신은 `update-agent-ui`를 사용한다.
- 구조와 정합성 검사, 문서 간 자동 보정, USER_REVIEW 생성은 `validate-agent-ui`를 사용한다.
- 정합화된 agent-ui 변경분을 코드에 반영할 때는 `sync-agent-ui`를 사용한다.

View file

@ -0,0 +1,205 @@
# 로드맵 규칙
`agent-roadmap/` 디렉터리가 있는 프로젝트에서만 적용한다.
## 구조
- 최상위 로드맵은 `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로 넘길 수 있는 입력과 결과를 함께 남긴다.
## 로딩
- 세션 최초 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 문서만 읽는다.
## Phase와 Milestone 선택
- `current.md`는 현재 작업 위치가 아니라 활성 Phase와 활성 Milestone 후보 목록이다.
- `priority-queue.md`는 현재 작업 위치가 아니라 Phase를 가로지르는 실행 순서 문서다. 위에 있는 항목을 먼저 검토한다.
- `priority-queue.md`는 순서 전용 문서이며, Milestone 제목 링크와 식별용 한 줄 설명만 둔다. 상태, 목표, 범위, 잠금, 기능, 완료 근거, 의존성은 Milestone 문서를 원본으로 삼는다.
- `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`로 분리한다.
## 상태 표기
- 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를 가로지르는 실행 순서로 해석하지 않는다.
## 구현 잠금
- `구현 잠금`은 승인 의식이 아니라 에이전트가 확정할 수 없는 결정이 필요한지 표시하는 얇은 상태다.
- 제품 방향, 범위, 우선순위, 책임 경계처럼 에이전트가 확정할 수 없는 항목이 남아 있으면 상태를 `잠금`으로 두고 `결정 필요` 목록에 남긴다.
- 기존 구조, 도메인 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은 `구현 잠금``해제`로 보이더라도 구현 계획과 코드 구현 대상이 아니다. 먼저 `[계획]`으로 승격해야 한다.
## 프로젝트 간 잠금
- 프로젝트 상위 `.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 게이트
- 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`로 분리한다.
## Epic과 Task id
- 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는 명시적 요청 없이 바꾸지 않는다.
## 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의 user-review gate가 트리거되면 연결된 Milestone 잠금 결정을 `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 후보를 여럿 가리키면 모두 `현재 후보`로 표시하고 짧은 역할 태그만 붙인다.
## 아카이브
- 완료 또는 폐기되어 현재 작업 후보에서 제외할 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 선택이나 위치 분석의 후보로 삼지 않는다.
- 아카이브 문서는 과거 기록 스냅샷으로 보고, 최신 템플릿이나 스킬 규약에 맞춰 재포맷하지 않는다.

View file

@ -0,0 +1,55 @@
# 공통 규칙
**현재 문서를 반드시 끝까지 정독하고 작업한다. 다 읽지 않고 즉각 작업은 금지한다.**
- 기존 구조를 우선한다. 새 파일 생성보다 기존 파일 수정을 우선한다.
- 사용자에게 보이는 최종 답변과 설명은 기본적으로 한국어로 작성한다.
- 코드 변경 전 관련 domain rule을 먼저 확인한다.
- 요청 범위를 넘는 변경을 하지 않는다.
- 불확실하면 단정하지 말고 후보를 제시한다.
- `agent-task/archive/**`는 일반 작업에서 읽지 않는다. 예외: 사용자가 과거 작업 확인, 복원, 비교, 특정 archive 경로 확인을 요청한 경우, active `PLAN-*.md` / `CODE_REVIEW-*.md` / `USER_REVIEW.md`가 특정 archive evidence 경로를 명시한 경우, 또는 plan/code-review 루프의 split subtask 선행 의존성 충족 여부를 확인하는 경우에만 필요한 파일을 좁게 읽는다. split 의존성 확인은 같은 task group의 후보 `complete.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/`는 사람용 최신 가이드와 공개 설명만 둔다.
- 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`
# 프로젝트 간 잠금
- "이 Milestone은 X가 끝나야 가능하다", "A 전까지 B를 잠근다", "잠금 해제 조건은 X다", "현재 마일스톤은 X 프로젝트 작업 뒤에 진행되어야 한다", "의존성 설정해"는 `update-roadmap`으로 처리한다.
# 스킬 규칙
**아래 경우에 부합되는지 반드시 끝까지 정독해서 읽고, 부합할 경우 `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 생성
- 코드 리뷰 / review 진행
- git commit / push
- agent-ops 업데이트 / 진입 파일 재적용
# 테스트 규칙
**테스트 실행/검증 작업이 포함된 경우, 작업 환경에 맞게 최초 1회 읽고 수행한다. 환경 미지정은 local로 본다.**
- local: `agent-test/local/rules.md` (없으면 `create-test`)
- dev-corp: `agent-test/dev-corp/rules.md`

View file

@ -0,0 +1,51 @@
---
domain: control-plane
last_rule_review_commit: null
last_rule_updated_at: 2026-07-18
---
# control-plane
## 목적 / 책임
RARA의 핵심 수명주기 상태를 소유한다. 프로젝트, knowledge base, dataset, artifact lineage, workflow, evaluation, release, schedule의 관리와 명시적 승격·롤백 경계를 정의한다.
## 포함 경로
- `apps/control-plane/` — 제어 플레인 프로세스 조립과 실행 진입점
- `apps/client/` — 향후 제어 플레인 운영 UI를 위한 예약 경로
- `packages/go/controlplane/` — 수명주기 관리 HTTP handler
- `db/migrations/` — 제어 상태와 lineage의 PostgreSQL 스키마 원본
- `db/queries/` — 제어 상태를 다루는 sqlc 쿼리 원본
## 제외 경로
- `packages/go/rag/` — 게시된 release를 소비하는 온라인 RAG 데이터 플레인
- `packages/go/workflow/`, `packages/python/` — 제어 플레인이 만든 작업을 실행하는 worker
- `packages/go/database/dbgen/` — sqlc가 생성하는 공통 persistence adapter
## 주요 구성 요소
- `controlplane.Register` — 제어 플레인 HTTP route 등록
- `db/migrations/00001_initial.sql` — 프로젝트·knowledge·workflow·release·trace 등 제어 상태 스키마
- `db/queries/*.sql` — sqlc 입력이 되는 상태 조회·변경 쿼리
## 유지할 패턴
- release promotion은 명시적으로 수행하고 production index는 불변 artifact로 취급한다.
- 후보 artifact를 만든 뒤 승격하며 source 삭제와 ACL 변경을 lineage로 추적한다.
- 스키마와 쿼리를 변경한 뒤 `make sqlc`로 Go adapter를 재생성한다.
- integration 설정에는 secret 원문 대신 secret reference만 저장한다.
## 다른 도메인과의 경계
- **rag-data-plane**: control-plane은 release와 policy를 게시하고, rag-data-plane은 해당 식별자와 정책을 해석해 온라인 요청을 처리한다.
- **workflow-execution**: control-plane은 workflow/job 상태를 소유하고, worker는 lease된 step의 실행과 결과 보고를 담당한다.
- **platform-common**: 데이터베이스 연결과 공통 HTTP/관측성 구현은 platform-common adapter를 사용한다.
## 금지 사항
- PostgreSQL을 기본 retrieval backend나 대형 artifact 저장소로 사용하지 않는다.
- 생성된 `packages/go/database/dbgen/` 파일을 직접 수정하지 않는다.
- 특정 retrieval, model, artifact 제품을 수명주기 모델에 하드코딩하지 않는다.

View file

@ -0,0 +1,56 @@
---
domain: platform-common
last_rule_review_commit: null
last_rule_updated_at: 2026-07-18
---
# platform-common
## 목적 / 책임
각 plane이 공유하는 설정, PostgreSQL 연결, HTTP lifecycle, 관측성, artifact 저장, 외부 integration port를 제공한다. 도메인 로직이 특정 인프라 제품에 결합되지 않도록 adapter 경계를 유지한다.
## 포함 경로
- `packages/go/artifact/` — 교체 가능한 artifact store 계약과 filesystem 구현
- `packages/go/config/` — 서비스별 YAML 설정 로딩과 검증
- `packages/go/database/` — pgx 연결 lifecycle과 sqlc 생성 adapter
- `packages/go/httpserver/` — 공통 health/readiness와 HTTP server lifecycle
- `packages/go/integration/` — source, retrieval, embedding, reranking, generation, secret의 product-neutral port
- `packages/go/observability/` — logging, metrics, tracing 조립
- `configs/`, `deploy/` — 로컬 설정 예시와 배포 자산
## 제외 경로
- `packages/go/controlplane/`, `db/` — 수명주기 상태 모델과 쿼리 원본
- `packages/go/rag/` — 온라인 RAG 요청 의미와 응답 계약
- `packages/go/workflow/`, `packages/python/` — workflow와 adaptation 실행 의미
## 주요 구성 요소
- `database.Store` — pgx pool과 생성된 sqlc query 접근점
- `artifact.Store` / `artifact.Filesystem` — artifact 저장 port와 로컬 구현
- `integration.Ports` — 외부 capability의 제품 중립 계약
- `httpserver.Start` — 공통 HTTP lifecycle
- `observability.SetupTracing` — trace exporter 설정
## 유지할 패턴
- 공통 패키지는 plane별 정책을 소유하지 않고 작은 port와 lifecycle adapter에 집중한다.
- integration instance는 versioned capability와 secret reference로 구성한다.
- artifact URI와 content hash를 유지해 lineage를 추적할 수 있게 한다.
- readiness는 실제 필수 dependency 상태를 반영하고 health와 구분한다.
- 설정 예시에는 로컬 기본값만 두며 운영 secret을 포함하지 않는다.
## 다른 도메인과의 경계
- **control-plane**: 공통 persistence adapter를 제공하되 스키마와 수명주기 규칙은 control-plane이 소유한다.
- **rag-data-plane**: retrieval/generation port를 제공하되 release 해석과 응답 의미는 rag-data-plane이 소유한다.
- **workflow-execution**: config, database, artifact adapter를 제공하되 lease와 executor 상태 전이는 workflow-execution이 소유한다.
## 금지 사항
- 공통 패키지에 control-plane, RAG, workflow의 유즈케이스 정책을 넣지 않는다.
- integration port를 특정 vendor의 request/response 타입으로 노출하지 않는다.
- config, log, trace, 예제 배포 파일에 secret이나 credential 원문을 남기지 않는다.

View file

@ -0,0 +1,50 @@
---
domain: rag-data-plane
last_rule_review_commit: null
last_rule_updated_at: 2026-07-18
---
# rag-data-plane
## 목적 / 책임
게시된 release를 기준으로 온라인 retrieve와 answer 요청을 처리한다. evidence, release identity, trace identity와 JSON/SSE 응답 계약의 일관성을 책임진다.
## 포함 경로
- `apps/rag-api/` — 온라인 RAG API 프로세스 조립과 실행 진입점
- `packages/go/rag/` — release 해석, 요청 검증, retrieve/answer handler와 engine port
- `api/openapi/` — 공개 HTTP/JSON 및 SSE 계약 원본
## 제외 경로
- `packages/go/controlplane/`, `db/migrations/` — release를 생성·승격하는 제어 플레인
- `packages/go/integration/` — retrieval과 generation 공급자를 추상화하는 공통 port
- `packages/go/workflow/`, `packages/python/` — 비동기 workflow와 adaptation 실행
## 주요 구성 요소
- `rag.Handler``/v1/retrieve`, `/v1/answer` 요청 검증과 응답 변환
- `rag.ReleaseResolver` — project, knowledge base, alias로 활성 release 해석
- `rag.Engine` — retrieval과 generation 구현을 교체하기 위한 도메인 port
- `api/openapi/rara-v1.yaml` — 공개 요청·응답 및 오류 스키마
## 유지할 패턴
- 모든 온라인 요청은 knowledge base와 release alias를 해석하고 응답에 release identity를 포함한다.
- release alias가 없으면 `production`, `top_k`가 없으면 10을 사용하며 검증 범위는 OpenAPI와 handler가 일치해야 한다.
- engine 구현은 capability-aware integration 뒤에 두고 handler가 특정 제품 SDK에 의존하지 않게 한다.
- streaming 응답은 SSE event와 오류 의미를 비 streaming JSON 응답과 호환되게 유지한다.
## 다른 도메인과의 경계
- **control-plane**: release의 생성·승격·롤백은 control-plane 책임이며 이 도메인은 활성 release를 읽기만 한다.
- **workflow-execution**: index 작성·평가 같은 비동기 단계는 workflow에서 실행하고 이 도메인은 승격된 결과만 제공한다.
- **platform-common**: database, HTTP server, observability와 공급자 port는 공통 adapter를 사용한다.
## 금지 사항
- 요청 시점에 candidate release를 암묵적으로 production으로 승격하지 않는다.
- handler에 특정 vector store, reranker, model provider를 직접 결합하지 않는다.
- 공개 handler 변경 시 OpenAPI와 JSON/SSE 오류 계약 검토를 생략하지 않는다.

View file

@ -0,0 +1,52 @@
---
domain: workflow-execution
last_rule_review_commit: null
last_rule_updated_at: 2026-07-18
---
# workflow-execution
## 목적 / 책임
제어 플레인이 만든 workflow step을 lease하고 실행 상태를 보고한다. Go executor와 Python adaptation executor 사이의 버전 있는 실행 계약 및 취소·진행·결과 의미를 책임진다.
## 포함 경로
- `apps/worker/` — Go workflow worker 프로세스 조립과 실행 진입점
- `packages/go/workflow/` — step lease, executor registry, 재시도와 상태 전이
- `packages/python/` — Python gRPC executor와 adaptation 실행 구현
- `api/proto/` — Go/Python executor wire contract 원본
- `gen/go/rara/v1/` — Protobuf에서 생성된 Go 타입과 gRPC stub
## 제외 경로
- `packages/go/controlplane/`, `db/migrations/` — workflow 정의와 영속 상태의 소유권
- `packages/go/rag/` — 온라인 retrieve/answer 요청 처리
- `packages/go/integration/` — 제품 중립적인 외부 capability port
## 주요 구성 요소
- `workflow.Worker` — 실행 가능한 step을 lease하고 executor 결과에 따라 상태 갱신
- `workflow.Registry` — operation 이름과 Go executor 구현 연결
- `ExecutorService` — Python capability 조회, streaming 실행, 취소 gRPC 서비스
- `api/proto/rara/v1/executor.proto` — job, progress, artifact, error 계약
## 유지할 패턴
- worker identity, lease duration, retry delay를 설정에서 읽고 lease 소유권과 재시도 의미를 보존한다.
- executor operation과 capability는 명시적 이름과 버전으로 등록한다.
- ML 라이브러리 실행과 LoRA/QLoRA adaptation은 Python executor가 담당하고 제어 상태는 PostgreSQL이 소유한다.
- Protobuf 변경은 기존 field number를 재사용하지 않고 Go/Python 생성물을 `make proto`로 함께 갱신한다.
## 다른 도메인과의 경계
- **control-plane**: workflow와 job의 영속 상태는 control-plane 소유이며 이 도메인은 lease된 실행과 결과만 처리한다.
- **rag-data-plane**: 온라인 요청 경로를 worker에서 처리하지 않고, workflow가 만든 artifact를 release 승격 뒤 소비하게 한다.
- **platform-common**: database, config, observability, artifact와 integration port는 공통 adapter에 위임한다.
## 금지 사항
- `gen/go/rara/v1/``packages/python/src/rara/v1/*_pb2*.py`를 직접 수정하지 않는다.
- lease 없이 step을 실행하거나 다른 worker 소유의 step 상태를 완료 처리하지 않는다.
- secret 원문이나 제품별 credential을 job payload와 추적 문서에 기록하지 않는다.

View file

@ -0,0 +1,67 @@
# RARA 프로젝트 규칙
## 응답 언어
- 사용자에게 보이는 답변과 프로젝트 문서는 기본적으로 한국어로 작성한다.
- 코드 식별자, 공개 API 필드, 프로토콜 이름은 기존 영문 표기를 유지한다.
## 프로젝트 개요
- RARA는 저장소와 모델 제품에 종속되지 않도록 설계된 내부 RAG 수명주기 플랫폼이다.
- 제어 플레인, 온라인 RAG 데이터 플레인, Go/Python 실행기를 한 저장소에서 운영한다.
- 현재 코드는 플랫폼 스캐폴드 단계이며, 실제 검색 백엔드·모델 공급자·소스 커넥터는 버전이 있는 integration으로 확장한다.
## 주요 구조
| 경로 | 역할 |
|------|------|
| `apps/` | control-plane, rag-api, Go worker 실행 진입점과 향후 운영 UI |
| `packages/go/` | Go 도메인 로직, 포트, 공통 런타임 어댑터 |
| `packages/python/` | Python adaptation executor와 생성된 Protobuf 클라이언트 |
| `api/openapi/` | 공개 HTTP/JSON 및 SSE 계약 |
| `api/proto/` | Go/Python executor 간 내부 gRPC 계약 |
| `db/` | PostgreSQL 스키마와 sqlc 쿼리 원본 |
| `gen/` | Protobuf에서 생성된 Go 코드 |
| `configs/`, `deploy/` | 서비스 설정 예시와 로컬 배포 자산 |
## 기술 스택
- Go 1.26, Cobra, Fx, pgx, sqlc
- Python 3.12, gRPC, pytest, Ruff
- PostgreSQL 18
- OpenAPI 3.1, Protobuf/gRPC, HTTP/JSON, SSE
- Make 기반 생성·검증·빌드 흐름
## 프로젝트 특화 컨벤션
- PostgreSQL은 제어 상태와 lineage만 저장한다. 대형 artifact와 retrieval index를 PostgreSQL에 결합하지 않는다.
- 외부 저장소·검색·모델·secret 기능은 `packages/go/integration`의 product-neutral port 뒤에 둔다.
- `api/proto/``db/migrations/`, `db/queries/`를 생성 코드의 원본으로 취급한다.
- `gen/go/`, `packages/python/src/rara/v1/*_pb2*.py`, `packages/go/database/dbgen/`은 직접 수정하지 않고 `make proto` 또는 `make sqlc`로 갱신한다.
- 공개 RAG handler를 변경할 때는 `api/openapi/rara-v1.yaml`과 요청·응답·SSE 동작을 함께 검토한다.
- executor wire contract를 변경할 때는 Protobuf 호환성을 유지하고 Go/Python 생성물을 함께 갱신한다.
- 기본 검증 진입점은 `make test``make build`이며, CI는 sqlc diff, Go 테스트, Ruff, Python 테스트, 서비스 빌드를 수행한다.
## 도메인 매핑
| 경로 패턴 | 도메인 | rules.md |
|----------|--------|----------|
| `apps/control-plane/**` | control-plane | `agent-ops/rules/project/domain/control-plane/rules.md` |
| `apps/client/**` | control-plane | `agent-ops/rules/project/domain/control-plane/rules.md` |
| `packages/go/controlplane/**` | control-plane | `agent-ops/rules/project/domain/control-plane/rules.md` |
| `db/migrations/**`, `db/queries/**` | control-plane | `agent-ops/rules/project/domain/control-plane/rules.md` |
| `apps/rag-api/**` | rag-data-plane | `agent-ops/rules/project/domain/rag-data-plane/rules.md` |
| `packages/go/rag/**` | rag-data-plane | `agent-ops/rules/project/domain/rag-data-plane/rules.md` |
| `api/openapi/**` | rag-data-plane | `agent-ops/rules/project/domain/rag-data-plane/rules.md` |
| `apps/worker/**` | workflow-execution | `agent-ops/rules/project/domain/workflow-execution/rules.md` |
| `packages/go/workflow/**` | workflow-execution | `agent-ops/rules/project/domain/workflow-execution/rules.md` |
| `packages/python/**` | workflow-execution | `agent-ops/rules/project/domain/workflow-execution/rules.md` |
| `api/proto/**`, `gen/go/rara/v1/**` | workflow-execution | `agent-ops/rules/project/domain/workflow-execution/rules.md` |
| `packages/go/artifact/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `packages/go/config/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `packages/go/database/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `packages/go/httpserver/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `packages/go/integration/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `packages/go/observability/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |
| `configs/**`, `deploy/**` | platform-common | `agent-ops/rules/project/domain/platform-common/rules.md` |

View file

@ -0,0 +1,33 @@
---
spec_doc_type: index
status: 활성
---
# 구현 스펙 색인
## 목적
이 디렉터리는 사람과 agent가 함께 보는 현재 구현 기능 living spec을 관리한다.
로드맵 완료 이력, SDD, 계약 원문, 사람용 docs를 대체하지 않는다.
## 읽기 규칙
- 필요한 작업에서만 이 index를 읽고, 매칭되는 spec 문서만 읽는다.
- `archive/**`는 과거 비교, 복원, 특정 근거 확인 요청이 있을 때만 읽는다.
- API, wire protocol, config/event schema, 프로세스 간 계약 원문은 `agent-contract/`를 따른다.
- 코드 배치, 구현 진입점, 도메인 간 상세 책임 경계는 domain rule을 따른다.
## Spec Map
| id | 상태 | 언제 읽나 | path | 주요 근거 |
|----|------|-----------|------|-----------|
| 없음 | 없음 | 없음 | 없음 | 없음 |
## 작성 규칙
- 현재 구현 기준으로 작성한다.
- 기능 목록과 주요 흐름을 먼저 파악할 수 있게 작성한다.
- 코드/계약/테스트 evidence를 우선한다.
- 계약 원문은 복제하지 않고 링크한다.
- 코드 진입점과 도메인룰 성격의 상세 경계는 반복하지 않는다.
- 불확실한 내용은 `불명확`으로 남긴다.

View file

@ -0,0 +1,55 @@
---
spec_doc_type: spec
spec_id: <area>/<spec-id>
status: 불명확
source_evidence:
- type: code
path: null
notes: <현재 구현 근거>
---
# 스펙: <title>
## 목적
< spec이 설명하는 현재 구현 기능과 문서를 읽어야 하는 이유>
## 기능 목록
| 기능 | 설명 |
|------|------|
| <기능명> | <현재 코드와 계약으로 확인된 동작> |
## 범위
- 포함: <현재 spec이 다루는 범위>
- 제외: <다른 spec, roadmap, SDD, contract, docs로 넘기는 범위>
## 주요 흐름
```mermaid
sequenceDiagram
participant A as <주체>
participant B as <주체>
A->>B: <주요 메시지 또는 동작>
```
## 계약
- <관련 agent-contract 문서 또는 코드 계약 포인터>
## 설정/데이터/이벤트
- <관련 config, 저장소, event, runtime state 요약. 원문 schema는 복제하지 않는다.>
## 검증
- `<command or profile>` - <기대 결과>
## 한계와 주의사항
- <현재 구현 한계 또는 조건부 동작>
## 변경 기록
- <YYYY-MM-DD>: <생성/갱신 근거>

View file

@ -0,0 +1,20 @@
---
ui_doc_type: archive-log
target: <target>
---
# <target> log
## <YYYY-MM-DD>
### Changed
- <변경 또는 폐기된 정의>
### Reason
- <변경 이유>
### Superseded
- <대체된 이전 기준 또는 없음>

View file

@ -0,0 +1,61 @@
---
ui_doc_type: component
component_id: <component-id>
status: <구현됨|계획|가정|불명확>
source_evidence:
- type: code
path: null
notes: <구현 근거. 없으면 없음>
- type: docs
path: null
notes: <컨셉/계획 근거. 없으면 없음>
- type: user
path: null
notes: <사용자 명시 입력. 없으면 없음>
---
# <Component Name>
Component ID: `<component-id>`
Status: `<구현됨|계획|가정|불명확>`
## Source Evidence
| Type | Path | Notes |
|------|------|-------|
| code | 없음 | <구현 근거. 없으면 `없음`> |
| docs | 없음 | <컨셉/계획 근거. 없으면 `없음`> |
| user | 없음 | <사용자 명시 입력. 없으면 `없음`> |
## Purpose
< component가 해결하는 UI 문제를 적는다.>
## Used By
- `<view-id>`: <사용 위치 또는 region id>
## Anatomy
- <구성 부분>
## Variants
- default: <기본 사용>
## States
- default
- loading
- empty
- error
- disabled
## Rules
- <사용 규칙>
## Decision History
- <YYYY-MM-DD>: <현재 기준으로 남길 결정 요약>

View file

@ -0,0 +1,18 @@
---
ui_doc_type: components-index
components: []
---
# Component Definitions
## Component List
| Component ID | Status | Evidence | Description |
|--------------|--------|----------|-------------|
| 없음 | - | - | - |
## Rules
- component 정의는 구현 API가 아니라 UI 사용 규칙을 다룬다.
- view별 변형이 필요하면 `<component-id>/<variant>.md` 또는 하위 디렉터리를 사용한다.
- 실제 구현체 이름과 다를 수 있지만, view 정의서에서 참조하는 component id는 이 목록에 있어야 한다.

View file

@ -0,0 +1,57 @@
---
ui_doc_type: definition-index
surface_type: ops-dev
source_evidence:
- type: code
path: null
notes: <UI 구현 근거 요약>
- type: docs
path: null
notes: <컨셉/계획 근거 요약>
- type: user
path: null
notes: <사용자 명시 입력 요약>
---
# UI Definition
## Purpose
< agent-ui가 다루는 UI 표면과 목표를 적는다.>
## Surface Type
- Type: ops-dev
- Notes: <product UI 레이어가 필요한 경우 brand/content/assets/tokens/motion 확장 후보를 적는다.>
## Source Evidence
| Type | Path | Notes |
|------|------|-------|
| code | 없음 | <UI 구현 근거 요약> |
| docs | 없음 | <컨셉/계획 근거 요약> |
| user | 없음 | <사용자 명시 입력 요약> |
## Structure
- `views/`: 화면 또는 업무 단위 정의
- `components/`: 반복 UI 구성요소 정의
- `archive/`: 현재 기준이 아닌 과거 정의/결정 로그
## Reading Rules
- 현재 UI 동기화는 이 디렉터리의 활성 문서를 기준으로 한다.
- `archive/**`는 과거 비교, 복원, 특정 근거 확인 요청이 있을 때만 읽는다.
## Sync Rules
- frame-view가 있으면 view region id와 frame region id는 동일해야 한다.
- view에서 참조한 component id는 `components/` 아래에 정의되어야 한다.
- frame은 definition을 대체하지 않는다.
- `구현됨`, `계획`, `가정`, `불명확` 상태를 섞어 쓰지 않는다.
- 기본 코드 동기화는 `.sync-state.json` 기준 이후 변경분만 대상으로 한다.
- 전체 동기화는 사용자가 명시한 경우에만 수행한다.
## Decision History
- <YYYY-MM-DD>: <초기 결정 또는 변경 요약>

View file

@ -0,0 +1,22 @@
---
ui_doc_type: frame-index
frames: []
---
# UI Frames
## Purpose
이 디렉터리는 visual source가 있는 view의 wireframe과 definition 연결 정보를 보관한다.
## Frame Sources
- `views/<view-id>/index.md`: visual source가 있는 view의 frame 연결 문서
- `views/<view-id>/wire.excalidraw`: 선택 visual source
## Rules
- frame은 definition을 대체하지 않는다.
- visual source가 있으면 대응되는 frame index에 기록한다.
- visual source가 없으면 `views/<view-id>/`를 만들지 않는다.
- frame-view가 있으면 frame region id는 definition region id와 동일해야 한다.

View file

@ -0,0 +1,36 @@
---
ui_doc_type: frame-view
view_id: <view-id>
definition: ../../../definition/views/<view-id>/index.md
visual_source: <frame-source>
regions:
- <view-id>.<region>
---
# <View Name> Frame
Definition:
- `../../../definition/views/<view-id>/index.md`
Visual Source:
- `<frame-source>`
## Frame Intent
- < frame이 검증하려는 배치, 밀도, 시선 흐름을 적는다.>
## Required Regions
- `<view-id>.<region>`: <visual source의 라벨 또는 위치 설명>
## Layout Notes
- desktop: <배치 기준>
- tablet: <배치 기준>
- mobile: <배치 기준>
## Sync Rules
- visual source의 주요 박스 text label 또는 `customData.region_id`는 가능한 한 region id를 포함한다.
- definition에 없는 region을 frame에 추가하지 않는다. 필요한 경우 `agent-ui/USER_REVIEW.md`에 남긴다.
- frame에서 제거한 region은 definition에서도 제거 대상인지 확인한다.

View file

@ -0,0 +1,29 @@
---
ui_doc_type: readme
surface_type: ops-dev
---
# agent-ui
이 디렉터리는 AI agent와 사람이 UI 의도, 화면 구조, 와이어프레임, 반복 구성요소를 동기화하기 위한 작업 문맥 저장소다.
## 대상
- 1차 대상: ops/dev UI
- 확장 후보: product UI
## 구조
- `definition/`: 현재 UI 정의 source of truth
- `frame/`: visual source가 있는 view의 wireframe 연결
- `.sync-state.json`: agent-ui -> code 동기화 기준점
- `USER_REVIEW.md`: 사용자 판단이 필요한 활성 질문
- `archive/user-review/`: 해결된 사용자 리뷰 로그
## 기본 규칙
- 현재 기준은 `definition/**`에 둔다.
- visual wireframe은 visual source가 있을 때만 `frame/**`에 둔다.
- `.excalidraw` 파일만으로 UI 기준을 확정하지 않는다.
- 초기 생성 이후 기본 흐름은 `agent-ui -> code` 방향이다.
- `definition/archive/**``archive/user-review/**`는 과거 기록이며 일반 작업에서 읽지 않는다.

View file

@ -0,0 +1,11 @@
{
"schema_version": 1,
"surface_type": "ops-dev",
"baseline_mode": "<code-first|concept-first|blank|migration>",
"last_sync_mode": "baseline",
"last_synced_head": "<git-commit-hash>",
"last_synced_at": "<ISO-8601>",
"agent_ui_paths": [],
"code_paths": [],
"notes": []
}

View file

@ -0,0 +1,25 @@
---
ui_doc_type: user-review
status: open
---
# agent-ui 사용자 리뷰
이 문서는 agent가 확정할 수 없는 UI 결정을 사용자에게 넘기기 위한 활성 리뷰 문서다.
해결된 항목은 `agent-ui/archive/user-review/user_review_N.log`로 이동할 수 있다.
## Review Items
- [ ] [UIR-001] <결정이 필요한 질문>
- Source Skill: <update-agent-ui | validate-agent-ui | sync-agent-ui>
- Stage: <definition-edit | document-consistency | code-sync>
- Blocking Step: <validate-agent-ui | sync-agent-ui | none>
- Context: <관련 view/component/frame 경로>
- Options: <후보가 있으면 적는다>
- Needed For: <차단되는 작업>
- Resume From: <해결 재개할 스킬/명령>
- Pending Changes: <남은 작업트리 변경 파일 또는 없음>
## Notes
- 없음

View file

@ -0,0 +1,79 @@
---
ui_doc_type: view
view_id: <view-id>
status: <구현됨|계획|가정|불명확>
frame: null
source_evidence:
- type: code
path: null
notes: <구현 근거. 없으면 없음>
- type: docs
path: null
notes: <컨셉/계획 근거. 없으면 없음>
- type: user
path: null
notes: <사용자 명시 입력. 없으면 없음>
regions:
- <view-id>.<region>
---
# <View Name>
View ID: `<view-id>`
Frame:
- 없음
Status: `<구현됨|계획|가정|불명확>`
## Source Evidence
| Type | Path | Notes |
|------|------|-------|
| code | 없음 | <구현 근거. 없으면 `없음`> |
| docs | 없음 | <컨셉/계획 근거. 없으면 `없음`> |
| user | 없음 | <사용자 명시 입력. 없으면 `없음`> |
## Purpose
< view의 목적을 1-3줄로 적는다.>
## Primary Users
- <사용자 역할>
## Primary Tasks
- <사용자 작업>
## Information Priority
1. <가장 먼저 보여야 하는 정보>
2. <다음 우선순위 정보>
## Regions
| Region ID | Purpose | Component | Priority | Notes |
|-----------|---------|-----------|----------|-------|
| `<view-id>.<region>` | <역할> | `<component-id 또는 없음>` | high | <비고> |
## Actions
| Action ID | Trigger | Result | Guard |
|-----------|---------|--------|-------|
| `<view-id>.<action>` | <사용자 입력> | <결과> | <권한/상태 조건> |
## States
- loading: <표시 기준>
- empty: <표시 기준>
- error: <표시 기준>
- permission-denied: <표시 기준>
## Open Questions
- 없음
## Decision History
- <YYYY-MM-DD>: <현재 기준으로 남길 결정 요약>

View file

@ -0,0 +1,31 @@
---
ui_doc_type: views-index
views: []
---
# View Definitions
## View Tree
| View ID | Status | Evidence | Description |
|---------|--------|----------|-------------|
| 없음 | - | - | - |
## Navigation
- `<from-view>` -> `<to-view>`: <이동 조건 또는 사용자 작업>
## Common States
- loading
- empty
- error
- permission-denied
## Common Permissions
- <권한 이름>: <허용되는 view/action>
## Open Questions
- 없음

View file

@ -0,0 +1,12 @@
## 사용자 리뷰 요청
_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._
- 상태: 없음
- 사유 유형: 없음
- 연결 대상: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

View file

@ -0,0 +1,35 @@
# 현재 로드맵 컨텍스트
## 고정 참조
- Phase를 가로지르는 다음 작업 후보는 [전역 마일스톤 실행 순서](priority-queue.md)를 먼저 확인한다.
- Phase는 도메인/책임 영역이며 순차 실행 게이트가 아니다.
## 활성 Phase
- [<스케치 | 계획 | 진행중 | 검토중 | 보류>] <phase-name>
- 경로: [PHASE.md](phase/<phase-slug>/PHASE.md)
## 활성 Milestone
- [<스케치 | 계획 | 진행중 | 검토중 | 보류>] <milestone-name>
- Phase: [PHASE.md](phase/<phase-slug>/PHASE.md)
- 경로: [<milestone-name>](phase/<phase-slug>/milestones/<milestone-slug>.md)
## 선택 규칙
- 이 문서는 활성 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 상태가 `[스케치]`이면 `구현 잠금` 상태와 관계없이 구현이나 구현 계획을 시작하지 않고 `[계획]` 승격 필요를 보고한다.

View file

@ -0,0 +1,98 @@
# Milestone: <Milestone 이름>
## 위치
- Roadmap: [ROADMAP.md](../../../ROADMAP.md)
- Phase: [PHASE.md](../PHASE.md)
## 목표
< Milestone이 끝났을 달성되어야 하는 결과를 1~3문장으로 작성>
## 상태
[<스케치 | 계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>]
## 승격 조건
<!--
[스케치] 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이 완료 Roadmap Completion과 최종 검증 evidence로 검증 가능하게 연결되어 있다>
- 결정 필요: <없음 | 아래 목록>
- <에이전트가 확정할 없는 제품/범위/우선순위/책임 경계 결정 항목>
## 범위
- < 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 안에 `검증: <명령/확인 방법/기대 결과>`를 덧붙인다.
Task 체크리스트는 Epic 바로 아래의 flat list로 유지하고, 구현 세부나 테스트만 따로 떼어낸 하위 체크박스는 만들지 않는다.
별도 `완료 기준` 섹션은 만들지 않는다.
-->
### Epic: [epic-id] <Epic 이름>
< Epic이 묶는 capability 또는 산출물 설명>
- [ ] [item-id] <구현 세부가 아니라 Milestone에서 달성해야 capability 또는 산출물>
<!-- 검증이 필요한 기능 Task 예시:
- [ ] [item-id] <기능 설명>. 검증: <명령/확인 방법/기대 결과>
-->
## 완료 리뷰
- 상태: <없음 | 검토중 | 통과 | 보완 필요 | 보류 | 폐기>
- 요청일: <YYYY-MM-DD | 없음>
- 완료 근거: <모든 기능 Task와 Task 안에 명시된 검증 충족 구현 잠금 해제 여부를 1~3줄로 요약>
- 검토 항목: <없음 | 에이전트/런타임이 확인할 완료 근거 또는 archive 조건>
- agent-ui 상태 반영: <해당 없음 | 대기 | 완료 | 차단: 사유>
- 리뷰 코멘트: <없음 | 보완/보류/폐기 방향성>
<!--
기본값은 `해당 없음`이다.
`sync-agent-ui`가 코드 작업을 `milestone-required`로 라우팅했거나 사용자가 Milestone 종료 검토에서 agent-ui 구현 상태 반영을 명시한 경우에만 `대기`로 둔다.
`대기`인 경우 Milestone 종료 검토에서 최종 검증과 code evidence가 확인된 agent-ui view/component/frame만 `구현됨`으로 반영한다.
-->
## 범위 제외
- < Milestone에서 의도적으로 하지 않는 >
## 작업 컨텍스트
- 관련 경로: `<path>`
- 표준선(선택): <기존 구조, 도메인 rule, 플랫폼 관례, 업계 표준으로 진행할 기본 기준>
- 선행 작업: <없음 또는 파일 위치 기준 Markdown 링크(예: [Milestone 이름](../other-milestone.md))/태스크 이름>
- 후속 작업: <없음 또는 파일 위치 기준 Markdown 링크(예: [Milestone 이름](../next-milestone.md))/태스크 이름>
- 확인 필요: <없음 | `구현 잠금 > 결정 필요` 또는 [USER_REVIEW.md](../../../sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md) 분리할 항목>

View file

@ -0,0 +1,25 @@
# Phase: <Phase 이름>
## 상태
[<스케치 | 계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>]
## 목표
< Phase가 끝났을 달성되어야 하는 결과와 책임 경계를 1~3문장으로 작성>
## Milestone 흐름
완료된 Milestone은 archive 경로를 가리키고, 검토중, 진행중, 계획, 스케치 또는 보류 Milestone은 이 Phase 하위 `milestones/` 경로를 가리킨다.
이 흐름은 해당 Phase 안의 상태 정리이며, Phase를 가로지르는 실행 순서는 아니다.
Milestone은 완료, 검토중, 진행중, 계획, 스케치 또는 보류 상태 그룹으로 정리한다.
Phase를 가로지르는 실제 다음 작업 선택은 [전역 마일스톤 실행 순서](../../priority-queue.md)를 우선한다.
스케치 Milestone은 아직 구현 가능한 계획이 아니므로 계획 Milestone보다 아래에 둔다.
- [<스케치 | 계획 | 진행중 | 검토중 | 완료 | 보류 | 폐기>] <Milestone 이름>
- 경로: [<Milestone 이름>](milestones/<milestone-slug>.md) 또는 [archive <Milestone 이름>](../../archive/phase/<phase-slug>/milestones/<milestone-slug>.md)
- 요약: <목표 또는 결과 1문장>
## Phase 경계
- < Phase에서 유지할 책임 경계 또는 범위 제외 기준>

View file

@ -0,0 +1,46 @@
# 로드맵 현지점
- local current: {없음 | [current.md](agent-roadmap/current.md)}
<!--
작성 규칙:
- 아래 {...} placeholder는 실제 출력에 남기지 않는다.
- 링크는 반드시 [제목](repo-root-relative-path) 형식으로 쓴다.
- 문서 안에서 읽은 file-location-relative 링크는 원본 파일 위치 기준으로 해석한 뒤 repo root 기준 target으로 다시 쓴다.
- 경로를 확정할 수 없는 항목은 깨진 Markdown 링크 대신 `링크 없음: <사유>`로 쓴다.
- {PHASE_LINK}, {MILESTONE_LINK}, {SDD_LINK}, {USER_REVIEW_LINK}는 실제 Markdown 링크로 치환한다.
- 이 주석은 출력하지 않는다.
-->
## Breadcrumb
- [로드맵: {roadmap-name}](agent-roadmap/ROADMAP.md)
- Phase: {PHASE_LINK}
- Milestone: {MILESTONE_LINK}
- [{상태}] {목표 또는 역할 한 줄}
- SDD: {없음 | SDD_LINK | SDD_LINK (파일 없음)}
- 사용자 리뷰: {없음 | USER_REVIEW_LINK}
- Milestone: {MILESTONE_LINK}
- [{상태}] {목표 또는 역할 한 줄}
- SDD: {없음 | SDD_LINK | SDD_LINK (파일 없음)}
- 사용자 리뷰: {없음 | USER_REVIEW_LINK}
## 전역 마일스톤 실행 순서
- {없음 | [MILESTONE_TITLE](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md): 식별용 한 줄 설명}
- {[MILESTONE_TITLE](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md): 식별용 한 줄 설명 | 큐 정리 필요: 사유}
## 전체 Phase 흐름
- [{상태}] {PHASE_LINK}
- [{상태}] {PHASE_LINK} ← 현재
- [{상태}] {PHASE_LINK}
## 현재 Phase의 Milestone 흐름
- [{상태}] {MILESTONE_LINK} ← 현재 후보, {역할 태그}
- SDD: {없음 | SDD_LINK | SDD_LINK (파일 없음)}
- 사용자 리뷰: {없음 | USER_REVIEW_LINK}
- [{상태}] {MILESTONE_LINK} ← 현재 후보, {역할 태그}
- SDD: {없음 | SDD_LINK | SDD_LINK (파일 없음)}
- 사용자 리뷰: {없음 | USER_REVIEW_LINK}

View file

@ -0,0 +1,17 @@
# 전역 마일스톤 실행 순서
이 문서는 Phase를 가로지르는 Milestone 실행 순서만 기록한다. 위에 있는 항목을 먼저 검토한다.
## 실행 순서
<!--
작성 규칙:
- 실행 후보가 없으면 이 섹션을 비워 둔다.
- 항목은 Milestone 제목 링크와 식별용 한 줄 설명만 둔다.
- 상태, 목표, 범위, 잠금, 기능, 완료 근거는 각 Milestone 문서를 원본으로 삼는다.
- 링크 target은 이 파일 위치 기준 상대 경로로 쓴다.
예:
1. [Milestone 제목](phase/<phase-slug>/milestones/<milestone-slug>.md)
이 Milestone에서 다루는 작업을 한 줄로 적는다.
-->

View file

@ -0,0 +1,85 @@
# SDD: <Milestone 이름>
## 위치
- Milestone: [Milestone 문서](../../../phase/<phase-slug>/milestones/<milestone-slug>.md)
- Phase: [PHASE.md](../../../phase/<phase-slug>/PHASE.md)
## 상태
[<초안 | 검토중 | 승인됨 | 대체됨 | 폐기>]
## 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> | <사용자 결정이 필요한 기준> |
## State Machine
| 상태 | 진입 조건 | 다음 상태 | 근거 |
|------|-----------|-----------|------|
| <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의 Roadmap Completion/최종 검증으로 남길 근거> |
## Cross-repo Dependencies
- 없음
<!-- 필요한 경우:
- `<project>:agent-roadmap/phase/<phase>/milestones/<milestone>.md`
- `.agent-roadmap-sync/locks.yaml` entry: `<id>`
-->
## Drift Check
- [ ] Milestone 기능 Task와 Acceptance Scenario가 일치한다.
- [ ] Evidence Map이 code-review/complete.log에서 검증 가능하다.
- [ ] agent-contract를 쓰는 경우 SDD에 계약 원문을 복제하지 않았다.
- [ ] 사용자 리뷰가 필요한 항목은 `USER_REVIEW.md`에만 남겼다.
## 사용자 리뷰 이력
- 없음
## 작업 컨텍스트
- 표준선: <기존 구조, 도메인 rule, 플랫폼 관례>
- 후속 SDD: <없음 또는 [SDD.md](../<other-milestone-slug>/SDD.md)>

View file

@ -0,0 +1,37 @@
# SDD User Review
## 상태
요청됨
## 검토 대상
- 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

@ -0,0 +1,57 @@
# 로드맵
## 고정 실행 순서
- 전역 Milestone 실행 순서는 [전역 마일스톤 실행 순서](priority-queue.md)를 먼저 확인한다.
- Phase는 도메인/책임 영역이며 순차 실행 게이트가 아니다.
- Phase 흐름과 상태는 로드맵 구조를 설명하고, 실제 다음 작업 선택은 `priority-queue.md`의 위아래 순서를 우선한다.
- `priority-queue.md`는 순서 전용 문서이며, 상태, 목표, 범위, 잠금, 기능, 완료 근거는 각 Milestone 문서를 원본으로 삼는다.
- `priority-queue.md` 항목은 Milestone 제목 링크와 식별용 한 줄 설명만 둔다.
- `priority-queue.md`는 로드맵 생성 시 함께 만들며, 실행 후보가 없을 때도 문서와 `실행 순서` 섹션은 유지한다.
- `priority-queue.md`는 사용자가 순서 조정을 요청한 경우, Milestone archive 시 완료 항목 제거가 필요한 경우, 큐에 있는 Milestone이 폐기, 경로 변경, split/merge, 또는 실행 의미가 바뀔 정도로 수정된 경우에만 재정렬한다.
- `priority-queue.md`의 링크가 깨졌으면 활성 Milestone 문서를 기준으로 큐를 재정렬하거나 재생성한다.
## 전체 목표
<프로젝트가 최종적으로 달성하려는 결과를 1~3문장으로 작성>
## 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문장>
## 로딩 정책
- 일반 작업에서는 [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 전체에서 에이전트가 확정할 수 없는 결정 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `구현 잠금` 상태를 `해제`로 둔다.

View file

@ -0,0 +1,56 @@
---
name: <skill-name>
version: 1.0.0
description: < skill이 하는 일을 줄로 설명. 트리거 키워드 포함 권장>
---
# <skill-name>
## 목적
< skill이 해결하는 문제를 1~2문장으로 설명>
## 언제 호출할지
- < skill을 호출해야 하는 상황 1>
- < skill을 호출해야 하는 상황 2>
- < skill을 호출해야 하는 상황 3>
## 입력
- `<param-name>`: <설명> (필수)
- `<param-name>`: <설명> (선택)
## 먼저 확인할 것
- [ ] <실행 반드시 확인해야 조건 1>
- [ ] <실행 반드시 확인해야 조건 2>
## 실행 절차
1. **<단계명>**
- <세부 행동>
- <세부 행동>
2. **<단계명>**
- <세부 행동>
3. **결과 보고**
- <출력할 내용>
## 실행 결과 검증
- [ ] <실행 확인해야 성공 조건 1>
- [ ] <실행 확인해야 성공 조건 2>
- 검증 실패 시: <실패 취할 행동 롤백, 사용자 알림, 재시도 >
## 출력 형식
```
<출력 예시>
```
## 금지 사항
- <절대 하면 되는 >
- <절대 하면 되는 >

View file

@ -0,0 +1,113 @@
---
name: analyze-roadmap-position
version: 1.13.0
description: "여러 레포를 전환할 때 코드/git 분석 없이 priority-queue 실행 순서와 ROADMAP > Phase > Milestone > current 현지점을 링크 달린 흐름 목록으로 빠르게 보여주는 읽기 전용 스킬"
---
# 로드맵 현지점
## 목적
여러 레포를 병렬 운용하다가 돌아왔을 때, 현재 작업이 전체 로드맵의 어느 Phase와 Milestone에 있는지 빠르게 보여준다.
기본 출력은 전역 Milestone 실행 순서, `로드맵 > Phase > Milestone` breadcrumb, 전체 Phase 흐름, 현재 Phase의 Milestone 흐름이다.
Phase 흐름은 실행 순서가 아니라 도메인/책임 영역의 구조적 지도이며, 다음 작업 후보는 `priority-queue.md` 순서를 우선한다.
코드 진행도 감사, git diff 분석, 테스트 근거 확인, 남은 작업 정밀 판정은 기본 책임이 아니다.
## 언제 호출할지
- 사용자가 "지금 작업이 뭐지?", "현재 작업이 뭐야?", "어디까지 했지?"라고 물을 때
- 사용자가 레포 전환 직후 로드맵상 현재 좌표를 빠르게 알고 싶어 할 때
- "로드맵상 현 위치", "현재 마일스톤 위치", "current 기준 breadcrumb"를 요청할 때
- Phase를 가로지르는 다음 작업 후보 순서를 함께 보고 싶어 할 때
- 구현 시작 전 전체 Roadmap > Phase > Milestone 관계만 확인하면 될 때
## 먼저 확인할 것
- [ ] `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 문서 링크/경로만 확인
## 실행 절차
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`가 있으면 `실행 순서` 항목을 읽어 전역 Milestone 실행 순서 목록을 만든다.
- 각 항목은 순번, Milestone 제목 링크, 식별용 한 줄 설명만 남긴다.
- 상태, 잠금, 목표, 기능 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`의 항목 순서를 그대로 출력한다. 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/**`를 읽지 않는다.

View file

@ -0,0 +1,94 @@
---
name: check-roadmap-dependency
version: 1.2.0
description: roadmap dependency lock 상태를 확인한다. 사용자가 roadmap-dependency-checker.sh, locks.yaml, 외부 의존 잠금 충족 여부, unlock-ready 판별, 프로젝트 간 잠금 해제 조건 확인을 요청할 때 사용하며, 현재 Milestone이 locked 쪽인지 rely-on.target 쪽인지 양방향으로 판별한다.
---
# check-roadmap-dependency
## 목적
`.agent-roadmap-sync/locks.yaml`에서 특정 lock `id``locked`, `rely-on.target`, `rely-on.status`가 유효한지 확인하고, 모든 `rely-on.status``enable`인지 판별한다.
lock id가 없으면 현재 Milestone identity가 `locked`에 있는지, `rely-on.target`에 있는지 모두 찾아 양방향으로 보고한다.
Milestone identity 역검색과 개별 lock 판별은 `agent-ops/bin/roadmap-dependency-checker.sh`에 맡기고, 스킬은 입력 확정, 실행, 결과 해석만 담당한다.
## 언제 호출할지
- 사용자가 특정 roadmap lock id의 의존 조건 충족 여부를 확인할 때
- runtime에서 unlock-ready 트리거 전 `locks.yaml` 판별 절차를 확인할 때
- `.agent-roadmap-sync/locks.yaml``rely-on.status` 기반 true/false 확인을 요청할 때
- 사용자가 현재 Milestone이 다른 Milestone을 잠그는지 또는 다른 Milestone에 의해 잠겼는지 확인할 때
## 입력
- `lock-id`: 확인할 lock entry id. 예: `oto:oto-agent-registration`. 명시되면 이 id만 판별한다 (선택)
- `target-milestone`: 확인할 Milestone path 또는 `<project>:agent-roadmap/phase/.../milestones/<slug>.md`. 없으면 현재 프로젝트 로컬 `current.md`의 활성 Milestone 단일 후보를 사용한다 (선택)
- `direction`: `locked` / `rely-on` / `both`. 기본값은 `both`다. `locked`는 대상 Milestone이 잠긴 entry만, `rely-on`은 대상 Milestone을 선행 조건으로 삼는 entry만 확인한다 (선택)
- `locks-file`: 기본값은 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`이며, 다른 파일을 검사할 때만 지정한다 (선택)
## 먼저 확인할 것
- [ ] `agent-ops/bin/roadmap-dependency-checker.sh`가 있는지 확인한다.
- [ ] `lock-id`가 명시되었거나 `target-milestone` 또는 현재 프로젝트 로컬 `current.md`의 활성 Milestone 하나로 Milestone identity를 추론 가능한지 확인한다.
- [ ] 기본 경로 또는 지정된 `locks-file`을 읽을 수 있는지 확인한다.
## 실행 절차
1. **입력 확정**
- 사용자 요청에서 `lock-id`를 추출한다.
- `locks-file`이 명시되지 않았으면 프로젝트 상위 `.agent-roadmap-sync/locks.yaml`을 사용한다.
- `locks-file`이 없거나 읽을 수 없으면 결과를 `error`로 보고한다. 이를 미충족 의존성으로 해석하지 않는다.
- `lock-id`가 있으면 그 id만 판별한다.
- `lock-id`가 없으면 `target-milestone` 또는 현재 프로젝트 로컬 `agent-roadmap/current.md`의 활성 Milestone 단일 후보로 Milestone identity를 만든다.
- Milestone identity는 `<project>:agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md` 형식이다.
- `target-milestone``agent-roadmap/...` 상대 경로이면 현재 프로젝트명을 prefix로 붙인다.
- `target-milestone`이 workspace 하위 절대/상대 경로이면 workspace 바로 아래 디렉터리명을 project로 삼고, 그 뒤 `agent-roadmap/...` 경로를 붙인다.
- `target-milestone`이 archive 경로이면 일반 의존 판별 후보로 쓰지 말고 활성 Milestone 대상이 모호하다고 보고한다.
- 활성 Milestone 후보가 없거나 둘 이상이면 추정하지 말고 lock id 또는 Milestone 대상이 모호하다고 보고한다.
- `lock-id`가 없으면 `agent-ops/bin/roadmap-dependency-checker.sh --find-milestone "<identity>" "<direction>" "<locks-file>"`로 Milestone identity와 일치하는 entry를 찾는다.
- find 출력의 `locked:<id>`는 locked entries로, `rely-on:<id>`는 rely-on entries로 분류한다.
- find 출력이 `none`이면 결과를 `error`가 아니라 `no-lock`으로 보고한다.
2. **판별 실행**
- 확인 대상 lock id마다 `agent-ops/bin/roadmap-dependency-checker.sh "<lock-id>" "<locks-file>"`를 실행한다.
- `locked` 방향의 결과는 대상 Milestone의 잠금 해제 조건 충족 여부다.
- `rely-on` 방향의 결과는 대상 Milestone이 완료될 때 영향을 받는 downstream lock의 현재 충족 여부다.
3. **결과 해석**
- stdout `true`와 exit code `0`은 모든 의존 조건 충족으로 보고한다.
- stdout `false`와 exit code `1`은 아직 충족되지 않은 의존 조건이 있음을 보고한다.
- exit code `2`는 설정 오류, 입력 오류, 필수 필드 누락, 파싱 오류로 보고한다.
- `rely-on` 방향에서 대상 Milestone이 `[검토중]` 또는 `[완료]`인데 status가 `disable`이면 `update-roadmap` 동기화가 필요한 stale lock으로 보고한다. 이 스킬은 status를 바꾸지 않는다.
- 사용자-facing 결과에 대상 Milestone 문서를 표시할 수 있으면 identity raw 값만 쓰지 말고 `[Milestone 문서](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)` 링크를 함께 보고한다.
## 실행 결과 검증
- [ ] 각 checker 실행의 stdout이 `true` 또는 `false` 하나로만 출력되었는가
- [ ] exit code `0`, `1`, `2` 의미를 구분해 보고했는가
- [ ] exit code `2`를 unlock 대기 상태로 해석하지 않았는가
- [ ] lock id가 없을 때 대상 Milestone을 `locked``rely-on.target` 양쪽에서 찾았는가
- [ ] `locks.yaml`이 없는 경우 `false`가 아니라 `error`로 보고했는가
- [ ] 이 스킬이 `locks.yaml`이나 roadmap 문서를 수정하지 않았는가
- [ ] 대상 Milestone 문서를 표시할 수 있으면 Markdown 링크로 함께 보고했는가
- 검증 실패 시: 오류 메시지와 사용한 `lock-id`, `locks-file` 경로를 보고하고 멈춘다.
## 출력 형식
```markdown
## 의존성 판별 결과
- target-milestone: `<identity | 해당 없음>`
- target-document: <[Milestone 문서](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md) | 해당 없음>
- direction: `<locked | rely-on | both>`
- locks-file: `<locks-file>`
- 결과: `<true | false | error | no-lock>`
- locked entries: `<lock-id=result, ... | 없음>`
- rely-on entries: `<lock-id=result, ... | 없음>`
- 의미: <모든 의존 조건 충족 | 미충족 의존 조건 있음 | 설정/입력/필수 필드/파싱 오류 | 대상 Milestone 관련 lock 없음>
```
## 금지 사항
- `locks.yaml``status`를 변경하지 않는다.
- roadmap Milestone의 `구현 잠금` 상태를 변경하지 않는다.
- `false`와 설정 오류를 같은 상태로 보고하지 않는다.

View file

@ -0,0 +1,490 @@
---
name: code-review
description: Use for active task review requests such as 리뷰 진행해, 리뷰해줘, 코드 리뷰해줘, code review, CODE_REVIEW.md, USER_REVIEW.md resolution, implementation-time 사용자 리뷰 요청, 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 writes follow-up PLAN/CODE_REVIEW files unless the user-review gate requires USER_REVIEW.md; user review resolution that closes the task writes complete.log before archive. Never stop after verdict append or user-review closure without writing the required next-state artifact.
---
# Code Review
## Purpose
Review the implementation phase of the plan-code-review loop:
```text
plan skill -> implementation -> code-review skill
^ |
+----- issues found: new routed plan/review files
```
Implementation may stop early by filling the active review stub's `사용자 리뷰 요청` section from `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`. This is the only implementation-time decision-stop path, and it is valid only for a selected Milestone `구현 잠금 > 결정 필요` item. Implementation must not ask the user directly, present choices in chat, or call a user-input tool such as `request_user_input`. Code-review validates that request and, when justified, writes `USER_REVIEW.md` from `agent-ops/skills/common/code-review/templates/user-review-template.md`.
## Core Loop Rules
- 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 active state: for `CODE_REVIEW-*-G??.md`, append one verdict, archive the active review and plan files, then create exactly one next state; for `USER_REVIEW.md` completion, update the stop state, write `complete.log`, and archive the task. Do not report before finalization is complete.
- 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 writes the next active `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md`; 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`.
- A filled implementation-owned `사용자 리뷰 요청` is a review input, not a next state by itself. The user-review gate triggers only when the request is tied to a concrete selected Milestone `구현 잠금 > 결정 필요` item. If it is vague, unsupported, repo-fixable, about external environment/secret/service setup, a generic scope conflict, loop exhaustion, or only missing evidence that a follow-up agent can produce by rerunning commands or collecting artifacts, write a normal WARN/FAIL follow-up plan instead.
- 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, if details are uncertain, write the smallest concrete follow-up plan with file references and verification commands.
- Recovery: if a prior turn appended a verdict without archive or next-state files, or resolved `USER_REVIEW.md` without `complete.log`, resume at the matching finalization step and finish the missing artifacts first.
## User Review Gate
`USER_REVIEW.md` is a loop stop state only for selected Milestone lock decisions. Default to a normal WARN/FAIL follow-up; the gate requires positive evidence that the blocker is already represented, or must be represented, as a Milestone `구현 잠금 > 결정 필요` item.
- 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 test environment blockers do not trigger `USER_REVIEW.md` by themselves. Write a narrower follow-up plan or report the non-roadmap blocker as verification evidence that remains unresolved.
- If the active review file has a filled `사용자 리뷰 요청` with `상태` other than `없음`, validate that `사유 유형` is `milestone-lock`, that `연결 대상` points to the selected Milestone, and that the requested decision matches a Milestone `구현 잠금 > 결정 필요` item.
- If the filled request is about external environment/secret/service setup, unsupported device, generic scope conflict, agent execution limits, missing handoff evidence, incomplete verification records, or anything not tied to the Milestone lock, do not write `USER_REVIEW.md`; archive the review and write a normal WARN/FAIL follow-up plan when implementation can continue, or report the blocker without asking the user.
- `USER_REVIEW.md` is created from `agent-ops/skills/common/code-review/templates/user-review-template.md`, filled with the archived loop history, current archived plan/review paths, verdict, loop count, blocking evidence, connection target, and the exact Milestone decision item.
## User Review Resolution
When an active `USER_REVIEW.md` exists and the linked Milestone decision closes the task as complete/PASS, finalization is still owned by this skill.
- Read `USER_REVIEW.md`, archived `plan_*.log`, and archived `code_review_*.log` in that task directory.
- Verify the linked decision and any follow-up evidence are sufficient to close the task. If a new implementation plan is needed instead, 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 decision items, 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 directory. 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 linked Milestone decision resolves the task as complete/PASS.
## Workflow Contract
Active work must live under an active task directory using routed filenames. This is the state protocol shared with the plan skill.
Task path terms:
- `{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.
Filename 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.
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. Read only the Milestone path from `Roadmap Targets` and its SDD path when needed to verify SDD Evidence Map.
- Do not call `update-roadmap` from this skill. The runtime consumes the PASS completion event, checks current state, resolves the active Milestone, and calls `update-roadmap` if needed.
- For `m-<milestone-slug>` PASS tasks, report the original active task path, final archive path, complete log path, task group, and milestone slug so the runtime has deterministic event inputs.
Review routing rules:
- Prefer `local` whenever the scope is bounded and verifiable; high local usage is fine. Do not choose `cloud` just to balance lane usage.
- `local` is for bounded, explicit, locally verifiable review: required behavior is explicit in the plan or existing pattern; relevant context fits in edited files plus nearby types/helpers, direct call sites, and existing or planned targeted tests/fixtures; correctness can be checked by code inspection plus type/build/unit tests or deterministic commands; no open-ended product/design judgment, live external provider/runtime semantics, broad cross-domain context, or evidence-trust diagnosis is decisive.
- `cloud` is required when any local condition is false, including when correctness depends on behavior promised outside the bounded context, wider context, or evidence-trust diagnosis. Repeated Required issues are evidence only when they show a local condition is false.
- `local-G01` through `local-G10` and `cloud-G01` through `cloud-G10` are valid. Lane is capability fit; grade is complexity within the chosen lane. Do not raise `local-GNN` to compensate for missing judgment, missing context, weak verification, or a previous loop failure.
- Repair non-behavioral review artifact drift during review instead of failing solely for it when implementation correctness, tests, and contracts remain judgeable.
- `cloud-G07` or higher is mandatory only when terminal-agent or external interactive behavior is central and cannot be made deterministic for local review, or when the review requires more source/test/diff/log context than local can hold without omitting material evidence: shell/CLI workflow implementation, bin script orchestration, process control, stdout/stderr parsing, exit-status contracts, long-running command diagnosis, terminal benchmark-style tasks, real bin/smoke/integration failures after unit tests passed, TUI/PTY/browser/screen repaint/cursor stream behavior, rerun-mismatched verification trust failures, or very large cross-module/cross-domain changes that cannot be safely split for review.
- On WARN/FAIL follow-up with 5+ `Required` findings, reassess lane/grade and default to `cloud-G07` or higher unless all findings are one narrow mechanical fix pattern; if keeping `local`, record why local conditions still hold.
- Previous loop lane does not matter. Recompute lane from the current review or follow-up scope using these rules.
Directory states:
| State | Meaning |
|-------|---------|
| `PLAN-*-G??.md` + unfilled `CODE_REVIEW-*-G??.md` stub/placeholders | Implementation is not judgeable; review should fail completeness if invoked |
| `PLAN-*-G??.md` + `CODE_REVIEW-*-G??.md` with filled `사용자 리뷰 요청` | Implementation claims a selected Milestone lock decision blocker; review validates the request and writes `USER_REVIEW.md` only if justified |
| `PLAN-*-G??.md` + filled `CODE_REVIEW-*-G??.md` | Ready for code-review skill |
| `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; linked Milestone lock decision 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`) | Task 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 expected beside it. |
| Exactly one active path and it is `USER_REVIEW.md`, with a linked Milestone completion/resolution decision | Perform User Review Resolution for that task. |
| One or more active paths and every active path is `USER_REVIEW.md`, with no completion/resolution decision | Report that the linked Milestone decision is required and list the paths. |
| No active paths | Stop and report that no active review exists. |
| 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.
## 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.
If the active plan or review file contains `Agent UI Completion`, also read `agent-ops/rules/common/rules-agent-ui.md` and the listed active agent-ui documents. Do not read `agent-ui/definition/archive/**` or `agent-ui/archive/user-review/**` unless the review explicitly cites those archive paths.
## Step 3 - Pre-Review Checklist
Before writing the verdict:
- Compare actual source files against every planned checklist item.
- Compare the plan `구현 체크리스트` and review stub `구현 체크리스트`; repair non-behavioral drift when implementation remains judgeable.
- When the active artifacts have `Roadmap Targets`, check whether the referenced Milestone has `SDD: 필요`. When it does, read only that Milestone and its SDD, compare implementation evidence against the SDD Acceptance Scenarios/Evidence Map for the targeted task ids, and fail completeness or verification trust when evidence is insufficient. Do not require a separate SDD target section.
- 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, treat that feature item as incomplete until both implementation evidence and the matching verification output are present. 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 final mandatory `CODE_REVIEW-*-G??.md` completion item; repair clear artifact drift when evidence supports completion.
- If the active plan or review file contains `Agent UI Completion`, verify the implementation-owned fields are filled before PASS: listed agent-ui docs exist, actual code evidence paths exist, requested status updates are explicit, and implementation verification evidence is present. Missing or untrusted evidence is a completeness or verification-trust issue.
- Treat review artifact gaps as failures only when they prevent judging implementation correctness, tests, contracts, or verification trust.
- Read the `사용자 리뷰 요청` section. If `상태` is not `없음`, validate the exact decision needed, `연결 대상`, blocker evidence, command output or not-run reason, why automatic follow-up cannot resolve it, and resume condition before deciding whether the user-review gate triggers. Reject the request unless it is tied to a selected Milestone `구현 잠금 > 결정 필요` item.
- 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 `코드리뷰 결과` to the active `CODE_REVIEW-*-G??.md`.
Before appending `PASS`, if all other PASS conditions are met and the active review file contains `Agent UI Completion`, perform the review-pass status update first: update the listed agent-ui docs to `구현됨`, add actual code evidence, run `validate-agent-ui`, and mark the section's review-agent-owned finalization items. If this update or validation fails, do not append `PASS`; classify the failure as `WARN` or `FAIL` and write the normal follow-up.
Required fields:
- `종합 판정`: exactly `PASS`, `WARN`, or `FAIL`.
- `차원별 평가`: Pass/Warn/Fail for correctness, completeness, test coverage, API contract, code quality, implementation deviation, verification trust. If SDD Evidence Map applies through `Roadmap Targets`, also include spec conformance.
- `발견된 문제`: `없음`, or bullets using `Required`, `Suggested`, or `Nit` with `file:line` and a concrete fix.
- `다음 단계`: keep only the matching PASS, WARN/FAIL follow-up, or USER_REVIEW line.
Do not check archive/next-state items in `코드리뷰 전용 체크리스트` 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-directory 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, missing required test, missing integrated verification, plan-completeness issue, or review artifact gaps that prevent judging implementation quality.
- `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 - Archive Active Files
Archive is mandatory for `PASS`, `WARN`, and `FAIL`. Before the archive order, 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`.
Archive order is fixed:
1. Count existing `code_review_*.log` as `N`; rename `CODE_REVIEW-{review_lane}-GNN.md` to `code_review_{review_lane}_GNN_N.log`.
2. Count existing `plan_*.log` as `M`; rename `PLAN-{build_lane}-GNN.md` to `plan_{build_lane}_GNN_M.log`.
After archiving, neither active `.md` file remains unless Step 6 writes a follow-up plan/review or `USER_REVIEW.md`.
## 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`.
- If the task did not close through `USER_REVIEW.md`, remove the optional user-review row from the `루프 이력` table.
- If the archived plan or review log contains `Roadmap Targets`, copy it into `complete.log` as `Roadmap Completion`. Include the Milestone path, completed Task ids, archived plan/review log paths, and verification evidence. If there is no `Roadmap Targets` section, remove the optional `Roadmap Completion` template section entirely and do not invent roadmap targets.
- If the archived review log contains `Agent UI Completion`, copy the completed evidence into `complete.log`. If there is no `Agent UI Completion` section, remove the optional complete-log section entirely.
- 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`.
For `WARN` or `FAIL`, apply the user-review gate before writing follow-up files.
If the user-review gate triggers:
- Write `agent-task/{task_name}/USER_REVIEW.md` from `agent-ops/skills/common/code-review/templates/user-review-template.md`.
- Fill every placeholder. Use only `milestone-lock` as the reason type.
- Include all available archived loop history in chronological order, the current archived plan/review log paths, the final verdict, review number, issue summary, blocking evidence, and the exact linked Milestone decision needed.
- Do not write a new active `PLAN-{build_lane}-GNN.md` or `CODE_REVIEW-{review_lane}-GNN.md`.
- Do not write `complete.log`.
- If the task group is `m-<milestone-slug>`, report that the milestone task is blocked on user review; do not emit PASS completion metadata and do not call `update-roadmap`.
If the user-review gate does not trigger, write new routed plan/review files using the plan skill format:
- New plan number is the count of `plan_*.log` after archive.
- Header tag is `REVIEW_<PARENT_TAG>`.
- If the selected task group is `m-<milestone-slug>`, write the follow-up plan/review under the same `m-<milestone-slug>` task group.
- Base the follow-up scope directly on the archived review findings. Keep it narrow and actionable.
- Choose lane/grade again from the current follow-up scope using Review routing rules. Ignore the prior lane and do not increment GNN solely because the previous loop failed.
- If the finding is only missing or untrusted verification evidence that an appropriate follow-up lane can produce by rerunning commands or collecting artifacts, do not write `USER_REVIEW.md` solely for that reason. Write a follow-up plan that reruns the exact commands in an appropriate lane and records actual stdout/stderr.
- If follow-up verification involves mobile/UI hangs, timeouts, or no progress for 2 minutes, stop blind retries; require focused rerun output plus screenshot/window/UI-tree evidence path, or the exact reason capture is impossible.
- Write an `Archive Evidence Snapshot` section in every WARN/FAIL follow-up plan. Copy enough prior-loop evidence from the archived plan/review logs for the next implementer to act without rereading archive by default: current archived plan/review log 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 instruct the implementer to search `agent-task/archive/**` broadly.
- Copy the follow-up plan's `Archive Evidence Snapshot` section exactly into the follow-up review stub.
- If the archived plan or review had `Agent UI Completion` and the follow-up still works toward the same agent-ui status update, include an updated `Agent UI Completion` section in the follow-up plan and review stub. If the follow-up intentionally no longer claims agent-ui status completion, omit the section and explain why in the follow-up plan `범위 결정 근거`.
- Before choosing the follow-up route, apply this gate:
- Keep the follow-up on `local` when all local allowlist conditions are true for the current fix; otherwise use `cloud`.
- If the follow-up work is terminal-agent work that cannot be reduced to deterministic commands and evidence, use `cloud-G07` or higher.
- If unit tests passed but a real bin/smoke/integration command failed and local follow-up cannot isolate the failure with deterministic evidence, use `cloud-G07` or higher.
- If the task depends on interactive TUI/PTY/browser/external CLI behavior, screen repaint/cursor stream parsing, or live command-palette state that cannot be captured deterministically, use `cloud-G07` or higher.
- If the follow-up requires more source/test/diff/log context than local can hold without dropping material evidence, or the failure spans broad cross-module/cross-domain context that cannot be safely split, use `cloud-G07` or higher.
- If verification evidence is missing, reconstructed, stale, untrusted, or mismatched on rerun, use a local follow-up only when exact commands and actual stdout/stderr capture are enough; use `cloud-G07` or higher when evidence trust recovery needs stronger diagnosis.
- `FAIL`: one plan item per Required issue.
- `WARN`: one grouped plan item for Suggested issues, plus related Nit issues if useful.
- Each plan item needs problem, solution with before/after when non-trivial, checklist, test decision, intermediate verification.
- The follow-up plan and review stub must contain matching `구현 체크리스트` item text/order, including the final mandatory `CODE_REVIEW-*-G??.md` completion item.
- The follow-up plan's implementer instructions and review stub must forbid direct user prompts and include the implementation-time `사용자 리뷰 요청` stop path so the next implementer can act without reading the plan skill.
- Copy `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` into the follow-up review stub's `사용자 리뷰 요청` section.
- If the archived plan had `Roadmap Targets` and the follow-up still works toward the same Milestone Task completion, copy that section into the follow-up plan and review stub. If the follow-up intentionally no longer claims roadmap Task completion, omit the section and explain why in the follow-up plan `범위 결정 근거`.
Routed review stub template (fill `{…}` placeholders; everything else is fixed and must not be changed by the implementing agent):
```markdown
<!-- task={task_name} plan={N} tag={TAG} -->
# 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 `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a selected Milestone `구현 잠금 > 결정 필요` item, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Environment/secret/service setup, generic scope conflicts, loop exhaustion, and evidence gaps that a follow-up agent can close are normal follow-up issues, not user-review blockers by themselves.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record only the linked Milestone lock decision in `사용자 리뷰 요청` and stop for code-review.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.
## 개요
date={YYYY-MM-DD}
task={task_name}, plan={N}, tag={TAG}
{copy the follow-up plan's Roadmap Targets section exactly if present; omit this block if the follow-up plan has no Roadmap Targets}
{copy the follow-up plan's Archive Evidence Snapshot section exactly if present; omit this block if the follow-up plan has no Archive Evidence Snapshot}
## 이 파일을 읽는 리뷰 에이전트에게
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.
1. 판정을 append한다.
2. `CODE_REVIEW-{review_lane}-GNN.md``code_review_{review_lane}_GNN_N.log`, `PLAN-{build_lane}-GNN.md``plan_{build_lane}_GNN_M.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 연결된 Milestone 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다.
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.
---
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [{TAG}-1] {item description} | [ ] |
| [{TAG}-2] {item description} | [ ] |
## 구현 체크리스트
{copy the follow-up plan's 구현 체크리스트 items exactly, preserving order and checkbox text}
## Agent UI Completion
> Include this section only when the follow-up plan has `Agent UI Completion`; otherwise omit it entirely.
> **[IMPLEMENTING AGENT]** Fill actual code evidence and implementation verification output for the listed docs.
> **[REVIEW AGENT ONLY]** On PASS, update only the listed agent-ui docs to `구현됨`, add the listed code evidence, run `validate-agent-ui`, and copy this section into `complete.log`.
- Mode: review-pass-status-update
- Agent UI docs:
- `agent-ui/definition/views/<view-id>/index.md`
- Actual code evidence:
- [ ] `<code path>`: <implemented evidence>
- Implementation verification evidence:
- [ ] `<test or analysis command>`: <actual result or output path>
- Status updates requested on PASS:
- [ ] `agent-ui/definition/views/<view-id>/index.md`: `계획` -> `구현됨`
- Review finalization:
- [ ] Review agent updated the listed agent-ui docs and code evidence.
- [ ] Review agent ran `validate-agent-ui scope=<scope>` after the status/evidence update.
## 코드리뷰 전용 체크리스트
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.
- [ ] `코드리뷰 결과``PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [ ] active `CODE_REVIEW-*-G??.md``code_review_{review_lane}_GNN_N.log`로 아카이브한다.
- [ ] active `PLAN-*-G??.md``plan_{build_lane}_GNN_M.log`로 아카이브한다.
- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md``agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/{task_name}/``agent-task/archive/YYYY/MM/{task_name}/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/{task_group}/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-{build_lane}-GNN.md``CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 연결된 Milestone 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 사용자 리뷰 요청
_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._
- 상태: 없음
- 사유 유형: 없음
- 연결 대상: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음
## 리뷰어를 위한 체크포인트
{pre-filled from plan — one bullet per review focus area}
## 검증 결과
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
필수 규칙:
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다.
- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다.
### {TAG}-1 중간 검증
```
$ {verification command from plan}
(output)
```
### 최종 검증
```
$ {final verification command from plan}
(output)
```
---
> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.
```
Sections and their ownership:
| 섹션 | 소유자 | 설명 |
|------|--------|------|
| 헤더 주석, 개요(date/task/plan/tag), 리뷰 에이전트 지시 | 스텁 생성 시 고정 | 구현 에이전트가 수정하거나 실행하지 않음 |
| Roadmap Targets | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트가 수정하지 않음; PASS 시 code-review가 `complete.log``Roadmap Completion`으로 복사 |
| Archive Evidence Snapshot | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트의 기본 이전 루프 컨텍스트; 추가 확인이 필요할 때 여기에 명시된 archive 파일만 좁게 읽음 |
| Agent UI Completion | Mixed | Present only for agent-ui code work that should become `구현됨` on code-review PASS; implementing agent fills actual evidence, review agent applies the status/evidence update and copies the section into `complete.log` |
| 구현 항목별 완료 여부 (항목명) | 스텁 생성 시 고정 | `[ ]``[x]` 체크만 구현 에이전트가 수행 |
| 구현 체크리스트 (항목 텍스트/순서) | follow-up plan에서 복사해 스텁 생성 시 고정 | 구현 에이전트가 `[ ]``[x]` 체크만 수행; 마지막 체크박스는 저장 전 필수 |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
| 계획 대비 변경 사항, 주요 설계 결정 | 구현 에이전트가 채움 | placeholder 텍스트를 실제 내용으로 교체 |
| 사용자 리뷰 요청 | 구현 에이전트가 채움 | 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채움; 구현 중 직접 질문은 금지; 환경/secret/서비스/검증 공백/일반 범위 조정은 사용자 리뷰 요청으로 쓰지 않음 |
| 리뷰어를 위한 체크포인트 | 스텁 생성 시 고정 | 계획에서 추출한 리뷰 포인트 |
| 검증 결과 (섹션 제목 + 명령) | 스텁 생성 시 고정 | 실행 출력만 구현 에이전트가 채움; 명령 변경은 `계획 대비 변경 사항`에 기록 |
| 코드리뷰 결과 | 리뷰 에이전트가 append | 스텁에 포함하지 않음 |
## 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 active task directory `agent-task/{task_name}/` to `agent-task/archive/YYYY/MM/{task_name}/`. For split work, the selected active task directory is the subtask directory, and the archive must 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 if it is empty. If sibling subtask directories or other files remain, leave the parent task group in place.
- 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 `roadmap-completion=<Task ids from complete.log or none>`.
- The runtime consumes that completion event, checks current state, and calls `update-roadmap` if needed. `update-roadmap` only checks Milestone Task ids when `complete.log` contains `Roadmap Completion`; if the section is absent, roadmap Task completion is a no-op even for `m-*` task groups.
- If verdict is `PASS` and the archived review log contains `Agent UI Completion`, ensure the listed agent-ui status/evidence update and `validate-agent-ui` check are complete before writing or finalizing `complete.log`. Do not defer this to runtime or Milestone completion.
- `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 the linked Milestone lock decision is resolved.
- If `USER_REVIEW.md` is later resolved as complete/PASS by linked Milestone decision and evidence, write `complete.log`, move the task directory 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}/code_review_{review_lane}_GNN_N.log`, 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}/code_review_{review_lane}_GNN_N.log`.
- 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 `코드리뷰 전용 체크리스트`; leave mutually exclusive verdict items unchecked.
- If any applicable item cannot be checked, finish the missing archive, `complete.log`, task-directory move, follow-up plan/review write, 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/verification items are done; review artifact drift is repaired 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.
- For follow-up plans about verification trust, specify deterministic commands, for example `rg --sort path`, and forbid repo-local tool artifacts.
## Final Checklist
- `code_review_{review_lane}_GNN_N.log` exists with verdict appended.
- `plan_{build_lane}_GNN_M.log` exists.
- `.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 `.md` files remain 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 directory 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 with `Roadmap Targets`: `complete.log` contains `Roadmap Completion` with Milestone path, Task ids, archived plan/review evidence, and verification evidence.
- PASS without `Roadmap Targets`: `complete.log` omits `Roadmap Completion` and reported metadata says `roadmap-completion=none`.
- PASS with `Agent UI Completion`: listed agent-ui docs were updated to `구현됨` with code evidence, `validate-agent-ui` passed, and `complete.log` contains `Agent UI Completion`.
- PASS without `Agent UI Completion`: complete.log omits `Agent UI Completion`.
- PASS split: empty active parent `agent-task/{task_group}/` removed after the subtask move; non-empty parent left in place.
- WARN/FAIL without user-review gate: new active `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` created with matching headers and matching `구현 체크리스트`; no `complete.log`.
- WARN/FAIL follow-up: new active plan and review stub contain identical `Archive Evidence Snapshot` sections with prior archived plan/review log paths, verdict, issue summary, affected files, verification evidence, and specific archive paths allowed for narrow reread when needed.
- Follow-up review stubs include the `사용자 리뷰 요청` section from `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` and forbid direct user prompts during implementation.
- USER_REVIEW: `USER_REVIEW.md` exists from template, no active `PLAN-*.md` or `CODE_REVIEW-*.md` remains, and no `complete.log` was written.
- Implementation-requested USER_REVIEW: archived review log preserves the filled `사용자 리뷰 요청` evidence and the generated `USER_REVIEW.md` records the exact linked Milestone decision needed.
- 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.

View file

@ -0,0 +1,4 @@
interface:
display_name: "Code Review"
short_description: "Review and route task loops"
default_prompt: "Use $code-review to review or resolve the active repository task, archive active files, and create complete.log, follow-up plan/review files, or USER_REVIEW.md."

View file

@ -0,0 +1,51 @@
# 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` | linked Milestone 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}
## Roadmap Completion
{optional; include only when archived plan/review had Roadmap Targets. Remove this entire section when there are no Roadmap Targets.}
- Milestone: `{agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md}`
- Milestone link: [Milestone 문서](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
- Completed task ids:
- `{task-id}`: PASS; evidence=`{archived-plan-log}`, `{archived-review-log}`; verification=`{command or saved output path}`
- Not completed task ids: 없음
## Agent UI Completion
{optional; include only when archived review had Agent UI Completion. Remove this entire section when there is no Agent UI Completion.}
- Agent UI docs:
- `{agent-ui/definition/views/<view-id>/index.md}`: `구현됨`; code evidence=`{code path}`; implementation verification=`{command or output path}`; validation=`{validate-agent-ui result or output path}`
- Status updates: 완료
- Remaining agent-ui issues: 없음
## 잔여 Nit
- 없음
## 후속 작업
- 없음

View file

@ -0,0 +1,50 @@
# User Review Required - {task_name}
## 요청 일시
{YYYY-MM-DD or ISO-8601}
## 상태
USER_REVIEW
## 사유
- 유형: milestone-lock
- 연결 대상: {agent-roadmap/phase/<phase>/milestones/<milestone>.md}
- 현재 리뷰 회차: {review-number}
- 최종 판정: {WARN or FAIL}
- 요약: {Milestone 구현 잠금 항목이 실구현을 차단한 이유}
## 루프 이력
| Plan | Review | Verdict | 메모 |
|------|--------|---------|------|
| `{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} |
## 차단 근거
- 문제: {review finding summary}
- 현재 archive plan: `{current-archived-plan-log}`
- 현재 archive review: `{current-archived-review-log}`
- 검증 명령: `{command or 없음}`
- 실제 출력: {stdout/stderr excerpt or saved output path}
- 차단 판단 근거: {연결 대상의 Milestone 결정 필요 항목과 일치하는 근거}
## 연결 결정 필요
- [ ] {Milestone `구현 잠금 > 결정 필요`에 기록된 결정 항목}
## 재개 조건
- {위 결정이 Milestone 구현 잠금에 반영되고, 필요한 경우 해당 USER_REVIEW.md가 user_review_N.log로 해결되어야 한다}
## 다음 실행 힌트
- {resolve-review 또는 update-roadmap으로 반영할 대상 경로와 후속 plan/review 재개 조건}
## 종료 규칙
- 연결 결정과 evidence가 이 stop state를 완료/PASS로 해소하면 `USER_REVIEW.md`를 해소 상태로 갱신하고, `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.
- 새 구현이 필요하면 `plan` 스킬이 `USER_REVIEW.md``user_review_N.log`로 아카이브한 뒤 새 `PLAN-*-G??.md` / `CODE_REVIEW-*-G??.md`를 작성한다.

View file

@ -0,0 +1,162 @@
---
name: commit-push
version: 1.2.0
description: 변경 사항을 커밋하거나 원격에 푸시한다. "커밋해줘", "푸시해줘", "커밋하고 푸시", "올려줘" 요청 시 사용하며 명시된 푸시는 재확인 없이 수행한다.
---
# commit-push
## 목적
현재 변경 내용을 분석하여 Conventional Commits 형식의 한국어 설명 커밋 메시지를 작성하고, 사용자가 요청한 커밋 또는 푸시를 수행한다.
일반적인 커밋/푸시는 승인 질문 없이 진행하고, 실제 위험 신호가 있을 때만 사용자 확인을 받는다.
## 언제 호출할지
- "커밋해줘", "커밋하고 푸시해줘" 요청 시
- "변경 사항 올려줘", "푸시해줘" 요청 시
- 코드 작업 완료 후 "반영해줘", "올려줘" 요청 시
## 입력
- `scope`: 커밋 범위 — all(전체) 또는 특정 파일/경로 (선택, 기본값: all)
- `push`: 푸시 여부 (선택, 기본값: auto)
- auto: 요청에 "푸시", "push", "올려줘", "반영해줘", "커밋하고 푸시"가 있으면 true, "커밋만" 또는 "푸시하지 마"가 있으면 false
- true: 푸시 여부를 다시 묻지 않고 현재 브랜치를 원격에 푸시한다
- false: 커밋만 수행하고 푸시는 생략한다
## 먼저 확인할 것
- [ ] 커밋할 변경 사항 또는 push할 unpushed commit이 존재하는가 (`git status`로 확인)
- [ ] 현재 브랜치, 원격, upstream 상태가 일반 커밋/푸시에 적합한가
- [ ] `.env`, 시크릿 파일 등 민감한 파일이 스테이징에 포함되어 있지 않은가
## 실행 절차
1. **변경 사항 파악**
- `git status`로 변경/추가/삭제된 파일 목록을 확인한다
- `git diff`로 구체적인 변경 내용을 확인한다
- 커밋할 변경 사항이 없고 push가 true이며 unpushed commit이 있으면 커밋 단계는 건너뛰고 푸시를 진행한다
- 커밋할 변경 사항도 없고 push할 unpushed commit도 없으면 사용자에게 알리고 종료한다
2. **민감 파일 검사**
- 스테이징 대상에 아래 패턴이 포함되면 해당 파일을 제외하고 사용자에게 경고한다
- `.env`, `.env.*`
- `*secret*`, `*credential*`, `*password*`
- `*.pem`, `*.key`, `*.p12`
- `.gitignore`에 이미 등록된 파일은 무시한다
3. **커밋 메시지 작성**
- 변경 내용을 분석하여 Conventional Commits 형식으로 커밋 메시지를 작성한다
- 아래 메시지 규칙을 따른다
4. **위험 신호 판단**
- 아래 위험 신호가 없으면 사용자 승인 없이 다음 단계로 진행한다
- 위험 신호가 있으면 커밋/푸시를 멈추고 대상 파일, 커밋 메시지, 위험 내용을 짧게 보여준 뒤 사용자 확인을 받는다
- 민감 파일 패턴이 스테이징 대상에 포함됨
- 사용자가 지정한 scope 밖의 변경을 포함해야 함
- 현재 브랜치가 사용자 요청이나 작업 맥락과 다를 가능성이 큼
- merge/rebase 충돌, detached HEAD, git 작업 중 상태가 감지됨
- 원격이 diverged 상태거나 일반 push가 실패해 force push가 필요해 보임
- 사용자가 메시지 수정을 요청하면 반영한다
5. **커밋 실행**
- 커밋할 변경 사항이 없고 push할 unpushed commit만 있으면 이 단계를 건너뛴다
- scope에 따라 파일을 스테이징한다
- all: 변경된 전체 파일을 개별적으로 `git add`
- 특정 경로: 해당 파일만 `git add`
- 작성한 메시지로 `git commit`을 실행한다
6. **푸시 실행**
- push가 true인 경우에만 실행한다
- 사용자가 푸시를 명시했으면 푸시 여부를 다시 묻지 않는다
- 현재 브랜치를 원격에 푸시한다
- 원격 브랜치가 없으면 `-u origin {branch}`로 설정한다
- 일반 push가 실패하거나 충돌이 발생하면 사용자에게 알리고 중단한다
- `--force`가 필요해 보여도 자동 실행하지 않고 사용자 확인을 받는다
7. **결과 보고**
- 커밋 해시, 메시지, 변경 파일 수, 푸시 결과를 출력한다
## 커밋 메시지 규칙
### 형식
```
<type>(<scope>): <한국어 서술형 요약>
< 변경했는지 설명하는 한국어 본문> (선택)
<footer> (선택)
```
`scope`는 선택 사항이며 변경 영역을 짧은 ASCII 토큰으로 쓴다. 예: `agent-ops`, `sync`, `docs`, `api`
### type 목록
| type | 용도 |
|------|------|
| feat | 새로운 기능 추가 |
| fix | 버그 수정 |
| docs | 문서 추가/수정 |
| refactor | 동작 변화 없는 구조 개선 |
| test | 테스트 추가/수정 |
| chore | 잡무성 변경, 저장소 관리 |
| build | 빌드, 패키징, 의존성 변경 |
| ci | CI/CD 설정 변경 |
| perf | 성능 개선 |
| revert | 이전 커밋 되돌림 |
### 작성 원칙
- `type``scope`는 Conventional Commits 호환을 위해 영어 ASCII 토큰을 사용한다
- 요약과 본문은 **한국어**로 작성한다
- 요약은 50자 이내로 간결하게 작성한다
- 요약은 "~한다" 형태의 서술형으로 끝낸다 (예: "로그인 검증 로직을 추가한다")
- 본문은 **무엇을** 변경했는지가 아니라 **왜** 변경했는지를 쓴다
- 변경 파일이 3개 이하이면 본문을 생략할 수 있다
- 여러 성격의 변경이 섞여 있으면 가장 핵심적인 변경을 기준으로 타입을 정한다
- 이슈, PR, 작업 ID가 있으면 footer에 `Refs: #123`, `Closes: #123`처럼 남긴다
- breaking change는 `type(scope)!:` 또는 footer의 `BREAKING CHANGE:`로 표시한다
### 예시
```text
docs(commit-push): 푸시 승인 조건을 명시한다
```
```text
fix(sync): unpushed commit 푸시 흐름을 보강한다
작업 트리에 변경이 없어도 로컬 커밋이 원격보다 앞서 있으면
커밋 단계를 건너뛰고 푸시해야 한다.
```
## 출력 형식
```
## 커밋 완료
- 브랜치: {브랜치명}
- 커밋: {해시} — {커밋 메시지 요약}
- 변경 파일: {n}개
- {파일 경로}: {변경 유형}
- 푸시: {성공/생략/실패}
```
## 실행 결과 검증
- [ ] `git log -1`로 방금 생성한 커밋이 존재하고, 메시지가 작성한 내용과 일치하는가
- [ ] 커밋에 포함된 파일 목록이 의도한 scope와 일치하는가 (`git diff-tree --no-commit-id --name-only -r HEAD`)
- [ ] push가 true인 경우, `git status`에서 "Your branch is up to date" 또는 원격과 동기화 상태인가
- 검증 실패 시: 실패 원인(커밋 누락, 푸시 실패 등)을 사용자에게 알리고 재시도 여부를 확인한다
## 금지 사항
- `git add -A` 또는 `git add .`을 사용하지 않는다 (민감 파일 혼입 방지)
- `git push --force`를 사용하지 않는다
- 명시적인 커밋/푸시 요청이 있고 위험 신호가 없는데도 습관적으로 사용자 승인을 요구하지 않는다
- 위험 신호를 무시하고 커밋하거나 푸시하지 않는다
- `type``scope`를 제외한 요약/본문을 영어로 작성하지 않는다
- 변경 내용과 무관한 커밋 메시지를 작성하지 않는다
- `--no-verify` 옵션을 사용하지 않는다

View file

@ -0,0 +1,134 @@
---
name: complete-milestone
version: 1.1.0
description: "마일스톤 완료해도 될지 검토, 현 마일스톤 종료 검토, 현재 마일스톤 닫고 다음 마일스톤 지정, 검토중 Milestone 코드레벨 종료 감사 요청에 사용한다. 코드/테스트/계약/evidence를 점검하고 작은 보완은 처리하거나 큰 보완은 plan으로 넘기며, agent-spec이 있으면 update-spec을 필수 gate로 수행한 뒤 update-roadmap으로 완료/archive와 다음 Milestone 지정을 처리한다."
---
# complete-milestone
## 목적
`[검토중]` 또는 완료 후보 Milestone을 코드레벨에서 종료해도 되는지 감사하고, 종료 가능할 때 spec sync와 roadmap 완료/archive까지 이어지는 오케스트레이션을 수행한다.
`update-spec``update-roadmap`의 책임을 합치지 않고, 이 스킬이 완료 workflow의 순서와 gate를 관리한다.
## 언제 호출할지
- 사용자가 "마일스톤 완료해도 될지 검토해봐"라고 요청할 때
- 사용자가 "현 마일스톤 종료 검토해", "현재 마일스톤 닫고 다음 마일스톤 지정해"라고 요청할 때
- `[검토중]` Milestone의 완료 리뷰 통과, archive, 다음 Milestone current 지정 여부를 코드레벨 evidence로 확인해야 할 때
- Milestone 종료 시점에 `agent-spec` 갱신이 함께 필요할 때
## 입력
- `target-milestone`: 종료 검토할 Milestone 경로, 이름, slug. 없으면 `agent-roadmap/current.md`의 활성 Milestone 단일 후보를 사용한다. (선택)
- `next-milestone`: 종료 후 `current.md`에 둘 다음 Milestone 후보. 없으면 Phase 흐름에서 자동 후보를 찾되 모호하면 보고한다. (선택)
- `mode`: `check-only` 또는 `close`. 기본값은 `close`다. (선택)
- `evidence`: 완료 판단에 사용할 complete.log, 테스트 결과, 사용자 설명, PR/커밋 등. (선택)
## 먼저 확인할 것
- [ ] `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 규칙을 따른다.
## 실행 절차
1. **대상 Milestone 확정**
- `target-milestone`이 있으면 활성 Milestone에서 정확히 하나를 찾는다.
- 없으면 `agent-roadmap/current.md`의 활성 Milestone 단일 후보를 사용한다.
- 대상이 archive 경로이거나 둘 이상이면 수정하지 않고 target 불명확으로 보고한다.
2. **완료 후보 상태 확인**
- 대상 Milestone이 `[검토중]`이면 종료 감사로 진행한다.
- `[진행중]` 또는 `[계획]`이면 `sync-milestone-workstate` 기준으로 기능 Task/evidence를 동기화할 수 있는지 먼저 확인한다. 동기화 후 `[검토중]` 조건을 충족하지 못하면 종료 감사로 진행하지 않는다.
- `[스케치]`, `[보류]`, `[폐기]`, `[완료]`이면 일반 종료 감사를 진행하지 않고 상태 불일치를 보고한다.
- `구현 잠금`이 남아 있거나 미완료 `결정 필요`가 있으면 archive하지 않는다.
3. **코드레벨 종료 감사**
- Milestone `기능` Task와 검증 문구, `완료 리뷰`, complete.log, SDD Evidence Map, 관련 코드/계약/테스트를 비교한다.
- `agent-task/archive/**`는 같은 `m-<milestone-slug>` complete.log 후보처럼 규칙상 허용된 범위만 좁게 읽는다.
- 코드/계약 변경에 닿으면 관련 domain rule과 `agent-contract/index.md` 라우팅을 따른다.
- 필요한 검증 명령은 `agent-test/<env>/rules.md`와 관련 profile을 따른다. 환경 미지정은 local로 본다.
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`가 있으면 큐의 위에서 아래 순서 중 완료/archive 대상이 아니고 `[폐기]`가 아닌 첫 활성 Milestone을 다음 후보로 찾는다.
- `priority-queue.md`가 없으면 같은 Phase의 Milestone 흐름에서 완료/폐기/archive가 아닌 다음 후보를 찾는다.
- 후보가 없거나 둘 이상이면 자동 지정하지 않고 후보와 이유를 보고한다.
- 다음 후보가 `[스케치]`이면 구현 대상이 아니라 구체화 대상임을 보고한다.
8. **결과 보고**
- 종료 가능 여부, 수정/생성한 파일, 실행 검증, spec sync 결과, roadmap archive 결과, 다음 Milestone을 보고한다.
## 실행 결과 검증
- [ ] 대상 Milestone이 활성 경로에서 정확히 하나로 확정되었는가
- [ ] Milestone 상태, 기능 Task, 구현 잠금, 완료 리뷰, SDD gate를 확인했는가
- [ ] 코드/계약/테스트 evidence를 확인했거나 범위 불명확 사유를 보고했는가
- [ ] 작은 보완은 검증까지 수행하고, 큰 보완은 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이 제거되었고 다음 후보 판단에 큐 순서가 반영되었는가
- [ ] 완료 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 후보가 모호한데 자동으로 선택하지 않는다.

View file

@ -0,0 +1,180 @@
---
name: create-agent-ui
version: 1.1.0
description: 프로젝트 코드 또는 문서 근거를 분석해 agent-ui 기본 스캐폴드와 최초 코드 동기화 기준선을 생성하는 스킬
---
# create-agent-ui
## 목적
프로젝트의 기존 UI 코드나 컨셉 문서를 근거로 `agent-ui/` 기본 구조와 UI 정의 초안을 생성한다.
ops/dev UI를 1차 대상으로 하며, 생성 결과를 최초 agent-ui 기준선으로 보고 `.sync-state.json`을 만든다.
## 언제 호출할지
- 사용자가 agent-ui 생성, UI 스캐폴드 생성, 화면 정의 구조 생성을 요청할 때
- 프로젝트에 `agent-ui/`가 없고 기존 코드 또는 문서에서 UI 정의 문맥을 추출할 때
- UI 코드가 있으면 구현 상태와 동기화된 view/component/frame 초안이 필요할 때
- UI 코드가 아직 부족하면 README, roadmap, SDD, docs 같은 컨셉 문서 기반 최소 view tree가 필요할 때
## 입력
- `surface-type`: `ops-dev` 또는 `product`. 기본값은 `ops-dev` (선택)
- `source-mode`: `auto`, `code-first`, `concept-first`, `blank` 중 하나. 기본값은 `auto` (선택)
- `views`: 초기 생성할 view id 목록, kebab-case (선택)
- `components`: 초기 생성할 component id 목록, kebab-case 또는 path id (선택)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules-agent-ui.md`를 읽는다.
- [ ] 생성 대상 `agent-ui/` 존재 여부를 확인한다.
- [ ] 기존 `agent-ui/`가 있으면 덮어쓰지 않고 `update-agent-ui` 또는 `validate-agent-ui` 대상인지 보고한다.
- [ ] 템플릿 경로 `agent-ops/skills/common/_templates/agent-ui/` 하위 파일을 확인한다.
- [ ] `source-mode=auto`이면 UI 코드 후보와 컨셉 문서 후보를 모두 가볍게 확인한다.
- [ ] baseline commit/push를 위해 현재 git status와 HEAD를 확인한다.
- [ ] unrelated dirty worktree가 있으면 baseline commit 전에 범위를 보고하고, agent-ui 생성 파일만 stage한다.
## 실행 절차
1. **생성 대상 확정**
- 생성 루트는 `agent-ui/`로 고정한다.
- `surface-type`이 없으면 `ops-dev`로 둔다.
- `source-mode`가 없으면 `auto`로 둔다.
- product UI가 명시되어도 기본 구조는 유지하고 product 전용 레이어는 요청된 경우에만 추가 후보로 보고한다.
2. **근거 수집**
- `code-first` 또는 `auto`에서는 UI 구현 후보를 찾는다.
- 예: `apps/**/lib/**`, `packages/**/lib/**`, `src/**`, `app/**`, `pages/**`, `screens/**`, `views/**`, `components/**`, `widgets/**`, route/navigation/shell 파일
- 프로젝트 규칙에 dedicated UI domain rule이 있으면 먼저 따른다.
- 코드가 많으면 전체 정독하지 말고 route, shell, page/view, widget/component 이름 중심으로 후보를 좁힌다.
- `concept-first` 또는 `auto`에서는 컨셉 문서 후보를 찾는다.
- 예: `README.md`, `docs/**`, `agent-roadmap/current.md`, 활성 Phase/Milestone, 승인된 SDD, `agent-ops/rules/project/rules.md`
- roadmap 문서는 `agent-ops/rules/common/rules-roadmap.md`의 loading/archive 접근 규칙을 따른다.
- archive 문서는 사용자가 과거 근거를 명시하지 않는 한 읽지 않는다.
- 근거가 없거나 사용자가 빈 구조를 요청하면 `blank`로 처리한다.
3. **source-mode 결정**
- `auto`에서 route, shell, page/view, widget/component 후보 중 하나 이상이 실제 파일 경로로 확인되면 `code-first`로 생성한다.
- UI 구현 후보가 부족하고 컨셉 문서 후보가 있으면 `concept-first`로 생성한다.
- 코드와 문서 근거가 모두 부족하면 `blank`로 생성하고 부족한 근거를 결과에 보고한다.
- 명시된 `views` 또는 `components`는 선택된 mode와 함께 생성 후보로 반영한다.
4. **기본 구조 생성**
- 다음 활성 문서를 템플릿 기준으로 만든다.
- `agent-ui/README.md`
- `agent-ui/definition/index.md`
- `agent-ui/definition/views/index.md`
- `agent-ui/definition/components/index.md`
- `agent-ui/frame/index.md`
- 생성하는 활성 Markdown 문서에는 `rules-agent-ui.md`의 Frontmatter Schema를 적용한다.
- 다음 archive/user-review 디렉터리가 빈 상태로 필요하면 `.gitkeep`을 둘 수 있다.
- `agent-ui/definition/archive/views/`
- `agent-ui/definition/archive/components/`
- `agent-ui/archive/user-review/`
- `USER_REVIEW.md`는 사용자 판단 항목이 있을 때만 만든다.
5. **초기 view 생성**
- `code-first`에서는 구현 코드에서 확인된 route/page/view/shell 단위를 view 후보로 만든다.
- `concept-first`에서는 문서에서 확인된 운영 업무, 화면, 콘솔 영역을 view 후보로 만든다.
- `blank`에서는 명시 `views`가 있을 때만 view 후보를 만든다.
- 각 view 후보마다 다음 문서를 만든다.
- `agent-ui/definition/views/<view-id>/index.md`
- view 문서에는 `Source Evidence``Status`를 반드시 남긴다.
- 코드 근거가 있으면 `status: 구현됨`
- 문서 근거만 있으면 `status: 계획`
- 명시 입력만 있고 근거가 부족하면 `status: 가정`
- 판단 불가하면 `status: 불명확`과 USER_REVIEW 항목을 남긴다.
- 실제 근거 파일이 없으면 frontmatter `source_evidence[].path``null`로 둔다.
- visual source가 없는 초기 view 문서의 frontmatter `frame``null`로 둔다.
- frontmatter의 `status`, `source_evidence`, `regions`와 본문 `Status`, `Source Evidence`, `Regions`가 같은 기준을 말하게 작성한다.
- `.excalidraw` 파일은 사용자가 요청했을 때만 빈 visual source로 만들거나 생성 후보로 보고한다.
- `.excalidraw` 또는 다른 visual source를 만들거나 연결할 때만 `agent-ui/frame/views/<view-id>/index.md`를 만든다.
- `.excalidraw`를 만들거나 연결하면 주요 박스 text label 또는 `customData.region_id`에 region id를 넣는다.
- view id는 kebab-case가 아니면 정규화 후보를 보고하고 사용자 확인이 필요하면 생성하지 않는다.
6. **초기 component 생성**
- `code-first`에서는 반복 widget/component/table/filter/log/status/action 단위를 component 후보로 만든다.
- `concept-first`에서는 문서상 반복 패턴이 분명한 data table, status badge, filter bar, log viewer 같은 구성요소만 component 후보로 만든다.
- `blank`에서는 명시 `components`가 있을 때만 component 후보를 만든다.
- 각 component 후보마다 `agent-ui/definition/components/<component-id>/index.md`를 만든다.
- component 문서에는 `Source Evidence``Status`를 반드시 남긴다.
- 실제 근거 파일이 없으면 frontmatter `source_evidence[].path``null`로 둔다.
- component id가 path id이면 하위 디렉터리 구조로 만든다.
- view에서 참조하지 않는 component도 사용자가 명시했으면 생성할 수 있다.
7. **불확실성 분리**
- 코드와 문서가 충돌하면 임의로 통합하지 않고 `agent-ui/USER_REVIEW.md`에 남긴다.
- view 경계, component 신규 생성 여부, page/drawer/split 같은 UX 판단은 USER_REVIEW로 남긴다.
- 문서 근거만 있는 계획 항목을 구현 완료처럼 쓰지 않는다.
8. **정합성 검증과 baseline 기록**
- 생성 직후 `validate-agent-ui`를 실행해 scaffold와 문서 간 정합성을 확인하고 자동 보정한다.
- `agent-ui/.sync-state.json`에 기록할 baseline 내용을 준비한다.
- `baseline_mode`는 선택된 `source-mode`로 둔다.
- `code-first`, `concept-first`, `blank` 모두 생성된 agent-ui를 최초 기준선으로 본다.
- baseline commit은 두 단계로 남긴다.
- 먼저 `.sync-state.json`을 제외한 agent-ui 생성/보정 파일을 commit한다.
- 그 commit hash를 새 `agent-ui/.sync-state.json``last_synced_head`에 기록한 뒤 별도 commit한다.
- commit message는 예를 들어 `docs(agent-ui): create baseline``sync: record agent-ui baseline`처럼 목적이 분리되게 쓴다.
- 두 commit을 push한다.
- USER_REVIEW가 생성되어도 생성 baseline은 남길 수 있다. 단, 이후 `sync-agent-ui`는 관련 USER_REVIEW가 해결될 때까지 실행하지 않는다.
9. **결과 보고**
- 선택된 `source-mode`
- 읽은 근거 파일과 생성에 사용한 evidence
- 생성한 파일
- 적용한 frontmatter schema
- 생성한 view/component의 status
- USER_REVIEW 생성 여부
- `.sync-state.json` 생성 여부와 baseline commit hash
- baseline commit/push 결과
- product UI 확장 후보
- 후속 권장 작업
## 실행 결과 검증
- [ ] `agent-ui/README.md`가 생성되었는가
- [ ] `definition/index.md`, `definition/views/index.md`, `definition/components/index.md`, `frame/index.md`가 생성되었는가
- [ ] 활성 Markdown 문서가 `ui_doc_type` frontmatter를 포함하는가
- [ ] view/component는 folder-first + `index.md` 구조를 사용하는가
- [ ] 생성한 view/component에 `Source Evidence``Status`가 있는가
- [ ] 구현 근거 없는 항목을 `구현됨`으로 표시하지 않았는가
- [ ] visual source가 없는 view에 빈 `frame/views/<view-id>/index.md`를 만들지 않았는가
- [ ] 코드/문서 충돌이나 UI 의도 판단이 필요한 항목이 USER_REVIEW에 남았는가
- [ ] 같은 레벨에 `<name>.md``<name>/`가 함께 생기지 않았는가
- [ ] archive 본문 파일을 불필요하게 생성하지 않았는가
- [ ] `validate-agent-ui` 결과가 PASS 또는 자동 보정 완료 WARN으로 보고되었는가
- [ ] `.sync-state.json`이 생성되었고 `last_synced_head`가 baseline commit을 가리키는가
- [ ] baseline commit/push가 완료되었는가
- [ ] unrelated dirty file이 baseline commit에 포함되지 않았는가
- 검증 실패 시: 누락된 scaffold만 보완하고 기존 문서를 덮어쓰지 않는다.
## 출력 형식
```md
## 생성 완료
- 루트: agent-ui/
- source-mode: <code-first|concept-first|blank>
- evidence: <주요 근거 파일 목록>
- 생성 파일: <목록>
- frontmatter schema: <적용/부분 적용/없음>
- views: <view-id=status 목록 또는 없음>
- components: <component-id=status 목록 또는 없음>
- USER_REVIEW: <생성/없음>
- sync state: <생성/없음, last_synced_head>
- baseline commit/push: <완료/실패/생략 사유>
- 확인 필요: <항목 또는 없음>
- 후속 권장: <필요 sync-agent-ui 또는 없음>
```
## 금지 사항
- 기존 `agent-ui/` 문서를 덮어쓰지 않는다.
- `.excalidraw` 파일을 현재 UI source of truth로 만들지 않는다.
- 코드나 문서 근거 없이 화면 의도를 확정하지 않는다.
- 문서 근거만 있는 항목을 구현 완료 상태로 쓰지 않는다.
- product UI 전용 레이어를 요청 없이 추가하지 않는다.
- `definition/archive/**``archive/user-review/**`에 현재 기준 문서를 만들지 않는다.
- baseline commit 없이 `.sync-state.json``last_synced_head`를 추정하지 않는다.

View file

@ -0,0 +1,121 @@
---
name: create-contract
version: 1.0.0
description: agent-contract 구조와 inner/outer 계약 문서를 생성한다. 계약 생성해, 프로젝트 계약 생성해, contract 생성, agent-contract 생성, inner/outer 계약 생성 요청에서 사용한다.
---
# create-contract
## 목적
프로젝트에 계약 관리가 필요해진 시점에 `agent-contract/` 구조를 생성하고, 흩어진 문서와 코드에서 확인한 계약을 `inner/outer` 기준으로 정리한다.
계약 문서는 schema 원본을 복제하지 않고, agent가 읽을 수 있는 라우팅, 원본 경로, 필드 의미, 변경 규칙, 검증 포인터를 한 곳에 모은다.
## 언제 호출할지
- 사용자가 계약 생성, 프로젝트 계약 생성, contract 생성, agent-contract 생성을 요청할 때
- API, runtime 호출, wire protocol, event/config schema 같은 계약을 처음 문서화할 때
- 프로젝트에 `agent-contract/`가 없고, 둘 이상의 프로젝트/프로세스/앱/도메인이 맞춰야 하는 요청/응답 경계가 확인될 때
- 기존 README/docs/rules/code에 흩어진 계약 설명을 새 계약 구조로 모아야 할 때
## 입력
- `contract-id`: 계약 식별자, kebab-case 또는 dotted id (선택, 없으면 분석으로 후보 산출)
- `boundary`: `inner` 또는 `outer` (선택, 없으면 실제 소비자와 경계로 판정)
- `scope`: 계약 범위 요약. 예: public HTTP API, worker-runtime protocol, app-server wire (선택, 없으면 코드/문서에서 산출)
- `canonical-path`: proto/OpenAPI/config/code 등 schema 원본 경로 (선택, 없으면 분석으로 찾음)
- `trigger-conditions`: 계약 문서를 읽어야 하는 조건 목록 (선택)
## 분류 기준
- `outer`: 프로젝트 바깥 caller나 다른 프로젝트가 직접 맞춰야 하는 계약이다. 예: 공개 HTTP API, webhook, 외부 SDK, 외부 agent handoff.
- `inner`: 같은 프로젝트 안이어도 프로세스, 앱, 도메인, runtime 경계를 넘는 계약이다. 예: controller-worker proto, service-service wire, app-server WebSocket, runtime request/event/config schema.
- 제외: 한 패키지 내부 private interface, 코드만 보면 충분한 DTO, 안정화되지 않은 실험 구조, 단일 구현 내부 helper.
## 먼저 확인할 것
- [ ] `agent-contract/` 존재 여부를 확인한다.
- [ ] `agent-contract/index.md`가 있으면 읽고 기존 구조와 중복 id를 확인한다.
- [ ] 요청 범위와 관련된 코드, proto, config, README/docs/rules를 읽어 원본 경로와 흩어진 계약 설명을 찾는다.
- [ ] 계약 원문을 이미 docs/README/rules에 길게 복제하고 있는지 확인한다.
## 실행 절차
1. **필요성 판정**
- 둘 이상의 프로젝트/프로세스/앱/도메인이 맞춰야 하는 안정 경계인지 확인한다.
- 단일 패키지 내부 구현이면 계약 문서를 만들지 않고 이유를 보고한다.
- 단건 `contract-id`가 없으면 코드와 문서에서 계약 후보를 수집하고, 안정 경계가 확인된 후보만 생성한다.
- 후보는 있지만 boundary나 원본 경로가 불명확하면 문서를 억지로 만들지 않고 `확인 필요`로 보고한다.
2. **구조 생성**
- `agent-contract/index.md`가 없으면 생성한다.
- `agent-contract/inner/``agent-contract/outer/`가 없으면 생성한다.
- legacy `provided/consumed/`가 있으면 덮어쓰지 않고, 이번 생성 결과와 충돌하는지 보고한다.
3. **코드와 문서 분석**
- 관련 schema 원본을 먼저 찾는다. 우선순위는 proto/OpenAPI/schema 파일, config struct, public DTO/interface, handler/parser, 테스트 fixture 순서다.
- README/docs/rules에 흩어진 계약 설명을 찾고, 계약 문서에 필요한 내용만 추린다.
- 필드 의미는 코드와 테스트에서 확인한 것만 쓴다. 추측은 `확인 필요`로 남긴다.
4. **계약 문서 작성**
- 경로는 `agent-contract/<inner|outer>/<contract-name>.md`로 둔다.
- 여러 계약을 생성해야 하면 각 문서는 독립된 경계 단위로 나누고, 공통 설명은 index가 아니라 각 계약의 원본 경로 포인터로 해결한다.
- 문서는 짧게 유지하고 다음 항목을 포함한다.
- 계약 메타: id, boundary, 원본 경로, status(필요한 경우)
- 읽는 조건
- 범위와 비범위
- 최소 요청/응답 또는 message/event 형태
- 필드 의미와 금지 사항
- 변경 시 확인할 코드/테스트
- 원본 schema 전체를 복제하지 않는다. 긴 schema는 원본 경로와 핵심 필드 의미만 둔다.
5. **index 갱신**
- `Outer Contracts``Inner Contracts` 섹션을 둔다.
- outer/inner 표는 `id`, `읽는 조건`, `원본 경로`, `path`를 둔다.
- 매칭 조건은 agent가 검색/판단할 수 있는 API 이름, message 이름, field 이름, runtime 이름, protocol 이름을 포함한다.
- 프로젝트 전용 path trigger는 공통 rule이 아니라 `agent-contract/index.md``읽는 조건`/`원본 경로` 또는 project/domain rule 포인터로 둔다.
6. **흩어진 문서 정리**
- README/docs/rules에 계약 본문이 중복되어 있으면 원문 경로 포인터로 줄인다.
- domain rule에는 소유권, 경계, 금지 사항만 남기고 상세 schema는 계약 문서 또는 원본 경로를 가리킨다.
- common rule에는 특정 프로젝트 경로, 계약 id, API 이름을 추가하지 않는다. common rule은 `agent-contract/index.md` 조건부 진입까지만 담당한다.
- 사람용 최신 가이드가 필요한 README 문구는 유지하되 계약 원문과 충돌하지 않게 축소한다.
7. **결과 보고**
- 생성한 index와 계약 문서
- boundary 판정 근거
- 원본 경로
- 중복 제거 또는 포인터화한 문서
- 확인 필요 항목
## 실행 결과 검증
- [ ] `agent-contract/index.md`가 생성되고 inner/outer 라우팅 표를 포함하는가
- [ ] 계약 문서가 `agent-contract/inner/` 또는 `agent-contract/outer/` 아래에 있는가
- [ ] 계약 id가 index와 문서 메타에서 일치하는가
- [ ] 원본 경로가 실제 존재하거나 외부 원본으로 명확히 적혀 있는가
- [ ] README/docs/rules에 계약 본문이 중복 복제되지 않고 포인터만 남았는가
- [ ] 코드/proto/config/test 분석 없이 계약을 추정하지 않았는가
- 검증 실패 시: 누락된 index, 문서 메타, 포인터, 원본 경로만 보완한다.
## 출력 형식
```md
## 계약 생성 완료
- index: agent-contract/index.md
- contracts: agent-contract/<inner|outer>/<contract-name>.md
- boundary: <inner|outer> (<근거>)
- 원본 경로: <path 또는 외부 원본>
- pointers: <갱신한 README/docs/rules 경로 또는 없음>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- 모든 내부 interface를 계약 문서로 만들지 않는다.
- 원본 schema 전체를 계약 문서에 장황하게 복제하지 않는다.
- 코드/proto/config/test 확인 없이 필드 의미를 단정하지 않는다.
- README/docs/rules에 계약 본문을 계속 중복 유지하지 않는다.
- 프로젝트 전용 path trigger를 common rule에 넣지 않는다.
- legacy `provided/consumed/` 구조가 있어도 사용자 요청 없이 대량 이동하지 않는다.

View file

@ -0,0 +1,120 @@
---
name: create-domain-rule
version: 1.0.0
description: 새로운 도메인 rules.md 파일을 생성하기 위한 범용 스킬
---
# Create Domain Rule
## 목적
`agent-ops/rules/project/domain/<domain-name>/rules.md` 파일을 올바른 형식으로 생성한다.
실제 프로젝트 폴더 구조를 분석하여 경로와 구성 요소를 자동으로 채운다.
생성 후 `rules/project/rules.md`의 도메인 룰 로딩 안내와 도메인 매핑 테이블을 갱신한다.
생성한 domain rule에는 현재 코드 상태를 어디까지 반영했는지 알 수 있도록 기준 커밋 메타데이터를 기록한다.
## 언제 호출할지
- 새로운 도메인 영역의 코드를 처음 변경하기 전에
- 기존 domain rule이 없는 경로에 대해 규칙이 필요할 때
- 사용자가 특정 도메인의 rule 파일을 만들어 달라고 요청할 때
- agent-ops 초기 scaffold 이후 도메인을 추가 확장할 때
## 입력
- `domain-name`: 생성할 도메인 이름, kebab-case (필수)
- `domain-type`: `core` / `supporting` / `generic` 중 하나 (필수)
- `path-hints`: 이 도메인에 해당하는 경로 힌트 목록 (선택, 없으면 자동 탐색)
## 먼저 확인할 것
- [ ] `agent-ops/rules/project/domain/<domain-name>/rules.md` 가 이미 존재하는지 확인
- [ ] `agent-ops/rules/common/_templates/domain-rule-template.md` 를 읽어 최신 템플릿 형식 파악
- [ ] `agent-ops/rules/project/domain/` 하위 기존 domain rule 목록을 확인하여 중복·유사 도메인 여부 판단
- [ ] `git rev-parse HEAD` 로 기준 커밋을 확인
- 이 값은 생성될 rules.md를 포함하는 미래 커밋 해시가 아니다
- 의미: "이 커밋까지의 코드 상태를 보고 domain rule을 생성했다"
## 실행 절차
1. **중복 확인**
- `agent-ops/rules/project/domain/<domain-name>/` 폴더 존재 여부 확인
- 책임이 겹치는 기존 domain rule 이 있으면 사용자에게 알리고 중단한다
2. **경로 탐색**
- `path-hints` 가 제공된 경우: 해당 경로를 기준으로 폴더 구조 확인
- `path-hints` 가 없는 경우: `domain-name` 과 연관된 폴더명·파일명으로 프로젝트를 탐색
- 실제로 존재하는 경로만 포함 경로에 기재한다
- 존재하지 않는 경로는 기재하지 않는다
3. **도메인 분석**
- 탐색된 경로의 주요 파일·모듈을 읽어 아래를 도출한다
- 도메인의 목적 / 책임 한 줄 요약
- 포함 경로 목록
- 제외 경로 (인접 도메인과 겹칠 수 있는 경로)
- 주요 구성 요소 (파일, 모듈, 클래스, 함수 등)
- 유지할 패턴 (네이밍 규칙, 아키텍처 패턴 등)
- 다른 도메인과의 경계
- 금지 사항
4. **도메인 rules.md 생성**
- 경로: `agent-ops/rules/project/domain/<domain-name>/rules.md`
- `domain-rule-template.md` 형식을 따른다
- frontmatter의 `last_rule_review_commit`에는 생성 직전에 확인한 `git rev-parse HEAD` 값을 기록한다
- frontmatter의 `last_rule_updated_at`에는 생성일을 `YYYY-MM-DD` 형식으로 기록한다
- 실제 코드에서 확인된 내용만 기재한다
- 불확실한 항목은 `<!-- TODO: 확인 필요 -->` 주석으로 남긴다
5. **rules/project/rules.md 업데이트**
- `agent-ops/rules/project/rules.md` 를 읽는다
- `## 도메인 룰 로딩` 섹션이 없으면 `## 도메인 매핑` 바로 위에 아래 형식으로 추가한다
```
## 도메인 룰 로딩
- 아래 도메인 매핑에 해당하는 작업에서 해당 domain 최초 진입 시 domain rule을 1회 읽는다.
- 이미 읽은 domain rule은 같은 세션에서 반복해서 읽지 않는다.
```
- 도메인 매핑 테이블에 아래 형식으로 추가한다
```
| `<path-pattern>` | <domain-name> | `agent-ops/rules/project/domain/<domain-name>/rules.md` |
```
- 경로 패턴은 실제 포함 경로를 기준으로 작성한다
- 기존 로딩 섹션과 테이블 항목을 삭제하거나 재정렬하지 않는다
6. **결과 보고**
- 생성한 파일 경로
- rules/project/rules.md 에 추가한 항목
- 불확실하여 TODO로 남긴 항목 (해당 시)
## 출력 형식
```
## 생성 완료
- Domain Rule 경로: agent-ops/rules/project/domain/<domain-name>/rules.md
- 도메인 유형: <core | supporting | generic>
- 도메인 룰 로딩 섹션: <추가함 | 이미 존재함>
- rules/project/rules.md 추가 경로 패턴: <path-pattern>
## TODO 항목 (확인 필요)
- <불확실하여 직접 확인이 필요한 항목> (해당 시)
```
## 실행 결과 검증
- [ ] `agent-ops/rules/project/domain/<domain-name>/rules.md` 파일이 생성되었는가
- [ ] 생성된 파일이 `domain-rule-template.md`의 frontmatter와 모든 섹션(목적, 포함 경로, 제외 경로, 주요 구성 요소, 유지할 패턴, 경계, 금지 사항)을 포함하는가
- [ ] `last_rule_review_commit`이 생성 직전 `HEAD`를 가리키는가
- [ ] `rules/project/rules.md`에 도메인 룰 로딩 섹션이 존재하는가
- [ ] `rules/project/rules.md`의 도메인 매핑 테이블에 해당 도메인 항목이 추가되었는가
- [ ] 포함 경로에 기재된 경로가 실제로 프로젝트에 존재하는가
- 검증 실패 시: 누락된 섹션 또는 잘못된 경로를 사용자에게 알리고 해당 부분만 보완한다
## 금지 사항
- 이미 존재하는 rules.md 를 덮어쓰지 않는다
- 실제 존재하지 않는 경로를 포함 경로에 넣지 않는다
- 추측으로 패턴이나 금지 사항을 채우지 않는다 — 확인된 내용만 기재한다
- rules/project/rules.md 의 기존 로딩 섹션과 테이블 항목을 삭제하거나 재정렬하지 않는다
- 하나의 domain rule 에 여러 독립 도메인의 책임을 묶지 않는다
- 코드 변경을 수행하지 않는다 — 이 skill 은 rule 파일 생성만 담당한다

View file

@ -0,0 +1,93 @@
---
name: create-handoff
version: 1.0.0
description: 작업을 다른 세션이나 다른 에이전트가 이어받을 수 있도록 핸즈오프 기록을 남기는 공통 스킬. "핸즈오프 남겨", "인수인계 작성", "다른 세션에서 이어가게 정리", "작업을 이어받도록 기록" 같은 요청에 사용한다.
---
# Create Handoff
## 목적
현재 작업 상태를 중단 없이 이어받을 수 있도록 짧고 검증 가능한 핸즈오프 기록을 남긴다.
핸즈오프는 새 구현 계획이나 코드 변경을 시작하는 절차가 아니라, 현재 상태와 다음 진입점을 보존하는 절차다.
## 언제 호출할지
- 사용자가 작업을 다른 세션, 다른 에이전트, 또는 이후 자기 자신이 이어가게 정리해 달라고 할 때
- 긴 작업 중 현재 판단, 변경 파일, 남은 검증, 차단 사항을 지속 가능한 문서에 남겨야 할 때
- 구현을 계속하지 않고 현재 위치만 안전하게 넘겨야 할 때
- 실패한 검증이나 외부 환경 상태를 다음 세션이 오해하지 않도록 남겨야 할 때
## 입력
- `handoff-request`: 사용자가 남기라고 한 핸즈오프 요청 문장 (필수)
- `target`: 현재 작업 대상 Phase, Milestone, plan, review, task group, issue, PR, 파일 경로 등 (선택)
- `evidence`: 이번 세션에서 확인한 명령, 테스트, 로그, 외부 상태, 사용자 결정 (선택)
## 먼저 확인할 것
- [ ] 현재 작업 대상이 명시되어 있으면 해당 활성 문서나 파일을 확인한다.
- [ ] 대상이 없으면 로컬 current, 활성 PLAN/CODE_REVIEW/USER_REVIEW, git diff, 최근 대화 맥락 중 가장 좁은 충분한 대상으로 정한다.
- [ ] 기존 핸즈오프 섹션이나 `HANDOFF.md`가 있으면 새 위치를 만들기 전에 갱신 후보로 본다.
- [ ] archive 경로는 일반 작업에서 읽지 않는다. 사용자가 archive 확인을 명시했거나 활성 문서가 특정 archive evidence를 가리킬 때만 필요한 파일을 좁게 읽는다.
- [ ] secret, token, private endpoint 원문, 서명값, 개인 credential은 핸즈오프에 기록하지 않는다.
## 실행 절차
1. **상태 수집**
- `git status --short`로 변경 파일과 untracked 파일을 확인한다.
- 필요한 경우 대상 파일의 diff 또는 관련 문서를 읽어 이번 세션에서 실제로 바뀐 내용과 바뀌지 않은 내용을 분리한다.
- 실행 중인 서버, 원격 runner, 외부 provider 같은 live 상태가 handoff에 영향을 주면 secret 없이 요약한다.
2. **기록 위치 선택**
- 활성 Milestone이 작업의 장기 기준이면 해당 Milestone의 `작업 컨텍스트` 아래에 `핸즈오프(<YYYY-MM-DD>)` 항목을 추가하거나 갱신한다.
- 활성 plan/review/task group이 작업의 실행 기준이면 그 디렉터리의 기존 `PLAN-*.md`, `CODE_REVIEW-*.md`, `USER_REVIEW.md`, 또는 `HANDOFF.md` 중 가장 직접적인 파일에 남긴다.
- 적절한 활성 문서가 없으면 새 파일을 만들기보다 최종 답변에만 남길지 판단하고, 지속 기록이 필요하면 가장 좁은 활성 작업 디렉터리 아래 `HANDOFF.md`를 만든다.
- 같은 내용을 여러 곳에 중복 기록하지 않는다. 필요하면 한 곳에 기록하고 다른 문서에는 짧은 링크만 남긴다.
3. **핸즈오프 작성**
- 현재 타겟과 다음 세션의 첫 진입 파일을 적는다.
- 이번 세션에서 실제로 한 일과 하지 않은 일을 분리한다.
- 남은 작업을 실행 순서로 적되, 구현 세부 계획으로 과하게 확장하지 않는다.
- 검증한 명령과 결과, 생략한 검증과 사유를 남긴다.
- dirty worktree, untracked 파일, 원격 환경, 외부 provider 상태처럼 다음 세션이 오해하기 쉬운 조건을 남긴다.
- 사용자 결정이나 명시 금지 사항을 그대로 보존한다.
4. **검증**
- 수정한 Markdown이나 text 파일에 대해 `git diff --check`를 실행한다.
- 새 `HANDOFF.md`를 만들었다면 경로가 active 작업 범위 안인지 확인한다.
- 핸즈오프가 완료/검토중/통과 같은 상태 전환을 암시하지 않는지 확인한다.
5. **결과 보고**
- 핸즈오프를 남긴 경로를 보고한다.
- 다음 세션이 바로 열어야 할 파일 1~3개를 보고한다.
- 검증 명령과 결과를 보고한다.
## 실행 결과 검증
- [ ] 핸즈오프가 지속 가능한 활성 문서나 가장 좁은 작업 디렉터리에 남아 있다.
- [ ] 현재 타겟, 실제 변경, 남은 작업, 검증 상태, 주의사항이 구분되어 있다.
- [ ] secret 또는 credential 원문이 기록되지 않았다.
- [ ] archive 문서를 불필요하게 읽거나 최신 형식으로 재작성하지 않았다.
- [ ] `git diff --check`가 통과했다.
- 검증 실패 시: 핸즈오프 문서만 보완하고, 본 작업 구현이나 상태 전환은 진행하지 않는다.
## 출력 형식
```markdown
## 핸즈오프 완료
- 위치: `<handoff-path>`
- 현재 타겟: `<target>`
- 다음 진입점: `<file-or-command>`
- 검증: `<command>` PASS
- 남은 주의: `<요약 또는 없음>`
```
## 금지 사항
- 핸즈오프 요청만 받았는데 새 구현, 테스트 보강, 리팩터링, 원격 배포를 시작하지 않는다.
- evidence 없이 완료, 검토중, PASS, archive 같은 상태 전환을 하지 않는다.
- secret, token, private signing key, password, 원문 credential을 기록하지 않는다.
- 여러 문서에 같은 핸즈오프 전문을 중복 작성하지 않는다.
- 사용자 또는 다른 에이전트가 만든 unrelated 변경을 되돌리지 않는다.

View file

@ -0,0 +1,156 @@
---
name: create-readme
version: 1.1.0
description: README 작성, README 생성, 프로젝트 설명 문서 작성 요청에 대해 사람이 읽기 쉽고 AI가 다음 작업에 바로 활용할 수 있는 표준형 README.md를 생성하는 공통 스킬
---
# README 생성
## 목적
프로젝트 루트의 `README.md`를 표준형으로 작성한다.
README는 사람에게 프로젝트의 목적과 사용법을 설명하면서, AI 에이전트가 다음 작업에서 빠르게 맥락을 파악하고 실행할 수 있는 작업 안내 문서가 되도록 구성한다.
## 언제 호출할지
- 사용자가 "README 작성해줘", "README 만들어줘", "프로젝트 설명 문서 만들어줘"라고 요청할 때
- 프로젝트 루트에 `README.md`가 없거나 내용이 비어 있을 때
- 기존 README가 제품 설명, 실행 방법, 구조, 검증 명령을 충분히 담지 못해 초기 정리가 필요할 때
- AI 에이전트가 프로젝트를 이어서 작업할 수 있도록 핵심 맥락을 한 문서에 모아야 할 때
## 입력
- `project-name`: README에 사용할 프로젝트 이름 (선택, 없으면 repo 이름 또는 package metadata에서 추론)
- `audience`: 주요 독자 또는 사용자 (선택)
- `purpose`: 프로젝트 목적 한 줄 요약 (선택)
- `scope`: README에 포함할 범위 또는 제외할 범위 (선택)
- `overwrite`: 기존 README 덮어쓰기 허용 여부 (선택, 명시 없으면 덮어쓰지 않음)
## README 표준 구성
README는 프로젝트 특성에 맞게 필요한 섹션만 사용하되, 기본 순서는 아래를 따른다.
```markdown
# <project-name>
<프로젝트 목적 1~3문장>
## 현재 상태
<개발 단계, 사용 가능 범위, 중요한 제약>
## 빠른 시작
<설치, 실행, 테스트의 최소 명령>
## 주요 명령
| 목적 | 명령 | 비고 |
|------|------|------|
## 구조
| 경로 | 역할 |
|------|------|
## 작업 맥락
<AI가 다음 작업에서 먼저 알아야 규칙, 문서, 로드맵, 주요 경계>
## 개발 흐름
<브랜치, 테스트, 검증, 리뷰 또는 배포 흐름>
## 환경 변수
| 이름 | 설명 | 필수 |
|------|------|------|
## 참고 문서
- <관련 문서 경로>
```
## AI-first 작성 기준
- README 상단에는 프로젝트가 무엇을 해결하는지와 현재 사용할 수 있는 범위를 먼저 쓴다.
- AI가 작업을 이어받을 때 필요한 경로, 명령, 검증 방법, 주요 문서를 명확한 제목과 표로 정리한다.
- `agent-ops/`가 있으면 규칙, 로드맵, 스킬 문서를 참고 문서나 작업 맥락에 연결한다.
- 로컬 `agent-roadmap/current.md`가 있으면 README에 현재 작업 위치를 복사하지 말고, 로드맵을 확인할 문서 경로만 적는다.
- README는 제품 소개 문서이면서 작업 진입점이다. 마케팅 문구보다 실행 가능한 정보와 프로젝트 경계를 우선한다.
- README의 자연어 설명은 한국어 중심으로 작성한다.
- 단, README, API, CLI, SDK, runtime, build, test, lint, deploy, workflow, migration, integration처럼 개발자가 흔히 쓰는 영어 표현과 제품명, 기술명, 패키지명, 명령, 경로, 코드 식별자는 자연스럽게 영어로 유지한다.
- 널리 쓰이는 기술 영어를 억지로 번역하지 말고, 사람과 AI가 함께 읽기 쉬운 표현을 우선한다.
- 불확실한 내용은 단정하지 않고 `TODO` 또는 "확인 필요"로 남긴다.
## 먼저 확인할 것
- [ ] 루트 `README.md` 존재 여부와 기존 내용 확인
- [ ] `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `Makefile`, `docker-compose.yml` 등 실행/검증 명령 근거 확인
- [ ] `agent-ops/rules/project/rules.md`가 있으면 프로젝트 개요, 기술 스택, 도메인 매핑 확인
- [ ] `agent-roadmap/ROADMAP.md` 또는 로컬 `agent-roadmap/current.md`가 있으면 제품 방향과 활성 Milestone 문서 경로만 확인
- [ ] 주요 소스 디렉터리와 테스트 디렉터리를 `rg --files`로 가볍게 확인
## 실행 절차
1. **기존 README 처리 결정**
- `README.md`가 없으면 새로 생성한다.
- `README.md`가 있고 사용자가 덮어쓰기를 명시하지 않았으면 기존 내용을 보존하고, 필요한 섹션만 보완한다.
- 기존 README의 제품 설명, 설치/실행 명령, 경고, 라이선스, 배포 정보를 삭제하지 않는다.
2. **프로젝트 근거 수집**
- metadata 파일에서 프로젝트 이름, 설명, scripts, dependencies, runtime을 확인한다.
- Makefile, compose 파일, CI 설정, 테스트 설정에서 실행 명령과 검증 명령을 확인한다.
- 소스 구조는 전체 정독하지 않고 README 작성에 필요한 상위 경로와 대표 진입점만 확인한다.
- 명령을 추론해야 하면 "추정"으로 쓰지 말고 TODO로 남긴다.
3. **README 초안 작성**
- 표준 구성 순서를 기준으로 프로젝트에 맞는 섹션을 선택한다.
- 빠른 시작에는 최소 실행 경로를 짧게 쓴다.
- 주요 명령 표에는 실제로 확인한 명령만 넣는다.
- 구조 표에는 AI가 작업 범위를 잡는 데 도움이 되는 경로만 넣는다.
- 작업 맥락에는 agent-ops 문서, 로드맵, 도메인 규칙, 중요한 작업 경계를 연결한다.
4. **기존 내용 병합**
- 기존 README가 있으면 중복 섹션을 합치고 정보가 더 정확한 쪽을 남긴다.
- 확인 근거가 없는 오래된 내용은 삭제하지 말고 "확인 필요"로 표시한다.
- 문서의 제목, 명령, 경로 표기가 실제 파일과 맞는지 확인한다.
5. **결과 보고**
- 생성 또는 수정한 README 경로
- 확인한 실행/테스트 명령
- TODO 또는 확인 필요로 남긴 항목
- 덮어쓰지 않고 보존한 기존 주요 내용
## 실행 결과 검증
- [ ] 루트 `README.md`가 존재하는가
- [ ] 프로젝트 목적, 빠른 시작, 주요 명령, 구조, 작업 맥락 중 프로젝트에 필요한 섹션이 포함되어 있는가
- [ ] README에 적은 명령이 실제 설정 파일 또는 프로젝트 관례에서 확인된 명령인가
- [ ] README에 적은 경로가 실제로 존재하는가
- [ ] agent-ops 문서를 복사해 중복하지 않고 필요한 경로만 연결했는가
- [ ] 불확실한 내용이 단정 표현이 아니라 TODO 또는 확인 필요로 남아 있는가
- 검증 실패 시: README의 해당 항목만 보완하고, 근거 없는 내용을 새로 만들지 않는다.
## 출력 형식
```markdown
## README 작성 완료
- README: README.md
- 처리 방식: <생성 | 보완 | 재작성>
- 확인한 명령:
- <command>
## 확인 필요
- <TODO 또는 확인 필요 항목> (해당 시)
```
## 금지 사항
- 사용자가 명시하지 않은 상태에서 기존 README를 통째로 덮어쓰지 않는다.
- 확인하지 않은 설치, 실행, 테스트, 배포 명령을 사실처럼 쓰지 않는다.
- README를 긴 내부 설계 문서로 만들지 않는다. 상세 규칙은 `agent-ops/` 문서로 연결한다.
- README에 개인 설정, 비밀값, 로컬 전용 경로를 넣지 않는다.
- 로드맵이나 도메인 규칙 내용을 README에 길게 복사하지 않는다.

View file

@ -0,0 +1,234 @@
---
name: create-roadmap
version: 1.19.0
description: AI-first 개인/소규모 프로젝트의 전체 목표, Phase scaffold, Phase 하위 Milestone 문서, 전역 priority-queue.md 실행 순서 문서, 로컬 current.md 활성 Phase/Milestone 창, archive Phase scaffold를 처음 생성하고, agent-ui 코드 동기화 Milestone의 완료 리뷰 상태 반영 항목을 포함하는 공통 스킬
---
# 로드맵 생성
## 목적
`agent-roadmap/` 하위에 `Roadmap -> priority-queue -> Phase -> Milestone` 기반 한국어 로드맵 구조를 처음 생성한다.
전체 로드맵은 전체 방향과 Phase index만 담당하고, 일반 작업에서는 브랜치별 로컬 `current.md`의 활성 Phase/Milestone 링크와 관련 문서만 읽도록 만든다.
`priority-queue.md`는 Phase를 가로지르는 실행 순서만 담당한다.
Milestone은 구현 계획이 아니라 방향성, 범위, 위험, 확인 필요 사항을 기록하는 협업 문서다.
Epic과 Task는 별도 파일로 분리하지 않고 Milestone 문서의 `기능` 안에서 관리한다. 별도 `완료 기준` 섹션은 만들지 않고, 검증이 필요한 기능에만 같은 Task 안의 `검증:` 문구로 통합한다.
## 언제 호출할지
- 프로젝트에 파일 기반 로드맵을 처음 만들 때
- 사용자가 "로드맵 만들어줘", "마일스톤 설계해줘", "goal/phase 구조 잡아줘"라고 요청할 때
- 기존 README나 메모에 흩어진 계획을 `agent-roadmap/` 구조로 분리할 때
## 입력
- `overall-goal`: 프로젝트 전체 목표 한 줄 또는 짧은 문단 (선택, 없으면 README와 현재 구조에서 추론)
- `phase-hints`: 예상 Phase 목록 또는 단계 힌트 (선택)
- `milestone-hints`: 예상 Milestone 목록 또는 기능 힌트 (선택)
- `active-phases`: 현재 열어둘 Phase 목록 (선택, 없으면 현재 구현 상태와 요청에서 추론)
- `active-milestones`: 현재 열어둘 Milestone 목록 (선택, 없으면 현재 구현 상태와 요청에서 추론)
## 생성 구조
```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
```
| 파일 | 역할 |
|------|------|
| `agent-roadmap/ROADMAP.md` | 전체 목표와 Phase 흐름만 담는 최상위 지도. 로드맵 생성/갱신/Phase 전환 때만 읽는다 |
| `agent-roadmap/priority-queue.md` | Phase를 가로지르는 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 스냅샷과 해결된 사용자 리뷰 로그 |
## 템플릿
- `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`는 순서 전용 문서이며, Milestone 제목 링크와 식별용 한 줄 설명만 둔다.
- `current.md`는 git 추적 대상이 아니며, 예시 파일을 `agent-roadmap/`에 따로 만들지 않는다.
- `current.md`는 활성 Phase/Milestone 후보만 담고, 개인별 현재 작업 위치나 완료 상태를 적지 않는다.
- archive 경로는 `current.md`의 활성 항목에 넣지 않는다.
## 작성 규칙
- 기본 작성 언어는 한국어다.
- 상태 표기는 `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
- `[스케치]`는 방향성, 문제의식, 후보 범위, 미정 질문을 기록하는 컨셉 상태다. 구현 가능한 계획이 아니므로 구현 계획 생성 대상이 아니다.
- `[계획]`은 목표, 범위, 기능 Task, 구현 잠금, 결정 필요 항목이 문서화되어 잠금 해제 후 구현 계획을 만들 수 있는 상태다.
- Phase와 Milestone 이름, 파일명에는 `1`, `2`, `M01`, `P1` 같은 순번을 붙이지 않는다.
- Phase 흐름은 실행 순서가 아니라 도메인/책임 영역의 구조적 지도다.
- Phase를 가로지르는 실제 실행 순서는 `priority-queue.md`의 위에서 아래 순서로 표현한다.
- `priority-queue.md`에는 상태, 목표, 범위, 잠금, 기능, 완료 근거, 의존성 필드를 복제하지 않는다.
- 실행 후보가 없더라도 `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을 끼워 넣을 수 있도록 기존 항목의 이름과 파일명을 불필요하게 바꾸지 않는다.
- 로드맵 문서 안에서 다른 로드맵 문서, 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에서 필수다. `[계획]` 이상 상태에서는 섹션을 생략하거나 `- 없음`으로 둘 수 있다.
- `[스케치]` 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] <이름>` 형식으로 작성한다.
- Task는 `- [ ] [item-id] 설명` 형식으로 작성한다.
- epic-id와 item-id는 공백 없는 짧은 ASCII 토큰이며, 해당 Milestone 안에서만 유일하면 된다.
- 검증이 필요한 Task에만 같은 항목 안에 `검증: <명령/확인 방법/기대 결과>`를 붙인다. 검증이 필요 없는 기능에는 억지 검증을 붙이지 않는다.
- `완료 리뷰`는 새 Milestone에서는 `상태: 없음`, `요청일: 없음`으로 두고, 모든 기능 Task와 Task 안에 명시된 검증이 충족되고 `구현 잠금`이 해제된 뒤 에이전트/런타임 완료 근거를 기록할 때 갱신한다. 에이전트가 확정할 수 없는 결정 항목은 완료 리뷰가 아니라 `구현 잠금 > 결정 필요` 또는 SDD `USER_REVIEW.md`로 분리한다.
- `agent-ui 상태 반영` 항목은 모든 신규 Milestone의 `완료 리뷰`에 두고 기본값은 `해당 없음`으로 적는다.
- `sync-agent-ui``milestone-required` 코드 작업 라우팅으로 생성/갱신하는 Milestone, 또는 사용자가 Milestone 종료 검토에서 agent-ui 구현 상태 반영을 명시한 Milestone만 `agent-ui 상태 반영: 대기`로 둔다.
- `대기` Milestone은 종료 검토에서 최종 검증과 code evidence가 확인된 agent-ui view/component/frame만 `구현됨`으로 반영한다.
- `범위`, `범위 제외`, `작업 컨텍스트`는 설명 목록으로 작성하고, 실행해야 할 작업을 이 섹션에 숨기지 않는다.
## 먼저 확인할 것
- [ ] `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 체크리스트를 둔다.
4. **파일 생성**
- `ROADMAP.md`, `priority-queue.md`, 로컬 `current.md`, 각 Phase의 `PHASE.md`, 각 Milestone 문서를 템플릿 순서대로 생성한다.
- `ROADMAP.md` 최상단에는 `priority-queue.md`를 먼저 확인하도록 `고정 실행 순서` 섹션을 둔다.
- `priority-queue.md`에는 Phase를 가로지르는 실행 후보 Milestone을 위에서 아래 순서로 둔다. 후보가 없으면 `실행 순서` 섹션만 비워 둔다.
- 활성 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 파일을 가리키는지 확인한다. 실행 후보가 없어서 빈 큐이면 정상으로 보고하되, 활성 실행 후보가 있는데 비어 있으면 큐 동기화 필요로 본다.
- 생성한 로드맵 문서의 문서/산출물 포인터가 raw path만 남지 않고 Markdown 링크로 작성되었는지 확인한다.
- 생성한 로드맵 문서의 Markdown 링크 target에 템플릿 placeholder가 남지 않았는지 확인한다.
- 로컬 `current.md` 활성 항목에 `agent-roadmap/archive/**` 경로가 없는지 확인한다.
- Epic heading과 Task 체크리스트 id가 형식을 따르는지 확인한다.
- 상태 표기가 `[진행중]`처럼 공백 없는 표준값인지 확인한다.
- `[스케치]` 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 문서에 `완료 리뷰` 섹션이 있는지 확인한다.
- `sync-agent-ui``milestone-required` 코드 작업 라우팅으로 생성/갱신한 Milestone이면 `완료 리뷰``agent-ui 상태 반영: 대기`가 있고, 그 외 Milestone은 `agent-ui 상태 반영: 해당 없음`인지 확인한다.
## 출력 형식
```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 이름 또는 파일명에 순번을 강제하지 않는다.
- `ROADMAP.md`에 Milestone 상세 작업 체크리스트를 넣지 않는다.
- Epic과 Task를 별도 파일로 분리하지 않는다.
- Milestone 문서에서 `구현 잠금` 섹션을 생략하지 않는다.
- 에이전트가 확정할 수 없는 결정 항목이 남아 있는데 새 Milestone을 `해제` 상태로 만들지 않는다.
- 확정되지 않은 제품 방향을 사실처럼 단정하지 않는다.

View file

@ -0,0 +1,101 @@
---
name: create-skill
version: 1.0.0
description: 새로운 SKILL.md 파일을 생성하기 위한 범용 스킬
---
# Create Skill
## 목적
`agent-ops/skills/` 하위에 올바른 형식의 SKILL.md 파일을 생성한다.
기존 skill-template.md 를 기반으로, 요청 목적에 맞는 내용을 채워 넣는다.
생성 후 라우팅 항목을 추가한다.
이 스킬은 프로젝트 내부 `agent-ops` 라우터가 읽는 스킬을 만든다.
`$CODEX_HOME/skills`에 설치되어 Codex가 직접 discover하는 스킬을 만들 때는 시스템 `skill-creator` 규칙을 우선하고, frontmatter는 `name``description`만 사용한다.
### 생성 위치 결정
- `.agent-ops-source` 파일이 **있으면** (공통 관리 레포): `agent-ops/skills/common/<skill-name>/SKILL.md`
- `.agent-ops-source` 파일이 **없으면** (타겟 프로젝트): `agent-ops/skills/project/<skill-name>/SKILL.md`
## 언제 호출할지
- 새로운 반복 작업 패턴이 생겨 skill로 정의해야 할 때
- 기존 skill이 없는 작업 유형을 처음 수행하기 전에
- 사용자가 특정 작업을 skill로 만들어 달라고 요청할 때
## 입력
- `skill-name`: 생성할 skill 이름, kebab-case (필수)
- `purpose`: 이 skill이 해결하는 문제 한 줄 요약 (필수)
- `trigger-cases`: 이 skill을 호출해야 하는 상황 목록 (선택)
## 먼저 확인할 것
- [ ] `agent-ops/skills/common/``agent-ops/skills/project/` 하위에 동일 이름의 디렉터리가 이미 존재하는지 확인
- [ ] `agent-ops/skills/common/router.md``agent-ops/rules/project/rules.md` 에 이미 유사한 라우팅 항목이 있는지 확인
- [ ] `agent-ops/skills/common/_templates/skill-template.md` 를 읽어 최신 템플릿 형식 파악
## 실행 절차
1. **중복 확인**
- `agent-ops/skills/common/<skill-name>/``agent-ops/skills/project/<skill-name>/` 폴더 존재 여부 확인
- 기능이 겹치는 기존 skill이 있으면 사용자에게 알리고 중단한다
2. **목적 분석**
- `purpose``trigger-cases` 를 바탕으로 아래 항목을 도출한다
- 언제 호출할지 (2~4개)
- 필요한 입력 파라미터
- 사전 확인 항목
- 실행 절차 (3~7단계)
- 출력 형식
- 금지 사항
3. **SKILL.md 생성**
- 경로: 생성 위치 결정 규칙에 따라 `common/` 또는 `project/` 하위에 생성
- `skill-template.md` 형식을 따른다
- agent-ops 내부 스킬은 기존 로컬 관례에 맞춰 `version`을 둘 수 있다. Codex 설치형 스킬로 배포할 목적이면 `version`이나 `depends` 같은 비표준 frontmatter를 넣지 않는다.
- 프로젝트 특화 내용보다 범용 절차를 우선한다
- 절차는 구체적이되 지나치게 세부 구현을 기술하지 않는다
4. **라우팅 업데이트**
- `.agent-ops-source` 마커가 **있으면** (공통 관리 레포): `agent-ops/skills/common/router.md`에 라우팅 항목 추가
- `.agent-ops-source` 마커가 **없으면** (타겟 프로젝트): `agent-ops/rules/project/rules.md`의 프로젝트 스킬 라우터 섹션에 라우팅 항목 추가
- 기존 공통 스킬을 수정해 trigger가 달라졌다면 새 skill을 만들지 말고 `agent-ops/skills/common/router.md`의 기존 행을 갱신한다
- 이 skill이 속할 라우팅 축(구조 분석/코드 변경/흐름 추적 등)을 판단한다
- 기존 라우팅 구조를 깨지 않는다
5. **결과 보고**
- 생성한 파일 경로
- 라우팅 항목을 추가한 파일과 내용
- 이 skill이 다루지 않는 범위(필요 시)
## 출력 형식
```
## 생성 완료
- SKILL 경로: agent-ops/skills/{common|project}/<skill-name>/SKILL.md
- 라우팅 추가: <대상 파일><라우팅 ><skill-name>
## 주의사항 (해당 시)
- < skill이 다루지 않는 범위 또는 주의할 >
```
## 실행 결과 검증
- [ ] `agent-ops/skills/{common|project}/<skill-name>/SKILL.md` 파일이 생성되었는가
- [ ] 생성된 파일이 `skill-template.md`의 필수 섹션(목적, 언제 호출할지, 실행 절차, 실행 결과 검증, 출력 형식, 금지 사항)을 포함하는가
- [ ] frontmatter에 name, description이 올바르게 기재되었는가
- [ ] agent-ops 내부 스킬이면 version 등 로컬 관례를 따르고, Codex 설치형 스킬이면 시스템 `skill-creator` frontmatter 규칙을 따르는가
- [ ] 라우팅 대상 파일에 해당 스킬의 라우팅 항목이 추가되었는가
- 검증 실패 시: 누락된 섹션 또는 라우팅 항목을 사용자에게 알리고 해당 부분만 보완한다
## 금지 사항
- 이미 존재하는 skill 을 덮어쓰지 않는다
- 프로젝트 특화 경로(예: `app/screens/`)를 skill 본문에 하드코딩하지 않는다
- skill 생성과 무관한 코드 파일을 수정하지 않는다
- 라우팅 대상 파일의 기존 항목을 삭제하거나 재정렬하지 않는다
- 하나의 skill 에 여러 독립적인 책임을 묶지 않는다

View file

@ -0,0 +1,117 @@
---
name: create-spec
version: 1.0.0
description: agent-spec 최초 생성, 현재 구현 스펙 작성, living spec bootstrap, 완료된 기능의 구현 스펙 신규 문서화 요청에 사용한다. 코드/계약/테스트/로드맵 근거를 바탕으로 agent-spec/index.md와 매칭 spec 문서를 생성한다.
---
# create-spec
## 목적
현재 구현된 기능의 living spec을 새로 만든다.
스펙은 로드맵 완료 이력이나 계약 원문을 복제하지 않고, 사람과 agent가 구현된 기능, 동작 흐름, 계약/검증 포인터를 함께 확인하는 문서로 유지한다.
## 언제 호출할지
- 사용자가 "스펙 생성", "구현 스펙 작성", "현재 구현 문서화", "agent-spec 생성"을 요청할 때
- agent-spec을 처음 도입해 `agent-spec/index.md`와 초기 spec 문서를 만들 때
- 완료된 기능이나 활성 기능에 대응되는 현재 구현 spec 문서가 없고, 새 spec 작성이 필요한 때
- `complete-milestone` 또는 `update-spec`에서 관련 spec이 없지만 evidence가 충분해 신규 작성이 필요하다고 판단한 때
## 입력
- `mode`: `bootstrap` 또는 `targeted`. 기본값은 요청에서 추론한다. (선택)
- `spec-id`: 만들 spec id. `<area>/<spec-id>` 형식을 권장한다. (선택)
- `target-milestone`: spec 근거로 삼을 활성 또는 명시 Milestone 경로, 이름, slug. (선택)
- `source-paths`: 우선 확인할 코드, 계약, 테스트, docs 경로 목록. (선택)
- `evidence`: complete.log, SDD, 사용자 설명, 검증 결과 등 보조 근거. (선택)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules-agent-spec.md`를 읽는다.
- [ ] `agent-spec/` 존재 여부와 `agent-spec/index.md` 존재 여부를 확인한다.
- [ ] `agent-ops/skills/common/_templates/agent-spec/index-template.md``spec-template.md`를 확인한다.
- [ ] 계약에 닿는 spec이면 `agent-contract/index.md`를 읽고 매칭 계약 문서만 읽는다.
- [ ] 로드맵 근거가 필요하면 활성 Milestone/SDD만 우선 읽고, archive는 사용자가 명시했거나 현재 스펙 배경 확인에 꼭 필요한 링크만 좁게 읽는다.
## 실행 절차
1. **범위 결정**
- 요청을 `bootstrap` 또는 `targeted`로 분류한다.
- `targeted`이면 spec 하나의 기능 범위와 `spec-id`를 정한다.
- `bootstrap`이면 프로젝트 전체를 완성하려 하지 말고, 코드/계약으로 확인 가능한 핵심 축과 spec 후보 목록을 먼저 만든다.
- `spec-id`는 소문자 영문, 숫자, 하이픈, `/`만 사용한다.
2. **근거 수집**
- 코드, 계약, 테스트, 설정 예시, README/docs, 활성 roadmap/SDD, complete.log 순서로 현재 동작 근거를 확인한다.
- 현재 동작은 코드와 계약으로 재확인한다.
- 로드맵 archive 또는 agent-task archive는 일반 탐색하지 않는다.
- 확인할 수 없는 내용은 `불명확` 또는 `확인 필요`로 둔다.
3. **agent-spec 구조 생성**
- `agent-spec/`가 없으면 만든다.
- `agent-spec/index.md`가 없으면 index template으로 만든다.
- 필요한 `<area>/` 디렉터리를 만든다.
- 기존 같은 `spec-id` 문서가 있으면 새로 만들지 말고 `update-spec` 대상이라고 보고한다.
4. **spec 문서 작성**
- spec template의 기본 섹션 구조를 따른다.
- frontmatter의 `spec_doc_type`, `spec_id`, `status`, `source_evidence`를 채운다.
- `status`는 evidence 수준에 따라 `구현됨`, `부분`, `가정`, `불명확` 중 하나로 둔다.
- `기능 목록``목적` 다음에 바로 둔다.
- 기능 목록은 `기능``설명` 중심으로 작성한다. 기능별 `상태` 칼럼은 기본 생성하지 않는다.
- `주요 흐름`은 Mermaid `sequenceDiagram` 또는 `flowchart`를 우선 고려한다. 단순 기능은 짧은 목록으로 둔다.
- 책임 경계는 기능 이해에 필요한 최소 수준만 적고, 도메인별 코드 배치나 금지 사항은 domain rule로 넘긴다.
- 계약 원문, proto field 전체 목록, config schema 원문은 복제하지 않고 링크한다.
- `코드 진입점` 섹션은 만들지 않는다. 코드 근거는 `source_evidence`에 남긴다.
- 검증 방법은 실행 가능한 명령 또는 확인 기준으로 남긴다.
5. **index 갱신**
- `Spec Map`에 새 spec id, 상태, 읽는 조건, path, 주요 근거를 추가하거나 보정한다.
- 매칭 조건은 agent가 좁게 읽을 수 있도록 기능명, 코드 경로, 계약 id, 운영 표면 중심으로 쓴다.
- 기존 행을 삭제하거나 재정렬하지 않는다. 명백히 placeholder인 `없음` 행은 첫 실제 spec 추가 시 제거할 수 있다.
6. **결과 보고**
- 만든 spec 문서와 index 변경 내용을 보고한다.
- 불명확하거나 후속 `update-spec`이 필요한 항목을 보고한다.
## 실행 결과 검증
- [ ] `agent-spec/index.md`가 존재하고 Spec Map에 생성한 spec이 들어 있는가
- [ ] 생성한 spec 문서가 `rules-agent-spec.md`의 기본 섹션 기준을 따르는가
- [ ] 기능 목록이 기능/설명 중심이며 불필요한 상태 칼럼이나 과한 상세 설명을 만들지 않았는가
- [ ] 코드 진입점, 패키지 배치, 도메인별 금지 사항을 spec 본문에 반복하지 않았는가
- [ ] frontmatter의 `spec_doc_type`, `spec_id`, `status`, `source_evidence`가 채워졌는가
- [ ] source evidence path가 실제 파일이거나 `path: null`인 사용자 근거인가
- [ ] 계약 원문을 복제하지 않고 `agent-contract/` 또는 코드 링크로 연결했는가
- [ ] archive를 무차별로 읽거나 과거 완료 기록을 현재 truth처럼 쓰지 않았는가
- [ ] `git diff --check`를 실행했는가
- 검증 실패 시: spec 문서와 index만 보완하고 코드 파일은 수정하지 않는다.
## 출력 형식
```markdown
## Spec 생성 완료
- 모드: <bootstrap | targeted>
- 생성/갱신 파일:
- [index.md](agent-spec/index.md)
- [<spec-id>.md](agent-spec/<area>/<spec-id>.md)
- 상태: <구현됨 | 부분 | 가정 | 불명확>
- 주요 근거:
- <path 또는 사용자 근거> - <요약>
## TODO 항목
- <확인 필요 또는 없음>
```
## 금지 사항
- agent-spec에 계약 원문, proto 전체 필드, config schema 원문을 복제하지 않는다.
- 현재 코드/계약으로 확인하지 않은 내용을 구현 사실처럼 쓰지 않는다.
- archive 전체를 훑지 않는다.
- 기존 spec이 있으면 중복 spec을 만들지 않는다.
- 코드 진입점, 구현 배치, 도메인 간 상세 책임 경계, 유지할 패턴, 금지 사항을 domain rule 대신 agent-spec에 길게 쓰지 않는다.
- 사람용 공개 가이드를 agent-spec에 장황하게 작성하지 않는다.
- spec 생성과 무관한 코드 파일을 수정하지 않는다.

View file

@ -0,0 +1,138 @@
---
name: create-test
version: 1.1.4
description: agent-test 환경 rules.md와 도메인/검증 시나리오별 테스트 rule 문서를 생성하거나 구조적 blank/skeleton baseline을 보완하는 스킬
---
# create-test
## 목적
`agent-test/<env>/rules.md``agent-test/<env>/<test-profile>.md`를 템플릿 기준으로 생성하거나 구조적 blank/skeleton 상태에서 baseline으로 보완한다.
공통 진입점은 얇게 유지하고, 실제 테스트 기준은 환경/도메인/검증 시나리오별 문서에 둔다.
`test-case`는 기존 호출과의 호환을 위한 alias이며, 새 문서 기준 이름은 `test-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`: 검증 대상 또는 변경 범위 설명 (선택)
## 핵심 규칙
- 도메인 매핑이나 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 라우팅만 채운다.
## 먼저 확인할 것
- [ ] `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 목록을 확인한다.
- [ ] 테스트 명령 확인을 위해 프로젝트의 대표 설정 파일을 가볍게 확인한다. 예: `package.json`, `Makefile`, `pyproject.toml`, `go.mod`, `Cargo.toml`, `docker-compose*.yml`, `.github/workflows/**`.
- [ ] `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 중 하나로 분류한다.
## 실행 절차
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

@ -0,0 +1,280 @@
---
name: init-agent-ops
version: 1.1.9
description: 프로젝트 상태를 판별하고 agent-ops 기본 스캐폴드를 생성하기 위한 초기 규칙
---
# init-agent-ops
## 목적
프로젝트에 Agent-Ops 구조가 없거나 불완전할 때,
현재 프로젝트 상태를 분석하여 다음을 세팅한다.
1. 에이전트 진입 파일
2. AI ignore / permission 기본 설정
3. agent-ops 기본 폴더 구조
4. rules/project/rules.md (프로젝트 특화 규칙, 분석 후 생성)
5. 초기 domain rule 초안
6. 초기 local 테스트 환경
7. 초기 skill (필요 시)
"현재 프로젝트에 맞는 최소 스캐폴드" 생성을 우선한다.
## 언제 호출할지
- 프로젝트에 agent-ops 구조가 없을 때
- agent-ops 구조가 불완전하여 재설정이 필요할 때
- 사용자가 "agent-ops 초기화해줘", "에이전트 설정해줘" 요청 시
## 입력
- `project-type`: 신규 / 운영중 (선택, 미지정 시 자동 판별)
## 먼저 확인할 것
- [ ] 프로젝트 루트에 기존 agent-ops 관련 파일(`CLAUDE.md`, `agent-ops/` 등)이 있는지 확인
- [ ] `.agent-ops-source` 파일이 있는지 확인 (공통 관리 레포 여부)
- [ ] 기존 진입 파일(`CLAUDE.md`, `GEMINI.md` 등)이 있는지 확인
- [ ] 기존 AI ignore / permission 파일(`.geminiignore`, `.aiexclude`, `.claude/settings.json`, `opencode.json` 등)이 있는지 확인
- [ ] `agent-ops/skills/common/create-test/SKILL.md`가 있는지 확인
## 핵심 원칙
- 기존 구조를 우선한다.
- 새 파일 생성은 꼭 필요한 최소 범위로 제한한다.
- 도메인은 발명하지 말고 현재 구조에서 발견한다.
- 처음에는 핵심 도메인만 생성한다.
- 반복되는 작업만 초기 skill로 만든다.
- 불확실한 내용은 후보로 제시한다.
## 상태 판별
### 신규 프로젝트
- 코드/폴더 구조가 단순하다
- 도메인 경계가 아직 약하다
- Agent-Ops 관련 파일이 없다
### 운영중 프로젝트
- 모듈/폴더/패키지 경계가 보인다
- 반복 작업이 드러난다
- 핵심 책임 경계가 식별된다
## 생성 대상
| 파일 | 방법 |
|------|------|
| `GEMINI.md`, `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, `.clinerules` 등 진입 파일 | `rules/common/rules.md``agent-ops/bin/entry-files.sh`의 파일 목록으로 프로젝트 루트에 복사 |
| `agent-ops/.version` | 공통 관리 레포의 VERSION 파일을 그대로 복사 (프레임워크 버전 추적용) |
| `agent-ops/bin/` | 공통 스크립트 전체 복사 (진입 파일 목록의 단일 기준인 `entry-files.sh` 포함) |
| `agent-ops/rules/common/` | 공통 폴더 전체 복사 (수정 금지) |
| `agent-ops/skills/common/` | 공통 폴더 전체 복사 (수정 금지) |
| `agent-ops/rules/project/rules.md` | 프로젝트 분석 후 생성 |
| `agent-ops/rules/project/domain/<domain>/rules.md` | 도메인 분석 후 생성 |
| `agent-ops/rules/private/` | 폴더만 생성 (내용은 개인이 작성) |
| `.gitignore``agent-ops/rules/private/` 추가 | git 추적 제외 |
| `.gitignore`의 Agent-Ops 관리 block | `*.log` 같은 전역 ignore가 있어도 `agent-task/**/*.md`, `agent-task/**/*.log` task 산출물이 추적되도록 unignore하고 `agent-roadmap/current.md`는 로컬 포인터로 ignore |
| `agent-test/local/rules.md` | `init-agent-ops.sh`가 최소 내용으로 생성 |
| `agent-test/local/project-smoke.md` | 도메인이 아직 없으면 `init-agent-ops.sh`가 fallback baseline으로 생성 |
| `agent-test/local/<domain>-smoke.md` | domain rule 생성 후 각 도메인별 기본 smoke 테스트 뼈대로 생성 |
| `.gitignore``agent-test/local/`, `agent-test/runs/` 추가 | `init-agent-ops.sh`가 local 테스트 환경/로그를 git 추적 제외 |
| `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore` | 사용자 항목은 보존하고 Agent-Ops 관리 block에 `agent-task/archive/**`, `agent-roadmap/archive/**` 추가 |
| `.claude/settings.json`, `opencode.json` | archive hard read/glob deny를 제거하고, 필요 시 명시 경로로 읽을 수 있게 둔다. `opencode.json`은 watcher ignore에 `agent-task/archive/**`, `agent-roadmap/archive/**`를 둘 수 있다 |
에이전트별 파일명:
실제 생성/동기화 대상 목록은 `agent-ops/bin/entry-files.sh``AGENT_OPS_ENTRY_FILES`를 단일 기준으로 사용한다.
| 에이전트 | 파일명 |
|---------|--------|
| Gemini | `GEMINI.md` |
| Claude | `CLAUDE.md` |
| Kilo Code / OpenCode | `AGENTS.md` |
| Cursor | `.cursorrules` |
| Cline | `.clinerules` |
## 에이전트 진입 파일 원칙
진입 파일은 `rules/common/rules.md` 내용 그대로를 에이전트별 파일명으로 복사한다.
별도 내용을 추가하거나 수정하지 않는다.
## Rule 구조 원칙
### rules/common/rules.md
- 공통 관리 레포에서 제공. 프로젝트에서 직접 수정하지 않는다.
- 실제 사용은 진입점 파일들에서 사용된다.
포함 항목:
- 기본 원칙
- 공통 스킬 라우팅 (router.md 참조)
- project/rules.md 로드 지시
### rules/project/rules.md
init-agent-ops가 프로젝트를 분석하여 생성한다.
포함 항목:
- 응답 언어
- 프로젝트 개요 / 주요 구조
- 기술 스택
- 프로젝트 특화 컨벤션
- 도메인 매핑 테이블 (경로 패턴 → domain rules.md)
- 프로젝트 스킬 라우팅 (해당 시)
common/rules.md와 내용이 중복되지 않도록 한다.
#### 도메인 매핑 테이블 형식
```markdown
## 도메인 매핑
| 경로 패턴 | 도메인 | rules.md |
|----------|--------|----------|
| `src/order/**` | order | `agent-ops/rules/project/domain/order/rules.md` |
| `src/payment/**` | payment | `agent-ops/rules/project/domain/payment/rules.md` |
| `src/common/**` | common | `agent-ops/rules/project/domain/common/rules.md` |
```
#### 프로젝트 스킬 라우팅 형식
```markdown
## 스킬 라우팅
| 요청 키워드 | SKILL.md |
|------------|----------|
| 테스트 실행해줘 | `agent-ops/skills/project/run-test/SKILL.md` |
```
### domain rule
각 도메인 rules.md에는 아래만 둔다.
- frontmatter metadata
- `domain`
- `last_rule_review_commit`: 생성 직전 `git rev-parse HEAD`
- `last_rule_updated_at`: 생성일 `YYYY-MM-DD`
- 목적 / 책임
- 포함 경로
- 제외 경로
- 주요 구성 요소
- 유지할 패턴
- 다른 도메인과의 경계
- 금지 사항
## DDD 기준
- **Core Domain**: 핵심 가치와 주요 유즈케이스
- **Supporting Domain**: 핵심 도메인을 지원
- **Generic / Common**: 여러 도메인이 공통으로 사용
도메인은 실제 폴더, 모듈, 패키지, 책임 경계와 연결되어야 한다.
## 실행 (Execution)
지정한 대상 디렉토리에 agent-ops 기본 스캐폴드와 local 테스트 환경을 생성한다.
스크립트 실행 후 이 skill의 실행 절차에 따라 project/domain 분석을 보완한다.
```bash
./agent-ops/bin/init-agent-ops.sh <target_directory>
```
## 실행 절차
1. **상태 판별**
- 프로젝트 구조, 모듈 경계, agent-ops 파일 유무를 분석하여 신규/운영중을 판별한다
2. **에이전트 진입 파일 생성**
- `rules/common/rules.md``agent-ops/bin/entry-files.sh`의 파일 목록으로 프로젝트 루트에 복사한다
3. **AI ignore / permission 기본 설정**
- `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에는 사용자 항목을 건드리지 않고 Agent-Ops 관리 block만 추가하거나 교체한다
- Agent-Ops 관리 block에는 `agent-task/archive/**``agent-roadmap/archive/**`를 넣는다
- `.claude/settings.json`, `opencode.json`이 없으면 archive hard read/glob deny 없이 생성하고, 있으면 가능한 경우 기존 설정을 보존하며 archive hard read/glob deny를 제거한다
- archive는 일반 작업에서 읽지 않도록 AI ignore, watcher ignore, 공통 규칙으로 제한하되, `.claude/settings.json`이나 `opencode.json`의 hard read/glob deny에는 두지 않는다
- 기존 `.claude/settings.json`이나 `opencode.json`에 archive hard read/glob deny가 있으면 init-agent-ops 표준에 맞게 제거한다
- 대상 루트에 `.agent-ops-source`가 있으면 AI ignore / permission 파일은 보강하지 않는다
- `agent-task/archive/**``agent-roadmap/archive/**` ignore 항목은 `.gitignore`에 추가하지 않는다
- `.gitignore`에는 Agent-Ops 관리 block으로 `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, `agent-roadmap/current.md`만 추가하거나 갱신한다
4. **agent-ops 폴더 구조 복사**
- 공통 관리 레포의 `agent-ops/` 공통 폴더(bin, rules/common, skills/common)를 복사한다
- `agent-ops/.version` 파일을 복사한다
5. **rules/project/rules.md 생성**
- 프로젝트를 분석하여 응답 언어, 프로젝트 개요, 기술 스택 등을 채운다
- common/rules.md와 내용이 중복되지 않도록 한다
6. **도메인 분석 및 domain rule 생성**
- 신규 프로젝트: 핵심 domain placeholder 2~4개만 제안한다. domain rules를 과도하게 채우지 않는다
- 운영중 프로젝트: Core/Supporting/Generic 도메인을 식별하고 실제 경로를 반영한 초안을 생성한다
7. **초기 local 테스트 환경 생성**
- `init-agent-ops.sh``agent-test/local/rules.md`를 최소 내용으로 자동 생성한다
- `init-agent-ops.sh`는 기존 domain rule이 있으면 각 도메인별 `agent-test/local/<domain>-smoke.md`를 생성하고 라우팅한다
- 기존 domain rule이 없으면 `agent-test/local/project-smoke.md` fallback 뼈대를 생성하고 라우팅한다
- `init-agent-ops.sh``.gitignore``agent-test/local/``agent-test/runs/`를 자동 추가한다
- 스크립트 실행 후 누락되었으면 대상 프로젝트의 `agent-ops/skills/common/create-test/SKILL.md`를 읽고 `env=local`, `test-profile` 없음으로 보완한다
- domain rule을 새로 생성한 경우, 각 생성 도메인마다 `agent-test/local/<domain>-smoke.md` 기본 뼈대를 만들고 `agent-test/local/rules.md`에 라우팅을 추가한다
- 도메인별 테스트 문서는 상세 명령을 모르면 `<확인 필요>`를 남기더라도 생략하지 않는다
8. **초기 skill 제안**
- 신규 프로젝트: 최소 2개만 제안한다
- 운영중 프로젝트: 반복 작업 기반으로 필요한 skill을 제안한다
9. **결과 보고**
- 상태 판별 결과, 생성된 파일 목록, 도메인 제안, skill 제안, 주의사항을 출력한다
## 출력 형식
### 상태 판별
- Agent-Ops 상태: 없음 / 부분 적용 / 운영중
- 프로젝트 상태: 신규 / 운영중
- 근거: 짧게 요약
### 스캐폴드 계획
- 생성할 파일
- 바로 채울 파일
- placeholder로 둘 파일
### 도메인 제안
- Core Domain
- Supporting Domain
- Generic / Common
### 초기 skill 제안
- skill 이름
- 필요한 이유
### 주의사항
- 지금 만들지 말아야 할 것
- 아직 확정하면 안 되는 것
## 실행 결과 검증
- [ ] `agent-ops/bin/entry-files.sh`의 모든 진입 파일이 프로젝트 루트에 존재하고, 내용이 초기화에 사용한 `rules/common/rules.md`와 일치하는가
- [ ] `agent-ops/rules/common/rules.md`가 대상 프로젝트에 남아 있고 초기화에 사용한 `rules/common/rules.md`와 일치하는가
- [ ] `agent-ops/rules/project/rules.md`가 생성되었고, 필수 항목(응답 언어, 프로젝트 개요, 기술 스택)이 포함되어 있는가
- [ ] 생성된 domain rules.md가 `domain-rule-template.md` 형식을 따르는가
- [ ] `rules/project/rules.md`의 도메인 매핑 테이블에 생성된 도메인이 모두 등록되어 있는가
- [ ] `.gitignore``agent-ops/rules/private/` 항목이 추가되어 있는가
- [ ] `.gitignore`에 Agent-Ops 관리 block이 있고 `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, `agent-roadmap/current.md`가 포함되어 있는가
- [ ] `agent-test/local/rules.md`가 생성되었는가
- [ ] 생성되었거나 기존에 있던 모든 domain rule에 대응하는 `agent-test/local/<domain>-smoke.md`가 있는가
- [ ] domain rule이 아직 없으면 `agent-test/local/project-smoke.md` fallback이 있는가
- [ ] `agent-test/local/rules.md`에 생성된 테스트 profile 라우팅이 연결되었는가
- [ ] `.gitignore``agent-test/local/``agent-test/runs/`가 추가되어 있는가
- [ ] `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 Agent-Ops 관리 block이 있고 그 안에 `agent-task/archive/**``agent-roadmap/archive/**`가 포함되어 있는가
- [ ] `.claude/settings.json`, `opencode.json``agent-task/archive/**` 또는 `agent-roadmap/archive/**` hard read/glob deny가 남아 있지 않은가
- [ ] 기존 archive hard deny가 있으면 init-agent-ops 표준에 맞게 제거했는가
- [ ] `.gitignore``agent-task/archive/**` 또는 `agent-roadmap/archive/**` ignore 항목을 추가하지 않았는가
- 검증 실패 시: 누락된 파일/항목을 사용자에게 알리고 해당 부분만 보완한다
## 금지 사항
- 진입 파일에 rules/common/rules.md 외 내용을 추가하지 않는다.
- `agent-task/archive/**``agent-roadmap/archive/**` ignore 항목을 `.gitignore`에 추가하지 않는다.
- `.gitignore`의 Agent-Ops 관리 task 산출물 unignore 예외를 제거하지 않는다.
- local 테스트 환경 파일을 git 추적 대상으로 만들지 않는다.
- domain rule이 확인된 경우 도메인별 기본 smoke 테스트 문서를 생략하지 않는다.
- 실제 구조보다 앞선 추상 구조를 강요하지 않는다.
- 처음부터 많은 domain / skill을 만들지 않는다.
- rules/common/rules.md를 프로젝트에서 직접 수정하지 않는다.
- rules/project/rules.md에 rules/common/rules.md와 중복되는 내용을 넣지 않는다.

View file

@ -0,0 +1,513 @@
---
name: plan
description: Analyze the current repository and write a detailed PLAN-{build_lane}-GNN.md for implementation work. Also writes the CODE_REVIEW-{review_lane}-GNN.md stub that the implementing agent will fill in after coding. Use for any feature, refactor, bug fix, or follow-up fix that should enter the plan-code-review loop. Milestone-linked work uses a reserved m-prefixed task group so runtime can route PASS completion events to update-roadmap. A separate implementing agent, or the same agent in an implementation pass, reads the plan file and does the coding.
---
# Plan
## Purpose
Create the planning artifacts for the implementation loop:
```text
plan skill -> PLAN-{build_lane}-GNN.md + CODE_REVIEW-{review_lane}-GNN.md stub
implementation -> code changes + filled CODE_REVIEW-{review_lane}-GNN.md, or blocked-state user-review request recorded in the review stub
code-review skill -> verdict + archive, complete.log, and PASS/user-review-resolved task-directory archive move, new follow-up plan/review files, or USER_REVIEW.md
runtime -> for m-prefixed PASS completion events, state check and optional update-roadmap call
```
`code-review` may stop the automatic loop with `USER_REVIEW.md` only when a selected Milestone `구현 잠금 > 결정 필요` item blocks implementation. Repeated non-PASS reviews, test environment blockers, external environment/secret/service setup, generic scope changes, and verification evidence gaps are not user-review reasons by themselves; they should become normal follow-up plans or unresolved verification evidence. Plan creation after `USER_REVIEW.md` requires the linked Milestone decision to be resolved. If the decision closes the task as complete/PASS, code-review resolves `USER_REVIEW.md`, writes `complete.log`, and archives the task instead of creating a new plan.
The plan file and review stub must be self-sufficient for implementation agents that do not read this skill. If implementation discovers a selected Milestone `구현 잠금 > 결정 필요` item that blocks safe progress, the implementing agent records a `사용자 리뷰 요청` in the active `CODE_REVIEW-*-G??.md`, leaves active files in place, and reports ready for review. This stop path is file-based only during implementation: the implementing agent must not interrupt the loop by asking the user directly, presenting choices in chat, or calling a user-input tool such as `request_user_input`. The code-review skill validates that request and writes `USER_REVIEW.md` when the stop is justified. Use `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` as the shared section template.
## Workflow Contract
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.
Task path terms:
- `{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}/` is only the grouping folder and must not contain active plan/review files.
Filename rules:
- 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.
Role boundary rules:
- Implementing agents fill implementation-owned `CODE_REVIEW-*-G??.md` sections, keep active files in place, and report ready for review.
- If implementation cannot continue because a selected Milestone `구현 잠금 > 결정 필요` item is unresolved, implementing agents fill the review stub's `사용자 리뷰 요청` section with the exact linked decision, evidence, commands/output, and resume condition, then stop with active files in place.
- During implementation, do not ask the user directly, present multiple-choice prompts in chat, or call `request_user_input`/equivalent input tools. Milestone lock choices belong in the review stub's `사용자 리뷰 요청` section so code-review can validate and create `USER_REVIEW.md` only when justified.
- Required UI evidence capture that needs a user-owned device, emulator, permission, secret, or interactive access unavailable to the agent is a verification blocker, not a user-review reason by itself. Record attempted commands and blocker evidence in `검증 결과` or `계획 대비 변경 사항` so code-review can write a normal follow-up or unresolved verification report.
- Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, review-only checklist) is code-review-skill only.
Split decision policy:
- Default to multiple subtask directories under one task group. Before writing any plan, decide whether the work has smaller independently reviewable implementation units.
- If there is any natural dependency boundary, ownership boundary, subsystem boundary, API-vs-call-site phase, test strategy split, or independently reviewable risk, write multiple subtask directories under one task group.
- A single plan is an exception. Use one only when all of these are true: the work is one coherent implementation unit, it has one primary ownership boundary, it has no prerequisite subtask, splitting would create artificial coordination overhead, and the whole change remains easy to review at once.
- When uncertain, split. Do not choose a single plan merely because it is shorter to write.
- Record the split decision in the plan. For a single plan, explicitly state why each applicable split boundary does not require a separate task. For multi-plan output, list the shared `{task_group}`, each sibling `{subtask_dir}`, and its dependency relationship.
Split gates:
- Split when the work combines shared API/foundation changes with broad call-site rollout. Put the API/foundation in an earlier task and the rollout in dependent task(s).
- Split when the work touches multiple domains or ownership boundaries, unless the change is purely mechanical and trivially reviewable.
- Split when different parts can be verified with different focused tests or have different risk profiles.
- Split when a likely failure in one part would force rewriting unrelated parts of the plan.
- Split when one part can produce a useful `complete.log` before another part starts.
- Split when mobile/UI verification can hang on emulator/device state, modal, permission dialog, animation, or external runner; isolate evidence recovery from feature implementation.
Task directory naming rules:
- 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 only the top-level `{task_group}` name. 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.
- 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_edge_integration`, `03+01_node_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`.
- Preserve task group and subtask directory names verbatim; do not normalize, reinterpret, or choose execution order by agent judgment.
Routing rules:
- Prefer `local` whenever the scope is bounded and verifiable; high local usage is fine. Do not choose `cloud` just to balance lane usage.
- `local` is for bounded, explicit, locally verifiable work: required behavior is explicit in task evidence, contracts, or existing pattern; relevant context fits in edited files plus nearby types/helpers, direct call sites, and existing or planned targeted tests/fixtures; correctness can be checked by code inspection plus type/build/unit tests or deterministic commands; no open-ended product/design judgment, live external provider/runtime semantics, or broad cross-domain context is decisive.
- Use `cloud` when any local condition is false, including when a plausible but wrong implementation could pass local checks while breaking behavior promised outside the bounded context.
- `local-G01` through `local-G10` and `cloud-G01` through `cloud-G10` are valid. Lane is capability fit; grade is complexity within the chosen lane. Do not raise `local-GNN` to compensate for missing judgment, missing context, weak verification, or a previous loop failure.
- Use `cloud-G07` or higher only when terminal-agent or external interactive behavior is central and cannot be made deterministic for local handling, or when the task requires more source/test/diff/log context than local can hold without omitting material evidence: shell/CLI workflow implementation, bin script orchestration, process control, stdout/stderr parsing, exit-status contracts, long-running command diagnosis, terminal benchmark-style tasks, TUI/PTY/browser/screen repaint/cursor stream behavior, real bin/smoke/integration failures after unit tests passed, or very large cross-module/cross-domain changes that cannot be safely split.
- For follow-ups from a review with 5+ `Required` findings, reassess lane/grade and default to `cloud-G07` or higher unless all findings are one narrow mechanical fix pattern; if keeping `local`, record why local conditions still hold.
- Previous loop lane does not matter. Recompute lane from the current plan or follow-up scope using these rules.
- Treat non-behavioral review artifact drift as reviewer-repairable unless it prevents judging implementation correctness, tests, or contracts.
- Treat obvious non-behavioral source nits as reviewer-repairable too: typos, stale comments, docs, or formatting only, with no behavior/test/API contract change.
- Raise `GNN` with scope, ambiguity, missing tests, irreversible behavior, and blast radius after lane selection; keep grade model-independent.
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` + `CODE_REVIEW-*-G??.md` with filled `사용자 리뷰 요청` | Implementation claims a selected Milestone lock decision blocker; ready for code-review to validate and create `USER_REVIEW.md` only if justified |
| `PLAN-*-G??.md` + filled `CODE_REVIEW-*-G??.md` | Ready for code-review skill |
| `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; linked Milestone lock decision 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`) | Task 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 that the linked Milestone decision is required 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 linked Milestone decision has been resolved or the new plan explicitly replans around that recorded decision. 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 decision in the new plan `배경` 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.
로드맵 확인:
- `agent-roadmap/current.md`는 브랜치별 로컬 포인터다. 있으면 구현 계획 파일을 만들기 전에 읽고, 사용자 요청, 브랜치, 변경 경로를 기준으로 관련 Phase와 Milestone을 선택한다.
- `agent-roadmap/priority-queue.md`가 있으면 명시 target이 없는 구현 계획에서 Phase를 가로지르는 후보 순서를 확인하기 위해 읽는다. 큐 순서는 우선순위 참고이며, 상태/잠금/기능 원본은 각 Milestone 문서다.
- 사용자가 target Milestone을 명시하지 않았고 요청이 "다음 작업" 또는 일반 구현 계획이면 `priority-queue.md`의 위에서 아래 순서 중 요청과 맞고 활성 경로에 존재하는 첫 Milestone을 우선 후보로 둔다.
- `priority-queue.md` 링크가 깨졌으면 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 기능 Task 완료를 목표로 하는 계획이면 `Roadmap Targets` 섹션에 활성 Milestone 경로와 완료 대상 Task id를 고정한다. 이 섹션은 `complete.log``Roadmap Completion` 근거로 복사되어 `update-roadmap`이 해당 Task만 체크하는 anchor가 된다. 이 섹션은 `{task_group}`이 해당 Milestone slug의 `m-<milestone-slug>`일 때만 쓴다.
- Milestone 작업이 아니거나, Milestone 안의 조사/하위 구현처럼 특정 기능 Task 완료를 주장하지 않는 계획이면 `Roadmap Targets` 섹션을 쓰지 않는다. 섹션이 없으면 PASS 후에도 roadmap Task 체크를 하지 않는다.
- `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. 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, plus `create-test` or `update-test` edits when the repository already uses agent-test for the relevant scope or the user explicitly asked to maintain test rules.
- [ ] **Load test environment rules** — because implementation plans include verification, determine `test_env` before choosing verification commands. Use the user-specified environment when provided; otherwise use `local`. Agent-test is optional: some repositories or tasks intentionally do not have or use `agent-test/`. Check `agent-test/<test_env>/rules.md`; read it in full when present, even if it appears blank or skeleton. If it is absent, record that no agent-test rule was applied and choose fallback verification sources from repository manifests, scripts, workflows, domain rules, or direct read-only environment probes. Do not create agent-test files merely because a plan has verification. Invoke `create-test` only when the user asked for test-rule creation/maintenance, the current task is itself test-rule work, or the repository already uses agent-test for this scope and the missing/blank rule is a real maintenance gap. If creation is not appropriate or possible in the current task context, record the gap and fallback source; absence is not a user-review blocker by itself.
- [ ] **Read all source files in full** — read every source file the change will touch, whole file. No partial reads.
- [ ] **Resolve test profiles** — if env rules exist and contain `## 라우팅`, read every matching `agent-test/<test_env>/<test-profile>.md` in full. If agent-test is absent or intentionally unused for the task, skip profile resolution and record the fallback verification source. Use `create-test` for missing or structurally blank routes/profiles only when the repository already uses agent-test for this scope or the task is test-rule maintenance. Use `update-test` only when verified command or criteria facts are available or the user asked to maintain test rules. If a profile exists but leaves command/criteria values as `<확인 필요>`, record the incomplete values and choose fallback verification commands from repository manifests or workflows with lower confidence. Do not claim agent-test requires a command that is not written in the env rules or matched profiles.
- [ ] **Preflight non-local test environments** — 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, derive a read-only preflight before writing final verification commands. Use matched `agent-test` rules when they exist and apply; otherwise derive the preflight from repository manifests, scripts, workflows, domain rules, current task evidence, user-provided environment facts, and direct read-only probes. 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 such as Edge id, 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, the plan must add an explicit setup/sync/rebuild step or report the blocker; do not write verification commands that silently assume profile or fallback values are already true.
- [ ] **Read all test files in full** — read every test file that exercises the changed behavior, including files implied by matched agent-test profiles when any are used and by the repository test layout.
- [ ] **Assess test coverage** — for each behavior change, explicitly record whether existing tests cover it.
- [ ] **Assess split boundaries first** — identify dependency boundaries, ownership boundaries, API-vs-call-site phases, test strategy splits, risk profile splits, and independently verifiable subwork before selecting plan files. If any split gate applies or the decision is uncertain, write multiple subtask directories under one task group instead of one plan.
- [ ] **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 `분석 결과 > 분할 판단` and, when order matters, `의존 관계 및 구현 순서`.
- [ ] **Grep all symbol references** — for any renamed or removed symbol, find every call site and import chain.
- [ ] **Check dependency manifests** — before adding any new package, verify its presence in go.mod / package manifest.
- [ ] **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 `-count=1` is required.
## Step 3 - Determine GXX Grade
GXX is an output of analysis, not an input. Determine lane and grade only after Step 2 is fully complete.
- [ ] **Assess change scope** — count affected files, interface impact, call-site count, and the amount of source/test/review context that must stay loaded together.
- [ ] **Check risk factors** — mark any that apply: behavior promised outside edited files, persisted-state rule, permission boundary, shared-state risk, irreversible behavior.
- [ ] **Evaluate test confidence** — judge whether existing tests sufficiently verify the changed behavior.
- [ ] **Decide lane** — apply `Routing rules` as a gate. Use `local` only when all local allowlist conditions are true; otherwise use `cloud`. Ignore previous loop lane.
- [ ] **Decide GNN** — assign grade within the selected lane as scope, ambiguity, irreversibility, and blast radius increase. Grade is complexity-based, not model-name-based; both `local-G10` and `cloud-G01` are valid when lane evidence supports them. Do not increment GNN solely because a previous loop failed.
## Step 4 - Archive Existing Active Files
Before writing new active files for the chosen active task directory:
- 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`.
- Count existing `agent-task/{task_name}/plan_*.log`; call it `N`. If `PLAN-*-G??.md` exists in that same directory, rename `PLAN-{build_lane}-GNN.md` to `plan_{build_lane}_GNN_N.log`.
- Count existing `agent-task/{task_name}/code_review_*.log`; call it `M`. If `CODE_REVIEW-*-G??.md` exists in that same directory, rename `CODE_REVIEW-{review_lane}-GNN.md` to `code_review_{review_lane}_GNN_M.log`.
- Count existing `agent-task/{task_name}/user_review_*.log`; call it `U`. If `USER_REVIEW.md` exists in that same directory and the linked Milestone decision is resolved for replanning, rename `USER_REVIEW.md` to `user_review_U.log`.
The new plan number is the count of `plan_*.log` after archiving.
## Step 5 - Write Plan File
Header line must be exactly:
```markdown
<!-- task={task_name} plan={N} tag={TAG} -->
```
Required sections:
- Title.
- `이 파일을 읽는 구현 에이전트에게`: 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. Also state that if implementation is blocked by a selected Milestone `구현 잠금 > 결정 필요` item, the implementer must fill the review stub's `사용자 리뷰 요청` section with exact linked evidence and stop for code-review; the implementer must not ask the user directly, present chat choices, call `request_user_input`, create `USER_REVIEW.md`, archive logs, or write `complete.log`. State that environment/secret/service blockers, generic scope changes, and evidence gaps a follow-up agent can close are not user-review requests by themselves.
- `배경`: 2-4 sentences explaining why the work is needed.
- `사용자 리뷰 요청 흐름`: state that only selected Milestone lock decisions are recorded in the active review stub's `사용자 리뷰 요청` section, copied from `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`; direct user prompts during implementation are forbidden, and code-review owns validation plus the actual `USER_REVIEW.md` file write.
- `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.
- `Roadmap Targets`: include this section only when the plan is intended to complete one or more existing Milestone 기능 Task ids. Omit the section entirely for non-roadmap work or Milestone-adjacent work that should not check a Task on PASS. Format exactly:
```markdown
## Roadmap Targets
- Milestone: `agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
- Task ids:
- `<task-id>`: <Task text or concise label>
- Completion mode: check-on-pass
```
- `Agent UI Completion`: include this section only when the plan implements agent-ui definition/frame/component changes in code and code-review PASS should move specific agent-ui documents to `status: 구현됨`. Omit it for non-agent-ui work, `direct-sync` work handled entirely by `sync-agent-ui`, and `milestone-required` work whose status update is intentionally deferred to Milestone 종료 검토. Format exactly:
```markdown
## Agent UI Completion
- Mode: review-pass-status-update
- Agent UI docs:
- `agent-ui/definition/views/<view-id>/index.md`
- Required code evidence:
- `<code path>`: <what proves the UI definition is implemented>
- Required implementation verification:
- `<test or analysis command>`: PASS expected before review
- Review finalization validation:
- `validate-agent-ui scope=<scope>`: PASS expected after status/evidence update
- Status updates on PASS:
- `agent-ui/definition/views/<view-id>/index.md`: `계획` -> `구현됨`
```
- `분석 결과`: record the findings from Step 2 and Step 3. This section is the written output of the analysis — not a summary, but the actual findings that justify the plan's scope and decisions. Must include all of the following subsections:
- `읽은 파일`: list every source and test file read during analysis, with path. List agent-test rule/profile files only when they were actually present and read.
- `SDD 기준`: for `SDD: 필요` Milestones, list the SDD path, status, targeted Acceptance Scenario ids, their Milestone Task 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".
- `테스트 환경 규칙`: state the chosen `test_env`, whether `agent-test/<test_env>/rules.md` was present/read/missing/intentionally unused, every matched profile path read when any, the concrete rules/commands applied, any structural blank/skeleton or missing rules, any `<확인 필요>` values, and any fallback verification source. If any required verification leaves the current checkout, include a `테스트 환경 프리플라이트` 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 such as Edge id, ports/process state, external hosts, OS/arch assumptions, and the exact setup/sync/rebuild step or blocker derived from mismatches. If agent-test is absent or unusable, explicitly say no agent-test rule was applied, what fallback is used, and whether test-rule maintenance is actually needed or not needed for this task.
- `테스트 커버리지 공백`: list each behavior change and whether existing tests cover it; explicitly note gaps.
- `심볼 참조`: list renamed/removed symbols and every call site found, or state "none" if no symbols were changed.
- `분할 판단`: state that the split decision policy was evaluated before choosing plan files. For a single plan, explain why each relevant split gate does not apply and why single-plan coordination is safer than splitting. For multi-plan output, list the shared task group plus each sibling subtask directory and dependency relationship. For dependent subtask plans, include each predecessor index and whether it is satisfied by an active or archived `complete.log`, missing, or ambiguous.
- `범위 결정 근거`: 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.
- `빌드 등급`: state the decided lane and GNN grade with a one-line rationale.
- `구현 체크리스트`: 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, and make the final item exactly: `- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.` Copy this checklist into the review stub's `구현 체크리스트` section with the same item text and order.
- One item per change: `### [TAG-1] Title`, `TAG-2`, etc.
- `수정 파일 요약`: table mapping files to item ids.
- `최종 검증`: runnable commands and expected outcome. Prefer commands from the matched agent-test env/profile rules. If agent-test is missing, blank, skeleton, or lacks a matching command, use repository manifests/workflows as fallback and record that fallback in `분석 결과 > 테스트 환경 규칙`. 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. The final line of this section must read exactly — **"모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다."**
Each plan item must include:
- `문제`: concrete problem with file:line references.
- `해결 방법`: exact approach and before/after code block for non-trivial changes.
- `수정 파일 및 체크리스트`: exhaustive file-level checklist.
- `테스트 작성`: explicit write/skip decision. If writing tests, include path, test name, assertion goal, and fixtures. If skipping, justify.
- `중간 검증`: runnable commands and expected result.
Include `의존 관계 및 구현 순서` 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, `의존 관계 및 구현 순서` 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 `계획 대비 변경 사항`, 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`.
- `검증 결과` 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 Go test cache output is acceptable. If fresh execution matters, use `go test -count=1 ...`.
## Step 6 - Write Review Stub
Use the template below exactly. Fill `{…}` placeholders from the plan; everything else is fixed and must not be changed by the implementing agent.
Copy `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` into the review stub's `사용자 리뷰 요청` section.
```markdown
<!-- task={task_name} plan={N} tag={TAG} -->
# 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 `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a selected Milestone `구현 잠금 > 결정 필요` item, fill `사용자 리뷰 요청` with linked evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Environment/secret/service blockers, generic scope changes, repeated failures, and evidence gaps that a follow-up agent can close are normal follow-up issues, not user-review blockers by themselves.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record only Milestone lock decisions in `사용자 리뷰 요청` and stop for code-review.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.
## 개요
date={YYYY-MM-DD}
task={task_name}, plan={N}, tag={TAG}
{copy the plan's Roadmap Targets section exactly if present; omit this block if the plan has no Roadmap Targets}
{copy the plan's Archive Evidence Snapshot section exactly if present; omit this block if the plan has no Archive Evidence Snapshot}
## 이 파일을 읽는 리뷰 에이전트에게
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다.
1. 판정을 append한다.
2. `CODE_REVIEW-{review_lane}-GNN.md``code_review_{review_lane}_GNN_N.log`, `PLAN-{build_lane}-GNN.md``plan_{build_lane}_GNN_M.log`로 아카이브한다.
3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 연결된 Milestone 결정으로 완료/PASS 해소되면 code-review가 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다.
4. PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다.
5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다.
---
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [{TAG}-1] {item description} | [ ] |
| [{TAG}-2] {item description} | [ ] |
## 구현 체크리스트
{copy the plan's 구현 체크리스트 items exactly, preserving order and checkbox text}
## Agent UI Completion
> Include this section only when the plan has `Agent UI Completion`; otherwise omit it entirely.
> **[IMPLEMENTING AGENT]** Fill actual code evidence and implementation verification output for the listed docs.
> **[REVIEW AGENT ONLY]** On PASS, update only the listed agent-ui docs to `구현됨`, add the listed code evidence, run `validate-agent-ui`, and copy this section into `complete.log`.
- Mode: review-pass-status-update
- Agent UI docs:
- `agent-ui/definition/views/<view-id>/index.md`
- Actual code evidence:
- [ ] `<code path>`: <implemented evidence>
- Implementation verification evidence:
- [ ] `<test or analysis command>`: <actual result or output path>
- Status updates requested on PASS:
- [ ] `agent-ui/definition/views/<view-id>/index.md`: `계획` -> `구현됨`
- Review finalization:
- [ ] Review agent updated the listed agent-ui docs and code evidence.
- [ ] Review agent ran `validate-agent-ui scope=<scope>` after the status/evidence update.
## 코드리뷰 전용 체크리스트
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다.
- [ ] `코드리뷰 결과``PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
- [ ] active `CODE_REVIEW-*-G??.md``code_review_{review_lane}_GNN_N.log`로 아카이브한다.
- [ ] active `PLAN-*-G??.md``plan_{build_lane}_GNN_M.log`로 아카이브한다.
- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md``agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/{task_name}/``agent-task/archive/YYYY/MM/{task_name}/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/{task_group}/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-{build_lane}-GNN.md``CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 연결된 Milestone 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 사용자 리뷰 요청
_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._
- 상태: 없음
- 사유 유형: 없음
- 연결 대상: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음
## 리뷰어를 위한 체크포인트
{pre-filled from plan — one bullet per review focus area}
## 검증 결과
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
필수 규칙:
- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다.
- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다.
- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다.
- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다.
- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다.
### {TAG}-1 중간 검증
```
$ {verification command from plan}
(output)
```
### 최종 검증
```
$ {final verification command from plan}
(output)
```
---
> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.
```
Sections and their ownership:
| Section | Owner | Note |
|---------|-------|------|
| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) |
| Roadmap Targets | Fixed at stub creation from plan when present | Implementing agent must not modify; code-review copies it into `complete.log` as `Roadmap Completion` only on PASS |
| 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 |
| Agent UI Completion | Mixed | Present only for plan-required agent-ui code work; implementing agent fills actual evidence, review agent applies `구현됨` status/evidence update on PASS and copies the section into `complete.log` |
| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]``[x]` only |
| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]``[x]` only; final checkbox is mandatory before saving |
| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section |
| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content |
| 사용자 리뷰 요청 | Implementing agent | Keep `상태: 없음` unless a selected Milestone `구현 잠금 > 결정 필요` item blocks implementation; do not ask the user directly during implementation; environment/secret/service blockers, generic scope changes, and evidence gaps are not user-review requests |
| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan |
| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `계획 대비 변경 사항` entry |
| 코드리뷰 결과 | Review agent appends | Not included in stub |
## Naming
| Tag | Use for |
|-----|---------|
| `API` | Public API changes |
| `REFACTOR` | Internal refactoring |
| `TEST` | Test additions/fixes |
| `REVIEW_<TAG>` | Follow-up fixes after review |
## Final Checklist
- `PLAN-{build_lane}-GNN.md` and `CODE_REVIEW-{review_lane}-GNN.md` both exist under the active task directory `agent-task/{task_name}/`.
- `.gitignore` has the Agent-Ops managed gitignore block that unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores local `agent-roadmap/current.md`, so active files and archived `*.log` task artifacts are trackable even when the project ignores `*.log`.
- 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_edge_integration`, `03+01_node_integration`; dependency details live in the subtask directory name as `NN+PP[,QQ...]_subtask_name`.
- 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 match `<!-- task={task_name} plan={N} tag={TAG} -->`.
- Previous active files, if any, were archived with correct numeric suffixes.
- If resuming from `USER_REVIEW.md`, it was archived to `user_review_N.log` and the resolved linked Milestone decision was recorded in the new plan.
- `Roadmap Targets` exists only when PASS should check explicit Milestone Task ids, the task group is `m-<milestone-slug>` for the listed Milestone path, and every listed Task id exists in the selected active Milestone.
- If `Roadmap Targets` exists in the plan, the review stub contains the identical section. If it does not exist in the plan, the review stub omits it too.
- If `Agent UI Completion` exists in the plan, the review stub contains the matching section with implementation-owned evidence fields. If it does not exist in the plan, the review stub omits it too.
- If the selected Milestone has `SDD: 필요`, the plan's `분석 결과 > 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.
- `분석 결과 > 테스트 환경 규칙` records the selected test env, env rules read/missing/structural-blank/intentionally-unused state, matched profiles read when any, and any fallback verification source.
- 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 `구현 체크리스트` item text/order, and the final checkbox is the mandatory `CODE_REVIEW-*-G??.md` completion item.
- The plan's implementer instructions and review stub both forbid direct user prompts during implementation and explain the implementation-time `사용자 리뷰 요청` stop path.
- The review stub includes the `사용자 리뷰 요청` section from `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`.
- The review stub has a clearly marked `코드리뷰 전용 체크리스트` owned only by the review agent.
- Routed review file completion table lists every plan item.

View file

@ -0,0 +1,4 @@
interface:
display_name: "Plan"
short_description: "Write implementation plans"
default_prompt: "Use $plan to create grouped PLAN/CODE_REVIEW task files for this repository change."

View file

@ -0,0 +1,213 @@
---
name: roadmap-sdd
version: 1.0.0
description: 로드맵 Milestone에 녹아 있는 SDD 설계 게이트를 판정, 생성, 갱신, 사용자 리뷰 대기, 잠금 해제, archive 처리할 때 사용한다. 사용자가 SDD, spec gate, 설계 게이트, SDD 필요 여부, SDD 승인 준비, SDD 사용자 리뷰, SDD 잠금 해제, SDD archive를 요청하거나, 큰 Milestone의 구현 잠금이 SDD 필요 상태일 때 사용한다.
---
# Roadmap SDD
## 목적
큰 Milestone에서 로드맵만으로 부족한 계약, 상태 전이, 수용 시나리오, 검증 근거를 `agent-roadmap/sdd/` 아래에 기록한다.
SDD는 로드맵과 분리된 별도 운영물이 아니라 Milestone `구현 잠금`을 해제하고, 이후 Milestone 구현 계획이 따라야 할 설계 입력을 고정하는 하위 설계 게이트다.
`SDD: 필요` Milestone의 구현 계획은 승인된 SDD의 Acceptance Scenario와 Evidence Map에서 구현 범위, 검증, 완료 evidence를 역산해야 한다.
## 모드
- `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 경로로 이동할 준비 상태인지 확인한다.
## 구조
```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
```
- `USER_REVIEW.md`는 필요한 경우에만 존재한다.
- `user_review_N.log`는 해결된 사용자 리뷰 기록이다.
- 완료 또는 폐기된 Milestone의 SDD는 `agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/`로 이동한다.
- SDD 경로는 같은 Milestone의 slug를 그대로 사용한다. 별도 SDD slug를 만들지 않는다.
## 표준 형식
- `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 값이 필요하면 유지할 수 있다.
## SDD 대상 판정
아래 중 하나라도 해당하면 `SDD: 필요`로 판정한다.
- 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, 사용자 소유 환경이 완료 근거의 일부다.
- 실패 처리 방식이 제품 판단, 보안, 비용, 권한, 데이터 보존에 영향을 준다.
아래에만 해당하면 `SDD: 불필요`로 판정한다.
- 단일 repo 내부의 작고 국소적인 리팩터링이다.
- 문서 정리, 테스트 보강, 작은 UI 보강이다.
- Milestone Task의 `검증:`과 일반 plan/code-review 루프만으로 완료 판단이 충분하다.
- 기존 SDD 또는 agent-contract를 그대로 소비하고 새 설계 결정이 없다.
## Milestone 연결
SDD가 필요한 Milestone은 `구현 잠금`에 아래 필드를 둔다.
```md
- 상태: 잠금
- SDD: 필요
- SDD 문서: [SDD.md](../../../sdd/<phase-slug>/<milestone-slug>/SDD.md)
- 잠금 해제 조건:
- [ ] SDD 잠금이 해제되어 있다
- [ ] SDD 사용자 리뷰가 없거나 승인/해결되었다
- [ ] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다
- [ ] Evidence Map이 완료 시 `Roadmap Completion`과 최종 검증 evidence로 검증 가능하게 연결되어 있다
- 결정 필요: 없음
```
SDD가 불필요한 Milestone은 사유를 남긴다.
```md
- SDD: 불필요
- SDD 사유: 단일 repo 내부 변경이며 외부 계약, 상태 머신, provider mutation이 없다.
```
## 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이 완료 시 `Roadmap Completion`과 최종 검증 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의 구현 잠금을 해제하지 않는다.

View file

@ -0,0 +1,44 @@
# 공통 스킬 라우터
라우팅 우선순위:
- 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로 수행한다.
- 구현 계획 요청에서 선택 Milestone의 구현 잠금이 남아 있으면 `plan`은 구현 계획을 만들지 않고 잠금 차단을 보고한다.
- SDD 생성/갱신/잠금 해제는 `roadmap-sdd` 또는 `update-roadmap` 요청으로 처리한다.
- 런타임이 `origin-task`/`complete-log` 단건 완료 이벤트를 전달한 경우는 `update-roadmap`으로 처리한다.
- active/archive `complete.log`, 관련 파일, git history를 종합해 Milestone 작업 상태를 복구하거나 확인하는 요청은 `sync-milestone-workstate`로 처리한다.
| 요청 키워드 | SKILL.md |
|------------|----------|
| agent-ops 세팅해줘, scaffold 만들어줘, 초기화해줘 | `agent-ops/skills/common/init-agent-ops/SKILL.md` |
| domain rule 만들어줘, rules.md 생성, 새 도메인 규칙 | `agent-ops/skills/common/create-domain-rule/SKILL.md` |
| skill 만들어줘, SKILL.md 생성, 새 스킬 추가 | `agent-ops/skills/common/create-skill/SKILL.md` |
| agent-ui 생성, UI 스캐폴드 생성, UI 정의 구조 생성, 화면 정의 구조 생성, agent-ui scaffold | `agent-ops/skills/common/create-agent-ui/SKILL.md` |
| agent-ui 갱신, agent-ui 업데이트, view 추가, component 추가, frame 추가, wireframe 추가, 화면 정의 갱신, 화면 정의서 갱신, 화면정의서 수정, 화면 정의서에 추가, 화면 정의서에서 제거, 와이어프레임 수정, 와이어프레임에 추가, wireframe 수정, wireframe에 추가, agent-ui USER_REVIEW 해결, UIR 결정 반영 | `agent-ops/skills/common/update-agent-ui/SKILL.md` |
| agent-ui 검증, agent-ui validate, UI 정의 정합성 확인, wireframe 정합성 확인, 화면정의서와 wireframe 맞춰, 화면 정의서와 와이어프레임 정합성 확인, 화면정의서와 코드가 안 맞아, UI 스캐폴드 검사 | `agent-ops/skills/common/validate-agent-ui/SKILL.md` |
| agent-ui와 코드 동기화, agent-ui와 코드 전체 동기화, 화면정의서대로 코드 반영, 화면 정의서 변경사항 구현, wireframe 변경사항 구현 | `agent-ops/skills/common/sync-agent-ui/SKILL.md` |
| create-test, 테스트 룰 작성, 테스트 룰 생성, 테스트 규칙 작성, 테스트 규칙 생성, 테스트 환경 생성, 상황별 테스트 문서 생성, 도메인별 테스트 문서 생성, 검증 시나리오별 테스트 문서 생성, test rule 생성, agent-test 생성 | `agent-ops/skills/common/create-test/SKILL.md` |
| update-test, 테스트 룰 수정, 테스트 룰 갱신, 테스트 규칙 수정, 테스트 규칙 갱신, 테스트 환경 수정, 상황별 테스트 문서 수정, 도메인별 테스트 문서 수정, 검증 시나리오별 테스트 문서 수정, test rule 수정, agent-test 수정 | `agent-ops/skills/common/update-test/SKILL.md` |
| 계약 생성해, 프로젝트 계약 생성해, 프로젝트 계약 생성, contract 생성, agent-contract 생성, 계약 문서 생성, inner 계약 생성, outer 계약 생성 | `agent-ops/skills/common/create-contract/SKILL.md` |
| 계약 업데이트해, 프로젝트 계약 업데이트해, 프로젝트 계약 업데이트, 계약 갱신해, 계약 갱신, 계약 수정, 계약 정리, contract update, agent-contract 갱신, inner 계약 갱신, outer 계약 갱신 | `agent-ops/skills/common/update-contract/SKILL.md` |
| 스펙 생성, 구현 스펙 생성, 현재 구현 문서화, agent-spec 생성, living spec 생성, 완료된 기능 스펙 작성 | `agent-ops/skills/common/create-spec/SKILL.md` |
| 스펙 업데이트, 스펙 갱신, 구현 스펙 갱신, 구현 스펙 업데이트, 완료 기능 스펙 반영, agent-spec 갱신, 스펙 동기화 | `agent-ops/skills/common/update-spec/SKILL.md` |
| README 작성해줘, README 만들어줘, 프로젝트 설명 문서 만들어줘 | `agent-ops/skills/common/create-readme/SKILL.md` |
| 핸즈오프 남겨, handoff 작성, 인수인계 작성, 다른 세션에서 이어가게 정리, 작업을 이어받도록 기록 | `agent-ops/skills/common/create-handoff/SKILL.md` |
| 로드맵 만들어줘, roadmap 생성, 마일스톤 설계, goal/phase 구조 잡아줘 | `agent-ops/skills/common/create-roadmap/SKILL.md` |
| 현 마일스톤과 작업현황 동기화, 현재 마일스톤 작업현황 동기화, 마일스톤 작업현황 동기화, 마일스톤 완료내역 동기화, agent-task 완료를 마일스톤에 반영, complete.log 후보 스캔, 누락된 Roadmap Completion 복구, 파일/git 기준 작업 상태 확인, 작은 작업 완료 반영, 마일스톤 체크박스 재동기화, 로드맵 작업 완료 상태 동기화 | `agent-ops/skills/common/sync-milestone-workstate/SKILL.md` |
| 마일스톤 완료해도 될지 검토해봐, 현 마일스톤 종료 검토, 현재 마일스톤 닫고 다음 마일스톤 지정, 마일스톤 종료해, 마일스톤 완료 검토, 종료 검토 | `agent-ops/skills/common/complete-milestone/SKILL.md` |
| 로드맵 업데이트, roadmap 갱신, 로드맵에 추가, 로드맵 작업 추가, 로드맵 기능 추가, 로드맵 Epic 추가, 로드맵 에픽 추가, 로드맵 Task 추가, 로드맵 태스크 추가, 로드맵 테스크 추가, 로드맵 TODO 추가, 마일스톤에 추가, 마일스톤 추가, 마일스톤 갱신, 마일스톤 아카이브, phase 추가, phase 변경, 페이즈 추가, 페이즈 변경, 현재 마일스톤 변경, 로드맵 한국어 전환, 로드맵 번역 | `agent-ops/skills/common/update-roadmap/SKILL.md` |
| SDD 작성, SDD 생성, SDD 갱신, SDD 필요 여부, SDD gate 확인, SDD 사용자 리뷰, SDD 잠금 해제, SDD 승인 준비, SDD archive, spec gate, 설계 게이트 | `agent-ops/skills/common/roadmap-sdd/SKILL.md` |
| 이 마일스톤은 X가 끝나야 가능해, A 전까지 B 잠가둬, 잠금 해제 조건은 X야, X 프로젝트 작업 뒤에 현재 마일스톤 진행, 의존성 설정해, 외부 의존 잠금 | `agent-ops/skills/common/update-roadmap/SKILL.md` |
| roadmap dependency 확인, locks.yaml 판별, 외부 의존 잠금 확인, unlock-ready 판별, 잠금 해제 조건 충족 여부 확인, roadmap-dependency-checker.sh | `agent-ops/skills/common/check-roadmap-dependency/SKILL.md` |
| 지금 작업이 뭐지?, 현재 작업 분석, 어디까지 했지?, 로드맵상 현 위치, 현재 마일스톤 위치, current 기준 breadcrumb | `agent-ops/skills/common/analyze-roadmap-position/SKILL.md` |
| 계획 세워줘, 계획 작성해, 계획 만들어줘, 구현 계획, PLAN.md, plan, plan 작성해, plan 만들어줘 | `agent-ops/skills/common/plan/SKILL.md` |
| 코드 리뷰해줘, 리뷰 진행해, 리뷰해줘, code review, CODE_REVIEW.md, 리뷰 루프 | `agent-ops/skills/common/code-review/SKILL.md` |
| 커밋해줘, 푸시해줘, commit, push, 반영해줘 | `agent-ops/skills/common/commit-push/SKILL.md` |
| agent-ops 싱크해, agent-ops 동기화해, agentic-framework에 올려줘, agent-ops를 [프로젝트]로 싱크해 | `agent-ops/skills/common/sync-push/SKILL.md` |
| 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` |

View file

@ -0,0 +1,155 @@
---
name: sync-agent-ui
version: 1.1.0
description: 정합화된 agent-ui 변경분을 코드에 직접 반영하거나, 코드 작업 규모에 따라 plan 또는 roadmap/milestone 작업으로 라우팅한다. 직접 반영이 검증된 경우에만 .sync-state.json 기준점을 갱신한다. "agent-ui와 코드 동기화", "화면정의서대로 코드 반영" 요청 시 사용한다.
---
# sync-agent-ui
## 목적
정합화된 `agent-ui/` 변경분을 실제 UI 코드에 반영한다.
기본 동작은 `.sync-state.json``last_synced_head` 이후 agent-ui 변경분만 반영하며, 사용자가 전체 동기화를 명시한 경우에만 현재 agent-ui 전체를 코드와 대조한다.
코드 반영 전에 코드 작업 규모를 판정해 작은 작업은 직접 반영하고, 중간 작업은 `plan` 루프로, Milestone이 필요한 큰 코드 작업은 `update-roadmap`의 Milestone/Epic/Task 갱신으로 넘긴다.
`plan-required` 또는 `milestone-required`로 라우팅한 경우에는 이 스킬 실행 안에서 코드 구현, status 전환, sync state 갱신, commit/push를 하지 않는다.
## 언제 호출할지
- 사용자가 "agent-ui와 코드 동기화", "화면정의서대로 코드 반영", "wireframe 변경사항 구현"을 요청할 때
- `update-agent-ui` 또는 `validate-agent-ui`가 code sync 필요성을 판단했고 현재 범위에 미해결 USER_REVIEW가 없을 때
- 사용자가 "agent-ui와 코드 전체 동기화"처럼 full sync를 명시할 때
## 입력
- `mode`: `incremental` 또는 `full`. 기본값은 `incremental` (선택)
- `scope`: `all`, `view:<view-id>`, `component:<component-id>` 중 하나. 기본값은 `all` (선택)
- `validated`: `true` 또는 `false`. 기본값은 `false` (선택)
- `sync-intent-source`: `manual`, `update-agent-ui`, `validate-agent-ui` 중 하나 (선택)
- `execution-route`: `auto`, `direct-sync`, `plan-required`, `milestone-required` 중 하나. 기본값은 `auto` (선택)
- `push`: `true` 또는 `false`. 기본값은 `true` (선택)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules-agent-ui.md`를 읽는다.
- [ ] `agent-ui/``agent-ui/definition/index.md` 존재 여부를 확인한다.
- [ ] `validated=true`가 아니면 먼저 `validate-agent-ui`를 실행한다.
- [ ] `agent-ui/USER_REVIEW.md`가 있으면 현재 sync 범위와 관련된 미해결 항목이 없는지 확인한다.
- [ ] `agent-ui/.sync-state.json`을 읽는다. 없고 `mode=incremental`이면 legacy baseline migration 필요로 보고 code sync를 시작하지 않는다.
- [ ] 수정할 UI 코드 경로에 해당하는 project/domain rule을 먼저 읽는다.
- [ ] 코드 변경 검증이 필요하면 작업 환경의 `agent-test/<env>/rules.md`를 읽는다. 환경 미지정은 `local`로 본다.
- [ ] `git status --short`와 현재 `HEAD`를 확인한다.
- [ ] unrelated dirty worktree가 있으면 sync commit 전에 범위를 보고하고, agent-ui와 관련 코드 파일만 stage한다.
- [ ] 이전 sync 실패로 남은 관련 작업트리 변경이 있으면 보존할지, 사용자 결정과 충돌하는지 확인한다.
## 실행 절차
1. **동기화 범위 확정**
- `.sync-state.json`이 없고 `mode=incremental`이면 현재 agent-ui를 legacy baseline 후보로 본다.
- legacy baseline 후보는 `validate-agent-ui` 통과 후 agent-ui baseline commit과 `.sync-state.json` commit을 남기는 migration으로 처리하고, 같은 실행에서 코드 반영은 하지 않는다.
- `mode=incremental`이면 `.sync-state.json.last_synced_head` 이후 현재 `HEAD`/worktree까지의 agent-ui 변경분을 확인한다.
- 변경분 판정에서 `agent-ui/.sync-state.json` 자체는 제외한다.
- `mode=full`이면 현재 활성 `agent-ui/definition/**``agent-ui/frame/**` 전체를 코드와 대조한다.
- `mode=full`에서 `.sync-state.json`이 없으면 code sync 성공 후 새 sync state를 만든다.
- `가정` 또는 `불명확` 상태 항목은 코드 반영 대상에서 제외하고 USER_REVIEW로 남긴다.
- 현재 범위에 미해결 USER_REVIEW가 있으면 중단한다.
2. **코드 반영 방식 판정**
- 이 판정은 agent-ui 문서 작업의 크기가 아니라, 정합화된 agent-ui 변경분을 코드에 반영하는 구현 작업의 크기와 위험만 대상으로 한다.
- `execution-route=auto`이면 코드 반영 대상의 크기와 위험을 `direct-sync`, `plan-required`, `milestone-required` 중 하나로 판정한다.
- `direct-sync`는 다음 조건을 모두 만족할 때만 사용한다.
- 단일 view/component/frame 또는 한 화면 안의 국소 변경이다.
- 기존 route, shell, navigation, shared state, design token, package boundary를 그대로 사용한다.
- 새 정보구조, 새 주요 workflow, 새 공통 component 체계, 제품 방향 결정이 필요 없다.
- 변경 후보 코드가 소수 파일로 좁혀지고 검증 명령이 명확하다.
- `plan-required`는 목표와 범위는 명확하지만 독립 리뷰 가능한 구현 루프가 필요할 때 사용한다.
- 여러 view/component에 걸친 반영, shared component 추출, route/shell 조정, 테스트/검증 보강, UI 상태와 코드 변경을 함께 다루는 작업이 여기에 속한다.
- 이 경우 직접 코드 반영을 시작하지 않고 `plan` 스킬로 전환한다.
- plan에는 반영 대상 agent-ui 문서, 코드 후보, 최종 `validate-agent-ui`, code evidence 기준을 포함한다.
- plan이 만드는 `CODE_REVIEW-*-G??.md`에는 `Agent UI Completion` 섹션을 넣어 code-review PASS 때 listed agent-ui 문서를 `구현됨`으로 전환하게 한다.
- `milestone-required`는 코드 구현이 제품 UI 구조나 장기 작업 단위까지 바꾸는 경우 사용한다.
- navigation/information architecture 재정렬, 외부 제품 UI 분석 기반 재설계, 여러 workflow/role/surface를 묶는 작업, 활성 Milestone 범위 밖 작업이 여기에 속한다.
- 이 경우 직접 코드 반영과 plan 생성을 시작하지 않고 `update-roadmap`으로 Milestone/Epic/Task 배치를 먼저 남긴다.
- 이 Milestone에는 `완료 리뷰``agent-ui 상태 반영: 대기`를 남기고, `status: 구현됨` 전환은 plan 완료가 아니라 Milestone 종료 검토 항목으로 둔다.
- `plan-required` 또는 `milestone-required`로 판정하면 agent-ui 문서 status를 `구현됨`으로 바꾸지 않고, sync state와 commit/push도 갱신하지 않는다.
3. **코드 반영**
- 이 단계는 `execution-route=direct-sync`일 때만 수행한다. `plan-required` 또는 `milestone-required` 판정이면 Step 2의 라우팅 결과를 보고하고 해당 스킬 흐름으로 전환한다.
- `계획` 상태의 view/component/frame 요구사항을 UI 코드에 반영한다.
- existing component, route, shell, widget 구조를 우선하고 새 구조를 임의로 만들지 않는다.
- definition이 요구하는 정보 우선순위, region, action, state, component 참조를 코드 반영 기준으로 삼는다.
- wireframe/frame은 layout, density, visual relationship 보조 근거로만 사용하고 definition을 대체하지 않는다.
4. **검증**
- 관련 domain rule과 agent-test rule에 맞는 최소 검증을 실행한다.
- 검증 실패가 명확하고 에이전트가 해결 가능하면 수정과 검증을 반복한다.
- 구현 방향 충돌, 환경/권한 차단, 반복 실패, 사용자 판단이 필요한 시각 결과는 `agent-ui/USER_REVIEW.md`에 남기고 중단한다.
- USER_REVIEW로 중단하면 commit/push하지 않고 `.sync-state.json`도 갱신하지 않는다.
- USER_REVIEW로 중단할 때 관련 작업트리 변경은 사용자 결정과 충돌하지 않으면 보존하고, 재개 진입점과 변경 파일을 USER_REVIEW에 남긴다.
- `execution-route=direct-sync`에서 코드 반영과 검증이 모두 통과한 항목은 이 스킬 실행 안에서 agent-ui 문서의 `status``구현됨`으로 갱신하고 Source Evidence에 코드 경로를 남긴다.
5. **sync state와 commit/push**
- 이 단계는 `execution-route=direct-sync`에서 코드 반영, 검증, agent-ui status/code evidence 갱신이 모두 통과한 경우에만 수행한다.
- 검증이 통과하면 agent-ui/code 변경을 먼저 commit한다.
- 방금 만든 sync 결과 commit hash를 `agent-ui/.sync-state.json``last_synced_head`에 기록한다.
- `.sync-state.json`이 없으면 `agent-ops/skills/common/_templates/agent-ui/sync-state-template.json` 기준으로 새로 만든다.
- `.sync-state.json`에는 `last_sync_mode`, `last_synced_at`, `agent_ui_paths`, `code_paths`, `notes`를 갱신한다.
- `.sync-state.json` 변경을 별도 commit한다.
- commit message는 예를 들어 `sync: apply agent-ui to code``sync: record agent-ui sync state`처럼 목적이 분리되게 쓴다.
- `push=true`이면 두 commit을 push한다.
6. **결과 보고**
- sync mode와 scope
- execution route와 판정 근거
- 반영한 agent-ui 파일과 코드 파일
- 변경한 status
- 실행한 검증
- sync 결과 commit hash와 sync-state commit/push 결과
- USER_REVIEW 생성/갱신 여부
## 실행 결과 검증
- [ ] `validate-agent-ui`가 먼저 실행되었거나 `validated=true` 근거가 있는가
- [ ] 현재 sync 범위에 미해결 USER_REVIEW가 없는가
- [ ] 코드 반영 전에 `direct-sync`, `plan-required`, `milestone-required` 중 하나로 판정했는가
- [ ] `plan-required` 또는 `milestone-required` 판정에서 직접 코드 변경, status 구현됨 전환, sync state 갱신, commit/push를 하지 않았는가
- [ ] `direct-sync` 판정에서 코드 반영과 검증이 통과한 항목은 같은 실행 안에서 agent-ui 문서 status를 `구현됨`으로 바꾸고 code evidence를 남겼는가
- [ ] `plan-required` 판정에서 생성될 `CODE_REVIEW-*-G??.md``Agent UI Completion` 섹션으로 status 전환 규칙을 넘겼는가
- [ ] `가정` 또는 `불명확` 항목을 코드로 반영하지 않았는가
- [ ] `direct-sync`로 코드 반영된 항목의 status가 `구현됨`이고 code evidence가 있는가
- [ ] `direct-sync` 관련 검증이 통과했는가
- [ ] 실패 또는 차단 시 commit/push와 `.sync-state.json` 갱신을 하지 않았는가
- [ ] 실패 또는 차단 시 재개 진입점과 남은 변경 파일이 USER_REVIEW에 기록되었는가
- [ ] `direct-sync` 성공 시 sync 결과 commit과 `.sync-state.json` commit이 분리되었는가
- [ ] `direct-sync` 성공 시 `.sync-state.json.last_synced_head`가 sync 결과 commit hash를 가리키는가
- [ ] unrelated dirty file이 sync commit에 포함되지 않았는가
- 검증 실패 시: 에이전트가 해결할 수 없으면 `agent-ui/USER_REVIEW.md`에 남기고 중단한다.
## 출력 형식
```md
## agent-ui 코드 동기화 결과: <PASS|PLAN_REQUIRED|MILESTONE_REQUIRED|USER_REVIEW|FAIL>
- Mode: <incremental|full>
- Scope: <scope>
- Execution Route: <direct-sync|plan-required|milestone-required>
- Agent UI Changes: <파일 목록 또는 없음>
- Code Changes: <파일 목록 또는 없음>
- Status Updates: <구현됨 전환 목록 또는 없음>
- Verification: <명령과 결과>
- Sync Commit: <hash 또는 없음>
- Sync State Commit/Push: <완료/생략/실패>
- USER_REVIEW: <생성/갱신/없음>
- Remaining Issues: <목록 또는 없음>
```
## 금지 사항
- `validate-agent-ui`를 거치지 않고 코드 동기화를 시작하지 않는다.
- 미해결 USER_REVIEW가 있는 범위를 코드에 반영하지 않는다.
- `가정` 또는 `불명확` 상태 항목을 코드로 구현하지 않는다.
- `plan-required` 또는 `milestone-required`로 판정된 작업을 같은 `sync-agent-ui` 실행에서 직접 구현하지 않는다.
- `execution-route=milestone-required`로 라우팅된 agent-ui 코드 작업의 일반 plan 완료만으로 agent-ui status를 일괄 `구현됨`으로 바꾸지 않는다. 종료 검토 통과와 code evidence가 있는 항목만 반영한다.
- 검증 실패나 사용자 판단 차단 상태에서 commit/push하지 않는다.
- `.sync-state.json`을 agent-ui 변경분 판정 대상으로 삼지 않는다.
- 정의서와 충돌하는 wireframe만을 근거로 코드 구현을 확정하지 않는다.
- 실패한 sync의 작업트리 변경을 사용자 결정 없이 되돌리지 않는다.

View file

@ -0,0 +1,182 @@
---
name: sync-milestone-workstate
version: 1.1.0
description: 현 마일스톤과 작업현황 동기화, 현재 마일스톤 작업현황 동기화, 마일스톤 완료내역 동기화, agent-task 완료를 마일스톤에 반영, active/archive complete.log 후보 스캔, 누락된 Roadmap Completion 복구, 작은 작업처럼 agent-task 기록이 없는 완료 내역을 관련 파일과 git 기록까지 종합 확인, 마일스톤 체크박스 재동기화 요청에서 Milestone Task, 상태, Phase/current 라벨을 실제 evidence와 맞추는 절차
---
# sync-milestone-workstate
## 목적
현재 또는 지정 Milestone의 기능 Task 상태를 실제 작업 evidence와 동기화한다.
새 작업을 배치하거나 구현 계획을 수정하지 않는다.
`complete.log``Roadmap Completion`은 가장 강한 직접 근거로 사용하되, 그 파일이 있더라도 관련 파일과 git history로 최소 sanity pass를 수행한다.
`complete.log`가 없거나 불완전해도 완료가 없다고 단정하지 않는다.
작은 작업이나 수동 수정처럼 `agent-task` 기록이 없을 수 있으므로 Milestone의 관련 경로, 실제 파일 내용, git history, 테스트/검증 흔적을 함께 확인한다.
런타임이 `origin-task``complete-log`를 단건 완료 이벤트로 전달한 일반 반영은 `update-roadmap`을 사용한다.
## 언제 호출할지
- 사용자가 "현 마일스톤과 작업현황 동기화", "현재 마일스톤 작업현황 동기화", "마일스톤 작업현황 동기화"라고 요청할 때
- 사용자가 "마일스톤 완료내역 동기화", "agent-task 완료를 마일스톤에 반영", "complete.log 후보 스캔"이라고 요청할 때
- 사용자가 "누락된 Roadmap Completion 복구", "마일스톤 체크박스 재동기화", "로드맵 작업 완료 상태 동기화"라고 요청할 때
- 사용자가 agent-task에는 없지만 실제 파일/git 기준으로는 완료된 것 같다고 지적할 때
- code-review PASS/archive 이후 runtime completion event 반영이 누락되었는지 확인하고 file-based fallback으로 복구해야 할 때
## 입력
- `target-milestone`: 동기화할 Milestone 이름, slug, 또는 경로. 없으면 `agent-roadmap/current.md`의 활성 Milestone 단일 후보를 사용한다. (선택)
- `complete-log`: 특정 `complete.log` 경로. 지정되면 이 파일을 우선 검증하되, 같은 Milestone slug의 active/archive 후보도 함께 확인한다. (선택)
- `mode`: `sync` 또는 `check-only`. 기본값은 `sync`다. (선택)
- `check-only`: 어떤 파일도 수정하지 않는다. Milestone, Phase, `current.md`, `.agent-roadmap-sync/locks.yaml` 모두 쓰기 금지이며 반영 후보만 보고한다.
## 먼저 확인할 것
- [ ] `agent-roadmap/current.md`를 읽어 활성 Milestone 후보를 확인한다.
- [ ] 대상 Milestone 문서의 `상태`, `구현 잠금`, `기능`, `완료 리뷰`, `작업 컨텍스트`를 확인한다.
- [ ] 대상 Phase `PHASE.md``Milestone 흐름`에 대상 Milestone 항목이 있는지 확인한다.
- [ ] 대상 Milestone의 `SDD: 필요` 여부와 `SDD 문서`, `USER_REVIEW.md` 존재 여부를 확인한다.
- [ ] 같은 slug의 active task와 archive task `complete.log` 후보를 모두 탐색한다. active만 보고 no-op으로 끝내지 않는다.
- [ ] 관련 파일과 git history를 최소 확인한다. `complete.log`가 없거나 일부 Task만 설명하면 더 깊게 감사한다.
## 실행 절차
1. **대상 Milestone 확정**
- `target-milestone`이 있으면 활성 `agent-roadmap/phase/*/milestones/*.md`에서 정확히 하나를 찾는다.
- `target-milestone`이 없으면 `agent-roadmap/current.md`의 활성 Milestone이 정확히 하나인지 확인한다.
- 대상이 없거나 둘 이상이면 Milestone을 수정하지 않고 target 불명확으로 보고한다.
- 대상 경로가 `agent-roadmap/archive/**`이면 수정하지 않고 archive target 불가로 보고한다.
2. **Milestone Task와 evidence scope 읽기**
- Milestone `기능` 섹션의 Task id만 완료 후보로 본다.
- Task id는 `- [ ] [item-id]` 또는 `- [x] [item-id]` 형식에서 추출한다.
- 각 Task의 설명과 `검증:` 문구를 기록한다.
- `구현 잠금`의 상태, `결정 필요`, `SDD: 필요|불필요`, SDD 문서 링크/경로를 확인한다.
- `작업 컨텍스트`의 관련 경로, Milestone 범위, Task 설명의 코드/문서 키워드를 evidence scope로 삼는다.
- 관련 경로가 전혀 없으면 Task 설명에서 검색어를 만들되, 후보가 넓거나 모호하면 Task를 자동 완료하지 않고 scope 불명확으로 보고한다.
3. **complete.log 후보 수집**
- 대상 Milestone slug를 `<milestone-slug>`로 두고 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` 입력이 있으면 그 파일도 후보에 포함하되, `Roadmap Completion`의 Milestone 경로가 대상과 일치해야 직접 반영한다.
- 일반 `agent-task/archive/**` 전체를 훑지 말고 위 패턴에 맞는 같은 milestone task group만 읽는다.
4. **Roadmap Completion 직접 근거 검증**
- 각 `complete.log``Roadmap Completion` 섹션이 없으면 직접 Task 체크 근거로 쓰지 않는다. 파일/git evidence를 찾기 위한 힌트로만 사용하고 no-op 사유에 남긴다.
- `Milestone:` 경로가 대상 Milestone 경로와 정확히 일치하지 않으면 해당 파일을 직접 반영하지 않고 mismatch로 보고한다.
- `Completed task ids`의 id가 대상 Milestone의 기존 Task id와 정확히 일치하지 않으면 직접 반영하지 않고 unknown task id로 보고한다.
- 완료 근거는 `PASS` 또는 동등한 완료 판정과 검증 evidence가 있는 항목만 직접 인정한다.
- 같은 Task id에 여러 `complete.log`가 있으면 PASS 근거가 있는 항목을 모으고, 서로 충돌하는 `Not completed task ids`가 있으면 충돌을 보고한다.
5. **파일/git evidence 감사**
- 항상 대상 Milestone의 관련 파일과 git history를 최소 확인한다.
- `Roadmap Completion`으로 확인되지 않은 Task가 있거나 사용자가 실제 구현 완료를 지적하면 Task별 상세 감사를 수행한다.
- 관련 파일을 `rg --files <관련 경로>`와 Task 키워드 `rg`로 찾고, 필요한 파일 본문을 읽어 Task 설명과 직접 대응되는 구현/문서/테스트 변경을 확인한다.
- `git log --oneline -- <관련 경로>`와 필요한 경우 `git show --stat --name-only <commit>`로 Milestone 관련 커밋을 확인한다.
- 커밋 메시지만으로 Task를 완료 처리하지 않는다. 커밋이 변경한 파일과 현재 파일 내용이 Task 설명을 충족해야 한다.
- Task 완료 인정 기준:
- 구현/산출물 evidence가 Task 설명과 직접 대응한다.
- Task에 `검증:`이 있으면 해당 검증 명령의 기록, 현재 테스트 실행 결과, 또는 같은 범위를 검증하는 명시 evidence가 있다.
- `validation-tests` 같은 테스트 Task는 테스트 코드와 검증 실행 evidence가 모두 있어야 한다.
- evidence가 의미상 유사하지만 Task id와 연결이 불분명하면 `[x]` 처리하지 않고 `검토 필요`로 보고한다.
6. **SDD Evidence Map 확인**
- `SDD: 필요`인 Milestone은 direct evidence와 file/git evidence 모두 SDD gate를 통과해야 한다.
- SDD `Acceptance Scenarios``Evidence Map`에서 각 완료 후보 Task id와 연결된 scenario가 있는지 확인한다.
- 연결된 scenario의 evidence가 확인한 complete log, 파일 변경, git commit, verification 중 하나로 설명 가능해야 한다.
- SDD 파일이 없거나 `USER_REVIEW.md`가 남아 있거나 Evidence Map 연결이 비어 있으면 Task 체크 또는 `[검토중]` 전환을 하지 않고 차단 사유로 보고한다.
7. **Milestone 문서 반영**
- `mode=check-only`이면 어떤 파일도 수정하지 않고 반영 후보만 보고한다.
- 검증된 완료 Task id만 `[x]`로 바꾼다. 이미 `[x]`인 항목은 유지한다.
- 일부 Task만 완료되었고 미완료 Task가 남으면 Milestone 상태는 `[진행중]`으로 둔다. 단, 기존 상태가 `[검토중]`, `[보류]`, `[폐기]`이면 자동으로 낮추지 않고 차이만 보고한다.
- 모든 기능 Task가 `[x]`이고 `구현 잠금``해제`, `결정 필요: 없음`, SDD 사용자 리뷰 없음, SDD evidence 충족이면 Milestone 상태를 `[검토중]`으로 바꾼다.
- `[검토중]`으로 바꾸면 `완료 리뷰` 섹션을 만들거나 갱신하고, 사용한 `complete.log`, 파일/git evidence 요약, 완료 Task id, 남은 차단 항목 없음 또는 요약을 1~3줄로 남긴다.
- 모든 Task가 `[x]`여도 구현 잠금이나 SDD gate가 남으면 `[검토중]`으로 바꾸지 않고 `완료 리뷰` 또는 `작업 컨텍스트`에 차단 항목을 남긴다.
- 이 스킬은 Milestone을 `[완료]`로 바꾸거나 archive로 이동하지 않는다.
8. **Phase와 current 라벨 동기화**
- `mode=check-only`이면 이 단계를 쓰기 없이 확인만 한다.
- 대상 Phase `PHASE.md``Milestone 흐름`에서 대상 Milestone 상태 라벨을 Milestone 본문 상태와 맞춘다.
- `agent-roadmap/current.md`에 대상 Milestone이 있으면 상태 라벨을 Milestone 본문 상태와 맞춘다.
- `current.md`에는 `[완료]` 또는 `[폐기]`를 남기지 않는다. 이 스킬은 `[검토중]`까지 유지할 수 있다.
9. **workspace lock 확인**
- `mode=check-only`이면 관련 lock 여부와 필요한 동기화 후보만 보고하고 `locks.yaml`을 수정하지 않는다.
- `.agent-roadmap-sync/locks.yaml`이 있으면 대상 Milestone identity로 `agent-ops/bin/roadmap-dependency-checker.sh --find-milestone "<project>:<milestone-path>" both "<locks-file>"`를 실행한다.
- 관련 lock이 없으면 결과에 `Workspace 잠금: 관련 lock 없음`을 남긴다.
- 대상 Milestone identity가 어느 entry의 `rely-on.target`과 일치하면 대상 Milestone 상태 기준으로 해당 `rely-on.status`를 동기화한다. `[검토중]` 또는 `[완료]`이면 `enable`, 그 외 상태면 `disable`이다.
- 대상 Milestone identity가 어느 entry의 `locked`와 일치하면 모든 `rely-on.status``enable`인지 결과에 남긴다.
- 이 스킬에서 새 lock을 만들거나 다른 Milestone의 구현 잠금을 직접 해제하지 않는다.
10. **결과 보고**
- 수정 파일과 변경 전/후 상태를 보고한다.
- 읽은 active/archive `complete.log` 후보 수, 확인한 관련 파일/git 범위, 반영한 Task id를 보고한다.
- 반영하지 않은 `complete.log`나 Task가 있으면 이유를 보고한다.
- SDD gate, 완료 리뷰, Workspace lock, 남은 미완료 Task, 검토 필요 Task를 보고한다.
- 대상 Milestone, 수정 파일, `complete.log`, SDD, 사용자 리뷰 같은 문서/산출물 포인터는 raw path만 쓰지 말고 `[표시 제목](상대경로)` Markdown 링크로 보고한다.
## 실행 결과 검증
- [ ] 대상 Milestone이 활성 경로에서 정확히 하나로 확정되었는가
- [ ] 같은 `m-<milestone-slug>`의 active/root/nested `complete.log`와 archive/root/nested `complete.log` 후보를 모두 확인했는가
- [ ] archive 확인을 생략하고 active task만 근거로 no-op 처리하지 않았는가
- [ ] `complete.log` 부재만으로 완료 Task 없음이라고 단정하지 않았는가
- [ ] 관련 파일과 git history를 확인했거나, scope 불명확 사유를 보고했는가
- [ ] `Roadmap Completion`의 Milestone 경로와 Task id가 대상 Milestone과 exact match였는가
- [ ] `SDD: 필요`인 경우 SDD 파일, `USER_REVIEW.md` 부재, Acceptance Scenario, Evidence Map 연결을 확인했는가
- [ ] 완료 근거가 있는 Task만 `[x]`로 바꾸었는가
- [ ] 모든 Task 완료와 구현 잠금 해제 조건이 충족된 경우에만 `[검토중]`으로 전환했는가
- [ ] `[검토중]`으로 전환했다면 `완료 리뷰`에 complete.log, 파일/git evidence, 남은 차단 항목이 남았는가
- [ ] Phase `PHASE.md``agent-roadmap/current.md`의 상태 라벨이 Milestone 본문과 일치하는가
- [ ] `[검토중]` 전환만 수행하고 `[완료]` 전환 또는 archive 이동을 하지 않았는가
- [ ] `.agent-roadmap-sync/locks.yaml`이 있으면 관련 lock 여부와 필요한 `rely-on.status` 동기화를 결과에 반영했는가
- [ ] 결과 보고의 문서/산출물 포인터가 raw path만 남지 않고 Markdown 링크로 작성되었는가
- [ ] `git diff --check`를 실행했는가
- 검증 실패 시: 파일을 추가로 추정 수정하지 말고 실패한 항목, 차단 사유, 필요한 evidence 경로를 보고한다.
## 출력 형식
```markdown
## 동기화 완료
- 대상 Milestone: [<milestone-name>](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
- 모드: <sync | check-only>
- 수정 파일:
- <없음 | [문서명](path)>
## 반영 내용
- 상태: <변경 없음 | 이전 -> 이후>
- 완료 Task: <id 목록 또는 없음>
- 미완료 Task: <id 목록 또는 없음>
- 검토 필요 Task: <id 목록 또는 없음>
- complete.log 후보: active <N>개, archive <N>
- 반영한 complete.log:
- <[complete.log](path)>
- 반영 제외 complete.log:
- <[complete.log](path)> - <사유>
- 파일/git evidence:
- <task-id 또는 범위> - <파일/커밋/검증 요약>
- SDD gate: <불필요 | 충족 | 차단: 사유>
- 완료 리뷰: <변경 없음 | 검토중 갱신 | 잠금 차단 기록>
- Workspace 잠금: <관련 lock 없음 | 상태 요약 | 미확인 사유>
## TODO 항목
- <남은 차단 항목 또는 없음>
```
## 금지 사항
- active `agent-task/m-<milestone-slug>`만 확인하고 archive `complete.log` 확인 없이 no-op 처리하지 않는다.
- `complete.log` 부재만으로 Task 미완료를 단정하지 않는다.
- 대상 slug와 다른 `agent-task/archive/**` 문서를 일반 탐색하지 않는다.
- 커밋 메시지, 파일명, plan/review log만으로 Task를 `[x]` 처리하지 않는다.
- `complete.log`의 Task id를 의미 유사도, 순서, 파일명으로 보정하지 않는다.
- 파일/git evidence가 있어도 Task 설명과 직접 대응되지 않으면 완료 처리하지 않는다.
- SDD gate가 필요한데 Evidence Map 연결을 확인하지 않고 `[검토중]`으로 전환하지 않는다.
- 구현 잠금이 남아 있거나 `결정 필요`가 있으면 `[검토중]`, `[완료]`, archive를 수행하지 않는다.
- 이 스킬에서 새 Milestone/Epic/Task를 만들거나 기존 id를 바꾸지 않는다.
- 이 스킬에서 Milestone을 `[완료]`로 전환하거나 archive 이동하지 않는다.

View file

@ -0,0 +1,43 @@
---
name: sync-pull
description: agentic-framework에서 현재 프로젝트로 agent-ops를 내려받는다. "agent-ops pull해", "agentic-framework에서 가져와" 요청 시 사용한다.
---
# sync-pull
## 목적
`agent-ops/bin/sync.sh --pull`을 호출해 agentic-framework → 현재 프로젝트 방향으로 agent-ops를 내려받는다.
내려받기 과정에서 현재 프로젝트의 `.gitignore` Agent-Ops 관리 block과 AI ignore / permission 설정도 보강한다.
## 언제 호출할지
- "agent-ops pull해", "agent-ops 가져와" 요청 시
- "agentic-framework에서 가져와" 요청 시
- "agent-ops 내려받아" 요청 시
## 실행 절차
1. 현재 프로젝트의 **상위 폴더(`../`)**`agentic-framework` 폴더가 있는지 확인한다 (현재 폴더 내부가 아님)
2. **있으면**: `agent-ops/bin/sync.sh --pull agentic-framework` 실행
3. **없으면**: 사용자에게 agentic-framework 경로 입력을 안내하고, 입력받은 경로로 실행
```bash
agent-ops/bin/sync.sh --pull <target>
```
## 실행 결과 검증
- [ ] sync.sh 가 오류 없이 완료됐는가
- [ ] 현재 프로젝트 버전이 framework 버전과 일치하는가
- [ ] `agent-ops/bin/entry-files.sh`의 모든 진입 파일이 갱신됐고, 내용이 framework의 `agent-ops/rules/common/rules.md`와 일치하는가
- [ ] `.gitignore`에 Agent-Ops 관리 gitignore block이 있고 `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, `agent-roadmap/current.md`가 포함되어 있는가
- [ ] `agent-roadmap/current.md`가 있으면 파일은 보존되고 git 추적 대상에서는 제거됐는가
- [ ] `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 Agent-Ops 관리 block이 있고 그 안에 `agent-task/archive/**``agent-roadmap/archive/**`가 포함되어 있는가
- [ ] `.claude/settings.json`, `opencode.json``agent-task/archive/**` 또는 `agent-roadmap/archive/**` hard read/glob deny가 남아 있지 않은가
- [ ] 현재 프로젝트에 기존 archive hard deny가 있으면 init-agent-ops 표준에 맞게 제거했는가
- [ ] agentic-framework의 `.gitignore`와 AI ignore / permission 파일은 수정되거나 stage되지 않았는가
## 금지 사항
- sync.sh 를 거치지 않고 직접 파일을 복사하지 않는다

View file

@ -0,0 +1,120 @@
---
name: sync-push
description: 현재 프로젝트의 agent-ops를 공통 원본 repo로 올리거나, `.agent-ops-source`가 있는 공통 원본 repo의 agent-ops를 대상 프로젝트 또는 상위 폴더의 agent-ops 적용 프로젝트 전체로 push하고 푸시한다. "agent-ops 싱크해", "agent-ops 동기화해", "agentic-framework에 올려줘" 요청 시 사용한다.
---
# sync-push
## 목적
`agent-ops/bin/sync.sh`를 호출해 agent-ops 공통 파일을 push 방향으로 동기화한다.
- 일반 프로젝트에서는 현재 프로젝트 → `.agent-ops-source`가 있는 공통 원본 repo 방향으로 올린다.
- `.agent-ops-source`가 있는 공통 원본 repo에서는 원본 repo → 대상 프로젝트 방향으로 보내고, 대상 repo를 commit/push 한다.
- 공통 원본 repo에서 대상이 명시되지 않으면 현재 프로젝트의 상위 폴더에 있는 agent-ops 적용 프로젝트 전체로 보낸다.
## 버전 정책
- 현재 프로젝트 루트에 `.agent-ops-source`가 있으면, 대상 프로젝트로 전파하는 push 동기화는 버전을 올리지 않는다.
- 이 경우 현재 공통 원본 repo의 `agent-ops/.version` 값을 그대로 대상 repo에 전파한다.
- 일반 프로젝트에서 `.agent-ops-source`가 있는 공통 원본 repo로 공통 변경을 올리는 push 동기화는 기존처럼 `sync.sh`가 버전을 한 단계 올린다.
## 언제 호출할지
- "agent-ops 싱크해", "agent-ops 동기화해" 요청 시
- "agentic-framework에 올려줘" 요청 시
- "agent-ops를 [프로젝트]로 싱크해" 요청 시
## 실행 절차
### 현 프로젝트가 일반 프로젝트인 경우 (`.agent-ops-source` 없음)
1. 현재 프로젝트의 **상위 폴더(`../`)**`.agent-ops-source`가 있는 공통 원본 repo가 있는지 확인한다. 기본 후보는 `agentic-framework`다.
2. **있으면**: `agent-ops/bin/sync.sh` 실행 또는 `agent-ops/bin/sync.sh agentic-framework` 실행
3. **없으면**: 사용자에게 agentic-framework 경로 입력을 안내하고, 입력받은 경로로 실행
4. 공통 관리 파일 변경 없이 `agent-ops/.version`만 다른 경우 `sync.sh`는 버전 갱신과 commit/push를 건너뛴다
5. 공통 관리 파일 변경이 없어도 현재 프로젝트 또는 공통 원본 repo의 진입 파일이 `agent-ops/rules/common/rules.md`와 다르면 진입 파일만 재적용하고 commit/push 한다
6. 공통 관리 파일 변경이 있으면 `sync.sh`가 버전을 한 단계 올리고 현재 프로젝트와 공통 원본 repo에 같은 버전을 반영한다
7. 이때 현재 프로젝트와 공통 원본 repo의 진입 파일은 각각 자기 `agent-ops/rules/common/rules.md` 내용으로 재적용한다
8. 일반 프로젝트에서 공통 원본 repo로 올릴 때는 AI ignore / permission 파일을 보강하거나 stage하지 않는다
### 현 프로젝트가 공통 원본 repo인 경우 (`.agent-ops-source` 있음)
1. 사용자 요청에서 target 프로젝트명 또는 경로를 추출한다
2. 공통 원본 repo 자신의 진입 파일이 `agent-ops/rules/common/rules.md`와 다르면 먼저 재적용하고 commit/push 한다
3. **명시된 경우**: `agent-ops/bin/sync.sh <target>` 실행
4. **명시되지 않은 경우**: `agent-ops/bin/sync.sh` 실행
5. target이 없으면 `sync.sh`가 현재 프로젝트 기준 상위 폴더(`../`)의 하위 디렉터리 중 `agent-ops/` 폴더가 있는 프로젝트를 모두 대상으로 삼는다
6. `sync.sh`는 현재 공통 원본 repo의 `agent-ops/rules/common/rules.md` 내용을 대상 프로젝트 루트의 진입 파일에 덮어쓴다
7. 적용 후 각 대상 repo에서 agent-ops 공통 관리 경로(`rules/common/rules.md` 포함), 진입 파일, `.gitignore`, AI ignore / permission 파일을 stage 하여 commit/push 한다
8. `.gitignore`와 AI ignore / permission 파일은 대상 프로젝트의 기존 내용을 덮어쓰지 않고, Agent-Ops 관리 block 또는 Agent-Ops 전용 permission key만 보강한다
9. 이 과정에서는 버전을 새로 올리지 않고 현재 공통 원본 repo의 `agent-ops/.version` 값을 그대로 대상 프로젝트에 반영한다
덮어쓰기 대상은 `init-agent-ops` 초기 세팅과 동일하며, 실제 목록은 `agent-ops/bin/entry-files.sh``AGENT_OPS_ENTRY_FILES`를 단일 기준으로 사용한다.
모든 repo에서 진입 파일 내용은 해당 repo의 `agent-ops/rules/common/rules.md`와 같아야 한다.
| 에이전트 | 파일명 |
|---------|--------|
| Gemini | `GEMINI.md` |
| Claude | `CLAUDE.md` |
| Kilo Code / OpenCode | `AGENTS.md` |
| Cursor | `.cursorrules` |
| Cline | `.clinerules` |
대상 프로젝트에 기존 진입 파일이 있어도 보존하거나 병합하지 않고 `agent-ops/rules/common/rules.md` 내용으로 교체한다.
## Gitignore / AI Ignore / Permission 재적용
- 이 절차는 `.agent-ops-source`가 있는 공통 원본 repo에서 대상 프로젝트로 push할 때와 `--pull`로 공통 원본 repo에서 현재 프로젝트로 내려받을 때만 적용한다.
- 일반 프로젝트에서 공통 원본 repo로 올리는 push에서는 `.gitignore`와 AI ignore / permission 파일을 수정하거나 stage하지 않는다.
- `.gitignore`는 사용자 영역을 수정하지 않고 아래 관리 block만 추가하거나 교체한다. 이 예외는 `*.log` 같은 전역 ignore가 있어도 plan/review/archive task 산출물이 git에 잡히도록 하고, `agent-roadmap/current.md`는 브랜치별 로컬 포인터로 남긴다.
```text
# BEGIN Agent-Ops managed gitignore
!agent-task/
!agent-task/**/
!agent-task/**/*.md
!agent-task/**/*.log
agent-roadmap/current.md
# END Agent-Ops managed gitignore
```
- `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`는 사용자 영역을 수정하지 않고 아래 관리 block만 추가하거나 교체한다.
```text
# BEGIN Agent-Ops managed ignore
agent-task/archive/**
agent-roadmap/archive/**
# END Agent-Ops managed ignore
```
- 관리 block 밖의 기존 ignore 항목은 사용자 소유로 보고 삭제, 정렬, 중복 제거하지 않는다.
- `.claude/settings.json``opencode.json`은 기존 사용자 설정을 보존하고 `agent-task/archive/**``agent-roadmap/archive/**` hard read/glob deny를 제거한다.
- archive는 기본 컨텍스트에서 제외하되 필요한 경우 명시 경로로 읽을 수 있어야 하므로 `.claude/settings.json`이나 `opencode.json`의 hard read/glob deny로 두지 않는다.
- 대상 프로젝트에 기존 archive hard read/glob deny가 있으면 init-agent-ops 표준에 맞게 제거한다.
- `opencode.json`의 watcher ignore에는 `agent-task/archive/**``agent-roadmap/archive/**`를 둘 수 있다.
```bash
agent-ops/bin/sync.sh [target]
```
푸시 대상 path는 항상 `agent-ops/.version`, `agent-ops/bin`, `agent-ops/rules/common`, `agent-ops/skills/common`, `AGENT_OPS_ENTRY_FILES`의 진입 파일로 제한한다. 예외적으로 `agent-roadmap/current.md`가 이미 추적 중이고 `.gitignore`에 로컬 current ignore가 있으면 파일을 보존한 채 git 추적에서 제거하는 삭제만 함께 commit할 수 있다. `.gitignore`와 AI ignore / permission 파일은 `.agent-ops-source`가 있는 공통 원본 repo에서 일반 프로젝트로 내려보내는 경우에만 대상 repo에서 추가 stage한다.
## 실행 결과 검증
- [ ] sync.sh 가 오류 없이 완료됐는가
- [ ] 버전 충돌 경고가 없었는가 — 있었다면 사용자에게 수동 머지 필요함을 알린다
- [ ] 대상 repo의 `agent-ops/rules/common/rules.md`가 현재 공통 원본 repo의 `agent-ops/rules/common/rules.md`와 일치하는가
- [ ] 현재 repo와 대상 repo의 `AGENT_OPS_ENTRY_FILES` 진입 파일이 각각 자기 repo의 `agent-ops/rules/common/rules.md`와 일치하는가
- [ ] 공통 원본 repo에서 대상 프로젝트로 push한 경우, `agent-ops/bin/entry-files.sh`의 모든 진입 파일 내용이 현재 공통 원본 repo의 `agent-ops/rules/common/rules.md`와 일치하는가
- [ ] 공통 원본 repo에서 대상 프로젝트로 push한 경우, `.gitignore`에 Agent-Ops 관리 gitignore block이 있고 `!agent-task/`, `!agent-task/**/`, `!agent-task/**/*.md`, `!agent-task/**/*.log`, `agent-roadmap/current.md`가 포함되어 있는가
- [ ] 대상 프로젝트에서 `agent-roadmap/current.md`가 있으면 파일은 보존되고 git 추적 대상에서는 제거됐는가
- [ ] 공통 원본 repo에서 대상 프로젝트로 push한 경우, `.geminiignore`, `.aiexclude`, `.cursorignore`, `.clineignore`에 Agent-Ops 관리 block이 있고 그 안에 `agent-task/archive/**``agent-roadmap/archive/**`가 포함되어 있는가
- [ ] 공통 원본 repo에서 대상 프로젝트로 push한 경우, `.claude/settings.json``opencode.json``agent-task/archive/**` 또는 `agent-roadmap/archive/**` hard read/glob deny가 남아 있지 않은가
- [ ] 대상 프로젝트에 기존 archive hard deny가 있으면 init-agent-ops 표준에 맞게 제거했는가
- [ ] 일반 프로젝트에서 공통 원본 repo로 push한 경우, `.gitignore`와 AI ignore / permission 파일이 공통 원본 repo에 유입되지 않았는가
- [ ] 대상 repo에 commit/push 된 path가 방향별 허용 범위로 제한되었는가
## 금지 사항
- sync.sh 를 거치지 않고 직접 파일을 복사하지 않는다

View file

@ -0,0 +1,156 @@
---
name: update-agent-ui
version: 1.1.1
description: 화면정의서, view, component, frame, wireframe 내용을 agent로 수정하고 후속 validate 필요성과 sync intent 전달 여부를 판단하는 스킬
---
# update-agent-ui
## 목적
기존 `agent-ui/`의 화면정의서와 wireframe 관련 문서를 갱신한다.
사용자가 "화면정의서에 X 추가", "wireframe에 사이드바 추가"처럼 agent-ui 명사를 쓰지 않아도 UI 정의 문서 수정 요청이면 이 스킬을 사용한다.
오래된 결정이 현재 기준을 흐리면 archive log로 분리하고, 변경 후 `validate-agent-ui` 필요성과 code sync intent 전달 여부를 판단한다.
코드 구현 규모 판정, plan 라우팅, roadmap/milestone 라우팅은 `sync-agent-ui` 책임이며 이 스킬에서 수행하지 않는다.
## 언제 호출할지
- 화면 정의서, view 정의, component 정의를 추가하거나 수정할 때
- wireframe 또는 Excalidraw visual source 연결을 추가하거나 수정할 때
- 기존 구현 코드 또는 컨셉 문서 변화에 맞춰 Source Evidence와 Status를 갱신할 때
- agent-ui 문서의 decision history, open question, user review를 갱신할 때
- ops/dev UI 정의를 제품 진행 상황에 맞춰 동기화할 때
- 사용자가 "화면정의서에 ... 추가/수정/삭제", "와이어프레임에 ... 추가/수정/삭제", "wireframe에 ... 반영"처럼 요청할 때
- 사용자가 `UIR-NNN` 결정, agent-ui USER_REVIEW 해결, 화면정의서와 코드 불일치 보정을 요청할 때
## 입력
- `change`: 갱신할 내용 요약 (필수)
- `view-id`: 대상 view id (선택)
- `component-id`: 대상 component id 또는 path id (선택)
- `frame-source`: 예: `wire.excalidraw`, `overview.png` (선택)
- `evidence`: 코드, 문서, 사용자 입력 근거 경로 또는 요약 (선택)
- `status`: `구현됨`, `계획`, `가정`, `불명확` 중 하나 (선택)
- `mode`: `definition`, `frame`, `component`, `mixed` 중 하나. 기본값은 `mixed` (선택)
- `post-validate`: `auto`, `true`, `false` 중 하나. 기본값은 `auto` (선택)
- `post-sync`: `auto`, `true`, `false` 중 하나. 기본값은 `auto` (선택)
- `review-resolution`: 해결할 `UIR-NNN`과 결정 내용 (선택)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules-agent-ui.md`를 읽는다.
- [ ] `agent-ui/` 존재 여부를 확인한다. 없으면 `create-agent-ui` 대상이라고 보고하고 중단한다.
- [ ] `agent-ui/definition/index.md``agent-ui/frame/index.md`를 읽는다.
- [ ] 대상 view/component/frame 문서가 있으면 해당 활성 문서만 읽는다.
- [ ] `agent-ui/USER_REVIEW.md`가 있으면 현재 변경과 관련된 항목만 확인한다.
- [ ] `definition/archive/**``archive/user-review/**`는 사용자가 과거 확인, 복원, 비교를 요청한 경우가 아니면 읽지 않는다.
- [ ] 필요한 템플릿만 `agent-ops/skills/common/_templates/agent-ui/`에서 읽는다.
## 실행 절차
1. **대상 분류**
- `view-id`가 있으면 view 정의를 대상으로 삼고, frame 문서가 있거나 `frame-source`가 입력된 경우에만 frame 문서를 대상으로 삼는다.
- `component-id`가 있으면 component 정의를 대상으로 삼는다.
- `frame-source`가 있으면 대응 `frame/views/<view-id>/index.md`에 visual source를 연결한다.
- 대상이 모호하면 추정으로 새 문서를 만들지 않고 `agent-ui/USER_REVIEW.md`에 결정 항목을 남긴다.
2. **정의 갱신**
- 현재 기준은 `definition/**` 활성 문서에 반영한다.
- 활성 Markdown 문서의 frontmatter를 유지하고, 새 문서는 `rules-agent-ui.md`의 Frontmatter Schema를 적용한다.
- view 문서에는 status, source evidence, purpose, tasks, information priority, regions, actions, states, open questions, decision history를 유지한다.
- component 문서에는 status, source evidence, purpose, used by, anatomy, variants, states, rules, decision history를 유지한다.
- 구현 코드 반영 완료 항목은 `구현됨`, 문서 기준으로 정합화됐지만 코드 반영 전이거나 재작업 대상인 항목은 `계획`, 사용자 입력/추정만 있는 항목은 `가정`, 판단 불가 항목은 `불명확`으로 둔다.
- 실제 근거 파일이 없으면 frontmatter `source_evidence[].path``null`로 둔다.
- frontmatter의 `status`, `source_evidence`, `regions`와 본문 `Status`, `Source Evidence`, `Regions`가 충돌하지 않게 함께 갱신한다.
- `status`가 입력되었더라도 evidence와 맞지 않으면 임의로 확정하지 않고 USER_REVIEW로 남긴다.
- 새 view/component를 만들 때는 `Source Evidence``Status`를 반드시 채운다.
- 오래된 결정이 현재 기준을 흐리면 대응되는 `definition/archive/**.log`로 이동하거나 추가한다. 단순 변경 이벤트를 모두 archive로 남기지 않는다.
3. **frame 갱신**
- `frame-source`가 있고 대응되는 `frame/views/<view-id>/index.md`가 없으면 템플릿으로 만든다.
- visual source가 있으면 frontmatter `visual_source`와 본문 `Visual Source`에 함께 기록한다.
- visual source가 없으면 새 frame-view 문서를 만들지 않는다.
- 기존 frame-view 문서의 visual source가 제거되고 더 이상 연결할 visual source가 없으면 frame-view 삭제 후보로 보고한다. 판단이 명확하면 삭제하고 view 문서의 `frame``null`로 둔다.
- Excalidraw visual source의 기본 후보 파일명은 `wire.excalidraw`다.
- `.excalidraw`를 만들거나 수정하면 주요 박스 text label 또는 `customData.region_id`에 region id를 넣는다.
- frame-view가 있으면 required region id는 view definition의 region id와 맞춘다.
- 정의에 없는 region이 frame-view에 필요하면 바로 확정하지 않고 open question 또는 USER_REVIEW로 분리한다.
4. **USER_REVIEW 처리**
- agent가 확정할 수 없는 화면 의도, region 추가/삭제, component 신규 생성 여부, page/drawer/split 선택은 `agent-ui/USER_REVIEW.md`에 남긴다.
- USER_REVIEW 항목에는 `Source Skill: update-agent-ui`, `Stage: definition-edit`, `Blocking Step`을 남긴다.
- 기존 USER_REVIEW 항목을 해결하는 변경이면 항목 상태를 갱신하고, 필요하면 `agent-ui/archive/user-review/user_review_N.log`로 이동한다.
- 해결 로그를 만들 때는 현재 변경과 직접 관련된 항목만 이동한다.
- `review-resolution`이 있으면 결정 내용을 관련 활성 definition/frame/component 문서에 먼저 반영한다.
- 해결된 항목은 `agent-ui/archive/user-review/user_review_N.log`로 이동하고, 활성 `USER_REVIEW.md`에는 미해결 항목만 남긴다. 남은 항목이 없으면 활성 `USER_REVIEW.md`를 제거할 수 있다.
- sync 실패 후 남은 작업트리 변경이 있고 사용자 결정과 충돌하지 않으면 보존한 채 후속 validate/sync에서 이어간다.
5. **후속 validate와 sync intent 판단**
- `post-validate=false`가 아니고 view/component/frame/wireframe/source evidence/status 중 하나라도 바뀌었으면 `validate-agent-ui`를 실행한다.
- `post-validate=true`이면 변경 크기와 무관하게 `validate-agent-ui`를 실행한다.
- `post-sync=true` 또는 코드 반영이 필요한 `계획` 상태 변경이 있으면 sync intent를 `validate-agent-ui`에 전달한다.
- `post-sync=false`이면 sync intent를 전달하지 않는다.
- 후속 단계가 실행되면 순서는 항상 `validate-agent-ui` 다음 `sync-agent-ui`다.
- 현재 변경 범위에 미해결 USER_REVIEW가 있으면 `sync-agent-ui`를 실행하지 않고 차단 항목을 보고한다.
- 사용자가 "화면정의서와 코드가 안 맞아"처럼 불일치를 보고하면 관련 항목을 `계획`으로 되돌릴지 확인하고 validate/sync intent를 만든다.
- sync intent를 만들더라도 코드 반영 방식이 direct-sync, plan-required, milestone-required 중 무엇인지는 판단하지 않는다.
6. **결과 보고**
- 수정한 활성 정의 문서
- 수정한 frame 문서와 visual source
- frontmatter schema 변경 여부
- archive log 변경 여부
- USER_REVIEW 생성/갱신 여부
- validate-agent-ui 실행 여부와 결과
- sync-agent-ui 필요 여부와 실행/보류 사유
- 남은 정합성 확인 항목
## 실행 결과 검증
- [ ] view/component는 folder-first + `index.md` 구조를 유지하는가
- [ ] 새로 만들거나 수정한 활성 Markdown 문서가 `ui_doc_type` frontmatter를 포함하는가
- [ ] 새로 만들거나 수정한 view/component에 `Source Evidence``Status`가 있는가
- [ ] 구현 근거 또는 sync 완료 없이 항목을 `구현됨`으로 표시하지 않았는가
- [ ] frame-view가 있으면 view region id와 frame region id가 충돌하지 않는가
- [ ] view에서 참조한 component id가 존재하거나 USER_REVIEW에 남았는가
- [ ] visual source가 있으면 대응 frame index에 기록되었는가
- [ ] visual source가 없는데 빈 frame-view 문서만 남아 있지 않은가
- [ ] 현재 기준이 archive에만 남지 않았는가
- [ ] 확정할 수 없는 UI 결정이 임의로 확정되지 않았는가
- [ ] 후속 단계가 필요할 때 `validate-agent-ui``sync-agent-ui`보다 먼저 실행되었는가
- [ ] USER_REVIEW 해결 요청이면 결정이 활성 문서에 반영되고 해결 로그가 archive 되었는가
- [ ] sync 실패 후 남은 작업트리를 임의로 버리지 않았는가
- 검증 실패 시: 자동 보정 가능한 것은 보완하고, 판단이 필요한 것은 `agent-ui/USER_REVIEW.md`에 남긴다.
## 출력 형식
```md
## 갱신 완료
- 수정 파일: <목록>
- view: <view-id 또는 없음>
- component: <component-id 또는 없음>
- frame source: <파일 또는 없음>
- evidence/status: <요약 또는 없음>
- frontmatter schema: <변경/유지/없음>
- archive 변경: <내용 또는 없음>
- USER_REVIEW: <생성/갱신/없음>
- USER_REVIEW resolution: <해결/부분 해결/없음>
- validate-agent-ui: <실행/PASS/WARN/FAIL/생략 사유>
- sync-agent-ui: <실행/보류/생략 사유>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- `definition/archive/**`를 현재 기준으로 사용하지 않는다.
- 코드나 문서 근거 없이 status를 확정하지 않는다.
- 문서 근거만 있는 항목을 구현 완료 상태로 쓰지 않는다.
- 사용자 판단이 필요한 UI 의도를 임의로 확정하지 않는다.
- view/component id를 명시적 요청 없이 바꾸지 않는다.
- `.excalidraw` 파일만 만들고 frame index를 생략하지 않는다.
- visual source 없이 빈 frame-view 문서를 만들지 않는다.
- agent-ui 갱신과 무관한 앱 구현 파일을 수정하지 않는다.
- 코드 구현 규모에 따라 plan 또는 roadmap/milestone 라우팅을 확정하지 않는다.
- `validate-agent-ui`를 거치지 않고 `sync-agent-ui`를 실행하지 않는다.
- sync 실패 후 남은 코드 변경을 사용자 결정 없이 되돌리지 않는다.

View file

@ -0,0 +1,111 @@
---
name: update-contract
version: 1.0.0
description: agent-contract inner/outer 계약 문서를 갱신하고 흩어진 계약 설명을 정리한다. 계약 업데이트해, 프로젝트 계약 업데이트해, 계약 갱신/수정/정리, contract update 요청에서 사용한다.
---
# update-contract
## 목적
기존 `agent-contract/`의 inner/outer 계약 문서를 최신 코드와 문서 기준으로 갱신한다.
계약 원문은 한 곳에 모으고, README/docs/rules에는 포인터와 경계 규칙만 남긴다.
## 언제 호출할지
- 사용자가 계약 업데이트, 프로젝트 계약 업데이트, 계약 갱신, 계약 수정, 계약 정리를 요청할 때
- API, runtime 호출, wire protocol, event/config schema 변경이 기존 계약에 영향을 줄 때
- 계약 설명이 README/docs/rules/code review 과정에서 다시 흩어진 것을 정리할 때
- legacy `provided/consumed` 계약을 `inner/outer` 모델로 점진 정리할 때
## 입력
- `contract-id`: 갱신할 계약 식별자 (선택, 없으면 index와 변경 diff에서 탐색)
- `change`: 바뀐 내용 또는 정리할 문제 요약 (선택, 없으면 최근 변경/요청 맥락에서 산출)
- `boundary`: `inner` 또는 `outer` (선택, 기존 문서 우선)
- `canonical-path`: 갱신 기준이 되는 proto/OpenAPI/config/code 원본 경로 (선택)
## 먼저 확인할 것
- [ ] `agent-contract/index.md` 존재 여부를 확인한다. 없으면 create-contract 흐름으로 전환할지 판단한다.
- [ ] index에서 대상 계약 문서를 찾는다. 없으면 새 계약 생성 대상인지 판단한다.
- [ ] 대상 계약 문서와 원본 경로를 읽는다.
- [ ] 변경 범위와 관련된 코드, proto, config, 테스트를 읽어 실제 동작을 확인한다.
- [ ] README/docs/rules에 계약 본문이 새로 중복 작성되었는지 검색한다.
- [ ] legacy `provided/consumed/` 구조가 남아 있으면 현재 요청이 구조 migration인지 단순 계약 갱신인지 구분한다.
## 실행 절차
1. **대상 확정**
- index의 `Outer Contracts`/`Inner Contracts`에서 계약을 찾는다.
- `contract-id`가 없으면 요청 키워드, 변경 파일, 코드 diff, README/docs/rules의 계약 설명을 기준으로 영향을 받는 계약을 좁힌다.
- legacy index만 있으면 `provided`는 outer 후보, 프로젝트 내부 runtime/wire 계약은 inner 후보로 분류하되 즉시 이동하지 말고 변경 범위와 함께 판단한다.
- 대상이 없고 요청이 계약 생성/정리까지 허용하면 create-contract 흐름으로 전환한다.
- 대상이 없고 사용자가 특정 기존 계약 갱신만 요청했다면 대상 부재를 보고한다.
2. **코드 우선 분석**
- 원본 경로를 먼저 확인한다.
- 실제 parser/handler/DTO/interface/test에서 필드 의미와 허용/거부 동작을 확인한다.
- 문서와 코드가 다르면 코드를 근거로 계약 문서를 갱신하고, 코드가 틀렸을 가능성이 있으면 사용자에게 후보를 제시한다.
3. **계약 문서 갱신**
- 필드 의미, 금지 사항, 읽는 조건, 변경 시 테스트를 최신 상태로 맞춘다.
- schema 원본 전체를 복제하지 않고 핵심 의미와 원본 경로를 유지한다.
- 불확실한 값은 단정하지 않고 `확인 필요`로 남긴다.
- `last updated` 같은 날짜 메타가 이미 있는 문서에서만 갱신한다. 없는 문서에 날짜 관례를 새로 만들지 않는다.
4. **index 갱신**
- 읽는 조건이 새 API/field/message/protocol 이름을 포함하는지 확인한다.
- path, 원본 경로, boundary가 실제 문서와 일치하는지 확인한다.
- 중복 id, dead path, 존재하지 않는 원본 경로를 제거하거나 수정한다.
- 프로젝트 전용 path trigger가 필요하면 `agent-contract/index.md` 또는 project/domain rule 포인터에 둔다. common rule에는 넣지 않는다.
5. **흩어진 문서 정리**
- README/docs/rules에 계약 본문이 들어간 경우 계약 문서 포인터로 축소한다.
- domain rule에는 책임 경계와 금지 사항만 남기고 상세 요청/응답 schema를 반복하지 않는다.
- 테스트 문서에는 검증 기준만 남기고 계약 본문을 복제하지 않는다.
- common rule에 특정 프로젝트 경로, 계약 id, API 이름이 새로 들어갔으면 제거하고 프로젝트 문서로 옮긴다.
6. **검증 판단**
- 계약 문서만 바꿨으면 링크/path/index 정합성을 확인한다.
- 원본 schema 또는 runtime 코드를 함께 바꿨으면 해당 domain/test rule의 검증 기준을 따른다.
- proto/config schema를 바꿨으면 생성물 갱신 명령과 관련 테스트를 실행한다.
7. **결과 보고**
- 수정한 계약 문서와 index
- 코드 분석 근거
- 중복 제거한 문서
- 실행한 검증
- 남은 확인 필요 항목
## 실행 결과 검증
- [ ] index가 대상 계약의 최신 path와 읽는 조건을 가리키는가
- [ ] 계약 문서의 원본 경로가 실제 코드/proto/config와 맞는가
- [ ] README/docs/rules에 같은 계약 본문이 중복 남아 있지 않은가
- [ ] inner/outer boundary가 계약의 실제 소비자와 맞는가
- [ ] 코드 분석 없이 문서만 추측해 갱신하지 않았는가
- [ ] 변경 범위에 필요한 테스트 또는 링크 검증을 실행했는가
- 검증 실패 시: index/path/원본 경로/중복 문서/테스트 누락을 보완한다.
## 출력 형식
```md
## 계약 업데이트 완료
- contract: agent-contract/<inner|outer>/<contract-name>.md
- index: agent-contract/index.md
- code evidence: <확인한 코드/proto/config/test>
- pointers: <갱신한 README/docs/rules 경로 또는 없음>
- verification: <실행한 명령 또는 생략 사유>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- 코드와 원본 경로를 확인하지 않고 계약 문서만 고치지 않는다.
- README/docs/rules에 계약 본문을 새로 복제하지 않는다.
- 프로젝트 전용 path trigger를 common rule에 넣지 않는다.
- 사용자 요청 없이 전체 계약 구조를 대량 migration하지 않는다.
- 한 패키지 내부 구현 세부를 inner 계약으로 승격하지 않는다.
- 계약 갱신과 무관한 리팩터링을 함께 수행하지 않는다.

View file

@ -0,0 +1,117 @@
---
name: update-domain-rule
version: 1.0.0
description: 기존 도메인 rules.md를 코드 현황에 맞게 갱신. 전체 스캔(full) 또는 지정 도메인(targeted) 두 모드 지원
---
# update-domain-rule
## 목적
프로젝트 코드가 변경되면서 기존 domain rule이 실제 구조와 어긋날 수 있다.
이 스킬은 실제 파일 구조를 탐색하여 기존 `rules.md`와 비교하고, 누락·오류·구식 항목을 수정한다.
갱신한 domain rule에는 어디까지의 코드 커밋을 검토 기준으로 삼았는지 기록한다.
## 언제 호출할지
- 대규모 리팩터링 또는 외부 패키지 내재화 후 domain rule 동기화가 필요할 때
- 특정 도메인 파일 구조가 바뀌어 기존 rule이 맞지 않을 때
- 사용자가 "도메인 업데이트", "domain rule 갱신", "domain 검토" 등을 요청할 때
- 로컬 모델의 자동 판단 런타임이 frontier 모델에게 domain rule 검토를 위임한 경우
- agent-ops 초기 scaffold 이후 코드가 많이 달라진 경우
## 입력
- `mode`: `full`(전체 도메인 스캔) | `targeted`(지정 도메인만) (필수)
- `domain-name`: 업데이트할 도메인 이름 — `targeted` 모드에서만 필수
## 먼저 확인할 것
- [ ] `agent-ops/rules/project/domain/` 하위 기존 도메인 목록 확인
- [ ] `agent-ops/rules/common/_templates/domain-rule-template.md` 읽어 최신 템플릿 형식 파악
- [ ] `targeted` 모드이면 `agent-ops/rules/project/domain/<domain-name>/rules.md` 존재 여부 확인
- 존재하지 않으면 `create-domain-rule` 스킬을 사용하도록 안내하고 중단
- [ ] `git rev-parse HEAD` 로 기준 커밋을 확인
- 이 값은 이번 domain rule 수정이 들어갈 미래 커밋 해시가 아니다
- 의미: "이 커밋까지의 코드 상태를 보고 domain rule을 검토했다"
- 코드 변경과 domain rule 변경이 같은 커밋에 섞여 있으면 다음 자동 판단에서 같은 코드 변경이 다시 후보로 잡힐 수 있으므로, 가능하면 코드 변경 커밋 이후 깨끗한 작업 트리에서 실행한다
## 실행 절차
1. **대상 목록 결정**
- `full`: `agent-ops/rules/project/domain/` 하위 모든 도메인 디렉터리를 대상으로 한다
- `targeted`: 지정된 `domain-name` 하나만 대상으로 한다
2. **도메인별 코드 탐색**
- 기존 `rules.md`**포함 경로** 목록을 기준으로 실제 파일 구조 탐색
- 포함 경로에 없지만 도메인 이름과 연관된 경로도 함께 탐색
- 탐색 시 실제로 존재하는 경로만 수집한다
3. **비교 및 변경 항목 식별**
다음 항목 각각을 현재 `rules.md`와 비교한다:
- **포함 경로**: 실제로 존재하지 않는 경로 제거, 새로 생긴 경로 추가
- **주요 구성 요소**: 파일/클래스 삭제·이름 변경·신규 추가 반영
- **유지할 패턴**: 코드에서 더 이상 사용되지 않는 패턴 제거, 새 패턴 추가
- **다른 도메인과의 경계**: 도메인 간 import 관계가 바뀐 경우 반영
- **목적/책임**: 도메인 책임이 실질적으로 변경된 경우에만 수정
4. **rules.md 업데이트**
- 변경이 필요한 항목만 수정한다 — 변경 불필요한 섹션은 그대로 둔다
- frontmatter가 없으면 `domain-rule-template.md` 형식으로 추가한다
- `last_rule_review_commit`에는 실행 초기에 확인한 `git rev-parse HEAD` 값을 기록한다
- `last_rule_updated_at`에는 갱신일을 `YYYY-MM-DD` 형식으로 기록한다
- 본문 섹션에 반영할 변경이 없더라도 검토가 완료되었다면 기준 커밋 메타데이터는 갱신한다
- 확인된 사실만 기재한다; 불확실하면 `<!-- TODO: 확인 필요 -->` 주석 처리
- `domain-rule-template.md`의 섹션 구조를 유지한다
5. **자동 판단 런타임 기준**
- 로컬 모델은 각 domain rule의 `last_rule_review_commit..HEAD` 범위를 기준으로 변경 커밋을 확인한다
- 판단 대상은 해당 도메인의 코드 경로이며, `agent-ops/rules/project/domain/**` 변경만으로는 다시 위임하지 않는다
- `last_rule_review_commit`이 없거나 유효하지 않으면 보수적으로 frontier 모델에게 위임한다
6. **도메인 매핑 테이블 검토** (`full` 모드 시)
- `agent-ops/rules/project/rules.md`의 도메인 매핑 테이블과 실제 포함 경로 비교
- 누락된 경로 패턴은 추가, 존재하지 않는 경로 패턴은 제거
- 기존 항목 순서는 변경하지 않는다
7. **결과 보고**
- 도메인별로 수정한 항목 목록
- `TODO`로 남긴 항목 (해당 시)
- 도메인 매핑 테이블 변경 내용 (full 모드 시)
## 실행 결과 검증
- [ ] 수정된 `rules.md`의 포함 경로가 모두 실제 프로젝트에 존재하는가
- [ ] 섹션 구조가 `domain-rule-template.md` 형식을 유지하는가
- [ ] `last_rule_review_commit`이 이번 갱신 직전 `HEAD`를 가리키는가
- [ ] 변경하지 않아도 되는 섹션이 의도치 않게 바뀌지 않았는가
- [ ] `full` 모드에서 도메인 매핑 테이블이 실제 포함 경로와 일치하는가
- 검증 실패 시: 실제 존재하지 않는 경로나 누락된 섹션을 사용자에게 알리고 해당 항목만 보완한다
## 출력 형식
```
## 업데이트 완료
### <domain-name>
- 변경: <수정된 항목 요약>
- 추가: <새로 추가된 경로/구성 요소>
- 제거: <삭제된 경로/구성 요소>
- 유지: 변경 없음 또는 기준 커밋 메타데이터만 갱신
- 기준 커밋: <last_rule_review_commit>
### 도메인 매핑 테이블 (full 모드 시)
- 추가: < 경로 패턴>
- 제거: <삭제된 경로 패턴>
## TODO 항목 (확인 필요)
- <불확실하여 직접 확인이 필요한 항목> (해당 시)
```
## 금지 사항
- 실제 존재하지 않는 경로를 포함 경로에 기재하지 않는다
- 추측으로 패턴·금지 사항을 추가하지 않는다 — 코드에서 확인된 내용만 기재한다
- 신규 도메인 생성이 필요한 경우 직접 생성하지 않고 `create-domain-rule` 스킬 사용을 안내한다
- `rules/project/rules.md`의 기존 항목을 삭제하거나 재정렬하지 않는다
- 코드 파일을 수정하지 않는다 — 이 스킬은 rule 파일 갱신만 담당한다

View file

@ -0,0 +1,533 @@
---
name: update-roadmap
version: 1.24.0
description: 로드맵 업데이트, 로드맵에 추가, 마일스톤 추가/갱신, phase/페이즈 변경, 전역 Milestone 실행 순서 갱신 요청에 사용한다. Roadmap-priority-queue-Phase-Milestone scaffold에서 target 없는 신규 작업의 규모를 판정하고 기존 Phase/Milestone/Epic/Task를 검색해 upsert한 뒤, 없을 때만 새 항목을 만들고 priority-queue.md 순서 동기화, 로컬 current.md 동기화, runtime m-task 완료 이벤트 반영, 완료 후보 검토중 전환, agent-ui 코드 동기화 Milestone의 종료 검토 시 구현됨 상태 반영, 완료 근거 충족 archive 이동, workspace 외부 의존 잠금 양방향 동기화를 처리한다.
---
# 로드맵 업데이트
## 목적
기존 `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를 가로지르는 실행 순서만 담당하며, Milestone 상세 정보는 복제하지 않는다.
Milestone은 구현 계획이 아니라 방향성, 범위, 위험, 확인 필요 사항을 기록하는 협업 문서로 유지한다.
Epic과 Task는 별도 파일로 분리하지 않고 Milestone 문서의 `기능` 안에서 관리한다. 별도 `완료 기준` 섹션은 만들지 않고, 검증이 필요한 기능에만 같은 Task 안의 `검증:` 문구로 통합한다.
## 언제 호출할지
- 사용자가 "로드맵 업데이트", "마일스톤 갱신", "phase 변경", "현재 활성 마일스톤 바꿔줘"라고 요청할 때
- 사용자가 "로드맵에 추가", "로드맵 작업 추가", "로드맵 기능 추가", "로드맵 Epic/Task 추가", "로드맵 에픽/태스크 추가", "마일스톤에 추가", "마일스톤 추가"처럼 로드맵에 새 내용을 넣어 달라고 요청할 때
- Milestone 완료, 보류, 폐기, 신규 추가가 필요할 때
- Phase 완료, 보류, 폐기, 신규 추가가 필요할 때
- 완료 또는 폐기된 Phase/Milestone을 archive로 이동해야 할 때
- 런타임이 `m-<milestone-slug>` task group의 PASS 완료 이벤트를 Milestone에 반영해야 할 때
- 특정 기능이나 작업을 새 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` / `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` 경로. `Roadmap Completion` 섹션이 있을 때만 Milestone 기능 Task 체크에 사용한다 (선택)
- `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 경로/제목 순서 목록. 사용자가 순서 조정을 명시한 경우에만 사용한다 (선택)
## 표준 구조
```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
```
- `ROADMAP.md`는 전체 목표와 Phase 흐름, `priority-queue.md` 고정 라우팅만 담는다.
- `priority-queue.md`는 Phase를 가로지르는 Milestone 실행 순서만 담는다. 항목은 Milestone 제목 링크와 식별용 한 줄 설명만 둔다.
- `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은 큐에서 제거한다.
## 상태와 id
- 상태 표기는 `[스케치]`, `[계획]`, `[진행중]`, `[검토중]`, `[완료]`, `[보류]`, `[폐기]` 중 하나만 사용한다.
- 기존 비표준 상태 표기는 갱신 범위에 포함될 때 표준 상태 표기로 정리한다.
- `[스케치]`는 방향성, 문제의식, 후보 범위, 미정 질문을 기록하는 컨셉 상태다. 구현 가능한 계획이 아니므로 `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] <이름>` 형식으로 작성한다.
- Task는 `- [ ] [item-id] 설명` 또는 `- [x] [item-id] 설명` 형식으로 작성한다.
- epic-id와 item-id는 공백 없는 짧은 ASCII 토큰이며, 해당 Milestone 안에서만 유일하면 된다.
- 사용자가 epic-id 또는 item-id를 언급하면 해당 항목을 우선 anchor로 삼고, 기존 id는 명시적 요청 없이 바꾸지 않는다.
## 로딩 원칙
- 일반 갱신은 로컬 `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 문서만 읽는다.
## 템플릿
- `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`, `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 문서 링크를 함께 붙인다.
## 구현 잠금
- `구현 잠금`은 승인 절차가 아니라 에이전트가 확정할 수 없는 결정이 필요한지 표시하는 얇은 상태다.
- 제품 방향, 범위, 우선순위, 책임 경계처럼 에이전트가 확정할 수 없는 항목이 남아 있으면 `잠금`으로 두고 `결정 필요` 목록에 남긴다.
- 기존 구조, 도메인 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은 `구현 잠금``해제`로 보이더라도 구현 계획과 코드 구현 대상이 아니다. 먼저 승격 조건을 충족해 `[계획]`으로 전환한다.
## 프로젝트 간 잠금
- 프로젝트 상위 `.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` 호출로 처리한다.
## 완료 리뷰와 검토중 상태
- 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한다.
### agent-ui 코드 동기화 Milestone 완료 리뷰
- 이 절은 `sync-agent-ui`가 코드 작업을 `milestone-required`로 라우팅했거나 사용자가 명시해 Milestone `완료 리뷰``agent-ui 상태 반영: 대기`가 있는 경우에만 적용한다.
- agent-ui 문서만 갱신한 Milestone, 작은 `direct-sync` 작업, 일반 `plan-required` 작업, `agent-ui 상태 반영: 해당 없음`인 Milestone에는 적용하지 않는다.
- 기존 Milestone에 `agent-ui 상태 반영` 항목이 없으면 `해당 없음`으로 취급한다. 문서 구조 보정 또는 해당 Milestone 갱신 범위에 포함될 때만 `agent-ui 상태 반영: 해당 없음`을 보강한다.
- 사용자가 "이 Milestone을 종료해도 될지 검토", "마일스톤 완료 검토", "종료 검토"처럼 완료 리뷰를 요청했거나 `review-state=통과`로 갱신할 때 적용한다.
- agent-ui 코드 동기화 Milestone이 완료 리뷰 `통과` 조건을 충족하면 `[완료]` 전환 또는 archive 전에 관련 agent-ui view/component/frame 문서의 `status``구현됨`으로 반영할 수 있다.
- 상태 반영은 완료 evidence가 직접 가리키는 agent-ui 활성 문서에만 적용한다. Milestone 전체 완료만을 근거로 `agent-ui/definition/**` 전체를 일괄 `구현됨`으로 바꾸지 않는다.
- 각 대상 문서는 실제 존재하는 code evidence path와 최종 검증 근거가 있어야 `구현됨`으로 바꾼다. 근거가 없으면 `계획` 또는 기존 상태를 유지하고 완료 리뷰를 `보완 필요`로 둔다.
- agent-ui 상태 반영은 `update-agent-ui`의 문서 갱신 규칙을 따르고, 반영 후 `validate-agent-ui`로 정합성을 확인한다. 이 단계는 이미 완료된 코드 반영의 문서 상태 갱신이므로 `sync-agent-ui`를 새로 실행하지 않는다.
- status/code evidence 반영과 `validate-agent-ui`가 모두 통과하면 Milestone `완료 리뷰``agent-ui 상태 반영``완료`로 바꾼다.
- 근거 부족, 미해결 USER_REVIEW, 또는 `validate-agent-ui` 실패로 반영하지 못하면 Milestone `완료 리뷰``agent-ui 상태 반영``차단: <사유>`로 바꾸고 `상태: 보완 필요`를 남긴다.
- `validate-agent-ui`가 FAIL이거나 현재 범위에 미해결 `agent-ui/USER_REVIEW.md`가 있으면 Milestone을 `[완료]`로 전환하지 않고 완료 리뷰를 `보완 필요`로 둔다.
- `agent-ui 상태 반영: 대기`가 아닌 Milestone에서는 완료 리뷰 중 agent-ui status를 변경하지 않는다.
## 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 불명확으로 보고한다.
- target이 확정되어도 `complete-log` 입력이 없거나 해당 파일에 `Roadmap Completion` 섹션이 없으면 Milestone 기능 Task를 체크하지 않고 no-op으로 보고한다. 일반 `m-*` 완료 이벤트만으로 Task를 추정해 체크하지 않는다.
- `Roadmap Completion` 섹션이 있으면 Milestone 경로가 target과 일치하는지, Completed task ids의 각 id가 해당 Milestone의 기존 기능 Task id 하나와 정확히 일치하는지 확인한다. 하나라도 일치하지 않으면 수정하지 말고 target 불일치로 보고한다.
- target Milestone이 `SDD: 필요`이면 런타임 완료 이벤트의 `complete-log`에 있는 `Roadmap Completion`과 최종 검증 evidence가 SDD `Evidence Map`을 충족해야 한다. 사용자가 `update-roadmap` 요청에 별도 evidence를 명시해 수동 반영을 요구한 경우에만 Evidence Map 충족 근거를 보조 근거로 사용할 수 있다. 근거가 없으면 `Roadmap Completion`이 있어도 Task를 체크하지 않고 SDD evidence 부족으로 보고한다.
- 일치하면 PASS evidence, `complete.log`, final archive path, archived plan/review log 경로, code-review 결과 요약을 근거로 `Roadmap Completion`에 적힌 기능 Task만 `[x]`로 갱신한다. target routing 자체는 완료 이벤트의 `m-<milestone-slug>` task group과 `complete.log``Roadmap Completion` 섹션으로 결정한다.
- 갱신 후 모든 기능 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` 중 가장 작은 충분한 단위를 고른다.
- 요청이 방향성, 문제의식, 컨셉, 운영 원칙 수준이고 기능 Task나 실행 범위가 아직 부족하면 새 항목의 상태는 `[스케치]`로 둔다.
- `[스케치]` Phase/Milestone을 만들 때는 `승격 조건``[계획]`으로 전환하기 위해 필요한 정의, 결정, 경계, 후속 구현 Milestone 후보를 체크리스트로 남긴다.
- 가장 작은 충분한 단위 원칙을 따른다. 애매하면 새 Phase나 새 Milestone으로 키우지 말고, 기존 Milestone의 Epic/Task에 넣을 수 있는지 먼저 확인한다.
- 위치 지정이 있으면 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의 활성 경로 항목을 제거한다. 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`를 전달하면 파일을 읽고 `Roadmap Completion` 섹션 유무와 Completed task ids를 확인한다. 섹션이 없으면 Milestone 기능 Task 체크는 no-op이다. SDD 대상 Milestone이면 SDD `Evidence Map` 충족 여부도 확인한다.
- 구조 전환, 템플릿 보정, current 동기화는 `sync`로 본다.
- `priority-queue.md` 생성, 순서 조정, 깨진 링크 복구, archive/폐기/경로 변경/split/merge 후 큐 정리는 `sync` 또는 `replan`으로 본다.
- 완료/폐기 근거가 충족된 이동은 `archive`로 본다.
- 완료 리뷰 요청에서 대상 Milestone의 `완료 리뷰``agent-ui 상태 반영: 대기`인지 확인한다. 항목이 없거나 `대기`가 아니면 agent-ui 상태 반영 단계를 적용하지 않는다.
- 새 기능 배치, 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`를 수정할 때는 Milestone 제목 링크와 식별용 한 줄 설명만 남기고, 상태, 목표, 범위, 잠금, 기능, 완료 근거, 의존성 필드를 복제하지 않는다.
- 로컬 `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 아래 `- [ ] [item-id] 설명`으로 만든다. 검증이 필요한 경우에만 같은 항목에 `검증: <명령/확인 방법/기대 결과>`를 붙인다.
- 새 항목은 레벨별 탐색에서 적절한 기존 후보가 없을 때만 만든다.
- 완료 체크는 evidence가 있을 때만 `[x]`로 바꾼다.
- 모든 기능 Task와 Task 안에 명시된 검증이 evidence와 함께 `[x]`이어도 `구현 잠금``해제`가 아니거나 미완료 `결정 필요` 항목이 있으면 Milestone 상태를 `[검토중]`으로 바꾸지 않는다. `완료 리뷰` 또는 `작업 컨텍스트`에 잠금 차단 항목을 남긴다.
- 모든 기능 Task와 Task 안에 명시된 검증이 evidence와 함께 `[x]`이고 `구현 잠금`도 해제되어 있으면 Milestone 상태를 `[검토중]`으로 바꾸고 `완료 리뷰`에 완료 근거와 남은 차단 항목을 남긴다.
- `[검토중]` 전환만으로 archive 이동, 로컬 `current.md` 제거, archive 링크 변경을 수행하지 않는다.
- `agent-ui 상태 반영: 대기`인 Milestone의 완료 리뷰가 `통과` 후보이면 `[완료]` 전환 전에 관련 agent-ui 문서의 `status``구현됨`으로 갱신할 수 있는지 확인한다. 대상 문서, code evidence, 최종 검증 근거, `validate-agent-ui` 결과가 모두 충족될 때만 반영하고 `agent-ui 상태 반영: 완료`로 바꾼다.
- agent-ui 상태 반영이 필요한데 근거가 부족하거나 `validate-agent-ui`가 통과하지 않으면 Milestone 상태를 `[진행중]` 또는 `[검토중]`으로 유지하고 `완료 리뷰: 보완 필요``agent-ui 상태 반영: 차단: <사유>`를 남긴다.
- 기능 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 파일을 가리키는지 확인한다.
- `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에는 `완료 리뷰` 섹션과 완료 근거/남은 차단 항목이 있는지 확인한다.
- `agent-ui 상태 반영: 대기`인 Milestone을 `[완료]`로 전환하는 경우, 완료 evidence가 가리키는 agent-ui 문서의 status/code evidence 반영 여부와 `validate-agent-ui` 결과가 완료 리뷰에 남았는지 확인한다.
- `agent-ui 상태 반영: 대기`가 아닌 Milestone 완료 리뷰에서 agent-ui 문서 status를 변경하지 않았는지 확인한다.
- 각 Milestone의 `구현 잠금`에 SDD 필요 여부와 사유가 있는지 확인한다.
- `SDD: 필요` Milestone은 SDD 문서 링크, SDD 파일 존재, 잠금 해제 조건, SDD 사용자 리뷰 상태가 일관되는지 확인한다. 사용자가 명시적으로 SDD 생성을 뒤로 미루지 않았는데 SDD 파일이 없으면 검증 실패로 본다.
- Epic heading과 Task id 형식이 맞는지 확인한다.
- 요청 규모가 판정되었고 결과 보고에 남았는지 확인한다.
- 동일/유사 기존 항목을 검색했고 신규/업데이트 판정이 결과 보고에 남았는지 확인한다.
- 자동 배치한 신규 작업이면 선택한 후보와 밀린 후보의 근거가 결과 보고에 포함되는지 확인한다.
- `.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 활성 창 변경 사항
- 완료 리뷰 상태와 남은 차단 항목
- `agent-ui 상태 반영: 대기`인 Milestone이면 agent-ui status 반영 여부와 validate-agent-ui 결과
- SDD gate 상태와 사용자 리뷰 필요 여부
- 런타임 완료 이벤트의 `origin-task``m-<milestone-slug>`이면 원래 active task 경로와 매칭된 target Milestone, `Roadmap Completion` Task ids 또는 no-op 사유
- archive 모드이면 이동 경로와 남긴 링크
- 확인 필요로 남긴 항목
## 출력 형식
```markdown
## 업데이트 완료
- 모드: <status | milestone | phase | replan | sync | concretize | archive>
- 수정 파일:
- [ROADMAP.md](agent-roadmap/ROADMAP.md)
- [priority-queue.md](agent-roadmap/priority-queue.md)
- [current.md](agent-roadmap/current.md) (local)
- [PHASE.md](agent-roadmap/phase/<phase-slug>/PHASE.md)
- [<milestone-slug>.md](agent-roadmap/phase/<phase-slug>/milestones/<milestone-slug>.md)
- [SDD.md](agent-roadmap/sdd/<phase-slug>/<milestone-slug>/SDD.md) (SDD 작성/갱신 시)
- [USER_REVIEW.md](agent-roadmap/sdd/<phase-slug>/<milestone-slug>/USER_REVIEW.md) (SDD 사용자 리뷰 요청 시)
- [archive PHASE.md](agent-roadmap/archive/phase/<phase-slug>/PHASE.md) 또는 [archive Milestone](agent-roadmap/archive/phase/<phase-slug>/milestones/<milestone-slug>.md) (archive 모드)
- [archive SDD.md](agent-roadmap/archive/sdd/<phase-slug>/<milestone-slug>/SDD.md) (SDD archive 시)
## 변경 사항
- 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: <불필요 | 필요-작성 | 필요-잠금 | 필요-사용자 리뷰 | 필요-승인됨 | 변경 없음>
- 승격 조건: <해당 없음 | 추가/수정/미충족 유지/충족 요약>
- 완료 리뷰: <변경 없음 | 검토중 | 통과 | 보완 필요 | 보류 | 폐기>
- agent-ui 상태 반영: <해당 없음 | 대기 | 완료 | 차단: 사유 | 변경 없음>
- runtime m-task 라우팅: <해당 없음 | origin-task -> 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`에 상태, 목표, 범위, 잠금, 기능, 완료 근거, 의존성 필드를 복제하지 않는다.
- `priority-queue.md`에 archive 경로를 남기지 않는다.
- 사용자 순서 조정 요청 없이 `priority-queue.md`의 순서를 에이전트 판단만으로 바꾸지 않는다. 단, archive/폐기 제거, 경로 변경, split/merge, 실행 의미 변경, 깨진 링크 복구는 예외다.
- 로컬 `current.md`에 개인별 현재 작업 위치나 완료 상태를 남기지 않는다.
- 로컬 `current.md``agent-roadmap/archive/**` 경로를 남기지 않는다.
- `agent-roadmap/current.md`를 git 추적 대상으로 만들지 않는다.
- archive 문서를 명시 요청 없이 읽거나 최신 템플릿으로 재포맷하지 않는다.
- 완료된 Phase/Milestone 기록을 삭제하지 않는다.
- Epic과 Task를 별도 파일로 분리하지 않는다.
- Phase와 Milestone 이름 또는 파일명에 순번을 강제하지 않는다.
- 에이전트가 확정할 수 없는 결정 항목이 남아 있는데 Milestone의 `구현 잠금``해제`로 바꾸지 않는다.
- `구현 잠금`이 남아 있는 Milestone을 `[검토중]`, `[완료]`, 또는 완료 archive 대상으로 전환하지 않는다. 명시적인 폐기 근거가 있는 `[폐기]` archive는 허용한다.
- `agent-ui 상태 반영: 대기`가 아닌 Milestone 완료 리뷰에서 agent-ui 문서 status를 변경하지 않는다.
- `agent-ui 상태 반영: 대기`인 Milestone이라도 최종 검증과 실제 code evidence 없이 agent-ui status를 `구현됨`으로 바꾸지 않는다.
- 사용자가 지정한 Phase/Milestone/Epic/Task anchor를 무시하지 않는다.
- 사용자가 명시하지 않은 기존 epic-id나 item-id를 바꾸지 않는다.
- `rely-on.status=enable`만으로 다른 프로젝트 Milestone의 `구현 잠금`을 직접 해제하지 않는다.

View file

@ -0,0 +1,124 @@
---
name: update-spec
version: 1.0.0
description: agent-spec 갱신, 구현 스펙 업데이트, 완료 기능 스펙 반영, 코드/계약/테스트 변경 후 living spec 동기화 요청에 사용한다. agent-spec/index.md에서 관련 spec을 찾아 현재 코드와 계약 기준으로 갱신하고 Spec updated, Spec update not needed, create-spec needed, Spec blocked 결과를 남긴다.
---
# update-spec
## 목적
기존 agent-spec 문서를 현재 코드, 계약, 테스트, 완료 evidence에 맞게 갱신한다.
이 스킬은 spec 문서만 책임지며 roadmap 상태 전환, Milestone archive, 코드 구현 계획 생성을 수행하지 않는다.
## 언제 호출할지
- 사용자가 "스펙 업데이트", "구현 스펙 갱신", "완료 기능 스펙 반영", "agent-spec 갱신"을 요청할 때
- 코드, 계약, config, event, runtime flow, 테스트가 바뀌어 현재 구현 spec이 달라질 수 있을 때
- `complete-milestone`이 Milestone 종료 전에 spec sync gate를 수행할 때
- `create-spec` 이후 불명확/부분 상태의 spec을 추가 evidence로 보강할 때
## 입력
- `target-spec`: 갱신할 spec id 또는 문서 경로. 없으면 index와 변경 근거에서 추론한다. (선택)
- `target-milestone`: spec 갱신 근거가 되는 Milestone 경로, 이름, slug. (선택)
- `changed-files`: spec 영향 판단에 사용할 코드/계약/테스트 파일 목록. (선택)
- `complete-log`: 완료 근거로 사용할 `complete.log` 경로. (선택)
- `mode`: `update` 또는 `check-only`. 기본값은 `update`다. (선택)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules-agent-spec.md`를 읽는다.
- [ ] `agent-spec/index.md`가 있는지 확인한다. 없으면 `create-spec` 필요 또는 `skipped-no-agent-spec`으로 보고한다.
- [ ] 매칭 spec 문서만 읽는다.
- [ ] 계약에 닿는 변경이면 `agent-contract/index.md`를 읽고 매칭 계약 문서만 읽는다.
- [ ] Milestone 또는 complete.log 근거가 있으면 해당 활성 Milestone, SDD gate, complete.log의 관련 섹션만 확인한다.
## 실행 절차
1. **대상 spec 확정**
- `target-spec`이 있으면 해당 문서가 활성 `agent-spec/**` 아래에 정확히 존재하는지 확인한다.
- `target-spec`이 없으면 `agent-spec/index.md`의 읽는 조건, spec id, path, evidence와 `changed-files`/Milestone/complete.log를 비교한다.
- 매칭 spec이 없고 구현 스펙 영향이 명확하면 `create-spec` 필요로 보고한다. 이 스킬에서 새 spec 문서를 직접 만들지 않는다.
- 매칭 spec이 없고 변경이 spec 대상이 아니면 `Spec update not needed`로 보고한다.
- 둘 이상의 spec이 매칭되면 모두 갱신 대상 후보로 두되, 각 spec별 영향 근거를 분리한다.
2. **현재 구현 재확인**
- spec 본문만 믿지 말고 관련 코드, 계약, 테스트, 설정 예시를 다시 확인한다.
- complete.log와 roadmap은 변경 근거로 쓰되 현재 동작은 코드/계약으로 검증한다.
- SDD가 있으면 acceptance/evidence가 현재 spec과 어긋나는지 확인한다.
- spec과 코드/계약이 충돌하면 코드/계약을 우선하고 spec을 수정한다.
3. **영향 판정**
- 기능 목록, 범위, 주요 흐름, 계약 링크, 설정/데이터/이벤트, 검증, 한계 중 바뀐 항목을 식별한다.
- 기능 이해에 필요한 최소 책임 설명이 바뀐 경우만 spec에 반영한다.
- 코드 배치, 구현 진입점, 유지할 패턴, 금지 사항 변경은 domain rule 갱신 대상으로 본다.
- 변경이 테스트 fixture, 내부 리팩터링, 문구 정리처럼 현재 구현 spec에 영향을 주지 않으면 `Spec update not needed: <사유>`를 남긴다.
- 판단 불가이면 spec을 추정 갱신하지 않고 `Spec blocked: <필요 evidence>`로 보고한다.
4. **문서 갱신**
- `mode=check-only`이면 쓰지 않고 갱신 후보만 보고한다.
- 영향이 있는 spec 문서만 수정한다.
- frontmatter `status``source_evidence`를 현재 evidence에 맞게 보강한다.
- `rules-agent-spec.md`의 기본 섹션 기준을 따른다.
- 기능 목록은 `기능``설명` 중심으로 유지한다. 기능별 `상태` 칼럼은 기본 추가하지 않는다.
- `주요 흐름`은 긴 텍스트보다 Mermaid `sequenceDiagram` 또는 `flowchart`를 우선 고려한다.
- `코드 진입점` 섹션은 추가하지 않는다. 기존 spec에 있으면 현재 기준에 맞춰 제거하거나 `source_evidence`로 옮긴다.
- 계약 원문을 복제하지 않고 링크만 보강한다.
- 변경 기록에 날짜, 변경 근거, 관련 Milestone/complete.log/코드 경로를 남긴다.
5. **index 동기화**
- spec 상태, 읽는 조건, path, 주요 근거가 바뀌었으면 `agent-spec/index.md`의 Spec Map을 갱신한다.
- 새 spec 문서가 필요하면 `create-spec` 대상으로 보고하고 index를 추정 갱신하지 않는다.
- 폐기된 spec은 활성 문서에 남기지 않고 archive log로 이동할 후보로 보고한다. 명시 요청 없이 archive 이동하지 않는다.
6. **결과 분류**
- 갱신한 문서가 있으면 `Spec updated`로 보고한다.
- 영향 없음이 확인되면 `Spec update not needed: <사유>`로 보고한다.
- 매칭 spec이 없고 신규 작성이 필요하면 `create-spec needed: <사유>`로 보고한다.
- evidence 부족, 대상 모호, 사용자 결정 필요이면 `Spec blocked: <사유>`로 보고한다.
## 실행 결과 검증
- [ ] `agent-spec/index.md`에서 관련 spec만 읽었는가
- [ ] 코드/계약/테스트 기준으로 현재 동작을 재확인했는가
- [ ] spec 문서의 기본 섹션 기준과 frontmatter가 유지되는가
- [ ] 기능 목록이 기능/설명 중심이며 불필요한 상태 칼럼이나 과한 상세 설명을 만들지 않았는가
- [ ] 코드 진입점, 패키지 배치, 도메인별 금지 사항을 spec 본문에 반복하지 않았는가
- [ ] index의 Spec Map이 갱신한 spec 상태와 일치하는가
- [ ] 계약 원문을 복제하지 않았는가
- [ ] 갱신/불필요/create 필요/차단 중 하나의 결과가 명확한가
- [ ] `complete-milestone`에서 호출된 경우 Milestone 완료 리뷰에 남길 spec sync 문구를 제공했는가
- [ ] `git diff --check`를 실행했는가
- 검증 실패 시: roadmap이나 코드 파일을 수정하지 말고 spec 갱신 실패 사유를 보고한다.
## 출력 형식
```markdown
## Spec 동기화 결과
- 결과: <Spec updated | Spec update not needed | create-spec needed | Spec blocked | skipped-no-agent-spec>
- 대상 spec:
- <없음 | [spec-id](agent-spec/<area>/<spec-id>.md)>
- 수정 파일:
- <없음 | [index.md](agent-spec/index.md) | [spec](agent-spec/<area>/<spec-id>.md)>
- 근거:
- <코드/계약/테스트/complete.log/Milestone 요약>
- Milestone 완료 리뷰 문구:
- `Spec sync: <완료 | 해당 없음 | create-spec 필요: 사유 | 차단: 사유>`
## TODO 항목
- <남은 확인 필요 또는 없음>
```
## 금지 사항
- roadmap 상태 전환이나 archive 이동을 수행하지 않는다.
- 새 spec 문서를 생성하지 않는다. 신규 작성이 필요하면 `create-spec`으로 넘긴다.
- 코드 구현이나 테스트 코드를 수정하지 않는다.
- spec과 코드가 충돌할 때 spec을 그대로 신뢰하지 않는다.
- 매칭되지 않는 spec을 광범위하게 읽거나 전부 갱신하지 않는다.
- archive spec을 명시 요청 없이 읽거나 갱신하지 않는다.
- complete.log나 roadmap 문구만으로 현재 동작을 단정하지 않는다.
- 코드 진입점, 구현 배치, 도메인 간 상세 책임 경계, 유지할 패턴, 금지 사항을 domain rule 대신 agent-spec에 길게 쓰지 않는다.

View file

@ -0,0 +1,99 @@
---
name: update-test
version: 1.1.0
description: 기존 agent-test 환경 rules.md 또는 도메인/검증 시나리오별 테스트 rule 문서를 수정하는 스킬
---
# update-test
## 목적
기존 `agent-test/<env>/rules.md` 또는 `agent-test/<env>/<test-profile>.md`를 최신 테스트 기준에 맞게 갱신한다.
라우팅은 3홉 안에 유지하고, 도메인/검증 시나리오별 문서는 자체 완결되게 보완한다.
`test-case`는 기존 호출과의 호환을 위한 alias이며, 새 문서 기준 이름은 `test-profile`이다.
## 언제 호출할지
- 기존 테스트 환경 규칙을 수정할 때
- 도메인/검증 시나리오별 테스트 기준, 명령, 판정 기준을 보완할 때
- 테스트 라우팅을 추가, 제거, 정리할 때
## 입력
- `env`: `local`, `dev`, `qa`, `prod` 중 하나 (필수)
- `test-profile`: 수정할 도메인/검증 시나리오별 테스트 문서 이름, kebab-case (선택)
- `test-case`: `test-profile`의 호환 alias (선택)
- `domain`: 대상 도메인 이름, kebab-case (선택)
- `change`: 수정할 내용 요약 (필수)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules.md`의 스킬 규칙과 테스트 규칙이 분리되어 있는지 확인한다.
- [ ] `agent-ops/skills/common/router.md``update-test` 라우팅이 있는지 확인한다.
- [ ] `test-case`가 있고 `test-profile`이 없으면 `test-profile`로 취급한다.
- [ ] `agent-test/<env>/rules.md` 존재 여부를 확인하고, 없으면 `create-test` 대상으로 보고 중단한다.
- [ ] `agent-test/<env>/rules.md`가 있으면 읽는다.
- [ ] `test-profile`이 있으면 `agent-test/<env>/<test-profile>.md` 존재 여부를 확인하고, 없으면 `create-test` 대상으로 보고 중단한다.
- [ ] `test-profile` 문서가 있으면 읽는다.
- [ ] `test-profile`이 없고 `domain` 또는 `change`가 특정 도메인/검증 시나리오를 가리키면 env rules의 라우팅에서 대상 문서를 찾는다.
- [ ] 템플릿 구조 확인이 필요하면 `agent-ops/rules/common/_templates/`의 테스트 템플릿을 읽는다.
- [ ] 기존 라우팅이 3홉 안에 있는지 확인한다.
## 실행 절차
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. **결과 보고**
- 수정한 파일
- 바꾼 라우팅
- 보존한 환경값
- 남은 확인 필요 항목
## 실행 결과 검증
- [ ] 수정 대상 문서가 여전히 필수 섹션을 포함하는가
- [ ] `rules.md` -> `router.md` -> `update-test/SKILL.md` 경로가 끊기지 않는가
- [ ] env rules 라우팅이 3홉 제한을 넘기지 않는가
- [ ] 도메인/검증 시나리오별 문서가 다른 테스트 문서로 라우팅하지 않는가
- [ ] local 수정 시 `.gitignore`에 local 경로가 반영되었는가
- [ ] secret, token, 개인 endpoint 원문이 tracked 파일에 추가되지 않았는가
- 검증 실패 시: 문제 문서만 다시 보완한다.
## 출력 형식
```md
## 수정 완료
- 환경: <env>
- 수정 파일: <path>
- 라우팅 변경: <내용 또는 없음>
- 보존한 환경값: <요약>
- 확인 필요: <항목 또는 없음>
```
## 금지 사항
- 기존 local 환경값을 추측으로 바꾸지 않는다.
- 확인되지 않은 테스트 명령을 필수 검증으로 단정하지 않는다.
- 도메인/검증 시나리오별 문서를 router처럼 쓰지 않는다.
- secret, token, 개인 endpoint 원문을 tracked 파일에 기록하지 않는다.

View file

@ -0,0 +1,189 @@
---
name: validate-agent-ui
version: 1.1.0
description: agent-ui scaffold, definition/frame/component/wireframe/source evidence/status 정합성을 맞추고 필요한 USER_REVIEW와 code sync intent를 분리하는 스킬
---
# validate-agent-ui
## 목적
`agent-ui/` 구조와 문서 그래프 정합성을 검사하고 자동 보정한다.
definition, component, frame, visual source, USER_REVIEW, archive가 서로 뒤처진 상태를 같은 수준으로 맞추며, UI 의도 판단이 필요한 문제는 `agent-ui/USER_REVIEW.md`에 남긴다.
## 언제 호출할지
- agent-ui 구조 검증, UI 정의 정합성 확인, wireframe 정합성 확인을 요청할 때
- view/component/frame 문서가 서로 어긋났는지 확인할 때
- view/component의 Source Evidence와 Status가 근거와 맞는지 확인할 때
- Excalidraw visual source와 frame index 연결을 검사할 때
- agent-ui 갱신 후 자동 보정과 사용자 리뷰 분리가 필요할 때
- 수동 호출에서 정합성 통과 후 code sync가 필요한지 판단할 때
- 사용자가 "화면정의서와 코드가 안 맞아"처럼 UI 정의와 코드 결과물의 불일치를 보고할 때
## 입력
- `scope`: `all`, `internal`, `implementation`, `view:<view-id>`, `component:<component-id>`, `frame:<view-id>` 중 하나. 기본값은 `all` (선택)
- `repair`: `true` 또는 `false`. 기본값은 `true` (선택)
- `sync-intent`: `auto`, `required`, `skip`, `inherited` 중 하나. 기본값은 수동 호출에서 `auto`, `update-agent-ui` 후속 호출에서 `inherited` (선택)
- `sync-mode`: `incremental` 또는 `full`. 기본값은 `incremental` (선택)
## 먼저 확인할 것
- [ ] `agent-ops/rules/common/rules-agent-ui.md`를 읽는다.
- [ ] `agent-ui/` 존재 여부를 확인한다. 없으면 `create-agent-ui` 대상이라고 보고하고 중단한다.
- [ ] `agent-ui/definition/index.md`, `definition/views/index.md`, `definition/components/index.md`, `frame/index.md` 존재 여부를 확인한다.
- [ ] scope에 해당하는 활성 definition/frame 문서만 읽는다.
- [ ] `scope=view:<view-id>` 또는 `scope=component:<component-id>`이면 해당 문서의 Source Evidence code path를 확인한다.
- [ ] `scope=all`, `scope=implementation` 또는 sync intent가 있으면 Source Evidence의 code path와 UI 구현 후보 파일을 확인한다.
- [ ] `agent-ui/.sync-state.json`이 있으면 읽고, 없으면 sync 기준 없음으로 보고한다.
- [ ] archive는 경로와 tree 대응만 확인하고, 사용자가 과거 내용 확인을 요청하지 않았으면 본문을 읽지 않는다.
- [ ] 필요한 템플릿만 `agent-ops/skills/common/_templates/agent-ui/`에서 읽는다.
## 실행 절차
1. **인벤토리 작성**
- `definition/views/**/index.md`에서 view 목록을 만든다.
- `definition/components/**/index.md`에서 component 목록을 만든다.
- `frame/views/**/index.md`에서 frame 목록을 만든다. frame이 없는 view는 visual source가 없는 정상 상태로 본다.
- 활성 Markdown 문서의 frontmatter에서 `ui_doc_type`, id, status, source_evidence, regions를 수집한다.
- 같은 레벨의 `<name>.md``<name>/` 혼재 여부를 확인한다.
2. **구조 검증과 자동 보정**
- 필수 루트 문서가 없고 `repair=true`이면 템플릿으로 생성한다.
- view/component 디렉터리에 `index.md`가 없고 의도가 명확하면 템플릿으로 생성한다.
- frame 디렉터리는 visual source가 있을 때만 `index.md` 생성 대상으로 삼는다.
- `.excalidraw` 파일이 하나 있고 frame index의 visual source가 비어 있으면 해당 파일을 등록한다.
- archive/user-review 디렉터리가 없고 필요하면 생성한다.
- `<name>.md``<name>/`가 모두 있고 둘 다 의미 있는 내용이면 자동 병합하지 않고 USER_REVIEW로 남긴다.
3. **definition 정합성 검사**
- 활성 Markdown 문서에 `ui_doc_type` frontmatter가 있는지 확인한다.
- `ui_doc_type`이 경로와 맞는지 확인한다. 예: `definition/views/<view-id>/index.md``view`다.
- view/component/frame id가 경로 id와 일치하는지 확인한다.
- view/component 문서에 `Source Evidence``Status`가 있는지 확인한다.
- frontmatter `source_evidence`는 list이고 각 항목은 `type`, `path`, `notes`를 가져야 한다.
- `source_evidence.type``code`, `docs`, `user` 중 하나여야 한다.
- 근거 파일이 없으면 `path: null`이어야 하며, placeholder 문자열을 근거로 보지 않는다.
- frontmatter의 `status`, `source_evidence`, `regions`와 본문 `Status`, `Source Evidence`, `Regions`가 충돌하는지 확인한다.
- `Status``구현됨`, `계획`, `가정`, `불명확` 중 하나여야 한다.
- `구현됨` 항목은 코드 반영 완료 상태여야 한다. 코드 근거가 있으면 실제 존재하는 code evidence path를 가져야 한다.
- `구현됨`의 code evidence 경로가 명시되어 있고 실제 존재하지 않으면 `repair=true`일 때 `계획`으로 낮추고 USER_REVIEW를 남길 수 있다.
- `가정`, `불명확` 항목이 코드 동기화 가능한 정의처럼 설명되면 자동 의미 변경하지 않고 USER_REVIEW로 남긴다.
- region id가 `<view-id>.<region>` 또는 `<view-id>.<region>.<subregion>` 형식인지 확인한다.
- view 문서에서 참조한 component id가 component 목록에 있는지 확인한다.
- 없는 component가 단순 누락이고 생성 의도가 명확하면 `repair=true`일 때 component skeleton을 만들고 `Status``Source Evidence`를 채운다.
- 새 component로 만들지 기존 component로 바꿀지 판단이 필요하면 USER_REVIEW로 남긴다.
4. **frame 정합성 검사**
- view가 있는데 대응 frame index가 없어도 visual source가 없으면 정상으로 본다.
- visual source 파일이 있는데 대응 frame index가 없으면 `repair=true`일 때 만든다.
- frame index가 있는데 `visual_source: null`이고 해당 view 아래 visual source 파일도 없으면 `repair=true`일 때 빈 frame index 삭제 후보로 본다.
- frame index가 가리키는 definition 경로가 실제 존재하는지 확인한다.
- `visual_source``null`이면 legacy/empty frame 후보로 보고 visual source 파일 존재 여부를 함께 확인한다.
- `visual_source`가 값이면 해당 파일이 실제 존재하는지 확인한다.
- `visual_source``.excalidraw`이면 JSON으로 읽고 `elements`의 text label 또는 `customData.region_id`에서 region id 후보를 수집한다.
- Excalidraw region id 후보가 있으면 frame required region, view definition region과 비교한다.
- Excalidraw region id 후보가 없고 frame required region이 있으면 USER_REVIEW로 남긴다.
- Excalidraw에 정의되지 않은 region label이 있거나 필수 region label이 없으면 자동 수정하지 않고 USER_REVIEW로 남긴다.
- Excalidraw가 JSON으로 파싱되지 않으면 visual source 손상 또는 형식 불일치로 보고한다.
- frame required region과 view definition region을 비교한다.
- visual source가 있는 frame index에서 definition region이 빠진 경우 `repair=true`이면 frame index의 required region을 보완할 수 있다.
- 기존 frame에만 있는 region은 definition에 자동 추가하지 않고 USER_REVIEW로 남긴다.
- region 추가/삭제 의도 판단이 필요하면 USER_REVIEW로 남긴다.
5. **구현 정합성 검사**
- `scope=view:<view-id>` 또는 `scope=component:<component-id>`이면 해당 문서의 `source_evidence``type: code` 경로만 확인하고 전체 코드 후보 스캔은 하지 않는다.
- `scope=all` 또는 `scope=implementation`이면 전체 view/component의 `source_evidence``type: code` 경로가 실제 존재하는지 확인한다.
- 실제 UI 구현 후보를 찾는다.
- 이 후보 스캔은 `scope=all` 또는 `scope=implementation`일 때만 수행한다.
- 예: `apps/**/lib/**`, `packages/**/lib/**`, `src/**`, `app/**`, `pages/**`, `screens/**`, `views/**`, `components/**`, `widgets/**`, route/navigation/shell 파일
- 프로젝트 규칙에 dedicated UI domain rule이 있으면 먼저 따른다.
- 코드가 많으면 route, shell, page/view, widget/component 이름 중심으로 후보를 좁힌다.
- 운영 단계에서는 코드 후보만 보고 agent-ui view/component를 새로 만들지 않는다.
- 코드 후보가 명확한 route/page/view/shell인데 agent-ui에 대응 view가 없으면 USER_REVIEW로 남기거나, 사용자가 코드 기준 반영을 명시한 경우 `update-agent-ui`로 돌린다.
- 코드 후보가 명확한 반복 widget/component/table/filter/log/status/action인데 agent-ui에 대응 component가 없으면 USER_REVIEW로 남기거나, 사용자가 코드 기준 반영을 명시한 경우 `update-agent-ui`로 돌린다.
- 코드 결과물이 `구현됨` 상태의 agent-ui 정의와 어긋난다는 사용자 보고가 있으면 해당 항목을 `계획`으로 낮추고 sync intent를 만든다.
- 후보가 임시/dev/debug 용도인지, view인지 component인지, region인지 판단이 필요하면 USER_REVIEW로 남긴다.
- 코드에서 사라진 evidence는 자동 삭제하지 않고, 명시된 code evidence 경로가 깨진 경우에만 `구현됨``계획`으로 낮출 수 있다.
6. **USER_REVIEW 생성 또는 갱신**
- active review 파일은 `agent-ui/USER_REVIEW.md`를 사용한다.
- 새 항목 id는 기존 최대 `UIR-NNN` 다음 번호를 사용한다.
- 같은 경로와 같은 질문의 중복 항목은 만들지 않는다.
- 항목에는 `Source Skill: validate-agent-ui`, `Stage: document-consistency`, `Blocking Step`, Context, Options, Needed For를 포함한다.
7. **code sync intent 판정**
- `sync-intent=inherited`이면 `update-agent-ui`가 전달한 판단을 그대로 사용하고 재판단하지 않는다.
- 수동 호출이거나 `sync-intent=auto`이면 agent-ui 변경분과 `계획` 상태 항목을 보고 `sync-agent-ui` 필요 여부를 판단한다.
- `sync-intent=required`이면 validate 결과가 PASS 또는 자동 보정 완료 WARN이고 현재 범위에 미해결 USER_REVIEW가 없을 때 `sync-agent-ui`를 실행한다.
- `sync-intent=skip`이면 code sync 필요 여부를 보고만 하고 실행하지 않는다.
- 현재 범위에 `가정` 또는 `불명확` 항목이 있거나 미해결 USER_REVIEW가 있으면 `sync-agent-ui`를 실행하지 않는다.
- `sync-agent-ui`를 실행할 때는 이 스킬의 보정 결과를 입력으로 넘기고, 순서를 바꾸지 않는다.
8. **결과 판정**
- `PASS`: 자동 수정도 USER_REVIEW도 필요 없는 상태
- `WARN`: 자동 수정이 있었거나 USER_REVIEW가 생성/갱신된 상태
- `FAIL`: 구조가 너무 모호해서 자동 보정과 리뷰 작성 모두 불완전한 상태
## 자동 수정 허용 범위
- 누락된 필수 디렉터리와 index 문서 생성
- 명확한 단일 후보 visual source 등록
- 명확한 단일 후보 상대 링크 보정
- visual source가 있는 frame index의 region 누락 보완
- 빈 archive/user-review 디렉터리 생성
- 템플릿 필수 섹션과 frontmatter 누락 보완. `ui_doc_type`, `Source Evidence`, `Status` 누락 포함
- 명시된 code evidence 경로가 실제 존재하지 않는 `구현됨``계획`으로 낮추고 USER_REVIEW를 남기는 보정
## USER_REVIEW 대상
- 정의에는 없는 region이 기존 frame-view에 있고 추가/삭제 의도 판단이 필요한 경우
- frame-view가 있는데 frame에는 없는 region이 정의에 있고 layout 반영 여부 판단이 필요한 경우
- component 참조가 없으며 새 component 생성 또는 기존 component 재사용 판단이 필요한 경우
- 운영 단계에서 코드 후보가 view, component, region, 임시/dev/debug UI 중 무엇인지 판단이 필요한 경우
- 운영 단계에서 코드에만 있는 view/component를 agent-ui에 반영할지 판단이 필요한 경우
- 코드와 agent-ui 정의가 충돌하지만 어느 쪽을 기준으로 삼을지 제품 판단이 필요한 경우
- `계획` 항목을 코드로 반영하려 했지만 구현 방향, 환경, 권한, 검증 실패를 에이전트가 해결하지 못한 경우
- `<name>.md``<name>/`가 모두 있고 둘 다 의미 있는 내용이 있는 경우
- drawer/page/split, 테이블/리스트, modal/page 같은 UX 방향 결정이 필요한 경우
## 실행 결과 검증
- [ ] 필수 루트 문서가 존재하거나 누락 사유가 보고되었는가
- [ ] 활성 Markdown 문서가 유효한 `ui_doc_type` frontmatter를 갖는가
- [ ] folder-first + `index.md` 구조가 유지되는가
- [ ] view/component에 `Source Evidence`와 유효한 `Status`가 있는가
- [ ] 명시된 code evidence 경로가 깨진 `구현됨`이 남아 있지 않은가
- [ ] `scope=implementation` 또는 `all`이면 명확한 UI 코드 후보와 agent-ui 불일치가 sync intent 또는 USER_REVIEW로 분리되었는가
- [ ] view/component/frame 참조가 끊기지 않는가
- [ ] visual source가 없는 view는 frame 참조가 `null`이거나 비어 있는 frame-view가 없는가
- [ ] 자동 수정한 파일 목록이 보고되는가
- [ ] 사용자 판단이 필요한 항목이 `agent-ui/USER_REVIEW.md`에 남는가
- [ ] archive 본문을 일반 검증에서 읽지 않았는가
- 검증 실패 시: 판정을 `FAIL`로 보고하고 자동 수정하지 못한 이유를 남긴다.
## 출력 형식
```md
## agent-ui 검증 결과: <PASS|WARN|FAIL>
- Scope: <scope>
- Auto Fixed: <파일/항목 목록 또는 없음>
- User Review: <agent-ui/USER_REVIEW.md 생성/갱신/없음>
- Remaining Issues: <목록 또는 없음>
- Checked Files: <활성 파일 목록>
- Sync Intent: <inherited|required|skip|auto 판단 결과>
- sync-agent-ui: <실행/보류/생략 사유>
```
## 금지 사항
- UI 의도 판단이 필요한 문제를 자동 수정하지 않는다.
- archive 본문을 일반 검증 컨텍스트로 읽지 않는다.
- `.excalidraw` 내용을 현재 UI 기준으로 단독 확정하지 않는다.
- 사용자 확인 없이 의미 있는 문서를 병합하거나 삭제하지 않는다.
- agent-ui 검증과 무관한 앱 구현 파일을 수정하지 않는다.
- 전달받은 sync intent가 있으면 같은 내용을 재판단하지 않는다.
- `sync-agent-ui`보다 뒤에 실행되어서는 안 된다.
- 운영 단계에서 코드 후보만 근거로 agent-ui view/component skeleton을 자동 생성하지 않는다.

219
api/openapi/rara-v1.yaml Normal file
View file

@ -0,0 +1,219 @@
openapi: 3.1.0
info:
title: RARA RAG API
version: 0.1.0
description: |
Public online RAG contract. Requests resolve a knowledge base and release
alias so responses remain attributable to a versioned retrieval policy.
servers:
- url: http://localhost:18081
paths:
/healthz:
get:
operationId: health
responses:
"200":
description: Process is running.
/readyz:
get:
operationId: ready
responses:
"200":
description: Required dependencies are ready.
"503":
description: A required dependency is unavailable.
/v1/retrieve:
post:
operationId: retrieve
summary: Retrieve versioned evidence from a knowledge base.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RetrieveRequest"
responses:
"200":
description: Ranked evidence.
content:
application/json:
schema:
$ref: "#/components/schemas/RetrieveResponse"
"400":
$ref: "#/components/responses/BadRequest"
"404":
$ref: "#/components/responses/NotFound"
"503":
$ref: "#/components/responses/Unavailable"
/v1/answer:
post:
operationId: answer
summary: Retrieve evidence and generate an answer.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AnswerRequest"
responses:
"200":
description: |
JSON is returned when stream=false. When stream=true the endpoint
returns text/event-stream with metadata, evidence, delta, completed,
or error events.
content:
application/json:
schema:
$ref: "#/components/schemas/AnswerResponse"
text/event-stream:
schema:
type: string
"400":
$ref: "#/components/responses/BadRequest"
"404":
$ref: "#/components/responses/NotFound"
"503":
$ref: "#/components/responses/Unavailable"
components:
responses:
BadRequest:
description: Invalid request.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
NotFound:
description: Project, knowledge base, or release was not found.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
Unavailable:
description: The release or one of its integrations is unavailable.
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
schemas:
ReleaseSelector:
type: object
required: [project_id, knowledge_base_id]
properties:
project_id:
type: string
format: uuid
knowledge_base_id:
type: string
format: uuid
release_alias:
type: string
default: production
RetrieveRequest:
allOf:
- $ref: "#/components/schemas/ReleaseSelector"
- type: object
required: [query]
properties:
query:
type: string
minLength: 1
top_k:
type: integer
minimum: 1
maximum: 100
default: 10
filters:
type: object
additionalProperties: true
trace:
type: boolean
default: true
AnswerRequest:
allOf:
- $ref: "#/components/schemas/RetrieveRequest"
- type: object
properties:
stream:
type: boolean
default: false
generation:
type: object
additionalProperties: true
Evidence:
type: object
required: [id, rank, content]
properties:
id:
type: string
rank:
type: integer
score:
type: number
content:
type: string
citation:
type: object
additionalProperties: true
metadata:
type: object
additionalProperties: true
ReleaseIdentity:
type: object
required: [release_id, release_alias, release_version]
properties:
release_id:
type: string
format: uuid
release_alias:
type: string
release_version:
type: integer
RetrieveResponse:
type: object
required: [trace_id, release, evidence]
properties:
trace_id:
type: string
format: uuid
release:
$ref: "#/components/schemas/ReleaseIdentity"
evidence:
type: array
items:
$ref: "#/components/schemas/Evidence"
diagnostics:
type: object
additionalProperties: true
AnswerResponse:
type: object
required: [trace_id, release, answer, evidence]
properties:
trace_id:
type: string
format: uuid
release:
$ref: "#/components/schemas/ReleaseIdentity"
answer:
type: string
evidence:
type: array
items:
$ref: "#/components/schemas/Evidence"
usage:
type: object
additionalProperties: true
Error:
type: object
required: [code, message]
properties:
code:
type: string
message:
type: string
trace_id:
type: string
format: uuid
details:
type: object
additionalProperties: true

View file

@ -0,0 +1,111 @@
syntax = "proto3";
package rara.v1;
option go_package = "git.toki-labs.com/toki/rara/gen/go/rara/v1;rarav1";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
service ExecutorService {
rpc GetCapabilities(CapabilityRequest) returns (ExecutorCapabilities);
rpc Execute(JobSpec) returns (stream ProgressEvent);
rpc Cancel(CancelJobRequest) returns (CancelJobResponse);
}
message CapabilityRequest {}
message ExecutorCapabilities {
string executor_id = 1;
string implementation = 2;
string implementation_version = 3;
uint32 contract_version = 4;
repeated Capability capabilities = 5;
map<string, string> labels = 6;
}
message Capability {
string name = 1;
string version = 2;
google.protobuf.Struct options = 3;
}
message JobSpec {
string job_id = 1;
string project_id = 2;
string workflow_run_id = 3;
string step_run_id = 4;
string idempotency_key = 5;
string kind = 6;
uint32 attempt = 7;
google.protobuf.Timestamp deadline = 8;
google.protobuf.Struct input = 9;
repeated ArtifactRef input_artifacts = 10;
map<string, string> labels = 11;
}
message ArtifactRef {
string artifact_id = 1;
string kind = 2;
string uri = 3;
string content_hash = 4;
string schema_version = 5;
google.protobuf.Struct metadata = 6;
}
message ArtifactManifest {
string artifact_id = 1;
string project_id = 2;
string kind = 3;
string uri = 4;
string content_hash = 5;
int64 size_bytes = 6;
string media_type = 7;
string schema_version = 8;
google.protobuf.Struct metadata = 9;
repeated string parent_artifact_ids = 10;
}
message JobResult {
google.protobuf.Struct output = 1;
repeated ArtifactManifest artifacts = 2;
}
message JobError {
string code = 1;
string message = 2;
bool retryable = 3;
google.protobuf.Struct details = 4;
}
message ProgressEvent {
enum Phase {
PHASE_UNSPECIFIED = 0;
PHASE_ACCEPTED = 1;
PHASE_RUNNING = 2;
PHASE_PROGRESS = 3;
PHASE_SUCCEEDED = 4;
PHASE_FAILED = 5;
PHASE_CANCELLED = 6;
}
string job_id = 1;
string step_run_id = 2;
uint64 sequence = 3;
Phase phase = 4;
double progress = 5;
string message = 6;
google.protobuf.Timestamp occurred_at = 7;
JobResult result = 8;
JobError error = 9;
}
message CancelJobRequest {
string job_id = 1;
string reason = 2;
}
message CancelJobResponse {
bool accepted = 1;
}

6
apps/client/README.md Normal file
View file

@ -0,0 +1,6 @@
# RARA operations client
The browser-based operations UI is intentionally deferred until the control and
RAG API contracts stabilize. This location is reserved for the future Flutter
client so adding the UI does not change the repository's top-level structure.

View file

@ -0,0 +1,58 @@
package main
import (
"fmt"
"os"
"git.toki-labs.com/toki/rara/packages/go/config"
"git.toki-labs.com/toki/rara/packages/go/controlplane"
"git.toki-labs.com/toki/rara/packages/go/database"
"git.toki-labs.com/toki/rara/packages/go/httpserver"
"git.toki-labs.com/toki/rara/packages/go/observability"
"github.com/spf13/cobra"
"go.uber.org/fx"
)
func main() {
if err := newCommand().Execute(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func newCommand() *cobra.Command {
var configPath string
command := &cobra.Command{
Use: "rara-control-plane",
Short: "Run the RARA control plane",
RunE: func(*cobra.Command, []string) error {
cfg, err := config.Load(configPath)
if err != nil {
return err
}
app := fx.New(
fx.Supply(cfg),
fx.Provide(
observability.NewLogger,
observability.NewRegistry,
database.New,
httpserver.NewMux,
databaseReadiness,
),
fx.Invoke(
observability.SetupTracing,
controlplane.Register,
httpserver.Start,
),
)
app.Run()
return nil
},
}
command.Flags().StringVar(&configPath, "config", "configs/control-plane.yaml", "configuration file")
return command
}
func databaseReadiness(store *database.Store) httpserver.Readiness {
return store.Ready
}

View file

@ -0,0 +1,61 @@
package main
import (
"fmt"
"os"
"git.toki-labs.com/toki/rara/packages/go/config"
"git.toki-labs.com/toki/rara/packages/go/database"
"git.toki-labs.com/toki/rara/packages/go/httpserver"
"git.toki-labs.com/toki/rara/packages/go/observability"
"git.toki-labs.com/toki/rara/packages/go/rag"
"github.com/spf13/cobra"
"go.uber.org/fx"
)
func main() {
if err := newCommand().Execute(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func newCommand() *cobra.Command {
var configPath string
command := &cobra.Command{
Use: "rara-rag-api",
Short: "Run the RARA online RAG API",
RunE: func(*cobra.Command, []string) error {
cfg, err := config.Load(configPath)
if err != nil {
return err
}
app := fx.New(
fx.Supply(cfg),
fx.Provide(
observability.NewLogger,
observability.NewRegistry,
database.New,
httpserver.NewMux,
databaseReadiness,
rag.NewReleaseResolver,
rag.NewEngine,
rag.NewHandler,
),
fx.Invoke(
observability.SetupTracing,
rag.Register,
httpserver.Start,
),
)
app.Run()
return nil
},
}
command.Flags().StringVar(&configPath, "config", "configs/rag-api.yaml", "configuration file")
return command
}
func databaseReadiness(store *database.Store) httpserver.Readiness {
return store.Ready
}

View file

@ -0,0 +1,62 @@
package main
import (
"fmt"
"os"
"git.toki-labs.com/toki/rara/packages/go/config"
"git.toki-labs.com/toki/rara/packages/go/database"
"git.toki-labs.com/toki/rara/packages/go/httpserver"
"git.toki-labs.com/toki/rara/packages/go/observability"
"git.toki-labs.com/toki/rara/packages/go/workflow"
"github.com/spf13/cobra"
"go.uber.org/fx"
)
func main() {
if err := newCommand().Execute(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func newCommand() *cobra.Command {
var configPath string
command := &cobra.Command{
Use: "rara-worker",
Short: "Run the RARA Go workflow worker",
RunE: func(*cobra.Command, []string) error {
cfg, err := config.Load(configPath)
if err != nil {
return err
}
app := fx.New(
fx.Supply(cfg),
fx.Provide(
observability.NewLogger,
observability.NewRegistry,
database.New,
httpserver.NewMux,
databaseReadiness,
workflow.NewRegistry,
workflow.NewWorker,
),
fx.Invoke(
observability.SetupTracing,
startWorker,
httpserver.Start,
),
)
app.Run()
return nil
},
}
command.Flags().StringVar(&configPath, "config", "configs/worker.yaml", "configuration file")
return command
}
func databaseReadiness(store *database.Store) httpserver.Readiness {
return store.Ready
}
func startWorker(*workflow.Worker) {}

View file

@ -0,0 +1,21 @@
service:
name: rara-control-plane
listen: 0.0.0.0:18080
database:
url: postgres://rara:rara@localhost:5432/rara?sslmode=disable
max_connections: 20
min_connections: 2
artifact:
driver: filesystem
root: ./var/artifacts
logging:
level: info
pretty: false
observability:
otel_endpoint: ""
otel_insecure: true

21
configs/rag-api.yaml Normal file
View file

@ -0,0 +1,21 @@
service:
name: rara-rag-api
listen: 0.0.0.0:18081
database:
url: postgres://rara:rara@localhost:5432/rara?sslmode=disable
max_connections: 40
min_connections: 4
artifact:
driver: filesystem
root: ./var/artifacts
logging:
level: info
pretty: false
observability:
otel_endpoint: ""
otel_insecure: true

28
configs/worker.yaml Normal file
View file

@ -0,0 +1,28 @@
service:
name: rara-worker
listen: 0.0.0.0:18082
database:
url: postgres://rara:rara@localhost:5432/rara?sslmode=disable
max_connections: 10
min_connections: 1
artifact:
driver: filesystem
root: ./var/artifacts
worker:
id: local-go-worker
executor_kind: go
poll_interval: 2s
lease_duration: 30s
retry_delay: 5s
shutdown_grace: 20s
logging:
level: info
pretty: false
observability:
otel_endpoint: ""
otel_insecure: true

View file

@ -0,0 +1,369 @@
-- +goose Up
CREATE TABLE projects (
id uuid PRIMARY KEY,
slug text NOT NULL UNIQUE,
name text NOT NULL,
description text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE integration_instances (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
name text NOT NULL,
kind text NOT NULL CHECK (kind IN (
'source',
'retrieval_backend',
'artifact_store',
'embedding_provider',
'rerank_provider',
'generation_provider',
'executor'
)),
implementation text NOT NULL,
schema_version text NOT NULL DEFAULT 'v1',
capabilities jsonb NOT NULL DEFAULT '{}'::jsonb,
config jsonb NOT NULL DEFAULT '{}'::jsonb,
secret_ref text,
enabled boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, name)
);
CREATE TABLE knowledge_sources (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
integration_instance_id uuid NOT NULL REFERENCES integration_instances(id),
key text NOT NULL,
name text NOT NULL,
revision text,
cursor jsonb NOT NULL DEFAULT '{}'::jsonb,
sync_state text NOT NULL DEFAULT 'pending'
CHECK (sync_state IN ('pending', 'syncing', 'ready', 'failed', 'disabled')),
last_synced_at timestamptz,
tombstone_checked_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, key)
);
CREATE TABLE knowledge_bases (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
key text NOT NULL,
name text NOT NULL,
description text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, key)
);
CREATE TABLE knowledge_base_sources (
knowledge_base_id uuid NOT NULL REFERENCES knowledge_bases(id) ON DELETE CASCADE,
knowledge_source_id uuid NOT NULL REFERENCES knowledge_sources(id) ON DELETE CASCADE,
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (knowledge_base_id, knowledge_source_id)
);
CREATE TABLE artifacts (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
kind text NOT NULL,
uri text NOT NULL,
content_hash text NOT NULL,
size_bytes bigint NOT NULL CHECK (size_bytes >= 0),
media_type text NOT NULL DEFAULT 'application/octet-stream',
schema_version text NOT NULL DEFAULT 'v1',
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
status text NOT NULL DEFAULT 'ready'
CHECK (status IN ('pending', 'ready', 'failed', 'deleted')),
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, content_hash, kind)
);
CREATE TABLE artifact_lineage (
parent_artifact_id uuid NOT NULL REFERENCES artifacts(id) ON DELETE CASCADE,
child_artifact_id uuid NOT NULL REFERENCES artifacts(id) ON DELETE CASCADE,
relation text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (parent_artifact_id, child_artifact_id, relation),
CHECK (parent_artifact_id <> child_artifact_id)
);
CREATE TABLE datasets (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
key text NOT NULL,
name text NOT NULL,
purpose text NOT NULL CHECK (purpose IN (
'raw_snapshot',
'normalized',
'retrieval',
'evaluation',
'training_candidate',
'training',
'validation',
'holdout'
)),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, key)
);
CREATE TABLE workflow_definitions (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
key text NOT NULL,
name text NOT NULL,
kind text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, key)
);
CREATE TABLE workflow_versions (
id uuid PRIMARY KEY,
workflow_definition_id uuid NOT NULL REFERENCES workflow_definitions(id) ON DELETE CASCADE,
version integer NOT NULL CHECK (version > 0),
spec jsonb NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (workflow_definition_id, version)
);
CREATE TABLE schedules (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
workflow_version_id uuid NOT NULL REFERENCES workflow_versions(id),
name text NOT NULL,
cron_expression text NOT NULL,
timezone text NOT NULL DEFAULT 'UTC',
enabled boolean NOT NULL DEFAULT true,
input jsonb NOT NULL DEFAULT '{}'::jsonb,
next_run_at timestamptz,
last_run_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, name)
);
CREATE TABLE workflow_runs (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
workflow_version_id uuid NOT NULL REFERENCES workflow_versions(id),
status text NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'running', 'succeeded', 'failed', 'cancelled')),
trigger_type text NOT NULL,
input jsonb NOT NULL DEFAULT '{}'::jsonb,
output jsonb NOT NULL DEFAULT '{}'::jsonb,
error jsonb NOT NULL DEFAULT '{}'::jsonb,
idempotency_key text,
started_at timestamptz,
finished_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX workflow_runs_idempotency_idx
ON workflow_runs (project_id, idempotency_key)
WHERE idempotency_key IS NOT NULL;
CREATE TABLE step_runs (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
workflow_run_id uuid NOT NULL REFERENCES workflow_runs(id) ON DELETE CASCADE,
step_key text NOT NULL,
executor_kind text NOT NULL,
status text NOT NULL DEFAULT 'pending'
CHECK (status IN (
'pending',
'leased',
'running',
'succeeded',
'retryable_failed',
'terminal_failed',
'cancelled'
)),
attempt integer NOT NULL DEFAULT 0 CHECK (attempt >= 0),
max_attempts integer NOT NULL DEFAULT 3 CHECK (max_attempts > 0),
priority integer NOT NULL DEFAULT 0,
input jsonb NOT NULL DEFAULT '{}'::jsonb,
output jsonb NOT NULL DEFAULT '{}'::jsonb,
error jsonb NOT NULL DEFAULT '{}'::jsonb,
idempotency_key text NOT NULL,
available_at timestamptz NOT NULL DEFAULT now(),
leased_by text,
leased_until timestamptz,
started_at timestamptz,
finished_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, idempotency_key)
);
CREATE INDEX step_runs_lease_idx
ON step_runs (executor_kind, status, available_at, priority DESC, created_at)
WHERE status IN ('pending', 'retryable_failed');
CREATE INDEX step_runs_workflow_idx ON step_runs (workflow_run_id, created_at);
CREATE TABLE dataset_versions (
id uuid PRIMARY KEY,
dataset_id uuid NOT NULL REFERENCES datasets(id) ON DELETE CASCADE,
version integer NOT NULL CHECK (version > 0),
artifact_id uuid NOT NULL REFERENCES artifacts(id),
source_revision text,
recipe jsonb NOT NULL DEFAULT '{}'::jsonb,
stats jsonb NOT NULL DEFAULT '{}'::jsonb,
status text NOT NULL DEFAULT 'candidate'
CHECK (status IN ('candidate', 'active', 'retired', 'failed')),
created_by_step_run_id uuid REFERENCES step_runs(id),
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (dataset_id, version)
);
CREATE TABLE evaluation_suites (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
key text NOT NULL,
name text NOT NULL,
description text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (project_id, key)
);
CREATE TABLE evaluation_cases (
id uuid PRIMARY KEY,
evaluation_suite_id uuid NOT NULL REFERENCES evaluation_suites(id) ON DELETE CASCADE,
case_key text NOT NULL,
input jsonb NOT NULL,
expectations jsonb NOT NULL DEFAULT '{}'::jsonb,
tags text[] NOT NULL DEFAULT ARRAY[]::text[],
enabled boolean NOT NULL DEFAULT true,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (evaluation_suite_id, case_key)
);
CREATE TABLE evaluation_runs (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
evaluation_suite_id uuid NOT NULL REFERENCES evaluation_suites(id),
subject_type text NOT NULL,
subject_id uuid NOT NULL,
baseline_subject_id uuid,
workflow_run_id uuid REFERENCES workflow_runs(id),
status text NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'running', 'succeeded', 'failed', 'cancelled')),
metrics jsonb NOT NULL DEFAULT '{}'::jsonb,
passed boolean,
started_at timestamptz,
finished_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE evaluation_results (
id uuid PRIMARY KEY,
evaluation_run_id uuid NOT NULL REFERENCES evaluation_runs(id) ON DELETE CASCADE,
evaluation_case_id uuid REFERENCES evaluation_cases(id) ON DELETE CASCADE,
metric_key text NOT NULL,
score double precision,
passed boolean,
details jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX evaluation_results_run_idx ON evaluation_results (evaluation_run_id);
CREATE TABLE releases (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
knowledge_base_id uuid NOT NULL REFERENCES knowledge_bases(id) ON DELETE CASCADE,
alias text NOT NULL DEFAULT 'production',
version integer NOT NULL CHECK (version > 0),
status text NOT NULL DEFAULT 'candidate'
CHECK (status IN ('candidate', 'active', 'retired', 'failed')),
dataset_version_id uuid NOT NULL REFERENCES dataset_versions(id),
index_artifact_id uuid REFERENCES artifacts(id),
retrieval_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
generation_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
evaluation_run_id uuid REFERENCES evaluation_runs(id),
created_by_workflow_run_id uuid REFERENCES workflow_runs(id),
promoted_at timestamptz,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (knowledge_base_id, alias, version)
);
CREATE UNIQUE INDEX releases_active_alias_idx
ON releases (knowledge_base_id, alias)
WHERE status = 'active';
CREATE TABLE rag_traces (
id uuid PRIMARY KEY,
project_id uuid NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
knowledge_base_id uuid NOT NULL REFERENCES knowledge_bases(id),
release_id uuid NOT NULL REFERENCES releases(id),
request_kind text NOT NULL CHECK (request_kind IN ('retrieve', 'answer')),
trace_id uuid NOT NULL UNIQUE,
query_hash text NOT NULL,
query_text text,
response_text text,
status text NOT NULL CHECK (status IN ('succeeded', 'failed')),
latency_ms bigint NOT NULL CHECK (latency_ms >= 0),
expires_at timestamptz NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX rag_traces_project_created_idx
ON rag_traces (project_id, created_at DESC);
CREATE INDEX rag_traces_expiry_idx ON rag_traces (expires_at);
CREATE TABLE rag_trace_evidence (
id uuid PRIMARY KEY,
rag_trace_id uuid NOT NULL REFERENCES rag_traces(id) ON DELETE CASCADE,
rank integer NOT NULL CHECK (rank > 0),
artifact_id uuid REFERENCES artifacts(id),
external_ref text,
score double precision,
citation jsonb NOT NULL DEFAULT '{}'::jsonb,
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (rag_trace_id, rank)
);
CREATE INDEX integration_instances_project_kind_idx
ON integration_instances (project_id, kind, enabled);
CREATE INDEX knowledge_sources_project_idx ON knowledge_sources (project_id);
CREATE INDEX knowledge_bases_project_idx ON knowledge_bases (project_id);
CREATE INDEX artifacts_project_kind_idx ON artifacts (project_id, kind, created_at DESC);
CREATE INDEX datasets_project_idx ON datasets (project_id);
CREATE INDEX workflow_runs_project_status_idx
ON workflow_runs (project_id, status, created_at DESC);
CREATE INDEX releases_project_idx ON releases (project_id, created_at DESC);
-- +goose Down
DROP TABLE rag_trace_evidence;
DROP TABLE rag_traces;
DROP TABLE releases;
DROP TABLE evaluation_results;
DROP TABLE evaluation_runs;
DROP TABLE evaluation_cases;
DROP TABLE evaluation_suites;
DROP TABLE dataset_versions;
DROP TABLE step_runs;
DROP TABLE workflow_runs;
DROP TABLE schedules;
DROP TABLE workflow_versions;
DROP TABLE workflow_definitions;
DROP TABLE datasets;
DROP TABLE artifact_lineage;
DROP TABLE artifacts;
DROP TABLE knowledge_base_sources;
DROP TABLE knowledge_bases;
DROP TABLE knowledge_sources;
DROP TABLE integration_instances;
DROP TABLE projects;

21
db/queries/knowledge.sql Normal file
View file

@ -0,0 +1,21 @@
-- name: CreateKnowledgeBase :one
INSERT INTO knowledge_bases (id, project_id, key, name, description)
VALUES ($1, $2, $3, $4, $5)
RETURNING *;
-- name: GetKnowledgeBase :one
SELECT * FROM knowledge_bases
WHERE id = $1 AND project_id = $2;
-- name: GetKnowledgeBaseByKey :one
SELECT * FROM knowledge_bases
WHERE project_id = $1 AND key = $2;
-- name: GetActiveReleaseByAlias :one
SELECT r.*
FROM releases r
JOIN knowledge_bases kb ON kb.id = r.knowledge_base_id
WHERE kb.project_id = sqlc.arg(project_id)
AND kb.id = sqlc.arg(knowledge_base_id)
AND r.alias = sqlc.arg(alias)
AND r.status = 'active';

17
db/queries/projects.sql Normal file
View file

@ -0,0 +1,17 @@
-- name: CreateProject :one
INSERT INTO projects (id, slug, name, description)
VALUES ($1, $2, $3, $4)
RETURNING *;
-- name: GetProject :one
SELECT * FROM projects
WHERE id = $1;
-- name: GetProjectBySlug :one
SELECT * FROM projects
WHERE slug = $1;
-- name: ListProjects :many
SELECT * FROM projects
ORDER BY created_at DESC
LIMIT $1 OFFSET $2;

35
db/queries/traces.sql Normal file
View file

@ -0,0 +1,35 @@
-- name: CreateRAGTrace :one
INSERT INTO rag_traces (
id,
project_id,
knowledge_base_id,
release_id,
request_kind,
trace_id,
query_hash,
query_text,
response_text,
status,
latency_ms,
expires_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
RETURNING *;
-- name: CreateRAGTraceEvidence :one
INSERT INTO rag_trace_evidence (
id,
rag_trace_id,
rank,
artifact_id,
external_ref,
score,
citation,
metadata
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING *;
-- name: DeleteExpiredRAGTraces :execrows
DELETE FROM rag_traces
WHERE expires_at <= now();

Some files were not shown because too many files have changed in this diff Show more